Source code of Windows XP (NT5)
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.

266 lines
7.2 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: S V C M A I N . C P P
  7. //
  8. // Contents: Service main for upnphost.dll
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 8 Aug 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include <dbt.h>
  18. #include "uhbase.h"
  19. #include "uhinit.h"
  20. #include "uhres.h"
  21. #include "hostp.h"
  22. // Includes for COM objects needed in the following object map.
  23. #include "DynamicContentSource.h"
  24. #include "DescriptionManager.h"
  25. #include "DevicePersistenceManager.h"
  26. #include "ContainerManager.h"
  27. #include "Registrar.h"
  28. #include "AutomationProxy.h"
  29. #include "evtobj.h"
  30. #include "ValidationManager.h"
  31. #include "udhhttp.h"
  32. #include "uhcommon.h"
  33. CServiceModule _Module;
  34. BEGIN_OBJECT_MAP(ObjectMap)
  35. OBJECT_ENTRY(CLSID_UPnPDynamicContentSource, CDynamicContentSource)
  36. OBJECT_ENTRY(CLSID_UPnPDescriptionManager, CDescriptionManager)
  37. OBJECT_ENTRY(CLSID_UPnPDevicePersistenceManager, CDevicePersistenceManager)
  38. OBJECT_ENTRY(CLSID_UPnPContainerManager, CContainerManager)
  39. OBJECT_ENTRY(CLSID_UPnPRegistrar, CRegistrar)
  40. OBJECT_ENTRY(CLSID_UPnPAutomationProxy, CUPnPAutomationProxy)
  41. OBJECT_ENTRY(CLSID_UPnPEventingManager, CUPnPEventingManager)
  42. OBJECT_ENTRY(CLSID_UPnPValidationManager, CValidationManager)
  43. END_OBJECT_MAP()
  44. VOID
  45. CServiceModule::DllProcessAttach (
  46. HINSTANCE hinst)
  47. {
  48. CComModule::Init (ObjectMap, hinst);
  49. }
  50. VOID
  51. CServiceModule::DllProcessDetach (
  52. VOID)
  53. {
  54. CComModule::Term ();
  55. }
  56. DWORD
  57. CServiceModule::DwHandler (
  58. DWORD dwControl,
  59. DWORD dwEventType,
  60. PVOID pEventData,
  61. PVOID pContext)
  62. {
  63. if ((SERVICE_CONTROL_STOP == dwControl) ||
  64. (SERVICE_CONTROL_SHUTDOWN == dwControl))
  65. {
  66. TraceTag (ttidUPnPHost, "Received SERVICE_CONTROL_STOP request");
  67. SetServiceStatus (SERVICE_STOP_PENDING);
  68. // Post the quit message.
  69. //
  70. PostThreadMessage (m_dwThreadID, WM_QUIT, 0, 0);
  71. }
  72. else if (SERVICE_CONTROL_INTERROGATE == dwControl)
  73. {
  74. TraceTag (ttidUPnPHost, "Received SERVICE_CONTROL_INTERROGATE request");
  75. UpdateServiceStatus (FALSE);
  76. }
  77. return 1;
  78. }
  79. VOID
  80. CServiceModule::SetServiceStatus(DWORD dwState)
  81. {
  82. m_status.dwCurrentState = dwState;
  83. m_status.dwCheckPoint = 0;
  84. if (!::SetServiceStatus (m_hStatus, &m_status))
  85. {
  86. TraceHr (ttidError, FAL, HrFromLastWin32Error(), FALSE,
  87. "CServiceModule::SetServiceStatus");
  88. }
  89. }
  90. VOID CServiceModule::UpdateServiceStatus (
  91. BOOL fUpdateCheckpoint /* = TRUE */)
  92. {
  93. if (fUpdateCheckpoint)
  94. {
  95. m_status.dwCheckPoint++;
  96. }
  97. if (!::SetServiceStatus (m_hStatus, &m_status))
  98. {
  99. TraceHr (ttidError, FAL, HrFromLastWin32Error(), FALSE,
  100. "CServiceModule::UpdateServiceStatus");
  101. }
  102. }
  103. VOID
  104. CServiceModule::Run()
  105. {
  106. HRESULT hr = S_OK;
  107. hr = CoInitializeEx (NULL,
  108. COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
  109. TraceHr (ttidError, FAL, hr, FALSE, "CServiceModule::Run: "
  110. "CoInitializeEx failed");
  111. if (SUCCEEDED(hr))
  112. {
  113. hr = HrCreateNetworkSID();
  114. TraceHr(ttidError, FAL, hr, FALSE,"HrCreateNetworkSID");
  115. }
  116. if (SUCCEEDED(hr))
  117. {
  118. TraceTag (ttidUPnPHost, "Calling RegisterClassObjects...");
  119. // Create the event to sychronize registering our class objects
  120. // with the connection manager which attempts to CoCreate
  121. // objects which are also registered here. I've seen cases
  122. // where the connection manager will be off and running before
  123. // this completes causing CoCreateInstance to fail.
  124. // The connection manager will wait on this event before
  125. // executing CoCreateInstance.
  126. //
  127. HANDLE hEvent;
  128. hr = HrNmCreateClassObjectRegistrationEvent (&hEvent);
  129. if (SUCCEEDED(hr))
  130. {
  131. hr = _Module.RegisterClassObjects (
  132. CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
  133. REGCLS_MULTIPLEUSE);
  134. TraceHr (ttidError, FAL, hr, FALSE, "CServiceModule::Run: "
  135. "_Module.RegisterClassObjects failed");
  136. if(SUCCEEDED(hr))
  137. {
  138. IUPnPRegistrarPrivate * pPriv = NULL;
  139. hr = HrCoCreateInstanceInproc(CLSID_UPnPRegistrar, &pPriv);
  140. if(SUCCEEDED(hr))
  141. {
  142. hr = pPriv->Initialize();
  143. ReleaseObj(pPriv);
  144. }
  145. }
  146. // Signal the event and close it. If this delete's the
  147. // event, so be it. It's purpose is served as all
  148. // class objects have been registered.
  149. //
  150. SetEvent (hEvent);
  151. CloseHandle (hEvent);
  152. }
  153. if (SUCCEEDED(hr))
  154. {
  155. hr = HrHttpInitialize();
  156. }
  157. if (SUCCEEDED(hr))
  158. {
  159. SetServiceStatus (SERVICE_RUNNING);
  160. TraceTag (ttidUPnPHost, "upnphost is now running...");
  161. MSG msg;
  162. while (GetMessage (&msg, 0, 0, 0))
  163. {
  164. DispatchMessage (&msg);
  165. }
  166. // // We must synchronize with the install queue's thread otherwise
  167. // // RevokeClassObjects will kill the InstallQueue object and
  168. // // CoUninitialize will free the NetCfg module before the thread
  169. // // is finished.
  170. // //
  171. // WaitForInstallQueueToExit();
  172. if (SUCCEEDED(hr))
  173. {
  174. hr = HrHttpShutdown();
  175. }
  176. IUPnPRegistrarPrivate * pPriv = NULL;
  177. hr = HrCoCreateInstanceInproc(CLSID_UPnPRegistrar, &pPriv);
  178. if(SUCCEEDED(hr))
  179. {
  180. CoSuspendClassObjects();
  181. hr = pPriv->Shutdown();
  182. ReleaseObj(pPriv);
  183. }
  184. _Module.RevokeClassObjects ();
  185. }
  186. CoUninitialize();
  187. }
  188. CleanupNetworkSID();
  189. }
  190. VOID
  191. CServiceModule::ServiceMain (
  192. DWORD argc,
  193. PWSTR argv[])
  194. {
  195. m_dwThreadID = GetCurrentThreadId ();
  196. ZeroMemory (&m_status, sizeof(m_status));
  197. m_status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
  198. m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
  199. // Register the service control handler.
  200. //
  201. m_hStatus = RegisterServiceCtrlHandlerEx (
  202. L"upnphost",
  203. _DwHandler,
  204. NULL);
  205. if (m_hStatus)
  206. {
  207. SetServiceStatus (SERVICE_START_PENDING);
  208. // When the Run function returns, the service has stopped.
  209. //
  210. Run ();
  211. SetServiceStatus (SERVICE_STOPPED);
  212. }
  213. else
  214. {
  215. TraceHr (ttidError, FAL, HrFromLastWin32Error(), FALSE,
  216. "CServiceModule::ServiceMain - RegisterServiceCtrlHandler failed");
  217. }
  218. }
  219. // static
  220. DWORD
  221. WINAPI
  222. CServiceModule::_DwHandler (
  223. DWORD dwControl,
  224. DWORD dwEventType,
  225. PVOID pEventData,
  226. PVOID pContext)
  227. {
  228. return _Module.DwHandler (dwControl, dwEventType, pEventData, pContext);
  229. }