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.

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