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.

2382 lines
57 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. ADAPCLS.CPP
  5. Abstract:
  6. History:
  7. --*/
  8. #include "precomp.h"
  9. #include <wbemcli.h>
  10. #include <throttle.h>
  11. #include <cominit.h>
  12. #include <winmgmtr.h>
  13. #include "perfndb.h"
  14. #include "adaputil.h"
  15. #include "adapreg.h"
  16. #include "ntreg.h"
  17. #include "WMIBroker.h"
  18. #include "ClassBroker.h"
  19. #include "adapcls.h"
  20. #include <comdef.h>
  21. extern HANDLE g_hAbort;
  22. struct _BaseClassTypes
  23. {
  24. WCHAR m_wszBaseClassName[128];
  25. }
  26. g_aBaseClass[WMI_ADAP_NUM_TYPES] =
  27. {
  28. ADAP_PERF_RAW_BASE_CLASS,
  29. ADAP_PERF_COOKED_BASE_CLASS
  30. };
  31. CLocaleDefn::CLocaleDefn( WCHAR* pwcsLangId,
  32. HKEY hKey )
  33. : m_wstrLangId( pwcsLangId ),
  34. m_LangId( 0 ),
  35. m_LocaleId( 0 ),
  36. m_pNamespace( NULL ),
  37. m_pNameDb( NULL ),
  38. m_bOK( FALSE ),
  39. m_hRes(WBEM_E_FAILED)
  40. {
  41. HRESULT hr = WBEM_S_NO_ERROR;
  42. // Initialize the base class array
  43. // ===============================
  44. memset( m_apBaseClass, NULL, WMI_ADAP_NUM_TYPES * sizeof( IWbemClassObject* ) );
  45. // A NULL means it is the default locale
  46. // =====================================
  47. if ( NULL != pwcsLangId )
  48. {
  49. hr = InitializeLID();
  50. }
  51. // Initialize the namespace and base class and verify their schema
  52. // ===============================================================
  53. if ( SUCCEEDED( hr ) )
  54. {
  55. hr = InitializeWMI();
  56. }
  57. // Create the names' database for the locale
  58. // =========================================
  59. if ( SUCCEEDED( hr ) )
  60. {
  61. m_pNameDb = new CPerfNameDb( hKey );
  62. if ( ( NULL == m_pNameDb ) || ( !m_pNameDb->IsOk() ) )
  63. {
  64. if ( NULL != m_pNameDb )
  65. {
  66. m_pNameDb->Release();
  67. m_pNameDb = NULL;
  68. }
  69. ERRORTRACE((LOG_WMIADAP,"failure in loading HKEY %p for locale %S err: %d\n",hKey,(LPCWSTR)pwcsLangId,GetLastError()));
  70. hr = WBEM_E_FAILED;
  71. }
  72. }
  73. // If every thing work out, then set the initialization flag
  74. // =========================================================
  75. if ( SUCCEEDED( hr ) )
  76. {
  77. m_bOK = TRUE;
  78. }
  79. else
  80. {
  81. m_hRes = hr;
  82. }
  83. }
  84. CLocaleDefn::~CLocaleDefn()
  85. {
  86. if ( NULL != m_pNamespace )
  87. m_pNamespace->Release();
  88. for ( DWORD dw = 0; dw < WMI_ADAP_NUM_TYPES; dw++ )
  89. {
  90. if ( NULL != m_apBaseClass[dw] )
  91. m_apBaseClass[dw]->Release();
  92. }
  93. if ( NULL != m_pNameDb )
  94. m_pNameDb->Release();
  95. }
  96. HRESULT CLocaleDefn::InitializeLID()
  97. {
  98. HRESULT hr = WBEM_S_NO_ERROR;
  99. LPCWSTR pwstrLangId = (LPWSTR) m_wstrLangId;
  100. // Get the length of the text LID
  101. // ==============================
  102. DWORD dwLangIdLen = m_wstrLangId.Length();
  103. // Ensure that all characters are numeric
  104. // ======================================
  105. for ( DWORD dwCtr = 0; dwCtr < dwLangIdLen && iswxdigit( pwstrLangId[dwCtr] ); dwCtr++ );
  106. if ( dwCtr >= dwLangIdLen )
  107. {
  108. // Now look for the first non-zero character
  109. // =========================================
  110. LPCWSTR pwcsNumStart = pwstrLangId;
  111. for ( dwCtr = 0; dwCtr < dwLangIdLen && *pwcsNumStart == L'0'; dwCtr++, pwcsNumStart++ );
  112. // As long as the LID was not all zeros and the LID is
  113. // 3 digits or less convert the LID to a number
  114. // ===================================================
  115. if ( dwCtr < dwLangIdLen && wcslen( pwcsNumStart ) <= 3 )
  116. {
  117. // Convert the LID to a hex value
  118. // ==============================
  119. WORD wPrimaryLangId = (WORD) wcstoul( pwcsNumStart, NULL, 16 );
  120. // If we are reading the default system id, ensure that we have
  121. // the proper sublanguage and then convert to the member types
  122. // ============================================================
  123. LANGID wSysLID = GetSystemDefaultUILanguage();
  124. if ( ( wSysLID & 0x03FF ) == wPrimaryLangId )
  125. {
  126. m_LangId = wSysLID;
  127. }
  128. else
  129. {
  130. m_LangId = MAKELANGID( wPrimaryLangId, SUBLANG_DEFAULT );
  131. }
  132. m_LocaleId = MAKELCID( m_LangId, SORT_DEFAULT );
  133. WCHAR wcsTemp[32];
  134. swprintf( wcsTemp, L"0x%.4X", m_LangId );
  135. m_wstrLocaleId = wcsTemp;
  136. swprintf( wcsTemp, L"MS_%hX", m_LangId );
  137. m_wstrSubNameSpace = wcsTemp;
  138. }
  139. else
  140. {
  141. hr = WBEM_E_FAILED;
  142. }
  143. }
  144. else
  145. {
  146. hr = WBEM_E_FAILED;
  147. }
  148. return hr;
  149. }
  150. HRESULT CLocaleDefn::InitializeWMI()
  151. {
  152. HRESULT hr = WBEM_S_NO_ERROR;
  153. // Initialize the namespace name
  154. // =============================
  155. WString wstrNamespace;
  156. try
  157. {
  158. wstrNamespace = ADAP_ROOT_NAMESPACE;
  159. if ( 0 != m_LangId )
  160. {
  161. wstrNamespace += L"\\";
  162. wstrNamespace += m_wstrSubNameSpace;
  163. }
  164. }
  165. catch(CX_MemoryException)
  166. {
  167. hr = WBEM_E_OUT_OF_MEMORY;
  168. }
  169. // Initialize the localization namespace
  170. // =====================================
  171. if ( SUCCEEDED( hr ) )
  172. {
  173. hr = CWMIBroker::GetNamespace( wstrNamespace, &m_pNamespace );
  174. }
  175. // Initialize the base classes
  176. // ===========================
  177. for ( DWORD dwBase = 0; ( dwBase < WMI_ADAP_NUM_TYPES ) && SUCCEEDED( hr ); dwBase++ )
  178. {
  179. BSTR bstrBaseClass = SysAllocString( g_aBaseClass[dwBase].m_wszBaseClassName );
  180. CSysFreeMe sfmBaseClass( bstrBaseClass );
  181. hr = m_pNamespace->GetObject( bstrBaseClass, 0L, NULL, (IWbemClassObject**)&m_apBaseClass[dwBase], NULL );
  182. }
  183. return hr;
  184. }
  185. HRESULT CLocaleDefn::GetLID( int* pnLID )
  186. {
  187. *pnLID = m_LangId;
  188. return WBEM_S_NO_ERROR;
  189. }
  190. HRESULT CLocaleDefn::GetNamespaceName( WString & wstrNamespaceName )
  191. {
  192. HRESULT hr = WBEM_S_NO_ERROR;
  193. try
  194. {
  195. wstrNamespaceName = ADAP_ROOT_NAMESPACE;
  196. if ( 0 != m_LangId )
  197. {
  198. wstrNamespaceName += L"\\";
  199. wstrNamespaceName += m_wstrSubNameSpace;
  200. }
  201. }
  202. catch(CX_MemoryException)
  203. {
  204. hr = WBEM_E_OUT_OF_MEMORY;
  205. }
  206. return hr;
  207. }
  208. HRESULT CLocaleDefn::GetNamespace( IWbemServices** ppNamespace )
  209. {
  210. HRESULT hr = WBEM_S_NO_ERROR;
  211. *ppNamespace = m_pNamespace;
  212. if ( NULL != *ppNamespace )
  213. {
  214. (*ppNamespace)->AddRef();
  215. }
  216. else
  217. {
  218. hr = WBEM_E_FAILED;
  219. }
  220. return hr;
  221. }
  222. HRESULT CLocaleDefn::GetNameDb( CPerfNameDb** ppNameDb )
  223. {
  224. HRESULT hr = WBEM_S_NO_ERROR;
  225. *ppNameDb = m_pNameDb;
  226. if ( NULL != *ppNameDb )
  227. {
  228. (*ppNameDb)->AddRef();
  229. }
  230. else
  231. {
  232. hr = WBEM_E_FAILED;
  233. }
  234. return hr;
  235. }
  236. HRESULT CLocaleDefn::GetBaseClass( DWORD dwType, IWbemClassObject** ppObject )
  237. {
  238. HRESULT hr = WBEM_S_NO_ERROR;
  239. if ( dwType < WMI_ADAP_NUM_TYPES )
  240. {
  241. if ( NULL != m_apBaseClass[ dwType ] )
  242. {
  243. *ppObject = m_apBaseClass[ dwType ];
  244. (*ppObject)->AddRef();
  245. }
  246. else
  247. {
  248. hr = WBEM_E_FAILED;
  249. }
  250. }
  251. return hr;
  252. }
  253. ////////////////////////////////////////////////////////////////////////////////
  254. //
  255. // CLocaleCache
  256. //
  257. ////////////////////////////////////////////////////////////////////////////////
  258. CLocaleCache::CLocaleCache( )
  259. : m_nEnumIndex( -1 )
  260. {
  261. }
  262. CLocaleCache::~CLocaleCache()
  263. {
  264. }
  265. HRESULT CLocaleCache::Reset()
  266. {
  267. HRESULT hr = WBEM_NO_ERROR;
  268. m_apLocaleDefn.RemoveAll();
  269. Initialize();
  270. return hr;
  271. }
  272. HRESULT CLocaleCache::Initialize()
  273. {
  274. HRESULT hr = WBEM_S_NO_ERROR;
  275. CNTRegistry reg;
  276. CLocaleDefn* pDefn = NULL;
  277. DWORD dwIndex = 0;
  278. long lError = 0;
  279. // Setup the default defn
  280. // ======================
  281. pDefn = new CLocaleDefn( NULL, HKEY_PERFORMANCE_TEXT );
  282. CAdapReleaseMe arm( pDefn );
  283. if ( ( NULL != pDefn ) && ( pDefn->IsOK() ) )
  284. {
  285. m_apLocaleDefn.Add( pDefn );
  286. LANGID wSysLID = GetSystemDefaultUILanguage();
  287. WCHAR pLang[8];
  288. wsprintfW(pLang,L"%03x",0x3FF & wSysLID);
  289. pDefn = new CLocaleDefn( pLang, HKEY_PERFORMANCE_NLSTEXT );
  290. CAdapReleaseMe armDefn( pDefn );
  291. if ( ( NULL != pDefn ) && ( pDefn->IsOK() ) )
  292. {
  293. m_apLocaleDefn.Add( pDefn );
  294. }
  295. else // this is likely to be the NLSTEXT bug
  296. {
  297. CLocaleDefn* pDefn2 = new CLocaleDefn( pLang, HKEY_PERFORMANCE_TEXT );
  298. CAdapReleaseMe armDefn2( pDefn2 );
  299. if ( ( NULL != pDefn2 ) && ( pDefn2->IsOK() ) )
  300. {
  301. m_apLocaleDefn.Add( pDefn2 );
  302. }
  303. }
  304. }
  305. else
  306. {
  307. ERRORTRACE((LOG_WMIADAP,"CLocaleDefn failed hr = %08x\n",pDefn->GetHRESULT()));
  308. hr = WBEM_E_FAILED;
  309. }
  310. return hr;
  311. }
  312. HRESULT CLocaleCache::GetDefaultDefn( CLocaleDefn** ppDefn )
  313. {
  314. HRESULT hr = WBEM_E_FAILED;
  315. // Get the definition at location 0
  316. // ================================
  317. int nLID = -1;
  318. if ( 0 < m_apLocaleDefn.GetSize() )
  319. {
  320. CLocaleDefn* pDefn = m_apLocaleDefn[0];
  321. // And verify that it has a locale of 0
  322. // ====================================
  323. if ( NULL != pDefn )
  324. {
  325. hr = pDefn->GetLID( &nLID );
  326. }
  327. if ( SUCCEEDED( hr ) && ( 0 == nLID ) )
  328. {
  329. *ppDefn = pDefn;
  330. (*ppDefn)->AddRef();
  331. }
  332. }
  333. return hr;
  334. }
  335. HRESULT CLocaleCache::BeginEnum( )
  336. {
  337. HRESULT hr = WBEM_S_NO_ERROR;
  338. // 1 is the first localized defnintion
  339. // ===================================
  340. m_nEnumIndex = 1;
  341. return hr;
  342. }
  343. HRESULT CLocaleCache::Next( CLocaleDefn** ppDefn )
  344. {
  345. HRESULT hr = WBEM_S_NO_ERROR;
  346. CLocaleDefn* pDefn = NULL;
  347. int nSize = m_apLocaleDefn.GetSize();
  348. if ( ( -1 < m_nEnumIndex ) && ( nSize > m_nEnumIndex ) )
  349. {
  350. pDefn = m_apLocaleDefn[m_nEnumIndex++];
  351. }
  352. else
  353. {
  354. m_nEnumIndex = -1;
  355. hr = WBEM_E_FAILED;
  356. }
  357. if ( SUCCEEDED( hr ) )
  358. {
  359. *ppDefn = pDefn;
  360. if ( NULL != *ppDefn )
  361. (*ppDefn)->AddRef();
  362. else
  363. hr = WBEM_E_FAILED;
  364. }
  365. return hr;
  366. }
  367. HRESULT CLocaleCache::EndEnum()
  368. {
  369. HRESULT hr = WBEM_S_NO_ERROR;
  370. m_nEnumIndex = -1;
  371. return hr;
  372. }
  373. //
  374. //
  375. // Known Service
  376. //
  377. ///////////////////////////////////////////////////////////
  378. //
  379. //
  380. //
  381. bool
  382. WCmp::operator()(WString pFirst,WString pSec) const
  383. {
  384. int res = _wcsicmp(pFirst,pSec);
  385. return (res<0);
  386. }
  387. CKnownSvcs::CKnownSvcs():
  388. m_cRef(1)
  389. {
  390. }
  391. CKnownSvcs::~CKnownSvcs()
  392. {
  393. }
  394. DWORD
  395. CKnownSvcs::Add(WCHAR * pService)
  396. {
  397. if (pService)
  398. {
  399. MapSvc::iterator it = m_SetServices.find(pService);
  400. if (it == m_SetServices.end())
  401. {
  402. try
  403. {
  404. m_SetServices.insert(MapSvc::value_type(pService,ServiceRec(true)));
  405. }
  406. catch (CX_MemoryException)
  407. {
  408. return ERROR_OUTOFMEMORY;
  409. }
  410. }
  411. return 0;
  412. }
  413. else
  414. return ERROR_INVALID_PARAMETER;
  415. }
  416. DWORD
  417. CKnownSvcs::Get(WCHAR * pService, ServiceRec ** ppServiceRec)
  418. {
  419. if (pService && ppServiceRec)
  420. {
  421. MapSvc::iterator it = m_SetServices.find(pService);
  422. if (it == m_SetServices.end())
  423. {
  424. *ppServiceRec = NULL;
  425. return ERROR_OBJECT_NOT_FOUND;
  426. }
  427. else
  428. {
  429. *ppServiceRec = &(it->second);
  430. return 0;
  431. }
  432. }
  433. else
  434. return ERROR_INVALID_PARAMETER;
  435. }
  436. DWORD
  437. CKnownSvcs::Remove(WCHAR * pService)
  438. {
  439. if (pService)
  440. {
  441. MapSvc::iterator it = m_SetServices.find(pService);
  442. if (it != m_SetServices.end())
  443. {
  444. try {
  445. m_SetServices.erase(it);
  446. } catch (CX_MemoryException) {
  447. return ERROR_OUTOFMEMORY;
  448. }
  449. }
  450. return 0;
  451. }
  452. else
  453. return ERROR_INVALID_PARAMETER;
  454. }
  455. DWORD
  456. CKnownSvcs::Load()
  457. {
  458. // get the MULTI_SZ key
  459. LONG lRet;
  460. HKEY hKey;
  461. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  462. WBEM_REG_WINMGMT,
  463. NULL,
  464. KEY_READ,
  465. &hKey);
  466. if (ERROR_SUCCESS == lRet)
  467. {
  468. DWORD dwSize = 0;
  469. DWORD dwType = REG_MULTI_SZ;
  470. lRet = RegQueryValueEx(hKey,
  471. KNOWN_SERVICES,
  472. NULL,
  473. &dwType,
  474. NULL,
  475. &dwSize);
  476. if (ERROR_SUCCESS == lRet && (dwSize > 0))
  477. {
  478. TCHAR * pStr = new TCHAR[dwSize];
  479. if (pStr)
  480. {
  481. CVectorDeleteMe<TCHAR> vdm(pStr);
  482. lRet = RegQueryValueEx(hKey,
  483. KNOWN_SERVICES,
  484. NULL,
  485. &dwType,
  486. (BYTE *)pStr,
  487. &dwSize);
  488. if (ERROR_SUCCESS == lRet)
  489. {
  490. DWORD dwLen = 0;
  491. while(dwLen = lstrlen(pStr))
  492. {
  493. try
  494. {
  495. m_SetServices.insert(MapSvc::value_type(pStr,ServiceRec(true)));
  496. pStr += (dwLen+1);
  497. }
  498. catch (CX_MemoryException)
  499. {
  500. lRet = ERROR_OUTOFMEMORY;
  501. break;
  502. }
  503. }
  504. }
  505. }
  506. else
  507. {
  508. lRet = ERROR_OUTOFMEMORY;
  509. }
  510. }
  511. RegCloseKey(hKey);
  512. }
  513. return lRet;
  514. }
  515. DWORD
  516. CKnownSvcs::Save()
  517. {
  518. // Write the MULTI_SZ key
  519. MapSvc::iterator it;
  520. DWORD dwAllocSize = 1; // the trailing \0
  521. for (it = m_SetServices.begin();it != m_SetServices.end();++it)
  522. {
  523. dwAllocSize += (1+lstrlenW( (*it).first ));
  524. }
  525. WCHAR * pMultiSz = new WCHAR[dwAllocSize];
  526. if (!pMultiSz)
  527. return ERROR_NOT_ENOUGH_MEMORY;
  528. WCHAR * pTmp = pMultiSz;
  529. for (it = m_SetServices.begin();it != m_SetServices.end();++it)
  530. {
  531. const WCHAR * pSrc = (const wchar_t *)it->first;
  532. DWORD i;
  533. for (i=0;pSrc[i];i++){
  534. *pTmp = pSrc[i];
  535. pTmp++;
  536. };
  537. *pTmp = L'\0';
  538. pTmp++;
  539. };
  540. // last char
  541. *pTmp = L'\0';
  542. DWORD dwSize;
  543. LONG lRet;
  544. HKEY hKey;
  545. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  546. WBEM_REG_WINMGMT,
  547. NULL,
  548. KEY_WRITE,
  549. &hKey);
  550. if (ERROR_SUCCESS == lRet)
  551. {
  552. lRet = RegSetValueEx(hKey,
  553. KNOWN_SERVICES,
  554. NULL,
  555. REG_MULTI_SZ,
  556. (BYTE*)pMultiSz,
  557. dwAllocSize * sizeof(WCHAR));
  558. RegCloseKey(hKey);
  559. }
  560. if (pMultiSz)
  561. delete [] pMultiSz;
  562. return lRet;
  563. }
  564. ////////////////////////////////////////////////////////////////////////////////
  565. //
  566. // CClassElem
  567. //
  568. ////////////////////////////////////////////////////////////////////////////////
  569. CClassElem::CClassElem( IWbemClassObject* pObj,
  570. CLocaleCache* pLocaleCache,
  571. CKnownSvcs * pKnownSvcs)
  572. : m_pLocaleCache( pLocaleCache ),
  573. m_pDefaultObject( pObj ),
  574. m_dwIndex( 0 ),
  575. m_bCostly( FALSE ),
  576. m_dwStatus( 0 ),
  577. m_bOk( FALSE ),
  578. m_pKnownSvcs(pKnownSvcs),
  579. m_bReportEventCalled(FALSE)
  580. {
  581. HRESULT hr = WBEM_S_NO_ERROR;
  582. if ( NULL != m_pKnownSvcs)
  583. m_pKnownSvcs->AddRef();
  584. if ( NULL != m_pLocaleCache )
  585. {
  586. m_pLocaleCache->AddRef();
  587. }
  588. if ( NULL != m_pDefaultObject )
  589. {
  590. m_pDefaultObject->AddRef();
  591. hr = InitializeMembers();
  592. }
  593. if ( SUCCEEDED( hr ) && ( NULL != m_pLocaleCache ) && ( NULL != m_pDefaultObject ) )
  594. {
  595. m_bOk = TRUE;
  596. }
  597. }
  598. CClassElem::CClassElem( PERF_OBJECT_TYPE* pPerfObj,
  599. DWORD dwType,
  600. BOOL bCostly,
  601. WString wstrServiceName,
  602. CLocaleCache* pLocaleCache,
  603. CKnownSvcs * pKnownSvcs)
  604. : m_pLocaleCache( pLocaleCache ),
  605. m_pDefaultObject( NULL ),
  606. m_dwIndex( 0 ),
  607. m_bCostly( bCostly ),
  608. m_dwStatus( 0 ),
  609. m_bOk( FALSE ),
  610. m_wstrServiceName( wstrServiceName ),
  611. m_pKnownSvcs(pKnownSvcs),
  612. m_bReportEventCalled(FALSE)
  613. {
  614. HRESULT hr = WBEM_S_NO_ERROR;
  615. CLocaleDefn* pDefn = NULL;
  616. IWbemClassObject* pBaseClass = NULL;
  617. CPerfNameDb* pNameDb = NULL;
  618. if ( NULL != m_pKnownSvcs)
  619. m_pKnownSvcs->AddRef();
  620. if ( NULL != m_pLocaleCache )
  621. {
  622. m_pLocaleCache->AddRef();
  623. // Get the default locale record
  624. // =============================
  625. hr = m_pLocaleCache->GetDefaultDefn( &pDefn );
  626. CAdapReleaseMe rmDefn( pDefn );
  627. // Get the names' database
  628. // =======================
  629. if ( SUCCEEDED( hr ) )
  630. {
  631. hr = pDefn->GetNameDb( &pNameDb );
  632. }
  633. CAdapReleaseMe rmNameDb( pNameDb );
  634. // Create the requested class
  635. // ==========================
  636. if ( SUCCEEDED( hr ) )
  637. {
  638. hr = pDefn->GetBaseClass( dwType, &pBaseClass );
  639. }
  640. CReleaseMe rmBaseClass( pBaseClass );
  641. if ( SUCCEEDED( hr ) )
  642. {
  643. hr = CDefaultClassBroker::GenPerfClass( pPerfObj,
  644. dwType,
  645. m_bCostly,
  646. pBaseClass,
  647. pNameDb,
  648. m_wstrServiceName,
  649. &m_pDefaultObject );
  650. }
  651. }
  652. else
  653. {
  654. hr = WBEM_E_FAILED;
  655. }
  656. // Initialize the class members
  657. // ============================
  658. if ( SUCCEEDED( hr ) )
  659. {
  660. hr = InitializeMembers();
  661. }
  662. if ( SUCCEEDED( hr ) )
  663. {
  664. m_bOk = TRUE;
  665. }
  666. }
  667. VOID
  668. CClassElem::SetKnownSvcs(CKnownSvcs * pKnownSvcs)
  669. {
  670. if (m_pKnownSvcs)
  671. return;
  672. m_pKnownSvcs = pKnownSvcs;
  673. if (m_pKnownSvcs)
  674. m_pKnownSvcs->AddRef();
  675. }
  676. CClassElem::~CClassElem()
  677. {
  678. if ( NULL != m_pLocaleCache )
  679. m_pLocaleCache->Release();
  680. if ( NULL != m_pDefaultObject )
  681. m_pDefaultObject->Release();
  682. if (m_pKnownSvcs)
  683. m_pKnownSvcs->Release();
  684. }
  685. HRESULT CClassElem::InitializeMembers()
  686. // If the class name is unavaiable, then the initialization fails. It is not a fatal error if a qualifier is unavailable
  687. {
  688. HRESULT hr = WBEM_NO_ERROR;
  689. VARIANT var;
  690. try
  691. {
  692. // Get the object's name
  693. // =====================
  694. if ( SUCCEEDED( hr ) )
  695. {
  696. hr = m_pDefaultObject->Get(L"__CLASS", 0L, &var, NULL, NULL );
  697. if ( SUCCEEDED( hr ) )
  698. {
  699. m_wstrClassName = var.bstrVal;
  700. VariantClear( &var );
  701. }
  702. }
  703. if ( SUCCEEDED( hr ) )
  704. {
  705. IWbemQualifierSet* pQualSet = NULL;
  706. hr = m_pDefaultObject->GetQualifierSet( &pQualSet );
  707. CReleaseMe rmQualSet( pQualSet );
  708. // Get the service name
  709. // ====================
  710. if ( SUCCEEDED( hr ) )
  711. {
  712. hr = pQualSet->Get( L"registrykey", 0L, &var, NULL );
  713. if ( SUCCEEDED( hr ) )
  714. {
  715. m_wstrServiceName = var.bstrVal;
  716. VariantClear( &var );
  717. }
  718. else
  719. {
  720. m_wstrServiceName.Empty();
  721. hr = WBEM_S_FALSE;
  722. }
  723. }
  724. // Get the perf index
  725. // ==================
  726. if ( SUCCEEDED( hr ) )
  727. {
  728. hr = pQualSet->Get( L"perfindex", 0L, &var, NULL );
  729. if ( SUCCEEDED( hr ) )
  730. {
  731. m_dwIndex = var.lVal;
  732. VariantClear( &var );
  733. }
  734. else
  735. {
  736. m_dwIndex = 0;
  737. hr = WBEM_S_FALSE;
  738. }
  739. }
  740. // Get the costly qualifier
  741. // ========================
  742. if ( SUCCEEDED( hr ) )
  743. {
  744. hr = pQualSet->Get( L"costly", 0L, &var, NULL );
  745. if ( SUCCEEDED( hr ) )
  746. {
  747. m_bCostly = ( var.boolVal == VARIANT_TRUE );
  748. VariantClear( &var );
  749. }
  750. else
  751. {
  752. VariantClear( &var );
  753. m_bCostly = FALSE;
  754. hr = WBEM_NO_ERROR;
  755. }
  756. }
  757. }
  758. }
  759. catch(...)
  760. {
  761. hr = WBEM_E_OUT_OF_MEMORY;
  762. }
  763. return hr;
  764. }
  765. HRESULT CClassElem::UpdateObj( CClassElem* pEl )
  766. // Replaces the WMI object in this element. The commit will do a CompareTo to compare the
  767. // original object (if it exists) and replace it with the updated version
  768. {
  769. HRESULT hr = WBEM_S_NO_ERROR;
  770. IWbemClassObject* pObj = NULL;
  771. hr = pEl->GetObject( &pObj );
  772. if ( SUCCEEDED( hr ) )
  773. {
  774. if ( NULL != pObj )
  775. {
  776. // Release the old object
  777. // ======================
  778. m_pDefaultObject->Release();
  779. // Initialize the new object - already addref'd by GetObject
  780. // =========================================================
  781. m_pDefaultObject = pObj;
  782. }
  783. else
  784. {
  785. hr = WBEM_E_FAILED;
  786. }
  787. }
  788. return hr;
  789. }
  790. HRESULT CClassElem::Remove(BOOL CleanRegistry)
  791. {
  792. HRESULT hr = WBEM_S_NO_ERROR;
  793. IWbemServices* pNamespace = NULL;
  794. BSTR bstrClassName = SysAllocString( m_wstrClassName );
  795. CSysFreeMe sfmClassName( bstrClassName );
  796. // Delete the localized objects
  797. // ============================
  798. CLocaleDefn* pDefn = NULL;
  799. m_pLocaleCache->BeginEnum();
  800. while ( ( SUCCEEDED( hr ) ) && ( WBEM_S_NO_ERROR == m_pLocaleCache->Next( &pDefn ) ) )
  801. {
  802. CAdapReleaseMe rmDefn( pDefn );
  803. // Get the localization namespace
  804. // ==============================
  805. hr = pDefn->GetNamespace( &pNamespace );
  806. CReleaseMe rmNamespace( pNamespace );
  807. // And delete it
  808. // =============
  809. if ( SUCCEEDED( hr ) )
  810. {
  811. IWbemClassObject * pObj = NULL;
  812. hr = pNamespace->GetObject(bstrClassName,WBEM_FLAG_RETURN_WBEM_COMPLETE,NULL,&pObj,NULL);
  813. if(pObj) { // release the object before deleting
  814. pObj->Release();
  815. pObj=NULL;
  816. }
  817. if (SUCCEEDED(hr)){
  818. hr = pNamespace->DeleteClass( bstrClassName, 0, NULL, NULL );
  819. if ( FAILED( hr ) )
  820. {
  821. try
  822. {
  823. // Write on the trace
  824. // ============
  825. WString wstrNamespaceName;
  826. pDefn->GetNamespaceName( wstrNamespaceName );
  827. LPSTR pClass = m_wstrClassName.GetLPSTR();
  828. LPSTR pNames = wstrNamespaceName.GetLPSTR();
  829. CDeleteMe<CHAR> a(pClass);
  830. CDeleteMe<CHAR> b(pNames);
  831. ERRORTRACE( ( LOG_WMIADAP,"DeleteClass %s from %s 0x%08x",pClass,pNames,hr));
  832. }
  833. catch(...)
  834. {
  835. hr = WBEM_E_OUT_OF_MEMORY;
  836. }
  837. }
  838. } else {
  839. // class not found
  840. // nothing to delete
  841. }
  842. }
  843. }
  844. m_pLocaleCache->EndEnum();
  845. // Delete the default object
  846. // =========================
  847. if ( SUCCEEDED( hr ) )
  848. {
  849. hr = m_pLocaleCache->GetDefaultDefn( &pDefn );
  850. CAdapReleaseMe rmDefn( pDefn );
  851. if ( SUCCEEDED( hr ) )
  852. {
  853. hr = pDefn->GetNamespace( &pNamespace );
  854. CReleaseMe rmNamespace( pNamespace );
  855. if ( SUCCEEDED( hr ) )
  856. {
  857. hr = pNamespace->DeleteClass( bstrClassName, 0, NULL, NULL );
  858. if ( FAILED( hr ) )
  859. {
  860. // Log an event
  861. // ============
  862. ServiceRec * pSvcRec = NULL;
  863. if (0 == m_pKnownSvcs->Get(m_wstrServiceName,&pSvcRec))
  864. {
  865. if (!pSvcRec->IsELCalled() && !m_bReportEventCalled)
  866. {
  867. try
  868. {
  869. WString wstrNamespaceName;
  870. pDefn->GetNamespaceName( wstrNamespaceName );
  871. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  872. WBEM_MC_ADAP_PERFLIB_REMOVECLASS_FAILURE,
  873. (LPCWSTR) m_wstrClassName,
  874. (LPCWSTR) wstrNamespaceName,
  875. CHex( hr ) );
  876. pSvcRec->SetELCalled();
  877. m_bReportEventCalled = TRUE;
  878. }
  879. catch(...)
  880. {
  881. hr = WBEM_E_OUT_OF_MEMORY;
  882. }
  883. }
  884. }
  885. else
  886. {
  887. if (!m_bReportEventCalled)
  888. {
  889. try
  890. {
  891. WString wstrNamespaceName;
  892. pDefn->GetNamespaceName( wstrNamespaceName );
  893. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  894. WBEM_MC_ADAP_PERFLIB_REMOVECLASS_FAILURE,
  895. (LPCWSTR) m_wstrClassName,
  896. (LPCWSTR) wstrNamespaceName,
  897. CHex( hr ) );
  898. m_bReportEventCalled = TRUE;
  899. }
  900. catch(...)
  901. {
  902. hr = WBEM_E_OUT_OF_MEMORY;
  903. }
  904. }
  905. }
  906. }
  907. }
  908. }
  909. }
  910. if (SUCCEEDED(hr))
  911. {
  912. if (m_pKnownSvcs)
  913. m_pKnownSvcs->Remove((WCHAR *)m_wstrServiceName);
  914. }
  915. if (CleanRegistry && SUCCEEDED(hr))
  916. {
  917. WString wszRegPath = L"SYSTEM\\CurrentControlSet\\Services\\";
  918. wszRegPath += m_wstrServiceName;
  919. wszRegPath += L"\\Performance";
  920. CNTRegistry reg;
  921. int nRet = 0;
  922. nRet = reg.Open( HKEY_LOCAL_MACHINE, wszRegPath );
  923. switch( nRet )
  924. {
  925. case CNTRegistry::no_error:
  926. {
  927. reg.DeleteValue(ADAP_PERFLIB_STATUS_KEY);
  928. reg.DeleteValue(ADAP_PERFLIB_SIGNATURE);
  929. reg.DeleteValue(ADAP_PERFLIB_SIZE);
  930. reg.DeleteValue(ADAP_PERFLIB_TIME);
  931. }
  932. break;
  933. case CNTRegistry::not_found:
  934. {
  935. hr = WBEM_E_FAILED;
  936. }
  937. break;
  938. case CNTRegistry::access_denied:
  939. {
  940. ServiceRec * pSvcRec = NULL;
  941. if (0 == m_pKnownSvcs->Get(m_wstrServiceName,&pSvcRec))
  942. {
  943. if (!pSvcRec->IsELCalled() && !m_bReportEventCalled)
  944. {
  945. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  946. WBEM_MC_ADAP_PERFLIB_REG_VALUE_FAILURE,
  947. (LPWSTR)wszRegPath, nRet );
  948. pSvcRec->SetELCalled();
  949. m_bReportEventCalled = TRUE;
  950. }
  951. }
  952. else
  953. {
  954. if (!m_bReportEventCalled)
  955. {
  956. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  957. WBEM_MC_ADAP_PERFLIB_REG_VALUE_FAILURE,
  958. (LPWSTR)wszRegPath, nRet );
  959. m_bReportEventCalled = TRUE;
  960. }
  961. }
  962. }
  963. break;
  964. }
  965. }
  966. return hr;
  967. }
  968. HRESULT CClassElem::Insert()
  969. {
  970. HRESULT hr = WBEM_S_NO_ERROR;
  971. CLocaleDefn* pDefaultDefn = NULL;
  972. IWbemServices* pNamespace = NULL;
  973. // perform object validation
  974. _IWmiObject * pInternal = NULL;
  975. hr = m_pDefaultObject->QueryInterface(IID__IWmiObject,(void **)&pInternal);
  976. if (SUCCEEDED(hr))
  977. {
  978. CReleaseMe rmi(pInternal);
  979. hr = pInternal->ValidateObject(WMIOBJECT_VALIDATEOBJECT_FLAG_FORCE);
  980. if (FAILED(hr))
  981. {
  982. DebugBreak();
  983. ERRORTRACE((LOG_WMIADAP,"ValidateObject(%S) %08x\n",(LPWSTR)m_wstrClassName,hr));
  984. return hr;
  985. }
  986. }
  987. // Add the object to the default namespace
  988. // =======================================
  989. hr = m_pLocaleCache->GetDefaultDefn( &pDefaultDefn );
  990. CAdapReleaseMe rmDefaultDefn( pDefaultDefn );
  991. if ( SUCCEEDED( hr ) )
  992. {
  993. hr = pDefaultDefn->GetNamespace( &pNamespace );
  994. CReleaseMe rmNamespace( pNamespace );
  995. if ( SUCCEEDED( hr ) )
  996. {
  997. hr = pNamespace->PutClass( m_pDefaultObject, WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL );
  998. if ( FAILED( hr ) )
  999. {
  1000. ServiceRec * pSvcRec = NULL;
  1001. if (0 == m_pKnownSvcs->Get(m_wstrServiceName,&pSvcRec))
  1002. {
  1003. if (!pSvcRec->IsELCalled() && !m_bReportEventCalled)
  1004. {
  1005. try
  1006. {
  1007. WString wstrNamespace;
  1008. pDefaultDefn->GetNamespaceName( wstrNamespace );
  1009. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1010. WBEM_MC_ADAP_PERFLIB_PUTCLASS_FAILURE,
  1011. (LPCWSTR)m_wstrClassName,
  1012. (LPCWSTR) wstrNamespace,
  1013. CHex( hr ) );
  1014. m_bReportEventCalled = TRUE;
  1015. pSvcRec->SetELCalled();
  1016. }
  1017. catch(...)
  1018. {
  1019. hr = WBEM_E_OUT_OF_MEMORY;
  1020. }
  1021. }
  1022. }
  1023. else
  1024. {
  1025. if (!m_bReportEventCalled)
  1026. {
  1027. try
  1028. {
  1029. WString wstrNamespace;
  1030. pDefaultDefn->GetNamespaceName( wstrNamespace );
  1031. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1032. WBEM_MC_ADAP_PERFLIB_PUTCLASS_FAILURE,
  1033. (LPCWSTR)m_wstrClassName,
  1034. (LPCWSTR) wstrNamespace,
  1035. CHex( hr ) );
  1036. m_bReportEventCalled = TRUE;
  1037. }
  1038. catch(...)
  1039. {
  1040. hr = WBEM_E_OUT_OF_MEMORY;
  1041. }
  1042. }
  1043. }
  1044. }
  1045. //ERRORTRACE( ( LOG_WMIADAP, "PutClass(%S) %08x\n",(LPWSTR)m_wstrClassName,hr) );
  1046. }
  1047. }
  1048. if ( SUCCEEDED( hr ) )
  1049. {
  1050. //
  1051. // Add the servicename to the MultiSz Key
  1052. //
  1053. if (m_pKnownSvcs)
  1054. m_pKnownSvcs->Add((WCHAR *)m_wstrServiceName);
  1055. hr = VerifyLocales();
  1056. }
  1057. if ( SUCCEEDED( hr ) )
  1058. {
  1059. SetStatus( ADAP_OBJECT_IS_REGISTERED );
  1060. }
  1061. return hr;
  1062. }
  1063. HRESULT CClassElem::GetClassName( WString& wstr )
  1064. {
  1065. HRESULT hr = WBEM_S_NO_ERROR;
  1066. try
  1067. {
  1068. wstr = m_wstrClassName;
  1069. }
  1070. catch(CX_MemoryException)
  1071. {
  1072. hr = WBEM_E_OUT_OF_MEMORY;
  1073. }
  1074. return hr;
  1075. }
  1076. HRESULT CClassElem::GetClassName( BSTR* pbStr )
  1077. {
  1078. HRESULT hr = WBEM_S_NO_ERROR;
  1079. try
  1080. {
  1081. *pbStr = SysAllocString( (LPCWSTR) m_wstrClassName );
  1082. }
  1083. catch(...)
  1084. {
  1085. hr = WBEM_E_OUT_OF_MEMORY;
  1086. }
  1087. return hr;
  1088. }
  1089. HRESULT CClassElem::GetObject( IWbemClassObject** ppObj )
  1090. {
  1091. HRESULT hr = WBEM_S_NO_ERROR;
  1092. if ( NULL != m_pDefaultObject )
  1093. {
  1094. *ppObj = m_pDefaultObject;
  1095. (*ppObj)->AddRef();
  1096. }
  1097. else
  1098. {
  1099. hr = WBEM_E_FAILED;
  1100. }
  1101. return hr;
  1102. }
  1103. HRESULT CClassElem::GetServiceName( WString& wstrServiceName )
  1104. {
  1105. HRESULT hr = WBEM_S_NO_ERROR;
  1106. try
  1107. {
  1108. wstrServiceName = m_wstrServiceName;
  1109. }
  1110. catch(CX_MemoryException)
  1111. {
  1112. hr = WBEM_E_OUT_OF_MEMORY;
  1113. }
  1114. return hr;
  1115. }
  1116. BOOL CClassElem::SameName( CClassElem* pEl )
  1117. {
  1118. WString wstrOtherName;
  1119. try
  1120. {
  1121. if ( FAILED ( pEl->GetClassName( wstrOtherName ) ) )
  1122. return FALSE;
  1123. }
  1124. catch(...)
  1125. {
  1126. return FALSE;
  1127. }
  1128. return m_wstrClassName.Equal( wstrOtherName );
  1129. }
  1130. BOOL CClassElem::SameObject( CClassElem* pEl )
  1131. {
  1132. BOOL bRes = FALSE;
  1133. IWbemClassObject* pObj = NULL;
  1134. pEl->GetObject( &pObj );
  1135. CReleaseMe rmObj( pObj );
  1136. bRes = ( m_pDefaultObject->CompareTo( WBEM_FLAG_IGNORE_OBJECT_SOURCE, pObj ) == WBEM_S_SAME );
  1137. return bRes;
  1138. }
  1139. HRESULT CClassElem::Commit()
  1140. {
  1141. HRESULT hr = WBEM_S_NO_ERROR;
  1142. // Ensure that object is in default namespace
  1143. // ==========================================
  1144. if ( CheckStatus( ADAP_OBJECT_IS_DELETED ) )
  1145. {
  1146. hr = Remove( CheckStatus(ADAP_OBJECT_IS_TO_BE_CLEARED) );
  1147. }
  1148. else if ( CheckStatus( ADAP_OBJECT_IS_REGISTERED | ADAP_OBJECT_IS_NOT_IN_PERFLIB ) && !CheckStatus( ADAP_OBJECT_IS_INACTIVE ) )
  1149. {
  1150. if ( IsPerfLibUnloaded() )
  1151. {
  1152. hr = Remove( TRUE );
  1153. }
  1154. else // the object is there
  1155. {
  1156. if (m_pKnownSvcs)
  1157. m_pKnownSvcs->Add((WCHAR *)m_wstrServiceName);
  1158. }
  1159. }
  1160. else if ( !CheckStatus( ADAP_OBJECT_IS_REGISTERED ) )
  1161. {
  1162. hr = Insert();
  1163. }
  1164. else
  1165. {
  1166. if (m_pKnownSvcs)
  1167. m_pKnownSvcs->Add((WCHAR *)m_wstrServiceName);
  1168. VerifyLocales();
  1169. }
  1170. return hr;
  1171. }
  1172. BOOL CClassElem::IsPerfLibUnloaded()
  1173. {
  1174. // Unless we can specifically prove that the perflib has been unloaded, then we assume that it is still loaded
  1175. BOOL bLoaded = TRUE;
  1176. HRESULT hr = WBEM_S_FALSE;
  1177. WCHAR wszRegPath[256];
  1178. DWORD dwFirstCtr = 0,
  1179. dwLastCtr = 0;
  1180. WCHAR* wszObjList = NULL;
  1181. CNTRegistry reg;
  1182. int nRet = 0;
  1183. if ( 0 == m_wstrServiceName.Length() )
  1184. {
  1185. bLoaded = FALSE;
  1186. }
  1187. else if ( m_wstrServiceName.EqualNoCase( L"PERFOS" ) ||
  1188. m_wstrServiceName.EqualNoCase( L"TCPIP" ) ||
  1189. m_wstrServiceName.EqualNoCase( L"PERFPROC" ) ||
  1190. m_wstrServiceName.EqualNoCase( L"PERFDISK" ) ||
  1191. m_wstrServiceName.EqualNoCase( L"PERFNET" ) ||
  1192. m_wstrServiceName.EqualNoCase( L"TAPISRV" ) ||
  1193. m_wstrServiceName.EqualNoCase( L"SPOOLER" ) ||
  1194. m_wstrServiceName.EqualNoCase( L"MSFTPSvc" ) ||
  1195. m_wstrServiceName.EqualNoCase( L"RemoteAccess" ) ||
  1196. m_wstrServiceName.EqualNoCase( L"WINS" ) ||
  1197. m_wstrServiceName.EqualNoCase( L"MacSrv" ) ||
  1198. m_wstrServiceName.EqualNoCase( L"AppleTalk" ) ||
  1199. m_wstrServiceName.EqualNoCase( L"NM" ) ||
  1200. m_wstrServiceName.EqualNoCase( L"RSVP" ))
  1201. {
  1202. // This is the list of the hardcoded perflibs - according
  1203. // to BobW, they are always considered to be loaded
  1204. // ======================================================
  1205. bLoaded = TRUE;
  1206. }
  1207. else
  1208. {
  1209. // Try to open the service's registry key and read the object list or the first/last counter values
  1210. // ================================================================================================
  1211. swprintf( wszRegPath, L"SYSTEM\\CurrentControlSet\\Services\\%s\\Performance", (WCHAR *)m_wstrServiceName );
  1212. nRet = reg.Open( HKEY_LOCAL_MACHINE, wszRegPath );
  1213. switch( nRet )
  1214. {
  1215. case CNTRegistry::not_found:
  1216. {
  1217. bLoaded = FALSE;
  1218. }break;
  1219. case CNTRegistry::no_error:
  1220. {
  1221. bLoaded = ( reg.GetStr( L"Object List", &wszObjList ) == CNTRegistry::no_error ) ||
  1222. ( ( reg.GetDWORD( L"First Counter", &dwFirstCtr ) == CNTRegistry::no_error ) &&
  1223. ( reg.GetDWORD( L"Last Counter", &dwLastCtr ) == CNTRegistry::no_error )
  1224. );
  1225. }break;
  1226. case CNTRegistry::access_denied:
  1227. {
  1228. ServiceRec * pSvcRec = NULL;
  1229. if (0 == m_pKnownSvcs->Get(m_wstrServiceName,&pSvcRec))
  1230. {
  1231. if (!pSvcRec->IsELCalled() && !m_bReportEventCalled)
  1232. {
  1233. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1234. WBEM_MC_ADAP_PERFLIB_REG_VALUE_FAILURE,
  1235. wszRegPath, nRet );
  1236. m_bReportEventCalled = TRUE;
  1237. pSvcRec->SetELCalled();
  1238. }
  1239. }
  1240. else
  1241. {
  1242. if (!m_bReportEventCalled)
  1243. {
  1244. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1245. WBEM_MC_ADAP_PERFLIB_REG_VALUE_FAILURE,
  1246. wszRegPath, nRet );
  1247. m_bReportEventCalled = TRUE;
  1248. }
  1249. }
  1250. }break;
  1251. }
  1252. }
  1253. return !bLoaded;
  1254. }
  1255. HRESULT CClassElem::CompareLocale( CLocaleDefn* pLocaleDefn, IWbemClassObject* pObj )
  1256. {
  1257. HRESULT hr = WBEM_S_NO_ERROR;
  1258. CLocaleDefn* pDefaultDefn = NULL;
  1259. IWbemClassObject* pLocaleObj = NULL;
  1260. m_pLocaleCache->GetDefaultDefn( &pDefaultDefn );
  1261. CAdapReleaseMe armDefaultDefn( pDefaultDefn );
  1262. hr = CLocaleClassBroker::ConvertToLocale( m_pDefaultObject, pLocaleDefn, pDefaultDefn, &pLocaleObj);
  1263. CReleaseMe rmLocaleObj( pLocaleObj );
  1264. if ( SUCCEEDED( hr ) )
  1265. {
  1266. hr = pObj->CompareTo( WBEM_FLAG_IGNORE_OBJECT_SOURCE, pLocaleObj );
  1267. }
  1268. return hr;
  1269. }
  1270. HRESULT CClassElem::InsertLocale( CLocaleDefn* pLocaleDefn )
  1271. {
  1272. HRESULT hr = WBEM_S_NO_ERROR;
  1273. CLocaleDefn* pDefaultDefn = NULL;
  1274. IWbemClassObject* pLocaleObj = NULL;
  1275. IWbemServices* pNamespace = NULL;
  1276. m_pLocaleCache->GetDefaultDefn( &pDefaultDefn );
  1277. CAdapReleaseMe armDefaultDefn( pDefaultDefn );
  1278. hr = CLocaleClassBroker::ConvertToLocale( m_pDefaultObject, pLocaleDefn, pDefaultDefn, &pLocaleObj);
  1279. CReleaseMe rmLocaleObj( pLocaleObj );
  1280. if (SUCCEEDED(hr))
  1281. {
  1282. // perform object validation
  1283. _IWmiObject * pInternal = NULL;
  1284. hr = pLocaleObj->QueryInterface(IID__IWmiObject,(void **)&pInternal);
  1285. if (SUCCEEDED(hr))
  1286. {
  1287. CReleaseMe rmi(pInternal);
  1288. hr = pInternal->ValidateObject(WMIOBJECT_VALIDATEOBJECT_FLAG_FORCE);
  1289. if (FAILED(hr))
  1290. {
  1291. DebugBreak();
  1292. ERRORTRACE((LOG_WMIADAP,"ValidateObject(%S) %08x\n",(LPWSTR)m_wstrClassName,hr));
  1293. return hr;
  1294. }
  1295. }
  1296. }
  1297. // And add it to the localized namespace
  1298. // =====================================
  1299. if ( SUCCEEDED( hr ) )
  1300. {
  1301. hr = pLocaleDefn->GetNamespace( &pNamespace );
  1302. CReleaseMe rmNamespace( pNamespace );
  1303. if ( SUCCEEDED( hr ) )
  1304. {
  1305. hr = pNamespace->PutClass( pLocaleObj, WBEM_FLAG_CREATE_OR_UPDATE, NULL, NULL );
  1306. if ( FAILED( hr ) )
  1307. {
  1308. ServiceRec * pSvcRec = NULL;
  1309. if (0 == m_pKnownSvcs->Get(m_wstrServiceName,&pSvcRec))
  1310. {
  1311. if (!pSvcRec->IsELCalled() && !m_bReportEventCalled)
  1312. {
  1313. try
  1314. {
  1315. WString wstrNamespace;
  1316. pLocaleDefn->GetNamespaceName( wstrNamespace );
  1317. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1318. WBEM_MC_ADAP_PERFLIB_PUTCLASS_FAILURE,
  1319. (LPCWSTR)m_wstrClassName, (LPCWSTR) wstrNamespace, CHex( hr ) );
  1320. m_bReportEventCalled = TRUE;
  1321. pSvcRec->SetELCalled();
  1322. }
  1323. catch(...)
  1324. {
  1325. hr = WBEM_E_OUT_OF_MEMORY;
  1326. }
  1327. }
  1328. }
  1329. else
  1330. {
  1331. if (!m_bReportEventCalled)
  1332. {
  1333. try
  1334. {
  1335. WString wstrNamespace;
  1336. pLocaleDefn->GetNamespaceName( wstrNamespace );
  1337. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1338. WBEM_MC_ADAP_PERFLIB_PUTCLASS_FAILURE,
  1339. (LPCWSTR)m_wstrClassName, (LPCWSTR) wstrNamespace, CHex( hr ) );
  1340. m_bReportEventCalled = TRUE;
  1341. }
  1342. catch(...)
  1343. {
  1344. hr = WBEM_E_OUT_OF_MEMORY;
  1345. }
  1346. }
  1347. }
  1348. }
  1349. }
  1350. }
  1351. else
  1352. {
  1353. // no localized class
  1354. ERRORTRACE( ( LOG_WMIADAP, "InsertLocale PutClass(%S) %08x\n",(LPWSTR)m_wstrClassName,hr) );
  1355. }
  1356. return hr;
  1357. }
  1358. HRESULT CClassElem::VerifyLocales()
  1359. {
  1360. HRESULT hr = WBEM_S_NO_ERROR;
  1361. CLocaleDefn* pLocaleDefn = NULL;
  1362. IWbemClassObject* pLocaleObj = NULL;
  1363. IWbemServices* pNamespace = NULL;
  1364. // Get the localized objects
  1365. // =========================
  1366. hr = m_pLocaleCache->BeginEnum();
  1367. while ( ( SUCCEEDED( hr ) ) && ( WBEM_S_NO_ERROR == m_pLocaleCache->Next( &pLocaleDefn ) ) )
  1368. {
  1369. CAdapReleaseMe rmLocaleDefn( pLocaleDefn );
  1370. // Get the localization namespace
  1371. // ==============================
  1372. hr = pLocaleDefn->GetNamespace( &pNamespace );
  1373. CReleaseMe rmNamespace( pNamespace );
  1374. // Get the localized object
  1375. // ========================
  1376. if ( SUCCEEDED( hr ) )
  1377. {
  1378. BSTR bstrClassName = SysAllocString( m_wstrClassName );
  1379. CSysFreeMe sfmClassName( bstrClassName );
  1380. hr = pNamespace->GetObject( bstrClassName, 0L, NULL, &pLocaleObj, NULL );
  1381. CReleaseMe rmLocaleObj( pLocaleObj );
  1382. if ( SUCCEEDED( hr ) )
  1383. {
  1384. if ( CompareLocale( pLocaleDefn, pLocaleObj ) != WBEM_S_SAME )
  1385. {
  1386. hr = InsertLocale( pLocaleDefn );
  1387. }
  1388. }
  1389. else
  1390. {
  1391. hr = InsertLocale( pLocaleDefn );
  1392. }
  1393. }
  1394. pLocaleObj = NULL;
  1395. }
  1396. m_pLocaleCache->EndEnum();
  1397. return hr;
  1398. }
  1399. HRESULT CClassElem::SetStatus( DWORD dwStatus )
  1400. {
  1401. m_dwStatus |= dwStatus;
  1402. return WBEM_NO_ERROR;
  1403. }
  1404. HRESULT CClassElem::ClearStatus( DWORD dwStatus )
  1405. {
  1406. m_dwStatus &= ~dwStatus;
  1407. return WBEM_NO_ERROR;
  1408. }
  1409. BOOL CClassElem::CheckStatus( DWORD dwStatus )
  1410. {
  1411. return ( ( m_dwStatus & dwStatus ) == dwStatus );
  1412. }
  1413. ////////////////////////////////////////////////////////////////////////////////////////////
  1414. //
  1415. // CClassList
  1416. //
  1417. ////////////////////////////////////////////////////////////////////////////////////////////
  1418. CClassList::CClassList( CLocaleCache* pLocaleCache )
  1419. : m_pLocaleCache( pLocaleCache ),
  1420. m_nEnumIndex( -1 ),
  1421. m_fOK( FALSE )
  1422. {
  1423. if ( NULL != m_pLocaleCache )
  1424. m_pLocaleCache->AddRef();
  1425. }
  1426. CClassList::~CClassList( void )
  1427. {
  1428. if ( NULL != m_pLocaleCache )
  1429. m_pLocaleCache->Release();
  1430. }
  1431. HRESULT CClassList::BeginEnum()
  1432. {
  1433. HRESULT hr = WBEM_S_NO_ERROR;
  1434. m_nEnumIndex = 0;
  1435. return hr;
  1436. }
  1437. HRESULT CClassList::Next( CClassElem** ppEl )
  1438. {
  1439. HRESULT hr = WBEM_S_NO_ERROR;
  1440. int nSize = m_array.GetSize();
  1441. CClassElem* pEl = NULL;
  1442. do
  1443. {
  1444. if ( ( -1 < m_nEnumIndex ) && ( nSize > m_nEnumIndex ) )
  1445. {
  1446. pEl = m_array[m_nEnumIndex++];
  1447. }
  1448. else
  1449. {
  1450. m_nEnumIndex = -1;
  1451. hr = WBEM_E_FAILED;
  1452. }
  1453. }
  1454. while ( ( SUCCEEDED( hr ) ) && ( pEl->CheckStatus( ADAP_OBJECT_IS_DELETED ) ) );
  1455. if ( SUCCEEDED( hr ) )
  1456. {
  1457. *ppEl = pEl;
  1458. if ( NULL != *ppEl )
  1459. {
  1460. (*ppEl)->AddRef();
  1461. }
  1462. else
  1463. {
  1464. hr = WBEM_E_FAILED;
  1465. }
  1466. }
  1467. return hr;
  1468. }
  1469. HRESULT CClassList::EndEnum()
  1470. {
  1471. HRESULT hr = WBEM_S_NO_ERROR;
  1472. m_nEnumIndex = -1;
  1473. return hr;
  1474. }
  1475. HRESULT CClassList::AddElement( CClassElem* pElem )
  1476. {
  1477. HRESULT hr = WBEM_S_NO_ERROR;
  1478. if ( ( NULL != pElem ) && ( pElem->IsOk() ) )
  1479. {
  1480. if ( -1 == m_array.Add( pElem ) )
  1481. {
  1482. // Add failed
  1483. // ==========
  1484. hr = WBEM_E_OUT_OF_MEMORY;
  1485. }
  1486. }
  1487. else
  1488. {
  1489. hr = WBEM_E_FAILED;
  1490. }
  1491. return hr;
  1492. }
  1493. // Removes the object at the index
  1494. HRESULT CClassList::RemoveAt( int nIndex )
  1495. {
  1496. HRESULT hr = WBEM_S_NO_ERROR;
  1497. // Should auto release the object
  1498. m_array.RemoveAt( nIndex );
  1499. return hr;
  1500. }
  1501. ////////////////////////////////////////////////////////////////////////////////
  1502. //
  1503. // CPerfClassList
  1504. //
  1505. ////////////////////////////////////////////////////////////////////////////////
  1506. CPerfClassList::CPerfClassList( CLocaleCache* pLocaleCache, WCHAR* pwcsServiceName )
  1507. : CClassList( pLocaleCache ),
  1508. m_wstrServiceName( pwcsServiceName )
  1509. {
  1510. }
  1511. HRESULT CPerfClassList::AddPerfObject( PERF_OBJECT_TYPE* pObj, DWORD dwType, BOOL bCostly )
  1512. {
  1513. HRESULT hr = WBEM_S_NO_ERROR;
  1514. // Create the WMI object
  1515. // =====================
  1516. CClassElem* pElem = new CClassElem( pObj, dwType, bCostly, m_wstrServiceName, m_pLocaleCache );
  1517. CAdapReleaseMe armElem( pElem );
  1518. if ( ( NULL != pElem ) && ( pElem->IsOk() ) )
  1519. {
  1520. AddElement( pElem );
  1521. }
  1522. else
  1523. {
  1524. hr = WBEM_E_FAILED;
  1525. }
  1526. return hr;
  1527. }
  1528. HRESULT CPerfClassList::AddElement( CClassElem *pEl )
  1529. {
  1530. HRESULT hr = WBEM_S_NO_ERROR;
  1531. CClassElem* pCurrEl = NULL;
  1532. BOOL bFound = FALSE;
  1533. hr = BeginEnum();
  1534. while ( ( WBEM_S_NO_ERROR == Next( &pCurrEl ) ) && ( SUCCEEDED( hr ) ) )
  1535. {
  1536. CAdapReleaseMe rmCurEl( pCurrEl );
  1537. if ( pCurrEl->SameName( pEl ) )
  1538. {
  1539. bFound = TRUE;
  1540. break;
  1541. }
  1542. }
  1543. EndEnum();
  1544. if ( bFound )
  1545. {
  1546. WString wstrClassName;
  1547. WString wstrServiceName;
  1548. hr = pEl->GetClassName( wstrClassName );
  1549. if(FAILED(hr))
  1550. return hr;
  1551. hr = pEl->GetServiceName( wstrServiceName );
  1552. if(FAILED(hr))
  1553. return hr;
  1554. CAdapUtility::NTLogEvent( EVENTLOG_WARNING_TYPE,
  1555. WBEM_MC_ADAP_DUPLICATE_CLASS,
  1556. (LPCWSTR)wstrClassName, (LPCWSTR)wstrServiceName );
  1557. }
  1558. else
  1559. {
  1560. m_array.Add( pEl );
  1561. }
  1562. return hr;
  1563. }
  1564. ////////////////////////////////////////////////////////////////////////////////
  1565. //
  1566. // CMasterClassList
  1567. //
  1568. ////////////////////////////////////////////////////////////////////////////////
  1569. CMasterClassList::CMasterClassList( CLocaleCache* pLocaleCache,
  1570. CKnownSvcs * pCKnownSvcs)
  1571. : CClassList( pLocaleCache ),
  1572. m_pKnownSvcs(pCKnownSvcs)
  1573. {
  1574. if (m_pKnownSvcs)
  1575. m_pKnownSvcs->AddRef();
  1576. }
  1577. CMasterClassList::~CMasterClassList()
  1578. {
  1579. if (m_pKnownSvcs)
  1580. m_pKnownSvcs->Release();
  1581. }
  1582. // Adds an element to the classlist
  1583. HRESULT CMasterClassList::AddClassObject( IWbemClassObject* pObj, BOOL bSourceWMI, BOOL bDelta )
  1584. {
  1585. HRESULT hr = WBEM_NO_ERROR;
  1586. // Create a new class list element
  1587. // ===============================
  1588. CClassElem* pElem = new CClassElem( pObj, m_pLocaleCache );
  1589. CAdapReleaseMe armElem( pElem );
  1590. if ( ( NULL != pElem ) && ( pElem->IsOk() ) )
  1591. {
  1592. if ( bSourceWMI )
  1593. {
  1594. pElem->SetStatus( ADAP_OBJECT_IS_REGISTERED | ADAP_OBJECT_IS_NOT_IN_PERFLIB );
  1595. }
  1596. if ( -1 == m_array.Add( pElem ) )
  1597. {
  1598. // Add failed
  1599. // ==========
  1600. hr = WBEM_E_OUT_OF_MEMORY;
  1601. }
  1602. else
  1603. {
  1604. pElem->SetKnownSvcs(m_pKnownSvcs);
  1605. }
  1606. }
  1607. else
  1608. {
  1609. hr = WBEM_E_FAILED;
  1610. }
  1611. if ( FAILED( hr ) )
  1612. {
  1613. if ( NULL != pElem )
  1614. {
  1615. delete pElem;
  1616. }
  1617. }
  1618. return hr;
  1619. }
  1620. // Builds a list of class objects that can be located by name
  1621. HRESULT CMasterClassList::BuildList( WCHAR* wszBaseClass,
  1622. BOOL bDelta,
  1623. BOOL bThrottle )
  1624. {
  1625. HRESULT hr = WBEM_S_NO_ERROR;
  1626. CLocaleDefn* pDefn = NULL;
  1627. IWbemServices* pNamespace = NULL;
  1628. // Create the class enumerator
  1629. // ===========================
  1630. hr = m_pLocaleCache->GetDefaultDefn( &pDefn );
  1631. CAdapReleaseMe rmDefn( pDefn );
  1632. if ( SUCCEEDED( hr ) )
  1633. {
  1634. hr = pDefn->GetNamespace( &pNamespace );
  1635. }
  1636. CReleaseMe rmNamespace( pNamespace );
  1637. if ( SUCCEEDED( hr ) )
  1638. {
  1639. BSTR bstrClass = SysAllocString( wszBaseClass );
  1640. CSysFreeMe sfmClass(bstrClass);
  1641. if ( NULL != bstrClass )
  1642. {
  1643. IEnumWbemClassObject* pEnum = NULL;
  1644. hr = pNamespace->CreateClassEnum( bstrClass,
  1645. WBEM_FLAG_SHALLOW,
  1646. NULL,
  1647. &pEnum );
  1648. // Walk the enumerator
  1649. // ===================
  1650. if ( SUCCEEDED( hr ) )
  1651. {
  1652. // Set Interface security
  1653. // ======================
  1654. hr = WbemSetProxyBlanket( pEnum, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
  1655. RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
  1656. // Walk the object list in blocks of 100
  1657. // =====================================
  1658. while ( SUCCEEDED( hr ) && WBEM_S_FALSE != hr)
  1659. {
  1660. ULONG ulNumReturned = 0;
  1661. IWbemClassObject* apObjectArray[100];
  1662. ZeroMemory( apObjectArray, sizeof(apObjectArray) );
  1663. // Fetch the objects from the enumerator in blocks of 100
  1664. // ======================================================
  1665. hr = pEnum->Next( WBEM_INFINITE,
  1666. 100,
  1667. apObjectArray,
  1668. &ulNumReturned );
  1669. // For each object, add it to the class list array
  1670. // ===============================================
  1671. if ( SUCCEEDED( hr ) && ulNumReturned > 0 )
  1672. {
  1673. // Add the objects
  1674. // ===============
  1675. for ( int x = 0; SUCCEEDED( hr ) && x < ulNumReturned; x++ )
  1676. {
  1677. if (bThrottle )
  1678. {
  1679. HRESULT hrThr = Throttle(THROTTLE_USER|THROTTLE_IO,
  1680. ADAP_IDLE_USER,
  1681. ADAP_IDLE_IO,
  1682. ADAP_LOOP_SLEEP,
  1683. ADAP_MAX_WAIT);
  1684. if (THROTTLE_FORCE_EXIT == hrThr)
  1685. {
  1686. //OutputDebugStringA("(ADAP) Unthrottle command received\n");
  1687. bThrottle = FALSE;
  1688. UNICODE_STRING BaseUnicodeCommandLine = NtCurrentPeb()->ProcessParameters->CommandLine;
  1689. WCHAR * pT = wcschr(BaseUnicodeCommandLine.Buffer,L't');
  1690. if (0 == pT)
  1691. pT = wcschr(BaseUnicodeCommandLine.Buffer,L'T');
  1692. if (pT)
  1693. {
  1694. *pT = L' ';
  1695. pT--;
  1696. *pT = L' ';
  1697. }
  1698. }
  1699. }
  1700. HRESULT temphr = WBEM_S_NO_ERROR;
  1701. _variant_t var;
  1702. IWbemClassObject* pObject = apObjectArray[x];
  1703. // Only add generic perf counter objects
  1704. // =====================================
  1705. IWbemQualifierSet* pQualSet = NULL;
  1706. hr = pObject->GetQualifierSet( &pQualSet );
  1707. CReleaseMe rmQualSet( pQualSet );
  1708. if ( SUCCEEDED( hr ) )
  1709. {
  1710. var = bool(true);
  1711. temphr = pQualSet->Get( L"genericperfctr", 0L, &var, NULL );
  1712. if ( SUCCEEDED( temphr ) &&
  1713. ( V_VT(&var) == VT_BOOL ) &&
  1714. ( V_BOOL(&var) == VARIANT_TRUE ) )
  1715. {
  1716. hr = AddClassObject( pObject, TRUE, bDelta );
  1717. }
  1718. }
  1719. pObject->Release();
  1720. }
  1721. // If an add operation failed, release the rest of the pointers
  1722. // ============================================================
  1723. if ( FAILED( hr ) )
  1724. {
  1725. for ( ; x < ulNumReturned; x++ )
  1726. {
  1727. apObjectArray[x]->Release();
  1728. }
  1729. } // IF FAILED( hr ) )
  1730. } // IF Next
  1731. } // WHILE enuming
  1732. if ( WBEM_S_FALSE == hr )
  1733. {
  1734. hr = WBEM_S_NO_ERROR;
  1735. }
  1736. pEnum->Release();
  1737. } // IF CreateClassEnum
  1738. }
  1739. else
  1740. {
  1741. hr = WBEM_E_OUT_OF_MEMORY;
  1742. }
  1743. }
  1744. return hr;
  1745. }
  1746. HRESULT CMasterClassList::Merge( CClassList* pClassList, BOOL bDelta )
  1747. {
  1748. HRESULT hr = WBEM_S_NO_ERROR;
  1749. CClassElem* pEl = NULL;
  1750. hr = pClassList->BeginEnum();
  1751. // Does not return objects marked for deletion
  1752. while ( ( WBEM_S_NO_ERROR == pClassList->Next( &pEl ) ) && ( SUCCEEDED( hr ) ) )
  1753. {
  1754. CAdapReleaseMe rmEl( pEl );
  1755. hr = AddElement( pEl, bDelta );
  1756. }
  1757. pClassList->EndEnum();
  1758. return hr;
  1759. }
  1760. // Cycle through all of the objects and set the inactive status for any object
  1761. // with an index between the library's counter index range
  1762. HRESULT CMasterClassList::Commit(BOOL bThrottle)
  1763. {
  1764. HRESULT hr = WBEM_NO_ERROR;
  1765. int nEl,
  1766. nNumEl = m_array.GetSize();
  1767. DWORD dwWait;
  1768. dwWait = WaitForSingleObject( g_hAbort, 0 );
  1769. if ( WAIT_OBJECT_0 != dwWait )
  1770. {
  1771. // Validate object's uniqueness in list
  1772. // ====================================
  1773. for ( nEl = 0; SUCCEEDED( hr ) && nEl < nNumEl; nEl++ )
  1774. {
  1775. if (bThrottle)
  1776. {
  1777. HRESULT hrThr = Throttle(THROTTLE_USER|THROTTLE_IO,
  1778. ADAP_IDLE_USER,
  1779. ADAP_IDLE_IO,
  1780. ADAP_LOOP_SLEEP,
  1781. ADAP_MAX_WAIT);
  1782. if (THROTTLE_FORCE_EXIT == hrThr)
  1783. {
  1784. //OutputDebugStringA("(ADAP) Unthrottle command received\n");
  1785. bThrottle = FALSE;
  1786. UNICODE_STRING BaseUnicodeCommandLine = NtCurrentPeb()->ProcessParameters->CommandLine;
  1787. WCHAR * pT = wcschr(BaseUnicodeCommandLine.Buffer,L't');
  1788. if (0 == pT)
  1789. pT = wcschr(BaseUnicodeCommandLine.Buffer,L'T');
  1790. if (pT)
  1791. {
  1792. *pT = L' ';
  1793. pT--;
  1794. *pT = L' ';
  1795. }
  1796. }
  1797. }
  1798. CClassElem* pCurrElem = (CClassElem*)m_array[nEl];
  1799. pCurrElem->Commit();
  1800. }
  1801. }
  1802. else
  1803. {
  1804. hr = WBEM_E_CRITICAL_ERROR;
  1805. }
  1806. return hr;
  1807. }
  1808. HRESULT CMasterClassList::AddElement( CClassElem *pEl, BOOL bDelta )
  1809. {
  1810. HRESULT hr = WBEM_S_NO_ERROR;
  1811. CClassElem* pCurrEl = NULL;
  1812. BOOL bFound = FALSE;
  1813. hr = BeginEnum();
  1814. while ( ( WBEM_S_NO_ERROR == Next( &pCurrEl ) ) && ( SUCCEEDED( hr ) ) )
  1815. {
  1816. CAdapReleaseMe rmCurrEl( pCurrEl );
  1817. if ( pCurrEl->SameName( pEl ) )
  1818. {
  1819. bFound = TRUE;
  1820. if ( pCurrEl->SameObject( pEl ) )
  1821. {
  1822. // Set the satus as found
  1823. // ======================
  1824. pCurrEl->ClearStatus( ADAP_OBJECT_IS_NOT_IN_PERFLIB );
  1825. }
  1826. else
  1827. {
  1828. // Replace the current perflib
  1829. // ===========================
  1830. pCurrEl->UpdateObj( pEl );
  1831. pCurrEl->ClearStatus( ADAP_OBJECT_IS_NOT_IN_PERFLIB | ADAP_OBJECT_IS_REGISTERED );
  1832. }
  1833. break;
  1834. }
  1835. }
  1836. EndEnum();
  1837. if ( !bFound )
  1838. {
  1839. pEl->SetKnownSvcs(m_pKnownSvcs);
  1840. m_array.Add( pEl );
  1841. }
  1842. return hr;
  1843. }
  1844. HRESULT
  1845. CMasterClassList::ForceStatus(WCHAR* pServiceName,BOOL bSet,DWORD dwStatus)
  1846. {
  1847. if (!pServiceName){
  1848. return WBEM_E_INVALID_PARAMETER;
  1849. }
  1850. HRESULT hr = WBEM_S_NO_ERROR;
  1851. CClassElem* pCurrEl = NULL;
  1852. BOOL bFound = FALSE;
  1853. hr = BeginEnum();
  1854. while ( ( WBEM_S_NO_ERROR == Next( &pCurrEl ) ) && ( SUCCEEDED( hr ) ) )
  1855. {
  1856. CAdapReleaseMe rmCurrEl( pCurrEl );
  1857. WString wstr;
  1858. hr = pCurrEl->GetServiceName(wstr);
  1859. if(FAILED(hr))
  1860. return hr;
  1861. if (0==_wcsicmp((LPWSTR)wstr,pServiceName))
  1862. {
  1863. DEBUGTRACE((LOG_WMIADAP,"ForeceStatus %S %08x\n",(LPWSTR)wstr,pCurrEl->GetStatus()));
  1864. if (bSet){
  1865. pCurrEl->SetStatus(dwStatus);
  1866. } else {
  1867. pCurrEl->ClearStatus(dwStatus);
  1868. }
  1869. }
  1870. }
  1871. EndEnum();
  1872. return hr;
  1873. }
  1874. #ifdef _DUMP_LIST
  1875. HRESULT
  1876. CMasterClassList::Dump()
  1877. {
  1878. HRESULT hr = WBEM_S_NO_ERROR;
  1879. CClassElem* pCurrEl = NULL;
  1880. BOOL bFound = FALSE;
  1881. hr = BeginEnum();
  1882. while ( ( WBEM_S_NO_ERROR == Next( &pCurrEl ) ) && ( SUCCEEDED( hr ) ) )
  1883. {
  1884. CAdapReleaseMe rmCurrEl( pCurrEl );
  1885. WString wstr;
  1886. hr = pCurrEl->GetServiceName(wstr);
  1887. if(FAILED(hr))
  1888. return hr;
  1889. WString wstr2;
  1890. hr = pCurrEl->GetClassName(wstr2);
  1891. if(FAILED(hr))
  1892. return hr;
  1893. DEBUGTRACE((LOG_WMIADAP,"_DUMP_LIST %S %S\n",(LPWSTR)wstr,(LPWSTR)wstr2));
  1894. }
  1895. EndEnum();
  1896. return hr;
  1897. }
  1898. #endif