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.

1786 lines
41 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 2000 Microsoft Corporation
  4. //
  5. // REFRESHER.CPP
  6. //
  7. // alanbos 20-Jan-00 Created.
  8. //
  9. // Defines the implementation of ISWbemRefresher and ISWbemRefreshableItem
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. //***************************************************************************
  14. //
  15. // CSWbemRefresher::CSWbemRefresher
  16. //
  17. // DESCRIPTION:
  18. //
  19. // Constructor.
  20. //
  21. //***************************************************************************
  22. CSWbemRefreshableItem::CSWbemRefreshableItem(
  23. ISWbemRefresher *pRefresher,
  24. long iIndex,
  25. IDispatch *pServices,
  26. IWbemClassObject *pObject,
  27. IWbemHiPerfEnum *pObjectSet
  28. )
  29. : m_pISWbemRefresher (pRefresher),
  30. m_iIndex (iIndex),
  31. m_bIsSet (VARIANT_FALSE),
  32. m_pISWbemObjectEx (NULL),
  33. m_pISWbemObjectSet (NULL),
  34. m_cRef (0)
  35. {
  36. m_Dispatch.SetObj (this, IID_ISWbemRefreshableItem,
  37. CLSID_SWbemRefreshableItem, L"SWbemRefreshableItem");
  38. // Note that we do NOT AddRef m_pISWbemRefresher. To do so would create
  39. // a circular reference between this object and the refresher, since the
  40. // refresher's map already holds a reference to this object.
  41. if (pServices)
  42. {
  43. CComQIPtr<ISWbemInternalServices> pISWbemInternalServices (pServices);
  44. if (pISWbemInternalServices)
  45. {
  46. CSWbemServices *pCSWbemServices = new CSWbemServices (pISWbemInternalServices);
  47. if (pCSWbemServices)
  48. pCSWbemServices->AddRef ();
  49. if (pObject)
  50. {
  51. // Create a new CSWbemObject for ourselves
  52. CSWbemObject *pCSWbemObject = new CSWbemObject (pCSWbemServices, pObject);
  53. if (pCSWbemObject){
  54. if(FAILED(pCSWbemObject->QueryInterface (IID_ISWbemObjectEx, (void**) &m_pISWbemObjectEx))){
  55. delete pCSWbemObject;
  56. }
  57. }
  58. }
  59. if (pObjectSet)
  60. {
  61. // Create a new CSWbemHiPerfObjectSet for ourselves
  62. CSWbemHiPerfObjectSet *pCSWbemHiPerfObjectSet =
  63. new CSWbemHiPerfObjectSet (pCSWbemServices, pObjectSet);
  64. if (pCSWbemHiPerfObjectSet)
  65. {
  66. if(SUCCEEDED(pCSWbemHiPerfObjectSet->QueryInterface (IID_ISWbemObjectSet, (void**) &m_pISWbemObjectSet))){
  67. m_bIsSet = VARIANT_TRUE;
  68. } else {
  69. delete pCSWbemHiPerfObjectSet;
  70. }
  71. }
  72. }
  73. if (pCSWbemServices)
  74. pCSWbemServices->Release ();
  75. }
  76. }
  77. InterlockedIncrement(&g_cObj);
  78. }
  79. //***************************************************************************
  80. //
  81. // CSWbemRefreshableItem::~CSWbemRefreshableItem
  82. //
  83. // DESCRIPTION:
  84. //
  85. // Destructor.
  86. //
  87. //***************************************************************************
  88. CSWbemRefreshableItem::~CSWbemRefreshableItem(void)
  89. {
  90. InterlockedDecrement(&g_cObj);
  91. if (m_pISWbemObjectEx)
  92. {
  93. m_pISWbemObjectEx->Release ();
  94. m_pISWbemObjectEx = NULL;
  95. }
  96. if (m_pISWbemObjectSet)
  97. {
  98. m_pISWbemObjectSet->Release ();
  99. m_pISWbemObjectSet = NULL;
  100. }
  101. }
  102. //***************************************************************************
  103. // HRESULT CSWbemRefreshableItem::QueryInterface
  104. // long CSWbemRefreshableItem::AddRef
  105. // long CSWbemRefreshableItem::Release
  106. //
  107. // DESCRIPTION:
  108. //
  109. // Standard Com IUNKNOWN functions.
  110. //
  111. //***************************************************************************
  112. STDMETHODIMP CSWbemRefreshableItem::QueryInterface (
  113. IN REFIID riid,
  114. OUT LPVOID *ppv
  115. )
  116. {
  117. *ppv=NULL;
  118. if (IID_IUnknown==riid)
  119. *ppv = reinterpret_cast<IUnknown*>(this);
  120. else if (IID_ISWbemRefreshableItem==riid)
  121. *ppv = (ISWbemRefresher *)this;
  122. else if (IID_IDispatch==riid)
  123. *ppv = (IDispatch *)this;
  124. else if (IID_ISupportErrorInfo==riid)
  125. *ppv = (ISupportErrorInfo *)this;
  126. else if (IID_IProvideClassInfo==riid)
  127. *ppv = (IProvideClassInfo *)this;
  128. if (NULL!=*ppv)
  129. {
  130. ((LPUNKNOWN)*ppv)->AddRef();
  131. return NOERROR;
  132. }
  133. return ResultFromScode(E_NOINTERFACE);
  134. }
  135. STDMETHODIMP_(ULONG) CSWbemRefreshableItem::AddRef(void)
  136. {
  137. InterlockedIncrement(&m_cRef);
  138. return m_cRef;
  139. }
  140. STDMETHODIMP_(ULONG) CSWbemRefreshableItem::Release(void)
  141. {
  142. LONG cRef = InterlockedDecrement(&m_cRef);
  143. if (0 != cRef)
  144. {
  145. _ASSERT(cRef > 0);
  146. return cRef;
  147. }
  148. delete this;
  149. return 0;
  150. }
  151. //***************************************************************************
  152. //
  153. // CSWbemRefresher::CSWbemRefresher
  154. //
  155. // DESCRIPTION:
  156. //
  157. // Constructor.
  158. //
  159. //***************************************************************************
  160. CSWbemRefresher::CSWbemRefresher()
  161. : m_iCount (0),
  162. m_bAutoReconnect (VARIANT_TRUE),
  163. m_pIWbemConfigureRefresher (NULL),
  164. m_pIWbemRefresher (NULL),
  165. m_cRef (0)
  166. {
  167. m_Dispatch.SetObj (this, IID_ISWbemRefresher,
  168. CLSID_SWbemRefresher, L"SWbemRefresher");
  169. InterlockedIncrement(&g_cObj);
  170. }
  171. //***************************************************************************
  172. //
  173. // CSWbemRefresher::~CSWbemRefresher
  174. //
  175. // DESCRIPTION:
  176. //
  177. // Destructor.
  178. //
  179. //***************************************************************************
  180. CSWbemRefresher::~CSWbemRefresher(void)
  181. {
  182. InterlockedDecrement(&g_cObj);
  183. // Remove all items from the refresher
  184. DeleteAll ();
  185. if (m_pIWbemConfigureRefresher)
  186. m_pIWbemConfigureRefresher->Release ();
  187. if (m_pIWbemRefresher)
  188. m_pIWbemRefresher->Release ();
  189. }
  190. //***************************************************************************
  191. // HRESULT CSWbemRefresher::QueryInterface
  192. // long CSWbemRefresher::AddRef
  193. // long CSWbemRefresher::Release
  194. //
  195. // DESCRIPTION:
  196. //
  197. // Standard Com IUNKNOWN functions.
  198. //
  199. //***************************************************************************
  200. STDMETHODIMP CSWbemRefresher::QueryInterface (
  201. IN REFIID riid,
  202. OUT LPVOID *ppv
  203. )
  204. {
  205. *ppv=NULL;
  206. if (IID_IUnknown==riid)
  207. *ppv = reinterpret_cast<IUnknown*>(this);
  208. else if (IID_ISWbemRefresher==riid)
  209. *ppv = (ISWbemRefresher *)this;
  210. else if (IID_IDispatch==riid)
  211. *ppv = (IDispatch *)this;
  212. else if (IID_IObjectSafety==riid)
  213. *ppv = (IObjectSafety *)this;
  214. else if (IID_ISupportErrorInfo==riid)
  215. *ppv = (ISupportErrorInfo *)this;
  216. else if (IID_IProvideClassInfo==riid)
  217. *ppv = (IProvideClassInfo *)this;
  218. if (NULL!=*ppv)
  219. {
  220. ((LPUNKNOWN)*ppv)->AddRef();
  221. return NOERROR;
  222. }
  223. return ResultFromScode(E_NOINTERFACE);
  224. }
  225. STDMETHODIMP_(ULONG) CSWbemRefresher::AddRef(void)
  226. {
  227. InterlockedIncrement(&m_cRef);
  228. return m_cRef;
  229. }
  230. STDMETHODIMP_(ULONG) CSWbemRefresher::Release(void)
  231. {
  232. LONG cRef = InterlockedDecrement(&m_cRef);
  233. if (0 != cRef)
  234. {
  235. _ASSERT(cRef > 0);
  236. return cRef;
  237. }
  238. delete this;
  239. return 0;
  240. }
  241. //***************************************************************************
  242. //
  243. // SCODE CSWbemRefresher::get__NewEnum
  244. //
  245. // DESCRIPTION:
  246. //
  247. // Return an IEnumVARIANT-supporting interface for collections
  248. //
  249. // PARAMETERS:
  250. //
  251. // ppUnk on successful return addresses the IUnknown interface
  252. //
  253. // RETURN VALUES:
  254. //
  255. // S_OK success
  256. // E_FAIL otherwise
  257. //
  258. //***************************************************************************
  259. HRESULT CSWbemRefresher::get__NewEnum (
  260. IUnknown **ppUnk
  261. )
  262. {
  263. HRESULT hr = E_FAIL;
  264. ResetLastErrors ();
  265. if (NULL != ppUnk)
  266. {
  267. *ppUnk = NULL;
  268. CEnumRefresher *pEnumRefresher = new CEnumRefresher (this);
  269. if (!pEnumRefresher)
  270. hr = WBEM_E_OUT_OF_MEMORY;
  271. else if (FAILED(hr = pEnumRefresher->QueryInterface (IID_IUnknown, (PPVOID) ppUnk)))
  272. delete pEnumRefresher;
  273. }
  274. if (FAILED(hr))
  275. m_Dispatch.RaiseException (hr);
  276. return hr;
  277. }
  278. //***************************************************************************
  279. //
  280. // SCODE CSWbemRefresher::get_Count
  281. //
  282. // DESCRIPTION:
  283. //
  284. // Return the number of items in the collection
  285. //
  286. // PARAMETERS:
  287. //
  288. // plCount on successful return addresses the count
  289. //
  290. // RETURN VALUES:
  291. //
  292. // S_OK success
  293. // E_FAIL otherwise
  294. //
  295. //***************************************************************************
  296. HRESULT CSWbemRefresher::get_Count (
  297. long *plCount
  298. )
  299. {
  300. HRESULT hr = E_FAIL;
  301. ResetLastErrors ();
  302. if (NULL != plCount)
  303. {
  304. *plCount = m_ObjectMap.size ();
  305. hr = S_OK;
  306. }
  307. if (FAILED(hr))
  308. m_Dispatch.RaiseException (hr);
  309. return hr;
  310. }
  311. //***************************************************************************
  312. //
  313. // SCODE CSWbemRefresher::Add
  314. //
  315. // DESCRIPTION:
  316. //
  317. // Add a single instance to the refresher
  318. //
  319. // PARAMETERS:
  320. //
  321. // pISWbemServicesEx the SWbemServicesEx to use
  322. // bsInstancePath the relative path of the instance
  323. // iFlags flags
  324. // pSWbemContext context
  325. // ppSWbemRefreshableItem addresses the SWbemRefreshableItem on successful return
  326. //
  327. // RETURN VALUES:
  328. //
  329. // WBEM_S_NO_ERROR success
  330. // WBEM_E_INVALID_PARAMETER bad input parameters
  331. // WBEM_E_NOT_FOUND index out of range
  332. // WBEM_E_FAILED otherwise
  333. //
  334. //***************************************************************************
  335. HRESULT CSWbemRefresher::Add (
  336. ISWbemServicesEx *pISWbemServicesEx,
  337. BSTR bsInstancePath,
  338. long iFlags,
  339. IDispatch *pSWbemContext,
  340. ISWbemRefreshableItem **ppSWbemRefreshableItem
  341. )
  342. {
  343. HRESULT hr = WBEM_E_FAILED;
  344. ResetLastErrors ();
  345. if ((NULL == ppSWbemRefreshableItem) || (NULL == pISWbemServicesEx) || (NULL == bsInstancePath))
  346. hr = WBEM_E_INVALID_PARAMETER;
  347. else
  348. {
  349. // Extract the context
  350. CComPtr<IWbemContext> pIWbemContext;
  351. //Can't assign directly because the raw pointer gets AddRef'd twice and we leak,
  352. //So we use Attach() instead to prevent the smart pointer from AddRef'ing.
  353. pIWbemContext.Attach(CSWbemNamedValueSet::GetIWbemContext (pSWbemContext));
  354. // Extract the IWbemServices
  355. CComPtr<IWbemServices> pIWbemServices;
  356. pIWbemServices.Attach( CSWbemServices::GetIWbemServices (pISWbemServicesEx));
  357. if (pIWbemServices)
  358. {
  359. // Get our refresher - may need to create on demand
  360. if (NULL == m_pIWbemConfigureRefresher)
  361. CreateRefresher ();
  362. if (m_pIWbemConfigureRefresher)
  363. {
  364. IWbemClassObject *pObject = NULL;
  365. long iIndex = 0;
  366. if (SUCCEEDED(hr = m_pIWbemConfigureRefresher->AddObjectByPath (pIWbemServices,
  367. bsInstancePath, iFlags, pIWbemContext, &pObject, &iIndex)))
  368. {
  369. CSWbemRefreshableItem *pRefreshableItem = new
  370. CSWbemRefreshableItem (this, iIndex,
  371. pISWbemServicesEx, pObject, NULL);
  372. if (!pRefreshableItem)
  373. hr = WBEM_E_OUT_OF_MEMORY;
  374. else if (SUCCEEDED(hr =pRefreshableItem->QueryInterface (IID_ISWbemRefreshableItem,
  375. (void**) ppSWbemRefreshableItem)))
  376. {
  377. m_ObjectMap [iIndex] = pRefreshableItem;
  378. pRefreshableItem->AddRef ();
  379. }
  380. else
  381. delete pRefreshableItem;
  382. }
  383. }
  384. }
  385. }
  386. if (FAILED(hr))
  387. m_Dispatch.RaiseException (hr);
  388. return hr;
  389. }
  390. //***************************************************************************
  391. //
  392. // SCODE CSWbemRefresher::AddEnum
  393. //
  394. // DESCRIPTION:
  395. //
  396. // Add a single enum (shallow instance) to the refresher
  397. //
  398. // PARAMETERS:
  399. //
  400. // pISWbemServicesEx the SWbemServicesEx to use
  401. // bsClassName the name of the class
  402. // iFlags flags
  403. // pSWbemContext context
  404. // ppSWbemRefreshableItem addresses the SWbemRefreshableItem on successful return
  405. //
  406. // RETURN VALUES:
  407. //
  408. // WBEM_S_NO_ERROR success
  409. // WBEM_E_INVALID_PARAMETER bad input parameters
  410. // WBEM_E_NOT_FOUND index out of range
  411. // WBEM_E_FAILED otherwise
  412. //
  413. //***************************************************************************
  414. HRESULT CSWbemRefresher::AddEnum (
  415. ISWbemServicesEx *pISWbemServicesEx,
  416. BSTR bsClassName,
  417. long iFlags,
  418. IDispatch *pSWbemContext,
  419. ISWbemRefreshableItem **ppSWbemRefreshableItem
  420. )
  421. {
  422. HRESULT hr = WBEM_E_FAILED;
  423. ResetLastErrors ();
  424. if ((NULL == ppSWbemRefreshableItem) || (NULL == pISWbemServicesEx)
  425. || (NULL == bsClassName))
  426. hr = WBEM_E_INVALID_PARAMETER;
  427. else
  428. {
  429. // Extract the context
  430. CComPtr<IWbemContext> pIWbemContext;
  431. //Can't assign directly because the raw pointer gets AddRef'd twice and we leak,
  432. //So we use Attach() instead to prevent the smart pointer from AddRef'ing.
  433. pIWbemContext.Attach(CSWbemNamedValueSet::GetIWbemContext (pSWbemContext));
  434. // Extract the IWbemServices
  435. CComPtr<IWbemServices> pIWbemServices;
  436. pIWbemServices.Attach( CSWbemServices::GetIWbemServices (pISWbemServicesEx));
  437. if (pIWbemServices)
  438. {
  439. // Get our refresher - may need to create on demand
  440. if (NULL == m_pIWbemConfigureRefresher)
  441. CreateRefresher ();
  442. if (m_pIWbemConfigureRefresher)
  443. {
  444. IWbemHiPerfEnum *pIWbemHiPerfEnum = NULL;
  445. long iIndex = 0;
  446. if (SUCCEEDED(hr = m_pIWbemConfigureRefresher->AddEnum (pIWbemServices,
  447. bsClassName, iFlags, pIWbemContext, &pIWbemHiPerfEnum, &iIndex)))
  448. {
  449. CSWbemRefreshableItem *pRefreshableItem = new
  450. CSWbemRefreshableItem (this, iIndex,
  451. pISWbemServicesEx, NULL, pIWbemHiPerfEnum);
  452. if (!pRefreshableItem)
  453. hr = WBEM_E_OUT_OF_MEMORY;
  454. else if (SUCCEEDED(hr =pRefreshableItem->QueryInterface (IID_ISWbemRefreshableItem,
  455. (void**) ppSWbemRefreshableItem)))
  456. {
  457. m_ObjectMap [iIndex] = pRefreshableItem;
  458. pRefreshableItem->AddRef ();
  459. }
  460. else
  461. delete pRefreshableItem;
  462. }
  463. }
  464. }
  465. }
  466. if (FAILED(hr))
  467. m_Dispatch.RaiseException (hr);
  468. return hr;
  469. }
  470. //***************************************************************************
  471. //
  472. // SCODE CSWbemRefresher::Remove
  473. //
  474. // DESCRIPTION:
  475. //
  476. // Remove object from refresher
  477. //
  478. // PARAMETERS:
  479. //
  480. // iIndex Index of object to retrieve
  481. // iFlags Flags
  482. //
  483. // RETURN VALUES:
  484. //
  485. // WBEM_S_NO_ERROR success
  486. // WBEM_E_INVALID_PARAMETER bad input parameters
  487. // WBEM_E_NOT_FOUND index out of range
  488. // WBEM_E_FAILED otherwise
  489. //
  490. //***************************************************************************
  491. HRESULT CSWbemRefresher::Remove (
  492. long iIndex,
  493. long iFlags
  494. )
  495. {
  496. HRESULT hr = WBEM_E_FAILED;
  497. ResetLastErrors ();
  498. if (m_pIWbemConfigureRefresher)
  499. {
  500. if (0 != iFlags)
  501. hr = WBEM_E_INVALID_PARAMETER;
  502. else
  503. {
  504. hr = m_pIWbemConfigureRefresher->Remove (iIndex,
  505. (VARIANT_TRUE == m_bAutoReconnect) ?
  506. WBEM_FLAG_REFRESH_AUTO_RECONNECT :
  507. WBEM_FLAG_REFRESH_NO_AUTO_RECONNECT);
  508. if (WBEM_S_FALSE == hr)
  509. hr = WBEM_E_NOT_FOUND;
  510. if (SUCCEEDED(hr))
  511. {
  512. // Now remove from our collection
  513. RefreshableItemMap::iterator theIterator = m_ObjectMap.find (iIndex);
  514. if (theIterator != m_ObjectMap.end ())
  515. EraseItem (theIterator);
  516. }
  517. }
  518. }
  519. if (FAILED(hr))
  520. m_Dispatch.RaiseException (hr);
  521. return hr;
  522. }
  523. //***************************************************************************
  524. //
  525. // SCODE CSWbemRefresher::DeleteAll
  526. //
  527. // DESCRIPTION:
  528. //
  529. // Remove all items from refresher
  530. //
  531. // PARAMETERS:
  532. //
  533. // none
  534. //
  535. // RETURN VALUES:
  536. //
  537. // WBEM_S_NO_ERROR success
  538. // WBEM_E_INVALID_PARAMETER bad input parameters
  539. // WBEM_E_NOT_FOUND index out of range
  540. // WBEM_E_FAILED otherwise
  541. //
  542. //***************************************************************************
  543. HRESULT CSWbemRefresher::DeleteAll (
  544. )
  545. {
  546. ResetLastErrors ();
  547. RefreshableItemMap::iterator next;
  548. while ((next = m_ObjectMap.begin ()) != m_ObjectMap.end ())
  549. {
  550. CSWbemRefreshableItem *pRefreshableItem = (*next).second;
  551. long iIndex = 0;
  552. if (m_pIWbemConfigureRefresher && pRefreshableItem &&
  553. SUCCEEDED(pRefreshableItem->get_Index (&iIndex)))
  554. {
  555. HRESULT hr = m_pIWbemConfigureRefresher->Remove (iIndex,
  556. (VARIANT_TRUE == m_bAutoReconnect) ?
  557. WBEM_FLAG_REFRESH_AUTO_RECONNECT :
  558. WBEM_FLAG_REFRESH_NO_AUTO_RECONNECT);
  559. }
  560. EraseItem (next);
  561. }
  562. return WBEM_S_NO_ERROR;
  563. }
  564. //***************************************************************************
  565. //
  566. // SCODE CSWbemRefresher::Refresh
  567. //
  568. // DESCRIPTION:
  569. //
  570. // Refresh all objects in this refresher.
  571. //
  572. // PARAMETERS:
  573. //
  574. // lFlags Flags
  575. //
  576. // RETURN VALUES:
  577. //
  578. // WBEM_S_NO_ERROR success
  579. // WBEM_E_INVALID_PARAMETER bad input parameters
  580. // WBEM_E_NOT_FOUND index out of range
  581. // WBEM_E_FAILED otherwise
  582. //
  583. //***************************************************************************
  584. HRESULT CSWbemRefresher::Refresh (
  585. long iFlags
  586. )
  587. {
  588. HRESULT hr = WBEM_E_FAILED;
  589. ResetLastErrors ();
  590. if (0 != iFlags)
  591. hr = WBEM_E_INVALID_PARAMETER;
  592. else if (m_pIWbemRefresher)
  593. {
  594. hr = m_pIWbemRefresher->Refresh ((VARIANT_TRUE == m_bAutoReconnect) ?
  595. WBEM_FLAG_REFRESH_AUTO_RECONNECT :
  596. WBEM_FLAG_REFRESH_NO_AUTO_RECONNECT);
  597. }
  598. if (FAILED(hr))
  599. m_Dispatch.RaiseException (hr);
  600. return hr;
  601. }
  602. //***************************************************************************
  603. //
  604. // SCODE CSWbemRefresher::Item
  605. //
  606. // DESCRIPTION:
  607. //
  608. // Get object from the enumeration by index.
  609. //
  610. // PARAMETERS:
  611. //
  612. // iIndex Index of object to retrieve
  613. // lFlags Flags
  614. // ppSWbemRefreshableItem On successful return addresses the object
  615. //
  616. // RETURN VALUES:
  617. //
  618. // WBEM_S_NO_ERROR success
  619. // WBEM_E_INVALID_PARAMETER bad input parameters
  620. // WBEM_E_NOT_FOUND index out of range
  621. // WBEM_E_FAILED otherwise
  622. //
  623. //***************************************************************************
  624. HRESULT CSWbemRefresher::Item (
  625. long iIndex,
  626. ISWbemRefreshableItem **ppSWbemRefreshableItem
  627. )
  628. {
  629. HRESULT hr = WBEM_E_NOT_FOUND;
  630. ResetLastErrors ();
  631. if (NULL == ppSWbemRefreshableItem)
  632. hr = WBEM_E_INVALID_PARAMETER;
  633. else
  634. {
  635. *ppSWbemRefreshableItem = NULL;
  636. RefreshableItemMap::iterator theIterator;
  637. theIterator = m_ObjectMap.find (iIndex);
  638. if (theIterator != m_ObjectMap.end ())
  639. {
  640. CSWbemRefreshableItem *pRefreshableItem = (*theIterator).second;
  641. if (SUCCEEDED(pRefreshableItem->QueryInterface
  642. (IID_ISWbemRefreshableItem, (PPVOID) ppSWbemRefreshableItem)))
  643. {
  644. hr = WBEM_S_NO_ERROR;
  645. }
  646. }
  647. }
  648. if (FAILED(hr))
  649. m_Dispatch.RaiseException (hr);
  650. return hr;
  651. }
  652. //***************************************************************************
  653. //
  654. // void CSWbemRefresher::CreateRefresher
  655. //
  656. // DESCRIPTION:
  657. //
  658. // Create the underlying WMI refresher objects.
  659. //
  660. // PARAMETERS:
  661. //
  662. // none
  663. //
  664. // RETURN VALUES:
  665. //
  666. // none
  667. //***************************************************************************
  668. void CSWbemRefresher::CreateRefresher ()
  669. {
  670. HRESULT hr;
  671. if (NULL == m_pIWbemRefresher)
  672. {
  673. if (SUCCEEDED(hr = CoCreateInstance( CLSID_WbemRefresher, NULL, CLSCTX_INPROC_SERVER,
  674. IID_IWbemRefresher, (void**) &m_pIWbemRefresher )))
  675. {
  676. IWbemConfigureRefresher *pConfigureRefresher = NULL;
  677. // Get ourselves a refresher configurator
  678. hr = m_pIWbemRefresher->QueryInterface (IID_IWbemConfigureRefresher,
  679. (void**) &m_pIWbemConfigureRefresher);
  680. }
  681. }
  682. }
  683. //***************************************************************************
  684. //
  685. // void CSWbemRefresher::EraseItem
  686. //
  687. // DESCRIPTION:
  688. //
  689. // Scrub out an item.
  690. //
  691. // PARAMETERS:
  692. //
  693. // none
  694. //
  695. // RETURN VALUES:
  696. //
  697. // none
  698. //***************************************************************************
  699. void CSWbemRefresher::EraseItem (RefreshableItemMap::iterator iterator)
  700. {
  701. CSWbemRefreshableItem *pRefresherObject = (*iterator).second;
  702. // Remove from the map
  703. m_ObjectMap.erase (iterator);
  704. // Ensure the item is unhooked from the parent.
  705. pRefresherObject->UnhookRefresher ();
  706. // Release the item as it is no longer in the map
  707. pRefresherObject->Release ();
  708. }
  709. // CEnumRefresher Methods
  710. //***************************************************************************
  711. //
  712. // CEnumRefresher::CEnumRefresher
  713. //
  714. // DESCRIPTION:
  715. //
  716. // Constructor.
  717. //
  718. //***************************************************************************
  719. CEnumRefresher::CEnumRefresher(CSWbemRefresher *pRefresher)
  720. {
  721. m_cRef=0;
  722. m_pCSWbemRefresher = pRefresher;
  723. m_pCSWbemRefresher->AddRef ();
  724. m_Iterator = m_pCSWbemRefresher->m_ObjectMap.begin ();
  725. InterlockedIncrement(&g_cObj);
  726. }
  727. CEnumRefresher::CEnumRefresher(CSWbemRefresher *pRefresher,
  728. RefreshableItemMap::iterator iterator) :
  729. m_Iterator (iterator)
  730. {
  731. m_cRef=0;
  732. m_pCSWbemRefresher = pRefresher;
  733. m_pCSWbemRefresher->AddRef ();
  734. InterlockedIncrement(&g_cObj);
  735. }
  736. //***************************************************************************
  737. //
  738. // CEnumRefresher::~CEnumRefresher
  739. //
  740. // DESCRIPTION:
  741. //
  742. // Destructor.
  743. //
  744. //***************************************************************************
  745. CEnumRefresher::~CEnumRefresher(void)
  746. {
  747. InterlockedDecrement(&g_cObj);
  748. if (m_pCSWbemRefresher)
  749. m_pCSWbemRefresher->Release ();
  750. }
  751. //***************************************************************************
  752. // HRESULT CEnumRefresher::QueryInterface
  753. // long CEnumRefresher::AddRef
  754. // long CEnumRefresher::Release
  755. //
  756. // DESCRIPTION:
  757. //
  758. // Standard Com IUNKNOWN functions.
  759. //
  760. //***************************************************************************
  761. STDMETHODIMP CEnumRefresher::QueryInterface (
  762. IN REFIID riid,
  763. OUT LPVOID *ppv
  764. )
  765. {
  766. *ppv=NULL;
  767. if (IID_IUnknown==riid || IID_IEnumVARIANT==riid)
  768. *ppv=this;
  769. if (NULL!=*ppv)
  770. {
  771. ((LPUNKNOWN)*ppv)->AddRef();
  772. return NOERROR;
  773. }
  774. return ResultFromScode(E_NOINTERFACE);
  775. }
  776. STDMETHODIMP_(ULONG) CEnumRefresher::AddRef(void)
  777. {
  778. long l = InterlockedIncrement(&m_cRef);
  779. return l;
  780. }
  781. STDMETHODIMP_(ULONG) CEnumRefresher::Release(void)
  782. {
  783. LONG cRef = InterlockedDecrement(&m_cRef);
  784. if (0 != cRef)
  785. {
  786. _ASSERT(cRef > 0);
  787. return cRef;
  788. }
  789. delete this;
  790. return 0;
  791. }
  792. //***************************************************************************
  793. //
  794. // SCODE CEnumRefresher::Reset
  795. //
  796. // DESCRIPTION:
  797. //
  798. // Reset the enumeration
  799. //
  800. // PARAMETERS:
  801. //
  802. // RETURN VALUES:
  803. //
  804. // S_OK success
  805. // S_FALSE otherwise
  806. //
  807. //***************************************************************************
  808. HRESULT CEnumRefresher::Reset ()
  809. {
  810. HRESULT hr = S_FALSE;
  811. m_Iterator = m_pCSWbemRefresher->m_ObjectMap.begin ();
  812. return hr;
  813. }
  814. //***************************************************************************
  815. //
  816. // SCODE CEnumRefresher::Next
  817. //
  818. // DESCRIPTION:
  819. //
  820. // Get the next object in the enumeration
  821. //
  822. // PARAMETERS:
  823. //
  824. // lTimeout Number of ms to wait for object (or WBEM_INFINITE for
  825. // indefinite)
  826. // ppObject On return may contain the next element (if any)
  827. //
  828. // RETURN VALUES:
  829. //
  830. // S_OK success
  831. // S_FALSE not all elements could be returned
  832. //
  833. //***************************************************************************
  834. HRESULT CEnumRefresher::Next (
  835. ULONG cElements,
  836. VARIANT FAR* pVar,
  837. ULONG FAR* pcElementFetched
  838. )
  839. {
  840. HRESULT hr = S_OK;
  841. ULONG l2 = 0;
  842. if (NULL != pcElementFetched)
  843. *pcElementFetched = 0;
  844. if ((NULL != pVar) && (m_pCSWbemRefresher))
  845. {
  846. for (ULONG l = 0; l < cElements; l++)
  847. VariantInit (&pVar [l]);
  848. // Retrieve the next cElements elements.
  849. for (l2 = 0; l2 < cElements; l2++)
  850. {
  851. if (m_Iterator != m_pCSWbemRefresher->m_ObjectMap.end ())
  852. {
  853. CSWbemRefreshableItem *pCSWbemRefreshableItem = (*m_Iterator).second;
  854. m_Iterator++;
  855. ISWbemRefreshableItem *pISWbemRefreshableItem = NULL;
  856. if (SUCCEEDED(pCSWbemRefreshableItem->QueryInterface
  857. (IID_ISWbemRefreshableItem, (PPVOID) &pISWbemRefreshableItem)))
  858. {
  859. // Set the object into the variant array; note that pObject
  860. // has been addref'd as a result of the QI() call above
  861. pVar[l2].vt = VT_DISPATCH;
  862. pVar[l2].pdispVal = pISWbemRefreshableItem;
  863. }
  864. }
  865. else
  866. break;
  867. }
  868. if (NULL != pcElementFetched)
  869. *pcElementFetched = l2;
  870. }
  871. if (FAILED(hr))
  872. return hr;
  873. return (l2 < cElements) ? S_FALSE : S_OK;
  874. }
  875. //***************************************************************************
  876. //
  877. // SCODE CEnumRefresher::Clone
  878. //
  879. // DESCRIPTION:
  880. //
  881. // Create a copy of this enumeration
  882. //
  883. // PARAMETERS:
  884. //
  885. // ppEnum on successful return addresses the clone
  886. //
  887. // RETURN VALUES:
  888. //
  889. // WBEM_S_NO_ERROR success
  890. // WBEM_E_FAILED otherwise
  891. //
  892. //***************************************************************************
  893. HRESULT CEnumRefresher::Clone (
  894. IEnumVARIANT **ppEnum
  895. )
  896. {
  897. HRESULT hr = E_FAIL;
  898. if (NULL != ppEnum)
  899. {
  900. *ppEnum = NULL;
  901. if (m_pCSWbemRefresher)
  902. {
  903. CEnumRefresher *pEnum = new CEnumRefresher (m_pCSWbemRefresher, m_Iterator);
  904. if (!pEnum)
  905. hr = WBEM_E_OUT_OF_MEMORY;
  906. else if (FAILED(hr = pEnum->QueryInterface (IID_IEnumVARIANT, (PPVOID) ppEnum)))
  907. delete pEnum;;
  908. }
  909. }
  910. return hr;
  911. }
  912. //***************************************************************************
  913. //
  914. // SCODE CEnumRefresher::Skip
  915. //
  916. // DESCRIPTION:
  917. //
  918. // Skip specified number of elements
  919. //
  920. // PARAMETERS:
  921. //
  922. // ppEnum on successful return addresses the clone
  923. //
  924. // RETURN VALUES:
  925. //
  926. // S_OK success
  927. // S_FALSE end of sequence reached prematurely
  928. //
  929. //***************************************************************************
  930. HRESULT CEnumRefresher::Skip(
  931. ULONG cElements
  932. )
  933. {
  934. HRESULT hr = S_FALSE;
  935. if (m_pCSWbemRefresher)
  936. {
  937. ULONG l2;
  938. // Retrieve the next cElements elements.
  939. for (l2 = 0; l2 < cElements; l2++)
  940. {
  941. if (m_Iterator != m_pCSWbemRefresher->m_ObjectMap.end ())
  942. m_Iterator++;
  943. else
  944. break;
  945. }
  946. if (l2 == cElements)
  947. hr = S_OK;
  948. }
  949. return hr;
  950. }
  951. // CSWbemHiPerfObjectSet methods
  952. //***************************************************************************
  953. //
  954. // CSWbemHiPerfObjectSet::CSWbemHiPerfObjectSet
  955. //
  956. // DESCRIPTION:
  957. //
  958. // Constructor.
  959. //
  960. //***************************************************************************
  961. CSWbemHiPerfObjectSet::CSWbemHiPerfObjectSet(CSWbemServices *pService,
  962. IWbemHiPerfEnum *pIWbemHiPerfEnum)
  963. : m_SecurityInfo (NULL),
  964. m_pSWbemServices (pService),
  965. m_pIWbemHiPerfEnum (pIWbemHiPerfEnum),
  966. m_cRef (0)
  967. {
  968. m_Dispatch.SetObj (this, IID_ISWbemObjectSet,
  969. CLSID_SWbemObjectSet, L"SWbemObjectSet");
  970. if (m_pIWbemHiPerfEnum)
  971. m_pIWbemHiPerfEnum->AddRef ();
  972. if (m_pSWbemServices)
  973. {
  974. m_pSWbemServices->AddRef ();
  975. // Use the SWbemServices security object here since
  976. // IWbemHiPerfEnum is not a remote interface
  977. CSWbemSecurity *pSecurity = m_pSWbemServices->GetSecurityInfo ();
  978. m_SecurityInfo = new CSWbemSecurity (pSecurity);
  979. if (pSecurity)
  980. pSecurity->Release ();
  981. }
  982. InterlockedIncrement(&g_cObj);
  983. }
  984. //***************************************************************************
  985. //
  986. // CSWbemHiPerfObjectSet::~CSWbemHiPerfObjectSet
  987. //
  988. // DESCRIPTION:
  989. //
  990. // Destructor.
  991. //
  992. //***************************************************************************
  993. CSWbemHiPerfObjectSet::~CSWbemHiPerfObjectSet(void)
  994. {
  995. InterlockedDecrement(&g_cObj);
  996. if (m_pSWbemServices)
  997. m_pSWbemServices->Release ();
  998. if (m_SecurityInfo)
  999. m_SecurityInfo->Release ();
  1000. if (m_pIWbemHiPerfEnum)
  1001. m_pIWbemHiPerfEnum->Release ();
  1002. }
  1003. //***************************************************************************
  1004. // HRESULT CSWbemHiPerfObjectSet::QueryInterface
  1005. // long CSWbemHiPerfObjectSet::AddRef
  1006. // long CSWbemHiPerfObjectSet::Release
  1007. //
  1008. // DESCRIPTION:
  1009. //
  1010. // Standard Com IUNKNOWN functions.
  1011. //
  1012. //***************************************************************************
  1013. STDMETHODIMP CSWbemHiPerfObjectSet::QueryInterface (
  1014. IN REFIID riid,
  1015. OUT LPVOID *ppv
  1016. )
  1017. {
  1018. *ppv=NULL;
  1019. if (IID_IUnknown==riid)
  1020. *ppv = reinterpret_cast<IUnknown*>(this);
  1021. else if (IID_ISWbemObjectSet==riid)
  1022. *ppv = (ISWbemObjectSet *)this;
  1023. else if (IID_IDispatch==riid)
  1024. *ppv = (IDispatch *)this;
  1025. else if (IID_ISupportErrorInfo==riid)
  1026. *ppv = (ISupportErrorInfo *)this;
  1027. else if (IID_IProvideClassInfo==riid)
  1028. *ppv = (IProvideClassInfo *)this;
  1029. if (NULL!=*ppv)
  1030. {
  1031. ((LPUNKNOWN)*ppv)->AddRef();
  1032. return NOERROR;
  1033. }
  1034. return ResultFromScode(E_NOINTERFACE);
  1035. }
  1036. STDMETHODIMP_(ULONG) CSWbemHiPerfObjectSet::AddRef(void)
  1037. {
  1038. InterlockedIncrement(&m_cRef);
  1039. return m_cRef;
  1040. }
  1041. STDMETHODIMP_(ULONG) CSWbemHiPerfObjectSet::Release(void)
  1042. {
  1043. LONG cRef = InterlockedDecrement(&m_cRef);
  1044. if (0 != cRef)
  1045. {
  1046. _ASSERT(cRef > 0);
  1047. return cRef;
  1048. }
  1049. delete this;
  1050. return 0;
  1051. }
  1052. //***************************************************************************
  1053. //
  1054. // SCODE CSWbemHiPerfObjectSet::ReadObjects
  1055. //
  1056. // DESCRIPTION:
  1057. //
  1058. // Gets the objects out of the enumerator
  1059. //
  1060. // PARAMETERS:
  1061. //
  1062. // RETURN VALUES:
  1063. //
  1064. // WBEM_S_NO_ERROR success
  1065. // WBEM_E_FAILED otherwise
  1066. //
  1067. //***************************************************************************
  1068. // Bug Id 566345
  1069. HRESULT CSWbemHiPerfObjectSet::ReadObjects (unsigned long & iCount , IWbemObjectAccess ***ppIWbemObjectAccess)
  1070. {
  1071. *ppIWbemObjectAccess = NULL;
  1072. iCount = 0;
  1073. HRESULT hr = WBEM_E_FAILED;
  1074. if (m_pIWbemHiPerfEnum)
  1075. {
  1076. // Start by getting the object count
  1077. if (WBEM_E_BUFFER_TOO_SMALL == (hr = m_pIWbemHiPerfEnum->GetObjects (0L, 0L,
  1078. NULL, &iCount)))
  1079. {
  1080. hr = S_OK;
  1081. if(iCount > 0)
  1082. {
  1083. *ppIWbemObjectAccess = new IWbemObjectAccess*[iCount];
  1084. if (*ppIWbemObjectAccess)
  1085. {
  1086. ZeroMemory( *ppIWbemObjectAccess, iCount * sizeof(IWbemObjectAccess*) );
  1087. unsigned long dummy = 0;
  1088. hr = m_pIWbemHiPerfEnum->GetObjects ( 0L, iCount, *ppIWbemObjectAccess, &dummy );
  1089. if(FAILED(hr))
  1090. {
  1091. delete [] (*ppIWbemObjectAccess);
  1092. *ppIWbemObjectAccess = NULL;
  1093. iCount = 0;
  1094. }
  1095. }
  1096. else
  1097. {
  1098. hr = E_OUTOFMEMORY;
  1099. }
  1100. }
  1101. }
  1102. }
  1103. return hr;
  1104. }
  1105. //***************************************************************************
  1106. //
  1107. // SCODE CSWbemHiPerfObjectSet::get__NewEnum
  1108. //
  1109. // DESCRIPTION:
  1110. //
  1111. // Return an IEnumVARIANT-supporting interface for collections
  1112. //
  1113. // PARAMETERS:
  1114. //
  1115. // ppUnk on successful return addresses the IUnknown interface
  1116. //
  1117. // RETURN VALUES:
  1118. //
  1119. // S_OK success
  1120. // E_FAIL otherwise
  1121. //
  1122. //***************************************************************************
  1123. HRESULT CSWbemHiPerfObjectSet::get__NewEnum (
  1124. IUnknown **ppUnk
  1125. )
  1126. {
  1127. HRESULT hr = E_FAIL;
  1128. ResetLastErrors ();
  1129. if (NULL != ppUnk)
  1130. {
  1131. *ppUnk = NULL;
  1132. CEnumVarHiPerf *pEnumVar = new CEnumVarHiPerf (this);
  1133. if (!pEnumVar)
  1134. hr = WBEM_E_OUT_OF_MEMORY;
  1135. else if (FAILED(hr = pEnumVar->QueryInterface (IID_IUnknown, (PPVOID) ppUnk)))
  1136. delete pEnumVar;
  1137. }
  1138. if (FAILED(hr))
  1139. m_Dispatch.RaiseException (hr);
  1140. return hr;
  1141. }
  1142. //***************************************************************************
  1143. //
  1144. // SCODE CSWbemHiPerfObjectSet::get_Count
  1145. //
  1146. // DESCRIPTION:
  1147. //
  1148. // Return the number of items in the collection
  1149. //
  1150. // PARAMETERS:
  1151. //
  1152. // plCount on successful return addresses the count
  1153. //
  1154. // RETURN VALUES:
  1155. //
  1156. // S_OK success
  1157. // E_FAIL otherwise
  1158. //
  1159. //***************************************************************************
  1160. HRESULT CSWbemHiPerfObjectSet::get_Count (
  1161. long *plCount
  1162. )
  1163. {
  1164. HRESULT hr = E_FAIL;
  1165. *plCount = 0;
  1166. ResetLastErrors ();
  1167. if (NULL == plCount)
  1168. hr = WBEM_E_INVALID_PARAMETER;
  1169. else
  1170. {
  1171. unsigned long iCount = 0;
  1172. IWbemObjectAccess **ppIWbemObjectAccess = NULL;
  1173. hr = ReadObjects (iCount,&ppIWbemObjectAccess);
  1174. if(SUCCEEDED(hr)) // Bug Id 566345
  1175. {
  1176. *plCount = iCount;
  1177. hr = WBEM_S_NO_ERROR;
  1178. if(ppIWbemObjectAccess)
  1179. delete [] ppIWbemObjectAccess;
  1180. }
  1181. }
  1182. if (FAILED(hr))
  1183. m_Dispatch.RaiseException (hr);
  1184. return hr;
  1185. }
  1186. //***************************************************************************
  1187. //
  1188. // SCODE CSWbemHiPerfObjectSet::Item
  1189. //
  1190. // DESCRIPTION:
  1191. //
  1192. // Get object from the enumeration by path.
  1193. //
  1194. // PARAMETERS:
  1195. //
  1196. // bsObjectPath The path of the object to retrieve
  1197. // lFlags Flags
  1198. // ppNamedObject On successful return addresses the object
  1199. //
  1200. // RETURN VALUES:
  1201. //
  1202. // WBEM_S_NO_ERROR success
  1203. // WBEM_E_INVALID_PARAMETER bad input parameters
  1204. // WBEM_E_FAILED otherwise
  1205. //
  1206. //***************************************************************************
  1207. HRESULT CSWbemHiPerfObjectSet::Item (
  1208. BSTR bsObjectPath,
  1209. long lFlags,
  1210. ISWbemObject **ppObject
  1211. )
  1212. {
  1213. HRESULT hr = WBEM_E_FAILED;
  1214. ResetLastErrors ();
  1215. if ((NULL == ppObject) || (NULL == bsObjectPath))
  1216. hr = WBEM_E_INVALID_PARAMETER;
  1217. else
  1218. {
  1219. CWbemPathCracker objectPath;
  1220. if (objectPath = bsObjectPath)
  1221. {
  1222. unsigned long iCount = 0;
  1223. IWbemObjectAccess **ppIWbemObjectAccess = NULL;
  1224. hr = ReadObjects (iCount,&ppIWbemObjectAccess);
  1225. if(SUCCEEDED(hr)) // Bug Id 566345
  1226. {
  1227. bool found = false;
  1228. for (unsigned long i = 0; !found && (i < iCount); i++)
  1229. {
  1230. CComPtr<IWbemClassObject> pIWbemClassObject;
  1231. hr = WBEM_E_NOT_FOUND;
  1232. // Iterate through the enumerator to try to find the element with the
  1233. // specified path.
  1234. if (SUCCEEDED(ppIWbemObjectAccess [i]->QueryInterface (IID_IWbemClassObject,
  1235. (void**) &pIWbemClassObject)))
  1236. {
  1237. if (CSWbemObjectPath::CompareObjectPaths (pIWbemClassObject, objectPath))
  1238. {
  1239. // Found it - assign to passed interface and break out
  1240. found = true;
  1241. CSWbemObject *pObject = new CSWbemObject (m_pSWbemServices,
  1242. pIWbemClassObject, m_SecurityInfo);
  1243. if (!pObject)
  1244. hr = WBEM_E_OUT_OF_MEMORY;
  1245. else if (FAILED(pObject->QueryInterface (IID_ISWbemObject,
  1246. (PPVOID) ppObject)))
  1247. {
  1248. hr = WBEM_E_FAILED;
  1249. delete pObject;
  1250. }
  1251. }
  1252. }
  1253. }
  1254. if (found)
  1255. hr = S_OK;
  1256. if (ppIWbemObjectAccess)
  1257. delete [] ppIWbemObjectAccess;
  1258. }
  1259. }
  1260. }
  1261. if (FAILED(hr))
  1262. m_Dispatch.RaiseException (hr);
  1263. return hr;
  1264. }
  1265. //***************************************************************************
  1266. //
  1267. // SCODE CSWbemHiPerfObjectSet::get_Security_
  1268. //
  1269. // DESCRIPTION:
  1270. //
  1271. // Return the security configurator
  1272. //
  1273. // WBEM_S_NO_ERROR success
  1274. // WBEM_E_INVALID_PARAMETER bad input parameters
  1275. // WBEM_E_FAILED otherwise
  1276. //
  1277. //***************************************************************************
  1278. HRESULT CSWbemHiPerfObjectSet::get_Security_ (
  1279. ISWbemSecurity **ppSecurity
  1280. )
  1281. {
  1282. HRESULT hr = WBEM_E_FAILED;
  1283. ResetLastErrors ();
  1284. if (NULL == ppSecurity)
  1285. hr = WBEM_E_INVALID_PARAMETER;
  1286. else // Bug ID 566345
  1287. {
  1288. *ppSecurity = NULL;
  1289. if (m_SecurityInfo)
  1290. {
  1291. *ppSecurity = m_SecurityInfo;
  1292. (*ppSecurity)->AddRef ();
  1293. hr = WBEM_S_NO_ERROR;
  1294. }
  1295. }
  1296. if (FAILED(hr))
  1297. m_Dispatch.RaiseException (hr);
  1298. return hr;
  1299. }
  1300. // CEnumVarHiPerfHiPerf methods
  1301. //***************************************************************************
  1302. //
  1303. // CEnumVarHiPerf::CEnumVarHiPerf
  1304. //
  1305. // DESCRIPTION:
  1306. //
  1307. // Constructor.
  1308. //
  1309. //***************************************************************************
  1310. CEnumVarHiPerf::CEnumVarHiPerf(CSWbemHiPerfObjectSet *pCSWbemHiPerfObjectSet) :
  1311. m_cRef (0),
  1312. m_iCount (0),
  1313. m_iPos (0),
  1314. m_ppIWbemObjectAccess (NULL),
  1315. m_pCSWbemHiPerfObjectSet (NULL)
  1316. {
  1317. if (pCSWbemHiPerfObjectSet)
  1318. {
  1319. m_pCSWbemHiPerfObjectSet = pCSWbemHiPerfObjectSet;
  1320. m_pCSWbemHiPerfObjectSet->AddRef ();
  1321. HRESULT hr = pCSWbemHiPerfObjectSet->ReadObjects (m_iCount,&m_ppIWbemObjectAccess);
  1322. }
  1323. InterlockedIncrement(&g_cObj);
  1324. }
  1325. //***************************************************************************
  1326. //
  1327. // CEnumVarHiPerf::~CEnumVarHiPerf
  1328. //
  1329. // DESCRIPTION:
  1330. //
  1331. // Destructor.
  1332. //
  1333. //***************************************************************************
  1334. CEnumVarHiPerf::~CEnumVarHiPerf(void)
  1335. {
  1336. InterlockedDecrement(&g_cObj);
  1337. if (m_pCSWbemHiPerfObjectSet)
  1338. m_pCSWbemHiPerfObjectSet->Release ();
  1339. if (m_ppIWbemObjectAccess)
  1340. delete [] m_ppIWbemObjectAccess;
  1341. }
  1342. //***************************************************************************
  1343. // HRESULT CEnumVarHiPerf::QueryInterface
  1344. // long CEnumVarHiPerf::AddRef
  1345. // long CEnumVarHiPerf::Release
  1346. //
  1347. // DESCRIPTION:
  1348. //
  1349. // Standard Com IUNKNOWN functions.
  1350. //
  1351. //***************************************************************************
  1352. STDMETHODIMP CEnumVarHiPerf::QueryInterface (
  1353. IN REFIID riid,
  1354. OUT LPVOID *ppv
  1355. )
  1356. {
  1357. *ppv=NULL;
  1358. if (IID_IUnknown==riid || IID_IEnumVARIANT==riid)
  1359. *ppv=this;
  1360. if (NULL!=*ppv)
  1361. {
  1362. ((LPUNKNOWN)*ppv)->AddRef();
  1363. return NOERROR;
  1364. }
  1365. return ResultFromScode(E_NOINTERFACE);
  1366. }
  1367. STDMETHODIMP_(ULONG) CEnumVarHiPerf::AddRef(void)
  1368. {
  1369. InterlockedIncrement(&m_cRef);
  1370. return m_cRef;
  1371. }
  1372. STDMETHODIMP_(ULONG) CEnumVarHiPerf::Release(void)
  1373. {
  1374. LONG cRef = InterlockedDecrement(&m_cRef);
  1375. if (0 != cRef)
  1376. {
  1377. _ASSERT(cRef > 0);
  1378. return cRef;
  1379. }
  1380. delete this;
  1381. return 0;
  1382. }
  1383. //***************************************************************************
  1384. //
  1385. // SCODE CEnumVarHiPerf::Next
  1386. //
  1387. // DESCRIPTION:
  1388. //
  1389. // Get the next object in the enumeration
  1390. //
  1391. // PARAMETERS:
  1392. //
  1393. // lTimeout Number of ms to wait for object (or WBEM_INFINITE for
  1394. // indefinite)
  1395. // ppObject On return may contain the next element (if any)
  1396. //
  1397. // RETURN VALUES:
  1398. //
  1399. // S_OK success
  1400. // S_FALSE not all elements could be returned
  1401. //
  1402. //***************************************************************************
  1403. HRESULT CEnumVarHiPerf::Next (
  1404. ULONG cElements,
  1405. VARIANT FAR* pVar,
  1406. ULONG FAR* pcElementFetched
  1407. )
  1408. {
  1409. HRESULT hr = S_OK;
  1410. ULONG l2 = 0;
  1411. if (NULL != pcElementFetched)
  1412. *pcElementFetched = 0;
  1413. if (NULL != pVar)
  1414. {
  1415. for (ULONG l = 0; l < cElements; l++)
  1416. VariantInit (&pVar [l]);
  1417. // Retrieve the next cElements elements.
  1418. for (l2 = 0; l2 < cElements; l2++)
  1419. {
  1420. CComPtr<IWbemClassObject> pIWbemClassObject;
  1421. if (m_iPos < m_iCount)
  1422. {
  1423. if (SUCCEEDED(hr = m_ppIWbemObjectAccess [m_iPos]->QueryInterface
  1424. (IID_IWbemClassObject, (void**) &pIWbemClassObject)))
  1425. {
  1426. m_iPos++;
  1427. // Make a new ISWbemObjectEx
  1428. CSWbemObject *pCSWbemObject = new CSWbemObject
  1429. (m_pCSWbemHiPerfObjectSet->GetSWbemServices (),
  1430. pIWbemClassObject);
  1431. ISWbemObjectEx *pISWbemObjectEx = NULL;
  1432. if (!pCSWbemObject)
  1433. hr = WBEM_E_OUT_OF_MEMORY;
  1434. else if (SUCCEEDED(hr = pCSWbemObject->QueryInterface (IID_ISWbemObjectEx,
  1435. (PPVOID) &pISWbemObjectEx)))
  1436. {
  1437. // Set the object into the variant array
  1438. pVar[l2].vt = VT_DISPATCH;
  1439. pVar[l2].pdispVal = pISWbemObjectEx;
  1440. }
  1441. else
  1442. {
  1443. delete pCSWbemObject;
  1444. hr = WBEM_E_FAILED;
  1445. }
  1446. }
  1447. if (FAILED(hr))
  1448. break;
  1449. }
  1450. else
  1451. break; // No more elements
  1452. }
  1453. if (NULL != pcElementFetched)
  1454. *pcElementFetched = l2;
  1455. SetWbemError (m_pCSWbemHiPerfObjectSet->GetSWbemServices ());
  1456. }
  1457. if (FAILED(hr))
  1458. return hr;
  1459. return (l2 < cElements) ? S_FALSE : S_OK;
  1460. }
  1461. //***************************************************************************
  1462. //
  1463. // SCODE CEnumVarHiPerf::Clone
  1464. //
  1465. // DESCRIPTION:
  1466. //
  1467. // Create a copy of this enumeration
  1468. //
  1469. // PARAMETERS:
  1470. //
  1471. // ppEnum on successful return addresses the clone
  1472. //
  1473. // RETURN VALUES:
  1474. //
  1475. // WBEM_S_NO_ERROR success
  1476. // WBEM_E_FAILED otherwise
  1477. //
  1478. //***************************************************************************
  1479. HRESULT CEnumVarHiPerf::Clone (
  1480. IEnumVARIANT **ppEnum
  1481. )
  1482. {
  1483. HRESULT hr = E_FAIL;
  1484. if (NULL != ppEnum)
  1485. {
  1486. *ppEnum = NULL;
  1487. CEnumVarHiPerf *pEnumVar = new CEnumVarHiPerf (m_pCSWbemHiPerfObjectSet);
  1488. if (!pEnumVar)
  1489. hr = WBEM_E_OUT_OF_MEMORY;
  1490. else if (FAILED(hr = pEnumVar->QueryInterface (IID_IEnumVARIANT, (PPVOID) ppEnum)))
  1491. delete pEnumVar;
  1492. SetWbemError (m_pCSWbemHiPerfObjectSet->GetSWbemServices ());
  1493. }
  1494. return hr;
  1495. }
  1496. //***************************************************************************
  1497. //
  1498. // SCODE CEnumVarHiPerf::Skip
  1499. //
  1500. // DESCRIPTION:
  1501. //
  1502. // Create a copy of this enumeration
  1503. //
  1504. // PARAMETERS:
  1505. //
  1506. // ppEnum on successful return addresses the clone
  1507. //
  1508. // RETURN VALUES:
  1509. //
  1510. // S_OK success
  1511. // S_FALSE end of sequence reached prematurely
  1512. //
  1513. //***************************************************************************
  1514. HRESULT CEnumVarHiPerf::Skip(
  1515. ULONG cElements
  1516. )
  1517. {
  1518. HRESULT hr = S_FALSE;
  1519. if (m_iPos + cElements > m_iCount)
  1520. m_iPos = m_iCount;
  1521. else
  1522. {
  1523. m_iPos += cElements;
  1524. hr = S_OK;
  1525. }
  1526. SetWbemError (m_pCSWbemHiPerfObjectSet->GetSWbemServices ());
  1527. return hr;
  1528. }