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.

811 lines
24 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. WMIBROKER.H
  5. Abstract:
  6. implementation of the CWMIBroker class.
  7. History:
  8. --*/
  9. #include "precomp.h"
  10. #include <stdio.h>
  11. #include <wbemcli.h>
  12. #include <cominit.h>
  13. #include <winmgmtr.h>
  14. #include <stdio.h>
  15. #include "perfndb.h"
  16. #include "adaputil.h"
  17. #include "adapcls.h"
  18. #include "ntreg.h"
  19. #include "WMIBroker.h"
  20. #include <comdef.h>
  21. //////////////////////////////////////////////////////////////////////
  22. // Construction/Destruction
  23. //////////////////////////////////////////////////////////////////////
  24. CWMIBroker::CWMIBroker( WString wstrNamespace )
  25. : m_wstrNamespace( wstrNamespace )
  26. {
  27. }
  28. CWMIBroker::~CWMIBroker()
  29. {
  30. }
  31. // This function is used to hook us up to Winmgmt and registry data
  32. HRESULT CWMIBroker::Connect( IWbemServices** ppNamespace, CPerfNameDb* pDefaultNameDb )
  33. {
  34. HRESULT hr = WBEM_NO_ERROR;
  35. IWbemServices* pNamespace = NULL;
  36. {
  37. // Connect to the namespace
  38. hr= ConnectToNamespace( &pNamespace );
  39. if ( SUCCEEDED( hr ) )
  40. {
  41. hr = VerifyNamespace( pNamespace );
  42. }
  43. if ( SUCCEEDED( hr ) )
  44. {
  45. *ppNamespace = pNamespace;
  46. DEBUGTRACE( ( LOG_WMIADAP, "The ADAP process ( PID: %d ) is connected to the WinMgmt service ( PID: %d )\n", GetCurrentProcessId(), 0 ) );
  47. }
  48. }
  49. return hr;
  50. }
  51. HRESULT CWMIBroker::ConnectToNamespace( IWbemServices** ppNamespace )
  52. {
  53. IWbemServices* pNameSpace = NULL;
  54. IWbemLocator* pWbemLocator = NULL;
  55. CReleaseMe rmWbemLocator(pWbemLocator);
  56. HRESULT hr = CoCreateInstance( CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void**) &pWbemLocator );
  57. if ( SUCCEEDED(hr) )
  58. {
  59. // Name space to connect to
  60. BSTR bstrNameSpace = NULL;
  61. try
  62. {
  63. bstrNameSpace = SysAllocString( m_wstrNamespace );
  64. }
  65. catch(...)
  66. {
  67. hr = WBEM_E_OUT_OF_MEMORY;
  68. bstrNameSpace = NULL;
  69. }
  70. CSysFreeMe sfmNameSpace( bstrNameSpace);
  71. if ( NULL != bstrNameSpace )
  72. {
  73. hr = pWbemLocator->ConnectServer( bstrNameSpace, // NameSpace Name
  74. NULL, // UserName
  75. NULL, // Password
  76. NULL, // Locale
  77. 0L, // Security Flags
  78. NULL, // Authority
  79. NULL, // Wbem Context
  80. &pNameSpace // Namespace
  81. );
  82. if ( SUCCEEDED( hr ) )
  83. {
  84. // Set Interface security
  85. hr = WbemSetProxyBlanket( pNameSpace, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
  86. RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
  87. if ( FAILED( hr ) )
  88. {
  89. // Handle this as appropriate
  90. if (wcsstr(bstrNameSpace,L"MS_")) {
  91. ERRORTRACE( ( LOG_WMIADAP, "ConnectServer on namespace %S hr = %08x\n",(LPWSTR)bstrNameSpace,hr) );
  92. } else {
  93. HandleConnectServerFailure( hr );
  94. }
  95. }
  96. } // IF ConnectServer
  97. else
  98. {
  99. // We are no longer creating namespaces since we are living under
  100. // root\cimv2 and NOW deriving off of CIM_StatisticalInformation
  101. // HOWEVER, we'll keep the function around, since the way this thing's
  102. // going, someone's bound to change this on us AGAIN
  103. // hr = CreateNamespace( m_wstrNamespace, &pNameSpace );
  104. // Handle this as appropriate
  105. if (wcsstr(bstrNameSpace,L"MS_")) {
  106. ERRORTRACE( ( LOG_WMIADAP, "ConnectServer on namespace %S hr = %08x\n",(LPWSTR)bstrNameSpace,hr) );
  107. } else {
  108. HandleConnectServerFailure( hr );
  109. }
  110. }
  111. }
  112. else
  113. {
  114. hr = WBEM_E_OUT_OF_MEMORY;
  115. // Handle this as appropriate
  116. HandleConnectServerFailure( hr );
  117. }
  118. }
  119. else
  120. {
  121. // Handle this as appropriate
  122. HandleConnectServerFailure( hr );
  123. }
  124. if ( NULL != pNameSpace )
  125. {
  126. *ppNamespace = pNameSpace;
  127. }
  128. return hr;
  129. }
  130. HRESULT CWMIBroker::VerifyNamespace( IWbemServices* pNS )
  131. {
  132. HRESULT hr = WBEM_NO_ERROR;
  133. // Check that the provider classes exist. We will only do this for the base namespace,
  134. // Root\cimv2
  135. if ( lstrcmpiW( m_wstrNamespace, ADAP_ROOT_NAMESPACE ) == 0 )
  136. {
  137. hr = VerifyProviderClasses( pNS, L"NT5_GenericPerfProvider_V1",
  138. CLSID_NT5PerfProvider_V1_Srv,
  139. CLSID_NT5PerfProvider_V1 );
  140. if ( SUCCEEDED( hr ) )
  141. {
  142. hr = VerifyProviderClasses( pNS, L"HiPerfCooker_v1",
  143. CLSID_HiPerfCooker_V1_Srv,
  144. CLSID_HiPerfCooker_V1);
  145. }
  146. }
  147. if ( SUCCEEDED( hr ) )
  148. {
  149. hr = VerifyBaseClasses( pNS );
  150. }
  151. return hr;
  152. }
  153. HRESULT
  154. CWMIBroker::VerifyProviderClasses( IWbemServices* pNamespace,
  155. LPCWSTR wszProvider,
  156. LPCWSTR wszGUID_Server,
  157. LPCWSTR wszGUID_Client)
  158. {
  159. HRESULT hr = WBEM_NO_ERROR;
  160. // Verify that an instance of the generic provider exists
  161. // We need to create an object with our desired attributes so that we may
  162. // use it to compare it to the instance in WMI, if it already exists
  163. // ======================================================================
  164. // NOTE:
  165. // What if the generic provider has not been installed
  166. // ========================================================
  167. try
  168. {
  169. // Create the generic provider instance
  170. // ====================================
  171. IWbemClassObject* pProviderClass = NULL;
  172. WCHAR* wszRelPath = new WCHAR[64 + wcslen( wszProvider )];
  173. CVectorDeleteMe<WCHAR> dmRelPath( wszRelPath );
  174. swprintf( wszRelPath, L"__Win32Provider.Name=\"%s\"", wszProvider );
  175. BSTR bstrProviderInst = SysAllocString( wszRelPath );
  176. CSysFreeMe fmProviderInst(bstrProviderInst);
  177. BSTR bstrProviderClass = SysAllocString( L"__Win32Provider" );
  178. CSysFreeMe fmProviderClass(bstrProviderClass);
  179. hr = pNamespace->GetObject( bstrProviderClass, 0L, NULL, &pProviderClass, NULL );
  180. CReleaseMe rmProviderClass( pProviderClass );
  181. if ( SUCCEEDED( hr ) )
  182. {
  183. IWbemClassObject* pProviderInstance = NULL;
  184. _variant_t var;
  185. hr = pProviderClass->SpawnInstance( 0L, &pProviderInstance );
  186. CReleaseMe rmProviderInstance( pProviderInstance );
  187. if ( SUCCEEDED( hr ) )
  188. {
  189. var = wszProvider;
  190. hr = pProviderInstance->Put(L"Name", 0L, &var, CIM_STRING );
  191. }
  192. if ( SUCCEEDED( hr ) )
  193. {
  194. var = wszGUID_Server;
  195. hr = pProviderInstance->Put( L"CLSID", 0L, &var, CIM_STRING );
  196. if ( SUCCEEDED( hr ) )
  197. {
  198. var = wszGUID_Client;
  199. hr = pProviderInstance->Put( L"ClientLoadableCLSID", 0L, &var, CIM_STRING );
  200. if ( SUCCEEDED(hr) ){
  201. var = L"NetworkServiceHost";
  202. hr = pProviderInstance->Put(L"HostingModel",0L,&var,CIM_STRING);
  203. }
  204. }
  205. }
  206. if ( SUCCEEDED( hr ) )
  207. {
  208. IWbemClassObject* pDbProviderInstance = NULL;
  209. // Try to get the object from the db.
  210. // ==================================
  211. HRESULT hresDb = pNamespace->GetObject( bstrProviderInst, 0L, NULL,
  212. (IWbemClassObject**)&pDbProviderInstance, NULL );
  213. // If we got an object from the database, then we need to compare it to the
  214. // one we just built. If the comparison fails, we should replace the object
  215. // =========================================================================
  216. if ( SUCCEEDED( hresDb ) && NULL != pDbProviderInstance )
  217. {
  218. if ( pProviderInstance->CompareTo( WBEM_FLAG_IGNORE_OBJECT_SOURCE,
  219. pDbProviderInstance ) != WBEM_S_SAME )
  220. {
  221. hr = pNamespace->PutInstance( pProviderInstance, 0L, NULL, NULL );
  222. }
  223. pDbProviderInstance->Release();
  224. }
  225. else
  226. {
  227. hr = pNamespace->PutInstance( pProviderInstance, 0L, NULL, NULL );
  228. }
  229. }
  230. }
  231. }
  232. catch(...)
  233. {
  234. hr = WBEM_E_OUT_OF_MEMORY;
  235. }
  236. // Log an error event and bail, because something is pretty badly wrong
  237. // ====================================================================
  238. if ( FAILED( hr ) )
  239. {
  240. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  241. WBEM_MC_ADAP_UNABLE_TO_ADD_PROVIDER,
  242. CHex( hr ) );
  243. ERRORTRACE( ( LOG_WMIADAP, "CAdapSync::VerifyProviderClasses() failed: %X.\n", hr ) );
  244. return hr;
  245. }
  246. // Add the Instance Provider
  247. // =========================
  248. try
  249. {
  250. IWbemClassObject* pInstProvRegClass = NULL;
  251. WCHAR* wszProviderKey = new WCHAR[ 128 + wcslen( wszProvider ) ];
  252. CVectorDeleteMe<WCHAR> dmProviderKey( wszProviderKey );
  253. swprintf( wszProviderKey, L"__InstanceProviderRegistration.Provider=\"\\\\\\\\.\\\\root\\\\cimv2:__Win32Provider.Name=\\\"%s\\\"\"", wszProvider );
  254. BSTR bstrInstProvRegInst = SysAllocString( wszProviderKey );
  255. CSysFreeMe fmInstProvRegInst( bstrInstProvRegInst );
  256. BSTR bstrInstProvRegClass = SysAllocString( L"__InstanceProviderRegistration" );
  257. CSysFreeMe fmInstProvRegClass( bstrInstProvRegClass );
  258. hr = pNamespace->GetObject( bstrInstProvRegClass, 0L, NULL, &pInstProvRegClass, NULL );
  259. CReleaseMe rmProviderClass( pInstProvRegClass );
  260. if ( SUCCEEDED( hr ) )
  261. {
  262. IWbemClassObject* pInstProvRegInstance = NULL;
  263. _variant_t var;
  264. hr = pInstProvRegClass->SpawnInstance( 0L, &pInstProvRegInstance);
  265. CReleaseMe rmInstProvRegInstance( pInstProvRegInstance );
  266. if ( SUCCEEDED( hr ) )
  267. {
  268. WCHAR* wszProviderInst = new WCHAR[ 64 + wcslen( wszProvider ) ];
  269. CVectorDeleteMe<WCHAR> dmProviderInst( wszProviderInst );
  270. swprintf( wszProviderInst, L"\\\\.\\root\\cimv2:__Win32Provider.Name=\"%s\"", wszProvider );
  271. var = wszProviderInst;
  272. hr = pInstProvRegInstance->Put( L"Provider", 0L, (VARIANT*)&var, CIM_REFERENCE );
  273. }
  274. if ( SUCCEEDED( hr ) )
  275. {
  276. var = bool(true);
  277. hr = pInstProvRegInstance->Put( L"SupportsGet", 0L, (VARIANT*)&var, CIM_BOOLEAN );
  278. }
  279. if ( SUCCEEDED( hr ) )
  280. {
  281. var = bool(true);
  282. hr = pInstProvRegInstance->Put( L"SupportsEnumeration", 0L, (VARIANT*)&var, CIM_BOOLEAN );
  283. }
  284. if ( SUCCEEDED( hr ) )
  285. {
  286. IWbemClassObject* pDbInstProvRegInstance = NULL;
  287. // Try to get the object from the db.
  288. HRESULT hresDb = pNamespace->GetObject( bstrInstProvRegInst, 0L, NULL, &pDbInstProvRegInstance, NULL );
  289. // If we got an object from the database, then we need to compare it to
  290. // the one we just built. If the comparison fails, we should replace the
  291. // object.
  292. if ( SUCCEEDED( hresDb ) && NULL != pDbInstProvRegInstance )
  293. {
  294. if ( pInstProvRegInstance->CompareTo( WBEM_FLAG_IGNORE_OBJECT_SOURCE,
  295. pDbInstProvRegInstance ) != WBEM_S_SAME )
  296. {
  297. hr = pNamespace->PutInstance( pInstProvRegInstance, 0L, NULL, NULL );
  298. }
  299. pDbInstProvRegInstance->Release();
  300. }
  301. else
  302. {
  303. hr = pNamespace->PutInstance( pInstProvRegInstance, 0L, NULL, NULL );
  304. }
  305. } // IF Successfully built the object
  306. } // IF able to get the class
  307. }
  308. catch(...)
  309. {
  310. hr = WBEM_E_OUT_OF_MEMORY;
  311. }
  312. if ( FAILED( hr ) )
  313. {
  314. // Log the event
  315. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  316. WBEM_MC_ADAP_UNABLE_TO_ADD_PROVREG,
  317. CHex( hr ) );
  318. }
  319. return hr;
  320. }
  321. HRESULT CWMIBroker::VerifyBaseClasses( IWbemServices* pNS )
  322. {
  323. HRESULT hr = WBEM_NO_ERROR;
  324. BOOL bDefault = TRUE;
  325. // Verify the base Perf classes
  326. // ============================
  327. try
  328. {
  329. _variant_t var;
  330. // Verify CIM_StatisticalInformation
  331. // =================================
  332. // If the "abstract" qualifier exists, then we presume to be in the
  333. // default (as opposed to localized) namespace
  334. BSTR bstrCimStatisticalClass = SysAllocString( ADAP_PERF_CIM_STAT_INFO );
  335. CSysFreeMe fmCimStatisticalClass(bstrCimStatisticalClass);
  336. IWbemClassObject* pCimStatClass = NULL;
  337. hr = pNS->GetObject( bstrCimStatisticalClass, 0L, NULL, (IWbemClassObject**)&pCimStatClass, NULL );
  338. CReleaseMe rmCimStatClass( pCimStatClass );
  339. if ( SUCCEEDED( hr ) )
  340. {
  341. IWbemQualifierSet* pQualSet = NULL;
  342. hr = pCimStatClass->GetQualifierSet( &pQualSet );
  343. CReleaseMe rmStatClass( pQualSet );
  344. if ( SUCCEEDED ( hr ) )
  345. {
  346. bDefault = ( SUCCEEDED ( ( pQualSet->Get( L"abstract", 0, &var, NULL ) ) ) );
  347. }
  348. }
  349. else
  350. {
  351. ERRORTRACE((LOG_WMIADAP,"unable to obtain class CIM_StatisticalInformation for namespace %S: hr = %08x\n",(WCHAR *)m_wstrNamespace,hr));
  352. }
  353. // Verify Win32_Perf
  354. // =================
  355. // We do this by creating a template class with all of the properties and
  356. // qualifiers set, and then compare this to the object in the repository.
  357. // If the class does not exist, or if it different that the template, then
  358. // update the repository using the template object
  359. if ( SUCCEEDED ( hr ) )
  360. {
  361. IWbemClassObject* pPerfClass = NULL;
  362. // Do not use auto release since the pointer
  363. // may change in the VerifyByTemplate method
  364. // =========================================
  365. hr = pCimStatClass->SpawnDerivedClass( 0L, &pPerfClass );
  366. // Set the name
  367. // ============
  368. if ( SUCCEEDED( hr ) )
  369. {
  370. var = ADAP_PERF_BASE_CLASS ;
  371. hr = pPerfClass->Put(L"__CLASS", 0L, &var, CIM_STRING );
  372. }
  373. // Set the class qualifiers
  374. // ========================
  375. if ( SUCCEEDED( hr ) )
  376. {
  377. hr = SetBaseClassQualifiers( pPerfClass, bDefault );
  378. }
  379. // Create the class properties
  380. // ===========================
  381. if ( SUCCEEDED( hr ) )
  382. {
  383. hr = SetProperties( pPerfClass );
  384. }
  385. // Verify the repository's version
  386. // ===============================
  387. if ( SUCCEEDED( hr ) )
  388. {
  389. hr = VerifyByTemplate( pNS, &pPerfClass, ADAP_PERF_BASE_CLASS );
  390. }
  391. // If we have had a failure, log an error event and bail
  392. // =====================================================
  393. if ( FAILED( hr ) )
  394. {
  395. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  396. WBEM_MC_ADAP_UNABLE_TO_ADD_WIN32PERF,
  397. (LPCWSTR)m_wstrNamespace, CHex( hr ) );
  398. ERRORTRACE( ( LOG_WMIADAP, "CAdapSync::VerifyBaseClasses() failed when comparing Win32_Perf: %X.\n", hr ) );
  399. return hr;
  400. }
  401. // Verify Win32_PerfRawData
  402. // ========================
  403. IWbemClassObject* pRawPerfClass = NULL;
  404. _variant_t var2;
  405. // Spawn a derived class
  406. // =====================
  407. if ( SUCCEEDED ( hr ) )
  408. {
  409. // Do not use auto release since the pointer
  410. // may change in the VerifyByTemplate method
  411. // =========================================
  412. hr = pPerfClass->SpawnDerivedClass( 0L, &pRawPerfClass );
  413. // Set the name
  414. // ============
  415. if ( SUCCEEDED( hr ) )
  416. {
  417. var2 = ADAP_PERF_RAW_BASE_CLASS ;
  418. hr = pRawPerfClass->Put(L"__CLASS", 0L, (VARIANT*)&var2, CIM_STRING );
  419. // Set the class qualifiers
  420. // ========================
  421. hr = SetBaseClassQualifiers( pRawPerfClass, bDefault );
  422. if ( SUCCEEDED( hr ) )
  423. {
  424. hr = VerifyByTemplate( pNS, &pRawPerfClass, ADAP_PERF_RAW_BASE_CLASS );
  425. }
  426. pRawPerfClass->Release();
  427. }
  428. }
  429. // If we have had a failure, log an error event and bail
  430. // =====================================================
  431. if ( FAILED( hr ) )
  432. {
  433. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  434. WBEM_MC_ADAP_UNABLE_TO_ADD_WIN32PERFRAWDATA,
  435. (LPCWSTR)m_wstrNamespace, CHex( hr ) );
  436. ERRORTRACE( ( LOG_WMIADAP, "CAdapSync::VerifyBaseClasses() failed when comparing Win32_PerfRawData: %X.\n", hr ) );
  437. return hr;
  438. }
  439. // Verify Win32_PerfFormattedData
  440. // ==============================
  441. IWbemClassObject* pFormattedPerfClass = NULL;
  442. // Spawn a derived class
  443. // =====================
  444. if ( SUCCEEDED ( hr ) )
  445. {
  446. // Do not use auto release since the pointer
  447. // may change in the VerifyByTemplate method
  448. // =========================================
  449. hr = pPerfClass->SpawnDerivedClass( 0L, &pFormattedPerfClass );
  450. // Set the name
  451. // ============
  452. if ( SUCCEEDED( hr ) )
  453. {
  454. var2 = ADAP_PERF_COOKED_BASE_CLASS ;
  455. hr = pFormattedPerfClass->Put(L"__CLASS", 0L, &var2, CIM_STRING );
  456. // Set the class qualifiers
  457. // ========================
  458. hr = SetBaseClassQualifiers( pFormattedPerfClass, bDefault );
  459. if ( SUCCEEDED( hr ) )
  460. {
  461. hr = VerifyByTemplate( pNS, &pFormattedPerfClass, ADAP_PERF_COOKED_BASE_CLASS );
  462. }
  463. pFormattedPerfClass->Release();
  464. }
  465. }
  466. if ( FAILED( hr ) )
  467. {
  468. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  469. WBEM_MC_ADAP_UNABLE_TO_ADD_WIN32PERFRAWDATA,
  470. (LPCWSTR)m_wstrNamespace, CHex( hr ) );
  471. ERRORTRACE( ( LOG_WMIADAP, "CAdapSync::VerifyBaseClasses() failed when comparing Win32_PerfFormattedData: %X.\n", hr ) );
  472. return hr;
  473. }
  474. pPerfClass->Release();
  475. }
  476. }
  477. catch(...)
  478. {
  479. hr = WBEM_E_OUT_OF_MEMORY;
  480. }
  481. return hr;
  482. }
  483. HRESULT CWMIBroker::VerifyByTemplate( IWbemServices* pNS, IWbemClassObject** ppTemplate, WCHAR* wcsClassName )
  484. {
  485. HRESULT hr = WBEM_NO_ERROR;
  486. BOOL fGetClass = FALSE;
  487. IWbemClassObject* pClass = NULL;
  488. // Get the repository's version of the class
  489. // =========================================
  490. BSTR strClassName = SysAllocString( wcsClassName );
  491. CSysFreeMe fmClassName( strClassName );
  492. HRESULT hresDb = pNS->GetObject( strClassName, 0L, NULL, &pClass, NULL );
  493. CReleaseMe rmClass( pClass );
  494. // If we successfully retrieved an object from the database, then we compare it to
  495. // the template we just built. If the comparison fails, we should replace the object
  496. // ==================================================================================
  497. if ( SUCCEEDED( hresDb ) && NULL != pClass )
  498. {
  499. if ( WBEM_S_SAME == pClass->CompareTo( WBEM_FLAG_IGNORE_OBJECT_SOURCE, *ppTemplate ) )
  500. {
  501. // If they are the same, then swap the template for the stored object
  502. // ==================================================================
  503. (*ppTemplate)->Release();
  504. *ppTemplate = pClass;
  505. (*ppTemplate)->AddRef();
  506. }
  507. else
  508. {
  509. // If they are not the same, then force an update of the repository
  510. // ================================================================
  511. hr = pNS->PutClass( *ppTemplate, WBEM_FLAG_UPDATE_FORCE_MODE, NULL, NULL );
  512. if ( FAILED( hr ) )
  513. {
  514. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  515. WBEM_MC_ADAP_PERFLIB_PUTCLASS_FAILURE,
  516. ADAP_PERF_RAW_BASE_CLASS, (LPCWSTR) m_wstrNamespace, CHex( hr ) );
  517. }
  518. else
  519. {
  520. // Now we need to retrieve the class so we can spawn subclasses as necessary
  521. fGetClass = TRUE;
  522. }
  523. }
  524. }
  525. else
  526. {
  527. // If the retrieval failed, then add the template class to the repository
  528. // ======================================================================
  529. hr = pNS->PutClass( *ppTemplate, WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL );
  530. if ( FAILED( hr ) )
  531. {
  532. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  533. WBEM_MC_ADAP_PERFLIB_PUTCLASS_FAILURE,
  534. ADAP_PERF_RAW_BASE_CLASS, (LPCWSTR) m_wstrNamespace, CHex( hr ) );
  535. }
  536. else
  537. {
  538. // Now we need to retrieve the class so we can spawn subclasses as necessary
  539. fGetClass = TRUE;
  540. }
  541. }
  542. // If we need to retrieve the class from the repository, do so now
  543. if ( SUCCEEDED( hr ) && fGetClass )
  544. {
  545. IWbemClassObject* pSavedObj = NULL;
  546. hr = pNS->GetObject( strClassName, 0L, NULL, &pSavedObj, NULL );
  547. if ( SUCCEEDED( hr ) )
  548. {
  549. (*ppTemplate)->Release();
  550. *ppTemplate = pSavedObj;
  551. }
  552. else
  553. {
  554. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  555. WBEM_MC_ADAP_PERFLIB_PUTCLASS_FAILURE,
  556. ADAP_PERF_RAW_BASE_CLASS, (LPCWSTR) m_wstrNamespace, CHex( hr ) );
  557. }
  558. }
  559. return hr;
  560. }
  561. HRESULT CWMIBroker::SetBaseClassQualifiers( IWbemClassObject* pBaseClass, BOOL bDefault )
  562. {
  563. HRESULT hr = WBEM_NO_ERROR;
  564. _variant_t var;
  565. IWbemQualifierSet* pQualSet = NULL;
  566. hr = pBaseClass->GetQualifierSet( &pQualSet );
  567. CReleaseMe rmQualSet( pQualSet );
  568. // In the root namespace the class is abstract, in the
  569. // localized namespaces the class is an amendment
  570. // ===================================================
  571. if ( bDefault )
  572. {
  573. var = bool(true);
  574. hr = pQualSet->Put( L"abstract", &var, 0L );
  575. if ( SUCCEEDED( hr ) )
  576. {
  577. V_VT(&var) = VT_I4;
  578. V_I4(&var) = ( ADAP_DEFAULT_LANGID );
  579. hr = pQualSet->Put( L"Locale", &var, 0L );
  580. }
  581. }
  582. else
  583. {
  584. var = bool(true);
  585. hr = pQualSet->Put( L"amendment", &var, 0L );
  586. }
  587. return hr;
  588. }
  589. HRESULT CWMIBroker::SetProperties( IWbemClassObject* pPerfClass )
  590. {
  591. HRESULT hr = WBEM_NO_ERROR;
  592. _variant_t var;
  593. V_VT(&var) = VT_NULL;
  594. V_I8(&var) = 0;
  595. // Create the class properties
  596. // ===========================
  597. if ( SUCCEEDED( hr ) )
  598. hr = pPerfClass->Put(L"Frequency_PerfTime", 0L, &var, CIM_UINT64 );
  599. if ( SUCCEEDED( hr ) )
  600. hr = pPerfClass->Put(L"Timestamp_PerfTime", 0L, &var, CIM_UINT64 );
  601. if ( SUCCEEDED( hr ) )
  602. hr = pPerfClass->Put(L"Timestamp_Sys100NS", 0L, &var, CIM_UINT64 );
  603. if ( SUCCEEDED( hr ) )
  604. hr = pPerfClass->Put(L"Frequency_Sys100NS", 0L, &var, CIM_UINT64 );
  605. if ( SUCCEEDED( hr ) )
  606. hr = pPerfClass->Put(L"Frequency_Object", 0L, &var, CIM_UINT64 );
  607. if ( SUCCEEDED( hr ) )
  608. hr = pPerfClass->Put(L"Timestamp_Object", 0L, &var, CIM_UINT64 );
  609. return hr;
  610. }
  611. // This function is called when we actually fail to connect to a namespace. Because there are special
  612. // cases for when a localized namespace may or may not exist, derived classes can do their own
  613. // handling. We, on the other hand, could care less and will always log an event
  614. void CWMIBroker::HandleConnectServerFailure( HRESULT hr )
  615. {
  616. // Log an event
  617. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  618. WBEM_MC_ADAP_CONNECTION_FAILURE,
  619. (LPCWSTR) m_wstrNamespace,
  620. CHex( hr ) );
  621. }
  622. HRESULT CWMIBroker::GetNamespace( WString wstrNamespace, IWbemServices** ppNamespace )
  623. {
  624. HRESULT hr = WBEM_S_NO_ERROR;
  625. CWMIBroker aBroker( wstrNamespace );
  626. hr = aBroker.Connect( ppNamespace );
  627. return hr;
  628. }
  629. HRESULT CWMIBroker::VerifyWMI()
  630. {
  631. HRESULT hr = WBEM_E_FAILED;
  632. HANDLE hWMIMutex = CreateMutex( NULL, FALSE, __TEXT("WINMGMT_ACTIVE") );
  633. if ( hWMIMutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
  634. {
  635. hr = WBEM_S_NO_ERROR;
  636. }
  637. if ( NULL != hWMIMutex )
  638. {
  639. CloseHandle( hWMIMutex );
  640. }
  641. return hr;
  642. }