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.

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