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.

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