Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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