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.

860 lines
20 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. //
  5. // ENUMOBJ.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines the implementation of ISWbemObjectSet
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. //***************************************************************************
  14. //
  15. // CSWbemObjectSet::CSWbemObjectSet
  16. //
  17. // DESCRIPTION:
  18. //
  19. // Constructor.
  20. //
  21. //***************************************************************************
  22. CSWbemObjectSet::CSWbemObjectSet(CSWbemServices *pService,
  23. IEnumWbemClassObject *pIEnumWbemClassObject,
  24. CSWbemSecurity *pSecurity)
  25. : m_SecurityInfo (NULL),
  26. m_bIsEmpty (false)
  27. {
  28. m_Dispatch.SetObj (this, IID_ISWbemObjectSet,
  29. CLSID_SWbemObjectSet, L"SWbemObjectSet");
  30. m_cRef=0;
  31. m_firstEnumerator = true;
  32. m_pSWbemServices = pService;
  33. if (m_pSWbemServices)
  34. {
  35. m_pSWbemServices->AddRef ();
  36. if (pSecurity)
  37. m_SecurityInfo = new CSWbemSecurity (pIEnumWbemClassObject, pSecurity);
  38. else
  39. {
  40. pSecurity = m_pSWbemServices->GetSecurityInfo ();
  41. m_SecurityInfo = new CSWbemSecurity (pIEnumWbemClassObject, pSecurity);
  42. if (pSecurity)
  43. pSecurity->Release ();
  44. }
  45. }
  46. InterlockedIncrement(&g_cObj);
  47. }
  48. CSWbemObjectSet::CSWbemObjectSet (void)
  49. : m_SecurityInfo (NULL),
  50. m_cRef (0),
  51. m_firstEnumerator (true),
  52. m_bIsEmpty (true),
  53. m_pSWbemServices (NULL)
  54. {
  55. m_Dispatch.SetObj (this, IID_ISWbemObjectSet,
  56. CLSID_SWbemObjectSet, L"SWbemObjectSet");
  57. InterlockedIncrement(&g_cObj);
  58. }
  59. //***************************************************************************
  60. //
  61. // CSWbemObjectSet::~CSWbemObjectSet
  62. //
  63. // DESCRIPTION:
  64. //
  65. // Destructor.
  66. //
  67. //***************************************************************************
  68. CSWbemObjectSet::~CSWbemObjectSet(void)
  69. {
  70. InterlockedDecrement(&g_cObj);
  71. RELEASEANDNULL(m_pSWbemServices)
  72. RELEASEANDNULL(m_SecurityInfo)
  73. }
  74. //***************************************************************************
  75. // HRESULT CSWbemObjectSet::QueryInterface
  76. // long CSWbemObjectSet::AddRef
  77. // long CSWbemObjectSet::Release
  78. //
  79. // DESCRIPTION:
  80. //
  81. // Standard Com IUNKNOWN functions.
  82. //
  83. //***************************************************************************
  84. STDMETHODIMP CSWbemObjectSet::QueryInterface (
  85. IN REFIID riid,
  86. OUT LPVOID *ppv
  87. )
  88. {
  89. *ppv=NULL;
  90. if (IID_IUnknown==riid)
  91. *ppv = reinterpret_cast<IUnknown*>(this);
  92. else if (IID_ISWbemObjectSet==riid)
  93. *ppv = (ISWbemObjectSet *)this;
  94. else if (IID_IDispatch==riid)
  95. *ppv = (IDispatch *)this;
  96. else if (IID_ISupportErrorInfo==riid)
  97. *ppv = (ISupportErrorInfo *)this;
  98. else if (IID_IProvideClassInfo==riid)
  99. *ppv = (IProvideClassInfo *)this;
  100. if (NULL!=*ppv)
  101. {
  102. ((LPUNKNOWN)*ppv)->AddRef();
  103. return NOERROR;
  104. }
  105. return ResultFromScode(E_NOINTERFACE);
  106. }
  107. STDMETHODIMP_(ULONG) CSWbemObjectSet::AddRef(void)
  108. {
  109. InterlockedIncrement(&m_cRef);
  110. return m_cRef;
  111. }
  112. STDMETHODIMP_(ULONG) CSWbemObjectSet::Release(void)
  113. {
  114. LONG cRef = InterlockedDecrement(&m_cRef);
  115. if (0 != cRef)
  116. {
  117. _ASSERT(cRef > 0);
  118. return cRef;
  119. }
  120. delete this;
  121. return 0;
  122. }
  123. //***************************************************************************
  124. // HRESULT CSWbemObjectSet::InterfaceSupportsErrorInfo
  125. //
  126. // DESCRIPTION:
  127. //
  128. // Standard Com ISupportErrorInfo functions.
  129. //
  130. //***************************************************************************
  131. STDMETHODIMP CSWbemObjectSet::InterfaceSupportsErrorInfo (IN REFIID riid)
  132. {
  133. return (IID_ISWbemObjectSet == riid) ? S_OK : S_FALSE;
  134. }
  135. //***************************************************************************
  136. //
  137. // SCODE CSWbemObjectSet::Reset
  138. //
  139. // DESCRIPTION:
  140. //
  141. // Reset the enumeration
  142. //
  143. // PARAMETERS:
  144. //
  145. // RETURN VALUES:
  146. //
  147. // WBEM_S_NO_ERROR success
  148. // WBEM_E_FAILED otherwise
  149. //
  150. //***************************************************************************
  151. HRESULT CSWbemObjectSet::Reset ()
  152. {
  153. HRESULT hr = WBEM_E_FAILED;
  154. ResetLastErrors ();
  155. if (m_SecurityInfo)
  156. {
  157. IEnumWbemClassObject *pIEnumWbemClassObject =
  158. (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
  159. if (pIEnumWbemClassObject)
  160. {
  161. bool needToResetSecurity = false;
  162. HANDLE hThreadToken = NULL;
  163. if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken))
  164. hr = pIEnumWbemClassObject->Reset ();
  165. pIEnumWbemClassObject->Release ();
  166. if (needToResetSecurity)
  167. m_SecurityInfo->ResetSecurity (hThreadToken);
  168. }
  169. }
  170. if (FAILED(hr))
  171. m_Dispatch.RaiseException (hr);
  172. return hr;
  173. }
  174. //***************************************************************************
  175. //
  176. // SCODE CSWbemObjectSet::Next
  177. //
  178. // DESCRIPTION:
  179. //
  180. // Get the next object in the enumeration
  181. //
  182. // PARAMETERS:
  183. //
  184. // lTimeout Number of ms to wait for object (or WBEM_INFINITE for
  185. // indefinite)
  186. // ppObject On return may contain the next element (if any)
  187. //
  188. // RETURN VALUES:
  189. //
  190. // WBEM_S_NO_ERROR success
  191. // WBEM_E_FAILED otherwise
  192. //
  193. //***************************************************************************
  194. HRESULT CSWbemObjectSet::Next (
  195. long lTimeout,
  196. ISWbemObject **ppObject
  197. )
  198. {
  199. HRESULT hr = WBEM_E_FAILED;
  200. ResetLastErrors ();
  201. if (NULL == ppObject)
  202. hr = WBEM_E_INVALID_PARAMETER;
  203. else if (m_SecurityInfo)
  204. {
  205. IEnumWbemClassObject *pIEnumWbemClassObject =
  206. (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
  207. if (pIEnumWbemClassObject)
  208. {
  209. *ppObject = NULL;
  210. IWbemClassObject *pIWbemClassObject = NULL;
  211. ULONG returned = 0;
  212. bool needToResetSecurity = false;
  213. HANDLE hThreadToken = NULL;
  214. if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken))
  215. hr = pIEnumWbemClassObject->Next (lTimeout, 1, &pIWbemClassObject, &returned);
  216. if (needToResetSecurity)
  217. m_SecurityInfo->ResetSecurity (hThreadToken);
  218. if (SUCCEEDED(hr) && (0 < returned) && pIWbemClassObject)
  219. {
  220. CSWbemObject *pObject = new CSWbemObject (m_pSWbemServices, pIWbemClassObject,
  221. m_SecurityInfo);
  222. if (!pObject)
  223. hr = WBEM_E_OUT_OF_MEMORY;
  224. else if (FAILED(hr = pObject->QueryInterface (IID_ISWbemObject,
  225. (PPVOID) ppObject)))
  226. delete pObject;
  227. pIWbemClassObject->Release ();
  228. }
  229. else if (WBEM_S_TIMEDOUT == hr)
  230. {
  231. /*
  232. * Since a timeout would be indistinguishable from an end-of-enumeration
  233. * we flag it as a real error rather than an S-CODE.
  234. */
  235. hr = wbemErrTimedout;
  236. }
  237. SetWbemError (m_pSWbemServices);
  238. pIEnumWbemClassObject->Release ();
  239. }
  240. }
  241. if (FAILED(hr))
  242. m_Dispatch.RaiseException (hr);
  243. return hr;
  244. }
  245. //***************************************************************************
  246. //
  247. // SCODE CSWbemObjectSet::Clone
  248. //
  249. // DESCRIPTION:
  250. //
  251. // Create a copy of this enumeration
  252. //
  253. // PARAMETERS:
  254. //
  255. // ppEnum on successful return addresses the clone
  256. //
  257. // RETURN VALUES:
  258. //
  259. // WBEM_S_NO_ERROR success
  260. // WBEM_E_FAILED otherwise
  261. //
  262. //***************************************************************************
  263. HRESULT CSWbemObjectSet::Clone (
  264. ISWbemObjectSet **ppEnum
  265. )
  266. {
  267. HRESULT hr = WBEM_E_FAILED;
  268. ResetLastErrors ();
  269. if (NULL == ppEnum)
  270. hr = WBEM_E_INVALID_PARAMETER;
  271. else if (m_SecurityInfo)
  272. {
  273. IEnumWbemClassObject *pIEnumWbemClassObject =
  274. (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
  275. if (pIEnumWbemClassObject)
  276. {
  277. *ppEnum = NULL;
  278. IEnumWbemClassObject *pIWbemEnum = NULL;
  279. bool needToResetSecurity = false;
  280. HANDLE hThreadToken = NULL;
  281. if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken))
  282. hr = pIEnumWbemClassObject->Clone (&pIWbemEnum);
  283. if (needToResetSecurity)
  284. m_SecurityInfo->ResetSecurity (hThreadToken);
  285. if (WBEM_S_NO_ERROR == hr)
  286. {
  287. CSWbemObjectSet *pEnum = new CSWbemObjectSet (m_pSWbemServices, pIWbemEnum,
  288. m_SecurityInfo);
  289. if (!pEnum)
  290. hr = WBEM_E_OUT_OF_MEMORY;
  291. else if (FAILED(hr = pEnum->QueryInterface (IID_ISWbemObjectSet, (PPVOID) ppEnum)))
  292. delete pEnum;
  293. pIWbemEnum->Release ();
  294. }
  295. SetWbemError (m_pSWbemServices);
  296. pIEnumWbemClassObject->Release ();
  297. }
  298. }
  299. if (FAILED(hr))
  300. m_Dispatch.RaiseException (hr);
  301. return hr;
  302. }
  303. //***************************************************************************
  304. //
  305. // SCODE CSWbemObjectSet::Skip
  306. //
  307. // DESCRIPTION:
  308. //
  309. // Skip over some objects in the enumeration
  310. //
  311. // PARAMETERS:
  312. //
  313. // lElements Number of elements to skip
  314. // lTimeout Number of ms to wait for object (or WBEM_INFINITE for
  315. // indefinite)
  316. //
  317. // RETURN VALUES:
  318. //
  319. // S_OK success
  320. // S_FALSE otherwise
  321. //
  322. //***************************************************************************
  323. HRESULT CSWbemObjectSet::Skip (
  324. ULONG lElements,
  325. long lTimeout
  326. )
  327. {
  328. HRESULT hr = WBEM_E_FAILED;
  329. ResetLastErrors ();
  330. if (m_SecurityInfo)
  331. {
  332. IEnumWbemClassObject *pIEnumWbemClassObject =
  333. (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
  334. if (pIEnumWbemClassObject)
  335. {
  336. bool needToResetSecurity = false;
  337. HANDLE hThreadToken = NULL;
  338. if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken))
  339. hr = pIEnumWbemClassObject->Skip (lTimeout, lElements);
  340. if (needToResetSecurity)
  341. m_SecurityInfo->ResetSecurity (hThreadToken);
  342. /*
  343. * Since a timeout would be indistinguishable from an end-of-enumeration
  344. * we flag it as a real error rather than an S-CODE.
  345. */
  346. if (WBEM_S_TIMEDOUT == hr)
  347. hr = wbemErrTimedout;
  348. SetWbemError (m_pSWbemServices);
  349. pIEnumWbemClassObject->Release ();
  350. }
  351. }
  352. if (FAILED(hr))
  353. m_Dispatch.RaiseException (hr);
  354. return hr;
  355. }
  356. //***************************************************************************
  357. //
  358. // SCODE CSWbemObjectSet::get__NewEnum
  359. //
  360. // DESCRIPTION:
  361. //
  362. // Return an IEnumVARIANT-supporting interface for collections
  363. //
  364. // PARAMETERS:
  365. //
  366. // ppUnk on successful return addresses the IUnknown interface
  367. //
  368. // RETURN VALUES:
  369. //
  370. // S_OK success
  371. // E_FAIL otherwise
  372. //
  373. //***************************************************************************
  374. HRESULT CSWbemObjectSet::get__NewEnum (
  375. IUnknown **ppUnk
  376. )
  377. {
  378. HRESULT hr = E_FAIL;
  379. ResetLastErrors ();
  380. if (NULL != ppUnk)
  381. {
  382. *ppUnk = NULL;
  383. CEnumVar *pEnumVar = NULL;
  384. if (m_bIsEmpty)
  385. {
  386. if (!(pEnumVar = new CEnumVar ()))
  387. hr = WBEM_E_OUT_OF_MEMORY;
  388. }
  389. else
  390. {
  391. /*
  392. * If this is the first enumerator, use ourselves as the underlying
  393. * iterator. Otherwise clone a copy and use that.
  394. */
  395. if (m_firstEnumerator)
  396. {
  397. if (!(pEnumVar = new CEnumVar (this)))
  398. hr = WBEM_E_OUT_OF_MEMORY;
  399. else
  400. m_firstEnumerator = false;
  401. }
  402. else
  403. {
  404. CSWbemObjectSet *pNewEnum = NULL;
  405. /*
  406. * Try to reset the cloned enumerator. This may not always
  407. * succeed, as some IEnumWbemClassObject's may not be
  408. * rewindable.
  409. */
  410. if (SUCCEEDED (CloneObjectSet (&pNewEnum)))
  411. {
  412. HRESULT hr2 = pNewEnum->Reset ();
  413. if (!(pEnumVar = new CEnumVar (pNewEnum)))
  414. hr = WBEM_E_OUT_OF_MEMORY;
  415. pNewEnum->Release ();
  416. }
  417. }
  418. }
  419. if (pEnumVar)
  420. if (FAILED(hr = pEnumVar->QueryInterface (IID_IUnknown, (PPVOID) ppUnk)))
  421. delete pEnumVar;
  422. }
  423. if (FAILED(hr))
  424. m_Dispatch.RaiseException (hr);
  425. return hr;
  426. }
  427. //***************************************************************************
  428. //
  429. // SCODE CSWbemObjectSet::get_Count
  430. //
  431. // DESCRIPTION:
  432. //
  433. // Return the number of items in the collection
  434. //
  435. // PARAMETERS:
  436. //
  437. // plCount on successful return addresses the count
  438. //
  439. // RETURN VALUES:
  440. //
  441. // S_OK success
  442. // E_FAIL otherwise
  443. //
  444. //***************************************************************************
  445. HRESULT CSWbemObjectSet::get_Count (
  446. long *plCount
  447. )
  448. {
  449. HRESULT hr = E_FAIL;
  450. ResetLastErrors ();
  451. if (NULL != plCount)
  452. {
  453. *plCount = 0;
  454. if (m_bIsEmpty)
  455. hr = WBEM_S_NO_ERROR;
  456. else if (m_SecurityInfo)
  457. {
  458. IEnumWbemClassObject *pIEnumWbemClassObject =
  459. (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
  460. if (pIEnumWbemClassObject)
  461. {
  462. /*
  463. * Work out the current count - clone the object to avoid messing
  464. * with the iterator.
  465. */
  466. IEnumWbemClassObject *pNewEnum = NULL;
  467. bool needToResetSecurity = false;
  468. HANDLE hThreadToken = NULL;
  469. if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken))
  470. {
  471. if (WBEM_S_NO_ERROR == pIEnumWbemClassObject->Clone (&pNewEnum))
  472. {
  473. // Secure the enumerator
  474. m_SecurityInfo->SecureInterface (pNewEnum);
  475. /*
  476. * This will fail if the enumerator was created with the
  477. * WBEM_FLAG_FORWARD_ONLY option.
  478. */
  479. if (WBEM_S_NO_ERROR == pNewEnum->Reset ())
  480. {
  481. IWbemClassObject *pObject = NULL;
  482. ULONG lReturned = 0;
  483. HRESULT hrEnum;
  484. // Iterate through the enumerator to count the elements
  485. while (SUCCEEDED(hrEnum = pNewEnum->Next (INFINITE, 1, &pObject, &lReturned)))
  486. {
  487. if (0 == lReturned)
  488. break; // We are done
  489. // Getting here means we have at least one object returned
  490. (*plCount) ++;
  491. pObject->Release ();
  492. }
  493. if (SUCCEEDED(hrEnum))
  494. hr = S_OK;
  495. else
  496. hr = hrEnum;
  497. }
  498. pNewEnum->Release ();
  499. }
  500. }
  501. if (needToResetSecurity)
  502. m_SecurityInfo->ResetSecurity (hThreadToken);
  503. pIEnumWbemClassObject->Release ();
  504. }
  505. }
  506. }
  507. if (FAILED(hr))
  508. m_Dispatch.RaiseException (hr);
  509. return hr;
  510. }
  511. //***************************************************************************
  512. //
  513. // SCODE CSWbemObjectSet::Item
  514. //
  515. // DESCRIPTION:
  516. //
  517. // Get object from the enumeration by path.
  518. //
  519. // PARAMETERS:
  520. //
  521. // bsObjectPath The path of the object to retrieve
  522. // lFlags Flags
  523. // ppNamedObject On successful return addresses the object
  524. //
  525. // RETURN VALUES:
  526. //
  527. // WBEM_S_NO_ERROR success
  528. // WBEM_E_INVALID_PARAMETER bad input parameters
  529. // WBEM_E_FAILED otherwise
  530. //
  531. //***************************************************************************
  532. HRESULT CSWbemObjectSet::Item (
  533. BSTR bsObjectPath,
  534. long lFlags,
  535. ISWbemObject **ppObject
  536. )
  537. {
  538. HRESULT hr = WBEM_E_FAILED;
  539. ResetLastErrors ();
  540. if ((NULL == ppObject) || (NULL == bsObjectPath))
  541. hr = WBEM_E_INVALID_PARAMETER;
  542. else if (!m_bIsEmpty)
  543. {
  544. CWbemPathCracker objectPath;
  545. if (objectPath = bsObjectPath)
  546. {
  547. if (m_SecurityInfo)
  548. {
  549. IEnumWbemClassObject *pIEnumWbemClassObject =
  550. (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
  551. if (pIEnumWbemClassObject)
  552. {
  553. /*
  554. * Try to find the object - clone the object to avoid messing
  555. * with the iterator.
  556. */
  557. IEnumWbemClassObject *pNewEnum = NULL;
  558. bool needToResetSecurity = false;
  559. HANDLE hThreadToken = NULL;
  560. if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken))
  561. {
  562. if (WBEM_S_NO_ERROR == pIEnumWbemClassObject->Clone (&pNewEnum))
  563. {
  564. // Secure the enumerator
  565. m_SecurityInfo->SecureInterface (pNewEnum);
  566. /*
  567. * This will fail if the enumerator was created with the
  568. * WBEM_FLAG_FORWARD_ONLY option.
  569. */
  570. if (WBEM_S_NO_ERROR == pNewEnum->Reset ())
  571. {
  572. CComPtr<IWbemClassObject> pIWbemClassObject;
  573. ULONG lReturned = 0;
  574. bool found = false;
  575. hr = WBEM_E_NOT_FOUND;
  576. // Iterate through the enumerator to try to find the element with the
  577. // specified path.
  578. while (!found &&
  579. (WBEM_S_NO_ERROR == pNewEnum->Next (INFINITE, 1, &pIWbemClassObject, &lReturned)))
  580. {
  581. // Getting here means we have at least one object returned; check the
  582. // path
  583. if (CSWbemObjectPath::CompareObjectPaths (pIWbemClassObject, objectPath))
  584. {
  585. // Found it - assign to passed interface and break out
  586. found = true;
  587. CSWbemObject *pObject = new CSWbemObject (m_pSWbemServices,
  588. pIWbemClassObject, m_SecurityInfo);
  589. if (!pObject)
  590. hr = WBEM_E_OUT_OF_MEMORY;
  591. else if (FAILED(pObject->QueryInterface (IID_ISWbemObject,
  592. (PPVOID) ppObject)))
  593. {
  594. hr = WBEM_E_FAILED;
  595. delete pObject;
  596. }
  597. }
  598. pIWbemClassObject.Release();
  599. }
  600. if (found)
  601. hr = S_OK;
  602. }
  603. pNewEnum->Release ();
  604. }
  605. }
  606. // Restore original privileges on this thread
  607. if (needToResetSecurity)
  608. m_SecurityInfo->ResetSecurity (hThreadToken);
  609. pIEnumWbemClassObject->Release ();
  610. }
  611. }
  612. }
  613. }
  614. if (FAILED(hr))
  615. m_Dispatch.RaiseException (hr);
  616. return hr;
  617. }
  618. //***************************************************************************
  619. //
  620. // SCODE CSWbemObjectSet::get_Security_
  621. //
  622. // DESCRIPTION:
  623. //
  624. // Return the security configurator
  625. //
  626. // WBEM_S_NO_ERROR success
  627. // WBEM_E_INVALID_PARAMETER bad input parameters
  628. // WBEM_E_FAILED otherwise
  629. //
  630. //***************************************************************************
  631. HRESULT CSWbemObjectSet::get_Security_ (
  632. ISWbemSecurity **ppSecurity
  633. )
  634. {
  635. HRESULT hr = WBEM_E_FAILED;
  636. ResetLastErrors ();
  637. if (NULL == ppSecurity)
  638. hr = WBEM_E_INVALID_PARAMETER;
  639. else // Bug ID 566345
  640. {
  641. *ppSecurity = NULL;
  642. if (m_SecurityInfo)
  643. {
  644. *ppSecurity = m_SecurityInfo;
  645. (*ppSecurity)->AddRef ();
  646. hr = WBEM_S_NO_ERROR;
  647. }
  648. }
  649. if (FAILED(hr))
  650. m_Dispatch.RaiseException (hr);
  651. return hr;
  652. }
  653. //***************************************************************************
  654. //
  655. // SCODE CSWbemObjectSet::CloneObjectSet
  656. //
  657. // DESCRIPTION:
  658. //
  659. // Create a copy of this enumeration, returning a coclass not an interface
  660. //
  661. // PARAMETERS:
  662. //
  663. // ppEnum on successful return addresses the clone
  664. //
  665. // RETURN VALUES:
  666. //
  667. // WBEM_S_NO_ERROR success
  668. // WBEM_E_FAILED otherwise
  669. //
  670. //***************************************************************************
  671. HRESULT CSWbemObjectSet::CloneObjectSet (
  672. CSWbemObjectSet **ppEnum
  673. )
  674. {
  675. HRESULT hr = WBEM_E_FAILED;
  676. ResetLastErrors ();
  677. if (NULL == ppEnum)
  678. hr = WBEM_E_INVALID_PARAMETER;
  679. else
  680. {
  681. *ppEnum = NULL;
  682. if (m_SecurityInfo)
  683. {
  684. IEnumWbemClassObject *pIEnumWbemClassObject =
  685. (IEnumWbemClassObject *) m_SecurityInfo->GetProxy ();
  686. if (pIEnumWbemClassObject)
  687. {
  688. IEnumWbemClassObject *pIWbemEnum = NULL;
  689. bool needToResetSecurity = false;
  690. HANDLE hThreadToken = NULL;
  691. if (m_SecurityInfo->SetSecurity (needToResetSecurity, hThreadToken))
  692. hr = pIEnumWbemClassObject->Clone (&pIWbemEnum);
  693. if (needToResetSecurity)
  694. m_SecurityInfo->ResetSecurity (hThreadToken);
  695. if (WBEM_S_NO_ERROR == hr)
  696. {
  697. *ppEnum = new CSWbemObjectSet (m_pSWbemServices, pIWbemEnum,
  698. m_SecurityInfo);
  699. if (!(*ppEnum))
  700. hr = WBEM_E_OUT_OF_MEMORY;
  701. else
  702. (*ppEnum)->AddRef ();
  703. pIWbemEnum->Release ();
  704. }
  705. SetWbemError (m_pSWbemServices);
  706. pIEnumWbemClassObject->Release ();
  707. }
  708. }
  709. }
  710. if (FAILED(hr))
  711. m_Dispatch.RaiseException (hr);
  712. return hr;
  713. }