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

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