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.

914 lines
20 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. //
  5. // QUALIFIER.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines the implementation of ISWbemQualifier
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. //***************************************************************************
  14. //
  15. // CSWbemQualifier::CSWbemQualifier
  16. //
  17. // DESCRIPTION:
  18. //
  19. // Constructor.
  20. //
  21. //***************************************************************************
  22. CSWbemQualifier::CSWbemQualifier(IWbemQualifierSet *pIWbemQualifierSet, BSTR name,
  23. CWbemSite *pSite) :
  24. m_pSite (NULL)
  25. {
  26. m_Dispatch.SetObj (this, IID_ISWbemQualifier,
  27. CLSID_SWbemQualifier, L"SWbemQualifier");
  28. m_cRef=1;
  29. m_pIWbemQualifierSet = pIWbemQualifierSet;
  30. m_pIWbemQualifierSet->AddRef ();
  31. if (pSite)
  32. {
  33. m_pSite = pSite;
  34. m_pSite->AddRef ();
  35. }
  36. m_name = SysAllocString (name);
  37. InterlockedIncrement(&g_cObj);
  38. }
  39. //***************************************************************************
  40. //
  41. // CSWbemQualifier::~CSWbemQualifier
  42. //
  43. // DESCRIPTION:
  44. //
  45. // Destructor.
  46. //
  47. //***************************************************************************
  48. CSWbemQualifier::~CSWbemQualifier(void)
  49. {
  50. InterlockedDecrement(&g_cObj);
  51. if (m_pIWbemQualifierSet)
  52. m_pIWbemQualifierSet->Release ();
  53. if (m_pSite)
  54. m_pSite->Release ();
  55. SysFreeString (m_name);
  56. }
  57. //***************************************************************************
  58. // HRESULT CSWbemQualifier::QueryInterface
  59. // long CSWbemQualifier::AddRef
  60. // long CSWbemQualifier::Release
  61. //
  62. // DESCRIPTION:
  63. //
  64. // Standard Com IUNKNOWN functions.
  65. //
  66. //***************************************************************************
  67. STDMETHODIMP CSWbemQualifier::QueryInterface (
  68. IN REFIID riid,
  69. OUT LPVOID *ppv
  70. )
  71. {
  72. *ppv=NULL;
  73. if (IID_IUnknown==riid)
  74. *ppv = reinterpret_cast<IUnknown*>(this);
  75. else if (IID_ISWbemQualifier==riid)
  76. *ppv = (ISWbemQualifier *)this;
  77. else if (IID_IDispatch==riid)
  78. *ppv = (IDispatch *)this;
  79. else if (IID_ISupportErrorInfo==riid)
  80. *ppv = (ISupportErrorInfo *)this;
  81. else if (IID_IProvideClassInfo==riid)
  82. *ppv = (IProvideClassInfo *)this;
  83. if (NULL!=*ppv)
  84. {
  85. ((LPUNKNOWN)*ppv)->AddRef();
  86. return NOERROR;
  87. }
  88. return ResultFromScode(E_NOINTERFACE);
  89. }
  90. STDMETHODIMP_(ULONG) CSWbemQualifier::AddRef(void)
  91. {
  92. InterlockedIncrement(&m_cRef);
  93. return m_cRef;
  94. }
  95. STDMETHODIMP_(ULONG) CSWbemQualifier::Release(void)
  96. {
  97. InterlockedDecrement(&m_cRef);
  98. if (0L!=m_cRef)
  99. return m_cRef;
  100. delete this;
  101. return 0;
  102. }
  103. //***************************************************************************
  104. // HRESULT CSWbemQualifier::InterfaceSupportsErrorInfo
  105. //
  106. // DESCRIPTION:
  107. //
  108. // Standard Com ISupportErrorInfo functions.
  109. //
  110. //***************************************************************************
  111. STDMETHODIMP CSWbemQualifier::InterfaceSupportsErrorInfo (IN REFIID riid)
  112. {
  113. return (IID_ISWbemQualifier == riid) ? S_OK : S_FALSE;
  114. }
  115. //***************************************************************************
  116. //
  117. // SCODE CSWbemQualifier::get_Value
  118. //
  119. // DESCRIPTION:
  120. //
  121. // Retrieve the qualifier value
  122. //
  123. // PARAMETERS:
  124. //
  125. // pValue holds the value on return
  126. //
  127. // RETURN VALUES:
  128. //
  129. // WBEM_S_NO_ERROR success
  130. // WBEM_E_INVALID_PARAMETER bad input parameters
  131. // WBEM_E_FAILED otherwise
  132. //
  133. //***************************************************************************
  134. HRESULT CSWbemQualifier::get_Value (
  135. VARIANT *pValue
  136. )
  137. {
  138. HRESULT hr = WBEM_E_FAILED;
  139. ResetLastErrors ();
  140. if (NULL == pValue)
  141. hr = WBEM_E_INVALID_PARAMETER;
  142. {
  143. VariantClear (pValue);
  144. if (m_pIWbemQualifierSet)
  145. {
  146. VARIANT var;
  147. VariantInit (&var);
  148. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get
  149. (m_name, 0, &var, NULL)))
  150. {
  151. if(var.vt & VT_ARRAY)
  152. hr = ConvertArrayRev(pValue, &var);
  153. else
  154. hr = VariantCopy (pValue, &var);
  155. }
  156. VariantClear(&var);
  157. }
  158. }
  159. if (FAILED(hr))
  160. m_Dispatch.RaiseException (hr);
  161. return hr;
  162. }
  163. //***************************************************************************
  164. //
  165. // SCODE CSWbemQualifier::put_Value
  166. //
  167. // DESCRIPTION:
  168. //
  169. // Set the qualifier value
  170. //
  171. // PARAMETERS:
  172. //
  173. // pVal the new value
  174. //
  175. // RETURN VALUES:
  176. //
  177. // WBEM_S_NO_ERROR success
  178. // WBEM_E_INVALID_PARAMETER bad input parameters
  179. // WBEM_E_FAILED otherwise
  180. //
  181. //***************************************************************************
  182. HRESULT CSWbemQualifier::put_Value (
  183. VARIANT *pVal
  184. )
  185. {
  186. HRESULT hr = WBEM_E_FAILED;
  187. ResetLastErrors ();
  188. if (NULL == pVal)
  189. hr = WBEM_E_INVALID_PARAMETER;
  190. {
  191. /*
  192. * We can only change the value, not the flavor. We have to read the
  193. * flavor first to avoid changing it.
  194. */
  195. if (m_pIWbemQualifierSet)
  196. {
  197. long flavor = 0;
  198. VARIANT curValue;
  199. VariantInit (&curValue);
  200. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (m_name, 0, &curValue, &flavor)))
  201. {
  202. // Mask out the origin bits from the flavor as those are read-only
  203. flavor &= ~WBEM_FLAVOR_MASK_ORIGIN;
  204. // Make sure we have a decent qualifier value to use
  205. if(((VT_ARRAY | VT_VARIANT) == V_VT(pVal)) ||
  206. ((VT_ARRAY | VT_VARIANT | VT_BYREF) == V_VT(pVal)))
  207. {
  208. VARIANT vTemp;
  209. VariantInit (&vTemp);
  210. if (S_OK == ConvertArray(&vTemp, pVal, true, curValue.vt & ~VT_ARRAY))
  211. hr = m_pIWbemQualifierSet->Put (m_name, &vTemp, flavor);
  212. VariantClear (&vTemp);
  213. }
  214. else if ((VT_DISPATCH == V_VT(pVal)) || ((VT_DISPATCH|VT_BYREF) == V_VT(pVal)))
  215. {
  216. // Could be a JScript IDispatchEx array
  217. VARIANT vTemp;
  218. VariantInit (&vTemp);
  219. if (S_OK == ConvertDispatchToArray (&vTemp, pVal, CIM_ILLEGAL, true,
  220. curValue.vt & ~VT_ARRAY))
  221. hr = m_pIWbemQualifierSet->Put (m_name, &vTemp, flavor);
  222. VariantClear (&vTemp);
  223. }
  224. else
  225. {
  226. // Only certain types, I4, R8, BOOL and BSTR are acceptable qualifier
  227. // values. Convert the data if need be
  228. VARTYPE vtOK = GetAcceptableQualType(V_VT(pVal));
  229. if(vtOK != V_VT(pVal))
  230. {
  231. VARIANT vTemp;
  232. VariantInit(&vTemp);
  233. if (S_OK == QualifierVariantChangeType (&vTemp, pVal, vtOK))
  234. hr = m_pIWbemQualifierSet->Put (m_name, &vTemp, flavor);
  235. VariantClear(&vTemp);
  236. }
  237. else
  238. hr = m_pIWbemQualifierSet->Put (m_name, pVal, flavor);
  239. }
  240. }
  241. VariantClear (&curValue);
  242. }
  243. }
  244. if (FAILED(hr))
  245. m_Dispatch.RaiseException (hr);
  246. else
  247. {
  248. // Propagate the change to the owning site
  249. if (m_pSite)
  250. m_pSite->Update ();
  251. }
  252. return hr;
  253. }
  254. //***************************************************************************
  255. //
  256. // SCODE CSWbemQualifier::get_Name
  257. //
  258. // DESCRIPTION:
  259. //
  260. // Retrieve the qualifier name
  261. //
  262. // PARAMETERS:
  263. //
  264. // pName holds the name on return
  265. //
  266. // RETURN VALUES:
  267. //
  268. // WBEM_S_NO_ERROR success
  269. // WBEM_E_INVALID_PARAMETER bad input parameters
  270. // WBEM_E_FAILED otherwise
  271. //
  272. //***************************************************************************
  273. HRESULT CSWbemQualifier::get_Name (
  274. BSTR *pName
  275. )
  276. {
  277. HRESULT hr = WBEM_E_INVALID_PARAMETER;
  278. ResetLastErrors ();
  279. if (NULL != pName)
  280. {
  281. *pName = SysAllocString (m_name);
  282. hr = WBEM_S_NO_ERROR;
  283. }
  284. if (FAILED(hr))
  285. m_Dispatch.RaiseException (hr);
  286. return hr;
  287. }
  288. //***************************************************************************
  289. //
  290. // SCODE CSWbemQualifier::get_IsLocal
  291. //
  292. // DESCRIPTION:
  293. //
  294. // Determine whether the qualifier is local to this object
  295. //
  296. // PARAMETERS:
  297. //
  298. // pIsLocal addresses whether the qualifier is local
  299. //
  300. // RETURN VALUES:
  301. //
  302. // WBEM_S_NO_ERROR success
  303. // WBEM_E_INVALID_PARAMETER bad input parameters
  304. // WBEM_E_FAILED otherwise
  305. //
  306. //***************************************************************************
  307. HRESULT CSWbemQualifier::get_IsLocal (
  308. VARIANT_BOOL *pIsLocal
  309. )
  310. {
  311. HRESULT hr = WBEM_E_FAILED;
  312. ResetLastErrors ();
  313. if (NULL == pIsLocal)
  314. hr = WBEM_E_INVALID_PARAMETER;
  315. else
  316. {
  317. long flavor = 0;
  318. if (m_pIWbemQualifierSet)
  319. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (m_name, 0, NULL, &flavor)))
  320. *pIsLocal = (WBEM_FLAVOR_ORIGIN_LOCAL == (flavor & WBEM_FLAVOR_MASK_ORIGIN)) ?
  321. VARIANT_TRUE : VARIANT_FALSE;
  322. }
  323. if (FAILED(hr))
  324. m_Dispatch.RaiseException (hr);
  325. return hr;
  326. }
  327. //***************************************************************************
  328. //
  329. // SCODE CSWbemQualifier::get_PropagatesToSubclass
  330. //
  331. // DESCRIPTION:
  332. //
  333. // Determine whether the qualifier can be propagated to subclasses
  334. //
  335. // PARAMETERS:
  336. //
  337. // pResult holds the value on return
  338. //
  339. // RETURN VALUES:
  340. //
  341. // WBEM_S_NO_ERROR success
  342. // WBEM_E_INVALID_PARAMETER bad input parameters
  343. // WBEM_E_FAILED otherwise
  344. //
  345. //***************************************************************************
  346. HRESULT CSWbemQualifier::get_PropagatesToSubclass (
  347. VARIANT_BOOL *pResult
  348. )
  349. {
  350. HRESULT hr = WBEM_E_FAILED;
  351. ResetLastErrors ();
  352. if (NULL == pResult)
  353. hr = WBEM_E_INVALID_PARAMETER;
  354. else
  355. {
  356. long flavor = 0;
  357. if (m_pIWbemQualifierSet)
  358. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (m_name, 0, NULL, &flavor)))
  359. *pResult = (WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS & (flavor & WBEM_FLAVOR_MASK_PROPAGATION))
  360. ? VARIANT_TRUE : VARIANT_FALSE;
  361. }
  362. if (FAILED(hr))
  363. m_Dispatch.RaiseException (hr);
  364. return hr;
  365. }
  366. //***************************************************************************
  367. //
  368. // SCODE CSWbemQualifier::put_PropagatesToSubclass
  369. //
  370. // DESCRIPTION:
  371. //
  372. // Set the qualifier propagation to subclass
  373. //
  374. // PARAMETERS:
  375. //
  376. // bValue the new propagation value
  377. //
  378. // RETURN VALUES:
  379. //
  380. // WBEM_S_NO_ERROR success
  381. // WBEM_E_INVALID_PARAMETER bad input parameters
  382. // WBEM_E_FAILED otherwise
  383. //
  384. //***************************************************************************
  385. HRESULT CSWbemQualifier::put_PropagatesToSubclass (
  386. VARIANT_BOOL bValue
  387. )
  388. {
  389. HRESULT hr = WBEM_E_FAILED;
  390. ResetLastErrors ();
  391. // We have to get the value so we can preserve it
  392. if (m_pIWbemQualifierSet)
  393. {
  394. VARIANT var;
  395. VariantInit (&var);
  396. long flavor = 0;
  397. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (m_name, 0, &var, &flavor)))
  398. {
  399. // Mask out the origin bits
  400. flavor &= ~WBEM_FLAVOR_MASK_ORIGIN;
  401. // Switch on or off the subclass propagation bit
  402. if (bValue)
  403. flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
  404. else
  405. flavor &= ~WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
  406. hr = m_pIWbemQualifierSet->Put (m_name, &var, flavor);
  407. }
  408. VariantClear (&var);
  409. }
  410. if (FAILED(hr))
  411. m_Dispatch.RaiseException (hr);
  412. else
  413. {
  414. // Propagate the change to the owning site
  415. if (m_pSite)
  416. m_pSite->Update ();
  417. }
  418. return hr;
  419. }
  420. //***************************************************************************
  421. //
  422. // SCODE CSWbemQualifier::get_PropagatesToInstance
  423. //
  424. // DESCRIPTION:
  425. //
  426. // Determine whether the qualifier can be propagated to instances
  427. //
  428. // PARAMETERS:
  429. //
  430. // pResult holds the value on return
  431. //
  432. // RETURN VALUES:
  433. //
  434. // WBEM_S_NO_ERROR success
  435. // WBEM_E_INVALID_PARAMETER bad input parameters
  436. // WBEM_E_FAILED otherwise
  437. //
  438. //***************************************************************************
  439. HRESULT CSWbemQualifier::get_PropagatesToInstance (
  440. VARIANT_BOOL *pResult
  441. )
  442. {
  443. HRESULT hr = WBEM_E_FAILED;
  444. ResetLastErrors ();
  445. if (NULL == pResult)
  446. hr = WBEM_E_INVALID_PARAMETER;
  447. else
  448. {
  449. long flavor = 0;
  450. if (m_pIWbemQualifierSet)
  451. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (m_name, 0, NULL, &flavor)))
  452. *pResult = (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE & (flavor & WBEM_FLAVOR_MASK_PROPAGATION))
  453. ? VARIANT_TRUE : VARIANT_FALSE;
  454. }
  455. if (FAILED(hr))
  456. m_Dispatch.RaiseException (hr);
  457. return hr;
  458. }
  459. //***************************************************************************
  460. //
  461. // SCODE CSWbemQualifier::put_PropagatesToInstance
  462. //
  463. // DESCRIPTION:
  464. //
  465. // Set the qualifier propagation to subclass
  466. //
  467. // PARAMETERS:
  468. //
  469. // bValue the new propagation value
  470. //
  471. // RETURN VALUES:
  472. //
  473. // WBEM_S_NO_ERROR success
  474. // WBEM_E_INVALID_PARAMETER bad input parameters
  475. // WBEM_E_FAILED otherwise
  476. //
  477. //***************************************************************************
  478. HRESULT CSWbemQualifier::put_PropagatesToInstance (
  479. VARIANT_BOOL bValue
  480. )
  481. {
  482. HRESULT hr = WBEM_E_FAILED;
  483. ResetLastErrors ();
  484. // We have to get the value so we can preserve it
  485. if (m_pIWbemQualifierSet)
  486. {
  487. VARIANT var;
  488. VariantInit (&var);
  489. long flavor = 0;
  490. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (m_name, 0, &var, &flavor)))
  491. {
  492. // Mask out the origin bits
  493. flavor &= ~WBEM_FLAVOR_MASK_ORIGIN;
  494. // Switch on or off the subclass propagation bit
  495. if (bValue)
  496. flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE;
  497. else
  498. flavor &= ~WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE;
  499. hr = m_pIWbemQualifierSet->Put (m_name, &var, flavor);
  500. }
  501. VariantClear (&var);
  502. }
  503. if (FAILED(hr))
  504. m_Dispatch.RaiseException (hr);
  505. else
  506. {
  507. // Propagate the change to the owning site
  508. if (m_pSite)
  509. m_pSite->Update ();
  510. }
  511. return hr;
  512. }
  513. //***************************************************************************
  514. //
  515. // SCODE CSWbemQualifier::get_IsOverridable
  516. //
  517. // DESCRIPTION:
  518. //
  519. // Determine whether the qualifier can be overriden
  520. //
  521. // PARAMETERS:
  522. //
  523. // pResult holds the value on return
  524. //
  525. // RETURN VALUES:
  526. //
  527. // WBEM_S_NO_ERROR success
  528. // WBEM_E_INVALID_PARAMETER bad input parameters
  529. // WBEM_E_FAILED otherwise
  530. //
  531. //***************************************************************************
  532. HRESULT CSWbemQualifier::get_IsOverridable (
  533. VARIANT_BOOL *pResult
  534. )
  535. {
  536. HRESULT hr = WBEM_E_FAILED;
  537. ResetLastErrors ();
  538. if (NULL == pResult)
  539. hr = WBEM_E_INVALID_PARAMETER;
  540. else
  541. {
  542. long flavor = 0;
  543. if (m_pIWbemQualifierSet)
  544. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (m_name, 0, NULL, &flavor)))
  545. *pResult = (WBEM_FLAVOR_OVERRIDABLE == (flavor & WBEM_FLAVOR_MASK_PERMISSIONS))
  546. ? VARIANT_TRUE : VARIANT_FALSE;
  547. }
  548. if (FAILED(hr))
  549. m_Dispatch.RaiseException (hr);
  550. return hr;
  551. }
  552. //***************************************************************************
  553. //
  554. // SCODE CSWbemQualifier::put_IsOverridable
  555. //
  556. // DESCRIPTION:
  557. //
  558. // Set the qualifier propagation to subclass
  559. //
  560. // PARAMETERS:
  561. //
  562. // bValue the new propagation value
  563. //
  564. // RETURN VALUES:
  565. //
  566. // WBEM_S_NO_ERROR success
  567. // WBEM_E_INVALID_PARAMETER bad input parameters
  568. // WBEM_E_FAILED otherwise
  569. //
  570. //***************************************************************************
  571. HRESULT CSWbemQualifier::put_IsOverridable (
  572. VARIANT_BOOL bValue
  573. )
  574. {
  575. HRESULT hr = WBEM_E_FAILED;
  576. ResetLastErrors ();
  577. // We have to get the value so we can preserve it
  578. if (m_pIWbemQualifierSet)
  579. {
  580. VARIANT var;
  581. VariantInit (&var);
  582. long flavor = 0;
  583. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (m_name, 0, &var, &flavor)))
  584. {
  585. // Mask out the origin bits
  586. flavor &= ~WBEM_FLAVOR_MASK_ORIGIN;
  587. // Switch on or off the subclass propagation bit
  588. if (bValue)
  589. flavor &= ~WBEM_FLAVOR_NOT_OVERRIDABLE;
  590. else
  591. flavor |= WBEM_FLAVOR_NOT_OVERRIDABLE ;
  592. hr = m_pIWbemQualifierSet->Put (m_name, &var, flavor);
  593. }
  594. VariantClear (&var);
  595. }
  596. if (FAILED(hr))
  597. m_Dispatch.RaiseException (hr);
  598. else
  599. {
  600. // Propagate the change to the owning site
  601. if (m_pSite)
  602. m_pSite->Update ();
  603. }
  604. return hr;
  605. }
  606. //***************************************************************************
  607. //
  608. // SCODE CSWbemQualifier::get_IsAmended
  609. //
  610. // DESCRIPTION:
  611. //
  612. // Determine whether the qualifier value has been amended
  613. //
  614. // PARAMETERS:
  615. //
  616. // pResult holds the value on return
  617. //
  618. // RETURN VALUES:
  619. //
  620. // WBEM_S_NO_ERROR success
  621. // WBEM_E_INVALID_PARAMETER bad input parameters
  622. // WBEM_E_FAILED otherwise
  623. //
  624. //***************************************************************************
  625. HRESULT CSWbemQualifier::get_IsAmended (
  626. VARIANT_BOOL *pResult
  627. )
  628. {
  629. HRESULT hr = WBEM_E_FAILED;
  630. ResetLastErrors ();
  631. if (NULL == pResult)
  632. hr = WBEM_E_INVALID_PARAMETER;
  633. else
  634. {
  635. long flavor = 0;
  636. if (m_pIWbemQualifierSet)
  637. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (m_name, 0, NULL, &flavor)))
  638. *pResult = (WBEM_FLAVOR_AMENDED == (flavor & WBEM_FLAVOR_MASK_AMENDED))
  639. ? VARIANT_TRUE : VARIANT_FALSE;
  640. }
  641. if (FAILED(hr))
  642. m_Dispatch.RaiseException (hr);
  643. return hr;
  644. }
  645. //***************************************************************************
  646. //
  647. // SCODE CSWbemQualifier::CQualifierDispatchHelp::HandleError
  648. //
  649. // DESCRIPTION:
  650. //
  651. // Provide bespoke handling of error conditions in the bolierplate
  652. // Dispatch implementation.
  653. //
  654. // PARAMETERS:
  655. //
  656. // dispidMember, wFlags,
  657. // pdispparams, pvarResult,
  658. // puArgErr, All passed directly from IDispatch::Invoke
  659. // hr The return code from the bolierplate invoke
  660. //
  661. // RETURN VALUES:
  662. // The new return code (to be ultimately returned from Invoke)
  663. //
  664. // WBEM_S_NO_ERROR success
  665. // WBEM_E_INVALID_PARAMETER bad input parameters
  666. // WBEM_E_FAILED otherwise
  667. //
  668. //***************************************************************************
  669. HRESULT CSWbemQualifier::CQualifierDispatchHelp::HandleError (
  670. DISPID dispidMember,
  671. unsigned short wFlags,
  672. DISPPARAMS FAR* pdispparams,
  673. VARIANT FAR* pvarResult,
  674. UINT FAR* puArgErr,
  675. HRESULT hr
  676. )
  677. {
  678. /*
  679. * We are looking for calls on the default member (the Value property) which
  680. * supplied an argument. Since the Value property is of type VARIANT, this may
  681. * be legal but undetectable by the standard Dispatch mechanism, because in the
  682. * the case that the qualifier happens to be an array type, it is meaningful to
  683. * pass an index (the interpretation is that the index specifies an offset in
  684. * the VT_ARRAY|VT_VARIANT structure that represents the property value).
  685. */
  686. if ((DISPID_VALUE == dispidMember) && (DISP_E_NOTACOLLECTION == hr) && (pdispparams->cArgs > 0))
  687. {
  688. // Looks promising - get the object to try and resolve this
  689. ISWbemQualifier *pQualifier = NULL;
  690. // This tells use where to expect the array index to appear in the argument list
  691. UINT indexArg = (DISPATCH_PROPERTYGET & wFlags) ? 0 : 1;
  692. if (SUCCEEDED (m_pObj->QueryInterface (IID_ISWbemQualifier, (PPVOID) &pQualifier)))
  693. {
  694. // Extract the current qualifier value
  695. VARIANT vQualVal;
  696. VariantInit (&vQualVal);
  697. if (SUCCEEDED(pQualifier->get_Value (&vQualVal)) && V_ISARRAY(&vQualVal))
  698. {
  699. VARIANT indexVar;
  700. VariantInit (&indexVar);
  701. // Attempt to coerce the index argument into a value suitable for an array index
  702. if (S_OK == VariantChangeType (&indexVar, &pdispparams->rgvarg[indexArg], 0, VT_I4))
  703. {
  704. long lArrayPropInx = V_I4(&indexVar);
  705. // Is this a Get? There should be one argument (the array index)
  706. if (DISPATCH_PROPERTYGET & wFlags)
  707. {
  708. if (1 == pdispparams->cArgs)
  709. {
  710. // We should have a VT_ARRAY|VT_VARIANT value at this point; extract the
  711. // VARIANT
  712. VariantInit (pvarResult);
  713. hr = SafeArrayGetElement (vQualVal.parray, &lArrayPropInx, pvarResult);
  714. }
  715. else
  716. hr = DISP_E_BADPARAMCOUNT;
  717. }
  718. else if (DISPATCH_PROPERTYPUT & wFlags)
  719. {
  720. if (2 == pdispparams->cArgs)
  721. {
  722. /*
  723. * Try to interpret this as an array member set operation. For
  724. * this the first argument passed is the new value, and the second
  725. * is the array index.
  726. */
  727. VARIANT vNewVal;
  728. VariantInit(&vNewVal);
  729. if (SUCCEEDED(VariantCopy(&vNewVal, &pdispparams->rgvarg[0])))
  730. {
  731. // Coerce the value if necessary
  732. VARTYPE expectedVarType = GetAcceptableQualType (V_VT(&vNewVal));
  733. if (S_OK == VariantChangeType (&vNewVal, &vNewVal, 0, expectedVarType))
  734. {
  735. // Check the index is not out of bounds and, if it is, grow
  736. // the array accordingly
  737. CheckArrayBounds (vQualVal.parray, lArrayPropInx);
  738. // Set the value into the relevant index of the property value array
  739. if (S_OK == (hr =
  740. SafeArrayPutElement (vQualVal.parray, &lArrayPropInx, &vNewVal)))
  741. {
  742. // Set the entire property value
  743. if (SUCCEEDED (pQualifier->put_Value (&vQualVal)))
  744. hr = S_OK;
  745. else
  746. {
  747. hr = DISP_E_TYPEMISMATCH;
  748. if (puArgErr)
  749. *puArgErr = 0;
  750. }
  751. }
  752. }
  753. else
  754. {
  755. hr = DISP_E_TYPEMISMATCH;
  756. if (puArgErr)
  757. *puArgErr = 0;
  758. }
  759. VariantClear (&vNewVal);
  760. }
  761. }
  762. else
  763. hr = DISP_E_BADPARAMCOUNT;
  764. }
  765. }
  766. else
  767. {
  768. hr = DISP_E_TYPEMISMATCH;
  769. if (puArgErr)
  770. *puArgErr = indexArg;
  771. }
  772. VariantClear (&indexVar);
  773. }
  774. VariantClear (&vQualVal);
  775. }
  776. pQualifier->Release ();
  777. }
  778. return hr;
  779. }