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.

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