// -------------------------------------------------------------------------------- // 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; }