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.

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