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.

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