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.

636 lines
14 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. //
  5. // QUALSET.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines the implementation of ISWbemQualifierSet
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. //***************************************************************************
  14. //
  15. // CSWbemQualifierSet::CSWbemQualifierSet
  16. //
  17. // DESCRIPTION:
  18. //
  19. // Constructor.
  20. //
  21. //***************************************************************************
  22. CSWbemQualifierSet::CSWbemQualifierSet(IWbemQualifierSet *pQualSet,
  23. ISWbemInternalObject *pSWbemObject) :
  24. m_pSite (NULL)
  25. {
  26. m_Dispatch.SetObj (this, IID_ISWbemQualifierSet,
  27. CLSID_SWbemQualifierSet, L"SWbemQualifierSet");
  28. m_pIWbemQualifierSet = pQualSet;
  29. m_pIWbemQualifierSet->AddRef ();
  30. if (pSWbemObject)
  31. m_pSite = new CWbemObjectSite (pSWbemObject);
  32. m_cRef=1;
  33. InterlockedIncrement(&g_cObj);
  34. }
  35. //***************************************************************************
  36. //
  37. // CSWbemQualifierSet::~CSWbemQualifierSet
  38. //
  39. // DESCRIPTION:
  40. //
  41. // Destructor.
  42. //
  43. //***************************************************************************
  44. CSWbemQualifierSet::~CSWbemQualifierSet()
  45. {
  46. InterlockedDecrement(&g_cObj);
  47. if (m_pIWbemQualifierSet)
  48. {
  49. m_pIWbemQualifierSet->EndEnumeration ();
  50. m_pIWbemQualifierSet->Release ();
  51. }
  52. if (m_pSite)
  53. m_pSite->Release ();
  54. }
  55. //***************************************************************************
  56. // HRESULT CSWbemQualifierSet::QueryInterface
  57. // long CSWbemQualifierSet::AddRef
  58. // long CSWbemQualifierSet::Release
  59. //
  60. // DESCRIPTION:
  61. //
  62. // Standard Com IUNKNOWN functions.
  63. //
  64. //***************************************************************************
  65. STDMETHODIMP CSWbemQualifierSet::QueryInterface (
  66. IN REFIID riid,
  67. OUT LPVOID *ppv
  68. )
  69. {
  70. *ppv=NULL;
  71. if (IID_IUnknown==riid)
  72. *ppv = reinterpret_cast<IUnknown*>(this);
  73. else if (IID_ISWbemQualifierSet==riid)
  74. *ppv = (ISWbemQualifierSet *)this;
  75. else if (IID_IDispatch==riid)
  76. *ppv = (IDispatch *)this;
  77. else if (IID_ISupportErrorInfo==riid)
  78. *ppv = (ISupportErrorInfo *)this;
  79. else if (IID_IProvideClassInfo==riid)
  80. *ppv = (IProvideClassInfo *)this;
  81. if (NULL!=*ppv)
  82. {
  83. ((LPUNKNOWN)*ppv)->AddRef();
  84. return NOERROR;
  85. }
  86. return ResultFromScode(E_NOINTERFACE);
  87. }
  88. STDMETHODIMP_(ULONG) CSWbemQualifierSet::AddRef(void)
  89. {
  90. InterlockedIncrement(&m_cRef);
  91. return m_cRef;
  92. }
  93. STDMETHODIMP_(ULONG) CSWbemQualifierSet::Release(void)
  94. {
  95. InterlockedDecrement(&m_cRef);
  96. if (0L!=m_cRef)
  97. return m_cRef;
  98. delete this;
  99. return 0;
  100. }
  101. //***************************************************************************
  102. // HRESULT CSWbemQualifierSet::InterfaceSupportsErrorInfo
  103. //
  104. // DESCRIPTION:
  105. //
  106. // Standard Com ISupportErrorInfo functions.
  107. //
  108. //***************************************************************************
  109. STDMETHODIMP CSWbemQualifierSet::InterfaceSupportsErrorInfo (IN REFIID riid)
  110. {
  111. return (IID_ISWbemQualifierSet == riid) ? S_OK : S_FALSE;
  112. }
  113. //***************************************************************************
  114. //
  115. // SCODE CSWbemQualifierSet::Item
  116. //
  117. // DESCRIPTION:
  118. //
  119. // Get a qualifier
  120. //
  121. // PARAMETERS:
  122. //
  123. // bsName The name of the qualifier
  124. // lFlags Flags
  125. // ppQual On successful return addresses the ISWbemQualifier
  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. // Other WBEM error codes may be returned by ConnectServer etc., in which
  134. // case these are passed on to the caller.
  135. //
  136. //***************************************************************************
  137. HRESULT CSWbemQualifierSet::Item (
  138. BSTR bsName,
  139. long lFlags,
  140. ISWbemQualifier ** ppQual
  141. )
  142. {
  143. HRESULT hr = WBEM_E_FAILED;
  144. ResetLastErrors ();
  145. if (NULL == ppQual)
  146. hr = WBEM_E_INVALID_PARAMETER;
  147. else if (m_pIWbemQualifierSet)
  148. {
  149. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Get (bsName, lFlags, NULL, NULL)))
  150. {
  151. if (!(*ppQual = new CSWbemQualifier (m_pIWbemQualifierSet, bsName, m_pSite)))
  152. hr = WBEM_E_OUT_OF_MEMORY;
  153. }
  154. }
  155. if (FAILED(hr))
  156. m_Dispatch.RaiseException (hr);
  157. return hr;
  158. }
  159. //***************************************************************************
  160. //
  161. // SCODE CSWbemQualifierSet::Add
  162. //
  163. // DESCRIPTION:
  164. //
  165. // Put a qualifier
  166. //
  167. // PARAMETERS:
  168. //
  169. // bsName The name of the qualifier
  170. // pVal Pointer to new value
  171. // flavor Flavor
  172. //
  173. // RETURN VALUES:
  174. //
  175. // WBEM_S_NO_ERROR success
  176. // WBEM_E_INVALID_PARAMETER bad input parameters
  177. // WBEM_E_FAILED otherwise
  178. //
  179. //***************************************************************************
  180. HRESULT CSWbemQualifierSet::Add (
  181. BSTR bsName,
  182. VARIANT *pVal,
  183. VARIANT_BOOL propagatesToSubclasses,
  184. VARIANT_BOOL propagatesToInstances,
  185. VARIANT_BOOL overridable,
  186. long lFlags,
  187. ISWbemQualifier **ppQualifier
  188. )
  189. {
  190. HRESULT hr = WBEM_E_FAILED;
  191. ResetLastErrors ();
  192. if ((NULL == pVal) || (NULL == ppQualifier))
  193. hr = WBEM_E_INVALID_PARAMETER;
  194. else if (m_pIWbemQualifierSet)
  195. {
  196. long flavor = 0;
  197. if (propagatesToSubclasses)
  198. flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS;
  199. if (propagatesToInstances)
  200. flavor |= WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE;
  201. if (!overridable)
  202. flavor |= WBEM_FLAVOR_NOT_OVERRIDABLE;
  203. // Make sure we have a decent qualifier value to use
  204. if(((VT_ARRAY | VT_VARIANT) == V_VT(pVal)) ||
  205. ((VT_ARRAY | VT_VARIANT | VT_BYREF) == V_VT(pVal)))
  206. {
  207. VARIANT vTemp;
  208. VariantInit (&vTemp);
  209. if (S_OK == ConvertArray(&vTemp, pVal, TRUE))
  210. hr = m_pIWbemQualifierSet->Put (bsName, &vTemp, flavor);
  211. VariantClear(&vTemp);
  212. }
  213. else if ((VT_DISPATCH == V_VT(pVal)) || ((VT_DISPATCH|VT_BYREF) == V_VT(pVal)))
  214. {
  215. // Could be a JScript IDispatchEx array
  216. VARIANT vTemp;
  217. VariantInit (&vTemp);
  218. if (S_OK == ConvertDispatchToArray (&vTemp, pVal, CIM_ILLEGAL, true))
  219. hr = m_pIWbemQualifierSet->Put (bsName, &vTemp, flavor);
  220. VariantClear (&vTemp);
  221. }
  222. else
  223. {
  224. // Only certain types, I4, R8, BOOL and BSTR are acceptable qualifier
  225. // values. Convert the data if need be
  226. VARTYPE vtOK = GetAcceptableQualType(pVal->vt);
  227. if(vtOK != pVal->vt)
  228. {
  229. VARIANT vTemp;
  230. VariantInit(&vTemp);
  231. if (S_OK == QualifierVariantChangeType (&vTemp, pVal, vtOK))
  232. hr = m_pIWbemQualifierSet->Put (bsName, &vTemp, flavor);
  233. VariantClear(&vTemp);
  234. }
  235. else
  236. hr = m_pIWbemQualifierSet->Put (bsName, pVal, flavor);
  237. }
  238. if (SUCCEEDED (hr))
  239. {
  240. if (!(*ppQualifier = new CSWbemQualifier (m_pIWbemQualifierSet, bsName, m_pSite)))
  241. hr = WBEM_E_OUT_OF_MEMORY;
  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 CSWbemQualifierSet::Remove
  257. //
  258. // DESCRIPTION:
  259. //
  260. // Delete a qualifier
  261. //
  262. // PARAMETERS:
  263. //
  264. // bsName The name of the qualifier
  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 CSWbemQualifierSet::Remove (
  274. BSTR bsName,
  275. long lFlags
  276. )
  277. {
  278. HRESULT hr = WBEM_E_FAILED;
  279. ResetLastErrors ();
  280. if (m_pIWbemQualifierSet)
  281. hr = m_pIWbemQualifierSet->Delete (bsName);
  282. // Translate default reset case to an error
  283. if (WBEM_S_RESET_TO_DEFAULT == hr)
  284. hr = wbemErrResetToDefault;
  285. if (FAILED(hr))
  286. m_Dispatch.RaiseException (hr);
  287. if (SUCCEEDED(hr) || (wbemErrResetToDefault == hr))
  288. {
  289. // Propagate the change to the owning site
  290. if (m_pSite)
  291. m_pSite->Update ();
  292. }
  293. return hr;
  294. }
  295. //***************************************************************************
  296. //
  297. // SCODE CSWbemQualifierSet::BeginEnumeration
  298. //
  299. // DESCRIPTION:
  300. //
  301. // Begin an enumeration of the qualifiers
  302. //
  303. // RETURN VALUES:
  304. //
  305. // WBEM_S_NO_ERROR success
  306. // WBEM_E_INVALID_PARAMETER bad input parameters
  307. // WBEM_E_FAILED otherwise
  308. //
  309. //***************************************************************************
  310. HRESULT CSWbemQualifierSet::BeginEnumeration (
  311. )
  312. {
  313. HRESULT hr = WBEM_E_FAILED;
  314. ResetLastErrors ();
  315. if (m_pIWbemQualifierSet)
  316. {
  317. hr = m_pIWbemQualifierSet->EndEnumeration ();
  318. hr = m_pIWbemQualifierSet->BeginEnumeration (0);
  319. }
  320. if (FAILED(hr))
  321. m_Dispatch.RaiseException (hr);
  322. return hr;
  323. }
  324. //***************************************************************************
  325. //
  326. // SCODE CSWbemQualifierSet::Next
  327. //
  328. // DESCRIPTION:
  329. //
  330. // Get next qualifier in enumeration
  331. //
  332. // PARAMETERS:
  333. //
  334. // lFlags Flags
  335. // ppQual Next qualifier (or NULL if end of enumeration)
  336. //
  337. // RETURN VALUES:
  338. //
  339. // WBEM_S_NO_ERROR success
  340. // WBEM_E_INVALID_PARAMETER bad input parameters
  341. // WBEM_E_FAILED otherwise
  342. //
  343. //***************************************************************************
  344. HRESULT CSWbemQualifierSet::Next (
  345. long lFlags,
  346. ISWbemQualifier ** ppQual
  347. )
  348. {
  349. HRESULT hr = WBEM_E_FAILED;
  350. ResetLastErrors ();
  351. if (NULL == ppQual)
  352. hr = WBEM_E_INVALID_PARAMETER;
  353. else if (m_pIWbemQualifierSet)
  354. {
  355. BSTR name = NULL;
  356. if (WBEM_S_NO_ERROR == (hr = m_pIWbemQualifierSet->Next (lFlags, &name, NULL, NULL)))
  357. {
  358. if (!(*ppQual = new CSWbemQualifier (m_pIWbemQualifierSet, name, m_pSite)))
  359. hr = WBEM_E_OUT_OF_MEMORY;
  360. SysFreeString (name);
  361. }
  362. }
  363. if (FAILED(hr))
  364. m_Dispatch.RaiseException (hr);
  365. return hr;
  366. }
  367. //***************************************************************************
  368. //
  369. // SCODE CSWbemQualifierSet::get__NewEnum
  370. //
  371. // DESCRIPTION:
  372. //
  373. // Return an IEnumVARIANT-supporting interface for collections
  374. //
  375. // PARAMETERS:
  376. //
  377. // ppUnk on successful return addresses the IUnknown interface
  378. //
  379. // RETURN VALUES:
  380. //
  381. // S_OK success
  382. // E_FAIL otherwise
  383. //
  384. //***************************************************************************
  385. HRESULT CSWbemQualifierSet::get__NewEnum (
  386. IUnknown **ppUnk
  387. )
  388. {
  389. HRESULT hr = E_FAIL;
  390. ResetLastErrors ();
  391. if (NULL != ppUnk)
  392. {
  393. *ppUnk = NULL;
  394. CQualSetEnumVar *pEnum = new CQualSetEnumVar (this);
  395. if (!pEnum)
  396. hr = WBEM_E_OUT_OF_MEMORY;
  397. else if (FAILED(hr = pEnum->QueryInterface (IID_IUnknown, (PPVOID) ppUnk)))
  398. delete pEnum;
  399. }
  400. if (FAILED(hr))
  401. m_Dispatch.RaiseException (hr);
  402. return hr;
  403. }
  404. //***************************************************************************
  405. //
  406. // SCODE CSWbemQualifierSet::get_Count
  407. //
  408. // DESCRIPTION:
  409. //
  410. // Return the number of items in the collection
  411. //
  412. // PARAMETERS:
  413. //
  414. // plCount on successful return addresses cardinality
  415. //
  416. // RETURN VALUES:
  417. //
  418. // S_OK success
  419. // E_FAIL otherwise
  420. //
  421. //***************************************************************************
  422. HRESULT CSWbemQualifierSet::get_Count (
  423. long *plCount
  424. )
  425. {
  426. HRESULT hr = E_FAIL;
  427. ResetLastErrors ();
  428. if (NULL != plCount)
  429. {
  430. *plCount = 0;
  431. /*
  432. * This is not the most efficient way of obtaining the count,
  433. * but it is the only way that is:
  434. * (a) Supported by the underlying interface
  435. * (b) Does not require access to any other interface
  436. * (c) Does not affect the current enumeration position
  437. */
  438. if (m_pIWbemQualifierSet)
  439. {
  440. SAFEARRAY *pArray = NULL;
  441. if (WBEM_S_NO_ERROR == m_pIWbemQualifierSet->GetNames (0, &pArray))
  442. {
  443. long lUBound = 0, lLBound = 0;
  444. SafeArrayGetUBound (pArray, 1, &lUBound);
  445. SafeArrayGetLBound (pArray, 1, &lLBound);
  446. *plCount = lUBound - lLBound + 1;
  447. SafeArrayDestroy (pArray);
  448. hr = S_OK;
  449. }
  450. }
  451. }
  452. if (FAILED(hr))
  453. m_Dispatch.RaiseException (hr);
  454. return hr;
  455. }
  456. //***************************************************************************
  457. //
  458. // SCODE CSWbemQualifierSet::CQualifierSetDispatchHelp::HandleError
  459. //
  460. // DESCRIPTION:
  461. //
  462. // Provide bespoke handling of error conditions in the bolierplate
  463. // Dispatch implementation.
  464. //
  465. // PARAMETERS:
  466. //
  467. // dispidMember, wFlags,
  468. // pdispparams, pvarResult,
  469. // puArgErr, All passed directly from IDispatch::Invoke
  470. // hr The return code from the bolierplate invoke
  471. //
  472. // RETURN VALUES:
  473. // The new return code (to be ultimately returned from Invoke)
  474. //
  475. // WBEM_S_NO_ERROR success
  476. // WBEM_E_INVALID_PARAMETER bad input parameters
  477. // WBEM_E_FAILED otherwise
  478. //
  479. //***************************************************************************
  480. HRESULT CSWbemQualifierSet::CQualifierSetDispatchHelp::HandleError (
  481. DISPID dispidMember,
  482. unsigned short wFlags,
  483. DISPPARAMS FAR* pdispparams,
  484. VARIANT FAR* pvarResult,
  485. UINT FAR* puArgErr,
  486. HRESULT hr
  487. )
  488. {
  489. /*
  490. * We are looking for calls on the default member (the Item method) which
  491. * are PUTs that supplied an argument. These are triggered by attempts
  492. * to set a value of a qualifier (Item) in the collection.
  493. * The first argument should be the new value for the item, and the second
  494. * argument should be the name of the item.
  495. */
  496. if ((DISPID_VALUE == dispidMember) && (DISP_E_MEMBERNOTFOUND == hr) && (2 == pdispparams->cArgs)
  497. && (DISPATCH_PROPERTYPUT == wFlags))
  498. {
  499. // Looks promising - get the object to try and resolve this
  500. ISWbemQualifierSet *pQualifierSet = NULL;
  501. if (SUCCEEDED (m_pObj->QueryInterface (IID_ISWbemQualifierSet, (PPVOID) &pQualifierSet)))
  502. {
  503. VARIANT valueVar;
  504. VariantInit (&valueVar);
  505. if (SUCCEEDED(VariantCopy(&valueVar, &pdispparams->rgvarg[0])))
  506. {
  507. VARIANT nameVar;
  508. VariantInit (&nameVar);
  509. if (SUCCEEDED(VariantCopy(&nameVar, &pdispparams->rgvarg[1])))
  510. {
  511. // Check name is a BSTR and use it to get the item
  512. if (VT_BSTR == V_VT(&nameVar))
  513. {
  514. ISWbemQualifier *pQualifier = NULL;
  515. if (SUCCEEDED (pQualifierSet->Item (V_BSTR(&nameVar), 0, &pQualifier)))
  516. {
  517. // Try and put the value
  518. if (SUCCEEDED (pQualifier->put_Value (&valueVar)))
  519. hr = S_OK;
  520. else
  521. {
  522. hr = DISP_E_TYPEMISMATCH;
  523. if (puArgErr)
  524. *puArgErr = 0;
  525. }
  526. pQualifier->Release ();
  527. }
  528. }
  529. else
  530. {
  531. hr = DISP_E_TYPEMISMATCH;
  532. if (puArgErr)
  533. *puArgErr = 1;
  534. }
  535. VariantClear (&nameVar);
  536. }
  537. VariantClear (&valueVar);
  538. }
  539. pQualifierSet->Release ();
  540. }
  541. }
  542. return hr;
  543. }