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.

1113 lines
25 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-2000 Microsoft Corporation
  4. //
  5. // CONTEXT.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines the implementation of ISWbemNamedValueSet
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. //***************************************************************************
  14. //
  15. // CSWbemNamedValueSet::CSWbemNamedValueSet
  16. //
  17. // DESCRIPTION:
  18. //
  19. // Constructor.
  20. //
  21. //***************************************************************************
  22. CSWbemNamedValueSet::CSWbemNamedValueSet()
  23. : m_pCWbemPathCracker (NULL),
  24. m_bMutable (true),
  25. m_cRef (0),
  26. m_pIWbemContext (NULL),
  27. m_pSWbemServices (NULL)
  28. {
  29. m_Dispatch.SetObj (this, IID_ISWbemNamedValueSet,
  30. CLSID_SWbemNamedValueSet, L"SWbemNamedValueSet");
  31. // Create a context
  32. CoCreateInstance(CLSID_WbemContext, 0, CLSCTX_INPROC_SERVER,
  33. IID_IWbemContext, (LPVOID *) &m_pIWbemContext);
  34. InterlockedIncrement(&g_cObj);
  35. }
  36. //***************************************************************************
  37. //
  38. // CSWbemNamedValueSet::CSWbemNamedValueSet
  39. //
  40. // DESCRIPTION:
  41. //
  42. // Constructor.
  43. //
  44. //***************************************************************************
  45. CSWbemNamedValueSet::CSWbemNamedValueSet(
  46. CSWbemServices *pService,
  47. IWbemContext *pContext
  48. )
  49. : m_pCWbemPathCracker (NULL),
  50. m_bMutable (true),
  51. m_cRef (0),
  52. m_pIWbemContext (pContext),
  53. m_pSWbemServices (pService)
  54. {
  55. m_Dispatch.SetObj (this, IID_ISWbemNamedValueSet,
  56. CLSID_SWbemNamedValueSet, L"SWbemNamedValueSet");
  57. if (m_pIWbemContext)
  58. m_pIWbemContext->AddRef ();
  59. if (m_pSWbemServices)
  60. m_pSWbemServices->AddRef ();
  61. InterlockedIncrement(&g_cObj);
  62. }
  63. //***************************************************************************
  64. //
  65. // CSWbemNamedValueSet::CSWbemNamedValueSet
  66. //
  67. // DESCRIPTION:
  68. //
  69. // Constructor.
  70. //
  71. //***************************************************************************
  72. CSWbemNamedValueSet::CSWbemNamedValueSet(
  73. CWbemPathCracker *pCWbemPathCracker,
  74. bool bMutable
  75. )
  76. : m_pCWbemPathCracker (pCWbemPathCracker),
  77. m_bMutable (bMutable),
  78. m_cRef (0),
  79. m_pIWbemContext (NULL),
  80. m_pSWbemServices (NULL)
  81. {
  82. m_Dispatch.SetObj (this, IID_ISWbemNamedValueSet,
  83. CLSID_SWbemNamedValueSet, L"SWbemNamedValueSet");
  84. // Create a context
  85. CoCreateInstance(CLSID_WbemContext, 0, CLSCTX_INPROC_SERVER,
  86. IID_IWbemContext, (LPVOID *) &m_pIWbemContext);
  87. if (m_pCWbemPathCracker)
  88. {
  89. m_pCWbemPathCracker->AddRef ();
  90. // Artificial refcount hike as the following may do an AddRef/Release
  91. // pair on this
  92. m_cRef++;
  93. BuildContextFromKeyList ();
  94. m_cRef--;
  95. }
  96. InterlockedIncrement(&g_cObj);
  97. }
  98. //***************************************************************************
  99. //
  100. // CSWbemNamedValueSet::~CSWbemNamedValueSet
  101. //
  102. // DESCRIPTION:
  103. //
  104. // Destructor.
  105. //
  106. //***************************************************************************
  107. CSWbemNamedValueSet::~CSWbemNamedValueSet(void)
  108. {
  109. InterlockedDecrement(&g_cObj);
  110. if (m_pIWbemContext)
  111. {
  112. m_pIWbemContext->EndEnumeration ();
  113. m_pIWbemContext->Release ();
  114. m_pIWbemContext = NULL;
  115. }
  116. RELEASEANDNULL(m_pSWbemServices)
  117. RELEASEANDNULL(m_pCWbemPathCracker)
  118. }
  119. //***************************************************************************
  120. // HRESULT CSWbemNamedValueSet::QueryInterface
  121. // long CSWbemNamedValueSet::AddRef
  122. // long CSWbemNamedValueSet::Release
  123. //
  124. // DESCRIPTION:
  125. //
  126. // Standard Com IUNKNOWN functions.
  127. //
  128. //***************************************************************************
  129. STDMETHODIMP CSWbemNamedValueSet::QueryInterface (
  130. IN REFIID riid,
  131. OUT LPVOID *ppv
  132. )
  133. {
  134. *ppv=NULL;
  135. if (IID_IUnknown==riid)
  136. *ppv = reinterpret_cast<IUnknown*>(this);
  137. else if (IID_IDispatch==riid)
  138. *ppv = (IDispatch *)this;
  139. else if (IID_ISWbemNamedValueSet==riid)
  140. *ppv = (ISWbemNamedValueSet *)this;
  141. else if (IID_ISWbemInternalContext==riid)
  142. *ppv = (ISWbemInternalContext *) this;
  143. else if (IID_IObjectSafety==riid)
  144. *ppv = (IObjectSafety *) this;
  145. else if (IID_ISupportErrorInfo==riid)
  146. *ppv = (ISupportErrorInfo *) this;
  147. else if (IID_IProvideClassInfo==riid)
  148. *ppv = (IProvideClassInfo *)this;
  149. if (NULL!=*ppv)
  150. {
  151. ((LPUNKNOWN)*ppv)->AddRef();
  152. return NOERROR;
  153. }
  154. return ResultFromScode(E_NOINTERFACE);
  155. }
  156. STDMETHODIMP_(ULONG) CSWbemNamedValueSet::AddRef(void)
  157. {
  158. InterlockedIncrement(&m_cRef);
  159. return m_cRef;
  160. }
  161. STDMETHODIMP_(ULONG) CSWbemNamedValueSet::Release(void)
  162. {
  163. InterlockedDecrement(&m_cRef);
  164. if (0L!=m_cRef)
  165. return m_cRef;
  166. delete this;
  167. return 0;
  168. }
  169. //***************************************************************************
  170. // HRESULT CSWbemNamedValueSet::InterfaceSupportsErrorInfo
  171. //
  172. // DESCRIPTION:
  173. //
  174. // Standard Com ISupportErrorInfo functions.
  175. //
  176. //***************************************************************************
  177. STDMETHODIMP CSWbemNamedValueSet::InterfaceSupportsErrorInfo (IN REFIID riid)
  178. {
  179. return (IID_ISWbemNamedValueSet == riid) ? S_OK : S_FALSE;
  180. }
  181. void CSWbemNamedValueSet::BuildContextFromKeyList ()
  182. {
  183. if (m_pCWbemPathCracker)
  184. {
  185. ULONG lKeyCount = 0;
  186. if (m_pCWbemPathCracker->GetKeyCount (lKeyCount))
  187. {
  188. for (ULONG i = 0; i <lKeyCount; i++)
  189. {
  190. VARIANT var;
  191. VariantInit (&var);
  192. CComBSTR bsName;
  193. WbemCimtypeEnum cimType;
  194. if (m_pCWbemPathCracker->GetKey (i, bsName, var, cimType))
  195. {
  196. SetValueIntoContext (bsName, &var, 0);
  197. }
  198. VariantClear (&var);
  199. }
  200. }
  201. }
  202. }
  203. //***************************************************************************
  204. //
  205. // CSWbemNamedValueSet::GetIWbemContext
  206. //
  207. // DESCRIPTION:
  208. //
  209. // Return the IWbemContext interface corresponding to this scriptable wrapper.
  210. //
  211. // PARAMETERS:
  212. // ppContext holds the IWbemContext pointer on return
  213. //
  214. // RETURN VALUES:
  215. // S_OK success
  216. // E_FAIL otherwise
  217. //
  218. // NOTES:
  219. // If successful, the returned interface is AddRef'd; the caller is
  220. // responsible for release.
  221. //
  222. //***************************************************************************
  223. STDMETHODIMP CSWbemNamedValueSet::GetIWbemContext (IWbemContext **ppContext)
  224. {
  225. HRESULT hr = S_OK; // By default if we have no context to copy
  226. if (ppContext)
  227. {
  228. *ppContext = NULL;
  229. if (m_pIWbemContext)
  230. {
  231. /*
  232. * Before returning a context, we ensure that coercion is performed
  233. * to render the type down to either an IUnknown or a Qualifier
  234. * type. This is done for the benefit of imposing a fixed typing
  235. * system for provider context, rather than have providers take
  236. * the burden of using VariantChangeType etc. themselves.
  237. */
  238. if (SUCCEEDED (hr = m_pIWbemContext->Clone (ppContext)))
  239. {
  240. if (SUCCEEDED (hr = (*ppContext)->BeginEnumeration (0)))
  241. {
  242. BSTR bsName = NULL;
  243. VARIANT var;
  244. VariantInit (&var);
  245. while (WBEM_S_NO_ERROR == (*ppContext)->Next(0, &bsName, &var))
  246. {
  247. VARIANT vTemp;
  248. VariantInit (&vTemp);
  249. // Stage 1 of transformation involves homogenisation of
  250. // arrays, transformation of JScript arrays, and weedling
  251. // out of IWbemClassObject's
  252. //
  253. // If successful hr will be a a success code and vTemp will
  254. // hold the value, which will either be a VT_UNKNOWN or a
  255. // "simple" (non-object) type, or array thereof.
  256. if((VT_ARRAY | VT_VARIANT) == V_VT(&var))
  257. {
  258. // A classical dispatch-style array of variants - map them
  259. // down to a homogeneous array of primitive values
  260. if (SUCCEEDED(hr = ConvertArray(&vTemp, &var)))
  261. {
  262. // Now check if we should map any VT_DISPATCH's inside
  263. // the array
  264. hr = MapToCIMOMObject(&vTemp);
  265. }
  266. }
  267. else if (VT_DISPATCH == V_VT(&var))
  268. {
  269. // First try a JScript array - if this succeeds it
  270. // will map to a regular SAFEARRAY. If not, we try
  271. // to map to an IWbem interface
  272. if (FAILED(ConvertDispatchToArray (&vTemp, &var)))
  273. {
  274. if (SUCCEEDED (hr = VariantCopy (&vTemp, &var)))
  275. hr = MapToCIMOMObject(&vTemp);
  276. }
  277. }
  278. else
  279. {
  280. // Just copy so we have the result in vTemp in all cases
  281. hr = VariantCopy (&vTemp, &var);
  282. }
  283. // Stage 2 of the transformation involves casting of simple
  284. // (non-VT_UNKNOWN) types to a qualifier type.
  285. if (SUCCEEDED (hr))
  286. {
  287. if (VT_UNKNOWN != (V_VT(&vTemp) & ~(VT_ARRAY|VT_BYREF)))
  288. {
  289. // Not a VT_UNKNOWN so try to cast to a qualifier type
  290. VARIANT vFinal;
  291. VariantInit (&vFinal);
  292. VARTYPE vtOK = GetAcceptableQualType(V_VT(&vTemp));
  293. if (vtOK != V_VT(&vTemp))
  294. {
  295. // Need to coerce
  296. if (SUCCEEDED(hr = QualifierVariantChangeType (&vFinal, &vTemp, vtOK)))
  297. hr = (*ppContext)->SetValue (bsName, 0, &vFinal);
  298. }
  299. else
  300. hr = (*ppContext)->SetValue (bsName, 0, &vTemp);
  301. VariantClear (&vFinal);
  302. }
  303. else
  304. hr = (*ppContext)->SetValue (bsName, 0, &vTemp);
  305. }
  306. VariantClear (&vTemp);
  307. SysFreeString (bsName);
  308. bsName = NULL;
  309. VariantClear (&var);
  310. }
  311. (*ppContext)->EndEnumeration ();
  312. }
  313. }
  314. }
  315. }
  316. return hr;
  317. }
  318. //***************************************************************************
  319. //
  320. // SCODE CSWbemNamedValueSet::Clone
  321. //
  322. // DESCRIPTION:
  323. //
  324. // Clone object
  325. //
  326. // PARAMETERS:
  327. // ppCopy On successful return addresses the copy
  328. //
  329. // RETURN VALUES:
  330. //
  331. // WBEM_S_NO_ERROR success
  332. // WBEM_E_INVALID_PARAMETER bad input parameters
  333. // WBEM_E_FAILED otherwise
  334. //
  335. //***************************************************************************
  336. HRESULT CSWbemNamedValueSet::Clone (
  337. ISWbemNamedValueSet **ppCopy
  338. )
  339. {
  340. HRESULT hr = WBEM_E_FAILED;
  341. ResetLastErrors ();
  342. if (NULL == ppCopy)
  343. hr = WBEM_E_INVALID_PARAMETER;
  344. else if (m_pIWbemContext)
  345. {
  346. IWbemContext *pWObject = NULL;
  347. if (WBEM_S_NO_ERROR == (hr = m_pIWbemContext->Clone (&pWObject)))
  348. {
  349. // NB: the cloned set is always mutable
  350. CSWbemNamedValueSet *pCopy =
  351. new CSWbemNamedValueSet (m_pSWbemServices, pWObject);
  352. if (!pCopy)
  353. hr = WBEM_E_OUT_OF_MEMORY;
  354. else if (FAILED(hr = pCopy->QueryInterface (IID_ISWbemNamedValueSet,
  355. (PPVOID) ppCopy)))
  356. delete pCopy;
  357. pWObject->Release ();
  358. }
  359. }
  360. if (FAILED(hr))
  361. m_Dispatch.RaiseException (hr);
  362. return hr;
  363. }
  364. //***************************************************************************
  365. //
  366. // SCODE CSWbemNamedValueSet::BeginEnumeration
  367. //
  368. // DESCRIPTION:
  369. //
  370. // Kick off a value enumeration
  371. //
  372. // RETURN VALUES:
  373. //
  374. // WBEM_S_NO_ERROR success
  375. // WBEM_E_INVALID_PARAMETER bad input parameters
  376. // WBEM_E_FAILED otherwise
  377. //
  378. //***************************************************************************
  379. HRESULT CSWbemNamedValueSet::BeginEnumeration (
  380. )
  381. {
  382. HRESULT hr = WBEM_E_FAILED;
  383. ResetLastErrors ();
  384. if (m_pIWbemContext)
  385. {
  386. // Preface with an end enumeration just in case
  387. hr = m_pIWbemContext->EndEnumeration ();
  388. hr = m_pIWbemContext->BeginEnumeration (0);
  389. }
  390. if (FAILED(hr))
  391. m_Dispatch.RaiseException (hr);
  392. return hr;
  393. }
  394. //***************************************************************************
  395. //
  396. // SCODE CSWbemNamedValueSet::Next
  397. //
  398. // DESCRIPTION:
  399. //
  400. // Iterate through value enumeration
  401. //
  402. // PARAMETERS:
  403. // lFlags Flags
  404. // ppNamedValue The next named value (or NULL if at end)
  405. //
  406. // RETURN VALUES:
  407. //
  408. // WBEM_S_NO_ERROR success
  409. // WBEM_E_INVALID_PARAMETER bad input parameters
  410. // WBEM_E_FAILED otherwise
  411. //
  412. //***************************************************************************
  413. HRESULT CSWbemNamedValueSet::Next (
  414. long lFlags,
  415. ISWbemNamedValue **ppNamedValue
  416. )
  417. {
  418. HRESULT hr = WBEM_E_FAILED;
  419. ResetLastErrors ();
  420. if (NULL == ppNamedValue)
  421. hr = WBEM_E_INVALID_PARAMETER;
  422. else
  423. {
  424. *ppNamedValue = NULL;
  425. if (m_pIWbemContext)
  426. {
  427. BSTR name = NULL;
  428. VARIANT var;
  429. VariantInit (&var);
  430. if (WBEM_S_NO_ERROR == (hr = m_pIWbemContext->Next (lFlags,
  431. &name, &var)))
  432. {
  433. *ppNamedValue = new CSWbemNamedValue (m_pSWbemServices,
  434. this, name, m_bMutable);
  435. if (!(*ppNamedValue))
  436. hr = WBEM_E_OUT_OF_MEMORY;
  437. SysFreeString (name);
  438. }
  439. VariantClear (&var);
  440. }
  441. }
  442. if (FAILED(hr))
  443. m_Dispatch.RaiseException (hr);
  444. return hr;
  445. }
  446. //***************************************************************************
  447. //
  448. // SCODE CSWbemNamedValueSet::Add
  449. //
  450. // DESCRIPTION:
  451. //
  452. // Add named value to set
  453. //
  454. // PARAMETERS:
  455. //
  456. // bsName The property to update/create
  457. // pVal The value
  458. // lFlags Flags
  459. // ppNamedValue The named value created
  460. //
  461. // RETURN VALUES:
  462. //
  463. // WBEM_S_NO_ERROR success
  464. // WBEM_E_INVALID_PARAMETER bad input parameters
  465. // WBEM_E_FAILED otherwise
  466. //
  467. //***************************************************************************
  468. HRESULT CSWbemNamedValueSet::Add (
  469. BSTR bsName,
  470. VARIANT *pVal,
  471. long lFlags,
  472. ISWbemNamedValue **ppNamedValue
  473. )
  474. {
  475. HRESULT hr = WBEM_E_FAILED;
  476. ResetLastErrors ();
  477. if ((NULL == ppNamedValue) || (NULL == bsName) || (NULL == pVal))
  478. hr = WBEM_E_INVALID_PARAMETER;
  479. else if (!m_bMutable)
  480. hr = WBEM_E_READ_ONLY;
  481. else if (m_pIWbemContext)
  482. {
  483. *ppNamedValue = NULL;
  484. if (VT_BYREF & V_VT(pVal))
  485. {
  486. // We must dereference all byref's
  487. VARIANT var;
  488. VariantInit (&var);
  489. if (VT_ARRAY & V_VT(pVal))
  490. {
  491. var.vt = V_VT(pVal) & ~VT_BYREF;
  492. hr = SafeArrayCopy (*(pVal->pparray), &(var.parray));
  493. }
  494. else
  495. hr = VariantChangeType(&var, pVal, 0, V_VT(pVal) & ~VT_BYREF);
  496. if (SUCCEEDED(hr))
  497. hr = m_pIWbemContext->SetValue (bsName, lFlags, &var);
  498. VariantClear (&var);
  499. }
  500. else if ((VT_ERROR == V_VT(pVal)) && (DISP_E_PARAMNOTFOUND == pVal->scode))
  501. {
  502. // Treat as NULL assignment
  503. pVal->vt = VT_NULL;
  504. hr = m_pIWbemContext->SetValue (bsName, lFlags, pVal);
  505. }
  506. else
  507. hr = m_pIWbemContext->SetValue (bsName, lFlags, pVal);
  508. if (SUCCEEDED (hr))
  509. {
  510. WbemCimtypeEnum cimtype = MapVariantTypeToCimType(pVal);
  511. // Add to the path key list if we have one - note this MAY fail
  512. if (m_pCWbemPathCracker)
  513. {
  514. if (!m_pCWbemPathCracker->SetKey (bsName, cimtype, *pVal))
  515. {
  516. // Rats - delete it
  517. m_pIWbemContext->DeleteValue (bsName, 0);
  518. hr = WBEM_E_FAILED;
  519. }
  520. }
  521. if (SUCCEEDED(hr))
  522. {
  523. *ppNamedValue = new CSWbemNamedValue (m_pSWbemServices,
  524. this, bsName);
  525. if (!(*ppNamedValue))
  526. hr = WBEM_E_OUT_OF_MEMORY;
  527. }
  528. }
  529. }
  530. if (FAILED(hr))
  531. m_Dispatch.RaiseException (hr);
  532. return hr;
  533. }
  534. HRESULT CSWbemNamedValueSet::SetValueIntoContext (
  535. BSTR bsName,
  536. VARIANT *pVal,
  537. ULONG lFlags
  538. )
  539. {
  540. HRESULT hr = WBEM_E_FAILED;
  541. if (m_pIWbemContext)
  542. {
  543. if (VT_BYREF & V_VT(pVal))
  544. {
  545. // We must dereference all byref's
  546. VARIANT var;
  547. VariantInit (&var);
  548. if (VT_ARRAY & V_VT(pVal))
  549. {
  550. var.vt = V_VT(pVal) & ~VT_BYREF;
  551. hr = SafeArrayCopy (*(pVal->pparray), &(var.parray));
  552. }
  553. else
  554. hr = VariantChangeType(&var, pVal, 0, V_VT(pVal) & ~VT_BYREF);
  555. if (SUCCEEDED(hr))
  556. hr = m_pIWbemContext->SetValue (bsName, lFlags, &var);
  557. VariantClear (&var);
  558. }
  559. else if ((VT_ERROR == V_VT(pVal)) && (DISP_E_PARAMNOTFOUND == pVal->scode))
  560. {
  561. // Treat as NULL assignment
  562. pVal->vt = VT_NULL;
  563. hr = m_pIWbemContext->SetValue (bsName, lFlags, pVal);
  564. }
  565. else
  566. hr = m_pIWbemContext->SetValue (bsName, lFlags, pVal);
  567. }
  568. return hr;
  569. }
  570. //***************************************************************************
  571. //
  572. // SCODE CSWbemNamedValueSet::Item
  573. //
  574. // DESCRIPTION:
  575. //
  576. // Get named value
  577. //
  578. // PARAMETERS:
  579. //
  580. // bsName The value to retrieve
  581. // lFlags Flags
  582. // ppNamedValue On successful return addresses the value
  583. //
  584. // RETURN VALUES:
  585. //
  586. // WBEM_S_NO_ERROR success
  587. // WBEM_E_INVALID_PARAMETER bad input parameters
  588. // WBEM_E_FAILED otherwise
  589. //
  590. //***************************************************************************
  591. HRESULT CSWbemNamedValueSet::Item (
  592. BSTR bsName,
  593. long lFlags,
  594. ISWbemNamedValue **ppNamedValue
  595. )
  596. {
  597. HRESULT hr = WBEM_E_FAILED;
  598. ResetLastErrors ();
  599. if (NULL == ppNamedValue)
  600. hr = WBEM_E_INVALID_PARAMETER;
  601. else if (m_pIWbemContext)
  602. {
  603. VARIANT var;
  604. VariantInit (&var);
  605. if (WBEM_S_NO_ERROR == (hr = m_pIWbemContext->GetValue (bsName, lFlags, &var)))
  606. {
  607. *ppNamedValue = new CSWbemNamedValue (m_pSWbemServices,
  608. this, bsName, m_bMutable);
  609. if (!(*ppNamedValue))
  610. hr = WBEM_E_OUT_OF_MEMORY;
  611. }
  612. VariantClear (&var);
  613. }
  614. if (FAILED(hr))
  615. m_Dispatch.RaiseException (hr);
  616. return hr;
  617. }
  618. //***************************************************************************
  619. //
  620. // SCODE CSWbemNamedValueSet::Remove
  621. //
  622. // DESCRIPTION:
  623. //
  624. // Delete named value
  625. //
  626. // PARAMETERS:
  627. //
  628. // bsName The value to delete
  629. // lFlags Flags
  630. //
  631. // RETURN VALUES:
  632. //
  633. // WBEM_S_NO_ERROR success
  634. // WBEM_E_INVALID_PARAMETER bad input parameters
  635. // WBEM_E_FAILED otherwise
  636. //
  637. //***************************************************************************
  638. HRESULT CSWbemNamedValueSet::Remove (
  639. BSTR bsName,
  640. long lFlags
  641. )
  642. {
  643. HRESULT hr = WBEM_E_FAILED;
  644. ResetLastErrors ();
  645. if (!m_bMutable)
  646. hr = WBEM_E_READ_ONLY;
  647. else if (m_pIWbemContext)
  648. hr = m_pIWbemContext->DeleteValue (bsName, lFlags);
  649. if (FAILED(hr))
  650. m_Dispatch.RaiseException (hr);
  651. else
  652. {
  653. // Remove from our key list if we have one
  654. if (m_pCWbemPathCracker)
  655. hr = m_pCWbemPathCracker->RemoveKey (bsName);
  656. }
  657. return hr;
  658. }
  659. //***************************************************************************
  660. //
  661. // SCODE CSWbemNamedValueSet::DeleteAll
  662. //
  663. // DESCRIPTION:
  664. //
  665. // Empty the bag
  666. //
  667. // PARAMETERS:
  668. // None
  669. //
  670. // RETURN VALUES:
  671. //
  672. // WBEM_S_NO_ERROR success
  673. // WBEM_E_INVALID_PARAMETER bad input parameters
  674. // WBEM_E_FAILED otherwise
  675. //
  676. //***************************************************************************
  677. HRESULT CSWbemNamedValueSet::DeleteAll (
  678. )
  679. {
  680. HRESULT hr = WBEM_E_FAILED;
  681. ResetLastErrors ();
  682. if (!m_bMutable)
  683. hr = WBEM_E_READ_ONLY;
  684. else if (m_pIWbemContext)
  685. hr = m_pIWbemContext->DeleteAll ();
  686. if (FAILED(hr))
  687. m_Dispatch.RaiseException (hr);
  688. else
  689. {
  690. // Empty the key list
  691. if (m_pCWbemPathCracker)
  692. m_pCWbemPathCracker->RemoveAllKeys ();
  693. }
  694. return hr;
  695. }
  696. //***************************************************************************
  697. //
  698. // SCODE CSWbemNamedValueSet::get__NewEnum
  699. //
  700. // DESCRIPTION:
  701. //
  702. // Return an IEnumVARIANT-supporting interface for collections
  703. //
  704. // PARAMETERS:
  705. //
  706. // ppUnk on successful return addresses the IUnknown interface
  707. //
  708. // RETURN VALUES:
  709. //
  710. // S_OK success
  711. // E_FAIL otherwise
  712. //
  713. //***************************************************************************
  714. HRESULT CSWbemNamedValueSet::get__NewEnum (
  715. IUnknown **ppUnk
  716. )
  717. {
  718. HRESULT hr = E_FAIL;
  719. ResetLastErrors ();
  720. if (NULL != ppUnk)
  721. {
  722. *ppUnk = NULL;
  723. CContextEnumVar *pEnum = new CContextEnumVar (this, 0);
  724. if (!pEnum)
  725. hr = WBEM_E_OUT_OF_MEMORY;
  726. else if (FAILED(hr = pEnum->QueryInterface (IID_IUnknown, (PPVOID) ppUnk)))
  727. delete pEnum;
  728. }
  729. if (FAILED(hr))
  730. m_Dispatch.RaiseException (hr);
  731. return hr;
  732. }
  733. //***************************************************************************
  734. //
  735. // SCODE CSWbemNamedValueSet::get_Count
  736. //
  737. // DESCRIPTION:
  738. //
  739. // Return the number of items in the collection
  740. //
  741. // PARAMETERS:
  742. //
  743. // plCount on successful return addresses the count
  744. //
  745. // RETURN VALUES:
  746. //
  747. // S_OK success
  748. // E_FAIL otherwise
  749. //
  750. //***************************************************************************
  751. HRESULT CSWbemNamedValueSet::get_Count (
  752. long *plCount
  753. )
  754. {
  755. HRESULT hr = E_FAIL;
  756. ResetLastErrors ();
  757. if (NULL != plCount)
  758. {
  759. *plCount = 0;
  760. if (m_pIWbemContext)
  761. {
  762. /*
  763. * This is not the most efficient way of obtaining the count,
  764. * but it is the only way that is:
  765. * (a) Supported by the underlying interface
  766. * (b) Does not require access to any other interface
  767. * (c) Does not affect the current enumeration position
  768. */
  769. SAFEARRAY *pArray = NULL;
  770. if (WBEM_S_NO_ERROR == m_pIWbemContext->GetNames (0, &pArray))
  771. {
  772. long lUBound = 0, lLBound = 0;
  773. SafeArrayGetUBound (pArray, 1, &lUBound);
  774. SafeArrayGetLBound (pArray, 1, &lLBound);
  775. *plCount = lUBound - lLBound + 1;
  776. SafeArrayDestroy (pArray);
  777. hr = S_OK;
  778. }
  779. }
  780. }
  781. if (FAILED(hr))
  782. m_Dispatch.RaiseException (hr);
  783. return hr;
  784. }
  785. //***************************************************************************
  786. //
  787. // CSWbemNamedValueSet::GetIWbemContext
  788. //
  789. // DESCRIPTION:
  790. //
  791. // Given an IDispatch interface which we hope is also an ISWbemNamedValueSet
  792. // interface, return the underlying IWbemContext interface.
  793. //
  794. // PARAMETERS:
  795. // pDispatch the IDispatch in question
  796. //
  797. // RETURN VALUES:
  798. // The underlying IWbemContext interface, or NULL.
  799. //
  800. // NOTES:
  801. // If successful, the returned interface is AddRef'd; the caller is
  802. // responsible for release.
  803. //
  804. //***************************************************************************
  805. /*
  806. * THIS FUNCTION NEEDS FIXING
  807. * Currently this function returns the context from the service provider
  808. * obtained from the host, if there is one. If there isn't one then it uses
  809. * the one passed in from the user. The correct behaviour is to _add_ the
  810. * context from the user to the one provided by the service provider if there
  811. * is one, if not just use the one from the user
  812. */
  813. IWbemContext *CSWbemNamedValueSet::GetIWbemContext (
  814. IDispatch *pDispatch,
  815. IServiceProvider *pServiceProvider
  816. )
  817. {
  818. _RD(static char *me = "CSWbemNamedValueSet::GetIWbemContext";)
  819. IWbemContext *pContext = NULL;
  820. ISWbemInternalContext *pIContext = NULL;
  821. _RPrint(me, "Called", 0, "");
  822. if (pServiceProvider) {
  823. if (FAILED(pServiceProvider->QueryService(IID_IWbemContext,
  824. IID_IWbemContext, (LPVOID *)&pContext))) {
  825. _RPrint(me, "Failed to get context from services", 0, "");
  826. pContext = NULL;
  827. } else {
  828. _RPrint(me, "Got context from services", 0, "");
  829. ;
  830. }
  831. }
  832. if (pDispatch && !pContext)
  833. {
  834. if (SUCCEEDED (pDispatch->QueryInterface
  835. (IID_ISWbemInternalContext, (PPVOID) &pIContext)))
  836. {
  837. pIContext->GetIWbemContext (&pContext);
  838. pIContext->Release ();
  839. }
  840. }
  841. return pContext;
  842. }
  843. /*
  844. * Call GetIWbemContext to get the service context if there is one.
  845. * Then wrap the result with an SWbemContext and return
  846. */
  847. IDispatch *CSWbemNamedValueSet::GetSWbemContext(IDispatch *pDispatch,
  848. IServiceProvider *pServiceProvider, CSWbemServices *pServices)
  849. {
  850. _RD(static char *me = "CSWbemNamedValueSet::GetSWbemContext";)
  851. IDispatch *pDispatchOut = NULL;
  852. IWbemContext *pContext = GetIWbemContext(pDispatch, pServiceProvider);
  853. if (pContext) {
  854. CSWbemNamedValueSet *pCSWbemNamedValueSet = new CSWbemNamedValueSet(pServices, pContext);
  855. if (pCSWbemNamedValueSet)
  856. {
  857. if (FAILED(pCSWbemNamedValueSet->QueryInterface
  858. (IID_IDispatch, (PPVOID) &pDispatchOut))) {
  859. delete pCSWbemNamedValueSet;
  860. pDispatchOut = NULL;
  861. }
  862. }
  863. pContext->Release();
  864. }
  865. _RPrint(me, "Returning with context: ", (long)pDispatchOut, "");
  866. return pDispatchOut;
  867. }
  868. //***************************************************************************
  869. //
  870. // SCODE CSWbemNamedValueSet::CContextDispatchHelp::HandleError
  871. //
  872. // DESCRIPTION:
  873. //
  874. // Provide bespoke handling of error conditions in the bolierplate
  875. // Dispatch implementation.
  876. //
  877. // PARAMETERS:
  878. //
  879. // dispidMember, wFlags,
  880. // pdispparams, pvarResult,
  881. // puArgErr, All passed directly from IDispatch::Invoke
  882. // hr The return code from the bolierplate invoke
  883. //
  884. // RETURN VALUES:
  885. // The new return code (to be ultimately returned from Invoke)
  886. //
  887. // WBEM_S_NO_ERROR success
  888. // WBEM_E_INVALID_PARAMETER bad input parameters
  889. // WBEM_E_FAILED otherwise
  890. //
  891. //***************************************************************************
  892. HRESULT CSWbemNamedValueSet::CContextDispatchHelp::HandleError (
  893. DISPID dispidMember,
  894. unsigned short wFlags,
  895. DISPPARAMS FAR* pdispparams,
  896. VARIANT FAR* pvarResult,
  897. UINT FAR* puArgErr,
  898. HRESULT hr
  899. )
  900. {
  901. /*
  902. * We are looking for calls on the default member (the Item method) which
  903. * are PUTs that supplied an argument. These are triggered by attempts
  904. * to set a value of a named value (Item) in the collection.
  905. * The first argument should be the new value for the item, and the second
  906. * argument should be the name of the item.
  907. */
  908. if ((DISPID_VALUE == dispidMember) && (DISP_E_MEMBERNOTFOUND == hr) && (2 == pdispparams->cArgs)
  909. && (DISPATCH_PROPERTYPUT == wFlags))
  910. {
  911. // Looks promising - get the object to try and resolve this
  912. ISWbemNamedValueSet *pContext = NULL;
  913. if (SUCCEEDED (m_pObj->QueryInterface (IID_ISWbemNamedValueSet, (PPVOID) &pContext)))
  914. {
  915. VARIANT valueVar;
  916. VariantInit (&valueVar);
  917. if (SUCCEEDED(VariantCopy(&valueVar, &pdispparams->rgvarg[0])))
  918. {
  919. VARIANT nameVar;
  920. VariantInit (&nameVar);
  921. if (SUCCEEDED(VariantCopy(&nameVar, &pdispparams->rgvarg[1])))
  922. {
  923. // Check name is a BSTR and use it to get the item
  924. if (VT_BSTR == V_VT(&nameVar))
  925. {
  926. ISWbemNamedValue *pNamedValue = NULL;
  927. if (SUCCEEDED (pContext->Item (V_BSTR(&nameVar), 0, &pNamedValue)))
  928. {
  929. // Try and put the value
  930. if (SUCCEEDED (pNamedValue->put_Value (&valueVar)))
  931. hr = S_OK;
  932. else
  933. {
  934. hr = DISP_E_TYPEMISMATCH;
  935. if (puArgErr)
  936. *puArgErr = 0;
  937. }
  938. pNamedValue->Release ();
  939. }
  940. }
  941. else
  942. {
  943. hr = DISP_E_TYPEMISMATCH;
  944. if (puArgErr)
  945. *puArgErr = 1;
  946. }
  947. VariantClear (&nameVar);
  948. }
  949. VariantClear (&valueVar);
  950. }
  951. pContext->Release ();
  952. }
  953. }
  954. return hr;
  955. }