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.

581 lines
13 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. maindll.cpp
  5. Abstract:
  6. Contains DLL entry points. Also has code that controls
  7. when the DLL can be unloaded by tracking the number of
  8. objects and locks as well as routines that support
  9. self registration.
  10. Author:
  11. ???
  12. Revision History:
  13. Mohit Srivastava 06-Feb-01
  14. --*/
  15. //#include <objbase.h>
  16. //#include <initguid.h>
  17. #include "iisprov.h"
  18. HMODULE g_hModule;
  19. //
  20. // Count number of objects and number of locks.
  21. //
  22. long g_cObj=0;
  23. long g_cLock=0;
  24. extern CDynSchema* g_pDynSch; // Initialized to NULL in schemadynamic.cpp
  25. //
  26. // GuidGen generated GUID for the IIS WMI Provider.
  27. // the GUID in somewhat more legible terms: {D78F1796-E03B-4a81-AFE0-B3B6B0EEE091}
  28. //
  29. DEFINE_GUID(CLSID_IISWbemProvider, 0xd78f1796, 0xe03b, 0x4a81, 0xaf, 0xe0, 0xb3, 0xb6, 0xb0, 0xee, 0xe0, 0x91);
  30. //
  31. // Debugging Stuff
  32. //
  33. #include "pudebug.h"
  34. DECLARE_DEBUG_PRINTS_OBJECT()
  35. //
  36. // Forward declaration(s)
  37. //
  38. HRESULT MofCompile(TCHAR *i_tszPathMofFile, ULONG i_cch);
  39. STDAPI RegisterEventLog();
  40. STDAPI UnregisterEventLog();
  41. //
  42. // Entry points
  43. //
  44. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD ulReason, LPVOID pvReserved)
  45. /*++
  46. Synopsis:
  47. Entry point for the DLL
  48. Arguments: [hInstance] -
  49. [ulReason] -
  50. [pvReserved] -
  51. Return Value:
  52. --*/
  53. {
  54. switch( ulReason )
  55. {
  56. case DLL_PROCESS_ATTACH:
  57. g_hModule = hInstance;
  58. #ifndef _NO_TRACING_
  59. CREATE_DEBUG_PRINT_OBJECT("IISWMI");
  60. #else
  61. CREATE_DEBUG_PRINT_OBJECT("IISWMI");
  62. #endif
  63. break;
  64. case DLL_PROCESS_DETACH:
  65. DELETE_DEBUG_PRINT_OBJECT( );
  66. delete g_pDynSch;
  67. g_pDynSch = NULL;
  68. break;
  69. }
  70. return TRUE;
  71. }
  72. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, PPVOID ppv)
  73. /*++
  74. Synopsis:
  75. Called by Ole when some client wants a class factory. Return
  76. one only if it is the sort of class this DLL supports.
  77. Arguments: [rclsid] -
  78. [riid] -
  79. [ppv] -
  80. Return Value:
  81. --*/
  82. {
  83. HRESULT hr = S_OK;
  84. IClassFactory* pObj = NULL;
  85. if (CLSID_IISWbemProvider == rclsid)
  86. {
  87. pObj=new CProvFactory();
  88. if(NULL == pObj)
  89. {
  90. return E_OUTOFMEMORY;
  91. }
  92. }
  93. else
  94. {
  95. return CLASS_E_CLASSNOTAVAILABLE ;
  96. }
  97. hr = pObj->QueryInterface(riid, ppv);
  98. if (FAILED(hr))
  99. {
  100. delete pObj;
  101. pObj = NULL;
  102. }
  103. return hr;
  104. }
  105. STDAPI DllCanUnloadNow(void)
  106. /*++
  107. Synopsis:
  108. Called periodically by Ole in order to determine if the DLL can be freed.
  109. Arguments: [void] -
  110. Return Value:
  111. S_OK if there are no objects in use and the class factory isn't locked.
  112. S_FALSE otherwise.
  113. --*/
  114. {
  115. SCODE sc;
  116. //It is OK to unload if there are no objects or locks on the
  117. // class factory.
  118. sc = (0L>=g_cObj && 0L>=g_cLock) ? S_OK : S_FALSE;
  119. return sc;
  120. }
  121. STDAPI DllRegisterServer(void)
  122. /*++
  123. Synopsis:
  124. Called during setup or by regsvr32
  125. Arguments: [void] -
  126. Return Value:
  127. NOERROR if registration successful, error otherwise.
  128. --*/
  129. {
  130. WCHAR szID[MAX_PATH+1];
  131. WCHAR wcID[MAX_PATH+1];
  132. WCHAR szCLSID[MAX_PATH+1];
  133. WCHAR szModule[MAX_PATH+1];
  134. WCHAR * pName = L"Microsoft Internet Information Server Provider";
  135. WCHAR * pModel = L"Both";
  136. HKEY hKey1, hKey2;
  137. // Create the path.
  138. StringFromGUID2(CLSID_IISWbemProvider, wcID, MAX_PATH);
  139. lstrcpyW(szID, wcID);
  140. lstrcpyW(szCLSID, L"Software\\classes\\CLSID\\");
  141. lstrcatW(szCLSID, szID);
  142. // Create entries under CLSID
  143. LONG lRet;
  144. lRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
  145. szCLSID,
  146. 0,
  147. NULL,
  148. 0,
  149. KEY_ALL_ACCESS,
  150. NULL,
  151. &hKey1,
  152. NULL);
  153. if(lRet != ERROR_SUCCESS)
  154. return SELFREG_E_CLASS;
  155. RegSetValueExW(hKey1,
  156. NULL,
  157. 0,
  158. REG_SZ,
  159. (BYTE *)pName,
  160. lstrlenW(pName)*sizeof(WCHAR)+1);
  161. lRet = RegCreateKeyExW(hKey1,
  162. L"InprocServer32",
  163. 0,
  164. NULL,
  165. 0,
  166. KEY_ALL_ACCESS,
  167. NULL,
  168. &hKey2,
  169. NULL);
  170. if(lRet != ERROR_SUCCESS)
  171. {
  172. RegCloseKey(hKey1);
  173. return SELFREG_E_CLASS;
  174. }
  175. GetModuleFileNameW(g_hModule, szModule, MAX_PATH);
  176. RegSetValueExW(hKey2,
  177. NULL,
  178. 0,
  179. REG_SZ,
  180. (BYTE*)szModule,
  181. lstrlenW(szModule) * sizeof(WCHAR) + 1);
  182. RegSetValueExW(hKey2,
  183. L"ThreadingModel",
  184. 0,
  185. REG_SZ,
  186. (BYTE *)pModel,
  187. lstrlenW(pModel) * sizeof(WCHAR) + 1);
  188. RegCloseKey(hKey1);
  189. RegCloseKey(hKey2);
  190. //
  191. // Register other stuff
  192. //
  193. HRESULT hr = RegisterEventLog();
  194. if(FAILED(hr))
  195. {
  196. return hr;
  197. }
  198. return hr;
  199. }
  200. STDAPI DllUnregisterServer(void)
  201. /*++
  202. Synopsis:
  203. Called when it is time to remove the registry entries.
  204. Arguments: [void] -
  205. Return Value:
  206. NOERROR if registration successful, error otherwise.
  207. --*/
  208. {
  209. WCHAR szID[MAX_PATH+1];
  210. WCHAR wcID[MAX_PATH+1];
  211. WCHAR szCLSID[MAX_PATH+1];
  212. HKEY hKey;
  213. //
  214. // Create the path using the CLSID
  215. //
  216. StringFromGUID2(CLSID_IISWbemProvider, wcID, 128);
  217. lstrcpyW(szID, wcID);
  218. lstrcpyW(szCLSID, L"Software\\classes\\CLSID\\");
  219. lstrcatW(szCLSID, szID);
  220. //
  221. // First delete the InProcServer subkey.
  222. //
  223. LONG lRet;
  224. lRet = RegOpenKeyExW(
  225. HKEY_LOCAL_MACHINE,
  226. szCLSID,
  227. 0,
  228. KEY_ALL_ACCESS,
  229. &hKey
  230. );
  231. if(lRet == ERROR_SUCCESS)
  232. {
  233. RegDeleteKeyW(hKey, L"InProcServer32");
  234. RegCloseKey(hKey);
  235. }
  236. lRet = RegOpenKeyExW(
  237. HKEY_LOCAL_MACHINE,
  238. L"Software\\classes\\CLSID",
  239. 0,
  240. KEY_ALL_ACCESS,
  241. &hKey
  242. );
  243. if(lRet == ERROR_SUCCESS)
  244. {
  245. RegDeleteKeyW(hKey,szID);
  246. RegCloseKey(hKey);
  247. }
  248. UnregisterEventLog();
  249. return S_OK;
  250. }
  251. STDAPI DoMofComp(void)
  252. /*++
  253. Synopsis:
  254. Called by NT Setup to put MOF in repository.
  255. Arguments: [void] -
  256. Return Value:
  257. NOERROR if registration successful, error otherwise.
  258. --*/
  259. {
  260. ULONG cchWinPath;
  261. LPCTSTR tszSysPath = TEXT("\\system32\\wbem\\");
  262. ULONG cchSysPath = _tcslen(tszSysPath);
  263. LPCTSTR tszMOFs[] = { TEXT("iiswmi.mof"), TEXT("iiswmi.mfl"), NULL };
  264. ULONG idx = 0;
  265. LPCTSTR tszCurrent = NULL;
  266. TCHAR tszMOFPath[_MAX_PATH];
  267. HRESULT hres = S_OK;
  268. hres = CoInitialize(NULL);
  269. if (FAILED(hres))
  270. {
  271. return hres;
  272. }
  273. //
  274. // After this block, tszMOFPath = C:\winnt, len = cchWinPath
  275. //
  276. cchWinPath = GetSystemWindowsDirectory(tszMOFPath, _MAX_PATH);
  277. if(cchWinPath == 0)
  278. {
  279. hres = HRESULT_FROM_WIN32(GetLastError());
  280. goto exit;
  281. }
  282. if(cchWinPath > _MAX_PATH)
  283. {
  284. hres = HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME);
  285. goto exit;
  286. }
  287. if(tszMOFPath[cchWinPath-1] == TEXT('\\'))
  288. {
  289. tszMOFPath[cchWinPath-1] = TEXT('\0');
  290. cchWinPath--;
  291. }
  292. //
  293. // After this block, tszMOFPath = C:\winnt\system32\wbem\, len = cchWinPath+cchSysPath
  294. //
  295. if(cchWinPath+cchSysPath+1 > _MAX_PATH)
  296. {
  297. hres = HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME);
  298. goto exit;
  299. }
  300. memcpy(&tszMOFPath[cchWinPath], tszSysPath, sizeof(TCHAR)*(cchSysPath+1));
  301. //
  302. // Verify each file exists, and compile it.
  303. //
  304. for(idx = 0, tszCurrent = tszMOFs[0];
  305. tszCurrent != NULL;
  306. tszCurrent = tszMOFs[++idx])
  307. {
  308. ULONG cchCurrent = _tcslen(tszCurrent);
  309. if(cchWinPath+cchSysPath+cchCurrent+1 > _MAX_PATH)
  310. {
  311. hres = HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME);
  312. goto exit;
  313. }
  314. memcpy(&tszMOFPath[cchWinPath+cchSysPath],
  315. tszCurrent,
  316. sizeof(TCHAR)*(cchCurrent+1));
  317. if (GetFileAttributes(tszMOFPath) == 0xFFFFFFFF)
  318. {
  319. hres = HRESULT_FROM_WIN32(GetLastError());
  320. goto exit;
  321. }
  322. hres = MofCompile(tszMOFPath, cchWinPath+cchSysPath+cchCurrent);
  323. if(FAILED(hres))
  324. {
  325. goto exit;
  326. }
  327. }
  328. exit:
  329. CoUninitialize();
  330. return hres;
  331. }
  332. //
  333. // Below this line are helper functions.
  334. // They are not actually exported.
  335. //
  336. HRESULT MofCompile(TCHAR *i_tszPathMofFile, ULONG i_cch)
  337. /*++
  338. Synopsis:
  339. NOT Exported. Call by DoMofComp (above)
  340. Arguments: [i_tszPathMofFile] -
  341. [i_cch] - count of chars NOT including null terminator.
  342. Return Value:
  343. HRESULT
  344. --*/
  345. {
  346. DBG_ASSERT(i_tszPathMofFile != NULL);
  347. DBG_ASSERT(i_cch < _MAX_PATH);
  348. DBG_ASSERT(i_cch > 0);
  349. DBG_ASSERT(i_tszPathMofFile[i_cch] == TEXT('\0'));
  350. HRESULT hRes = E_FAIL;
  351. WCHAR wszFileName[_MAX_PATH];
  352. CComPtr<IMofCompiler> spMofComp;
  353. WBEM_COMPILE_STATUS_INFO Info;
  354. hRes = CoCreateInstance( CLSID_MofCompiler, NULL, CLSCTX_INPROC_SERVER, IID_IMofCompiler, (LPVOID *)&spMofComp);
  355. if (FAILED(hRes))
  356. {
  357. goto exit;
  358. }
  359. //
  360. // Ensure that the string is WCHAR.
  361. //
  362. #if defined(UNICODE) || defined(_UNICODE)
  363. memcpy(wszFileName, i_tszPathMofFile, sizeof(TCHAR)*(i_cch+1));
  364. #else
  365. if(MultiByteToWideChar( CP_ACP, 0, i_tszPathMofFile, -1, wszFileName, _MAX_PATH) == 0)
  366. {
  367. hres = GetLastError();
  368. hres = HRESULT_FROM_WIN32(hres);
  369. goto exit;
  370. }
  371. #endif
  372. hRes = spMofComp->CompileFile (
  373. (LPWSTR) wszFileName,
  374. NULL, // load into namespace specified in MOF file
  375. NULL, // use default User
  376. NULL, // use default Authority
  377. NULL, // use default Password
  378. 0, // no options
  379. 0, // no class flags
  380. 0, // no instance flags
  381. &Info);
  382. if(FAILED(hRes))
  383. {
  384. goto exit;
  385. }
  386. exit:
  387. return hRes;
  388. }
  389. STDAPI RegisterEventLog(void)
  390. /*++
  391. Synopsis:
  392. Sets up iiswmi.dll in the EventLog registry for resolution of NT EventLog
  393. message strings
  394. Arguments: [void] -
  395. Return Value:
  396. HRESULT
  397. --*/
  398. {
  399. HKEY hk;
  400. WCHAR wszModuleFullPath[MAX_PATH];
  401. DWORD dwTypesSupported = 0;
  402. DWORD dwRet;
  403. HRESULT hr = S_OK;
  404. dwRet = GetModuleFileNameW(g_hModule, wszModuleFullPath, MAX_PATH);
  405. if(dwRet == 0)
  406. {
  407. return SELFREG_E_CLASS;
  408. }
  409. //
  410. // Create the key
  411. //
  412. dwRet = RegCreateKeyW(
  413. HKEY_LOCAL_MACHINE,
  414. L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\System\\IISWMI", &hk);
  415. if(dwRet != ERROR_SUCCESS)
  416. {
  417. return SELFREG_E_CLASS;
  418. }
  419. //
  420. // Set the "EventMessageFile" value
  421. //
  422. dwRet = RegSetValueExW(
  423. hk, // subkey handle
  424. L"EventMessageFile", // value name
  425. 0, // must be zero
  426. REG_EXPAND_SZ, // value type
  427. (LPBYTE)wszModuleFullPath, // address of value data
  428. sizeof(WCHAR)*(wcslen(wszModuleFullPath)+1) ); // length of value data
  429. if(dwRet != ERROR_SUCCESS)
  430. {
  431. hr = SELFREG_E_CLASS;
  432. goto exit;
  433. }
  434. //
  435. // Set the "TypesSupported" value
  436. //
  437. dwTypesSupported =
  438. EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
  439. dwRet = RegSetValueExW(
  440. hk, // subkey handle
  441. L"TypesSupported", // value name
  442. 0, // must be zero
  443. REG_DWORD, // value type
  444. (LPBYTE)&dwTypesSupported, // address of value data
  445. sizeof(DWORD) ); // length of value data
  446. if(dwRet != ERROR_SUCCESS)
  447. {
  448. hr = SELFREG_E_CLASS;
  449. goto exit;
  450. }
  451. exit:
  452. RegCloseKey(hk);
  453. return hr;
  454. }
  455. STDAPI UnregisterEventLog(void)
  456. /*++
  457. Synopsis:
  458. Called by DllUnregisterServer.
  459. Called when it is time to remove the registry entries for event logging.
  460. Arguments: [void] -
  461. Return Value:
  462. HRESULT
  463. --*/
  464. {
  465. //
  466. // Delete the key
  467. //
  468. RegDeleteKeyW(
  469. HKEY_LOCAL_MACHINE,
  470. L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\System\\IISWMI");
  471. return S_OK;
  472. }