Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
7.7 KiB

  1. // --------------------------------------------------------------------------------
  2. // Enginit.cpp
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // Steven J. Bailey
  5. // --------------------------------------------------------------------------------
  6. #include "pch.hxx"
  7. #include "spengine.h"
  8. #include "ourguid.h"
  9. HANDLE hSmapiEvent; // Added for Bug# 62129 (v-snatar)
  10. // --------------------------------------------------------------------------------
  11. // SAFECLOSEHANDLE
  12. // --------------------------------------------------------------------------------
  13. #ifndef WIN16
  14. #define SAFECLOSEHANDLE(_handle) \
  15. if (NULL != _handle) { \
  16. CloseHandle(_handle); \
  17. _handle = NULL; \
  18. }
  19. #else
  20. #define SAFECLOSEHANDLE(_handle) \
  21. if (NULL != _handle) { \
  22. CloseEvent(_handle); \
  23. _handle = NULL; \
  24. }
  25. #endif
  26. // --------------------------------------------------------------------------------
  27. // ENGINECREATEINFO
  28. // --------------------------------------------------------------------------------
  29. typedef struct tagENGINECREATEINFO {
  30. HEVENT hEvent; // Event used to synchronize creation
  31. HRESULT hrResult; // Result from SpoolEngineThreadEntry
  32. PFNCREATESPOOLERUI pfnCreateUI; // Function to create the spooler ui object
  33. CSpoolerEngine *pSpooler; // Spooler Engine
  34. BOOL fPoll; // Whether or not to poll
  35. } ENGINECREATEINFO, *LPENGINECREATEINFO;
  36. // --------------------------------------------------------------------------------
  37. // SpoolerEngineThreadEntry
  38. // --------------------------------------------------------------------------------
  39. #ifndef WIN16
  40. DWORD SpoolerEngineThreadEntry(LPDWORD pdwParam);
  41. #else
  42. unsigned int __stdcall LOADDS_16 SpoolerEngineThreadEntry(LPDWORD pdwParam);
  43. #endif
  44. HTHREAD hThread = NULL;
  45. // --------------------------------------------------------------------------------
  46. // CreateThreadedSpooler
  47. // --------------------------------------------------------------------------------
  48. HRESULT CreateThreadedSpooler(PFNCREATESPOOLERUI pfnCreateUI, ISpoolerEngine **ppSpooler,
  49. BOOL fPoll)
  50. {
  51. // Locals
  52. HRESULT hr=S_OK;
  53. HTHREAD hThread=NULL;
  54. DWORD dwThreadId;
  55. ENGINECREATEINFO rCreate;
  56. // Invalid Arg
  57. if (NULL == ppSpooler)
  58. return TrapError(E_INVALIDARG);
  59. // Initialize the Structure
  60. ZeroMemory(&rCreate, sizeof(ENGINECREATEINFO));
  61. rCreate.hrResult = S_OK;
  62. rCreate.pfnCreateUI = pfnCreateUI;
  63. rCreate.fPoll = fPoll;
  64. // Create an Event to synchonize creation
  65. rCreate.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  66. if (NULL == rCreate.hEvent)
  67. {
  68. hr = TrapError(E_OUTOFMEMORY);
  69. goto exit;
  70. }
  71. // Added Bug# 62129 (v-snatar)
  72. hSmapiEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  73. // Create the inetmail thread
  74. hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SpoolerEngineThreadEntry, &rCreate, 0, &dwThreadId);
  75. if (NULL == hThread)
  76. {
  77. hr = TrapError(E_OUTOFMEMORY);
  78. goto exit;
  79. }
  80. // Wait for SpoolEngineThreadEntry to signal the event
  81. WaitForSingleObject_16(rCreate.hEvent, INFINITE);
  82. // Failure
  83. if (FAILED(rCreate.hrResult))
  84. {
  85. hr = TrapError(rCreate.hrResult);
  86. goto exit;
  87. }
  88. // Return the object
  89. Assert(rCreate.pSpooler);
  90. *ppSpooler = (ISpoolerEngine *)rCreate.pSpooler;
  91. rCreate.pSpooler->m_hThread = hThread;
  92. exit:
  93. // Cleanup
  94. SAFECLOSEHANDLE(rCreate.hEvent);
  95. SafeRelease(rCreate.pSpooler);
  96. // Done
  97. return hr;
  98. }
  99. // ------------------------------------------------------------------------------------
  100. // CloseThreadedSpooler
  101. // ------------------------------------------------------------------------------------
  102. HRESULT CloseThreadedSpooler(ISpoolerEngine *pSpooler)
  103. {
  104. // Locals
  105. DWORD dwThreadId;
  106. HTHREAD hThread;
  107. // Invalid Arg
  108. if (NULL == pSpooler)
  109. return TrapError(E_INVALIDARG);
  110. // Get the Thread Info
  111. pSpooler->GetThreadInfo(&dwThreadId, &hThread);
  112. // Assert
  113. Assert(dwThreadId && hThread);
  114. // Post quit message
  115. PostThreadMessage(dwThreadId, WM_QUIT, 0, 0);
  116. // Wait for event to become signaled
  117. WaitForSingleObject(hThread, INFINITE);
  118. // Close the thread handle
  119. CloseHandle(hThread);
  120. // Close the Event Created for Simple MAPI purposes
  121. // Bug #62129 (v-snatar)
  122. CloseHandle(hSmapiEvent);
  123. // Done
  124. return S_OK;
  125. }
  126. // --------------------------------------------------------------------------------
  127. // SpoolerEngineThreadEntry
  128. // --------------------------------------------------------------------------------
  129. #ifndef WIN16
  130. DWORD SpoolerEngineThreadEntry(LPDWORD pdwParam)
  131. #else
  132. unsigned int __stdcall LOADDS_16 SpoolerEngineThreadEntry(LPDWORD pdwParam)
  133. #endif
  134. {
  135. // Locals
  136. MSG msg;
  137. HWND hwndUI;
  138. CSpoolerEngine *pSpooler=NULL;
  139. ISpoolerUI *pUI=NULL;
  140. LPENGINECREATEINFO pCreate;
  141. // We better have a parameter
  142. Assert(pdwParam);
  143. // Cast to create info
  144. pCreate = (LPENGINECREATEINFO)pdwParam;
  145. // Initialize COM
  146. pCreate->hrResult = OleInitialize(NULL);
  147. if (FAILED(pCreate->hrResult))
  148. {
  149. TrapError(pCreate->hrResult);
  150. SetEvent(pCreate->hEvent);
  151. return 0;
  152. }
  153. // Create the Spooler UI
  154. if (pCreate->pfnCreateUI)
  155. {
  156. // Create the UI Object
  157. pCreate->hrResult = (*pCreate->pfnCreateUI)(&pUI);
  158. if (FAILED(pCreate->hrResult))
  159. {
  160. CoUninitialize();
  161. TrapError(pCreate->hrResult);
  162. SetEvent(pCreate->hEvent);
  163. return 0;
  164. }
  165. }
  166. // Create a Spooler Object
  167. pCreate->pSpooler = new CSpoolerEngine;
  168. if (NULL == pCreate->pSpooler)
  169. {
  170. CoUninitialize();
  171. pCreate->hrResult = TrapError(E_OUTOFMEMORY);
  172. SetEvent(pCreate->hEvent);
  173. return 0;
  174. }
  175. // Initialize the Spooler Engine
  176. pCreate->hrResult = pCreate->pSpooler->Init(pUI, pCreate->fPoll);
  177. if (FAILED(pCreate->hrResult))
  178. {
  179. CoUninitialize();
  180. TrapError(pCreate->hrResult);
  181. SetEvent(pCreate->hEvent);
  182. return 0;
  183. }
  184. // No UI Yet ?
  185. if (NULL == pUI)
  186. {
  187. // Get the spooler UI object
  188. SideAssert(SUCCEEDED(pCreate->pSpooler->BindToObject(IID_ISpoolerUI, (LPVOID *)&pUI)));
  189. }
  190. // I want to hold onto the spooler
  191. pSpooler = pCreate->pSpooler;
  192. pSpooler->AddRef();
  193. // Set Event
  194. SetEvent(pCreate->hEvent);
  195. // Pump Messages
  196. while (GetMessage(&msg, NULL, 0, 0))
  197. {
  198. // Give the message to the UI object
  199. if (pUI->IsDialogMessage(&msg) == S_FALSE && pSpooler->IsDialogMessage(&msg) == S_FALSE)
  200. {
  201. TranslateMessage(&msg);
  202. DispatchMessage(&msg);
  203. }
  204. }
  205. // Raid 67816: OE:TW:Error message stop responding after OE is closed.
  206. // If a dialog was displayed when the above message loop broke out, then that dialog will
  207. // have automatically gone away and left the spooler UI window disabled!
  208. pUI->GetWindow(&hwndUI);
  209. EnableWindow(hwndUI, TRUE);
  210. // Shutdown the spooler
  211. pSpooler->Shutdown();
  212. // Release the UI Object
  213. pUI->Close();
  214. pUI->Release();
  215. // Release
  216. pSpooler->Release();
  217. // Deinit COM
  218. OleUninitialize();
  219. // Done
  220. return 1;
  221. }