Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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