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.

706 lines
15 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. //
  5. // SOBJPATH.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines the implementation of ISWbemObjectPathEx
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. ///***************************************************************************
  14. //
  15. // CSWbemObjectPathComponents::CSWbemObjectPathComponents
  16. //
  17. // DESCRIPTION:
  18. //
  19. // Constructor.
  20. //
  21. //***************************************************************************
  22. CSWbemObjectPathComponents::CSWbemObjectPathComponents(
  23. CWbemPathCracker *pCWbemPathCracker,
  24. bool bMutable
  25. ) : m_cRef (0),
  26. m_pCWbemPathCracker (pCWbemPathCracker),
  27. m_bMutable (bMutable)
  28. {
  29. m_Dispatch.SetObj (this, IID_ISWbemObjectPathComponents,
  30. CLSID_SWbemObjectPathComponents, L"SWbemObjectPathComponents");
  31. if (m_pCWbemPathCracker)
  32. m_pCWbemPathCracker->AddRef ();
  33. InterlockedIncrement(&g_cObj);
  34. }
  35. CSWbemObjectPathComponents::CSWbemObjectPathComponents(
  36. const BSTR & bsPath,
  37. bool bMutable
  38. ) : m_cRef (0),
  39. m_pCWbemPathCracker (NULL),
  40. m_bMutable (bMutable)
  41. {
  42. m_Dispatch.SetObj (this, IID_ISWbemObjectPathComponents,
  43. CLSID_SWbemObjectPathComponents, L"SWbemObjectPathComponents");
  44. m_pCWbemPathCracker = new CWbemPathCracker (bsPath);
  45. if (m_pCWbemPathCracker)
  46. m_pCWbemPathCracker->AddRef ();
  47. InterlockedIncrement(&g_cObj);
  48. }
  49. //***************************************************************************
  50. //
  51. // CSWbemObjectPathComponents::~CSWbemObjectPathComponents
  52. //
  53. // DESCRIPTION:
  54. //
  55. // Destructor.
  56. //
  57. //***************************************************************************
  58. CSWbemObjectPathComponents::~CSWbemObjectPathComponents(void)
  59. {
  60. RELEASEANDNULL(m_pCWbemPathCracker)
  61. InterlockedDecrement(&g_cObj);
  62. }
  63. //***************************************************************************
  64. // HRESULT CSWbemObjectPathComponents::QueryInterface
  65. // long CSWbemObjectPathComponents::AddRef
  66. // long CSWbemObjectPathComponents::Release
  67. //
  68. // DESCRIPTION:
  69. //
  70. // Standard Com IUNKNOWN functions.
  71. //
  72. //***************************************************************************
  73. STDMETHODIMP CSWbemObjectPathComponents::QueryInterface (
  74. IN REFIID riid,
  75. OUT LPVOID *ppv
  76. )
  77. {
  78. *ppv=NULL;
  79. if (IID_IUnknown==riid)
  80. *ppv = reinterpret_cast<IUnknown*>(this);
  81. else if (IID_ISWbemObjectPathComponents==riid)
  82. *ppv = (ISWbemObjectPathComponents *)this;
  83. else if (IID_IDispatch==riid)
  84. *ppv = (IDispatch *)this;
  85. else if (IID_ISupportErrorInfo==riid)
  86. *ppv = (ISupportErrorInfo *)this;
  87. else if (IID_IProvideClassInfo==riid)
  88. *ppv = (IProvideClassInfo *)this;
  89. if (NULL!=*ppv)
  90. {
  91. ((LPUNKNOWN)*ppv)->AddRef();
  92. return NOERROR;
  93. }
  94. return ResultFromScode(E_NOINTERFACE);
  95. }
  96. STDMETHODIMP_(ULONG) CSWbemObjectPathComponents::AddRef(void)
  97. {
  98. InterlockedIncrement(&m_cRef);
  99. return m_cRef;
  100. }
  101. STDMETHODIMP_(ULONG) CSWbemObjectPathComponents::Release(void)
  102. {
  103. InterlockedDecrement(&m_cRef);
  104. if (0L!=m_cRef)
  105. return m_cRef;
  106. delete this;
  107. return 0;
  108. }
  109. //***************************************************************************
  110. //
  111. // SCODE CSWbemObjectPathComponents::get__NewEnum
  112. //
  113. // DESCRIPTION:
  114. //
  115. // Return an IEnumVARIANT-supporting interface for collections
  116. //
  117. // PARAMETERS:
  118. //
  119. // ppUnk on successful return addresses the IUnknown interface
  120. //
  121. // RETURN VALUES:
  122. //
  123. // S_OK success
  124. // E_FAIL otherwise
  125. //
  126. //***************************************************************************
  127. HRESULT CSWbemObjectPathComponents::get__NewEnum (
  128. IUnknown **ppUnk
  129. )
  130. {
  131. HRESULT hr = E_FAIL;
  132. ResetLastErrors ();
  133. if (NULL != ppUnk)
  134. {
  135. *ppUnk = NULL;
  136. CEnumObjectPathComponent *pEnumObjectPathComponent =
  137. new CEnumObjectPathComponent (m_pCWbemPathCracker, m_bMutable);
  138. if (!pEnumObjectPathComponent)
  139. hr = WBEM_E_OUT_OF_MEMORY;
  140. else if (FAILED(hr = pEnumObjectPathComponent->QueryInterface (IID_IUnknown, (PPVOID) ppUnk)))
  141. delete pEnumObjectPathComponent;
  142. }
  143. if (FAILED(hr))
  144. m_Dispatch.RaiseException (hr);
  145. return hr;
  146. }
  147. //***************************************************************************
  148. //
  149. // SCODE CSWbemObjectPathComponents::get_Count
  150. //
  151. // DESCRIPTION:
  152. //
  153. // Return the number of items in the collection
  154. //
  155. // PARAMETERS:
  156. //
  157. // plCount on successful return addresses the count
  158. //
  159. // RETURN VALUES:
  160. //
  161. // S_OK success
  162. // E_FAIL otherwise
  163. //
  164. //***************************************************************************
  165. HRESULT CSWbemObjectPathComponents::get_Count (
  166. long *plCount
  167. )
  168. {
  169. HRESULT hr = E_FAIL;
  170. ResetLastErrors ();
  171. if (NULL == plCount)
  172. hr = WBEM_E_INVALID_PARAMETER;
  173. else if (m_pCWbemPathCracker)
  174. {
  175. ULONG lCount = 0;
  176. if (m_pCWbemPathCracker->GetComponentCount (lCount))
  177. {
  178. *plCount = lCount;
  179. hr = WBEM_S_NO_ERROR;
  180. }
  181. }
  182. if (FAILED(hr))
  183. m_Dispatch.RaiseException (hr);
  184. return hr;
  185. }
  186. //***************************************************************************
  187. //
  188. // SCODE CSWbemObjectPathComponents::Add
  189. //
  190. // DESCRIPTION:
  191. //
  192. // Add a single scope element to the list
  193. //
  194. // PARAMETERS:
  195. //
  196. // bsScopePath path form of scope element
  197. // iIndex index for insertion (-1 is at the end)
  198. // ppISWbemScopeElement addresses the SWbemScopeElement on successful return
  199. //
  200. // RETURN VALUES:
  201. //
  202. // WBEM_S_NO_ERROR success
  203. // WBEM_E_INVALID_PARAMETER bad input parameters
  204. // WBEM_E_NOT_FOUND index out of range
  205. // WBEM_E_FAILED otherwise
  206. //
  207. //***************************************************************************
  208. HRESULT CSWbemObjectPathComponents::Add (
  209. BSTR bsComponent,
  210. long iIndex
  211. )
  212. {
  213. HRESULT hr = WBEM_E_FAILED;
  214. ResetLastErrors ();
  215. if (NULL == bsComponent)
  216. hr = WBEM_E_INVALID_PARAMETER;
  217. else if (!m_bMutable)
  218. hr = WBEM_E_READ_ONLY;
  219. else if (m_pCWbemPathCracker)
  220. {
  221. if (m_pCWbemPathCracker->AddComponent (iIndex, bsComponent))
  222. hr = WBEM_S_NO_ERROR;
  223. }
  224. if (FAILED(hr))
  225. m_Dispatch.RaiseException (hr);
  226. return hr;
  227. }
  228. //***************************************************************************
  229. //
  230. // SCODE CSWbemObjectPathComponents::Set
  231. //
  232. // DESCRIPTION:
  233. //
  234. // Change an existing component in the list
  235. //
  236. // PARAMETERS:
  237. //
  238. // bsScopePath path form of component
  239. // iIndex index (-1 is at the end)
  240. //
  241. // RETURN VALUES:
  242. //
  243. // WBEM_S_NO_ERROR success
  244. // WBEM_E_INVALID_PARAMETER bad input parameters
  245. // WBEM_E_NOT_FOUND index out of range
  246. // WBEM_E_FAILED otherwise
  247. //
  248. //***************************************************************************
  249. HRESULT CSWbemObjectPathComponents::Set (
  250. BSTR bsComponent,
  251. long iIndex
  252. )
  253. {
  254. HRESULT hr = WBEM_E_FAILED;
  255. ResetLastErrors ();
  256. if (NULL == bsComponent)
  257. hr = WBEM_E_INVALID_PARAMETER;
  258. else if (!m_bMutable)
  259. hr = WBEM_E_READ_ONLY;
  260. else if (m_pCWbemPathCracker)
  261. {
  262. if (m_pCWbemPathCracker->SetComponent (iIndex, bsComponent))
  263. hr = WBEM_S_NO_ERROR;
  264. }
  265. if (FAILED(hr))
  266. m_Dispatch.RaiseException (hr);
  267. return hr;
  268. }
  269. //***************************************************************************
  270. //
  271. // SCODE CSWbemObjectPathComponents::Remove
  272. //
  273. // DESCRIPTION:
  274. //
  275. // Remove element from scope list
  276. //
  277. // PARAMETERS:
  278. //
  279. // iIndex Index of object to retrieve (default -1)
  280. //
  281. // RETURN VALUES:
  282. //
  283. // WBEM_S_NO_ERROR success
  284. // WBEM_E_INVALID_PARAMETER bad input parameters
  285. // WBEM_E_NOT_FOUND index out of range
  286. // WBEM_E_FAILED otherwise
  287. //
  288. //***************************************************************************
  289. HRESULT CSWbemObjectPathComponents::Remove (
  290. long iIndex
  291. )
  292. {
  293. HRESULT hr = WBEM_E_FAILED;
  294. ResetLastErrors ();
  295. if (!m_bMutable)
  296. hr = WBEM_E_READ_ONLY;
  297. else if (m_pCWbemPathCracker)
  298. {
  299. if (m_pCWbemPathCracker->RemoveComponent (iIndex))
  300. hr = WBEM_S_NO_ERROR;
  301. else
  302. hr = wbemErrValueOutOfRange;
  303. }
  304. if (FAILED(hr))
  305. m_Dispatch.RaiseException (hr);
  306. return hr;
  307. }
  308. //***************************************************************************
  309. //
  310. // SCODE CSWbemObjectPathComponents::DeleteAll
  311. //
  312. // DESCRIPTION:
  313. //
  314. // Remove all elements from the scope
  315. //
  316. // PARAMETERS:
  317. //
  318. // none
  319. //
  320. // RETURN VALUES:
  321. //
  322. // WBEM_S_NO_ERROR success
  323. // WBEM_E_INVALID_PARAMETER bad input parameters
  324. // WBEM_E_NOT_FOUND index out of range
  325. // WBEM_E_FAILED otherwise
  326. //
  327. //***************************************************************************
  328. HRESULT CSWbemObjectPathComponents::DeleteAll (
  329. )
  330. {
  331. HRESULT hr = WBEM_E_FAILED;
  332. ResetLastErrors ();
  333. if (!m_bMutable)
  334. hr = WBEM_E_READ_ONLY;
  335. else if (m_pCWbemPathCracker)
  336. {
  337. if (m_pCWbemPathCracker->RemoveAllComponents ())
  338. hr = WBEM_S_NO_ERROR;
  339. }
  340. return hr;
  341. }
  342. //***************************************************************************
  343. //
  344. // SCODE CSWbemObjectPathComponents::Item
  345. //
  346. // DESCRIPTION:
  347. //
  348. // Get element from the list by index.
  349. //
  350. // PARAMETERS:
  351. //
  352. // iIndex Index of object to retrieve
  353. // lFlags Flags
  354. // ppSWbemScopeElement On successful return addresses the object
  355. //
  356. // RETURN VALUES:
  357. //
  358. // WBEM_S_NO_ERROR success
  359. // WBEM_E_INVALID_PARAMETER bad input parameters
  360. // WBEM_E_NOT_FOUND index out of range
  361. // WBEM_E_FAILED otherwise
  362. //
  363. //***************************************************************************
  364. HRESULT CSWbemObjectPathComponents::Item (
  365. long iIndex,
  366. BSTR *pbsComponent
  367. )
  368. {
  369. HRESULT hr = WBEM_E_NOT_FOUND;
  370. ResetLastErrors ();
  371. if ((NULL == pbsComponent) || (0 > iIndex))
  372. hr = WBEM_E_INVALID_PARAMETER;
  373. else if (m_pCWbemPathCracker)
  374. {
  375. CComBSTR bsComponent;
  376. if (m_pCWbemPathCracker->GetComponent (iIndex, bsComponent))
  377. {
  378. *pbsComponent = bsComponent.Detach ();
  379. hr = WBEM_S_NO_ERROR;
  380. }
  381. }
  382. if (FAILED(hr))
  383. m_Dispatch.RaiseException (hr);
  384. return hr;
  385. }
  386. // CEnumObjectPathComponent Methods
  387. //***************************************************************************
  388. //
  389. // CEnumObjectPathComponent::CEnumObjectPathComponent
  390. //
  391. // DESCRIPTION:
  392. //
  393. // Constructor.
  394. //
  395. //***************************************************************************
  396. CEnumObjectPathComponent::CEnumObjectPathComponent(
  397. CWbemPathCracker *pCWbemPathCracker,
  398. bool bMutable
  399. )
  400. : m_cRef (0),
  401. m_iIndex (0),
  402. m_pCWbemPathCracker (pCWbemPathCracker),
  403. m_bMutable (bMutable)
  404. {
  405. if (m_pCWbemPathCracker)
  406. m_pCWbemPathCracker->AddRef ();
  407. InterlockedIncrement(&g_cObj);
  408. }
  409. //***************************************************************************
  410. //
  411. // CEnumObjectPathComponent::~CEnumObjectPathComponent
  412. //
  413. // DESCRIPTION:
  414. //
  415. // Destructor.
  416. //
  417. //***************************************************************************
  418. CEnumObjectPathComponent::~CEnumObjectPathComponent(void)
  419. {
  420. InterlockedDecrement(&g_cObj);
  421. RELEASEANDNULL(m_pCWbemPathCracker)
  422. }
  423. //***************************************************************************
  424. // HRESULT CEnumObjectPathComponent::QueryInterface
  425. // long CEnumObjectPathComponent::AddRef
  426. // long CEnumObjectPathComponent::Release
  427. //
  428. // DESCRIPTION:
  429. //
  430. // Standard Com IUNKNOWN functions.
  431. //
  432. //***************************************************************************
  433. STDMETHODIMP CEnumObjectPathComponent::QueryInterface (
  434. IN REFIID riid,
  435. OUT LPVOID *ppv
  436. )
  437. {
  438. *ppv=NULL;
  439. if (IID_IUnknown==riid || IID_IEnumVARIANT==riid)
  440. *ppv=this;
  441. if (NULL!=*ppv)
  442. {
  443. ((LPUNKNOWN)*ppv)->AddRef();
  444. return NOERROR;
  445. }
  446. return ResultFromScode(E_NOINTERFACE);
  447. }
  448. STDMETHODIMP_(ULONG) CEnumObjectPathComponent::AddRef(void)
  449. {
  450. long l = InterlockedIncrement(&m_cRef);
  451. return l;
  452. }
  453. STDMETHODIMP_(ULONG) CEnumObjectPathComponent::Release(void)
  454. {
  455. long l = InterlockedDecrement(&m_cRef);
  456. if (0L!=l)
  457. return l;
  458. delete this;
  459. return 0;
  460. }
  461. //***************************************************************************
  462. //
  463. // SCODE CEnumObjectPathComponent::Reset
  464. //
  465. // DESCRIPTION:
  466. //
  467. // Reset the enumeration
  468. //
  469. // PARAMETERS:
  470. //
  471. // RETURN VALUES:
  472. //
  473. // S_OK success
  474. // S_FALSE otherwise
  475. //
  476. //***************************************************************************
  477. HRESULT CEnumObjectPathComponent::Reset ()
  478. {
  479. m_iIndex = 0;
  480. return S_OK;
  481. }
  482. //***************************************************************************
  483. //
  484. // SCODE CEnumObjectPathComponent::Next
  485. //
  486. // DESCRIPTION:
  487. //
  488. // Get the next object in the enumeration
  489. //
  490. // PARAMETERS:
  491. //
  492. // lTimeout Number of ms to wait for object (or WBEM_INFINITE for
  493. // indefinite)
  494. // ppObject On return may contain the next element (if any)
  495. //
  496. // RETURN VALUES:
  497. //
  498. // S_OK success
  499. // S_FALSE not all elements could be returned
  500. //
  501. //***************************************************************************
  502. HRESULT CEnumObjectPathComponent::Next (
  503. ULONG cElements,
  504. VARIANT FAR* pVar,
  505. ULONG FAR* pcElementFetched
  506. )
  507. {
  508. HRESULT hr = S_OK;
  509. ULONG l2 = 0;
  510. if (NULL != pcElementFetched)
  511. *pcElementFetched = 0;
  512. if ((NULL != pVar) && (m_pCWbemPathCracker))
  513. {
  514. for (ULONG l = 0; l < cElements; l++)
  515. VariantInit (&pVar [l]);
  516. // Retrieve the next cElements elements.
  517. for (l2 = 0; l2 < cElements; l2++)
  518. {
  519. CComBSTR bsName;
  520. if (m_pCWbemPathCracker->GetComponent (m_iIndex, bsName))
  521. {
  522. pVar[l2].vt = VT_BSTR;
  523. pVar[l2].bstrVal = bsName.Detach ();
  524. m_iIndex++;
  525. }
  526. else
  527. break;
  528. }
  529. if (NULL != pcElementFetched)
  530. *pcElementFetched = l2;
  531. }
  532. if (FAILED(hr))
  533. return hr;
  534. return (l2 < cElements) ? S_FALSE : S_OK;
  535. }
  536. //***************************************************************************
  537. //
  538. // SCODE CEnumObjectPathComponent::Clone
  539. //
  540. // DESCRIPTION:
  541. //
  542. // Create a copy of this enumeration
  543. //
  544. // PARAMETERS:
  545. //
  546. // ppEnum on successful return addresses the clone
  547. //
  548. // RETURN VALUES:
  549. //
  550. // WBEM_S_NO_ERROR success
  551. // WBEM_E_FAILED otherwise
  552. //
  553. //***************************************************************************
  554. HRESULT CEnumObjectPathComponent::Clone (
  555. IEnumVARIANT **ppEnum
  556. )
  557. {
  558. HRESULT hr = E_FAIL;
  559. if (NULL != ppEnum)
  560. {
  561. *ppEnum = NULL;
  562. if (m_pCWbemPathCracker)
  563. {
  564. CEnumObjectPathComponent *pEnum =
  565. new CEnumObjectPathComponent (m_pCWbemPathCracker, m_bMutable);
  566. if (!pEnum)
  567. hr = WBEM_E_OUT_OF_MEMORY;
  568. else if (FAILED(hr = pEnum->QueryInterface (IID_IEnumVARIANT, (PPVOID) ppEnum)))
  569. delete pEnum;;
  570. }
  571. }
  572. return hr;
  573. }
  574. //***************************************************************************
  575. //
  576. // SCODE CEnumObjectPathComponent::Skip
  577. //
  578. // DESCRIPTION:
  579. //
  580. // Skip specified number of elements
  581. //
  582. // PARAMETERS:
  583. //
  584. // ppEnum on successful return addresses the clone
  585. //
  586. // RETURN VALUES:
  587. //
  588. // S_OK success
  589. // S_FALSE end of sequence reached prematurely
  590. //
  591. //***************************************************************************
  592. HRESULT CEnumObjectPathComponent::Skip(
  593. ULONG cElements
  594. )
  595. {
  596. HRESULT hr = S_FALSE;
  597. if (m_pCWbemPathCracker)
  598. {
  599. // Get the count
  600. ULONG lComponentCount = 0;
  601. if (m_pCWbemPathCracker->GetComponentCount (lComponentCount))
  602. {
  603. if (m_iIndex + cElements < lComponentCount)
  604. {
  605. hr = S_OK;
  606. m_iIndex += cElements;
  607. }
  608. }
  609. }
  610. return hr;
  611. }