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.

484 lines
14 KiB

  1. //
  2. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  3. //
  4. // ***************************************************************************
  5. //
  6. // Original Author: Rajesh Rao
  7. //
  8. // $Author: rajeshr $
  9. // $Date: 6/11/98 4:43p $
  10. // $Workfile: maindll.cpp $
  11. //
  12. // $Modtime: 6/11/98 11:21a $
  13. // $Revision: 1 $
  14. // $Nokeywords: $
  15. //
  16. //
  17. // Description: Contains DLL entry points. Also has code that controls
  18. // when the DLL can be unloaded by tracking the number of objects and locks.
  19. //
  20. //***************************************************************************
  21. #include "precomp.h"
  22. #include <initguid.h>
  23. #include "dscpguid.h"
  24. #include "dsipguid.h"
  25. // HANDLE of the DLL
  26. HINSTANCE g_hInst = NULL;
  27. // Count of locks
  28. long g_lComponents = 0;
  29. // Count of active locks
  30. long g_lServerLocks = 0;
  31. // A critical section to create/delete statics
  32. CRITICAL_SECTION g_StaticsCreationDeletion;
  33. ProvDebugLog *g_pLogObject = NULL;
  34. //***************************************************************************
  35. //
  36. // DllMain
  37. //
  38. // Description: Entry point for DLL. Good place for initialization.
  39. // Parameters: The standard DllMain() parameters
  40. // Return: TRUE if OK.
  41. //***************************************************************************
  42. BOOL APIENTRY DllMain (
  43. HINSTANCE hInstance,
  44. ULONG ulReason ,
  45. LPVOID pvReserved
  46. )
  47. {
  48. g_hInst = hInstance;
  49. BOOL status = TRUE ;
  50. if ( DLL_PROCESS_ATTACH == ulReason )
  51. {
  52. // Initialize the critical section to access the static initializer objects
  53. InitializeCriticalSection(&g_StaticsCreationDeletion);
  54. // Initialize the static Initializer objects. These are destroyed in DllCanUnloadNow
  55. CDSClassProviderClassFactory :: s_pDSClassProviderInitializer = NULL;
  56. CDSClassProviderClassFactory ::s_pLDAPClassProviderInitializer = NULL;
  57. CDSInstanceProviderClassFactory :: s_pDSInstanceProviderInitializer = NULL;
  58. DisableThreadLibraryCalls(g_hInst); // 158024
  59. status = TRUE ;
  60. }
  61. else if ( DLL_PROCESS_DETACH == ulReason )
  62. {
  63. DeleteCriticalSection(&g_StaticsCreationDeletion);
  64. status = TRUE ;
  65. }
  66. else if ( DLL_THREAD_DETACH == ulReason )
  67. {
  68. status = TRUE ;
  69. }
  70. else if ( DLL_THREAD_ATTACH == ulReason )
  71. {
  72. status = TRUE ;
  73. }
  74. return status ;
  75. }
  76. //***************************************************************************
  77. //
  78. // DllGetClassObject
  79. //
  80. // Description: Called by COM when some client wants a a class factory.
  81. //
  82. // Parameters: Ths standard DllGetClassObject() parameters
  83. //
  84. // Return Value: S_OK only if it is the sort of class this DLL supports.
  85. //
  86. //***************************************************************************
  87. STDAPI DllGetClassObject (
  88. REFCLSID rclsid ,
  89. REFIID riid,
  90. void **ppv
  91. )
  92. {
  93. HRESULT status = S_OK ;
  94. try
  95. {
  96. if ( rclsid == CLSID_DSProvider )
  97. {
  98. CDSClassProviderClassFactory *lpunk = NULL;
  99. lpunk = new CDSClassProviderClassFactory ;
  100. status = lpunk->QueryInterface ( riid , ppv ) ;
  101. if ( FAILED ( status ) )
  102. {
  103. delete lpunk ;
  104. }
  105. }
  106. else if ( rclsid == CLSID_DSClassAssocProvider )
  107. {
  108. CDSClassAssociationsProviderClassFactory *lpunk = new CDSClassAssociationsProviderClassFactory ;
  109. status = lpunk->QueryInterface ( riid , ppv ) ;
  110. if ( FAILED ( status ) )
  111. {
  112. delete lpunk ;
  113. }
  114. }
  115. else if ( rclsid == CLSID_DSInstanceProvider )
  116. {
  117. CDSInstanceProviderClassFactory *lpunk = new CDSInstanceProviderClassFactory ;
  118. status = lpunk->QueryInterface ( riid , ppv ) ;
  119. if ( FAILED ( status ) )
  120. {
  121. delete lpunk ;
  122. }
  123. }
  124. else
  125. {
  126. status = CLASS_E_CLASSNOTAVAILABLE ;
  127. }
  128. }
  129. catch(Heap_Exception e_HE)
  130. {
  131. status = E_OUTOFMEMORY ;
  132. }
  133. return status ;
  134. }
  135. //***************************************************************************
  136. //
  137. // DllCanUnloadNow
  138. //
  139. // Description: Called periodically by COM in order to determine if the
  140. // DLL can be unloaded.
  141. //
  142. // Return Value: S_OK if there are no objects in use and the class factory
  143. // isn't locked.
  144. //***************************************************************************
  145. STDAPI DllCanUnloadNow ()
  146. {
  147. if(g_lServerLocks == 0 && g_lComponents == 0)
  148. {
  149. // Delete the Initializer objects
  150. EnterCriticalSection(&g_StaticsCreationDeletion);
  151. if ( g_pLogObject )
  152. {
  153. g_pLogObject->WriteW(L"DllCanUnloadNow called\r\n");
  154. }
  155. if ( CDSClassProviderClassFactory::s_pDSClassProviderInitializer )
  156. {
  157. delete CDSClassProviderClassFactory::s_pDSClassProviderInitializer;
  158. CDSClassProviderClassFactory::s_pDSClassProviderInitializer = NULL;
  159. }
  160. if ( CDSClassProviderClassFactory::s_pLDAPClassProviderInitializer )
  161. {
  162. delete CDSClassProviderClassFactory::s_pLDAPClassProviderInitializer;
  163. CDSClassProviderClassFactory::s_pLDAPClassProviderInitializer = NULL;
  164. }
  165. if ( CDSInstanceProviderClassFactory::s_pDSInstanceProviderInitializer )
  166. {
  167. delete CDSInstanceProviderClassFactory::s_pDSInstanceProviderInitializer;
  168. CDSInstanceProviderClassFactory::s_pDSInstanceProviderInitializer = NULL;
  169. }
  170. if ( g_pLogObject )
  171. {
  172. delete g_pLogObject;
  173. g_pLogObject = NULL;
  174. }
  175. LeaveCriticalSection(&g_StaticsCreationDeletion);
  176. return S_OK;
  177. }
  178. else
  179. return S_FALSE;
  180. }
  181. /***************************************************************************
  182. *
  183. * SetKeyAndValue
  184. *
  185. * Description: Helper function for DllRegisterServer that creates
  186. * a key, sets a value, and closes that key. If pszSubkey is NULL, then
  187. * the value is created for the pszKey key.
  188. *
  189. * Parameters:
  190. * pszKey LPTSTR to the name of the key
  191. * pszSubkey LPTSTR to the name of a subkey
  192. * pszValueName LPTSTR to the value name to use
  193. * pszValue LPTSTR to the value to store
  194. *
  195. * Return Value:
  196. * BOOL TRUE if successful, FALSE otherwise.
  197. ***************************************************************************/
  198. BOOL SetKeyAndValue(LPCTSTR pszKey, LPCTSTR pszSubkey, LPCTSTR pszValueName, LPCTSTR pszValue)
  199. {
  200. HKEY hKey;
  201. TCHAR szKey[256];
  202. _tcscpy(szKey, pszKey);
  203. // If a sub key is mentioned, use it.
  204. if (NULL != pszSubkey)
  205. {
  206. _tcscat(szKey, __TEXT("\\"));
  207. _tcscat(szKey, pszSubkey);
  208. }
  209. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  210. szKey, 0, NULL, REG_OPTION_NON_VOLATILE,
  211. KEY_ALL_ACCESS, NULL, &hKey, NULL))
  212. return FALSE;
  213. if (NULL != pszValue)
  214. {
  215. if (ERROR_SUCCESS != RegSetValueEx(hKey, pszValueName, 0, REG_SZ, (BYTE *)pszValue,
  216. (_tcslen(pszValue)+1)*sizeof(TCHAR)))
  217. return FALSE;
  218. }
  219. RegCloseKey(hKey);
  220. return TRUE;
  221. }
  222. /***************************************************************************
  223. *
  224. * DeleteKey
  225. *
  226. * Description: Helper function for DllUnRegisterServer that deletes the subkey
  227. * of a key.
  228. *
  229. * Parameters:
  230. * pszKey LPTSTR to the name of the key
  231. * pszSubkey LPTSTR ro the name of a subkey
  232. *
  233. * Return Value:
  234. * BOOL TRUE if successful, FALSE otherwise.
  235. ***************************************************************************/
  236. BOOL DeleteKey(LPCTSTR pszKey, LPCTSTR pszSubkey)
  237. {
  238. HKEY hKey;
  239. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  240. pszKey, 0, NULL, REG_OPTION_NON_VOLATILE,
  241. KEY_ALL_ACCESS, NULL, &hKey, NULL))
  242. return FALSE;
  243. if(ERROR_SUCCESS != RegDeleteKey(hKey, pszSubkey))
  244. return FALSE;
  245. RegCloseKey(hKey);
  246. return TRUE;
  247. }
  248. ////////////////////////////////////////////////////////////////////
  249. // Strings used during self registration
  250. ////////////////////////////////////////////////////////////////////
  251. LPCTSTR INPROC32_STR = __TEXT("InprocServer32");
  252. LPCTSTR INPROC_STR = __TEXT("InprocServer");
  253. LPCTSTR THREADING_MODEL_STR = __TEXT("ThreadingModel");
  254. LPCTSTR APARTMENT_STR = __TEXT("Both");
  255. LPCTSTR CLSID_STR = __TEXT("SOFTWARE\\CLASSES\\CLSID\\");
  256. // DS Class Provider
  257. LPCTSTR DSPROVIDER_NAME_STR = __TEXT("Microsoft NT DS Class Provider for WBEM");
  258. // DS Class Associations provider
  259. LPCTSTR DS_ASSOC_PROVIDER_NAME_STR = __TEXT("Microsoft NT DS Class Associations Provider for WBEM");
  260. // DS Instance provider
  261. LPCTSTR DS_INSTANCE_PROVIDER_NAME_STR = __TEXT("Microsoft NT DS Instance Provider for WBEM");
  262. STDAPI DllRegisterServer()
  263. {
  264. TCHAR szModule[512];
  265. GetModuleFileName(g_hInst, szModule, sizeof(szModule)/sizeof(TCHAR));
  266. TCHAR szDSProviderClassID[128];
  267. TCHAR szDSProviderCLSIDClassID[128];
  268. #ifdef UNICODE
  269. if(StringFromGUID2(CLSID_DSProvider, szDSProviderClassID, 128) == 0)
  270. return SELFREG_E_CLASS;
  271. #else
  272. WCHAR wszDSProviderClassID[128];
  273. if(StringFromGUID2(CLSID_DSProvider, wszDSProviderClassID, 128) == 0)
  274. return SELFREG_E_CLASS;
  275. WideCharToMultiByte(CP_ACP, 0, wszDSProviderClassID, -1, szDSProviderClassID, 128, NULL, NULL);
  276. #endif
  277. _tcscpy(szDSProviderCLSIDClassID, CLSID_STR);
  278. _tcscat(szDSProviderCLSIDClassID, szDSProviderClassID);
  279. //
  280. // Create entries under CLSID for DS Class Provider
  281. //
  282. if (FALSE == SetKeyAndValue(szDSProviderCLSIDClassID, NULL, NULL, DSPROVIDER_NAME_STR))
  283. return SELFREG_E_CLASS;
  284. if (FALSE == SetKeyAndValue(szDSProviderCLSIDClassID, INPROC32_STR, NULL, szModule))
  285. return SELFREG_E_CLASS;
  286. if (FALSE == SetKeyAndValue(szDSProviderCLSIDClassID, INPROC32_STR, THREADING_MODEL_STR, APARTMENT_STR))
  287. return SELFREG_E_CLASS;
  288. TCHAR szDSClassAssocProviderClassID[128];
  289. TCHAR szDSClassAssocProviderCLSIDClassID[128];
  290. #ifdef UNICODE
  291. if(StringFromGUID2(CLSID_DSClassAssocProvider, szDSClassAssocProviderClassID, 128) == 0)
  292. return SELFREG_E_CLASS;
  293. #else
  294. WCHAR wszDSClassAssocProviderClassID[128];
  295. if(StringFromGUID2(CLSID_DSClassAssocProvider, wszDSClassAssocProviderClassID, 128) == 0)
  296. return SELFREG_E_CLASS;
  297. WideCharToMultiByte(CP_ACP, 0, wszDSClassAssocProviderClassID, -1, szDSClassAssocProviderClassID, 128, NULL, NULL);
  298. #endif
  299. _tcscpy(szDSClassAssocProviderCLSIDClassID, CLSID_STR);
  300. _tcscat(szDSClassAssocProviderCLSIDClassID, szDSClassAssocProviderClassID);
  301. //
  302. // Create entries under CLSID for DS Class Associations Provider
  303. //
  304. if (FALSE == SetKeyAndValue(szDSClassAssocProviderCLSIDClassID, NULL, NULL, DS_ASSOC_PROVIDER_NAME_STR))
  305. return SELFREG_E_CLASS;
  306. if (FALSE == SetKeyAndValue(szDSClassAssocProviderCLSIDClassID, INPROC32_STR, NULL, szModule))
  307. return SELFREG_E_CLASS;
  308. if (FALSE == SetKeyAndValue(szDSClassAssocProviderCLSIDClassID, INPROC32_STR, THREADING_MODEL_STR, APARTMENT_STR))
  309. return SELFREG_E_CLASS;
  310. TCHAR szDSInstanceProviderClassID[128];
  311. TCHAR szDSInstanceProviderCLSIDClassID[128];
  312. #ifdef UNICODE
  313. if(StringFromGUID2(CLSID_DSInstanceProvider, szDSInstanceProviderClassID, 128) == 0)
  314. return SELFREG_E_CLASS;
  315. #else
  316. WCHAR wszDSInstanceProviderClassID[128];
  317. if(StringFromGUID2(CLSID_DSInstanceProvider, wszDSInstanceProviderClassID, 128) == 0)
  318. return SELFREG_E_CLASS;
  319. WideCharToMultiByte(CP_ACP, 0, wszDSInstanceProviderClassID, -1, szDSInstanceProviderClassID, 128, NULL, NULL);
  320. #endif
  321. _tcscpy(szDSInstanceProviderCLSIDClassID, CLSID_STR);
  322. _tcscat(szDSInstanceProviderCLSIDClassID, szDSInstanceProviderClassID);
  323. //
  324. // Create entries under CLSID for DS Instance Provider
  325. //
  326. if (FALSE == SetKeyAndValue(szDSInstanceProviderCLSIDClassID, NULL, NULL, DS_INSTANCE_PROVIDER_NAME_STR))
  327. return SELFREG_E_CLASS;
  328. if (FALSE == SetKeyAndValue(szDSInstanceProviderCLSIDClassID, INPROC32_STR, NULL, szModule))
  329. return SELFREG_E_CLASS;
  330. if (FALSE == SetKeyAndValue(szDSInstanceProviderCLSIDClassID, INPROC32_STR, THREADING_MODEL_STR, APARTMENT_STR))
  331. return SELFREG_E_CLASS;
  332. return S_OK;
  333. }
  334. STDAPI DllUnregisterServer(void)
  335. {
  336. TCHAR szModule[512];
  337. GetModuleFileName(g_hInst,szModule, sizeof(szModule)/sizeof(TCHAR));
  338. TCHAR szDSProviderClassID[128];
  339. TCHAR szDSProviderCLSIDClassID[128];
  340. #ifdef UNICODE
  341. if(StringFromGUID2(CLSID_DSProvider, szDSProviderClassID, 128) == 0)
  342. return SELFREG_E_CLASS;
  343. #else
  344. WCHAR wszDSProviderClassID[128];
  345. if(StringFromGUID2(CLSID_DSProvider, wszDSProviderClassID, 128) == 0)
  346. return SELFREG_E_CLASS;
  347. WideCharToMultiByte(CP_ACP, 0, wszDSProviderClassID, -1, szDSProviderClassID, 128, NULL, NULL);
  348. #endif
  349. _tcscpy(szDSProviderCLSIDClassID, CLSID_STR);
  350. _tcscat(szDSProviderCLSIDClassID, szDSProviderClassID);
  351. //
  352. // Delete the keys for DS Class Provider in the reverse order of creation in DllRegisterServer()
  353. //
  354. if(FALSE == DeleteKey(szDSProviderCLSIDClassID, INPROC32_STR))
  355. return SELFREG_E_CLASS;
  356. if(FALSE == DeleteKey(CLSID_STR, szDSProviderClassID))
  357. return SELFREG_E_CLASS;
  358. TCHAR szDSClassAssocProviderClassID[128];
  359. TCHAR szDSClassAssocProviderCLSIDClassID[128];
  360. #ifdef UNICODE
  361. if(StringFromGUID2(CLSID_DSClassAssocProvider, szDSClassAssocProviderClassID, 128) == 0)
  362. return SELFREG_E_CLASS;
  363. #else
  364. WCHAR wszDSClassAssocProviderClassID[128];
  365. if(StringFromGUID2(CLSID_DSClassAssocProvider, wszDSClassAssocProviderClassID, 128) == 0)
  366. return SELFREG_E_CLASS;
  367. WideCharToMultiByte(CP_ACP, 0, wszDSClassAssocProviderClassID, -1, szDSClassAssocProviderClassID, 128, NULL, NULL);
  368. #endif
  369. _tcscpy(szDSClassAssocProviderCLSIDClassID, CLSID_STR);
  370. _tcscat(szDSClassAssocProviderCLSIDClassID, szDSClassAssocProviderClassID);
  371. //
  372. // Delete the keys for DS Class Provider in the reverse order of creation in DllRegisterServer()
  373. //
  374. if(FALSE == DeleteKey(szDSClassAssocProviderCLSIDClassID, INPROC32_STR))
  375. return SELFREG_E_CLASS;
  376. if(FALSE == DeleteKey(CLSID_STR, szDSClassAssocProviderClassID))
  377. return SELFREG_E_CLASS;
  378. TCHAR szDSInstanceProviderClassID[128];
  379. TCHAR szDSInstanceProviderCLSIDClassID[128];
  380. #ifdef UNICODE
  381. if(StringFromGUID2(CLSID_DSInstanceProvider, szDSInstanceProviderClassID, 128) == 0)
  382. return SELFREG_E_CLASS;
  383. #else
  384. WCHAR wszDSInstanceProviderClassID[128];
  385. if(StringFromGUID2(CLSID_DSInstanceProvider, wszDSInstanceProviderClassID, 128) == 0)
  386. return SELFREG_E_CLASS;
  387. WideCharToMultiByte(CP_ACP, 0, wszDSInstanceProviderClassID, -1, szDSInstanceProviderClassID, 128, NULL, NULL);
  388. #endif
  389. _tcscpy(szDSInstanceProviderCLSIDClassID, CLSID_STR);
  390. _tcscat(szDSInstanceProviderCLSIDClassID, szDSInstanceProviderClassID);
  391. //
  392. // Delete the keys in the reverse order of creation in DllRegisterServer()
  393. //
  394. if(FALSE == DeleteKey(szDSInstanceProviderCLSIDClassID, INPROC32_STR))
  395. return SELFREG_E_CLASS;
  396. if(FALSE == DeleteKey(CLSID_STR, szDSInstanceProviderClassID))
  397. return SELFREG_E_CLASS;
  398. return S_OK;
  399. }