264 lines
7.7 KiB
C++
264 lines
7.7 KiB
C++
// --------------------------------------------------------------------------------
|
|
// Enginit.cpp
|
|
// Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
|
|
// Steven J. Bailey
|
|
// --------------------------------------------------------------------------------
|
|
#include "pch.hxx"
|
|
#include "spengine.h"
|
|
#include "ourguid.h"
|
|
|
|
HANDLE hSmapiEvent; // Added for Bug# 62129 (v-snatar)
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// SAFECLOSEHANDLE
|
|
// --------------------------------------------------------------------------------
|
|
#ifndef WIN16
|
|
#define SAFECLOSEHANDLE(_handle) \
|
|
if (NULL != _handle) { \
|
|
CloseHandle(_handle); \
|
|
_handle = NULL; \
|
|
}
|
|
#else
|
|
#define SAFECLOSEHANDLE(_handle) \
|
|
if (NULL != _handle) { \
|
|
CloseEvent(_handle); \
|
|
_handle = NULL; \
|
|
}
|
|
#endif
|
|
// --------------------------------------------------------------------------------
|
|
// ENGINECREATEINFO
|
|
// --------------------------------------------------------------------------------
|
|
typedef struct tagENGINECREATEINFO {
|
|
HEVENT hEvent; // Event used to synchronize creation
|
|
HRESULT hrResult; // Result from SpoolEngineThreadEntry
|
|
PFNCREATESPOOLERUI pfnCreateUI; // Function to create the spooler ui object
|
|
CSpoolerEngine *pSpooler; // Spooler Engine
|
|
BOOL fPoll; // Whether or not to poll
|
|
} ENGINECREATEINFO, *LPENGINECREATEINFO;
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// SpoolerEngineThreadEntry
|
|
// --------------------------------------------------------------------------------
|
|
#ifndef WIN16
|
|
DWORD SpoolerEngineThreadEntry(LPDWORD pdwParam);
|
|
#else
|
|
unsigned int __stdcall LOADDS_16 SpoolerEngineThreadEntry(LPDWORD pdwParam);
|
|
#endif
|
|
HTHREAD hThread = NULL;
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CreateThreadedSpooler
|
|
// --------------------------------------------------------------------------------
|
|
HRESULT CreateThreadedSpooler(PFNCREATESPOOLERUI pfnCreateUI, ISpoolerEngine **ppSpooler,
|
|
BOOL fPoll)
|
|
{
|
|
// Locals
|
|
HRESULT hr=S_OK;
|
|
HTHREAD hThread=NULL;
|
|
DWORD dwThreadId;
|
|
ENGINECREATEINFO rCreate;
|
|
|
|
// Invalid Arg
|
|
if (NULL == ppSpooler)
|
|
return TrapError(E_INVALIDARG);
|
|
|
|
// Initialize the Structure
|
|
ZeroMemory(&rCreate, sizeof(ENGINECREATEINFO));
|
|
|
|
rCreate.hrResult = S_OK;
|
|
rCreate.pfnCreateUI = pfnCreateUI;
|
|
rCreate.fPoll = fPoll;
|
|
|
|
// Create an Event to synchonize creation
|
|
rCreate.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
if (NULL == rCreate.hEvent)
|
|
{
|
|
hr = TrapError(E_OUTOFMEMORY);
|
|
goto exit;
|
|
}
|
|
|
|
// Added Bug# 62129 (v-snatar)
|
|
hSmapiEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
|
|
// Create the inetmail thread
|
|
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SpoolerEngineThreadEntry, &rCreate, 0, &dwThreadId);
|
|
if (NULL == hThread)
|
|
{
|
|
hr = TrapError(E_OUTOFMEMORY);
|
|
goto exit;
|
|
}
|
|
|
|
// Wait for SpoolEngineThreadEntry to signal the event
|
|
WaitForSingleObject_16(rCreate.hEvent, INFINITE);
|
|
|
|
// Failure
|
|
if (FAILED(rCreate.hrResult))
|
|
{
|
|
hr = TrapError(rCreate.hrResult);
|
|
goto exit;
|
|
}
|
|
|
|
// Return the object
|
|
Assert(rCreate.pSpooler);
|
|
*ppSpooler = (ISpoolerEngine *)rCreate.pSpooler;
|
|
rCreate.pSpooler->m_hThread = hThread;
|
|
|
|
exit:
|
|
// Cleanup
|
|
SAFECLOSEHANDLE(rCreate.hEvent);
|
|
SafeRelease(rCreate.pSpooler);
|
|
|
|
// Done
|
|
return hr;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------------
|
|
// CloseThreadedSpooler
|
|
// ------------------------------------------------------------------------------------
|
|
HRESULT CloseThreadedSpooler(ISpoolerEngine *pSpooler)
|
|
{
|
|
// Locals
|
|
DWORD dwThreadId;
|
|
HTHREAD hThread;
|
|
|
|
// Invalid Arg
|
|
if (NULL == pSpooler)
|
|
return TrapError(E_INVALIDARG);
|
|
|
|
// Get the Thread Info
|
|
pSpooler->GetThreadInfo(&dwThreadId, &hThread);
|
|
|
|
// Assert
|
|
Assert(dwThreadId && hThread);
|
|
|
|
// Post quit message
|
|
PostThreadMessage(dwThreadId, WM_QUIT, 0, 0);
|
|
|
|
// Wait for event to become signaled
|
|
WaitForSingleObject(hThread, INFINITE);
|
|
|
|
// Close the thread handle
|
|
CloseHandle(hThread);
|
|
|
|
// Close the Event Created for Simple MAPI purposes
|
|
// Bug #62129 (v-snatar)
|
|
|
|
CloseHandle(hSmapiEvent);
|
|
|
|
// Done
|
|
return S_OK;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// SpoolerEngineThreadEntry
|
|
// --------------------------------------------------------------------------------
|
|
#ifndef WIN16
|
|
DWORD SpoolerEngineThreadEntry(LPDWORD pdwParam)
|
|
#else
|
|
unsigned int __stdcall LOADDS_16 SpoolerEngineThreadEntry(LPDWORD pdwParam)
|
|
#endif
|
|
{
|
|
// Locals
|
|
MSG msg;
|
|
HWND hwndUI;
|
|
CSpoolerEngine *pSpooler=NULL;
|
|
ISpoolerUI *pUI=NULL;
|
|
LPENGINECREATEINFO pCreate;
|
|
|
|
// We better have a parameter
|
|
Assert(pdwParam);
|
|
|
|
// Cast to create info
|
|
pCreate = (LPENGINECREATEINFO)pdwParam;
|
|
|
|
// Initialize COM
|
|
pCreate->hrResult = OleInitialize(NULL);
|
|
if (FAILED(pCreate->hrResult))
|
|
{
|
|
TrapError(pCreate->hrResult);
|
|
SetEvent(pCreate->hEvent);
|
|
return 0;
|
|
}
|
|
|
|
// Create the Spooler UI
|
|
if (pCreate->pfnCreateUI)
|
|
{
|
|
// Create the UI Object
|
|
pCreate->hrResult = (*pCreate->pfnCreateUI)(&pUI);
|
|
if (FAILED(pCreate->hrResult))
|
|
{
|
|
CoUninitialize();
|
|
TrapError(pCreate->hrResult);
|
|
SetEvent(pCreate->hEvent);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Create a Spooler Object
|
|
pCreate->pSpooler = new CSpoolerEngine;
|
|
if (NULL == pCreate->pSpooler)
|
|
{
|
|
CoUninitialize();
|
|
pCreate->hrResult = TrapError(E_OUTOFMEMORY);
|
|
SetEvent(pCreate->hEvent);
|
|
return 0;
|
|
}
|
|
|
|
// Initialize the Spooler Engine
|
|
pCreate->hrResult = pCreate->pSpooler->Init(pUI, pCreate->fPoll);
|
|
if (FAILED(pCreate->hrResult))
|
|
{
|
|
CoUninitialize();
|
|
TrapError(pCreate->hrResult);
|
|
SetEvent(pCreate->hEvent);
|
|
return 0;
|
|
}
|
|
|
|
// No UI Yet ?
|
|
if (NULL == pUI)
|
|
{
|
|
// Get the spooler UI object
|
|
SideAssert(SUCCEEDED(pCreate->pSpooler->BindToObject(IID_ISpoolerUI, (LPVOID *)&pUI)));
|
|
}
|
|
|
|
// I want to hold onto the spooler
|
|
pSpooler = pCreate->pSpooler;
|
|
pSpooler->AddRef();
|
|
|
|
// Set Event
|
|
SetEvent(pCreate->hEvent);
|
|
|
|
// Pump Messages
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
// Give the message to the UI object
|
|
if (pUI->IsDialogMessage(&msg) == S_FALSE && pSpooler->IsDialogMessage(&msg) == S_FALSE)
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
// Raid 67816: OE:TW:Error message stop responding after OE is closed.
|
|
// If a dialog was displayed when the above message loop broke out, then that dialog will
|
|
// have automatically gone away and left the spooler UI window disabled!
|
|
pUI->GetWindow(&hwndUI);
|
|
EnableWindow(hwndUI, TRUE);
|
|
|
|
// Shutdown the spooler
|
|
pSpooler->Shutdown();
|
|
|
|
// Release the UI Object
|
|
pUI->Close();
|
|
pUI->Release();
|
|
|
|
// Release
|
|
pSpooler->Release();
|
|
|
|
// Deinit COM
|
|
OleUninitialize();
|
|
|
|
// Done
|
|
return 1;
|
|
}
|