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.

636 lines
16 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-2002 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. #include <strsafe.h>
  20. HMODULE ghModule;
  21. CWMIEvent * g_pBinaryMofEvent = NULL;
  22. CCriticalSection g_EventCs;
  23. CCriticalSection g_SharedLocalEventsCs;
  24. CCriticalSection g_ListCs;
  25. CCriticalSection g_LoadUnloadCs;
  26. CCriticalSection *g_pEventCs = &g_EventCs; // pointer for backward comp
  27. CCriticalSection *g_pSharedLocalEventsCs = &g_SharedLocalEventsCs; // pointer for backward comp
  28. CCriticalSection *g_pListCs = &g_ListCs; // pointer for backward comp
  29. CCriticalSection *g_pLoadUnloadCs = &g_LoadUnloadCs; // pointer for backward comp
  30. //Count number of objects and number of locks.
  31. long g_cObj=0;
  32. long g_cLock=0;
  33. long glInits = 0;
  34. long glProvObj = 0;
  35. long glEventsRegistered = 0;
  36. #include "wmiguard.h"
  37. WmiGuard * pGuard = NULL;
  38. /////////////////////////////////////////////////////////////////////////////////////////////////
  39. //
  40. // LibMain32
  41. //
  42. // Purpose: Entry point for DLL. Good place for initialization.
  43. // Return: TRUE if OK.
  44. //
  45. /////////////////////////////////////////////////////////////////////////////////////////////////
  46. BOOL WINAPI DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
  47. {
  48. SetStructuredExceptionHandler seh;
  49. BOOL fRc = TRUE;
  50. try
  51. {
  52. switch( ulReason )
  53. {
  54. case DLL_PROCESS_DETACH:
  55. {
  56. //
  57. // release binary mof changes worker
  58. //
  59. SAFE_DELETE_PTR(g_pBinaryMofEvent);
  60. if ( pGuard )
  61. {
  62. delete pGuard;
  63. pGuard = NULL;
  64. if( g_ListCs.IsValid() )
  65. {
  66. g_ListCs.Delete();
  67. }
  68. if( g_EventCs.IsValid() )
  69. {
  70. g_EventCs.Delete();
  71. }
  72. if( g_SharedLocalEventsCs.IsValid() )
  73. {
  74. g_SharedLocalEventsCs.Delete();
  75. }
  76. if( g_LoadUnloadCs.IsValid() )
  77. {
  78. g_LoadUnloadCs.Delete();
  79. }
  80. }
  81. }
  82. break;
  83. case DLL_PROCESS_ATTACH:
  84. {
  85. if ( ( pGuard = new WmiGuard ( ) ) == NULL )
  86. {
  87. fRc = FALSE;
  88. }
  89. else
  90. {
  91. g_LoadUnloadCs.Init();
  92. g_SharedLocalEventsCs.Init();
  93. g_EventCs.Init();
  94. g_ListCs.Init();
  95. fRc = ( g_LoadUnloadCs.IsValid() &&
  96. g_SharedLocalEventsCs.IsValid() &&
  97. g_EventCs.IsValid() &&
  98. g_ListCs.IsValid() ) ? TRUE : FALSE ;
  99. if ( fRc )
  100. {
  101. fRc = pGuard->Init ( g_pSharedLocalEventsCs );
  102. if ( fRc )
  103. {
  104. //
  105. // instantiate worker for driver's
  106. // classes addition and deletion
  107. //
  108. fRc = FALSE;
  109. HRESULT hr = WBEM_S_NO_ERROR ;
  110. try
  111. {
  112. g_pBinaryMofEvent = (CWMIEvent *)new CWMIEvent(INTERNAL_EVENT); // This is the global guy that catches events of new drivers being added at runtime.
  113. if(g_pBinaryMofEvent)
  114. {
  115. if ( g_pBinaryMofEvent->Initialized () )
  116. {
  117. fRc = TRUE ;
  118. }
  119. else
  120. {
  121. delete g_pBinaryMofEvent ;
  122. g_pBinaryMofEvent = NULL ;
  123. }
  124. }
  125. else
  126. {
  127. }
  128. }
  129. STANDARD_CATCH
  130. }
  131. }
  132. }
  133. ghModule = hInstance;
  134. if (!DisableThreadLibraryCalls(ghModule))
  135. {
  136. ERRORTRACE((THISPROVIDER, "DisableThreadLibraryCalls failed\n" ));
  137. }
  138. }
  139. break;
  140. }
  141. }
  142. catch(Structured_Exception e_SE)
  143. {
  144. fRc = FALSE;
  145. }
  146. catch(Heap_Exception e_HE)
  147. {
  148. fRc = FALSE;
  149. }
  150. catch(...)
  151. {
  152. fRc = FALSE;
  153. }
  154. return fRc;
  155. }
  156. /////////////////////////////////////////////////////////////////////////////////////////////////
  157. //
  158. // DllGetClassObject
  159. //
  160. // Purpose: Called by Ole when some client wants a a class factory. Return
  161. // one only if it is the sort of class this DLL supports.
  162. //
  163. /////////////////////////////////////////////////////////////////////////////////////////////////
  164. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv)
  165. {
  166. HRESULT hr = CLASS_E_CLASSNOTAVAILABLE ;
  167. CProvFactory *pFactory = NULL;
  168. SetStructuredExceptionHandler seh;
  169. try
  170. {
  171. //============================================================================
  172. // Verify the caller is asking for our type of object.
  173. //============================================================================
  174. if((CLSID_WMIProvider != rclsid) && (CLSID_WMIEventProvider != rclsid) && (CLSID_WMIHiPerfProvider != rclsid) )
  175. {
  176. hr = E_FAIL;
  177. }
  178. else
  179. {
  180. //============================================================================
  181. // Check that we can provide the interface.
  182. //============================================================================
  183. if (IID_IUnknown != riid && IID_IClassFactory != riid)
  184. {
  185. hr = E_NOINTERFACE;
  186. }
  187. else
  188. {
  189. CAutoBlock block (g_pLoadUnloadCs);
  190. //============================================================================
  191. // Get a new class factory.
  192. //============================================================================
  193. pFactory=new CProvFactory(rclsid);
  194. if (NULL!=pFactory)
  195. {
  196. //============================================================================
  197. // Verify we can get an instance.
  198. //============================================================================
  199. hr = pFactory->QueryInterface(riid, ppv);
  200. if ( FAILED ( hr ) )
  201. {
  202. SAFE_DELETE_PTR(pFactory);
  203. }
  204. else
  205. {
  206. //
  207. // it is safe to check if this is 1st object like this
  208. // as there is no way any provider or class factory is
  209. // incrementing global refrence count
  210. //
  211. if ( 1 == g_cObj )
  212. {
  213. //
  214. // GlobalInterfaceTable
  215. //
  216. hr = CoCreateInstance ( CLSID_StdGlobalInterfaceTable,
  217. NULL,
  218. CLSCTX_INPROC_SERVER,
  219. IID_IGlobalInterfaceTable,
  220. (void**)&g_pGIT
  221. );
  222. //
  223. // bail out every resource
  224. //
  225. if ( FAILED ( hr ) )
  226. {
  227. SAFE_DELETE_PTR(pFactory);
  228. SAFE_RELEASE_PTR(g_pGIT);
  229. }
  230. }
  231. }
  232. }
  233. }
  234. }
  235. }
  236. STANDARD_CATCH
  237. return hr;
  238. }
  239. /////////////////////////////////////////////////////////////////////////////////////////////////
  240. //
  241. // DllCanUnloadNow
  242. //
  243. // Purpose: Called periodically by Ole in order to determine if the
  244. // DLL can be freed.//
  245. // Return: TRUE if there are no objects in use and the class factory
  246. // isn't locked.
  247. /////////////////////////////////////////////////////////////////////////////////////////////////
  248. STDAPI DllCanUnloadNow(void)
  249. {
  250. HRESULT sc = S_FALSE ;
  251. try
  252. {
  253. CAutoBlock block (g_pLoadUnloadCs);
  254. //============================================================================
  255. // It is OK to unload if there are no objects or locks on the
  256. // class factory.
  257. //============================================================================
  258. if ( 0L == g_cObj && 0L == g_cLock )
  259. {
  260. sc = S_OK ;
  261. SAFE_RELEASE_PTR(g_pGIT);
  262. }
  263. }
  264. catch ( ... )
  265. {
  266. }
  267. return sc;
  268. }
  269. /////////////////////////////////////////////////////////////////////////////////////////////////
  270. //
  271. // CreateKey
  272. //
  273. // Purpose: Function to create a key
  274. //
  275. // Return: NOERROR if registration successful, error otherwise.
  276. //
  277. /////////////////////////////////////////////////////////////////////////////////////////////////
  278. HRESULT CreateKey(TCHAR * szCLSID, TCHAR * szName)
  279. {
  280. HKEY hKey1, hKey2;
  281. HRESULT hr = S_OK;
  282. #ifdef LOCALSERVER
  283. HKEY hKey;
  284. TCHAR szProviderCLSIDAppID[128];
  285. if ( SUCCEEDED ( hr = StringCchPrintf ( szProviderCLSIDAppID, 128, _T("SOFTWARE\\CLASSES\\APPID\\%s"), szName ) ) )
  286. {
  287. hr = RegCreateKeyEx (
  288. HKEY_LOCAL_MACHINE,
  289. szProviderCLSIDAppID,
  290. 0,
  291. NULL,
  292. REG_OPTION_NON_VOLATILE,
  293. KEY_ALL_ACCESS,
  294. NULL,
  295. &hKey,
  296. NULL
  297. );
  298. if( ERROR_SUCCESS == hr )
  299. {
  300. RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)szName, (_tcsclen(szName) + 1) * sizeof(TCHAR));
  301. CloseHandle(hKey);
  302. }
  303. else
  304. {
  305. hr = HRESULT_FROM_WIN32 ( hr );
  306. }
  307. }
  308. #endif
  309. if( S_OK == hr )
  310. {
  311. hr = RegCreateKeyEx (
  312. HKEY_CLASSES_ROOT,
  313. szCLSID,
  314. 0,
  315. NULL,
  316. REG_OPTION_NON_VOLATILE,
  317. KEY_ALL_ACCESS,
  318. NULL,
  319. &hKey1,
  320. NULL
  321. );
  322. if( ERROR_SUCCESS == hr )
  323. {
  324. DWORD dwLen;
  325. dwLen = (_tcsclen(szName)+1) * sizeof(TCHAR);
  326. hr = RegSetValueEx(hKey1, NULL, 0, REG_SZ, (CONST BYTE *)szName, dwLen);
  327. if( ERROR_SUCCESS == hr )
  328. {
  329. #ifdef LOCALSERVER
  330. hr = RegCreateKeyEx (
  331. hKey1,
  332. _T("LocalServer32"),
  333. 0,
  334. NULL,
  335. REG_OPTION_NON_VOLATILE,
  336. KEY_ALL_ACCESS,
  337. NULL,
  338. &hKey2,
  339. NULL
  340. );
  341. #else
  342. hr = RegCreateKeyEx (
  343. hKey1,
  344. _T("InprocServer32"),
  345. 0,
  346. NULL,
  347. REG_OPTION_NON_VOLATILE,
  348. KEY_ALL_ACCESS,
  349. NULL,
  350. &hKey2,
  351. NULL
  352. );
  353. #endif
  354. if( ERROR_SUCCESS == hr )
  355. {
  356. TCHAR szModule [MAX_PATH+1];
  357. szModule [MAX_PATH] = 0;
  358. if ( GetModuleFileName(ghModule, szModule, MAX_PATH) )
  359. {
  360. dwLen = (_tcsclen(szModule)+1) * sizeof(TCHAR);
  361. hr = RegSetValueEx(hKey2, NULL, 0, REG_SZ, (CONST BYTE *)szModule, dwLen );
  362. if( ERROR_SUCCESS == hr )
  363. {
  364. dwLen = (_tcsclen(_T("Both"))+1) * sizeof(TCHAR);
  365. hr = RegSetValueEx(hKey2, _T("ThreadingModel"), 0, REG_SZ,(CONST BYTE *)_T("Both"), dwLen);
  366. }
  367. else
  368. {
  369. hr = HRESULT_FROM_WIN32 ( hr );
  370. }
  371. }
  372. else
  373. {
  374. hr = HRESULT_FROM_WIN32 ( ::GetLastError () );
  375. }
  376. CloseHandle(hKey2);
  377. }
  378. else
  379. {
  380. hr = HRESULT_FROM_WIN32 ( hr );
  381. }
  382. }
  383. CloseHandle(hKey1);
  384. }
  385. else
  386. {
  387. hr = HRESULT_FROM_WIN32 ( hr );
  388. }
  389. }
  390. return hr;
  391. }
  392. /////////////////////////////////////////////////////////////////////////////////////////////////
  393. #ifdef _X86_
  394. BOOL IsReallyWOW64( void )
  395. {
  396. // Environment variable should only exist on WOW64
  397. return ( GetEnvironmentVariable( L"PROCESSOR_ARCHITEW6432", 0L, NULL ) != 0L );
  398. }
  399. #endif
  400. STDAPI DllRegisterServer(void)
  401. {
  402. WCHAR wcID[128];
  403. TCHAR szCLSID[128];
  404. HRESULT hr = WBEM_E_FAILED;
  405. SetStructuredExceptionHandler seh;
  406. try{
  407. #ifdef _X86
  408. if (!IsReallyWOW64())
  409. {
  410. // on 32-bit builds, we want to register everything if we are not really running in syswow64
  411. #endif
  412. //==============================================
  413. // Create keys for WDM Instance Provider.
  414. //==============================================
  415. StringFromGUID2(CLSID_WMIProvider, wcID, 128);
  416. StringCchPrintf(szCLSID, 128, _T("CLSID\\%s"), wcID);
  417. hr = CreateKey(szCLSID,_T("WDM Instance Provider"));
  418. if( ERROR_SUCCESS == hr )
  419. {
  420. //==============================================
  421. // Create keys for WDM Event Provider.
  422. //==============================================
  423. StringFromGUID2(CLSID_WMIEventProvider, wcID, 128);
  424. StringCchPrintf(szCLSID, 128, _T("CLSID\\%s"), wcID);
  425. hr = CreateKey(szCLSID,_T("WDM Event Provider"));
  426. if( ERROR_SUCCESS == hr )
  427. {
  428. //==============================================
  429. // Create keys for WDM HiPerf Provider.
  430. //==============================================
  431. StringFromGUID2(CLSID_WMIHiPerfProvider, wcID, 128);
  432. StringCchPrintf(szCLSID, 128, _T("CLSID\\%s"), wcID);
  433. hr = CreateKey(szCLSID,_T("WDM HiPerf Provider"));
  434. }
  435. }
  436. #ifdef _X86
  437. }
  438. else
  439. {
  440. // on 32-bit builds, we want to register only the HiPerf Provider if we are really running in syswow64
  441. //==============================================
  442. // Create keys for WDM HiPerf Provider.
  443. //==============================================
  444. StringFromGUID2(CLSID_WMIHiPerfProvider, wcID, 128);
  445. StringCchPrintf(szCLSID, 128, _T("CLSID\\%s"), wcID);
  446. hr = CreateKey(szCLSID,_T("WDM HiPerf Provider"));
  447. }
  448. #endif
  449. }
  450. STANDARD_CATCH
  451. return hr;
  452. }
  453. /////////////////////////////////////////////////////////////////////////////////////
  454. //
  455. // DeleteKey
  456. //
  457. // Purpose: Called when it is time to remove the registry entries.
  458. //
  459. // Return: NOERROR if registration successful, error otherwise.
  460. //
  461. /////////////////////////////////////////////////////////////////////////////////////
  462. HRESULT DeleteKey(TCHAR * pCLSID, TCHAR * pID)
  463. {
  464. HKEY hKey;
  465. HRESULT hr = S_OK;
  466. #ifdef LOCALSERVER
  467. TCHAR szTmp[MAX_PATH];
  468. StringCchPrintf(szTmp, MAX_PATH, _T("SOFTWARE\\CLASSES\\APPID\\%s"), pID);
  469. //Delete entries under APPID
  470. hr = RegDeleteKey(HKEY_LOCAL_MACHINE, szTmp);
  471. if( ERROR_SUCCESS == hr )
  472. {
  473. StringCchPrintf(szTmp, MAX_PATH, _T("%s\\LocalServer32"), pCLSID);
  474. hr = RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  475. }
  476. #endif
  477. hr = RegOpenKey(HKEY_CLASSES_ROOT, pCLSID, &hKey);
  478. if(NO_ERROR == hr)
  479. {
  480. hr = RegDeleteKey(hKey,_T("InprocServer32"));
  481. CloseHandle(hKey);
  482. }
  483. hr = RegOpenKey(HKEY_CLASSES_ROOT, _T("CLSID"), &hKey);
  484. if(NO_ERROR == hr)
  485. {
  486. hr = RegDeleteKey(hKey,pID);
  487. CloseHandle(hKey);
  488. }
  489. return hr;
  490. }
  491. /////////////////////////////////////////////////////////////////////
  492. STDAPI DllUnregisterServer(void)
  493. {
  494. WCHAR wcID[128];
  495. TCHAR strCLSID[MAX_PATH];
  496. HRESULT hr = WBEM_E_FAILED;
  497. try
  498. {
  499. #ifdef _X86
  500. if (!IsReallyWOW64())
  501. {
  502. // on 32-bit builds, we want to unregister everything if we are not really running in syswow64
  503. #endif
  504. //===============================================
  505. // Delete the WMI Instance Provider
  506. //===============================================
  507. StringFromGUID2(CLSID_WMIProvider, wcID, 128);
  508. StringCchPrintf(strCLSID, MAX_PATH, _T("CLSID\\%s"), wcID);
  509. hr = DeleteKey(strCLSID, wcID);
  510. if( ERROR_SUCCESS == hr )
  511. {
  512. //==========================================
  513. // Delete the WMI Event Provider
  514. //==========================================
  515. StringFromGUID2(CLSID_WMIEventProvider, wcID, 128);
  516. StringCchPrintf(strCLSID, MAX_PATH, _T("CLSID\\%s"), wcID);
  517. hr = DeleteKey(strCLSID,wcID);
  518. if( ERROR_SUCCESS == hr )
  519. {
  520. //==========================================
  521. // Delete the WMI HiPerf Provider
  522. //==========================================
  523. StringFromGUID2(CLSID_WMIHiPerfProvider, wcID, 128);
  524. StringCchPrintf(strCLSID, MAX_PATH, _T("CLSID\\%s"), wcID);
  525. hr = DeleteKey(strCLSID,wcID);
  526. }
  527. }
  528. #ifdef _X86
  529. }
  530. else
  531. {
  532. // on 32-bit builds, we need to unregister only the HiPerf provider if we are really running in syswow64
  533. //==========================================
  534. // Delete the WMI HiPerf Provider
  535. //==========================================
  536. StringFromGUID2(CLSID_WMIHiPerfProvider, wcID, 128);
  537. StringCchPrintf(strCLSID, MAX_PATH, _T("CLSID\\%s"), wcID);
  538. hr = DeleteKey(strCLSID,wcID);
  539. }
  540. #endif
  541. }
  542. STANDARD_CATCH
  543. return hr;
  544. }