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.

321 lines
6.9 KiB

  1. //***************************************************************************
  2. //
  3. // MAINDLL.CPP
  4. //
  5. // Module: SCE WMI provider code
  6. //
  7. // Purpose: Contains DLL entry points. Also has code that controls
  8. // when the DLL can be unloaded by tracking the number of
  9. // objects and locks as well as routines that support
  10. // self registration.
  11. //
  12. // Copyright (c) 1999-2001 Microsoft Corporation
  13. //
  14. //***************************************************************************
  15. #include <objbase.h>
  16. #include <initguid.h>
  17. #include "sceprov.h"
  18. #include "scecore_i.c"
  19. #include "sceparser.h"
  20. #include "persistmgr.h"
  21. #include "resource.h"
  22. #ifdef _MERGE_PROXYSTUB
  23. extern "C" HINSTANCE hProxyDll;
  24. #endif
  25. //
  26. // this is the ATL wrapper for our module
  27. //
  28. CComModule _Module;
  29. //
  30. // this is the ATL object map. If you need to create another COM object that
  31. // is externally createable, then you need to add an entry here. You don't need
  32. // to mess with class factory stuff.
  33. //
  34. BEGIN_OBJECT_MAP(ObjectMap)
  35. OBJECT_ENTRY(CLSID_SceProv, CSceWmiProv)
  36. OBJECT_ENTRY(CLSID_ScePathParser, CScePathParser)
  37. OBJECT_ENTRY(CLSID_SceQueryParser, CSceQueryParser)
  38. OBJECT_ENTRY(CLSID_ScePersistMgr, CScePersistMgr)
  39. END_OBJECT_MAP()
  40. LPCWSTR lpszSceProvMof = L"Wbem\\SceProv.mof";
  41. /*
  42. Routine Description:
  43. Name:
  44. DllMain
  45. Functionality:
  46. Entry point for DLL.
  47. Arguments:
  48. See DllMain on MSDN.
  49. Return Value:
  50. TRUE if OK.
  51. Notes:
  52. DllMain will be called for attach and detach. When other dlls are loaded, this function
  53. will also get called. So, this is not necessary a good place for you to initialize some
  54. globals unless you know precisely what you are doing. Please read MSDN for details before
  55. you try to modify this function.
  56. As a general design approach, we use gloal class instances to guarantee its creation and
  57. destruction.
  58. */
  59. extern "C"
  60. BOOL WINAPI DllMain (
  61. IN HINSTANCE hInstance,
  62. IN ULONG ulReason,
  63. LPVOID pvReserved
  64. )
  65. {
  66. #ifdef _MERGE_PROXYSTUB
  67. if (!PrxDllMain(hInstance, dwReason, lpReserved))
  68. return FALSE;
  69. #endif
  70. if (ulReason == DLL_PROCESS_ATTACH)
  71. {
  72. OutputDebugString(L"SceProv.dll loaded.\n");
  73. _Module.Init(ObjectMap, hInstance);
  74. DisableThreadLibraryCalls(hInstance);
  75. }
  76. else if (ulReason == DLL_PROCESS_DETACH)
  77. {
  78. OutputDebugString(L"SceProv.dll unloaded.\n");
  79. _Module.Term();
  80. }
  81. return TRUE;
  82. }
  83. /*
  84. Routine Description:
  85. Name:
  86. DllGetClassObject
  87. Functionality:
  88. Retrieves the class object from a DLL object handler or object application.
  89. DllGetClassObject is called from within the CoGetClassObject function when the
  90. class context is a DLL.
  91. As a benefit of using ATL, we just need to delegate this to our _Module object.
  92. Arguments:
  93. rclsid - Class ID (guid) for the class object being requested.
  94. riid - Interface GUID that is being requested.
  95. ppv - the interface pointer being returned if successful
  96. Return Value:
  97. Whatever GetClassObject returns for this class ID and its requested interface id.
  98. Notes:
  99. */
  100. STDAPI DllGetClassObject (
  101. IN REFCLSID rclsid,
  102. IN REFIID riid,
  103. OUT PPVOID ppv
  104. )
  105. {
  106. #ifdef _MERGE_PROXYSTUB
  107. if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
  108. return S_OK;
  109. #endif
  110. return _Module.GetClassObject(rclsid, riid, ppv);
  111. }
  112. /*
  113. Routine Description:
  114. Name:
  115. DllCanUnloadNow
  116. Functionality:
  117. Called periodically by COM in order to determine if the DLL can be freed.
  118. As a benefit of using ATL, we just need to delegate this to our _Module object.
  119. Arguments:
  120. None
  121. Return Value:
  122. S_OK if the dll can be unloaded. Otherwise, it returns S_FALSE;
  123. Notes:
  124. */
  125. STDAPI DllCanUnloadNow (void)
  126. {
  127. #ifdef _MERGE_PROXYSTUB
  128. if (PrxDllCanUnloadNow() != S_OK)
  129. return S_FALSE;
  130. #endif
  131. return (_Module.GetLockCount() == 0) ? S_OK : S_FALSE;
  132. }
  133. /*
  134. Routine Description:
  135. Name:
  136. DllRegisterServer
  137. Functionality:
  138. (1) Called during dll registration.
  139. As a benefit of using ATL, we just need to delegate this to our _Module object.
  140. (2) Since we are a provider, we will also compile our MOF file(s).
  141. Arguments:
  142. None
  143. Return Value:
  144. Success: success code (use SUCCEEDED(hr) to test).
  145. Failure: it returns various errors;
  146. Notes:
  147. */
  148. STDAPI DllRegisterServer(void)
  149. {
  150. #ifdef _MERGE_PROXYSTUB
  151. HRESULT hRes = PrxDllRegisterServer();
  152. if (FAILED(hRes))
  153. return hRes;
  154. #endif
  155. HRESULT hr = _Module.RegisterServer(TRUE);
  156. //
  157. // now compile the MOF file. This is only our current approach. It is not
  158. // required to compile the MOF file during DLL registration. Users can compile
  159. // MOF file(s) indenpendently from dll registration
  160. //
  161. if (SUCCEEDED(hr))
  162. {
  163. const int WBEM_MOF_FILE_LEN = 30;
  164. WCHAR szBuffer[MAX_PATH];
  165. WCHAR szMofFile[MAX_PATH + WBEM_MOF_FILE_LEN];
  166. szBuffer[0] = L'\0';
  167. szMofFile[0] = L'\0';
  168. if ( GetSystemDirectory( szBuffer, MAX_PATH ) ) {
  169. LPWSTR sz = szBuffer + wcslen(szBuffer);
  170. if ( sz != szBuffer && *(sz-1) != L'\\') {
  171. *sz++ = L'\\';
  172. *sz = L'\0';
  173. }
  174. hr = WBEM_NO_ERROR;
  175. //
  176. // this protects buffer overrun
  177. //
  178. if (wcslen(lpszSceProvMof) < WBEM_MOF_FILE_LEN)
  179. {
  180. wcscpy(szMofFile, szBuffer);
  181. wcscat( szMofFile, lpszSceProvMof);
  182. //
  183. // we need COM to be ready
  184. //
  185. hr = ::CoInitialize (NULL);
  186. if (SUCCEEDED(hr))
  187. {
  188. //
  189. // Get the MOF compiler interface
  190. //
  191. CComPtr<IMofCompiler> srpMof;
  192. hr = ::CoCreateInstance (CLSID_MofCompiler, NULL, CLSCTX_INPROC_SERVER, IID_IMofCompiler, (void **)&srpMof);
  193. if (SUCCEEDED(hr))
  194. {
  195. WBEM_COMPILE_STATUS_INFO stat;
  196. hr = srpMof->CompileFile( szMofFile,
  197. NULL,NULL,NULL,NULL,
  198. 0,0,0, &stat);
  199. }
  200. ::CoUninitialize();
  201. }
  202. }
  203. }
  204. }
  205. return hr;
  206. }
  207. /*
  208. Routine Description:
  209. Name:
  210. DllRegisterServer
  211. Functionality:
  212. (1) Called when it is time to remove the registry entries.
  213. As a benefit of using ATL, we just need to delegate this to our _Module object.
  214. Arguments:
  215. None
  216. Return Value:
  217. Success: S_OK (same as NOERROR).
  218. Failure: it returns various errors;
  219. Notes:
  220. There is no MOF unregistration. Otherwise, we should probably do a MOF unregistration
  221. */
  222. STDAPI DllUnregisterServer(void)
  223. {
  224. #ifdef _MERGE_PROXYSTUB
  225. PrxDllUnregisterServer();
  226. #endif
  227. _Module.UnregisterServer();
  228. return S_OK;
  229. }