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.

496 lines
13 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // MAINDLL.CPP
  4. //
  5. // Purpose: Contains DLL entry points. Also has code that controls
  6. // when the DLL can be unloaded by tracking the number of
  7. // objects and locks as well as routines that support
  8. // self registration.
  9. //
  10. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  11. //
  12. /////////////////////////////////////////////////////////////////////////////////////////////////
  13. #include "precomp.h"
  14. #include <initguid.h>
  15. #include <locale.h>
  16. #include "wdmdefs.h"
  17. #include <stdio.h>
  18. #include <tchar.h>
  19. HMODULE ghModule;
  20. CWMIEvent * g_pBinaryMofEvent = NULL;
  21. CCriticalSection * g_pEventCs = NULL; // Shared between all CWMIEvent instances to protect the global list
  22. CCriticalSection * g_pSharedLocalEventsCs = NULL;
  23. CCriticalSection * g_pListCs = NULL;
  24. //Count number of objects and number of locks.
  25. long g_cObj=0;
  26. long g_cLock=0;
  27. /////////////////////////////////////////////////////////////////////////////////////////////////
  28. //
  29. // LibMain32
  30. //
  31. // Purpose: Entry point for DLL. Good place for initialization.
  32. // Return: TRUE if OK.
  33. //
  34. /////////////////////////////////////////////////////////////////////////////////////////////////
  35. BOOL WINAPI DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
  36. {
  37. SetStructuredExceptionHandler seh;
  38. BOOL fRc = TRUE;
  39. try
  40. {
  41. switch( ulReason )
  42. {
  43. case DLL_PROCESS_DETACH:
  44. if( g_pListCs )
  45. {
  46. g_pListCs->Delete();
  47. delete g_pListCs;
  48. g_pListCs = NULL;
  49. }
  50. if( g_pEventCs )
  51. {
  52. g_pEventCs->Delete();
  53. delete g_pEventCs;
  54. g_pEventCs = NULL;
  55. }
  56. if( g_pSharedLocalEventsCs )
  57. {
  58. g_pSharedLocalEventsCs->Delete();
  59. delete g_pSharedLocalEventsCs;
  60. g_pSharedLocalEventsCs = NULL;
  61. }
  62. break;
  63. case DLL_PROCESS_ATTACH:
  64. g_pSharedLocalEventsCs = new CCriticalSection();
  65. if( g_pSharedLocalEventsCs )
  66. {
  67. g_pSharedLocalEventsCs->Init();
  68. g_pEventCs = new CCriticalSection();
  69. if( g_pEventCs )
  70. {
  71. g_pEventCs->Init();
  72. g_pListCs = new CCriticalSection();
  73. if( g_pListCs )
  74. {
  75. g_pListCs->Init();
  76. }
  77. else
  78. {
  79. fRc = FALSE;
  80. }
  81. }
  82. else
  83. {
  84. fRc = FALSE;
  85. }
  86. }
  87. else
  88. {
  89. fRc = FALSE;
  90. }
  91. ghModule = hInstance;
  92. if (!DisableThreadLibraryCalls(ghModule))
  93. {
  94. TranslateAndLog( L"DisableThreadLibraryCalls failed" );
  95. }
  96. break;
  97. }
  98. }
  99. catch(Structured_Exception e_SE)
  100. {
  101. fRc = FALSE;
  102. }
  103. catch(Heap_Exception e_HE)
  104. {
  105. fRc = FALSE;
  106. }
  107. catch(...)
  108. {
  109. fRc = FALSE;
  110. }
  111. return fRc;
  112. }
  113. /////////////////////////////////////////////////////////////////////////////////////////////////
  114. //
  115. // DllGetClassObject
  116. //
  117. // Purpose: Called by Ole when some client wants a a class factory. Return
  118. // one only if it is the sort of class this DLL supports.
  119. //
  120. /////////////////////////////////////////////////////////////////////////////////////////////////
  121. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv)
  122. {
  123. HRESULT hr = CLASS_E_CLASSNOTAVAILABLE ;
  124. CProvFactory *pFactory = NULL;
  125. SetStructuredExceptionHandler seh;
  126. try
  127. {
  128. //============================================================================
  129. // Verify the caller is asking for our type of object.
  130. //============================================================================
  131. if((CLSID_WMIProvider != rclsid) && (CLSID_WMIEventProvider != rclsid) && (CLSID_WMIHiPerfProvider != rclsid) )
  132. {
  133. hr = E_FAIL;
  134. }
  135. else{
  136. //============================================================================
  137. // Check that we can provide the interface.
  138. //============================================================================
  139. if (IID_IUnknown != riid && IID_IClassFactory != riid)
  140. {
  141. hr = E_NOINTERFACE;
  142. }
  143. else{
  144. //============================================================================
  145. // Get a new class factory.
  146. //============================================================================
  147. try
  148. {
  149. hr = S_OK;
  150. pFactory=new CProvFactory(rclsid);
  151. if (NULL==pFactory)
  152. {
  153. hr = E_OUTOFMEMORY;
  154. }
  155. }
  156. catch(...)
  157. {
  158. hr = WBEM_E_UNEXPECTED;
  159. }
  160. //============================================================================
  161. // Verify we can get an instance.
  162. //============================================================================
  163. if( SUCCEEDED(hr))
  164. {
  165. hr = pFactory->QueryInterface(riid, ppv);
  166. if (FAILED(hr))
  167. {
  168. SAFE_DELETE_PTR(pFactory);
  169. }
  170. else
  171. {
  172. // If this is the first object created then call
  173. // SetupLocalEvents to register for WMI events
  174. if(g_cObj == 1)
  175. {
  176. if(FAILED(hr = SetupLocalEvents()))
  177. {
  178. SAFE_DELETE_PTR(pFactory);
  179. }
  180. }
  181. }
  182. }
  183. }
  184. }
  185. }
  186. STANDARD_CATCH
  187. return hr;
  188. }
  189. /////////////////////////////////////////////////////////////////////////////////////////////////
  190. //
  191. // DllCanUnloadNow
  192. //
  193. // Purpose: Called periodically by Ole in order to determine if the
  194. // DLL can be freed.//
  195. // Return: TRUE if there are no objects in use and the class factory
  196. // isn't locked.
  197. /////////////////////////////////////////////////////////////////////////////////////////////////
  198. STDAPI DllCanUnloadNow(void)
  199. {
  200. SCODE sc = S_FALSE;
  201. //============================================================================
  202. // It is OK to unload if there are no objects or locks on the
  203. // class factory.
  204. //============================================================================
  205. if (0L==g_cObj && 0L==g_cLock)
  206. {
  207. sc = S_OK;
  208. DeleteLocalEvents();
  209. glInits = -1;
  210. }
  211. return sc;
  212. }
  213. // Convert the given string to TCHAR string
  214. void ConvertToTCHAR(WCHAR *pStrIn , TCHAR *& pOut)
  215. {
  216. CAnsiUnicode XLate;
  217. #ifndef UNICODE
  218. XLate.UnicodeToAnsi(pStrIn,pOut);
  219. #else
  220. pOut = pStrIn;
  221. #endif
  222. }
  223. // Delete the string if allocated. Memory is
  224. // allocated only if the system ANSI
  225. void SafeDeleteTStr(TCHAR *& pStr)
  226. {
  227. #ifndef UNICODE
  228. SAFE_DELETE_ARRAY(pStr);
  229. #else
  230. pStr = NULL;
  231. #endif
  232. }
  233. /////////////////////////////////////////////////////////////////////////////////////////////////
  234. //
  235. // CreateKey
  236. //
  237. // Purpose: Function to create a key
  238. //
  239. // Return: NOERROR if registration successful, error otherwise.
  240. //
  241. /////////////////////////////////////////////////////////////////////////////////////////////////
  242. HRESULT CreateKey(TCHAR * szCLSID, TCHAR * szName)
  243. {
  244. HKEY hKey1, hKey2;
  245. HRESULT hr = S_OK;
  246. #ifdef LOCALSERVER
  247. HKEY hKey;
  248. TCHAR szProviderCLSIDAppID[128];
  249. _stprintf(szProviderCLSIDAppID, _T("SOFTWARE\\CLASSES\\APPID\\%s"),szName);
  250. hr = RegCreateKey(HKEY_LOCAL_MACHINE, szProviderCLSIDAppID, &hKey);
  251. if( ERROR_SUCCESS == hr )
  252. {
  253. RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)szName, (_tcsclen(szName) + 1) * sizeof(TCHAR));
  254. CloseHandle(hKey);
  255. }
  256. #endif
  257. if( ERROR_SUCCESS == hr )
  258. {
  259. hr = RegCreateKey(HKEY_CLASSES_ROOT, szCLSID, &hKey1);
  260. if( ERROR_SUCCESS == hr )
  261. {
  262. DWORD dwLen;
  263. dwLen = (_tcsclen(szName)+1) * sizeof(TCHAR);
  264. hr = RegSetValueEx(hKey1, NULL, 0, REG_SZ, (CONST BYTE *)szName, dwLen);
  265. if( ERROR_SUCCESS == hr )
  266. {
  267. #ifdef LOCALSERVER
  268. hr = RegCreateKey(hKey1, _T("LocalServer32"), &hKey2);
  269. #else
  270. hr = RegCreateKey(hKey1, _T("InprocServer32"), &hKey2);
  271. #endif
  272. if( ERROR_SUCCESS == hr )
  273. {
  274. TCHAR szModule[MAX_PATH];
  275. GetModuleFileName(ghModule, szModule, MAX_PATH);
  276. dwLen = (_tcsclen(szModule)+1) * sizeof(TCHAR);
  277. hr = RegSetValueEx(hKey2, NULL, 0, REG_SZ, (CONST BYTE *)szModule, dwLen );
  278. if( ERROR_SUCCESS == hr )
  279. {
  280. dwLen = (_tcsclen(_T("Both"))+1) * sizeof(TCHAR);
  281. hr = RegSetValueEx(hKey2, _T("ThreadingModel"), 0, REG_SZ,(CONST BYTE *)_T("Both"), dwLen);
  282. }
  283. CloseHandle(hKey2);
  284. }
  285. }
  286. CloseHandle(hKey1);
  287. }
  288. }
  289. return hr;
  290. }
  291. /////////////////////////////////////////////////////////////////////////////////////////////////
  292. STDAPI DllRegisterServer(void)
  293. {
  294. WCHAR wcID[128];
  295. TCHAR * pID = NULL;
  296. TCHAR szCLSID[128];
  297. HRESULT hr = WBEM_E_FAILED;
  298. SetStructuredExceptionHandler seh;
  299. try{
  300. //==============================================
  301. // Create keys for WDM Instance Provider.
  302. //==============================================
  303. StringFromGUID2(CLSID_WMIProvider, wcID, 128);
  304. ConvertToTCHAR(wcID,pID);
  305. if( pID )
  306. {
  307. _stprintf(szCLSID, _T("CLSID\\%s"),pID);
  308. SafeDeleteTStr(pID);
  309. hr = CreateKey(szCLSID,_T("WDM Instance Provider"));
  310. if( ERROR_SUCCESS == hr )
  311. {
  312. //==============================================
  313. // Create keys for WDM Event Provider.
  314. //==============================================
  315. StringFromGUID2(CLSID_WMIEventProvider, wcID, 128);
  316. ConvertToTCHAR(wcID,pID);
  317. if( pID )
  318. {
  319. _stprintf(szCLSID,_T("CLSID\\%s"),pID);
  320. SafeDeleteTStr(pID);
  321. hr = CreateKey(szCLSID,_T("WDM Event Provider"));
  322. if( ERROR_SUCCESS == hr )
  323. {
  324. //==============================================
  325. // Create keys for WDM Event Provider.
  326. //==============================================
  327. StringFromGUID2(CLSID_WMIHiPerfProvider, wcID, 128);
  328. ConvertToTCHAR(wcID,pID);
  329. if( pID )
  330. {
  331. _stprintf(szCLSID,_T("CLSID\\%s"),pID);
  332. SafeDeleteTStr(pID);
  333. hr = CreateKey(szCLSID,_T("WDM HiPerf Provider"));
  334. }
  335. }
  336. }
  337. }
  338. }
  339. }
  340. STANDARD_CATCH
  341. return hr;
  342. }
  343. /////////////////////////////////////////////////////////////////////////////////////
  344. //
  345. // DeleteKey
  346. //
  347. // Purpose: Called when it is time to remove the registry entries.
  348. //
  349. // Return: NOERROR if registration successful, error otherwise.
  350. //
  351. /////////////////////////////////////////////////////////////////////////////////////
  352. HRESULT DeleteKey(TCHAR * pCLSID, TCHAR * pID)
  353. {
  354. HKEY hKey;
  355. HRESULT hr = S_OK;
  356. #ifdef LOCALSERVER
  357. TCHAR szTmp[MAX_PATH];
  358. _stprintf(szTmp, _T("SOFTWARE\\CLASSES\\APPID\\%s"),pID);
  359. //Delete entries under APPID
  360. hr = RegDeleteKey(HKEY_LOCAL_MACHINE, szTmp);
  361. if( ERROR_SUCCESS == hr )
  362. {
  363. _stprintf(szTemp,_T("%s\\LocalServer32"),pCLSID);
  364. hr = RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  365. }
  366. #endif
  367. hr = RegOpenKey(HKEY_CLASSES_ROOT, pCLSID, &hKey);
  368. if(NO_ERROR == hr)
  369. {
  370. hr = RegDeleteKey(hKey,_T("InprocServer32"));
  371. CloseHandle(hKey);
  372. }
  373. hr = RegOpenKey(HKEY_CLASSES_ROOT, _T("CLSID"), &hKey);
  374. if(NO_ERROR == hr)
  375. {
  376. hr = RegDeleteKey(hKey,pID);
  377. CloseHandle(hKey);
  378. }
  379. return hr;
  380. }
  381. /////////////////////////////////////////////////////////////////////
  382. STDAPI DllUnregisterServer(void)
  383. {
  384. WCHAR wcID[128];
  385. TCHAR * pId = NULL;
  386. TCHAR strCLSID[MAX_PATH];
  387. HRESULT hr = WBEM_E_FAILED;
  388. try
  389. {
  390. //===============================================
  391. // Delete the WMI Instance Provider
  392. //===============================================
  393. StringFromGUID2(CLSID_WMIProvider, wcID, 128);
  394. ConvertToTCHAR(wcID , pId);
  395. _stprintf(strCLSID, _T("CLSID\\%s"),pId);
  396. hr = DeleteKey(strCLSID, pId);
  397. SafeDeleteTStr(pId);
  398. if( ERROR_SUCCESS == hr )
  399. {
  400. //==========================================
  401. // Delete the WMI Event Provider
  402. //==========================================
  403. StringFromGUID2(CLSID_WMIEventProvider, wcID, 128);
  404. ConvertToTCHAR(wcID , pId);
  405. _stprintf(strCLSID, _T("CLSID\\%s"),pId);
  406. hr = DeleteKey(strCLSID,pId);
  407. SafeDeleteTStr(pId);
  408. if( ERROR_SUCCESS == hr )
  409. {
  410. //==========================================
  411. // Delete the WMI Event Provider
  412. //==========================================
  413. StringFromGUID2(CLSID_WMIHiPerfProvider, wcID, 128);
  414. ConvertToTCHAR(wcID , pId);
  415. _stprintf(strCLSID, _T("CLSID\\%s"),pId);
  416. hr = DeleteKey(strCLSID,pId);
  417. SafeDeleteTStr(pId);
  418. }
  419. }
  420. }
  421. STANDARD_CATCH
  422. return hr;
  423. }