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.

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