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.

2287 lines
81 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. CLASSBROKER.CPP
  5. Abstract:
  6. History:
  7. --*/
  8. #include "precomp.h"
  9. #include <objbase.h>
  10. #include <oaidl.h>
  11. #include <winmgmtr.h>
  12. #include "adaputil.h"
  13. #include "classbroker.h"
  14. #include <comdef.h>
  15. struct _CookingTypeRec
  16. {
  17. DWORD dwType;
  18. WCHAR wcsName[128];
  19. }
  20. g_aCookingRecs[] =
  21. {
  22. 0x00000000, L"PERF_COUNTER_RAWCOUNT_HEX",
  23. 0x00000100, L"PERF_COUNTER_LARGE_RAWCOUNT_HEX",
  24. 0x00000B00, L"PERF_COUNTER_TEXT",
  25. 0x00010000, L"PERF_COUNTER_RAWCOUNT",
  26. 0x00010100, L"PERF_COUNTER_LARGE_RAWCOUNT",
  27. 0x00012000, L"PERF_DOUBLE_RAW",
  28. 0x00400400, L"PERF_COUNTER_DELTA",
  29. 0x00400500, L"PERF_COUNTER_LARGE_DELTA",
  30. 0x00410400, L"PERF_SAMPLE_COUNTER",
  31. 0x00450400, L"PERF_COUNTER_QUEUELEN_TYPE",
  32. 0x00450500, L"PERF_COUNTER_LARGE_QUEUELEN_TYPE",
  33. 0x00550500, L"PERF_COUNTER_100NS_QUEUELEN_TYPE",
  34. 0x00650500, L"PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE",
  35. 0x10410400, L"PERF_COUNTER_COUNTER",
  36. 0x10410500, L"PERF_COUNTER_BULK_COUNT",
  37. 0x20020400, L"PERF_RAW_FRACTION",
  38. 0x20410500, L"PERF_COUNTER_TIMER",
  39. 0x20470500, L"PERF_PRECISION_SYSTEM_TIMER",
  40. 0x20510500, L"PERF_100NSEC_TIMER",
  41. 0x20570500, L"PERF_PRECISION_100NS_TIMER",
  42. 0x20610500, L"PERF_OBJ_TIME_TIMER",
  43. 0x20670500, L"PERF_PRECISION_OBJECT_TIMER",
  44. 0x20C20400, L"PERF_SAMPLE_FRACTION",
  45. 0x21410500, L"PERF_COUNTER_TIMER_INV",
  46. 0x21510500, L"PERF_100NSEC_TIMER_INV",
  47. 0x22410500, L"PERF_COUNTER_MULTI_TIMER",
  48. 0x22510500, L"PERF_100NSEC_MULTI_TIMER",
  49. 0x23410500, L"PERF_COUNTER_MULTI_TIMER_INV",
  50. 0x23510500, L"PERF_100NSEC_MULTI_TIMER_INV",
  51. 0x30020400, L"PERF_AVERAGE_TIMER",
  52. 0x30240500, L"PERF_ELAPSED_TIME",
  53. 0x40000200, L"PERF_COUNTER_NODATA",
  54. 0x40020500, L"PERF_AVERAGE_BULK",
  55. 0x40030401, L"PERF_SAMPLE_BASE",
  56. 0x40030402, L"PERF_AVERAGE_BASE",
  57. 0x40030403, L"PERF_RAW_BASE",
  58. 0x40030500, L"PERF_PRECISION_TIMESTAMP",
  59. 0x40030503, L"PERF_LARGE_RAW_BASE",
  60. 0x42030500, L"PERF_COUNTER_MULTI_BASE",
  61. 0x80000000, L"PERF_COUNTER_HISTOGRAM_TYPE",
  62. };
  63. HRESULT GetCounterTypeString( DWORD dwType, WCHAR** pwcsString )
  64. {
  65. HRESULT hRes = WBEM_E_NOT_FOUND;
  66. DWORD dwLeft = 0,
  67. dwRight = sizeof( g_aCookingRecs ) / sizeof( _CookingTypeRec ),
  68. dwMid = ( dwLeft + dwRight ) / 2;
  69. while ( ( dwLeft <= dwRight ) && FAILED( hRes ) )
  70. {
  71. if ( g_aCookingRecs[dwMid].dwType < dwType )
  72. {
  73. dwLeft = dwMid + 1;
  74. }
  75. else if ( g_aCookingRecs[dwMid].dwType > dwType )
  76. {
  77. dwRight = dwMid - 1;
  78. }
  79. else
  80. {
  81. *pwcsString = g_aCookingRecs[dwMid].wcsName;
  82. hRes = WBEM_NO_ERROR;
  83. break;
  84. }
  85. dwMid = ( dwLeft + dwRight ) / 2;
  86. }
  87. return hRes;
  88. }
  89. ///////////////////////////////////////////////////////////////////////////////
  90. //
  91. // CAdapPerfClassElem
  92. //
  93. ///////////////////////////////////////////////////////////////////////////////
  94. CClassBroker::CClassBroker( IWbemClassObject* pBaseClass,
  95. WString wstrClassName,
  96. CPerfNameDb* pDefaultNameDb )
  97. : m_pPerfObj( NULL ),
  98. m_pBaseClass( pBaseClass ),
  99. m_wstrClassName( wstrClassName ),
  100. m_pDefaultNameDb( pDefaultNameDb )
  101. {
  102. if ( NULL != m_pBaseClass )
  103. m_pBaseClass->AddRef();
  104. if ( NULL != m_pDefaultNameDb )
  105. m_pDefaultNameDb->AddRef();
  106. }
  107. CClassBroker::CClassBroker( PERF_OBJECT_TYPE* pPerfObj,
  108. BOOL bCostly,
  109. IWbemClassObject* pBaseClass,
  110. CPerfNameDb* pDefaultNameDb,
  111. WCHAR* pwcsServiceName )
  112. : m_pPerfObj( pPerfObj ),
  113. m_bCostly( bCostly ),
  114. m_pBaseClass( pBaseClass ),
  115. m_pDefaultNameDb( pDefaultNameDb ),
  116. m_wstrServiceName( pwcsServiceName )
  117. {
  118. if ( NULL != m_pBaseClass )
  119. m_pBaseClass->AddRef();
  120. if ( NULL != m_pDefaultNameDb )
  121. m_pDefaultNameDb->AddRef();
  122. }
  123. CClassBroker::~CClassBroker()
  124. {
  125. if ( NULL != m_pBaseClass )
  126. m_pBaseClass->Release();
  127. if ( NULL != m_pDefaultNameDb )
  128. m_pDefaultNameDb->Release();
  129. }
  130. HRESULT CClassBroker::Generate( DWORD dwType, IWbemClassObject** ppObj )
  131. ///////////////////////////////////////////////////////////////////////////////
  132. //
  133. // Generates a class based on the object BLOB passed in via the constructor
  134. //
  135. // Parameters:
  136. // ppObj - A pointer to the new class object interface pointer
  137. //
  138. ///////////////////////////////////////////////////////////////////////////////
  139. {
  140. IWbemClassObject* pNewClass = NULL;
  141. // Create the new class
  142. // ====================
  143. HRESULT hr = m_pBaseClass->SpawnDerivedClass( 0L, &pNewClass );
  144. CReleaseMe rmNewClass( pNewClass );
  145. // And initialize the data
  146. // =======================
  147. if ( SUCCEEDED( hr ) )
  148. {
  149. // Class name
  150. // ==========
  151. hr = SetClassName( dwType, pNewClass );
  152. // Class Qualifiers
  153. // ================
  154. if ( SUCCEEDED( hr ) )
  155. {
  156. hr = SetClassQualifiers( pNewClass, dwType, ( ADAP_DEFAULT_OBJECT == m_pPerfObj->ObjectNameTitleIndex ) );
  157. }
  158. // Standard Properties
  159. // ===================
  160. if ( SUCCEEDED( hr ) )
  161. {
  162. hr = AddDefaultProperties( pNewClass );
  163. }
  164. // Perf Counter Properties
  165. // =======================
  166. if ( SUCCEEDED( hr ) )
  167. {
  168. hr = EnumProperties( dwType, pNewClass );
  169. }
  170. // Return the class object interface
  171. // =================================
  172. if ( SUCCEEDED( hr ) )
  173. {
  174. hr = pNewClass->QueryInterface( IID_IWbemClassObject, (void**) ppObj );
  175. }
  176. }
  177. return hr;
  178. }
  179. HRESULT CClassBroker::SetClassName( DWORD dwType, IWbemClassObject* pClass )
  180. ///////////////////////////////////////////////////////////////////////////////
  181. //
  182. // Sets the name of the new WMI class. The syntax is:
  183. //
  184. // Win32_Perf_<servicename>_<displayname>
  185. //
  186. // where the service name is the name of the namespace and the display name
  187. // is the name of the object located in the perf name database
  188. //
  189. // Parameters:
  190. // pClass - The object which requires the name
  191. //
  192. ///////////////////////////////////////////////////////////////////////////////
  193. {
  194. HRESULT hr = WBEM_NO_ERROR;
  195. WString wstrObjectName;
  196. WString wstrTempSvcName;
  197. if ( 0 == m_wstrClassName.Length() )
  198. {
  199. try
  200. {
  201. switch( dwType )
  202. {
  203. case WMI_ADAP_RAW_CLASS: m_wstrClassName = ADAP_PERF_RAW_BASE_CLASS L"_"; break;
  204. case WMI_ADAP_COOKED_CLASS: m_wstrClassName = ADAP_PERF_COOKED_BASE_CLASS L"_"; break;
  205. default: hr = WBEM_E_INVALID_PARAMETER_ID; break;
  206. }
  207. }
  208. catch(...)
  209. {
  210. return WBEM_E_OUT_OF_MEMORY;
  211. }
  212. // Process the performance class name
  213. // ==================================
  214. if ( SUCCEEDED( hr ) )
  215. {
  216. // Get the performance class' display name
  217. // =======================================
  218. hr = m_pDefaultNameDb->GetDisplayName( m_pPerfObj->ObjectNameTitleIndex, wstrObjectName );
  219. // If no object name was returned, then log an error
  220. // =================================================
  221. if ( FAILED( hr ) )
  222. {
  223. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  224. WBEM_MC_ADAP_MISSING_OBJECT_INDEX,
  225. m_pPerfObj->ObjectNameTitleIndex,
  226. (LPCWSTR)m_wstrServiceName );
  227. }
  228. // Replace reserved characters with proper names
  229. // =============================================
  230. if ( SUCCEEDED( hr ) )
  231. {
  232. hr = ReplaceReserved( wstrObjectName );
  233. }
  234. // Remove whitespace and extraneous characters
  235. // ===========================================
  236. if ( SUCCEEDED( hr ) )
  237. {
  238. hr = RemoveWhitespaceAndNonAlphaNum( wstrObjectName );
  239. }
  240. }
  241. // Now do the same for the service name
  242. // ====================================
  243. if ( SUCCEEDED( hr ) )
  244. {
  245. // Get the service name
  246. // ====================
  247. wstrTempSvcName = m_wstrServiceName;
  248. // Replace reserved characters with proper names
  249. // =============================================
  250. if ( SUCCEEDED( hr ) )
  251. {
  252. hr = ReplaceReserved( wstrTempSvcName );
  253. }
  254. // Remove whitespace and extraneous characters
  255. // ===========================================
  256. if ( SUCCEEDED( hr ) )
  257. {
  258. hr = RemoveWhitespaceAndNonAlphaNum( wstrTempSvcName );
  259. }
  260. }
  261. // Now we can build the rest of the name and try setting it in the object
  262. // ======================================================================
  263. if ( SUCCEEDED( hr ) )
  264. {
  265. try
  266. {
  267. m_wstrClassName += wstrTempSvcName;
  268. m_wstrClassName += L"_";
  269. m_wstrClassName += wstrObjectName;
  270. if ( m_bCostly )
  271. {
  272. m_wstrClassName += "_Costly";
  273. }
  274. }
  275. catch( ... )
  276. {
  277. hr = WBEM_E_OUT_OF_MEMORY;
  278. }
  279. }
  280. }
  281. // Set the class name in the WMI object
  282. // ====================================
  283. if ( SUCCEEDED( hr ) )
  284. {
  285. _variant_t var = (LPWSTR) m_wstrClassName;
  286. hr = pClass->Put( L"__CLASS", 0L, &var, CIM_STRING );
  287. }
  288. return hr;
  289. }
  290. HRESULT CClassBroker::RemoveWhitespaceAndNonAlphaNum( WString& wstr )
  291. ///////////////////////////////////////////////////////////////////////////////
  292. //
  293. // Removes spaces, tabs, etc. and non-alphanumeric characters from the
  294. // input string
  295. //
  296. // Parameters:
  297. // wstr - The string to be processed
  298. //
  299. ///////////////////////////////////////////////////////////////////////////////
  300. {
  301. HRESULT hr = WBEM_S_NO_ERROR;
  302. WCHAR* pWstr = wstr.UnbindPtr();
  303. CVectorDeleteMe<WCHAR> vdmWstr( pWstr );
  304. if ( NULL != pWstr )
  305. {
  306. try
  307. {
  308. WCHAR* pNewWstr = new WCHAR[lstrlenW(pWstr) + 1];
  309. if (NULL == pNewWstr) return WBEM_E_OUT_OF_MEMORY;
  310. int x = 0;
  311. int y = 0;
  312. // Dump all of the leading, trailing and internal whitespace
  313. // =========================================================
  314. for ( ; NULL != pWstr[x]; x++ )
  315. {
  316. if ( !iswspace( pWstr[x] ) && isunialphanum( pWstr[x] ) )
  317. {
  318. pNewWstr[y] = pWstr[x];
  319. y++;
  320. }
  321. }
  322. pNewWstr[y] = NULL;
  323. // This will cause the WString to acquire the new pointer
  324. // ======================================================
  325. wstr.BindPtr( pNewWstr );
  326. }
  327. catch(...)
  328. {
  329. hr = WBEM_E_OUT_OF_MEMORY;
  330. }
  331. }
  332. return hr;
  333. }
  334. HRESULT CClassBroker::ReplaceReserved( WString& wstr )
  335. ///////////////////////////////////////////////////////////////////////////////
  336. //
  337. // This is a 2-pass filter. First we must determine the size of the new buffer by counting
  338. // the number of replacement candidates, and, after creating the new buffer, we copy the
  339. // data, replacing the restricted characters where required.
  340. //
  341. // Replaces:
  342. // "/" with "Per",
  343. // "%" with "Percent",
  344. // "#" with "Number",
  345. // "@" with "At",
  346. // "&" with "And"
  347. //
  348. // Parameters:
  349. // wstr - String to be processed
  350. //
  351. ///////////////////////////////////////////////////////////////////////////////
  352. {
  353. HRESULT hr = WBEM_S_NO_ERROR;
  354. int x = 0,
  355. y = 0;
  356. // Get the data buffer for processing
  357. // ==================================
  358. WCHAR* pWstr = wstr.UnbindPtr();
  359. CVectorDeleteMe<WCHAR> vdmWstr( pWstr );
  360. if ( NULL != pWstr )
  361. {
  362. // First pass: Count the number of reserved characters
  363. // ===================================================
  364. DWORD dwNumSlashes = 0,
  365. dwNumPercent = 0,
  366. dwNumAt = 0,
  367. dwNumNumber = 0,
  368. dwNumAmper = 0,
  369. dwNumReserved = 0;
  370. for ( ; NULL != pWstr[x]; x++ )
  371. {
  372. switch ( pWstr[x] )
  373. {
  374. case L'/': dwNumSlashes++; dwNumReserved++; break;
  375. case L'%': dwNumPercent++; dwNumReserved++; break;
  376. case L'@': dwNumAt++; dwNumReserved++; break;
  377. case L'#': dwNumNumber++; dwNumReserved++; break;
  378. case L'&': dwNumAmper++; dwNumReserved++; break;
  379. default: break;
  380. }
  381. }
  382. try
  383. {
  384. // Create the new buffer
  385. // =====================
  386. DWORD dwBuffSize = lstrlenW(pWstr) + 1 + ( 3 * dwNumSlashes ) + ( 7 * dwNumPercent ) +
  387. ( 2 * dwNumAt ) + ( 6 * dwNumNumber ) + ( 3 * dwNumAmper );
  388. WCHAR* pNewWstr = new WCHAR[dwBuffSize];
  389. if (NULL == pNewWstr) return WBEM_E_OUT_OF_MEMORY;
  390. // Second pass: Replace reserved characters
  391. // ========================================
  392. DWORD dwBuffSizeCurr = dwBuffSize;
  393. for ( x = 0; NULL != pWstr[x]; x++ )
  394. {
  395. BOOL AllIsUpper = FALSE;
  396. DWORD Cnt;
  397. switch ( pWstr[x] )
  398. {
  399. case L'/':
  400. // if all characters up to the end of string or to the next space are uppercase
  401. for (Cnt=1;pWstr[x+Cnt] && pWstr[x+Cnt]!=' ';Cnt++)
  402. {
  403. if (isupper(pWstr[x+Cnt]))
  404. {
  405. AllIsUpper = TRUE;
  406. }
  407. else
  408. {
  409. AllIsUpper = FALSE;
  410. break;
  411. }
  412. };
  413. if (!AllIsUpper)
  414. {
  415. StringCchCopyW( &pNewWstr[y],dwBuffSizeCurr, L"Per" );
  416. y+=3;
  417. dwBuffSizeCurr-=3;
  418. }
  419. else
  420. {
  421. x++;
  422. pNewWstr[y]=pWstr[x];
  423. y++;
  424. dwBuffSizeCurr--;
  425. }
  426. break;
  427. case L'%': StringCchCopyW( &pNewWstr[y],dwBuffSizeCurr, L"Percent" ); y+=7; dwBuffSizeCurr-=7; break;
  428. case L'@': StringCchCopyW( &pNewWstr[y],dwBuffSizeCurr, L"At" ); y+=2; dwBuffSizeCurr-=2; break;
  429. case L'#': StringCchCopyW( &pNewWstr[y],dwBuffSizeCurr, L"Number" ); y+=6; dwBuffSizeCurr-=6; break;
  430. case L'&': StringCchCopyW( &pNewWstr[y],dwBuffSizeCurr, L"And" ); y+=3; dwBuffSizeCurr-=3; break;
  431. default: pNewWstr[y] = pWstr[x]; y++; dwBuffSizeCurr--; break;
  432. }
  433. }
  434. pNewWstr[y] = NULL;
  435. // This will cause the WString to acquire the new pointer
  436. // ======================================================
  437. wstr.BindPtr( pNewWstr );
  438. }
  439. catch(...)
  440. {
  441. hr = WBEM_E_OUT_OF_MEMORY;
  442. }
  443. }
  444. return hr;
  445. }
  446. ////////////////////////////////////////////////////////////////////////////////////////////
  447. //
  448. // CLocaleClassBroker
  449. //
  450. ////////////////////////////////////////////////////////////////////////////////////////////
  451. CLocaleClassBroker::CLocaleClassBroker( IWbemClassObject* pBaseClass,
  452. WString wstrClassName,
  453. CPerfNameDb* pDefaultNameDb,
  454. CPerfNameDb* pLocaleNameDb )
  455. : CClassBroker( pBaseClass, wstrClassName, pDefaultNameDb ),
  456. m_pLocaleNameDb( pLocaleNameDb )
  457. {
  458. if ( NULL != m_pLocaleNameDb )
  459. m_pLocaleNameDb->AddRef();
  460. }
  461. CLocaleClassBroker::CLocaleClassBroker( PERF_OBJECT_TYPE* pPerfObj,
  462. BOOL bCostly,
  463. IWbemClassObject* pBaseClass,
  464. CPerfNameDb* pDefaultNameDb,
  465. CPerfNameDb* pLocaleNameDb,
  466. LANGID LangId,
  467. WCHAR* pwcsServiceName )
  468. : m_pLocaleNameDb( pLocaleNameDb ), m_LangId( LangId ),
  469. CClassBroker( pPerfObj, bCostly, pBaseClass, pDefaultNameDb, pwcsServiceName )
  470. {
  471. if ( NULL != m_pLocaleNameDb )
  472. m_pLocaleNameDb->AddRef();
  473. }
  474. CLocaleClassBroker::~CLocaleClassBroker()
  475. {
  476. if ( NULL != m_pLocaleNameDb )
  477. m_pLocaleNameDb->Release();
  478. }
  479. HRESULT CLocaleClassBroker::SetClassQualifiers( IWbemClassObject* pClass, DWORD dwType, BOOL fIsDefault )
  480. ////////////////////////////////////////////////////////////////////////////////////////////
  481. //
  482. // Sets the class' qualifiers per the localized object rules. Note that the operations
  483. // are performed directly on the IWbemClassObject
  484. //
  485. // The following qualifiers will be added:
  486. // - Amendment
  487. // - Locale(0x0409)
  488. // - DisplayName (Amended flavor)
  489. // - Genericperfctr (signals that this is a generic counter)
  490. //
  491. // Parameters:
  492. // pClass - The object to be massaged
  493. // fIsDefault - Indicator for the default object (not used in localized objects)
  494. //
  495. ////////////////////////////////////////////////////////////////////////////////////////////
  496. {
  497. HRESULT hr = WBEM_S_NO_ERROR;
  498. _variant_t var;
  499. try
  500. {
  501. IWbemQualifierSet* pQualSet = NULL;
  502. hr = pClass->GetQualifierSet( &pQualSet );
  503. CReleaseMe rmQualSet( pQualSet );
  504. // Amendment
  505. // =========
  506. if ( SUCCEEDED( hr ) )
  507. {
  508. var = (bool)true;
  509. hr = pQualSet->Put( L"Amendment", &var, 0L );
  510. }
  511. // Locale
  512. // ======
  513. if ( SUCCEEDED( hr ) )
  514. {
  515. var.Clear();
  516. V_VT(&var) = VT_I4;
  517. V_I4(&var) = m_LangId;
  518. hr = pQualSet->Put( L"locale", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  519. }
  520. // DisplayName
  521. // ===========
  522. if ( SUCCEEDED( hr ) )
  523. {
  524. LPCWSTR pwcsDisplayName = NULL;
  525. var.Clear();
  526. // Fetch the name from the Names' database
  527. // =======================================
  528. hr = m_pLocaleNameDb->GetDisplayName( m_pPerfObj->ObjectNameTitleIndex, &pwcsDisplayName );
  529. // If this is a localized Db, this is a benign error. We will just pull the value
  530. // from the default db (it must be there, we wouldn't have a class name if it didn't
  531. // =================================================================================
  532. if ( FAILED( hr ) )
  533. {
  534. hr = m_pDefaultNameDb->GetDisplayName( m_pPerfObj->ObjectNameTitleIndex, &pwcsDisplayName );
  535. }
  536. if ( SUCCEEDED( hr ) )
  537. {
  538. var = (LPWSTR) pwcsDisplayName ;
  539. hr = pQualSet->Put( L"DisplayName", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_AMENDED );
  540. }
  541. }
  542. // Genericperfctr
  543. // ==============
  544. if ( SUCCEEDED(hr) )
  545. {
  546. var = (bool)true;
  547. hr = pQualSet->Put( L"genericperfctr", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  548. }
  549. // Perfindex
  550. // =========
  551. if ( SUCCEEDED( hr ) )
  552. {
  553. var.Clear();
  554. V_VT(&var) = VT_I4;
  555. V_I4(&var) = m_pPerfObj->ObjectNameTitleIndex;
  556. hr = pQualSet->Put( L"perfindex", (VARIANT*)&var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  557. }
  558. }
  559. catch(...)
  560. {
  561. hr = WBEM_E_OUT_OF_MEMORY;
  562. }
  563. if ( FAILED( hr ) )
  564. {
  565. // Something whacky happened: log an event
  566. // =======================================
  567. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  568. WBEM_MC_ADAP_GENERAL_OBJECT_FAILURE,
  569. (LPCWSTR)m_wstrClassName,
  570. (LPCWSTR)m_wstrServiceName,
  571. CHex( hr ) );
  572. }
  573. return hr;
  574. }
  575. HRESULT CLocaleClassBroker::AddDefaultProperties( IWbemClassObject* pObj )
  576. ////////////////////////////////////////////////////////////////////////////////////////////
  577. //
  578. // Ignored for localized classes
  579. //
  580. ////////////////////////////////////////////////////////////////////////////////////////////
  581. {
  582. return WBEM_S_NO_ERROR;
  583. }
  584. HRESULT CLocaleClassBroker::EnumProperties( DWORD dwType, IWbemClassObject* pObj )
  585. ////////////////////////////////////////////////////////////////////////////////////////////
  586. //
  587. // Ignored for localized classes
  588. //
  589. ////////////////////////////////////////////////////////////////////////////////////////////
  590. {
  591. return WBEM_S_NO_ERROR;
  592. }
  593. HRESULT CLocaleClassBroker::SetPropertyQualifiers( PERF_COUNTER_DEFINITION* pCtrDefinition,
  594. DWORD dwType,
  595. BOOL fIsDefault,
  596. LPCWSTR pwcsPropertyName,
  597. IWbemClassObject* pClass,
  598. BOOL bBase )
  599. ////////////////////////////////////////////////////////////////////////////////////////////
  600. //
  601. // Adds localization qualifiers for the counter properties
  602. //
  603. // The following qualifiers will be added:
  604. // - DisplayName (Amended flavor)
  605. //
  606. // Properties:
  607. // pCtrDefinition - The portion of the performance blob related to the property
  608. // fIsDefault - Flag identifying default property
  609. // pwcsPropertyName - The name of the property
  610. // pClass - The WMI class containing the property
  611. // bBase - Base property identifier
  612. //
  613. ////////////////////////////////////////////////////////////////////////////////////////////
  614. {
  615. HRESULT hr = WBEM_S_NO_ERROR;
  616. _variant_t var;
  617. _variant_t varHelp;
  618. try
  619. {
  620. // DisplayName
  621. // ===========
  622. if ( SUCCEEDED( hr ) )
  623. {
  624. LPCWSTR pwcsDisplayName = NULL;
  625. LPCWSTR pwcsHelpName = NULL;
  626. // Fetch the name from the Names' database
  627. // =======================================
  628. if ( !bBase )
  629. {
  630. hr = m_pLocaleNameDb->GetDisplayName( pCtrDefinition->CounterNameTitleIndex, &pwcsDisplayName );
  631. // If this is a localized Db, this is a benign error. We will just pull the value
  632. // from the default db (it must be there, we wouldn't have a class name if it didn't
  633. // =================================================================================
  634. if ( FAILED( hr ) )
  635. {
  636. hr = m_pDefaultNameDb->GetDisplayName( pCtrDefinition->CounterNameTitleIndex, &pwcsDisplayName );
  637. }
  638. if ( SUCCEEDED( hr ) )
  639. {
  640. var = (LPWSTR) pwcsDisplayName ;
  641. }
  642. hr = m_pLocaleNameDb->GetHelpName( pCtrDefinition->CounterHelpTitleIndex, &pwcsHelpName );
  643. // If this is a localized Db, this is a benign error. We will just pull the value
  644. // from the default db (it must be there, we wouldn't have a class name if it didn't
  645. // =================================================================================
  646. if ( FAILED( hr ) )
  647. {
  648. hr = m_pDefaultNameDb->GetHelpName( pCtrDefinition->CounterHelpTitleIndex, &pwcsHelpName );
  649. }
  650. if ( SUCCEEDED( hr ) )
  651. {
  652. varHelp = (LPWSTR) pwcsHelpName ;
  653. }
  654. }
  655. else
  656. {
  657. var = L"";
  658. varHelp = L"";
  659. }
  660. // Set the qualifier
  661. // =================
  662. if ( SUCCEEDED( hr ) )
  663. {
  664. IWbemQualifierSet* pQualSet = NULL;
  665. hr = pClass->GetPropertyQualifierSet( pwcsPropertyName, &pQualSet );
  666. CReleaseMe rmQualSet( pQualSet );
  667. if ( SUCCEEDED( hr ) )
  668. {
  669. hr = pQualSet->Put( L"DisplayName", &var,
  670. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_AMENDED );
  671. if (SUCCEEDED(hr))
  672. {
  673. hr = pQualSet->Put( L"Description", &varHelp,
  674. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_AMENDED );
  675. }
  676. }
  677. }
  678. }
  679. }
  680. catch(...)
  681. {
  682. hr = WBEM_E_OUT_OF_MEMORY;
  683. }
  684. if ( FAILED( hr ) )
  685. {
  686. // Something whacky happened: log an event
  687. // =======================================
  688. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  689. WBEM_MC_ADAP_GENERAL_OBJECT_FAILURE,
  690. (LPCWSTR)m_wstrClassName,
  691. (LPCWSTR)m_wstrServiceName,
  692. CHex( hr ) );
  693. }
  694. return hr;
  695. }
  696. HRESULT CLocaleClassBroker::AddProperty( PERF_COUNTER_DEFINITION* pCtrDefinition,
  697. DWORD dwType,
  698. BOOL fIsDefault,
  699. IWbemClassObject* pClass,
  700. WString &wstrLastCtrName,
  701. BOOL* pbLastCounterIsNotBase )
  702. ////////////////////////////////////////////////////////////////////////////////////////////
  703. //
  704. // Ignored for localized classes
  705. //
  706. ////////////////////////////////////////////////////////////////////////////////////////////
  707. {
  708. return WBEM_S_NO_ERROR;
  709. }
  710. HRESULT CLocaleClassBroker::GenPerfClass( PERF_OBJECT_TYPE* pPerfObj,
  711. DWORD dwType,
  712. BOOL bCostly,
  713. IWbemClassObject* pBaseClass,
  714. CPerfNameDb* pDefaultNameDb,
  715. CPerfNameDb* pLocaleNameDb,
  716. LANGID LangId,
  717. WCHAR* pwcsServiceName,
  718. IWbemClassObject** ppObj)
  719. ///////////////////////////////////////////////////////////////////////////////
  720. //
  721. // A static member of the broker. It generates a WMI class based on the
  722. // object BLOB.
  723. //
  724. // Parameters:
  725. // pPerfObj - The object BLOB
  726. // bCostly - Costly object indicator
  727. // pBaseClass - The new object's base class
  728. // pDefaultNameDb - The default language names' database
  729. // pLocaleNameDb - The localized language names' database
  730. // LangId - The locale ID
  731. // pwcsServiceName - The name of the perflib service
  732. // ppObj - A pointer to the new class object interface pointer
  733. //
  734. ///////////////////////////////////////////////////////////////////////////////
  735. {
  736. HRESULT hr = WBEM_S_NO_ERROR;
  737. IWbemClassObject* pObject = NULL;
  738. CLocaleClassBroker Broker( pPerfObj, bCostly, pBaseClass, pDefaultNameDb, pLocaleNameDb, LangId, pwcsServiceName );
  739. hr = Broker.Generate( dwType, &pObject );
  740. if ( SUCCEEDED( hr ) )
  741. *ppObj = pObject;
  742. return hr;
  743. }
  744. HRESULT CLocaleClassBroker::ConvertToLocale( IWbemClassObject* pDefaultClass,
  745. CLocaleDefn* pLocaleDefn,
  746. CLocaleDefn* pDefaultDefn,
  747. IWbemClassObject** ppObject)
  748. ///////////////////////////////////////////////////////////////////////////////
  749. //
  750. // A static member of the broker. It generates a new localized class based
  751. // on the default object
  752. //
  753. ///////////////////////////////////////////////////////////////////////////////
  754. {
  755. HRESULT hr = WBEM_S_NO_ERROR;
  756. _variant_t var;
  757. int nLocale = 0;
  758. int nPerfIndex = 0;
  759. int nHelpIndex = 0;
  760. WString wstrClassName;
  761. DWORD dwType = WMI_ADAP_RAW_CLASS;
  762. CPerfNameDb* pLocaleNameDb = NULL;
  763. CPerfNameDb* pDefaultNameDb = NULL;
  764. // Get references to the localized name's databases
  765. // ================================================
  766. hr = pLocaleDefn->GetNameDb( &pLocaleNameDb );
  767. CAdapReleaseMe armLocaleNameDb( pLocaleNameDb );
  768. // Get references to the default name's databases
  769. // ==============================================
  770. if ( SUCCEEDED( hr ) )
  771. {
  772. hr = pDefaultDefn->GetNameDb( &pDefaultNameDb );
  773. }
  774. CAdapReleaseMe armDefaultNameDb( pDefaultNameDb );
  775. // Get the locale ID
  776. // =================
  777. if ( SUCCEEDED( hr ) )
  778. {
  779. hr = pLocaleDefn->GetLID( nLocale );
  780. }
  781. // Get the object's perf index
  782. // ===========================
  783. if ( SUCCEEDED( hr ) )
  784. {
  785. IWbemQualifierSet* pQualSet = NULL;
  786. hr = pDefaultClass->GetQualifierSet( &pQualSet );
  787. CReleaseMe rmQualSet( pQualSet );
  788. if ( SUCCEEDED( hr ) )
  789. {
  790. hr = pQualSet->Get( L"perfindex", 0L, &var, NULL );
  791. if (SUCCEEDED(hr))
  792. {
  793. nPerfIndex = V_I4(&var);
  794. }
  795. else
  796. {
  797. // see InitializeMembers
  798. nPerfIndex = 0;
  799. hr = WBEM_S_FALSE;
  800. }
  801. }
  802. if ( SUCCEEDED( hr ) )
  803. {
  804. hr = pQualSet->Get( L"helpindex", 0L, &var, NULL );
  805. if (SUCCEEDED(hr))
  806. {
  807. nHelpIndex = V_I4(&var);
  808. }
  809. else
  810. {
  811. // see InitializeMembers
  812. nHelpIndex = 0;
  813. hr = WBEM_S_FALSE;
  814. }
  815. }
  816. if ( SUCCEEDED( hr ) )
  817. {
  818. hr = pQualSet->Get( L"Cooked", 0L, &var, NULL );
  819. if ( SUCCEEDED( hr ) && ( V_BOOL(&var) == VARIANT_TRUE ) )
  820. {
  821. dwType = WMI_ADAP_COOKED_CLASS;
  822. }
  823. else
  824. {
  825. dwType = WMI_ADAP_RAW_CLASS;
  826. hr = WBEM_S_FALSE;
  827. }
  828. }
  829. }
  830. // Get the class name
  831. // ==================
  832. if ( SUCCEEDED( hr ) )
  833. {
  834. var.Clear();
  835. hr = pDefaultClass->Get( L"__CLASS", 0L, &var, NULL, NULL );
  836. wstrClassName = V_BSTR(&var);
  837. }
  838. // Create locaized class
  839. // =====================
  840. IWbemClassObject* pBaseClass = NULL;
  841. IWbemClassObject* pLocaleClass = NULL;
  842. if ( SUCCEEDED( hr ) )
  843. {
  844. hr = pLocaleDefn->GetBaseClass( dwType, &pBaseClass );
  845. CReleaseMe rmBaseClass( pBaseClass );
  846. if ( SUCCEEDED( hr ) )
  847. {
  848. hr = pBaseClass->SpawnDerivedClass( 0L, &pLocaleClass );
  849. }
  850. }
  851. // Initialize the data
  852. // ===================
  853. // Set the name
  854. // ============
  855. if ( SUCCEEDED( hr ) )
  856. {
  857. var.Clear();
  858. var = LPCWSTR(wstrClassName);
  859. hr = pLocaleClass->Put( L"__CLASS", 0L, &var, CIM_STRING );
  860. }
  861. // Set Qualifiers
  862. // ==============
  863. if ( SUCCEEDED( hr ) )
  864. {
  865. IWbemQualifierSet* pQualSet = NULL;
  866. hr = pLocaleClass->GetQualifierSet( &pQualSet );
  867. CReleaseMe rmQualSet( pQualSet );
  868. // Amendment
  869. // =========
  870. if ( SUCCEEDED( hr ) )
  871. {
  872. var.Clear();
  873. var = bool(true);
  874. hr = pQualSet->Put( L"Amendment", &var, 0L );
  875. }
  876. // Locale
  877. // ======
  878. if ( SUCCEEDED( hr ) )
  879. {
  880. var.Clear();
  881. V_VT(&var) = VT_I4;
  882. V_I4(&var) = nLocale;
  883. hr = pQualSet->Put( L"locale", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  884. }
  885. // DisplayName
  886. // ===========
  887. if ( SUCCEEDED( hr ) )
  888. {
  889. LPCWSTR pwcsDisplayName = NULL;
  890. hr = pLocaleNameDb->GetDisplayName( nPerfIndex, &pwcsDisplayName );
  891. // If this is a localized Db, this is a benign error. We will just pull the value
  892. // from the default db (it must be there, we wouldn't have a class name if it didn't
  893. // =================================================================================
  894. if ( FAILED( hr ) )
  895. {
  896. hr = pDefaultNameDb->GetDisplayName( nPerfIndex, &pwcsDisplayName );
  897. }
  898. if ( SUCCEEDED( hr ) )
  899. {
  900. var.Clear();
  901. var = (WCHAR *)( pwcsDisplayName );
  902. hr = pQualSet->Put( L"DisplayName", &var,
  903. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_AMENDED );
  904. }
  905. else
  906. {
  907. // the nPerfInedx was bad
  908. ERRORTRACE((LOG_WMIADAP,"class %S: DisplayName for counter %d not found\n",(WCHAR *)wstrClassName,nPerfIndex));
  909. }
  910. }
  911. // Description
  912. // ===========
  913. if ( SUCCEEDED( hr ) )
  914. {
  915. LPCWSTR pwcsHelpName = NULL;
  916. hr = pLocaleNameDb->GetHelpName( nHelpIndex, &pwcsHelpName );
  917. // If this is a localized Db, this is a benign error. We will just pull the value
  918. // from the default db (it must be there, we wouldn't have a class name if it didn't
  919. // =================================================================================
  920. if ( FAILED( hr ) )
  921. {
  922. hr = pDefaultNameDb->GetHelpName( nHelpIndex, &pwcsHelpName );
  923. }
  924. if ( SUCCEEDED( hr ) )
  925. {
  926. var.Clear();
  927. var = (WCHAR *)( pwcsHelpName );
  928. hr = pQualSet->Put( L"Description", &var,
  929. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_AMENDED );
  930. }
  931. else
  932. {
  933. // the nPerfInedx was bad
  934. ERRORTRACE((LOG_WMIADAP,"class %S: Description for counter %d not found\n",(WCHAR *)wstrClassName,nPerfIndex));
  935. }
  936. }
  937. // Genericperfctr
  938. // ==============
  939. if ( SUCCEEDED(hr) )
  940. {
  941. var.Clear();
  942. var = bool(true);
  943. hr = pQualSet->Put( L"genericperfctr", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  944. }
  945. }
  946. // Set Properties
  947. // ==============
  948. if ( SUCCEEDED( hr ) )
  949. {
  950. BSTR bstrPropName;
  951. pDefaultClass->BeginEnumeration( WBEM_FLAG_LOCAL_ONLY );
  952. while ( WBEM_S_NO_ERROR == pDefaultClass->Next( 0, &bstrPropName, NULL, NULL, NULL ) )
  953. {
  954. CSysFreeMe sfm(bstrPropName);
  955. var.Clear();
  956. CIMTYPE ct;
  957. int nCounterIndex = 0;
  958. int nHelpIndex2 = 0;
  959. WString wstrDefaultPropDisplayName;
  960. // Create the property based upon the default property
  961. // ===================================================
  962. V_VT(&var) = VT_NULL;
  963. V_I8(&var) = 0;
  964. hr = pDefaultClass->Get( bstrPropName, 0L, NULL, &ct, NULL );
  965. if (FAILED(hr)) continue;
  966. hr = pLocaleClass->Put( bstrPropName, 0L, (VARIANT*)&var, ct );
  967. if (FAILED(hr)) continue;
  968. // Grab the default property qualifier set
  969. // =======================================
  970. IWbemQualifierSet* pQualSet = NULL;
  971. hr = pDefaultClass->GetPropertyQualifierSet( bstrPropName, &pQualSet );
  972. CReleaseMe rmQualSet( pQualSet );
  973. // Get the default perfindex to be (used to retrieve the display
  974. // name from the localized names' database)
  975. // =============================================================
  976. if ( SUCCEEDED( hr ) )
  977. {
  978. hr = pQualSet->Get( L"perfindex", 0L, &var, NULL );
  979. nCounterIndex = V_UI4(&var);
  980. }
  981. // DisplayName
  982. // ===========
  983. if ( SUCCEEDED( hr ) )
  984. {
  985. LPCWSTR pwcsDisplayName = NULL;
  986. hr = pLocaleNameDb->GetDisplayName( nCounterIndex, &pwcsDisplayName );
  987. // If this is a localized Db, this is a benign error. We will just pull the value
  988. // from the default db (it must be there, we wouldn't have a class name if it didn't
  989. // =================================================================================
  990. if ( FAILED( hr ) )
  991. {
  992. hr = pDefaultNameDb->GetDisplayName( nCounterIndex, &pwcsDisplayName );
  993. }
  994. if ( SUCCEEDED( hr ) )
  995. {
  996. IWbemQualifierSet* pLocaleQualSet = NULL;
  997. hr = pLocaleClass->GetPropertyQualifierSet( bstrPropName, &pLocaleQualSet );
  998. CReleaseMe rmLocaleQualSet( pLocaleQualSet );
  999. var = (WCHAR *)( pwcsDisplayName );
  1000. hr = pLocaleQualSet->Put( L"DisplayName", &var,
  1001. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_AMENDED );
  1002. }
  1003. else
  1004. {
  1005. ERRORTRACE((LOG_WMIADAP,"class %S: Display for counter %d not found\n",(WCHAR *)wstrClassName,nCounterIndex));
  1006. }
  1007. }
  1008. // HelpIndex
  1009. if ( SUCCEEDED( hr ) )
  1010. {
  1011. var.Clear();
  1012. hr = pQualSet->Get( L"helpindex", 0L, &var, NULL );
  1013. nHelpIndex2 = V_UI4(&var);
  1014. }
  1015. // Description
  1016. // ===========
  1017. if ( SUCCEEDED( hr ) )
  1018. {
  1019. LPCWSTR pwcsHelpName = NULL;
  1020. hr = pLocaleNameDb->GetHelpName( nHelpIndex2, &pwcsHelpName );
  1021. // If this is a localized Db, this is a benign error. We will just pull the value
  1022. // from the default db (it must be there, we wouldn't have a class name if it didn't
  1023. // =================================================================================
  1024. if ( FAILED( hr ) )
  1025. {
  1026. hr = pDefaultNameDb->GetHelpName( nHelpIndex2, &pwcsHelpName );
  1027. }
  1028. if ( SUCCEEDED( hr ) )
  1029. {
  1030. IWbemQualifierSet* pLocaleQualSet = NULL;
  1031. hr = pLocaleClass->GetPropertyQualifierSet( bstrPropName, &pLocaleQualSet );
  1032. CReleaseMe rmLocaleQualSet( pLocaleQualSet );
  1033. var = (WCHAR *)( pwcsHelpName );
  1034. hr = pLocaleQualSet->Put( L"Description", &var,
  1035. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_AMENDED );
  1036. }
  1037. else
  1038. {
  1039. ERRORTRACE((LOG_WMIADAP,"class %S: Description for counter %d not found\n",(WCHAR *)wstrClassName,nCounterIndex));
  1040. }
  1041. }
  1042. }
  1043. pDefaultClass->EndEnumeration();
  1044. }
  1045. if ( SUCCEEDED( hr ) )
  1046. {
  1047. *ppObject = pLocaleClass;
  1048. if ( NULL != *ppObject )
  1049. (*ppObject)->AddRef();
  1050. }
  1051. return hr;
  1052. }
  1053. ////////////////////////////////////////////////////////////////////////////////////////////
  1054. //
  1055. // CDefaultClassBroker
  1056. //
  1057. ////////////////////////////////////////////////////////////////////////////////////////////
  1058. HRESULT CDefaultClassBroker::SetClassQualifiers( IWbemClassObject* pClass, DWORD dwType, BOOL fIsDefault )
  1059. ////////////////////////////////////////////////////////////////////////////////////////////
  1060. //
  1061. // Sets the class' qualifiers. Note that the operations are performed directly on the
  1062. // IWbemClassObject.
  1063. //
  1064. // The following qualifiers will be added:
  1065. // - Dynamic
  1066. // - Provider("NT5_GenericPerfProvider_V1")
  1067. // - Registrykey
  1068. // - Locale(0x0409)
  1069. // - Perfindex
  1070. // - Helpindex
  1071. // - Perfdetail
  1072. // - Genericperfctr (signals that this is a generic counter)
  1073. // - Singleton (if applicable)
  1074. // - Costly (if applicable)
  1075. //
  1076. // Parameters:
  1077. // pClass - The object to be massaged
  1078. // fIsDefault - Indicator for the default object (not used in localized objects)
  1079. //
  1080. ////////////////////////////////////////////////////////////////////////////////////////////
  1081. {
  1082. HRESULT hr = WBEM_S_NO_ERROR;
  1083. _variant_t var;
  1084. try
  1085. {
  1086. IWbemQualifierSet* pQualSet = NULL;
  1087. hr = pClass->GetQualifierSet( &pQualSet );
  1088. CReleaseMe rmQualSet( pQualSet );
  1089. switch ( dwType )
  1090. {
  1091. case WMI_ADAP_RAW_CLASS:
  1092. {
  1093. // Default
  1094. // =======
  1095. if ( SUCCEEDED( hr ) && fIsDefault )
  1096. {
  1097. var = bool(true);
  1098. hr = pQualSet->Put( L"perfdefault", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1099. }
  1100. // Dynamic
  1101. // =======
  1102. if ( SUCCEEDED( hr ) )
  1103. {
  1104. var = bool(true);
  1105. hr = pQualSet->Put( L"dynamic", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1106. }
  1107. // Provider
  1108. // ========
  1109. if ( SUCCEEDED( hr ) )
  1110. {
  1111. var = L"Nt5_GenericPerfProvider_V1";
  1112. hr = pQualSet->Put( L"provider", &var, 0L );
  1113. }
  1114. // Registrykey
  1115. // ===========
  1116. if ( SUCCEEDED( hr ) )
  1117. {
  1118. var = (WCHAR *)(m_wstrServiceName);
  1119. hr = pQualSet->Put( L"registrykey", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1120. }
  1121. // Locale
  1122. // ======
  1123. if ( SUCCEEDED( hr ) )
  1124. {
  1125. var.Clear();
  1126. V_VT(&var) = VT_I4;
  1127. V_I4(&var) = 0x0409;
  1128. hr = pQualSet->Put( L"locale", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1129. }
  1130. // Perfindex
  1131. // =========
  1132. if ( SUCCEEDED( hr ) )
  1133. {
  1134. V_VT(&var) = VT_I4;
  1135. V_I4(&var) = m_pPerfObj->ObjectNameTitleIndex;
  1136. hr = pQualSet->Put( L"perfindex", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1137. }
  1138. // Helpindex
  1139. // =========
  1140. if ( SUCCEEDED( hr ) )
  1141. {
  1142. V_VT(&var) = VT_I4;
  1143. V_I4(&var) = m_pPerfObj->ObjectHelpTitleIndex;
  1144. hr = pQualSet->Put( L"helpindex", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1145. }
  1146. #ifdef _PM_CHANGED_THEIR_MIND_
  1147. // Description
  1148. // ==========
  1149. if ( SUCCEEDED( hr ) )
  1150. {
  1151. HRESULT hr2;
  1152. LPCWSTR pwcsHelpName = NULL;
  1153. hr2 = m_pDefaultNameDb->GetHelpName( m_pPerfObj->ObjectHelpTitleIndex, &pwcsHelpName );
  1154. var = (WCHAR *)pwcsHelpName;
  1155. if (SUCCEEDED(hr2))
  1156. {
  1157. hr = pQualSet->Put( L"Description", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1158. }
  1159. else
  1160. {
  1161. ERRORTRACE((LOG_WMIADAP,"class %S: Help for counter %d not found\n",(WCHAR *)m_wstrClassName,m_pPerfObj->ObjectHelpTitleIndex));
  1162. }
  1163. var.Clear();
  1164. }
  1165. #endif
  1166. // Perfdetail
  1167. // ==========
  1168. if ( SUCCEEDED( hr ) )
  1169. {
  1170. V_VT(&var) = VT_I4;
  1171. V_I4(&var) = m_pPerfObj->DetailLevel;
  1172. hr = pQualSet->Put( L"perfdetail", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1173. }
  1174. // Genericperfctr
  1175. // ==============
  1176. if ( SUCCEEDED(hr) )
  1177. {
  1178. var = bool(true);
  1179. hr = pQualSet->Put( L"genericperfctr", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1180. }
  1181. // HiPerf
  1182. // ==============
  1183. if ( SUCCEEDED(hr) )
  1184. {
  1185. var = bool(true);
  1186. hr = pQualSet->Put( L"hiperf", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1187. }
  1188. // Singleton (set if the numinstances is PERF_NO_INSTANCES)
  1189. // ========================================================
  1190. if ( SUCCEEDED(hr) && IsSingleton( ) )
  1191. {
  1192. var = bool(true);
  1193. // This will have default flavors
  1194. hr = pQualSet->Put( L"singleton", &var, 0L );
  1195. }
  1196. // Costly
  1197. // ======
  1198. if ( SUCCEEDED(hr) && m_bCostly )
  1199. {
  1200. var = bool(true);
  1201. hr = pQualSet->Put( L"costly", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1202. }
  1203. }break;
  1204. case WMI_ADAP_COOKED_CLASS:
  1205. {
  1206. var.Clear();
  1207. // Dynamic
  1208. // =======
  1209. if ( SUCCEEDED( hr ) )
  1210. {
  1211. var = bool(true);
  1212. hr = pQualSet->Put( L"dynamic", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1213. }
  1214. // Provider
  1215. // ========
  1216. if ( SUCCEEDED( hr ) )
  1217. {
  1218. var = L"HiPerfCooker_v1";
  1219. hr = pQualSet->Put( L"provider", &var, 0L );
  1220. }
  1221. // Locale
  1222. // ======
  1223. if ( SUCCEEDED( hr ) )
  1224. {
  1225. var.Clear();
  1226. V_VT(&var) = VT_I4;
  1227. V_I4(&var) = 0x0409;
  1228. hr = pQualSet->Put( L"locale", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1229. }
  1230. // Registrykey
  1231. // ===========
  1232. if ( SUCCEEDED( hr ) )
  1233. {
  1234. var.Clear();
  1235. var = (WCHAR *)( m_wstrServiceName );
  1236. hr = pQualSet->Put( L"registrykey", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1237. }
  1238. // Cooked
  1239. // ======
  1240. if ( SUCCEEDED( hr ) )
  1241. {
  1242. var.Clear();
  1243. var = bool(true);
  1244. hr = pQualSet->Put( L"Cooked", &var, 0 );
  1245. }
  1246. // AutoCook
  1247. // ========
  1248. if ( SUCCEEDED( hr ) )
  1249. {
  1250. V_VT(&var) = VT_I4;
  1251. V_I4(&var) = 1 ;
  1252. hr = pQualSet->Put( L"AutoCook", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1253. }
  1254. // Genericperfctr
  1255. // ==============
  1256. if ( SUCCEEDED(hr) )
  1257. {
  1258. var = bool(true);
  1259. hr = pQualSet->Put( L"genericperfctr", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1260. }
  1261. // HiPerf
  1262. // ==============
  1263. if ( SUCCEEDED(hr) )
  1264. {
  1265. var = bool(true);
  1266. hr = pQualSet->Put( L"hiperf", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1267. }
  1268. // AutoCook_RawClass
  1269. // =================
  1270. if ( SUCCEEDED( hr ) )
  1271. {
  1272. _variant_t varClassName;
  1273. hr = pClass->Get( L"__CLASS", 0, &varClassName, 0, 0 );
  1274. if ( SUCCEEDED( hr ) )
  1275. {
  1276. WCHAR* wszRawClass = NULL;
  1277. WCHAR* wszClassRoot = varClassName.bstrVal + wcslen ( ADAP_PERF_COOKED_BASE_CLASS );
  1278. size_t cchSizeTmp = wcslen( wszClassRoot ) + wcslen( ADAP_PERF_RAW_BASE_CLASS ) + 1;
  1279. wszRawClass = new WCHAR[ cchSizeTmp ];
  1280. if (NULL == wszRawClass) hr = WBEM_E_OUT_OF_MEMORY;
  1281. if (SUCCEEDED(hr))
  1282. {
  1283. CDeleteMe<WCHAR> dmRawClass( wszRawClass );
  1284. StringCchPrintfW( wszRawClass,cchSizeTmp, L"%s%s", ADAP_PERF_RAW_BASE_CLASS, wszClassRoot );
  1285. var = wszRawClass;
  1286. hr = pQualSet->Put( L"AutoCook_RawClass",
  1287. &var,
  1288. WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1289. //WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS
  1290. }
  1291. }
  1292. }
  1293. // Perfindex
  1294. // =========
  1295. if ( SUCCEEDED( hr ) )
  1296. {
  1297. var.Clear();
  1298. V_VT(&var) = VT_I4;
  1299. V_I4(&var) = m_pPerfObj->ObjectNameTitleIndex;
  1300. hr = pQualSet->Put( L"perfindex", (VARIANT*)&var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1301. }
  1302. // Helpindex
  1303. // =========
  1304. if ( SUCCEEDED( hr ) )
  1305. {
  1306. V_VT(&var) = VT_I4;
  1307. V_I4(&var) = m_pPerfObj->ObjectHelpTitleIndex;
  1308. hr = pQualSet->Put( L"helpindex", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1309. }
  1310. #ifdef _PM_CHANGED_THEIR_MIND_
  1311. // Description
  1312. // ==========
  1313. if ( SUCCEEDED( hr ) )
  1314. {
  1315. HRESULT hr2;
  1316. LPCWSTR pwcsHelpName = NULL;
  1317. hr2 = m_pDefaultNameDb->GetHelpName( m_pPerfObj->ObjectHelpTitleIndex, &pwcsHelpName );
  1318. var = (WCHAR *)pwcsHelpName;
  1319. if (SUCCEEDED(hr2))
  1320. {
  1321. hr = pQualSet->Put( L"Description", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1322. }
  1323. else
  1324. {
  1325. ERRORTRACE((LOG_WMIADAP,"class %S: Help for counter %d not found\n",(WCHAR *)m_wstrClassName,m_pPerfObj->ObjectHelpTitleIndex));
  1326. }
  1327. var.Clear();
  1328. }
  1329. #endif
  1330. // Singleton (set if the numinstances is PERF_NO_INSTANCES)
  1331. // ========================================================
  1332. if ( SUCCEEDED(hr) && IsSingleton( ) )
  1333. {
  1334. var.Clear();
  1335. var = bool(true);
  1336. // This will have default flavors
  1337. hr = pQualSet->Put( L"singleton", (VARIANT*)&var, 0L );
  1338. }
  1339. }break;
  1340. }
  1341. }
  1342. catch(...)
  1343. {
  1344. hr = WBEM_E_OUT_OF_MEMORY;
  1345. }
  1346. if ( FAILED( hr ) )
  1347. {
  1348. // Something whacky happened: log an event
  1349. // =======================================
  1350. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1351. WBEM_MC_ADAP_GENERAL_OBJECT_FAILURE,
  1352. (LPCWSTR)m_wstrClassName,
  1353. (LPCWSTR)m_wstrServiceName,
  1354. CHex( hr ) );
  1355. }
  1356. return hr;
  1357. }
  1358. HRESULT CDefaultClassBroker::AddDefaultProperties( IWbemClassObject* pClass )
  1359. ///////////////////////////////////////////////////////////////////////////////
  1360. //
  1361. // Adds appropriate default properties.
  1362. //
  1363. // The following qualifiers will be added:
  1364. // - Name
  1365. //
  1366. // Parameters:
  1367. // pClass - The object to be massaged
  1368. //
  1369. ///////////////////////////////////////////////////////////////////////////////
  1370. {
  1371. HRESULT hr = WBEM_S_NO_ERROR;
  1372. // If we are not a singleton class, then we will
  1373. // need a name property that is marked as a key
  1374. // =============================================
  1375. if ( !IsSingleton() )
  1376. {
  1377. _variant_t var;
  1378. // Add the Name property
  1379. // =====================
  1380. V_VT(&var) = VT_NULL;
  1381. V_I8(&var) = 0;
  1382. hr = pClass->Put( L"Name", 0L, &var, CIM_STRING );
  1383. // Add the property qualifiers
  1384. // ===========================
  1385. if ( SUCCEEDED( hr ) )
  1386. {
  1387. IWbemQualifierSet* pQualSet = NULL;
  1388. hr = pClass->GetPropertyQualifierSet( L"Name", &pQualSet );
  1389. CReleaseMe rmQualSet( pQualSet );
  1390. // Dynamic
  1391. // =======
  1392. if ( SUCCEEDED( hr ) )
  1393. {
  1394. var.Clear();
  1395. var = bool(true);
  1396. hr = pQualSet->Put( L"key", (VARIANT*)&var, 0L );
  1397. }
  1398. }
  1399. }
  1400. return hr;
  1401. }
  1402. HRESULT CDefaultClassBroker::EnumProperties( DWORD dwType, IWbemClassObject* pClass )
  1403. ///////////////////////////////////////////////////////////////////////////////
  1404. //
  1405. // Walks the counter definitions and generates corresponding properties
  1406. //
  1407. // Parameters:
  1408. // pClass - The object to be massaged
  1409. //
  1410. ///////////////////////////////////////////////////////////////////////////////
  1411. {
  1412. HRESULT hr = WBEM_S_NO_ERROR;
  1413. BOOL bLastCounterIsNotBase = FALSE;
  1414. WString wstrLastCtrName;
  1415. // Set to first counter definition
  1416. // ===============================
  1417. LPBYTE pbData = ((LPBYTE) m_pPerfObj) + m_pPerfObj->HeaderLength;
  1418. // Cast to a counter definition
  1419. // ============================
  1420. PERF_COUNTER_DEFINITION* pCounterDefinition = (PERF_COUNTER_DEFINITION*) pbData;
  1421. // For each counter definition, add a corresponding property
  1422. // =========================================================
  1423. for ( DWORD dwCtr = 0; SUCCEEDED( hr ) && dwCtr < m_pPerfObj->NumCounters; dwCtr++ )
  1424. {
  1425. hr = AddProperty( pCounterDefinition, dwType, ( dwCtr == (DWORD) m_pPerfObj->DefaultCounter),
  1426. pClass, wstrLastCtrName, &bLastCounterIsNotBase );
  1427. // Now go to the next counter definition
  1428. // =====================================
  1429. pbData = ((LPBYTE) pCounterDefinition) + pCounterDefinition->ByteLength;
  1430. pCounterDefinition = (PERF_COUNTER_DEFINITION*) pbData;
  1431. }
  1432. return hr;
  1433. }
  1434. HRESULT CDefaultClassBroker::AddProperty( PERF_COUNTER_DEFINITION* pCtrDefinition,
  1435. DWORD dwType,
  1436. BOOL fIsDefault,
  1437. IWbemClassObject* pClass,
  1438. WString &wstrLastCtrName,
  1439. BOOL* pbLastCounterIsNotBase )
  1440. ///////////////////////////////////////////////////////////////////////////////
  1441. //
  1442. // Adds a property defined by the counter definition
  1443. //
  1444. // Properties:
  1445. // pCtrDefinition - The counter BLOB
  1446. // dwType - Raw or Formatted object?
  1447. // fIsDefault - The default property flag
  1448. // pClass - The class containing the property
  1449. // wstrLastCtrName - The name of the last counter (required for base
  1450. // properties)
  1451. // pbLastCounterIsNotBase
  1452. // - An indicator for the previous counter's baseness
  1453. //
  1454. ///////////////////////////////////////////////////////////////////////////////
  1455. {
  1456. if (NULL == pbLastCounterIsNotBase) return WBEM_E_INVALID_PARAMETER;
  1457. HRESULT hr = WBEM_S_NO_ERROR;
  1458. WString wstrPropertyName;
  1459. DWORD dwCounterTypeMask = PERF_SIZE_VARIABLE_LEN;
  1460. BOOL bBase = FALSE;
  1461. if ( PERF_COUNTER_BASE == ( pCtrDefinition->CounterType & 0x00070000 ) )
  1462. {
  1463. // It's a base property
  1464. // ====================
  1465. if ( *pbLastCounterIsNotBase )
  1466. {
  1467. try
  1468. {
  1469. // The property name is the same as the previous property,
  1470. // but with "_Base" appended to the end
  1471. // =======================================================
  1472. wstrPropertyName = wstrLastCtrName;
  1473. if ( WMI_ADAP_RAW_CLASS == dwType )
  1474. {
  1475. wstrPropertyName += "_Base";
  1476. }
  1477. }
  1478. catch(...)
  1479. {
  1480. hr = WBEM_E_OUT_OF_MEMORY;
  1481. }
  1482. bBase = TRUE;
  1483. }
  1484. else
  1485. {
  1486. // Cannot have 2 consequtive bases
  1487. // ===============================
  1488. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE, WBEM_MC_ADAP_BAD_PERFLIB_INVALID_DATA, (LPCWSTR)m_wstrServiceName, CHex(0) );
  1489. hr = WBEM_E_FAILED;
  1490. }
  1491. }
  1492. else
  1493. {
  1494. // It's not a base property so get the name from the names' database
  1495. // =================================================================
  1496. hr = m_pDefaultNameDb->GetDisplayName( pCtrDefinition->CounterNameTitleIndex, wstrPropertyName );
  1497. if ( FAILED( hr ) )
  1498. {
  1499. // Index does not exist in the Names' DB: log an event
  1500. // ===================================================
  1501. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1502. WBEM_MC_ADAP_MISSING_PROPERTY_INDEX,
  1503. (LPCWSTR)m_wstrClassName,
  1504. (LPCWSTR)m_wstrServiceName,
  1505. pCtrDefinition->CounterNameTitleIndex );
  1506. }
  1507. // Replace reserved characters with text
  1508. // =====================================
  1509. if ( SUCCEEDED( hr ) )
  1510. {
  1511. hr = ReplaceReserved( wstrPropertyName );
  1512. }
  1513. // Remove restricted characters
  1514. // ============================
  1515. if ( SUCCEEDED ( hr ) )
  1516. {
  1517. hr = RemoveWhitespaceAndNonAlphaNum( wstrPropertyName );
  1518. }
  1519. }
  1520. if ( SUCCEEDED( hr ) )
  1521. {
  1522. _variant_t varTest;
  1523. DWORD dwBaseCtr = 1;
  1524. // Ensure that the property does not exist
  1525. // =======================================
  1526. if ( FAILED( pClass->Get( wstrPropertyName, 0L, &varTest, NULL, NULL ) ) )
  1527. {
  1528. // Now check the perf counter type to see if it's a DWORD or LARGE.
  1529. // If it's anything else, we will NOT support this object
  1530. // ================================================================
  1531. DWORD dwCtrType = pCtrDefinition->CounterType & dwCounterTypeMask;
  1532. if ( PERF_SIZE_DWORD == dwCtrType ||
  1533. PERF_SIZE_LARGE == dwCtrType )
  1534. {
  1535. _variant_t var;
  1536. CIMTYPE ct = ( PERF_SIZE_DWORD == dwCtrType ? CIM_UINT32 : CIM_UINT64 );
  1537. // Add the property
  1538. // ================
  1539. V_VT(&var) = VT_NULL;
  1540. V_I8(&var) = 0;
  1541. hr = pClass->Put( wstrPropertyName, 0L, &var, ct );
  1542. // Set the property qualifiers
  1543. // ===========================
  1544. if ( SUCCEEDED( hr ) )
  1545. {
  1546. hr = SetPropertyQualifiers( pCtrDefinition,
  1547. dwType,
  1548. fIsDefault,
  1549. wstrPropertyName,
  1550. pClass,
  1551. bBase );
  1552. }
  1553. }
  1554. else if ( PERF_SIZE_ZERO == dwCtrType )
  1555. {
  1556. // Ignore zero size properties
  1557. // ===========================
  1558. }
  1559. else
  1560. {
  1561. // Illegal property type: log an event
  1562. // ===================================
  1563. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1564. WBEM_MC_ADAP_BAD_PERFLIB_BAD_PROPERTYTYPE,
  1565. (LPCWSTR)m_wstrClassName,
  1566. (LPCWSTR)m_wstrServiceName,
  1567. (LPCWSTR)wstrPropertyName);
  1568. hr = WBEM_E_FAILED;
  1569. }
  1570. }
  1571. else if ( ( WMI_ADAP_COOKED_CLASS == dwType ) && ( bBase ) )
  1572. {
  1573. hr = SetPropertyQualifiers( pCtrDefinition,
  1574. dwType,
  1575. fIsDefault,
  1576. wstrPropertyName,
  1577. pClass,
  1578. bBase );
  1579. }
  1580. else
  1581. {
  1582. // Raw Property already exists: log an event (
  1583. // =========================================
  1584. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1585. WBEM_MC_ADAP_DUPLICATE_PROPERTY,
  1586. (LPCWSTR)m_wstrClassName,
  1587. (LPCWSTR)m_wstrServiceName,
  1588. (LPCWSTR) wstrPropertyName );
  1589. hr = WBEM_E_FAILED;
  1590. }
  1591. }
  1592. if ( SUCCEEDED( hr ) )
  1593. {
  1594. *pbLastCounterIsNotBase = !bBase;
  1595. wstrLastCtrName = wstrPropertyName;
  1596. }
  1597. else
  1598. {
  1599. // Wierdness: log an event
  1600. // =======================
  1601. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1602. WBEM_MC_ADAP_GENERAL_OBJECT_FAILURE,
  1603. (LPCWSTR)m_wstrClassName,
  1604. (LPCWSTR)m_wstrServiceName,
  1605. CHex( hr ) );
  1606. }
  1607. return hr;
  1608. }
  1609. HRESULT CDefaultClassBroker::SetPropertyQualifiers( PERF_COUNTER_DEFINITION* pCtrDefinition,
  1610. DWORD dwType,
  1611. BOOL fIsDefault,
  1612. LPCWSTR pwcsPropertyName,
  1613. IWbemClassObject* pClass,
  1614. BOOL bBase )
  1615. ///////////////////////////////////////////////////////////////////////////////
  1616. //
  1617. // Sets the qualifier values of the properties defined by the counter
  1618. // definition.
  1619. //
  1620. // The following qualifiers will be added:
  1621. // - Perfdefault
  1622. // - Display
  1623. // - Countertype
  1624. // - Perfindex
  1625. // - Helpindex
  1626. // - Defaultscale
  1627. // - Perfdetail
  1628. //
  1629. // Properties:
  1630. // pCtrDefinition - The portion of the performance blob related to the property
  1631. // fIsDefault - Flag identifying default property
  1632. // pwcsPropertyName - The name of the property
  1633. // pClass - The WMI class containing the property
  1634. // bBase - Base property identifier
  1635. //
  1636. ///////////////////////////////////////////////////////////////////////////////
  1637. {
  1638. HRESULT hr = WBEM_S_NO_ERROR;
  1639. _variant_t var;
  1640. try
  1641. {
  1642. IWbemQualifierSet* pQualSet = NULL;
  1643. hr = pClass->GetPropertyQualifierSet( pwcsPropertyName, &pQualSet );
  1644. CReleaseMe rmQualSet( pQualSet );
  1645. switch ( dwType )
  1646. {
  1647. case WMI_ADAP_RAW_CLASS:
  1648. {
  1649. // Perfdefault
  1650. // ===========
  1651. if ( SUCCEEDED( hr ) && fIsDefault )
  1652. {
  1653. var = bool(true);
  1654. hr = pQualSet->Put( L"perfdefault", (VARIANT*)&var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1655. }
  1656. // Display
  1657. // =======
  1658. if ( SUCCEEDED( hr ) )
  1659. {
  1660. LPCWSTR pwcsDisplayName = NULL;
  1661. var.Clear();
  1662. // Fetch the name from the Names' database
  1663. // =======================================
  1664. if ( !bBase )
  1665. {
  1666. hr = m_pDefaultNameDb->GetDisplayName( pCtrDefinition->CounterNameTitleIndex, &pwcsDisplayName );
  1667. if ( SUCCEEDED( hr ) )
  1668. {
  1669. var = pwcsDisplayName;
  1670. }
  1671. else
  1672. {
  1673. ERRORTRACE((LOG_WMIADAP,"class %S: DisplayName for counter %d not found\n",(WCHAR *)m_wstrClassName,pCtrDefinition->CounterNameTitleIndex));
  1674. }
  1675. }
  1676. else
  1677. {
  1678. var = L"";
  1679. }
  1680. // If this is a localized Db, this could be a benign error
  1681. // =======================================================
  1682. if ( SUCCEEDED( hr ) )
  1683. {
  1684. hr = pQualSet->Put( L"DisplayName", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1685. }
  1686. }
  1687. #ifdef _PM_CHANGED_THEIR_MIND_
  1688. // Description
  1689. // ===========
  1690. if ( SUCCEEDED( hr ) )
  1691. {
  1692. LPCWSTR pwcsHelpName = NULL;
  1693. var.Clear();
  1694. if ( !bBase )
  1695. {
  1696. hr = m_pDefaultNameDb->GetHelpName( pCtrDefinition->CounterHelpTitleIndex, &pwcsHelpName );
  1697. if ( SUCCEEDED( hr ) )
  1698. {
  1699. var = pwcsHelpName;
  1700. }
  1701. else
  1702. {
  1703. ERRORTRACE((LOG_WMIADAP,"class %S: Help for counter %d not found\n",(WCHAR *)m_wstrClassName,pCtrDefinition->CounterNameTitleIndex));
  1704. }
  1705. }
  1706. else
  1707. {
  1708. var = L"";
  1709. }
  1710. if ( SUCCEEDED( hr ) )
  1711. {
  1712. hr = pQualSet->Put( L"Description", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1713. }
  1714. }
  1715. #endif
  1716. // Countertype
  1717. // ===========
  1718. if ( SUCCEEDED( hr ) )
  1719. {
  1720. var.Clear();
  1721. V_VT(&var) = VT_I4;
  1722. V_I4(&var) = pCtrDefinition->CounterType ;
  1723. hr = pQualSet->Put( L"countertype", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1724. }
  1725. // Perfindex
  1726. // =========
  1727. if ( SUCCEEDED( hr ) )
  1728. {
  1729. V_VT(&var) = VT_I4;
  1730. V_I4(&var) = pCtrDefinition->CounterNameTitleIndex ;
  1731. hr = pQualSet->Put( L"perfindex", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1732. }
  1733. // Helpindex
  1734. // =========
  1735. if ( SUCCEEDED( hr ) )
  1736. {
  1737. V_VT(&var) = VT_I4;
  1738. V_I4(&var) = pCtrDefinition->CounterHelpTitleIndex ;
  1739. hr = pQualSet->Put( L"helpindex", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1740. }
  1741. // Defaultscale
  1742. // ============
  1743. if ( SUCCEEDED( hr ) )
  1744. {
  1745. V_VT(&var) = VT_I4;
  1746. V_I4(&var) = pCtrDefinition->DefaultScale ;
  1747. hr = pQualSet->Put( L"defaultscale", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1748. }
  1749. // Perfdetail
  1750. // ==========
  1751. if ( SUCCEEDED( hr ) )
  1752. {
  1753. V_VT(&var) = VT_I4;
  1754. V_I4(&var) = pCtrDefinition->DetailLevel ;
  1755. hr = pQualSet->Put( L"perfdetail", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1756. }
  1757. }break;
  1758. case WMI_ADAP_COOKED_CLASS:
  1759. {
  1760. var.Clear();
  1761. #ifdef _PM_CHANGED_THEIR_MIND_
  1762. // Display
  1763. // =======
  1764. if ( SUCCEEDED( hr ) )
  1765. {
  1766. LPCWSTR pwcsDisplayName = NULL;
  1767. var.Clear();
  1768. // Fetch the name from the Names' database
  1769. // =======================================
  1770. if ( !bBase )
  1771. {
  1772. hr = m_pDefaultNameDb->GetDisplayName( pCtrDefinition->CounterNameTitleIndex, &pwcsDisplayName );
  1773. if ( SUCCEEDED( hr ) )
  1774. {
  1775. var = pwcsDisplayName;
  1776. }
  1777. else
  1778. {
  1779. ERRORTRACE((LOG_WMIADAP,"class %S: DisplayName for counter %d not found\n",(WCHAR *)m_wstrClassName,pCtrDefinition->CounterNameTitleIndex));
  1780. }
  1781. }
  1782. else
  1783. {
  1784. var = L"";
  1785. }
  1786. // If this is a localized Db, this could be a benign error
  1787. // =======================================================
  1788. if ( SUCCEEDED( hr ) )
  1789. {
  1790. hr = pQualSet->Put( L"DisplayName", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1791. }
  1792. }
  1793. // Description
  1794. // ===========
  1795. if ( SUCCEEDED( hr ) )
  1796. {
  1797. LPCWSTR pwcsHelpName = NULL;
  1798. var.Clear();
  1799. if ( !bBase )
  1800. {
  1801. hr = m_pDefaultNameDb->GetHelpName( pCtrDefinition->CounterHelpTitleIndex, &pwcsHelpName );
  1802. if ( SUCCEEDED( hr ) )
  1803. {
  1804. var = pwcsHelpName;
  1805. }
  1806. }
  1807. else
  1808. {
  1809. var = L"";
  1810. }
  1811. if ( SUCCEEDED( hr ) )
  1812. {
  1813. hr = pQualSet->Put( L"Description", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1814. }
  1815. }
  1816. #endif
  1817. if ( !bBase )
  1818. {
  1819. // CookingType
  1820. // ===========
  1821. if ( SUCCEEDED( hr ) )
  1822. {
  1823. WCHAR* wszCookingType = NULL;
  1824. hr = GetCounterTypeString( pCtrDefinition->CounterType, &wszCookingType );
  1825. if ( SUCCEEDED( hr ) )
  1826. {
  1827. var = wszCookingType;
  1828. hr = pQualSet->Put( L"CookingType", (VARIANT*)&var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1829. }
  1830. }
  1831. // Counter
  1832. // =======
  1833. if ( SUCCEEDED( hr ) )
  1834. {
  1835. WString wstrPropertyName;
  1836. var.Clear();
  1837. // Fetch the name from the Names' database
  1838. // =======================================
  1839. hr = m_pDefaultNameDb->GetDisplayName( pCtrDefinition->CounterNameTitleIndex, wstrPropertyName );
  1840. // Replace reserved characters with proper names
  1841. // =============================================
  1842. if ( SUCCEEDED( hr ) )
  1843. {
  1844. hr = ReplaceReserved( wstrPropertyName );
  1845. }
  1846. // Remove whitespace and extraneous characters
  1847. // ===========================================
  1848. if ( SUCCEEDED( hr ) )
  1849. {
  1850. hr = RemoveWhitespaceAndNonAlphaNum( wstrPropertyName );
  1851. }
  1852. if ( SUCCEEDED( hr ) )
  1853. {
  1854. var = LPCWSTR(wstrPropertyName );
  1855. // If this is a localized Db, this could be a benign error
  1856. // =======================================================
  1857. hr = pQualSet->Put( L"Counter", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1858. }
  1859. }
  1860. // PerfTimeStamp & PerfTimeFreq
  1861. // ============================
  1862. if ( SUCCEEDED( hr ) )
  1863. {
  1864. _variant_t varStamp;
  1865. _variant_t varFreq;
  1866. if ( pCtrDefinition->CounterType & PERF_TIMER_100NS )
  1867. {
  1868. varStamp = L"TimeStamp_Sys100NS";
  1869. varFreq = L"Frequency_Sys100NS";
  1870. }
  1871. else if ( pCtrDefinition->CounterType & PERF_OBJECT_TIMER )
  1872. {
  1873. varStamp = L"Timestamp_Object" ;
  1874. varFreq = L"Frequency_Object" ;
  1875. }
  1876. else
  1877. {
  1878. varStamp = L"Timestamp_PerfTime";
  1879. varFreq = L"Frequency_PerfTime";
  1880. }
  1881. hr = pQualSet->Put( L"PerfTimeStamp", &varStamp, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1882. if ( SUCCEEDED( hr ) )
  1883. {
  1884. hr = pQualSet->Put( L"PerfTimeFreq", &varFreq, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1885. }
  1886. }
  1887. // Perfindex
  1888. // =========
  1889. if ( SUCCEEDED( hr ) )
  1890. {
  1891. var.Clear();
  1892. V_VT(&var) = VT_I4;
  1893. V_I4(&var) = pCtrDefinition->CounterNameTitleIndex;
  1894. hr = pQualSet->Put( L"perfindex", (VARIANT*)&var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1895. }
  1896. // Helpindex
  1897. // =========
  1898. if ( SUCCEEDED( hr ) )
  1899. {
  1900. V_VT(&var) = VT_I4;
  1901. V_I4(&var) = pCtrDefinition->CounterHelpTitleIndex ;
  1902. hr = pQualSet->Put( L"helpindex", &var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1903. }
  1904. }
  1905. else
  1906. {
  1907. // Base
  1908. // ====
  1909. if ( SUCCEEDED( hr ) )
  1910. {
  1911. WCHAR* wszCounterBase = NULL;
  1912. _variant_t varCounter;
  1913. hr = pQualSet->Get( L"Counter", 0L, &varCounter, NULL );
  1914. size_t cchSizeTmp = wcslen( varCounter.bstrVal ) + 5 + 1;
  1915. wszCounterBase = new WCHAR[ cchSizeTmp ];
  1916. CDeleteMe<WCHAR> dmCounterBase( wszCounterBase );
  1917. if ( NULL == wszCounterBase )
  1918. {
  1919. hr = WBEM_E_OUT_OF_MEMORY;
  1920. }
  1921. else
  1922. {
  1923. StringCchPrintfW( wszCounterBase, cchSizeTmp , L"%s_Base", varCounter.bstrVal );
  1924. var = wszCounterBase;
  1925. hr = pQualSet->Put( L"Base", (VARIANT*)&var, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE );
  1926. }
  1927. }
  1928. }
  1929. }break;
  1930. }
  1931. }
  1932. catch(...)
  1933. {
  1934. hr = WBEM_E_OUT_OF_MEMORY;
  1935. }
  1936. if ( FAILED( hr ) )
  1937. {
  1938. // Weirdness: log an event
  1939. // =======================
  1940. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1941. WBEM_MC_ADAP_GENERAL_OBJECT_FAILURE,
  1942. (LPCWSTR)m_wstrClassName,
  1943. (LPCWSTR)m_wstrServiceName,
  1944. CHex( hr ) );
  1945. }
  1946. return hr;
  1947. }
  1948. HRESULT CDefaultClassBroker::GenPerfClass( PERF_OBJECT_TYPE* pPerfObj,
  1949. DWORD dwType,
  1950. BOOL bCostly,
  1951. IWbemClassObject* pBaseClass,
  1952. CPerfNameDb* pDefaultNameDb,
  1953. WCHAR* pwcsServiceName,
  1954. IWbemClassObject** ppObj)
  1955. ///////////////////////////////////////////////////////////////////////////////
  1956. //
  1957. // A static member of the broker. It generates a WMI class based on the
  1958. // object BLOB.
  1959. //
  1960. // Parameters:
  1961. // pPerfObj - The object BLOB
  1962. // bCostly - Costly object indicator
  1963. // pBaseClass - The new object's base class
  1964. // pDefaultNameDb - The default language names' database
  1965. // pwcsServiceName - The name of the perflib service
  1966. // ppObj - A pointer to the new class object interface pointer
  1967. //
  1968. ///////////////////////////////////////////////////////////////////////////////
  1969. {
  1970. if (NULL == ppObj) return WBEM_E_INVALID_PARAMETER;
  1971. HRESULT hr = WBEM_S_NO_ERROR;
  1972. IWbemClassObject* pObject = NULL;
  1973. CDefaultClassBroker Broker( pPerfObj, bCostly, pBaseClass, pDefaultNameDb, pwcsServiceName );
  1974. hr = Broker.Generate( dwType, &pObject );
  1975. if ( SUCCEEDED( hr ) )
  1976. *ppObj = pObject;
  1977. return hr;
  1978. }