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.

2405 lines
73 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. CFGMGR.CPP
  5. Abstract:
  6. This file implements the WinMgmt configuration manager class.
  7. See cfgmgr.h for documentation.
  8. Classes implemented:
  9. ConfigMgr configuration manager
  10. History:
  11. 09-Jul-96 raymcc Created.
  12. 3/10/97 levn Fully documented (ha, ha)
  13. --*/
  14. #include "precomp.h"
  15. #define OBJECT_BLOB_CRC
  16. #include <stdio.h>
  17. #include <wbemcore.h>
  18. #include <decor.h>
  19. #include "PersistCfg.h"
  20. #include <genutils.h>
  21. #include <oahelp.inl>
  22. #include <wmiarbitrator.h>
  23. #include <comdef.h>
  24. #include<helper.h>
  25. #include <autoptr.h>
  26. #include <sddl.h>
  27. #include <md5wbem.h>
  28. #include <accctrl.h>
  29. #include <aclapi.h>
  30. #define CONFIG_DEFAULT_QUEUE_SIZE 1
  31. #define DEFAULT_SHUTDOWN_TIMEOUT 10000
  32. #ifdef _WIN64
  33. #pragma message("WIN64 QUOTA")
  34. #define CONFIG_MAX_COMMITTED_MEMORY 300000000
  35. #else
  36. #pragma message("WIN32 QUOTA")
  37. #define CONFIG_MAX_COMMITTED_MEMORY 150000000 // 100 meg
  38. #endif
  39. extern LPTSTR g_pWorkDir;
  40. extern LPTSTR g_pDbDir;
  41. extern LPTSTR g_pAutorecoverDir;
  42. extern DWORD g_dwQueueSize;
  43. extern BOOL g_bDontAllowNewConnections;
  44. extern IWbemEventSubsystem_m4* g_pEss_m4;
  45. extern bool g_bDefaultMofLoadingNeeded;
  46. //*********************************************************************************
  47. //
  48. //*********************************************************************************
  49. LONG ExceptionCounter::s_Count = 0;
  50. _IWmiESS *g_pESS = 0;
  51. _IWmiProvSS *g_pProvSS = 0;
  52. HANDLE g_hOpenForClients = NULL;
  53. HRESULT g_hresForClients = WBEM_E_CRITICAL_ERROR;
  54. CAsyncServiceQueue* g_pAsyncSvcQueue = NULL;
  55. CEventLog* g_pEventLog = NULL;
  56. extern IClassFactory* g_pContextFac;
  57. extern IClassFactory* g_pPathFac;
  58. extern IClassFactory* g_pQueryFact;
  59. CStaticCritSec ConfigMgr::g_csEss;
  60. CPersistentConfig g_persistConfig;
  61. _IWmiCoreWriteHook * g_pRAHook = NULL;
  62. DWORD g_IdentifierLimit = WBEM_MAX_IDENTIFIER; // Max property, qualifier, class name (4K)
  63. DWORD g_QueryLimit = WBEM_MAX_QUERY; // Max query size (16K)
  64. DWORD g_PathLimit = WBEM_MAX_PATH; // Max object path (8K)
  65. /*
  66. DWORD g_ObjectNestingLimit = WBEM_MAX_OBJECT_NESTING; // Max embedded object nesting
  67. DWORD g_UserPropLimit = WBEM_MAX_USER_PROPERTIES; // Max user-defined properties in class
  68. */
  69. //******************************************************************************
  70. //
  71. // This routine checks if a string property has changed, and if it has, updates
  72. // it and setus a bool indicating that an update was done
  73. //
  74. //******************************************************************************
  75. HRESULT PutValueIfDiff(CWbemObject * pObj, LPWSTR pwsValueName, LPWSTR pwsValue, bool &bDiff)
  76. {
  77. if(pwsValue == NULL)
  78. return S_OK;
  79. VARIANT var;
  80. VariantInit(&var);
  81. HRESULT hr = pObj->Get(pwsValueName, 0, &var, NULL, NULL);
  82. CClearMe ccme(&var);
  83. if(SUCCEEDED(hr))
  84. {
  85. if(var.vt == VT_BSTR && var.bstrVal && !wbem_wcsicmp(var.bstrVal, pwsValue))
  86. return S_OK;
  87. }
  88. bDiff = true;
  89. BSTR bStr = SysAllocString(pwsValue);
  90. if (bStr)
  91. {
  92. CVar v2(VT_BSTR,auto_bstr(bStr));
  93. return pObj->SetPropValue(pwsValueName, &v2, CIM_STRING);
  94. }
  95. else
  96. {
  97. return WBEM_E_OUT_OF_MEMORY;
  98. }
  99. }
  100. //*********************************************************************************
  101. //
  102. //*********************************************************************************
  103. void ConfigMgr::FatalInitializationError(HRESULT hRes)
  104. {
  105. // If there are any clients waiting to get in, this must be set or else they
  106. // will wait forever. g_hresForClients should be set to error by default!
  107. ERRORTRACE((LOG_WBEMCORE, "Failure to initialize WinMgmt (hRes = 0x%X)\n", hRes));
  108. if (g_hOpenForClients)
  109. SetEvent(g_hOpenForClients);
  110. if (g_pEventLog == NULL)
  111. return;
  112. DWORD dwMsgId;
  113. if(hRes == WBEM_E_ALREADY_EXISTS)
  114. {
  115. dwMsgId = WBEM_MC_MULTIPLE_NOT_SUPPORTED;
  116. }
  117. else if(hRes == WBEM_E_INITIALIZATION_FAILURE)
  118. {
  119. dwMsgId = WBEM_MC_FAILED_TO_INITIALIZE_REPOSITORY;
  120. }
  121. else
  122. {
  123. dwMsgId = WBEM_MC_WBEM_CORE_FAILURE;
  124. }
  125. g_pEventLog->Report(EVENTLOG_ERROR_TYPE, dwMsgId);
  126. }
  127. //******************************************************************************
  128. //
  129. // See cfgmgr.h for documentation
  130. //
  131. //******************************************************************************
  132. HRESULT ConfigMgr::SetReady()
  133. {
  134. HRESULT hRes;
  135. IWmiDbHandle *pNs = NULL;
  136. IWmiDbSession * pSess = NULL;
  137. DEBUGTRACE((LOG_WBEMCORE, "****************** WinMgmt Startup ******************\n"));
  138. // Initialize unloading instruction configuration
  139. // ==============================================
  140. hRes = CRepository::GetDefaultSession(&pSess);
  141. if (FAILED(hRes))
  142. {
  143. ERRORTRACE((LOG_WBEMCORE, "System preperation: failed to get new session <0x%X>!\n", hRes));
  144. return hRes;
  145. }
  146. CReleaseMe rm0(pSess);
  147. //Deal with objects in root namespace...
  148. {
  149. hRes = CRepository::OpenEseNs(pSess,L"root", &pNs);
  150. if (FAILED(hRes))
  151. {
  152. ERRORTRACE((LOG_WBEMCORE, "System preperation: failed to open root namespace <0x%X>!\n", hRes));
  153. return hRes;
  154. }
  155. CReleaseMe rm1(pNs);
  156. hRes = ConfigMgr::SetIdentificationObject(pNs,pSess);
  157. if (FAILED(hRes))
  158. {
  159. ERRORTRACE((LOG_WBEMCORE, "System preperation: failed to set identification objects in root <0x%X>!\n", hRes));
  160. return hRes;
  161. }
  162. }
  163. {
  164. hRes = CRepository::OpenEseNs(pSess, L"root\\default", &pNs);
  165. if (FAILED(hRes))
  166. {
  167. ERRORTRACE((LOG_WBEMCORE, "System preperation: failed to open root\\default namespace <0x%X>!\n", hRes));
  168. return hRes;
  169. }
  170. CReleaseMe rm1(pNs);
  171. hRes = ConfigMgr::SetIdentificationObject(pNs,pSess);
  172. if (FAILED(hRes))
  173. {
  174. ERRORTRACE((LOG_WBEMCORE, "System preperation: failed to set identification objects in root\\default <0x%X>!\n", hRes));
  175. return hRes;
  176. }
  177. hRes = ConfigMgr::SetAdapStatusObject(pNs,pSess);
  178. if (FAILED(hRes))
  179. {
  180. ERRORTRACE((LOG_WBEMCORE, "System preperation: failed to set ADAP Status objects in root\\default <0x%X>!\n", hRes));
  181. return hRes;
  182. }
  183. }
  184. // Finish client preparations
  185. // ==========================
  186. hRes = PrepareForClients(0);
  187. if(FAILED(hRes))
  188. {
  189. ERRORTRACE((LOG_WBEMCORE, "System preperation: Prepare for clients failed <0x%X>!\n", hRes));
  190. return hRes;
  191. }
  192. return WBEM_S_NO_ERROR;
  193. }
  194. //******************************************************************************
  195. //
  196. // See cfgmgr.h for documentation
  197. //
  198. //******************************************************************************
  199. HRESULT ConfigMgr::SetIdentificationObject(
  200. IWmiDbHandle* pNs,
  201. IWmiDbSession * pSess
  202. )
  203. {
  204. HRESULT hRes;
  205. // __CIMOMIdentification class
  206. try // CIdentificationClass can throw and internal fastprox interfaces
  207. {
  208. bool bDifferenceFound = false;
  209. IWbemClassObject * pInst = NULL;
  210. hRes = CRepository::GetObject(pSess, pNs,
  211. L"__CIMOMIdentification=@",
  212. 0,&pInst);
  213. if(pInst == NULL)
  214. {
  215. // Instance isnt there, create it. Start by getting the class
  216. bDifferenceFound = true;
  217. IWbemClassObject * pClass = NULL;
  218. hRes = CRepository::GetObject(pSess, pNs, L"__CIMOMIdentification", 0,&pClass);
  219. if(pClass == NULL)
  220. {
  221. // class also needs to be created
  222. CIdentificationClass * pIdentificationClass = new CIdentificationClass;
  223. if(pIdentificationClass == NULL)
  224. return WBEM_E_OUT_OF_MEMORY;
  225. CDeleteMe<CIdentificationClass> dm1(pIdentificationClass);
  226. pIdentificationClass->Init(); // throw
  227. IWbemClassObject *pObj = NULL;
  228. hRes = pIdentificationClass->QueryInterface(IID_IWbemClassObject, (LPVOID *) &pObj);
  229. if (FAILED(hRes))
  230. return hRes;
  231. CReleaseMe rm3(pObj);
  232. hRes = CRepository::PutObject(pSess, pNs, IID_IWbemClassObject, pObj, WMIDB_DISABLE_EVENTS);
  233. if(FAILED(hRes))
  234. return hRes;
  235. hRes = CRepository::GetObject(pSess, pNs, L"__CIMOMIdentification", 0,&pClass);
  236. if(FAILED(hRes))
  237. return hRes;
  238. }
  239. CReleaseMe rm0(pClass);
  240. hRes = pClass->SpawnInstance(0, &pInst);
  241. if(FAILED(hRes))
  242. return hRes;
  243. }
  244. CReleaseMe rm(pInst);
  245. // We now have an instance. Set the values
  246. CWbemObject * pObj = (CWbemObject *)pInst;
  247. WCHAR wTemp[MAX_PATH+1];
  248. BOOL bRet = ConfigMgr::GetDllVersion(__TEXT("wbemcore.dll"), __TEXT("ProductVersion"), wTemp, MAX_PATH);
  249. if(bRet)
  250. {
  251. HKEY hKey = 0;
  252. if (RegOpenKey(HKEY_LOCAL_MACHINE, __TEXT("software\\microsoft\\wbem\\cimom"), &hKey) != ERROR_SUCCESS) // SEC:REVIEWED 2002-03-22 : OK
  253. return WBEM_E_FAILED;
  254. CRegCloseMe cm(hKey);
  255. // Get the properties. Note if any changes were found.
  256. hRes = PutValueIfDiff(pObj, L"VersionUsedToCreateDB", wTemp, bDifferenceFound);
  257. if(FAILED(hRes))
  258. return hRes;
  259. hRes = PutValueIfDiff(pObj, L"VersionCurrentlyRunning", wTemp, bDifferenceFound);
  260. if(FAILED(hRes))
  261. return hRes;
  262. DWORD lSize = 2*(MAX_PATH+1);
  263. DWORD dwType;
  264. if(ERROR_SUCCESS != RegQueryValueExW(hKey, L"SetupDate",NULL, &dwType,(BYTE *)wTemp, &lSize)) // SEC:REVIEWED 2002-03-22 : OK
  265. return WBEM_E_FAILED;
  266. hRes = PutValueIfDiff(pObj, L"SetupDate", wTemp, bDifferenceFound);
  267. if(FAILED(hRes))
  268. return hRes;
  269. lSize = 2*(MAX_PATH+1);
  270. if(ERROR_SUCCESS != RegQueryValueExW(hKey, L"SetupTime", NULL, &dwType, (BYTE *)wTemp, &lSize)) // SEC:REVIEWED 2002-03-22 : OK
  271. return WBEM_E_FAILED;
  272. hRes = PutValueIfDiff(pObj, L"SetupTime", wTemp, bDifferenceFound);
  273. if(FAILED(hRes))
  274. return hRes;
  275. lSize = 2*(MAX_PATH+1);
  276. if(ERROR_SUCCESS != RegQueryValueExW(hKey, L"Working Directory", NULL, &dwType, // SEC:REVIEWED 2002-03-22 : OK
  277. (BYTE *)wTemp, &lSize))
  278. return WBEM_E_FAILED;
  279. hRes = PutValueIfDiff(pObj, L"WorkingDirectory", wTemp, bDifferenceFound);
  280. if(FAILED(hRes))
  281. return hRes;
  282. if(bDifferenceFound)
  283. hRes = CRepository::PutObject(pSess, pNs, IID_IWbemClassObject, pObj, WMIDB_DISABLE_EVENTS);
  284. else
  285. hRes = S_OK;
  286. }
  287. else
  288. return WBEM_E_FAILED;
  289. } catch (CX_MemoryException &) {
  290. //
  291. hRes = WBEM_E_OUT_OF_MEMORY;
  292. }
  293. catch (CX_Exception &)
  294. {
  295. return WBEM_E_CRITICAL_ERROR;
  296. }
  297. return hRes;
  298. }
  299. HRESULT ConfigMgr::SetAdapStatusObject(
  300. IWmiDbHandle* pNs,
  301. IWmiDbSession* pSess
  302. )
  303. {
  304. HRESULT hRes;
  305. // __AdapStatus class
  306. try // CAdapStatusClass can throw
  307. {
  308. // if the object already exists, dont bother
  309. IWbemClassObject * pInst = NULL;
  310. HRESULT hr = CRepository::GetObject(pSess, pNs, L"__AdapStatus=@",0,&pInst);
  311. if(SUCCEEDED(hr) && pInst)
  312. {
  313. pInst->Release();
  314. return S_OK;
  315. }
  316. CAdapStatusClass * pAdapStatusClass = new CAdapStatusClass;
  317. if(pAdapStatusClass == NULL)
  318. return WBEM_E_OUT_OF_MEMORY;
  319. CDeleteMe<CAdapStatusClass> dm1(pAdapStatusClass);
  320. pAdapStatusClass->Init(); // throw
  321. CAdapStatusInstance * pAdapStatusInstance = new CAdapStatusInstance;
  322. if(pAdapStatusInstance == NULL)
  323. return WBEM_E_OUT_OF_MEMORY;
  324. CDeleteMe<CAdapStatusInstance> dm2(pAdapStatusInstance);
  325. pAdapStatusInstance->Init(pAdapStatusClass);
  326. IWbemClassObject *pObj = NULL;
  327. hRes = pAdapStatusClass->QueryInterface(IID_IWbemClassObject, (LPVOID *) &pObj);
  328. if (FAILED(hRes))
  329. return hRes;
  330. CReleaseMe rm1(pObj);
  331. hRes = CRepository::PutObject(pSess, pNs, IID_IWbemClassObject, pObj, WMIDB_DISABLE_EVENTS);
  332. if (FAILED(hRes))
  333. return hRes;
  334. IWbemClassObject *pObj2 = NULL;
  335. hRes = pAdapStatusInstance->QueryInterface(IID_IWbemClassObject, (LPVOID *) &pObj2);
  336. if (FAILED(hRes))
  337. return hRes;
  338. CReleaseMe rm2(pObj2);
  339. hRes = CRepository::PutObject(pSess, pNs, IID_IWbemClassObject, pObj2, WMIDB_DISABLE_EVENTS);
  340. if (FAILED(hRes))
  341. return hRes;
  342. } catch (CX_MemoryException &) {
  343. //
  344. hRes = WBEM_E_OUT_OF_MEMORY;
  345. }
  346. catch (CX_Exception &)
  347. {
  348. return WBEM_E_CRITICAL_ERROR;
  349. }
  350. return hRes;
  351. }
  352. //******************************************************************************
  353. //
  354. // See cfgmgr.h for documentation
  355. //
  356. //******************************************************************************
  357. IWbemEventSubsystem_m4* ConfigMgr::GetEssSink()
  358. {
  359. CInCritSec ics(&g_csEss);
  360. if(g_pEss_m4)
  361. g_pEss_m4->AddRef();
  362. return g_pEss_m4;
  363. }
  364. //******************************************************************************
  365. //
  366. // See cfgmgr.h for documentation
  367. //
  368. //******************************************************************************
  369. BOOL ConfigMgr::ShutdownInProgress() { return g_bDontAllowNewConnections; }
  370. //******************************************************************************
  371. //
  372. // See cfgmgr.h for documentation
  373. //
  374. //******************************************************************************
  375. IWbemContext* ConfigMgr::GetNewContext()
  376. {
  377. HRESULT hres;
  378. if(g_pContextFac == NULL)
  379. return NULL;
  380. IWbemContext* pContext;
  381. hres = g_pContextFac->CreateInstance(NULL, IID_IWbemContext,
  382. (void**)&pContext);
  383. if(FAILED(hres))
  384. {
  385. ERRORTRACE((LOG_WBEMCORE,"CRITICAL ERROR: cannot create contexts: %X\n", hres));
  386. return NULL;
  387. }
  388. return pContext;
  389. }
  390. //******************************************************************************
  391. //
  392. // See cfgmgr.h for documentation
  393. //
  394. //******************************************************************************
  395. READONLY LPWSTR ConfigMgr::GetMachineName()
  396. {
  397. static wchar_t ThisMachine[MAX_COMPUTERNAME_LENGTH+1];
  398. static BOOL bFirstCall = TRUE;
  399. if (bFirstCall)
  400. {
  401. wchar_t localMachine[MAX_COMPUTERNAME_LENGTH+1];
  402. DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1;
  403. GetComputerNameW(localMachine, &dwSize); // SEC:REVIEWED 2002-03-22 : Assumes success, need error check
  404. bFirstCall = FALSE;
  405. StringCchCopyW(ThisMachine, MAX_COMPUTERNAME_LENGTH+1, localMachine);
  406. }
  407. return ThisMachine;
  408. }
  409. //******************************************************************************
  410. //
  411. // See cfgmgr.h for documentation
  412. //
  413. //******************************************************************************
  414. CWbemQueue* ConfigMgr::GetUnRefedSvcQueue()
  415. {
  416. return g_pAsyncSvcQueue;
  417. }
  418. //******************************************************************************
  419. //
  420. // See cfgmgr.h for documentation
  421. //
  422. //******************************************************************************
  423. CAsyncServiceQueue* ConfigMgr::GetAsyncSvcQueue()
  424. {
  425. CInCritSec ics(&g_csEss);
  426. if (g_pAsyncSvcQueue)
  427. {
  428. g_pAsyncSvcQueue->AddRef();
  429. return g_pAsyncSvcQueue;
  430. }
  431. else
  432. return NULL;
  433. }
  434. //******************************************************************************
  435. //
  436. // See cfgmgr.h for documentation
  437. //
  438. //******************************************************************************
  439. HRESULT ConfigMgr::EnqueueRequest(CAsyncReq * pRequest)
  440. {
  441. try
  442. {
  443. CAsyncServiceQueue* pTemp = 0;
  444. {
  445. CInCritSec ics(&g_csEss);
  446. if(g_pAsyncSvcQueue == NULL)
  447. return WBEM_E_SHUTTING_DOWN;
  448. pTemp = g_pAsyncSvcQueue;
  449. g_pAsyncSvcQueue->AddRef();
  450. }
  451. HRESULT hr = pTemp->Enqueue(pRequest);
  452. pTemp->Release();
  453. return hr;
  454. }
  455. catch(CX_MemoryException &)
  456. {
  457. return WBEM_E_OUT_OF_MEMORY;
  458. }
  459. catch(...)
  460. {
  461. ExceptionCounter c;
  462. return WBEM_E_CRITICAL_ERROR;
  463. }
  464. }
  465. //******************************************************************************
  466. //
  467. // See cfgmgr.h for documentation
  468. //
  469. //******************************************************************************
  470. HRESULT ConfigMgr::EnqueueRequestAndWait(CAsyncReq * pRequest)
  471. {
  472. try
  473. {
  474. CAsyncServiceQueue* pTemp = 0;
  475. {
  476. CInCritSec ics(&g_csEss);
  477. if(g_pAsyncSvcQueue == NULL)
  478. return WBEM_E_SHUTTING_DOWN;
  479. pTemp = g_pAsyncSvcQueue;
  480. g_pAsyncSvcQueue->AddRef();
  481. }
  482. HRESULT hr = pTemp->EnqueueAndWait(pRequest);
  483. pTemp->Release();
  484. return hr;
  485. }
  486. catch(CX_MemoryException &)
  487. {
  488. return WBEM_E_OUT_OF_MEMORY;
  489. }
  490. catch(...)
  491. {
  492. ExceptionCounter c;
  493. return WBEM_E_CRITICAL_ERROR;
  494. }
  495. }
  496. //******************************************************************************
  497. //
  498. // See cfgmgr.h for documentation
  499. //
  500. //******************************************************************************
  501. LPTSTR ConfigMgr::GetWorkingDir()
  502. {
  503. return g_pWorkDir;
  504. }
  505. //******************************************************************************
  506. //
  507. // See cfgmgr.h for documentation
  508. //
  509. //******************************************************************************
  510. LPTSTR ConfigMgr::GetDbDir()
  511. {
  512. if (g_pDbDir == NULL)
  513. {
  514. Registry r(WBEM_REG_WINMGMT);
  515. if (g_pWorkDir == NULL)
  516. {
  517. if (r.GetStr(__TEXT("Working Directory"), &g_pWorkDir))
  518. {
  519. size_t tmpLength = MAX_PATH + 1 + lstrlen(__TEXT("\\WBEM")); // SEC:REVIEWED 2002-03-22 : OK
  520. g_pWorkDir = new TCHAR[tmpLength];
  521. if (g_pWorkDir == 0)
  522. return 0;
  523. GetSystemDirectory(g_pWorkDir, MAX_PATH + 1); // SEC:REVIEWED 2002-03-22 : Assumes success
  524. StringCchCat(g_pWorkDir, tmpLength, __TEXT("\\WBEM"));
  525. }
  526. }
  527. if (r.GetStr(__TEXT("Repository Directory"), &g_pDbDir))
  528. {
  529. size_t tmpLength = lstrlen(g_pWorkDir) + lstrlen(__TEXT("\\Repository")) +1; // SEC:REVIEWED 2002-03-22 : OK
  530. g_pDbDir = new TCHAR [tmpLength];
  531. if (g_pDbDir == 0)
  532. return 0;
  533. StringCchPrintf(g_pDbDir, tmpLength, __TEXT("%s\\REPOSITORY"), g_pWorkDir);
  534. r.SetStr(__TEXT("Repository Directory"), g_pDbDir);
  535. }
  536. }
  537. return g_pDbDir;
  538. }
  539. DWORD ConfigMgr::GetMaxMemoryQuota()
  540. {
  541. static DWORD dwMaxMemQuota = CONFIG_MAX_COMMITTED_MEMORY;
  542. static BOOL bCalled = FALSE;
  543. if (!bCalled)
  544. {
  545. Registry r(WBEM_REG_WINMGMT);
  546. if (r.GetDWORD(__TEXT("Max Committed Memory Quota"), &dwMaxMemQuota) == Registry::failed)
  547. r.SetDWORD(__TEXT("Max Committed Memory Quota"), dwMaxMemQuota);
  548. bCalled = TRUE;
  549. }
  550. return dwMaxMemQuota;
  551. }
  552. DWORD ConfigMgr::GetMaxWaitBeforeDenial()
  553. {
  554. //static DWORD dwMaxWaitBeforeDenial = 80000;
  555. static DWORD dwMaxWaitBeforeDenial = 5000;
  556. static BOOL bCalled = FALSE;
  557. if (!bCalled)
  558. {
  559. Registry r(WBEM_REG_WINMGMT);
  560. if (r.GetDWORD(__TEXT("Max Wait Before Denial"), &dwMaxWaitBeforeDenial) == Registry::failed)
  561. r.SetDWORD(__TEXT("Max Wait Before Denial"), dwMaxWaitBeforeDenial);
  562. bCalled = TRUE;
  563. }
  564. return dwMaxWaitBeforeDenial;
  565. }
  566. DWORD ConfigMgr::GetNewTaskResistance()
  567. {
  568. static DWORD dwResistance = 10;
  569. static BOOL bCalled = FALSE;
  570. if (!bCalled)
  571. {
  572. Registry r(WBEM_REG_WINMGMT);
  573. if (r.GetDWORD(__TEXT("New Task Resistance Factor"), &dwResistance) == Registry::failed)
  574. r.SetDWORD(__TEXT("New Task Resistance Factor"), dwResistance);
  575. bCalled = TRUE;
  576. }
  577. return dwResistance;
  578. }
  579. DWORD ConfigMgr::GetUncheckedTaskCount()
  580. {
  581. static DWORD dwUncheckedTaskCount = 50;
  582. static BOOL bCalled = FALSE;
  583. if (!bCalled)
  584. {
  585. Registry r(WBEM_REG_WINMGMT);
  586. if (r.GetDWORD(__TEXT("Unchecked Task Count"), &dwUncheckedTaskCount) == Registry::failed)
  587. r.SetDWORD(__TEXT("Unchecked Task Count"), dwUncheckedTaskCount);
  588. bCalled = TRUE;
  589. }
  590. return dwUncheckedTaskCount;
  591. }
  592. DWORD ConfigMgr::GetMaxTaskCount()
  593. {
  594. static DWORD dwMaxTasks = 5000;
  595. static BOOL bCalled = FALSE;
  596. if (!bCalled)
  597. {
  598. Registry r(WBEM_REG_WINMGMT);
  599. if (r.GetDWORD(__TEXT("Max Tasks"), &dwMaxTasks) == Registry::failed)
  600. r.SetDWORD(__TEXT("Max Tasks"), dwMaxTasks);
  601. bCalled = TRUE;
  602. }
  603. if (dwMaxTasks < 5000)
  604. dwMaxTasks = 5000;
  605. return dwMaxTasks;
  606. }
  607. DWORD ConfigMgr::GetProviderDeliveryTimeout()
  608. {
  609. static DWORD dwDeliveryTimeout = 600000;
  610. static BOOL bCalled = FALSE;
  611. if (!bCalled)
  612. {
  613. Registry r(WBEM_REG_WINMGMT);
  614. if (r.GetDWORD(__TEXT("Provider Delivery Timeout"), &dwDeliveryTimeout) == Registry::failed)
  615. r.SetDWORD(__TEXT("Provider Delivery Timeout"), dwDeliveryTimeout);
  616. bCalled = TRUE;
  617. }
  618. return dwDeliveryTimeout;
  619. }
  620. BOOL ConfigMgr::GetMergerThrottlingEnabled( void )
  621. {
  622. static DWORD dwMergerThrottlingEnabled = TRUE;
  623. static BOOL bCalled = FALSE;
  624. if (!bCalled)
  625. {
  626. Registry r(WBEM_REG_WINMGMT);
  627. // We don't write this one out
  628. r.GetDWORD(__TEXT("Merger Throttling Enabled"), &dwMergerThrottlingEnabled);
  629. bCalled = TRUE;
  630. }
  631. return dwMergerThrottlingEnabled;
  632. }
  633. BOOL ConfigMgr::GetEnableQueryArbitration( void )
  634. {
  635. static DWORD dwEnableQueryArbitration = TRUE;
  636. static BOOL bCalled = FALSE;
  637. if (!bCalled)
  638. {
  639. Registry r(WBEM_REG_WINMGMT);
  640. // We don't write this one out
  641. r.GetDWORD(__TEXT("Merger Query Arbitration Enabled"), &dwEnableQueryArbitration);
  642. bCalled = TRUE;
  643. }
  644. return dwEnableQueryArbitration;
  645. }
  646. BOOL ConfigMgr::GetMergerThresholdValues( DWORD* pdwThrottle, DWORD* pdwRelease, DWORD* pdwBatching )
  647. {
  648. static DWORD dwMergerThrottleThreshold = 10;
  649. static DWORD dwMergerReleaseThreshold = 5;
  650. static DWORD dwBatchingThreshold = 131072; // 128k
  651. static BOOL bCalled = FALSE;
  652. if (!bCalled)
  653. {
  654. // Temporrary stack variable to avboid thready synchronization issues
  655. DWORD dwThrottle = 10;
  656. DWORD dwRelease = 5;
  657. DWORD dwBatching = 131072;
  658. Registry r(WBEM_REG_WINMGMT);
  659. if (r.GetDWORD(__TEXT("Merger Throttling Threshold"), &dwThrottle) == Registry::failed)
  660. r.SetDWORD(__TEXT("Merger Throttling Threshold"), dwThrottle);
  661. if (r.GetDWORD(__TEXT("Merger Release Threshold"), &dwRelease) == Registry::failed)
  662. r.SetDWORD(__TEXT("Merger Release Threshold"), dwRelease);
  663. if (r.GetDWORD(__TEXT("Merger Batching Threshold"), &dwBatching) == Registry::failed)
  664. r.SetDWORD(__TEXT("Merger Batching Threshold"), dwBatching);
  665. if ( dwThrottle < dwRelease )
  666. {
  667. // If the Throttling Threshold is < the Release Threshold, this is not
  668. // valid. Spew something out into the errorlog and default to a release
  669. // which is 50% of the the throttle
  670. ERRORTRACE((LOG_WBEMCORE, "Throttling Threshold values invalid. Release Threshold is greater than Throttle Threshold. Defaulting to 50% of %d.\n", dwThrottle ));
  671. dwRelease = dwThrottle / 2;
  672. }
  673. dwMergerThrottleThreshold = dwThrottle;
  674. dwMergerReleaseThreshold = dwRelease;
  675. dwBatchingThreshold = dwBatching;
  676. bCalled = TRUE;
  677. }
  678. *pdwThrottle = dwMergerThrottleThreshold;
  679. *pdwRelease = dwMergerReleaseThreshold;
  680. *pdwBatching = dwBatchingThreshold;
  681. return bCalled;
  682. }
  683. /*
  684. * ==================================================================================================
  685. |
  686. | ULONG ConfigMgr::GetMinimumMemoryRequirements ( )
  687. | -------------------------------------------------
  688. | Returns minimum memory requirements for WMI. Currently defined as:
  689. |
  690. | ARB_DEFAULT_SYSTEM_MINIMUM 0x1E8480
  691. |
  692. | 2Mb
  693. |
  694. |
  695. * ==================================================================================================
  696. */
  697. ULONG ConfigMgr::GetMinimumMemoryRequirements ( )
  698. {
  699. return ARB_DEFAULT_SYSTEM_MINIMUM ;
  700. }
  701. BOOL ConfigMgr::GetArbitratorValues( DWORD* pdwEnabled, DWORD* pdwSystemHigh, DWORD* pdwMaxSleep,
  702. double* pdHighThreshold1, long* plMultiplier1, double* pdHighThreshold2,
  703. long* plMultiplier2, double* pdHighThreshold3, long* plMultiplier3 )
  704. {
  705. static DWORD dwArbThrottlingEnabled = 1;
  706. static DWORD uArbSystemHigh = ARB_DEFAULT_SYSTEM_HIGH_FACTOR;
  707. static DWORD dwArbMaxSleepTime = ARB_DEFAULT_MAX_SLEEP_TIME;
  708. static double dArbThreshold1 = ARB_DEFAULT_HIGH_THRESHOLD1 / (double) 100;
  709. static long lArbThreshold1Mult = ARB_DEFAULT_HIGH_THRESHOLD1MULT;
  710. static double dArbThreshold2 = ARB_DEFAULT_HIGH_THRESHOLD2 / (double) 100;
  711. static long lArbThreshold2Mult = ARB_DEFAULT_HIGH_THRESHOLD2MULT;
  712. static double dArbThreshold3 = ARB_DEFAULT_HIGH_THRESHOLD3 / (double) 100;
  713. static long lArbThreshold3Mult = ARB_DEFAULT_HIGH_THRESHOLD3MULT;
  714. static BOOL bCalled = FALSE;
  715. if (!bCalled)
  716. {
  717. // Temporrary stack variable to avoid thread synchronization issues
  718. DWORD dwThrottlingEnabled = 1;
  719. DWORD uSystemHigh = ARB_DEFAULT_SYSTEM_HIGH_FACTOR;
  720. DWORD dwMaxSleepTime = ARB_DEFAULT_MAX_SLEEP_TIME;
  721. double dThreshold1 = ARB_DEFAULT_HIGH_THRESHOLD1 / (double) 100;
  722. DWORD dwThreshold1Mult = ARB_DEFAULT_HIGH_THRESHOLD1MULT;
  723. double dThreshold2 = ARB_DEFAULT_HIGH_THRESHOLD2 / (double) 100;
  724. DWORD dwThreshold2Mult = ARB_DEFAULT_HIGH_THRESHOLD2MULT;
  725. double dThreshold3 = ARB_DEFAULT_HIGH_THRESHOLD3 / (double) 100;
  726. DWORD dwThreshold3Mult = ARB_DEFAULT_HIGH_THRESHOLD3MULT;
  727. Registry r(WBEM_REG_WINMGMT);
  728. // Throttling Enabled - Don't write this if it doesn't exist
  729. r.GetDWORD(__TEXT("ArbThrottlingEnabled"), &dwThrottlingEnabled);
  730. // System High Max Limit
  731. if (r.GetDWORD(__TEXT("ArbSystemHighMaxLimitFactor"), &uSystemHigh) == Registry::failed)
  732. //r.SetDWORD(__TEXT("ArbSystemHighMaxLimitFactor"), uSystemHigh);
  733. // Max Sleep Time
  734. if (r.GetDWORD(__TEXT("ArbTaskMaxSleep"), &dwMaxSleepTime) == Registry::failed)
  735. r.SetDWORD(__TEXT("ArbTaskMaxSleep"), dwMaxSleepTime);
  736. // High Threshold 1
  737. DWORD dwTmp = ARB_DEFAULT_HIGH_THRESHOLD1;
  738. if (r.GetDWORD(__TEXT("ArbSystemHighThreshold1"), &dwTmp) == Registry::failed)
  739. r.SetDWORD(__TEXT("ArbSystemHighThreshold1"), dwTmp);
  740. dThreshold1 = dwTmp / (double) 100;
  741. // High Threshold Multiplier 1
  742. if (r.GetDWORD(__TEXT("ArbSystemHighThreshold1Mult"), &dwThreshold1Mult) == Registry::failed)
  743. r.SetDWORD(__TEXT("ArbSystemHighThreshold1Mult"), dwThreshold1Mult);
  744. // High Threshold 2
  745. dwTmp = ARB_DEFAULT_HIGH_THRESHOLD2;
  746. if (r.GetDWORD(__TEXT("ArbSystemHighThreshold2"), &dwTmp) == Registry::failed)
  747. r.SetDWORD(__TEXT("ArbSystemHighThreshold2"), dwTmp);
  748. dThreshold2 = dwTmp / (double) 100;
  749. // High Threshold Multiplier 2
  750. if (r.GetDWORD(__TEXT("ArbSystemHighThreshold2Mult"), &dwThreshold2Mult) == Registry::failed)
  751. r.SetDWORD(__TEXT("ArbSystemHighThreshold2Mult"), dwThreshold2Mult);
  752. // High Threshold 3
  753. dwTmp = ARB_DEFAULT_HIGH_THRESHOLD3;
  754. if (r.GetDWORD(__TEXT("ArbSystemHighThreshold3"), &dwTmp) == Registry::failed)
  755. r.SetDWORD(__TEXT("ArbSystemHighThreshold3"), dwTmp);
  756. dThreshold3 = dwTmp / (double) 100;
  757. // High Threshold Multiplier 3
  758. if (r.GetDWORD(__TEXT("ArbSystemHighThreshold3Mult"), &dwThreshold3Mult) == Registry::failed)
  759. r.SetDWORD(__TEXT("ArbSystemHighThreshold3Mult"), dwThreshold3Mult);
  760. // Store the statics
  761. dwArbThrottlingEnabled = dwThrottlingEnabled;
  762. uArbSystemHigh = uSystemHigh;
  763. dwArbMaxSleepTime = dwMaxSleepTime;
  764. dArbThreshold1 = dThreshold1;
  765. lArbThreshold1Mult = dwThreshold1Mult;
  766. dArbThreshold2 = dThreshold2;
  767. lArbThreshold2Mult = dwThreshold2Mult;
  768. dArbThreshold3 = dThreshold3;
  769. lArbThreshold3Mult = dwThreshold3Mult;
  770. bCalled = TRUE;
  771. }
  772. *pdwEnabled = dwArbThrottlingEnabled;
  773. *pdwSystemHigh = uArbSystemHigh;
  774. *pdwMaxSleep = dwArbMaxSleepTime;
  775. *pdHighThreshold1 = dArbThreshold1;
  776. *plMultiplier1 = lArbThreshold1Mult;
  777. *pdHighThreshold2 = dArbThreshold2;
  778. *plMultiplier2 = lArbThreshold2Mult;
  779. *pdHighThreshold3 = dArbThreshold3;
  780. *plMultiplier3 = lArbThreshold3Mult;
  781. return bCalled;
  782. }
  783. BOOL ConfigMgr::GetEnableArbitratorDiagnosticThread( void )
  784. {
  785. BOOL fArbDiagnosticThreadEnabled = FALSE;
  786. Registry r(WBEM_REG_WINMGMT);
  787. LPTSTR pPath = 0;
  788. if ( r.GetStr(__TEXT("Task Log File"), &pPath) == Registry::no_error )
  789. {
  790. fArbDiagnosticThreadEnabled = TRUE;
  791. delete [] pPath;
  792. pPath = NULL;
  793. }
  794. return fArbDiagnosticThreadEnabled;
  795. }
  796. //******************************************************************************
  797. //
  798. //******************************************************************************
  799. //
  800. HRESULT ConfigMgr::GetDefaultRepDriverClsId(CLSID &clsid)
  801. {
  802. Registry r(WBEM_REG_WINMGMT);
  803. TCHAR *pClsIdStr = 0;
  804. TCHAR *pJetClsId = __TEXT("{7998dc37-d3fe-487c-a60a-7701fcc70cc6}");
  805. HRESULT hRes;
  806. if (r.GetStr(__TEXT("Default Repository Driver"), &pClsIdStr))
  807. {
  808. // If here, default to Jet ESE for now.
  809. // =====================================
  810. r.SetStr(__TEXT("Default Repository Driver"), pJetClsId);
  811. hRes = CLSIDFromString(pJetClsId, &clsid);
  812. return hRes;
  813. }
  814. // If here, we actually retrieved one.
  815. // ===================================
  816. hRes = CLSIDFromString(pClsIdStr, &clsid);
  817. delete [] pClsIdStr;
  818. return hRes;
  819. }
  820. //******************************************************************************
  821. //
  822. // See cfgmgr.h for documentation
  823. //
  824. //******************************************************************************
  825. DWORD ConfigMgr::InitSystem()
  826. {
  827. HRESULT hres;
  828. DEBUGTRACE((LOG_WBEMCORE, "+ ConfigMgr::InitSystem()\n"));
  829. GetSystemLimits();
  830. g_hresForClients = WBEM_E_CRITICAL_ERROR;
  831. g_pEventLog = new CEventLog;
  832. if (g_pEventLog == 0)
  833. return WBEM_E_OUT_OF_MEMORY;
  834. g_pEventLog->Open();
  835. g_hOpenForClients = CreateEvent(NULL, TRUE, FALSE, NULL);
  836. if (NULL == g_hOpenForClients) return WBEM_E_OUT_OF_MEMORY;
  837. // Init Arbitrator. Before the queue, since there is this dependecy now
  838. // ================
  839. _IWmiArbitrator * pTempArb = NULL;
  840. hres = CWmiArbitrator::Initialize(&pTempArb);
  841. CReleaseMe rmArb(pTempArb);
  842. if (FAILED(hres))
  843. {
  844. ERRORTRACE((LOG_WBEMCORE, "Arbitrator initialization returned failure <0x%X>!\n", hres));
  845. return hres;
  846. }
  847. // Create service queue objects
  848. // ============================
  849. g_pAsyncSvcQueue = new CAsyncServiceQueue(pTempArb);
  850. if (g_pAsyncSvcQueue == NULL ||
  851. !g_pAsyncSvcQueue->IsInit())
  852. {
  853. return WBEM_E_OUT_OF_MEMORY;
  854. }
  855. hres = CoGetClassObject(CLSID_WbemContext, CLSCTX_INPROC_SERVER, // SEC:REVIEWED 2002-03-22 : OK
  856. NULL, IID_IClassFactory, (void**)&g_pContextFac);
  857. if(FAILED(hres))
  858. {
  859. ERRORTRACE((LOG_WBEMCORE,"CRITICAL ERROR: cannot create contexts: %X\n", hres));
  860. return WBEM_E_CRITICAL_ERROR;
  861. }
  862. hres = CoGetClassObject(CLSID_WbemDefPath, CLSCTX_INPROC_SERVER, // SEC:REVIEWED 2002-03-22 : OK
  863. NULL, IID_IClassFactory, (void**)&g_pPathFac);
  864. if(FAILED(hres))
  865. {
  866. ERRORTRACE((LOG_WBEMCORE,"CRITICAL ERROR: cannot create paths: %X\n", hres));
  867. return WBEM_E_CRITICAL_ERROR;
  868. }
  869. hres = CoGetClassObject(CLSID_WbemQuery, CLSCTX_INPROC_SERVER,
  870. NULL,IID_IClassFactory, (void **) &g_pQueryFact);
  871. if(FAILED(hres))
  872. {
  873. ERRORTRACE((LOG_WBEMCORE,"CRITICAL ERROR: cannot create Query Parser: %X\n", hres));
  874. return WBEM_E_CRITICAL_ERROR;
  875. }
  876. //
  877. // Must lock it to keep fastprox in memory!
  878. //
  879. g_pContextFac->LockServer(TRUE);
  880. g_pPathFac->LockServer(TRUE);
  881. g_pQueryFact->LockServer(TRUE);
  882. // Read registry and get system info.
  883. // ==================================
  884. DEBUGTRACE((LOG_WBEMCORE,"Reading config info from registry\n"));
  885. Registry r(WBEM_REG_WINMGMT);
  886. if (r.GetStr(__TEXT("Working Directory"), &g_pWorkDir))
  887. {
  888. size_t tmpLength = MAX_PATH + 1 + lstrlen(__TEXT("\\WBEM")); // SEC:REVIEWED 2002-03-22 : OK
  889. g_pWorkDir = new TCHAR[tmpLength];
  890. if (NULL == g_pWorkDir)
  891. return WBEM_E_OUT_OF_MEMORY;
  892. GetSystemDirectory(g_pWorkDir, MAX_PATH + 1); // SEC:REVIEWED 2002-03-22 : Needs check for success
  893. StringCchCat(g_pWorkDir, tmpLength, __TEXT("\\WBEM"));
  894. }
  895. if (r.GetStr(__TEXT("Repository Directory"), &g_pDbDir))
  896. {
  897. size_t tmpLength = lstrlen(g_pWorkDir) + lstrlen(__TEXT("\\Repository")) +1; // SEC:REVIEWED 2002-03-22 : OK
  898. g_pDbDir = new TCHAR [tmpLength];
  899. if (NULL == g_pDbDir)
  900. return WBEM_E_OUT_OF_MEMORY;
  901. StringCchPrintf(g_pDbDir, tmpLength, __TEXT("%s\\Repository"), g_pWorkDir);
  902. r.SetStr(__TEXT("Repository Directory"), g_pDbDir);
  903. }
  904. // Write build info to the registry.
  905. // =================================
  906. TCHAR tchDateTime[30];
  907. StringCchPrintf(tchDateTime, 30, __TEXT("%S %S"), __DATE__, __TIME__);
  908. TCHAR * pCurrVal = NULL;
  909. int iRet = r.GetStr(__TEXT("Build"), &pCurrVal);
  910. if(iRet == Registry::failed || wbem_wcsicmp(pCurrVal, tchDateTime))
  911. r.SetStr(__TEXT("Build"), tchDateTime );
  912. if(iRet == Registry::no_error)
  913. delete pCurrVal;
  914. // The Database directory: same permission as the repository
  915. DEBUGTRACE((LOG_WBEMCORE,"Database location = <%S>\n", g_pDbDir));
  916. TCHAR * pString = __TEXT("D:P(A;CIOI;GA;;;BA)(A;CIOI;GA;;;SY)");
  917. HRESULT hRes = TestDirExistAndCreateWithSDIfNotThere(g_pDbDir, pString);
  918. if (FAILED(hRes))
  919. {
  920. ERRORTRACE((LOG_WBEMCORE,"TestDirExistAndCreateWithSDIfNotThere %S hr %08x\n",g_pDbDir,hRes));
  921. return hRes;
  922. }
  923. // The Loggingdirectory: same permission as the repository
  924. TCHAR * pLogDir = NULL;
  925. if (r.GetStr(__TEXT("Logging Directory"), &pLogDir))
  926. {
  927. size_t tmpLength = MAX_PATH + 1 + lstrlen(__TEXT("\\wbem\\Logs")); // SEC:REVIEWED 2002-03-22 : OK
  928. pLogDir = new TCHAR[tmpLength];
  929. if (NULL == pLogDir)
  930. return WBEM_E_OUT_OF_MEMORY;
  931. GetSystemDirectory(pLogDir, MAX_PATH + 1); // SEC:REVIEWED 2002-03-22 : Needs check on return code
  932. StringCchCat(pLogDir, tmpLength, __TEXT("\\wbem\\Logs"));
  933. }
  934. wmilib::auto_buffer<TCHAR> dm(pLogDir);
  935. // remove trailing BackSlash
  936. DWORD dwLast = lstrlen(pLogDir); // SEC:REVIEWED 2002-03-22 : OK or we wouldn't be here
  937. if (dwLast > 3 && pLogDir[dwLast-1] == __TEXT('\\')) pLogDir[dwLast-1] = 0;
  938. pString = __TEXT("D:P(A;CIOI;GA;;;BA)(A;CIOI;GA;;;SY)(A;CIOI;GRGW;;;NS)(A;CIOI;GRGW;;;LS)");
  939. hRes = TestDirExistAndCreateWithSDIfNotThere(pLogDir, pString);
  940. if (FAILED(hRes))
  941. {
  942. ERRORTRACE((LOG_WBEMCORE,"TestDirExistAndCreateWithSDIfNotThere %S hr %08x\n",pLogDir,hRes));
  943. return hRes;
  944. }
  945. // The Autorecover directory: same permission as the repository
  946. DWORD dwLen = lstrlen(g_pWorkDir); // SEC:REVIEWED 2002-03-22 : OK, or we wouldn't be here
  947. size_t tmpLength = dwLen + 1 + lstrlen(__TEXT("\\AutoRecover")); // SEC:REVIEWED 2002-03-22 : OK
  948. g_pAutorecoverDir = new TCHAR[tmpLength];
  949. if (NULL == g_pAutorecoverDir) return WBEM_E_OUT_OF_MEMORY;
  950. StringCchCopy(g_pAutorecoverDir,tmpLength, g_pWorkDir);
  951. StringCchCat(g_pAutorecoverDir,tmpLength, __TEXT("\\AutoRecover")); // SEC:REVIEWED 2002-03-22 : OK
  952. pString =__TEXT("D:P(A;CIOI;GA;;;BA)(A;CIOI;GA;;;SY)");
  953. hRes = TestDirExistAndCreateWithSDIfNotThere(g_pAutorecoverDir, pString);
  954. if (FAILED(hRes))
  955. {
  956. ERRORTRACE((LOG_WBEMCORE,"TestDirExistAndCreateWithSDIfNotThere %S hr %08x\n",g_pAutorecoverDir,hRes));
  957. return hRes;
  958. }
  959. // The HotMof same permission as the autorecover
  960. TCHAR * pMofDir = NULL;
  961. if (r.GetStr(__TEXT("MOF Self-Install Directory"), &pMofDir))
  962. {
  963. size_t tmpLength = MAX_PATH + 1 + lstrlen(__TEXT("\\wbem\\mof")); // SEC:REVIEWED 2002-03-22 : OK
  964. pMofDir = new TCHAR[tmpLength];
  965. if (NULL == pMofDir)
  966. return WBEM_E_OUT_OF_MEMORY;
  967. GetSystemDirectory(pMofDir, MAX_PATH + 1); // SEC:REVIEWED 2002-03-22 : No check
  968. StringCchCat(pMofDir, tmpLength, __TEXT("\\wbem\\mof"));
  969. }
  970. wmilib::auto_buffer<TCHAR> dm1(pMofDir);
  971. pString =__TEXT("D:P(A;CIOI;GA;;;BA)(A;CIOI;GA;;;SY)");
  972. hRes = TestDirExistAndCreateWithSDIfNotThere(pMofDir, pString);
  973. if (FAILED(hRes))
  974. {
  975. ERRORTRACE((LOG_WBEMCORE,"TestDirExistAndCreateWithSDIfNotThere %S hr %08x\n",pMofDir,hRes));
  976. return hRes;
  977. }
  978. // Open/create the database.
  979. // =========================
  980. hRes = InitSubsystems();
  981. if (FAILED(hRes)) return hRes;
  982. // Done.
  983. // =====
  984. DEBUGTRACE((LOG_WBEMCORE, "- ConfigMgr::InitSystem()\n"));
  985. return WBEM_NO_ERROR;
  986. }
  987. //******************************************************************************
  988. //
  989. // See cfgmgr.h for documentation
  990. //
  991. //******************************************************************************
  992. DWORD ConfigMgr::Shutdown(BOOL bProcessShutdown, BOOL bIsSystemShutDown)
  993. {
  994. g_bDontAllowNewConnections = TRUE;
  995. ShutdownSubsystems(bIsSystemShutDown);
  996. if (!bIsSystemShutDown)
  997. {
  998. DEBUGTRACE((LOG_WBEMCORE, "+ ConfigMgr::Shutdown(%d,%d)\n",bProcessShutdown,bIsSystemShutDown));
  999. if(g_pAsyncSvcQueue)
  1000. {
  1001. CInCritSec ics(&g_csEss);
  1002. g_pAsyncSvcQueue->Shutdown(bIsSystemShutDown);
  1003. g_pAsyncSvcQueue->Release();
  1004. g_pAsyncSvcQueue = NULL;
  1005. }
  1006. if (g_pContextFac)
  1007. {
  1008. //
  1009. // Must unlock it to allow fastprox to go away
  1010. //
  1011. g_pContextFac->LockServer(FALSE);
  1012. g_pContextFac->Release();
  1013. g_pContextFac = NULL;
  1014. }
  1015. if (g_pPathFac)
  1016. {
  1017. // Must unlock it to allow wmiutils to go away
  1018. g_pPathFac->LockServer(FALSE);
  1019. g_pPathFac->Release();
  1020. g_pPathFac = NULL;
  1021. }
  1022. if (g_pQueryFact)
  1023. {
  1024. // Must unlock it to allow wmiutils to go away
  1025. g_pQueryFact->LockServer(FALSE);
  1026. g_pQueryFact->Release();
  1027. g_pQueryFact = NULL;
  1028. }
  1029. if (g_pEventLog)
  1030. {
  1031. g_pEventLog->Close();
  1032. delete g_pEventLog;
  1033. g_pEventLog = NULL;
  1034. }
  1035. delete [] g_pDbDir;
  1036. g_pDbDir = NULL;
  1037. delete [] g_pWorkDir;
  1038. g_pWorkDir = NULL;
  1039. delete [] g_pAutorecoverDir;
  1040. g_pAutorecoverDir = NULL;
  1041. if (g_hOpenForClients)
  1042. {
  1043. CloseHandle(g_hOpenForClients);
  1044. g_hOpenForClients = NULL;
  1045. }
  1046. DEBUGTRACE((LOG_WBEMCORE, "- ConfigMgr::Shutdown\n"));
  1047. }
  1048. return WBEM_NO_ERROR;
  1049. }
  1050. //******************************************************************************
  1051. //
  1052. // See cfgmgr.h for documentation
  1053. //
  1054. //******************************************************************************
  1055. BOOL ConfigMgr::GetDllVersion(TCHAR * pDLLName, TCHAR * pResStringName,
  1056. WCHAR * pRes, DWORD dwResSize)
  1057. {
  1058. // Extract Version informatio
  1059. DWORD dwTemp, dwSize = MAX_PATH;
  1060. TCHAR cName[MAX_PATH];
  1061. BOOL bRet = FALSE;
  1062. // rajeshr : Fix for Prefix Bug# 144470
  1063. cName[0] = NULL;
  1064. int iLen = 0;
  1065. if(g_pWorkDir)
  1066. iLen = wcslen(g_pWorkDir); // SEC:REVIEWED 2002-03-22 : OK, provably has null terminator
  1067. iLen += wcslen(pDLLName) + 2; // SEC:REVIEWED 2002-03-22 : OK, provably a compiled const string
  1068. if(iLen > MAX_PATH)
  1069. return FALSE;
  1070. if(g_pWorkDir)
  1071. StringCchCopy(cName, MAX_PATH, g_pWorkDir);
  1072. StringCchCat(cName,MAX_PATH, __TEXT("\\"));
  1073. StringCchCat(cName, MAX_PATH, pDLLName);
  1074. long lSize = GetFileVersionInfoSize(cName, &dwTemp);
  1075. if(lSize < 1)
  1076. return FALSE;
  1077. TCHAR * pBlock = new TCHAR[lSize];
  1078. if(pBlock != NULL)
  1079. {
  1080. CDeleteMe<TCHAR> dm(pBlock);
  1081. try
  1082. {
  1083. bRet = GetFileVersionInfo(cName, NULL, lSize, pBlock);
  1084. if(bRet)
  1085. {
  1086. TCHAR lpSubBlock[MAX_PATH];
  1087. TCHAR * lpBuffer = NULL;
  1088. UINT wBuffSize = MAX_PATH;
  1089. short * piStuff;
  1090. bRet = VerQueryValue(pBlock, __TEXT("\\VarFileInfo\\Translation") , (void**)&piStuff, &wBuffSize);
  1091. if(bRet)
  1092. {
  1093. StringCchPrintf(lpSubBlock,MAX_PATH, __TEXT("\\StringFileInfo\\%04x%04x\\%s"),piStuff[0], piStuff[1],__TEXT("ProductVersion"));
  1094. bRet = VerQueryValue(pBlock, lpSubBlock, (void**)&lpBuffer, &wBuffSize);
  1095. }
  1096. if(bRet == FALSE)
  1097. {
  1098. // Try again in english
  1099. StringCchPrintf(lpSubBlock, MAX_PATH, __TEXT("\\StringFileInfo\\040904E4\\%s"),pResStringName);
  1100. bRet = VerQueryValue(pBlock, lpSubBlock,(void**)&lpBuffer, &wBuffSize);
  1101. }
  1102. if(bRet)
  1103. StringCchCopy(pRes, dwResSize, lpBuffer);
  1104. }
  1105. }
  1106. catch(...)
  1107. {
  1108. ExceptionCounter c;
  1109. return FALSE;
  1110. }
  1111. }
  1112. return bRet;
  1113. }
  1114. //******************************************************************************
  1115. //
  1116. // See cfgmgr.h for documentation
  1117. //
  1118. //******************************************************************************
  1119. CEventLog* ConfigMgr::GetEventLog()
  1120. {
  1121. return g_pEventLog;
  1122. }
  1123. //***************************************************************************
  1124. //
  1125. // GetPersistentCfgValue
  1126. //
  1127. // Gets an item from persistent storage ($WINMGMT.cfg)
  1128. //
  1129. //***************************************************************************
  1130. BOOL ConfigMgr::GetPersistentCfgValue(DWORD dwOffset, DWORD &dwValue)
  1131. {
  1132. return g_persistConfig.GetPersistentCfgValue(dwOffset, dwValue);
  1133. }
  1134. //***************************************************************************
  1135. //
  1136. // GetPersistentCfgValue
  1137. //
  1138. // Sets an item from persistent storage ($WinMgmt.cfg)
  1139. //
  1140. //***************************************************************************
  1141. BOOL ConfigMgr::SetPersistentCfgValue(DWORD dwOffset, DWORD dwValue)
  1142. {
  1143. return g_persistConfig.SetPersistentCfgValue(dwOffset, dwValue);
  1144. }
  1145. //***************************************************************************
  1146. //
  1147. // GetAutoRecoverMofsCleanDB
  1148. //
  1149. // Retrieve a list of MOFs which need to be loaded when we have
  1150. // have an empty database. User needs to "delete []" the
  1151. // returned string. String is in a REG_MULTI_SZ format.
  1152. //
  1153. //***************************************************************************
  1154. TCHAR* ConfigMgr::GetAutoRecoverMofs(DWORD &dwSize)
  1155. {
  1156. Registry r(WBEM_REG_WINMGMT);
  1157. return r.GetMultiStr(__TEXT("Autorecover MOFs"), dwSize);
  1158. }
  1159. BOOL ConfigMgr::GetAutoRecoverDateTimeStamp(LARGE_INTEGER &liDateTimeStamp)
  1160. {
  1161. Registry r(WBEM_REG_WINMGMT);
  1162. TCHAR *pszTimestamp = NULL;
  1163. if ((r.GetStr(__TEXT("Autorecover MOFs timestamp"), &pszTimestamp) == Registry::no_error) &&
  1164. pszTimestamp)
  1165. {
  1166. liDateTimeStamp.QuadPart = _wtoi64(pszTimestamp);
  1167. delete [] pszTimestamp;
  1168. return TRUE;
  1169. }
  1170. return FALSE;
  1171. }
  1172. //***************************************************************************
  1173. //
  1174. // PrepareForClients
  1175. //
  1176. // Once the system is in the initialized state (SetReady has succeeded), this
  1177. // function is called to prepare the system for real clients. This involves
  1178. // pre-compiling the MOFs, etc.
  1179. //
  1180. //***************************************************************************
  1181. HRESULT ConfigMgr::PrepareForClients(long lFlags)
  1182. {
  1183. ReadMaxQueueSize();
  1184. g_hresForClients = WBEM_S_NO_ERROR;
  1185. SetEvent(g_hOpenForClients);
  1186. return g_hresForClients;
  1187. }
  1188. HRESULT ConfigMgr::WaitUntilClientReady()
  1189. {
  1190. WaitForSingleObject(g_hOpenForClients, INFINITE);
  1191. return g_hresForClients;
  1192. }
  1193. void ConfigMgr::ReadMaxQueueSize()
  1194. {
  1195. Registry r(WBEM_REG_WINMGMT);
  1196. // Get the database backup intervals (in minutes)
  1197. if (r.GetDWORDStr(__TEXT("Max Async Result Queue Size"), &g_dwQueueSize) == Registry::failed)
  1198. {
  1199. r.SetDWORDStr(__TEXT("Max Async Result Queue Size"), CONFIG_DEFAULT_QUEUE_SIZE);
  1200. g_dwQueueSize = CONFIG_DEFAULT_QUEUE_SIZE;
  1201. }
  1202. }
  1203. DWORD ConfigMgr::GetMaxQueueSize()
  1204. {
  1205. return g_dwQueueSize;
  1206. }
  1207. //
  1208. //
  1209. //////////////////////////////////////////////////////////////////////////////////
  1210. IWbemPath *ConfigMgr::GetNewPath()
  1211. {
  1212. HRESULT hres;
  1213. if(g_pPathFac == NULL)
  1214. return NULL;
  1215. IWbemPath* pPath = NULL;
  1216. hres = g_pPathFac->CreateInstance(NULL, IID_IWbemPath, (void**)&pPath);
  1217. if(FAILED(hres))
  1218. {
  1219. ERRORTRACE((LOG_WBEMCORE,"CRITICAL ERROR: cannot create paths: %X\n", hres));
  1220. return NULL;
  1221. }
  1222. return pPath;
  1223. }
  1224. //
  1225. //
  1226. //////////////////////////////////////////////////////////////////////////////////
  1227. void ConfigMgr::GetSystemLimits()
  1228. {
  1229. LONG lRes;
  1230. HKEY hKey;
  1231. lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE,WBEM_REG_WINMGMT,0,KEY_READ,&hKey);
  1232. if (ERROR_SUCCESS != lRes) return;
  1233. CRegCloseMe cm(hKey);
  1234. DWORD dwType;
  1235. DWORD dwSize = sizeof(DWORD);
  1236. DWORD dwVal;
  1237. if (ERROR_SUCCESS == RegQueryValueExW(hKey,MAX_IDENTIFIER_WBEM,0,&dwType,(BYTE*)&dwVal,&dwSize))
  1238. {
  1239. if (REG_DWORD == dwType)
  1240. {
  1241. if (dwVal < MINIMUM_MAX_IDENTIFIER)
  1242. g_IdentifierLimit = MINIMUM_MAX_IDENTIFIER;
  1243. else
  1244. g_IdentifierLimit = dwVal;
  1245. }
  1246. }
  1247. dwSize = sizeof(DWORD);
  1248. if (ERROR_SUCCESS == RegQueryValueExW(hKey,MAX_QUERY_WBEM,0,&dwType,(BYTE*)&dwVal,&dwSize))
  1249. {
  1250. if (REG_DWORD == dwType)
  1251. {
  1252. if (dwVal < MINIMUM_MAX_QUERY)
  1253. g_QueryLimit = MINIMUM_MAX_QUERY;
  1254. else
  1255. g_QueryLimit = dwVal;
  1256. }
  1257. }
  1258. dwSize = sizeof(DWORD);
  1259. if (ERROR_SUCCESS == RegQueryValueExW(hKey,MAX_PATH_WBEM,0,&dwType,(BYTE*)&dwVal,&dwSize))
  1260. {
  1261. if (REG_DWORD == dwType)
  1262. {
  1263. if (dwVal < g_IdentifierLimit+CLASSNAME_ADJUSTMENT)
  1264. g_PathLimit = g_IdentifierLimit+CLASSNAME_ADJUSTMENT;
  1265. else
  1266. g_PathLimit = dwVal;
  1267. }
  1268. }
  1269. };
  1270. void ConfigMgr::SetDefaultMofLoadingNeeded()
  1271. {
  1272. g_bDefaultMofLoadingNeeded = true;
  1273. }
  1274. //
  1275. //
  1276. // the Implementation of the Hook Class
  1277. //
  1278. /////////////////////////////////////////////////
  1279. CRAHooks::CRAHooks(_IWmiCoreServices *pSvc)
  1280. :m_pSvc(pSvc),
  1281. m_cRef(1)
  1282. {
  1283. if (m_pSvc)
  1284. m_pSvc->AddRef();
  1285. }
  1286. CRAHooks::~CRAHooks()
  1287. {
  1288. if (m_pSvc)
  1289. m_pSvc->Release();
  1290. }
  1291. STDMETHODIMP
  1292. CRAHooks::QueryInterface(REFIID riid, void ** ppv)
  1293. {
  1294. if (!ppv)
  1295. return E_POINTER;
  1296. if (riid == IID_IUnknown ||
  1297. riid == IID__IWmiCoreWriteHook)
  1298. {
  1299. *ppv = this;
  1300. AddRef();
  1301. return S_OK;
  1302. }
  1303. return E_NOINTERFACE;
  1304. };
  1305. ULONG STDMETHODCALLTYPE
  1306. CRAHooks::AddRef()
  1307. {
  1308. return InterlockedIncrement(&m_cRef);
  1309. }
  1310. ULONG STDMETHODCALLTYPE
  1311. CRAHooks::Release()
  1312. {
  1313. LONG lRet = InterlockedDecrement(&m_cRef);
  1314. if (0 == lRet)
  1315. {
  1316. delete this;
  1317. return 0;
  1318. }
  1319. return lRet;
  1320. }
  1321. STDMETHODIMP
  1322. CRAHooks::PostPut(long lFlags, HRESULT hApiResult,
  1323. IWbemContext* pContext,
  1324. IWbemPath* pPath, LPCWSTR wszNamespace,
  1325. LPCWSTR wszClass, _IWmiObject* pNew,
  1326. _IWmiObject* pOld)
  1327. {
  1328. //
  1329. // Here we want to do something
  1330. //
  1331. HRESULT hRes = WBEM_S_NO_ERROR;
  1332. if (SUCCEEDED(hApiResult))
  1333. {
  1334. if (0 == wbem_wcsicmp(GUARDED_NAMESPACE,wszNamespace))
  1335. {
  1336. BOOL bIsInDerivation = FALSE;
  1337. if (WBEM_S_NO_ERROR == pNew->InheritsFrom(GUARDED_CLASS))
  1338. {
  1339. bIsInDerivation = TRUE;
  1340. }
  1341. //
  1342. // check qualifiers
  1343. //
  1344. if (bIsInDerivation)
  1345. {
  1346. HRESULT hRes1;
  1347. IWbemQualifierSet * pQualSet = NULL;
  1348. hRes1 = pNew->GetQualifierSet(&pQualSet);
  1349. if (SUCCEEDED(hRes1))
  1350. {
  1351. VARIANT Var;
  1352. VariantInit(&Var);
  1353. hRes1 = pQualSet->Get(GUARDED_HIPERF,0,&Var,NULL);
  1354. if (WBEM_S_NO_ERROR == hRes1 &&
  1355. (V_VT(&Var) == VT_BOOL) &&
  1356. (V_BOOL(&Var) == VARIANT_TRUE))
  1357. {
  1358. // variant does not own memory so far
  1359. hRes1 = pQualSet->Get(GUARDED_PERFCTR,0,&Var,NULL);
  1360. if (WBEM_E_NOT_FOUND == hRes1)
  1361. {
  1362. //
  1363. // here is our class that has been added
  1364. //
  1365. HMODULE hWmiSvc = GetModuleHandleW(WMISVC_DLL);
  1366. if (hWmiSvc)
  1367. {
  1368. DWORD (__stdcall * fnDredgeRA)(VOID * pVoid);
  1369. fnDredgeRA = (DWORD (__stdcall * )(VOID * pVoid))GetProcAddress(hWmiSvc,FUNCTION_DREDGERA);
  1370. if (fnDredgeRA)
  1371. {
  1372. fnDredgeRA(NULL);
  1373. }
  1374. }
  1375. else
  1376. {
  1377. // be nice towards winmgmt.exe and do not propagate errors
  1378. }
  1379. }
  1380. }
  1381. VariantClear(&Var);
  1382. pQualSet->Release();
  1383. }
  1384. else
  1385. {
  1386. hRes = hRes1; // class with no qualifier set is BAD, propagate
  1387. }
  1388. }
  1389. }
  1390. }
  1391. return hRes;
  1392. }
  1393. STDMETHODIMP
  1394. CRAHooks::PreDelete(long lFlags, long lUserFlags,
  1395. IWbemContext* pContext,
  1396. IWbemPath* pPath, LPCWSTR wszNamespace,
  1397. LPCWSTR wszClass)
  1398. {
  1399. return WBEM_S_NO_ERROR;
  1400. }
  1401. STDMETHODIMP
  1402. CRAHooks::PostDelete(long lFlags,
  1403. HRESULT hApiResult,
  1404. IWbemContext* pContext,
  1405. IWbemPath* pPath, LPCWSTR wszNamespace,
  1406. LPCWSTR wszClass, _IWmiObject* pOld)
  1407. {
  1408. return WBEM_S_NO_ERROR;
  1409. }
  1410. STDMETHODIMP
  1411. CRAHooks::PrePut(long lFlags, long lUserFlags,
  1412. IWbemContext* pContext,
  1413. IWbemPath* pPath, LPCWSTR wszNamespace,
  1414. LPCWSTR wszClass, _IWmiObject* pCopy)
  1415. {
  1416. return WBEM_S_NO_ERROR;
  1417. }
  1418. //
  1419. //
  1420. // function for instaling the Hook
  1421. //
  1422. ///////////////////////////////////////////////////////////
  1423. HRESULT InitRAHooks(_IWmiCoreServices *pSvc)
  1424. {
  1425. HRESULT hRes = WBEM_S_NO_ERROR;
  1426. if (!g_pRAHook)
  1427. {
  1428. g_pRAHook = new CRAHooks(pSvc); // refcount is ONE
  1429. if (NULL == g_pRAHook) return WBEM_E_OUT_OF_MEMORY;
  1430. hRes = pSvc->RegisterWriteHook(WBEM_FLAG_CLASS_PUT,g_pRAHook);
  1431. }
  1432. return hRes;
  1433. }
  1434. //
  1435. //
  1436. //
  1437. //
  1438. ///////////////////////////////////////////////////////////
  1439. HRESULT ShutdownRAHooks()
  1440. {
  1441. HRESULT hRes = WBEM_S_NO_ERROR;
  1442. if (g_pRAHook)
  1443. {
  1444. _IWmiCoreServices *pSvc = ((CRAHooks *)g_pRAHook)->GetSvc();
  1445. if (pSvc)
  1446. {
  1447. hRes = pSvc->UnregisterWriteHook(g_pRAHook);
  1448. }
  1449. g_pRAHook->Release();
  1450. g_pRAHook = NULL;
  1451. }
  1452. return hRes;
  1453. }
  1454. //***************************************************************************
  1455. //
  1456. //***************************************************************************
  1457. HRESULT InitESS(_IWmiCoreServices *pSvc, BOOL bAutoRecoverd)
  1458. {
  1459. HRESULT hRes;
  1460. // Check if event subsystem is enabled
  1461. // ===================================
  1462. Registry r(WBEM_REG_WINMGMT);
  1463. DWORD dwEnabled = 1;
  1464. r.GetDWORDStr(__TEXT("EnableEvents"), &dwEnabled);
  1465. if (dwEnabled != 1 || IsNtSetupRunning())
  1466. return WBEM_S_NO_ERROR;
  1467. // If here, we have to bring events into the picture.
  1468. // ===================================================
  1469. hRes = CoCreateInstance(CLSID_WmiESS, NULL, // SEC:REVIEWED 2002-03-22 : OK
  1470. CLSCTX_INPROC_SERVER, IID__IWmiESS,
  1471. (void**) &g_pESS);
  1472. if (FAILED(hRes))
  1473. {
  1474. ERRORTRACE((LOG_WBEMCORE, "Unable to load Event Subsystem: 0x%X\n", hRes));
  1475. return hRes;
  1476. };
  1477. DWORD dwEssNeedsInitialStart = 0;
  1478. g_persistConfig.GetPersistentCfgValue(PERSIST_CFGVAL_CORE_ESS_TO_BE_INITIALIZED,dwEssNeedsInitialStart);
  1479. if(bAutoRecoverd || dwEssNeedsInitialStart)
  1480. hRes = g_pESS->Initialize(WMIESS_INIT_REPOSITORY_RECOVERED, 0, pSvc);
  1481. else
  1482. hRes = g_pESS->Initialize(0, 0, pSvc);
  1483. if (FAILED(hRes))
  1484. {
  1485. ERRORTRACE((LOG_WBEMCORE, "Unable to Initialize Event Subsystem: 0x%X\n", hRes));
  1486. return hRes;
  1487. }
  1488. hRes = g_pESS->QueryInterface(IID_IWbemEventSubsystem_m4, (LPVOID *) &g_pEss_m4);
  1489. if (FAILED(hRes))
  1490. return hRes;
  1491. if (FAILED(hRes))
  1492. {
  1493. ERRORTRACE((LOG_WBEMCORE, "Unable to QI for IID_IWbemEventSubsystem_m4: 0x%X\n", hRes));
  1494. return hRes;
  1495. }
  1496. CCoreServices::SetEssPointers(g_pEss_m4, g_pESS);
  1497. return hRes;
  1498. }
  1499. //***************************************************************************
  1500. //
  1501. //***************************************************************************
  1502. //
  1503. static HRESULT ShutdownRepository(BOOL bIsSystemShutdown)
  1504. {
  1505. HRESULT hRes = CRepository::Shutdown(bIsSystemShutdown);
  1506. return hRes;
  1507. }
  1508. //***************************************************************************
  1509. //
  1510. //***************************************************************************
  1511. //
  1512. static HRESULT ShutdownESS(BOOL bIsSystemShutDown)
  1513. {
  1514. HRESULT hRes;
  1515. if (g_pESS)
  1516. {
  1517. IWbemShutdown *pShutdown = 0;
  1518. hRes = g_pESS->QueryInterface(IID_IWbemShutdown, (LPVOID *) & pShutdown);
  1519. if (FAILED(hRes))
  1520. return hRes;
  1521. if (bIsSystemShutDown)
  1522. {
  1523. hRes = pShutdown->Shutdown(0, 0, 0);
  1524. }
  1525. else
  1526. {
  1527. hRes = pShutdown->Shutdown(0, DEFAULT_SHUTDOWN_TIMEOUT, 0);
  1528. }
  1529. if (FAILED(hRes))
  1530. return hRes;
  1531. if (g_pEss_m4)
  1532. g_pEss_m4->Release();
  1533. pShutdown->Release();
  1534. g_pESS->Release();
  1535. g_pESS = NULL;
  1536. }
  1537. return WBEM_S_NO_ERROR;
  1538. }
  1539. //***************************************************************************
  1540. //
  1541. //***************************************************************************
  1542. //
  1543. HRESULT InitProvSS(CCoreServices *pSvc)
  1544. {
  1545. HRESULT hRes = pSvc->GetProviderSubsystem(0, &g_pProvSS);
  1546. if (FAILED(hRes))
  1547. return hRes;
  1548. return WBEM_S_NO_ERROR;
  1549. }
  1550. //***************************************************************************
  1551. //
  1552. //***************************************************************************
  1553. //
  1554. HRESULT ShutdownProvSS()
  1555. {
  1556. HRESULT hRes;
  1557. if (g_pProvSS)
  1558. {
  1559. IWbemShutdown *pShutdown = 0;
  1560. hRes = g_pProvSS->QueryInterface(IID_IWbemShutdown, (LPVOID *) & pShutdown);
  1561. if (FAILED(hRes))
  1562. return hRes;
  1563. hRes = pShutdown->Shutdown(0, DEFAULT_SHUTDOWN_TIMEOUT, 0);
  1564. if (FAILED(hRes))
  1565. return hRes;
  1566. pShutdown->Release();
  1567. g_pProvSS->Release();
  1568. g_pProvSS = NULL;
  1569. }
  1570. return WBEM_S_NO_ERROR;
  1571. }
  1572. //***************************************************************************
  1573. //
  1574. //***************************************************************************
  1575. //
  1576. static HRESULT InitRepository(CCoreServices *pSvc)
  1577. {
  1578. HRESULT hRes = CRepository::Init();
  1579. return hRes;
  1580. }
  1581. //***************************************************************************
  1582. //
  1583. //***************************************************************************
  1584. static HRESULT InitCore(CCoreServices *pSvc)
  1585. {
  1586. return WBEM_S_NO_ERROR;
  1587. }
  1588. static HRESULT ShutdownCore()
  1589. {
  1590. return WBEM_S_NO_ERROR;
  1591. }
  1592. //***************************************************************************
  1593. //
  1594. // This determines if a previous autorecovery attempt was aborted
  1595. //
  1596. //***************************************************************************
  1597. bool AutoRecoveryWasInterrupted()
  1598. {
  1599. DWORD dwValue;
  1600. Registry r(WBEM_REG_WINMGMT);
  1601. if (Registry::no_error == r.GetDWORD(__TEXT("NextAutoRecoverFile"), &dwValue))
  1602. if(dwValue != 0xffffffff)
  1603. return true;
  1604. return false;
  1605. }
  1606. //***************************************************************************
  1607. //
  1608. // Subsystem control
  1609. //
  1610. //***************************************************************************
  1611. HRESULT InitSubsystems()
  1612. {
  1613. HRESULT hRes;
  1614. BOOL bAutoRecovered = FALSE;
  1615. CCoreServices::Initialize();
  1616. CCoreServices *pSvc = CCoreServices::CreateInstance();
  1617. if (pSvc == 0)
  1618. return WBEM_E_OUT_OF_MEMORY;
  1619. CReleaseMe _rm(pSvc);
  1620. pSvc->StopEventDelivery();
  1621. // Core startup.
  1622. // =============
  1623. hRes = InitCore(pSvc);
  1624. if (FAILED(hRes))
  1625. {
  1626. ERRORTRACE((LOG_WBEMCORE, "Core Initialization returned failure <0x%X>!\n", hRes));
  1627. return hRes;
  1628. }
  1629. // Init repository.
  1630. // ================
  1631. hRes = InitRepository(pSvc);
  1632. if (FAILED(hRes))
  1633. {
  1634. ERRORTRACE((LOG_WBEMCORE, "Repository Initialization returned failure <0x%X>!\n", hRes));
  1635. return hRes;
  1636. }
  1637. pSvc->StartEventDelivery();
  1638. // This will load the default mofs if auto recover is needed
  1639. if (g_bDefaultMofLoadingNeeded || AutoRecoveryWasInterrupted())
  1640. {
  1641. HRESULT hrInner = ConfigMgr::LoadDefaultMofs(); // resets g_bDefaultMofLoadingNeeded
  1642. if (FAILED(hrInner))
  1643. {
  1644. ERRORTRACE((LOG_WBEMCORE,"LoadDefaultMofs hr = %08x\n",hrInner));
  1645. }
  1646. bAutoRecovered = TRUE;
  1647. }
  1648. // Init Provider Subsystem.
  1649. // ========================
  1650. hRes = InitProvSS(pSvc);
  1651. if (FAILED(hRes))
  1652. {
  1653. ERRORTRACE((LOG_WBEMCORE, "Provider Subsystem initialization returned failure <0x%X>!\n", hRes));
  1654. return hRes;
  1655. }
  1656. // Init ESS.
  1657. // =========
  1658. hRes = InitESS(pSvc, bAutoRecovered);
  1659. if (FAILED(hRes))
  1660. {
  1661. ERRORTRACE((LOG_WBEMCORE, "Event Subsystem initialization returned failure <0x%X>!\n", hRes));
  1662. return hRes;
  1663. }
  1664. // Init ReverseAdapters Hooks
  1665. // =========
  1666. hRes = InitRAHooks(pSvc);
  1667. if (FAILED(hRes))
  1668. return hRes;
  1669. return hRes;
  1670. }
  1671. //***************************************************************************
  1672. //
  1673. //***************************************************************************
  1674. //
  1675. HRESULT ShutdownSubsystems(BOOL bIsSystemShutdown)
  1676. {
  1677. HRESULT hRes1, hRes2, hRes3, hRes4, hRes5, hRes6, hRes7 ;
  1678. if (!bIsSystemShutdown)
  1679. {
  1680. // ShutDown ReverseAdapters Hooks
  1681. // =========
  1682. hRes7 = ShutdownRAHooks();
  1683. // Kill ESS.
  1684. // =========
  1685. hRes1 = ShutdownESS(bIsSystemShutdown);
  1686. // Kill Provider Subsystem.
  1687. // ========================
  1688. hRes2 = ShutdownProvSS();
  1689. // Arbitrator
  1690. // ==========
  1691. hRes3 = CWmiArbitrator::Shutdown(bIsSystemShutdown);
  1692. }
  1693. // Repository.
  1694. // ===========
  1695. hRes4 = ShutdownRepository(bIsSystemShutdown);
  1696. if (!bIsSystemShutdown)
  1697. {
  1698. // Core startup.
  1699. // =============
  1700. hRes5 = ShutdownCore();
  1701. hRes6 = CCoreServices::UnInitialize();
  1702. }
  1703. return WBEM_S_NO_ERROR;
  1704. }
  1705. //
  1706. //
  1707. ////////////////////////////////////////////////
  1708. VOID inline Hex2Char(BYTE Byte,TCHAR * &pOut)
  1709. {
  1710. BYTE HiNibble = (Byte&0xF0) >> 4;
  1711. BYTE LoNibble = Byte & 0xF;
  1712. *pOut = (HiNibble<10)?(__TEXT('0')+HiNibble):(__TEXT('A')+HiNibble-10);
  1713. pOut++;
  1714. *pOut = (LoNibble<10)?(__TEXT('0')+LoNibble):(__TEXT('A')+LoNibble-10);
  1715. pOut++;
  1716. }
  1717. // returns "string" representation of a buffer as a HEX number
  1718. VOID Buffer2String(BYTE * pStart,DWORD dwSize,TCHAR * pOut)
  1719. {
  1720. for (DWORD i=0;i<dwSize;i++) Hex2Char(pStart[i],pOut);
  1721. }
  1722. //
  1723. // given the pathname d:\folder1\folder2\foo.mof
  1724. // it returns
  1725. // ppHash = MD5 Hash of the UPPERCASE UNICODE Path + '.mof'
  1726. // call delete [] on return vclues
  1727. //
  1728. //////////////////////////////////////////////
  1729. DWORD ComposeName(WCHAR * pFullLongName, WCHAR **ppHash)
  1730. {
  1731. if (NULL == ppHash ) return ERROR_INVALID_PARAMETER;
  1732. DWORD dwLen = wcslen(pFullLongName); // SEC:REVIEWED 2002-03-22 : Needs NULL check and EH
  1733. WCHAR * pConvert = pFullLongName;
  1734. for (DWORD i=0;i<dwLen;i++) pConvert[i] = wbem_towupper(pConvert[i]);
  1735. wmilib::auto_buffer<WCHAR> pHash(new WCHAR[32 + 4 + 1]);
  1736. if (NULL == pHash.get()) return ERROR_OUTOFMEMORY;
  1737. MD5 md5;
  1738. BYTE aSignature[16];
  1739. md5.Transform( pFullLongName, dwLen * sizeof(WCHAR), aSignature );
  1740. Buffer2String(aSignature,16,pHash.get());
  1741. StringCchCopy(&pHash[32],5 ,__TEXT(".mof"));
  1742. *ppHash = pHash.release();
  1743. return ERROR_SUCCESS;
  1744. }
  1745. class AutoRevert
  1746. {
  1747. private:
  1748. HANDLE oldToken_;
  1749. BOOL SetThrTokResult_;
  1750. bool self_;
  1751. public:
  1752. AutoRevert();
  1753. ~AutoRevert();
  1754. void dismiss();
  1755. bool self(){ return self_;}
  1756. };
  1757. AutoRevert::AutoRevert():oldToken_(NULL),self_(true),SetThrTokResult_(FALSE)
  1758. {
  1759. if (OpenThreadToken(GetCurrentThread(),TOKEN_IMPERSONATE,TRUE,&oldToken_))
  1760. {
  1761. RevertToSelf();
  1762. }
  1763. else
  1764. {
  1765. if (GetLastError() != ERROR_NO_TOKEN)
  1766. self_ = false;
  1767. };
  1768. }
  1769. AutoRevert::~AutoRevert()
  1770. {
  1771. dismiss();
  1772. }
  1773. void AutoRevert::dismiss()
  1774. {
  1775. if (oldToken_)
  1776. {
  1777. // if the handle has been opened with TOKEN_IMPERSONATE
  1778. // and if nobody has touched the SD for the ETHREAD object, this will work
  1779. SetThrTokResult_ = SetThreadToken(NULL,oldToken_);
  1780. CloseHandle(oldToken_);
  1781. }
  1782. }
  1783. HRESULT ConfigMgr::LoadDefaultMofs()
  1784. {
  1785. g_bDefaultMofLoadingNeeded = false;
  1786. HRESULT hr;
  1787. AutoRevert revert;
  1788. if (revert.self()==false) return HRESULT_FROM_WIN32(GetLastError());
  1789. IWbemCallSecurity * pCallSec = CWbemCallSecurity::CreateInst();
  1790. if (NULL == pCallSec) return WBEM_E_OUT_OF_MEMORY;
  1791. CReleaseMe rm(pCallSec);
  1792. IUnknown * pOldCtx = NULL;
  1793. IUnknown * pDiscard = NULL;
  1794. if (FAILED(hr = CoSwitchCallContext(NULL,&pOldCtx))) return hr;
  1795. OnDelete2<IUnknown *,IUnknown **,
  1796. HRESULT(*)(IUnknown *,IUnknown **),
  1797. CoSwitchCallContext> SwitchBack(pOldCtx,&pDiscard);
  1798. if (FAILED(hr = pCallSec->CloneThreadContext(TRUE))) return hr;
  1799. if (FAILED(hr = CoSwitchCallContext(pCallSec,&pDiscard))) return hr;
  1800. size_t cchAutoRecLen = wcslen(g_pAutorecoverDir);
  1801. size_t cchRealPath = 32 + 4 + 1 + 1 + cchAutoRecLen;
  1802. wmilib::auto_buffer<WCHAR> pRealPath(new WCHAR[cchRealPath]);
  1803. if (NULL == pRealPath.get()) return WBEM_E_OUT_OF_MEMORY;
  1804. StringCchCopy(pRealPath.get(),cchRealPath,g_pAutorecoverDir);
  1805. WCHAR * pInsertPoint = &pRealPath[cchAutoRecLen];
  1806. *pInsertPoint = L'\\';
  1807. pInsertPoint++;
  1808. DWORD dwSize;
  1809. TCHAR *pszMofs;
  1810. TCHAR szExpandedFilename[MAX_PATH+1];
  1811. DWORD dwCurrMof;
  1812. DWORD dwNextAutoRecoverFile = 0xffffffff; // assume that this is clean
  1813. Registry r(WBEM_REG_WINMGMT);
  1814. r.GetDWORD(__TEXT("NextAutoRecoverFile"), &dwNextAutoRecoverFile);
  1815. IWbemContext * pCtx = NULL;
  1816. HRESULT hRes = CoCreateInstance(CLSID_WbemContext, 0, CLSCTX_INPROC_SERVER,
  1817. IID_IWbemContext, (LPVOID *) &pCtx);
  1818. if (FAILED(hRes)) return hRes;
  1819. CReleaseMe rmCtx(pCtx);
  1820. _variant_t Var = true;
  1821. if (FAILED(hRes = pCtx->SetValue(L"__MOFD_NO_STORE",0,&Var))) return hRes;
  1822. IWinmgmtMofCompiler * pCompiler = NULL;
  1823. hRes = CoCreateInstance(CLSID_WinmgmtMofCompiler, 0, CLSCTX_INPROC_SERVER, // SEC:REVIEWED 2002-03-22 : OK
  1824. IID_IWinmgmtMofCompiler, (LPVOID *) &pCompiler);
  1825. if(FAILED(hRes))
  1826. {
  1827. return hRes;
  1828. }
  1829. CReleaseMe relMe(pCompiler);
  1830. CLSID clsid;
  1831. IWmiDbController *pController = 0;
  1832. hRes = GetDefaultRepDriverClsId(clsid);
  1833. if (FAILED(hRes))
  1834. return hRes;
  1835. hRes = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
  1836. IID_IWmiDbController, (void **)&pController);
  1837. if (FAILED(hRes))
  1838. return hRes;
  1839. CReleaseMe relMe2(pController);
  1840. //Get the list of MOFs we need to
  1841. pszMofs = ConfigMgr::GetAutoRecoverMofs(dwSize);
  1842. CVectorDeleteMe<TCHAR> vdm(pszMofs);
  1843. if (pszMofs)
  1844. {
  1845. for (dwCurrMof = 0; *pszMofs != '\0'; dwCurrMof++)
  1846. {
  1847. if(dwNextAutoRecoverFile == 0xffffffff || dwCurrMof >= dwNextAutoRecoverFile)
  1848. {
  1849. //Make sure we restart from where we left off from in case of reboot or service failure!
  1850. r.SetDWORD(__TEXT("NextAutoRecoverFile"), dwCurrMof);
  1851. DWORD nRes = ExpandEnvironmentStrings(pszMofs,szExpandedFilename,FILENAME_MAX); // SEC:REVIEWED 2002-03-22 : OK
  1852. if (0 == nRes)
  1853. {
  1854. StringCchCopy(szExpandedFilename, MAX_PATH+1, pszMofs);
  1855. }
  1856. WCHAR * wPath = szExpandedFilename;
  1857. WCHAR * pHash = NULL;
  1858. DWORD dwRes = ComposeName(wPath,&pHash);
  1859. if (ERROR_SUCCESS != dwRes) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32,dwRes);
  1860. wmilib::auto_buffer<WCHAR> DelMe(pHash);
  1861. StringCchCopy(pInsertPoint,34+4+1,pHash);
  1862. //Call MOF Compiler with (pszMofs);
  1863. WBEM_COMPILE_STATUS_INFO Info;
  1864. hr = pCompiler->WinmgmtCompileFile(pRealPath.get(),
  1865. NULL,
  1866. WBEM_FLAG_CONNECT_REPOSITORY_ONLY |
  1867. WBEM_FLAG_CONNECT_PROVIDERS |
  1868. WBEM_FLAG_DONT_ADD_TO_LIST,
  1869. WBEM_FLAG_OWNER_UPDATE,
  1870. WBEM_FLAG_OWNER_UPDATE,
  1871. NULL, pCtx, &Info);
  1872. if(Info.hRes == CO_E_SERVER_STOPPING)
  1873. {
  1874. return CO_E_SERVER_STOPPING;
  1875. }
  1876. else if(hr) // will include S_FALSE
  1877. {
  1878. ERRORTRACE((LOG_WBEMCORE, "MOF compilation of <%S> failed during auto-recovery. Refer to the mofcomp.log for more details of failure.\n", wPath));
  1879. CEventLog *pEvt = ConfigMgr::GetEventLog();
  1880. if (pEvt)
  1881. pEvt->Report(EVENTLOG_ERROR_TYPE,
  1882. WBEM_MC_MOF_NOT_LOADED_AT_RECOVERY,
  1883. szExpandedFilename);
  1884. }
  1885. else
  1886. {
  1887. //We need to check-point the repository to make sure it is in a consistent state in case we get rebooted before
  1888. //writing the next MOF to load index in the registry.
  1889. hr = pController->LockRepository();
  1890. if (FAILED(hr))
  1891. return hr;
  1892. hr = pController->UnlockRepository();
  1893. if (FAILED(hr))
  1894. return hr;
  1895. }
  1896. }
  1897. //Move on to the next string
  1898. pszMofs += lstrlen(pszMofs) + 1; // SEC:REVIEWED 2002-03-22 : OK, assumes GetAutocoverMofs() returns correct string format
  1899. }
  1900. }
  1901. //We Have completed the MOF load, so make sure we don't continue from where we left off!
  1902. r.SetDWORD(__TEXT("NextAutoRecoverFile"), 0xffffffff);
  1903. return WBEM_S_NO_ERROR;;
  1904. }
  1905. //
  1906. // secure a registry key
  1907. // the name must be suitable for SetNamedSecurityInfoW
  1908. // of the SDDL string, we care only about the DACL
  1909. //
  1910. ///////////////////////////////////////////////////////////////
  1911. HRESULT SecureKey(WCHAR * pKeyName,WCHAR * pSDDLString)
  1912. {
  1913. PSECURITY_DESCRIPTOR pSD = NULL;
  1914. if (FALSE == ConvertStringSecurityDescriptorToSecurityDescriptor(pSDDLString, // SEC:REVIEWED 2002-03-22 : OK
  1915. SDDL_REVISION_1,
  1916. &pSD,
  1917. NULL)) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32,GetLastError());
  1918. OnDelete<HLOCAL,HLOCAL(*)(HLOCAL),LocalFree> dm1(pSD);
  1919. SECURITY_DESCRIPTOR_RELATIVE * pRel = (SECURITY_DESCRIPTOR_RELATIVE *)pSD;
  1920. if (!(pRel->Control & (SE_DACL_PRESENT | SE_SELF_RELATIVE)))
  1921. return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32,ERROR_INVALID_PARAMETER);
  1922. DWORD dwLen = 0;
  1923. DWORD dwLenDACL = 0;
  1924. DWORD dwLenSACL = 0;
  1925. DWORD dwLenOWNER = 0;
  1926. DWORD dwLenGRP = 0;
  1927. if (TRUE == MakeAbsoluteSD(pSD,
  1928. NULL,&dwLen,
  1929. NULL,&dwLenDACL,
  1930. NULL,&dwLenSACL,
  1931. NULL,&dwLenOWNER,
  1932. NULL,&dwLenGRP))
  1933. return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32,GetLastError());
  1934. PACL pDacl = (PACL)LocalAlloc(0,dwLenDACL);
  1935. if (NULL == pDacl) return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32,GetLastError());
  1936. OnDelete<HLOCAL,HLOCAL(*)(HLOCAL),LocalFree> dm2(pDacl);
  1937. memcpy(pDacl,(BYTE *)pRel+pRel->Dacl,dwLenDACL); // SEC:REVIEWED 2002-03-22 : OK
  1938. SECURITY_INFORMATION SecurityInfo = DACL_SECURITY_INFORMATION |
  1939. PROTECTED_DACL_SECURITY_INFORMATION;
  1940. LONG lRet;
  1941. if (ERROR_SUCCESS != (lRet = SetNamedSecurityInfoW(pKeyName, // SEC:REVIEWED 2002-03-22 : OK
  1942. SE_REGISTRY_KEY,
  1943. SecurityInfo,
  1944. NULL, NULL, pDacl,NULL)))
  1945. return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32,GetLastError());
  1946. return S_OK;
  1947. }