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.

538 lines
15 KiB

  1. //***************************************************************************
  2. //
  3. // MAINDLL.CPP
  4. //
  5. // Module: WMI Framework Instance provider
  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) 2001 Microsoft Corp.
  13. //
  14. //***************************************************************************
  15. #include "stdafx.h"
  16. #include <FWcommon.h>
  17. #include <objbase.h>
  18. #include <initguid.h>
  19. #include <tchar.h>
  20. #include "trace.h"
  21. #include "sdwmi.h"
  22. HINSTANCE g_hInstance = NULL;
  23. #ifdef UNICODE
  24. #pragma message("Its unicode")
  25. #else
  26. #pragma message("Its ansi")
  27. #endif
  28. //============
  29. // {BF258E47-A172-498d-971A-DA30A3301E94}
  30. DEFINE_GUID(CLSID_CIM_WIN32_TSSESSIONDIRECTORYCLUSTER,
  31. 0xbf258e47, 0xa172, 0x498d, 0x97, 0x1a, 0xda, 0x30, 0xa3, 0x30, 0x1e, 0x94);
  32. // {f99a3c50-74fa-460a-8d75-db8ef2e3651d}
  33. DEFINE_GUID(CLSID_CIM_WIN32_TSSESSIONDIRECTORYSERVER,
  34. 0xf99a3c50, 0x74fa, 0x460a, 0x8d, 0x75, 0xdb, 0x8e, 0xf2, 0xe3, 0x65, 0x1d);
  35. // {b745b87b-cc4e-4361-8d29-221d936c259c}
  36. DEFINE_GUID(CLSID_CIM_WIN32_TSSESSIONDIRECTORYSESSION,
  37. 0xb745b87b, 0xcc4e, 0x4361, 0x8d, 0x29, 0x22, 0x1d, 0x93, 0x6c, 0x25, 0x9c);
  38. CRITICAL_SECTION g_critsect;
  39. CWin32_SessionDirectoryCluster* g_pSessionDirectoryClusterobj = NULL;
  40. CWin32_SessionDirectoryServer* g_pSessionDirectoryServerobj = NULL;
  41. CWin32_SessionDirectorySession* g_pSessionDirectorySessionobj = NULL;
  42. //Count number of objects and number of locks.
  43. long g_cLock=0;
  44. /***************************************************************************
  45. * SetKeyAndValue
  46. *
  47. * Purpose:
  48. * Private helper function for DllRegisterServer that creates
  49. * a key, sets a value, and closes that key.
  50. *
  51. * Parameters:
  52. * pszKey LPTSTR to the ame of the key
  53. * pszSubkey LPTSTR ro the name of a subkey
  54. * pszValue LPTSTR to the value to store
  55. *
  56. * Return Value:
  57. * BOOL TRUE if successful, FALSE otherwise.
  58. ***************************************************************************/
  59. BOOL SetKeyAndValue (
  60. wchar_t *pszKey,
  61. wchar_t *pszSubkey,
  62. wchar_t *pszValueName,
  63. wchar_t *pszValue
  64. )
  65. {
  66. HKEY hKey;
  67. TCHAR szKey[MAX_PATH+1];
  68. if(lstrlen(pszKey) > MAX_PATH)
  69. {
  70. return FALSE;
  71. }
  72. lstrcpy(szKey, pszKey);
  73. if (NULL!=pszSubkey && (lstrlen(pszKey)+lstrlen(pszSubkey)+1) <= MAX_PATH )
  74. {
  75. lstrcat(szKey, TEXT("\\"));
  76. lstrcat(szKey, pszSubkey);
  77. }
  78. if (ERROR_SUCCESS!=RegCreateKeyEx(HKEY_LOCAL_MACHINE
  79. , szKey, 0, NULL, REG_OPTION_NON_VOLATILE
  80. , KEY_ALL_ACCESS, NULL, &hKey, NULL))
  81. return FALSE;
  82. if (NULL!=pszValue)
  83. {
  84. if (ERROR_SUCCESS != RegSetValueEx(hKey, (LPCTSTR)pszValueName, 0, REG_SZ, (BYTE *)(LPCTSTR)pszValue
  85. , (_tcslen(pszValue)+1)*sizeof(TCHAR)))
  86. return FALSE;
  87. }
  88. RegCloseKey(hKey);
  89. return TRUE;
  90. }
  91. //***************************************************************************
  92. //
  93. // Is4OrMore
  94. //
  95. // Returns true if win95 or any version of NT > 3.51
  96. //
  97. //***************************************************************************
  98. BOOL Is4OrMore(void)
  99. {
  100. OSVERSIONINFO os;
  101. os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  102. if(!GetVersionEx(&os))
  103. return FALSE; // should never happen
  104. return os.dwMajorVersion >= 4;
  105. }
  106. HRESULT RegisterServer (
  107. TCHAR *a_pName,
  108. REFGUID a_rguid
  109. )
  110. {
  111. WCHAR wcID[128];
  112. TCHAR szCLSID[128];
  113. TCHAR szModule[MAX_PATH];
  114. TCHAR * pName = TEXT("WBEM Framework Instance Provider");
  115. TCHAR * pModel;
  116. HKEY hKey1;
  117. GetModuleFileName(g_hInstance, szModule, MAX_PATH);
  118. // Normally we want to use "Both" as the threading model since
  119. // the DLL is free threaded, but NT 3.51 Ole doesnt work unless
  120. // the model is "Aparment"
  121. if(Is4OrMore())
  122. pModel = TEXT("Free") ;
  123. else
  124. pModel = TEXT("Free") ;
  125. // Create the path.
  126. StringFromGUID2(a_rguid, wcID, 128);
  127. lstrcpy(szCLSID, TEXT("SOFTWARE\\CLASSES\\CLSID\\"));
  128. lstrcat(szCLSID, wcID);
  129. #ifdef LOCALSERVER
  130. TCHAR szProviderCLSIDAppID[128];
  131. _tcscpy(szProviderCLSIDAppID,TEXT("SOFTWARE\\CLASSES\\APPID\\"));
  132. lstrcat(szProviderCLSIDAppID, wcID);
  133. if (FALSE ==SetKeyAndValue(szProviderCLSIDAppID, NULL, NULL, a_pName ))
  134. return SELFREG_E_CLASS;
  135. #endif
  136. // Create entries under CLSID
  137. RegCreateKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey1);
  138. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)a_pName, (lstrlen(a_pName)+1) *
  139. sizeof(TCHAR));
  140. #ifdef LOCALSERVER
  141. if (FALSE ==SetKeyAndValue(szCLSID, TEXT("LocalServer32"), NULL,szModule))
  142. return SELFREG_E_CLASS;
  143. if (FALSE ==SetKeyAndValue(szCLSID, TEXT("LocalServer32"),TEXT("ThreadingModel"), pModel))
  144. return SELFREG_E_CLASS;
  145. #else
  146. HKEY hKey2 ;
  147. RegCreateKey(hKey1, TEXT("InprocServer32"), &hKey2);
  148. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule,
  149. (lstrlen(szModule)+1) * sizeof(TCHAR));
  150. RegSetValueEx(hKey2, TEXT("ThreadingModel"), 0, REG_SZ,
  151. (BYTE *)pModel, (lstrlen(pModel)+1) * sizeof(TCHAR));
  152. CloseHandle(hKey2);
  153. #endif
  154. CloseHandle(hKey1);
  155. return S_OK;
  156. }
  157. HRESULT UnregisterServer (
  158. REFGUID a_rguid
  159. )
  160. {
  161. TCHAR szID[128];
  162. WCHAR wcID[128];
  163. TCHAR szCLSID[128];
  164. HKEY hKey;
  165. // Create the path using the CLSID
  166. StringFromGUID2( a_rguid, wcID, 128);
  167. lstrcpy(szCLSID, TEXT("SOFTWARE\\CLASSES\\CLSID\\"));
  168. lstrcat(szCLSID, wcID);
  169. DWORD dwRet ;
  170. #ifdef LOCALSERVER
  171. TCHAR szProviderCLSIDAppID[128];
  172. _tcscpy(szProviderCLSIDAppID,TEXT("SOFTWARE\\CLASSES\\APPID\\"));
  173. _tcscat(szProviderCLSIDAppID,szCLSID);
  174. //Delete entries under APPID
  175. DWORD hrStatus = RegDeleteKey(HKEY_CLASSES_ROOT, szProviderCLSIDAppID);
  176. TCHAR szTemp[128];
  177. _stprintf(szTemp, TEXT("%s\\%s"),szCLSID, TEXT("LocalServer32"));
  178. hrStatus = RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  179. #else
  180. // First delete the InProcServer subkey.
  181. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey);
  182. if(dwRet == NO_ERROR)
  183. {
  184. RegDeleteKey(hKey, TEXT("InProcServer32") );
  185. CloseHandle(hKey);
  186. }
  187. #endif
  188. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\CLASSES\\CLSID"), &hKey);
  189. if(dwRet == NO_ERROR)
  190. {
  191. RegDeleteKey(hKey,szID);
  192. CloseHandle(hKey);
  193. }
  194. else
  195. {
  196. ERR((TB,"UnregisterServer ret 0x%x\n", dwRet));
  197. }
  198. return HRESULT_FROM_WIN32( dwRet );
  199. }
  200. //***************************************************************************
  201. //
  202. // DllGetClassObject
  203. //
  204. // Purpose: Called by Ole when some client wants a class factory. Return
  205. // one only if it is the sort of class this DLL supports.
  206. //
  207. //***************************************************************************
  208. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv)
  209. {
  210. HRESULT hr = S_OK;
  211. CWbemGlueFactory *pObj;
  212. if ((CLSID_CIM_WIN32_TSSESSIONDIRECTORYCLUSTER == rclsid) ||
  213. (CLSID_CIM_WIN32_TSSESSIONDIRECTORYSERVER == rclsid) ||
  214. (CLSID_CIM_WIN32_TSSESSIONDIRECTORYSESSION == rclsid))
  215. {
  216. EnterCriticalSection(&g_critsect);
  217. try{
  218. pObj =new CWbemGlueFactory () ;
  219. if (NULL==pObj)
  220. {
  221. hr = E_OUTOFMEMORY;
  222. }
  223. else
  224. {
  225. hr=pObj->QueryInterface(riid, ppv);
  226. if (FAILED(hr))
  227. delete pObj;
  228. }
  229. if( SUCCEEDED(hr) )
  230. {
  231. // EnterCriticalSection prevents more than one threads from instantiating the global pointers to the objects.
  232. if( g_pSessionDirectoryClusterobj == NULL )
  233. {
  234. TRC2((TB, "DllMain DLL_PROCESS_ATTACH: CWin32_SessionDirectoryCluster object created"));
  235. g_pSessionDirectoryClusterobj = new CWin32_SessionDirectoryCluster( PROVIDER_NAME_Win32_WIN32_SESSIONDIRECTORYCLUSTER_Prov, L"root\\cimv2");
  236. }
  237. if( g_pSessionDirectoryServerobj == NULL )
  238. {
  239. TRC2((TB, "DllMain DLL_PROCESS_ATTACH: CWin32_SessionDirectoryServer object created"));
  240. g_pSessionDirectoryServerobj = new CWin32_SessionDirectoryServer( PROVIDER_NAME_Win32_WIN32_SESSIONDIRECTORYSERVER_Prov, L"root\\cimv2");
  241. }
  242. if( g_pSessionDirectorySessionobj == NULL )
  243. {
  244. TRC2((TB, "DllMain DLL_PROCESS_ATTACH: CWin32_SessionDirectorySession object created"));
  245. g_pSessionDirectorySessionobj = new CWin32_SessionDirectorySession( PROVIDER_NAME_Win32_WIN32_SESSIONDIRECTORYSESSION_Prov, L"root\\cimv2");
  246. }
  247. }
  248. }
  249. catch (...)
  250. {
  251. hr = E_OUTOFMEMORY;
  252. }
  253. LeaveCriticalSection(&g_critsect);
  254. }
  255. else
  256. {
  257. hr=E_FAIL;
  258. ERR((TB, "DllGetClassObject ret 0x%x\n" , hr));
  259. }
  260. return hr;
  261. }
  262. //***************************************************************************
  263. //
  264. // DllCanUnloadNow
  265. //
  266. // Purpose: Called periodically by Ole in order to determine if the
  267. // DLL can be freed.
  268. //
  269. // Return: S_OK if there are no objects in use and the class factory
  270. // isn't locked.
  271. //
  272. //***************************************************************************
  273. STDAPI DllCanUnloadNow(void)
  274. {
  275. SCODE sc;
  276. // It is OK to unload if there are no objects or locks on the
  277. // class factory and the framework is done with you.
  278. if ((0L==g_cLock) && CWbemProviderGlue::FrameworkLogoffDLL(L"TSSDWMI"))
  279. {
  280. // EnterCriticalSection prevents multiple threads from accessing the global pointers concurrently and
  281. // allows only one thread access to free the objects based on the condition that g_cLock count is zero
  282. // and FrameworkLogoffDLL is TRUE.
  283. EnterCriticalSection(&g_critsect);
  284. if( g_pSessionDirectoryClusterobj != NULL )
  285. {
  286. TRC2((TB, "DllMain DLL_PROCESS_DETACH: CWin32_SessionDirectoryCluster object deleted"));
  287. delete g_pSessionDirectoryClusterobj;
  288. g_pSessionDirectoryClusterobj = NULL;
  289. }
  290. if( g_pSessionDirectoryServerobj != NULL )
  291. {
  292. TRC2((TB, "DllMain DLL_PROCESS_DETACH: CWin32_SessionDirectoryServer object deleted"));
  293. delete g_pSessionDirectoryServerobj;
  294. g_pSessionDirectoryServerobj = NULL;
  295. }
  296. if( g_pSessionDirectorySessionobj != NULL )
  297. {
  298. TRC2((TB, "DllMain DLL_PROCESS_DETACH: CWin32_SessionDirectorySession object deleted"));
  299. delete g_pSessionDirectorySessionobj;
  300. g_pSessionDirectorySessionobj = NULL;
  301. }
  302. // LeaveCriticalSection releases the critical section once the thread has freed all objects.
  303. LeaveCriticalSection(&g_critsect);
  304. sc = S_OK;
  305. }
  306. else
  307. {
  308. sc = S_FALSE;
  309. // ERR((TB, "DllCanUnloadNow ret 0x%x\n" , sc));
  310. }
  311. return sc;
  312. }
  313. //***************************************************************************
  314. //
  315. // DllRegisterServer
  316. //
  317. // Purpose: Called during setup or by regsvr32.
  318. //
  319. // Return: NOERROR if registration successful, error otherwise.
  320. //***************************************************************************
  321. STDAPI DllRegisterServer(void)
  322. {
  323. HRESULT hrStatus;
  324. hrStatus = RegisterServer( TEXT("WBEM WIN32_TSSESSIONDIRECTORYCLUSTER Provider"), CLSID_CIM_WIN32_TSSESSIONDIRECTORYCLUSTER ) ;
  325. if( SUCCEEDED( hrStatus ) )
  326. {
  327. TRC2((TB,"RegisterServer Win32_WIN32_TSSESSIONDIRECTORYCLUSTER: succeeded"));
  328. }
  329. hrStatus = RegisterServer( TEXT("WBEM WIN32_TSSESSIONDIRECTORYSERVER Provider"), CLSID_CIM_WIN32_TSSESSIONDIRECTORYSERVER ) ;
  330. if( SUCCEEDED( hrStatus ) )
  331. {
  332. TRC2((TB,"RegisterServer Win32_WIN32_TSSESSIONDIRECTORYSERVER: succeeded"));
  333. }
  334. hrStatus = RegisterServer( TEXT("WBEM WIN32_TSSESSIONDIRECTORYSESSION Provider"), CLSID_CIM_WIN32_TSSESSIONDIRECTORYSESSION ) ;
  335. if( SUCCEEDED( hrStatus ) )
  336. {
  337. TRC2((TB,"RegisterServer Win32_WIN32_TSSESSIONDIRECTORYSESSION: succeeded"));
  338. }
  339. return hrStatus;
  340. }
  341. //***************************************************************************
  342. //
  343. // DllUnregisterServer
  344. //
  345. // Purpose: Called when it is time to remove the registry entries.
  346. //
  347. // Return: NOERROR if registration successful, error otherwise.
  348. //***************************************************************************
  349. STDAPI DllUnregisterServer(void)
  350. {
  351. UnregisterServer( CLSID_CIM_WIN32_TSSESSIONDIRECTORYCLUSTER );
  352. UnregisterServer( CLSID_CIM_WIN32_TSSESSIONDIRECTORYSERVER );
  353. UnregisterServer( CLSID_CIM_WIN32_TSSESSIONDIRECTORYSESSION );
  354. return S_OK;
  355. }
  356. //***************************************************************************
  357. //
  358. // DllMain
  359. //
  360. // Purpose: Called by the operating system when processes and threads are
  361. // initialized and terminated, or upon calls to the LoadLibrary
  362. // and FreeLibrary functions
  363. //
  364. // Return: TRUE if load was successful, else FALSE
  365. //***************************************************************************
  366. BOOL APIENTRY DllMain ( HINSTANCE hInstDLL, // handle to dll module
  367. DWORD fdwReason, // reason for calling function
  368. LPVOID lpReserved ) // reserved
  369. {
  370. BOOL bRet = TRUE;
  371. // Perform actions based on the reason for calling.
  372. if( DLL_PROCESS_ATTACH == fdwReason )
  373. {
  374. DisableThreadLibraryCalls(hInstDLL);
  375. // CriticalSection object is initialized on Thread attach.
  376. __try
  377. {
  378. InitializeCriticalSection(&g_critsect);
  379. }
  380. __except (EXCEPTION_EXECUTE_HANDLER)
  381. {
  382. return FALSE;
  383. }
  384. g_hInstance = hInstDLL ;
  385. bRet = CWbemProviderGlue :: FrameworkLoginDLL ( L"TSSDWMI" ) ;
  386. }
  387. else if( DLL_PROCESS_DETACH == fdwReason )
  388. {
  389. // CriticalSection object is deleted
  390. DeleteCriticalSection(&g_critsect);
  391. }
  392. return bRet; // Status of DLL_PROCESS_ATTACH.
  393. }