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.

660 lines
14 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. //
  5. // PROPSET.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines the implementation of ISWbemPropertySet
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. //***************************************************************************
  14. //
  15. // CSWbemPropertySet::CSWbemPropertySet
  16. //
  17. // DESCRIPTION:
  18. //
  19. // Constructor.
  20. //
  21. //***************************************************************************
  22. CSWbemPropertySet::CSWbemPropertySet(
  23. CSWbemServices *pService,
  24. CSWbemObject *pObject,
  25. bool bSystemProperties) :
  26. m_bSystemProperties (bSystemProperties)
  27. {
  28. m_Dispatch.SetObj (this, IID_ISWbemPropertySet,
  29. CLSID_SWbemPropertySet, L"SWbemPropertySet");
  30. m_pSWbemObject = pObject;
  31. m_pSWbemObject->AddRef ();
  32. m_pIWbemClassObject = m_pSWbemObject->GetIWbemClassObject ();
  33. m_pSite = new CWbemObjectSite (m_pSWbemObject);
  34. m_pSWbemServices = pService;
  35. if (m_pSWbemServices)
  36. m_pSWbemServices->AddRef ();
  37. m_cRef=1;
  38. InterlockedIncrement(&g_cObj);
  39. }
  40. //***************************************************************************
  41. //
  42. // CSWbemPropertySet::~CSWbemPropertySet
  43. //
  44. // DESCRIPTION:
  45. //
  46. // Destructor.
  47. //
  48. //***************************************************************************
  49. CSWbemPropertySet::~CSWbemPropertySet()
  50. {
  51. InterlockedDecrement(&g_cObj);
  52. if (m_pSWbemObject)
  53. m_pSWbemObject->Release ();
  54. if (m_pIWbemClassObject)
  55. {
  56. m_pIWbemClassObject->EndEnumeration ();
  57. m_pIWbemClassObject->Release ();
  58. }
  59. if (m_pSWbemServices)
  60. m_pSWbemServices->Release ();
  61. if (m_pSite)
  62. m_pSite->Release ();
  63. }
  64. //***************************************************************************
  65. // HRESULT CSWbemPropertySet::QueryInterface
  66. // long CSWbemPropertySet::AddRef
  67. // long CSWbemPropertySet::Release
  68. //
  69. // DESCRIPTION:
  70. //
  71. // Standard Com IUNKNOWN functions.
  72. //
  73. //***************************************************************************
  74. STDMETHODIMP CSWbemPropertySet::QueryInterface (
  75. IN REFIID riid,
  76. OUT LPVOID *ppv
  77. )
  78. {
  79. *ppv=NULL;
  80. if (IID_IUnknown==riid)
  81. *ppv = reinterpret_cast<IUnknown*>(this);
  82. else if (IID_ISWbemPropertySet==riid)
  83. *ppv = (ISWbemPropertySet *)this;
  84. else if (IID_IDispatch==riid)
  85. *ppv = (IDispatch *)this;
  86. else if (IID_ISupportErrorInfo==riid)
  87. *ppv = (ISupportErrorInfo *)this;
  88. else if (IID_IProvideClassInfo==riid)
  89. *ppv = (IProvideClassInfo *)this;
  90. if (NULL!=*ppv)
  91. {
  92. ((LPUNKNOWN)*ppv)->AddRef();
  93. return NOERROR;
  94. }
  95. return ResultFromScode(E_NOINTERFACE);
  96. }
  97. STDMETHODIMP_(ULONG) CSWbemPropertySet::AddRef(void)
  98. {
  99. InterlockedIncrement(&m_cRef);
  100. return m_cRef;
  101. }
  102. STDMETHODIMP_(ULONG) CSWbemPropertySet::Release(void)
  103. {
  104. InterlockedDecrement(&m_cRef);
  105. if (0L!=m_cRef)
  106. return m_cRef;
  107. delete this;
  108. return 0;
  109. }
  110. //***************************************************************************
  111. // HRESULT CSWbemPropertySet::InterfaceSupportsErrorInfo
  112. //
  113. // DESCRIPTION:
  114. //
  115. // Standard Com ISupportErrorInfo functions.
  116. //
  117. //***************************************************************************
  118. STDMETHODIMP CSWbemPropertySet::InterfaceSupportsErrorInfo (IN REFIID riid)
  119. {
  120. return (IID_ISWbemPropertySet == riid) ? S_OK : S_FALSE;
  121. }
  122. //***************************************************************************
  123. //
  124. // SCODE CSWbemPropertySet::Item
  125. //
  126. // DESCRIPTION:
  127. //
  128. // Get a property
  129. //
  130. // PARAMETERS:
  131. //
  132. // bsName The name of the property
  133. // lFlags Flags
  134. // ppProp On successful return addresses the ISWbemProperty
  135. //
  136. // RETURN VALUES:
  137. //
  138. // WBEM_S_NO_ERROR success
  139. // WBEM_E_INVALID_PARAMETER bad input parameters
  140. // WBEM_E_FAILED otherwise
  141. //
  142. // Other WBEM error codes may be returned by ConnectServer etc., in which
  143. // case these are passed on to the caller.
  144. //
  145. //***************************************************************************
  146. HRESULT CSWbemPropertySet::Item (
  147. BSTR bsName,
  148. long lFlags,
  149. ISWbemProperty ** ppProp
  150. )
  151. {
  152. HRESULT hr = WBEM_E_FAILED;
  153. ResetLastErrors ();
  154. if (NULL == ppProp)
  155. hr = WBEM_E_INVALID_PARAMETER;
  156. else
  157. {
  158. *ppProp = NULL;
  159. if (m_pIWbemClassObject)
  160. {
  161. long flavor = 0;
  162. if (WBEM_S_NO_ERROR == (hr = m_pIWbemClassObject->Get (bsName, lFlags, NULL, NULL, &flavor)))
  163. {
  164. // First we check if this is a system property.
  165. if (((WBEM_FLAVOR_ORIGIN_SYSTEM == (flavor & WBEM_FLAVOR_MASK_ORIGIN)) && m_bSystemProperties) ||
  166. ((WBEM_FLAVOR_ORIGIN_SYSTEM != (flavor & WBEM_FLAVOR_MASK_ORIGIN)) && !m_bSystemProperties))
  167. {
  168. if (!(*ppProp = new CSWbemProperty (m_pSWbemServices, m_pSWbemObject, bsName)))
  169. hr = WBEM_E_OUT_OF_MEMORY;
  170. }
  171. else
  172. hr = WBEM_E_NOT_FOUND;
  173. }
  174. }
  175. }
  176. if (FAILED(hr))
  177. m_Dispatch.RaiseException (hr);
  178. return hr;
  179. }
  180. //***************************************************************************
  181. //
  182. // SCODE CSWbemPropertySet::Add
  183. //
  184. // DESCRIPTION:
  185. //
  186. // Add a property. Note that the property is created with a NULL value.
  187. // If a non-NULL value is required, SetValue should
  188. // be called on the returned ISWbemProperty.
  189. //
  190. // PARAMETERS:
  191. //
  192. // bsName The name of the property
  193. // cimType The CIMTYPE (only needed for new properties, o/w
  194. // should be CIM_EMPTY).
  195. // flavor Flavor
  196. //
  197. // RETURN VALUES:
  198. //
  199. // The new property (if successful)
  200. //
  201. // WBEM_S_NO_ERROR success
  202. // WBEM_E_INVALID_PARAMETER bad input parameters
  203. // WBEM_E_FAILED otherwise
  204. //
  205. //***************************************************************************
  206. HRESULT CSWbemPropertySet::Add (
  207. BSTR bsName,
  208. WbemCimtypeEnum cimType,
  209. VARIANT_BOOL bIsArray,
  210. long lFlags,
  211. ISWbemProperty **ppProp
  212. )
  213. {
  214. HRESULT hr = WBEM_E_FAILED;
  215. ResetLastErrors ();
  216. if ((NULL == ppProp) || (NULL == bsName))
  217. hr = WBEM_E_INVALID_PARAMETER;
  218. else
  219. {
  220. *ppProp = NULL;
  221. if (m_pIWbemClassObject)
  222. {
  223. /*
  224. * If we are a system property collection we
  225. * check if the name begins "__"
  226. */
  227. if (!m_bSystemProperties || (0 == _wcsnicmp (L"__", bsName, 2)))
  228. {
  229. /*
  230. * Create the property with the required cimtype and no value.
  231. */
  232. CIMTYPE cimomType = (CIMTYPE) cimType;
  233. if (bIsArray)
  234. cimomType |= CIM_FLAG_ARRAY;
  235. if (SUCCEEDED(hr = m_pIWbemClassObject->Put (bsName, 0, NULL, cimomType)))
  236. {
  237. if (!(*ppProp = new CSWbemProperty (m_pSWbemServices, m_pSWbemObject, bsName)))
  238. hr = WBEM_E_OUT_OF_MEMORY;
  239. }
  240. }
  241. }
  242. }
  243. if (FAILED(hr))
  244. m_Dispatch.RaiseException (hr);
  245. else
  246. {
  247. // Propagate the change to the owning site
  248. if (m_pSite)
  249. m_pSite->Update ();
  250. }
  251. return hr;
  252. }
  253. //***************************************************************************
  254. //
  255. // SCODE CSWbemPropertySet::Remove
  256. //
  257. // DESCRIPTION:
  258. //
  259. // Delete a property
  260. //
  261. // PARAMETERS:
  262. //
  263. // bsName The name of the property
  264. //
  265. // RETURN VALUES:
  266. //
  267. // WBEM_S_NO_ERROR success
  268. // WBEM_E_INVALID_PARAMETER bad input parameters
  269. // WBEM_E_FAILED otherwise
  270. //
  271. //***************************************************************************
  272. HRESULT CSWbemPropertySet::Remove (
  273. BSTR bsName,
  274. long lFlags
  275. )
  276. {
  277. HRESULT hr = WBEM_E_FAILED;
  278. ResetLastErrors ();
  279. if (NULL == bsName)
  280. hr = WBEM_E_INVALID_PARAMETER;
  281. else
  282. {
  283. if (m_pIWbemClassObject)
  284. hr = m_pIWbemClassObject->Delete (bsName);
  285. // Translate default reset case to an error
  286. if (WBEM_S_RESET_TO_DEFAULT == hr)
  287. hr = wbemErrResetToDefault;
  288. }
  289. if (FAILED(hr))
  290. m_Dispatch.RaiseException (hr);
  291. if (SUCCEEDED(hr) || (wbemErrResetToDefault == hr))
  292. {
  293. // Propagate the change to the owning site
  294. if (m_pSite)
  295. m_pSite->Update ();
  296. }
  297. return hr;
  298. }
  299. //***************************************************************************
  300. //
  301. // SCODE CSWbemPropertySet::BeginEnumeration
  302. //
  303. // DESCRIPTION:
  304. //
  305. // Begin an enumeration of the properties
  306. //
  307. // RETURN VALUES:
  308. //
  309. // WBEM_S_NO_ERROR success
  310. // WBEM_E_INVALID_PARAMETER bad input parameters
  311. // WBEM_E_FAILED otherwise
  312. //
  313. //***************************************************************************
  314. HRESULT CSWbemPropertySet::BeginEnumeration ()
  315. {
  316. HRESULT hr = WBEM_E_FAILED;
  317. ResetLastErrors ();
  318. /*
  319. * Note that we do not expose system properties through this
  320. * API via the property set, so we supress them here.
  321. */
  322. if (m_pIWbemClassObject)
  323. {
  324. hr = m_pIWbemClassObject->EndEnumeration ();
  325. hr = m_pIWbemClassObject->BeginEnumeration (m_bSystemProperties ?
  326. WBEM_FLAG_SYSTEM_ONLY : WBEM_FLAG_NONSYSTEM_ONLY);
  327. }
  328. if (FAILED(hr))
  329. m_Dispatch.RaiseException (hr);
  330. return hr;
  331. }
  332. //***************************************************************************
  333. //
  334. // SCODE CSWbemPropertySet::Next
  335. //
  336. // DESCRIPTION:
  337. //
  338. // Get next property in enumeration
  339. //
  340. // PARAMETERS:
  341. //
  342. // lFlags Flags
  343. // ppProp Next property (or NULL if end of enumeration)
  344. //
  345. // RETURN VALUES:
  346. //
  347. // WBEM_S_NO_ERROR success
  348. // WBEM_E_INVALID_PARAMETER bad input parameters
  349. // WBEM_E_FAILED otherwise
  350. //
  351. //***************************************************************************
  352. HRESULT CSWbemPropertySet::Next (
  353. long lFlags,
  354. ISWbemProperty ** ppProp
  355. )
  356. {
  357. HRESULT hr = WBEM_E_FAILED;
  358. ResetLastErrors ();
  359. if (NULL == ppProp)
  360. hr = WBEM_E_INVALID_PARAMETER;
  361. else
  362. {
  363. *ppProp = NULL;
  364. if (m_pIWbemClassObject)
  365. {
  366. BSTR bsName = NULL;
  367. if (WBEM_S_NO_ERROR == (hr = m_pIWbemClassObject->Next (lFlags, &bsName, NULL, NULL, NULL)))
  368. {
  369. if (!(*ppProp = new CSWbemProperty (m_pSWbemServices, m_pSWbemObject, bsName)))
  370. hr = WBEM_E_OUT_OF_MEMORY;
  371. SysFreeString (bsName);
  372. }
  373. }
  374. }
  375. if (FAILED(hr))
  376. m_Dispatch.RaiseException (hr);
  377. return hr;
  378. }
  379. //***************************************************************************
  380. //
  381. // SCODE CSWbemPropertySet::get__NewEnum
  382. //
  383. // DESCRIPTION:
  384. //
  385. // Return an IEnumVARIANT-supporting interface for collections
  386. //
  387. // PARAMETERS:
  388. //
  389. // ppUnk on successful return addresses the IUnknown interface
  390. //
  391. // RETURN VALUES:
  392. //
  393. // S_OK success
  394. // E_FAIL otherwise
  395. //
  396. //***************************************************************************
  397. HRESULT CSWbemPropertySet::get__NewEnum (
  398. IUnknown **ppUnk
  399. )
  400. {
  401. HRESULT hr = E_FAIL;
  402. ResetLastErrors ();
  403. if (NULL != ppUnk)
  404. {
  405. *ppUnk = NULL;
  406. CPropSetEnumVar *pEnum = new CPropSetEnumVar (this);
  407. if (!pEnum)
  408. hr = WBEM_E_OUT_OF_MEMORY;
  409. else if (FAILED(hr = pEnum->QueryInterface (IID_IUnknown, (PPVOID) ppUnk)))
  410. delete pEnum;
  411. }
  412. if (FAILED(hr))
  413. m_Dispatch.RaiseException (hr);
  414. return hr;
  415. }
  416. //***************************************************************************
  417. //
  418. // SCODE CSWbemPropertySet::get_Count
  419. //
  420. // DESCRIPTION:
  421. //
  422. // Return the number of items in the collection
  423. //
  424. // PARAMETERS:
  425. //
  426. // plCount on successful return addresses the count
  427. //
  428. // RETURN VALUES:
  429. //
  430. // S_OK success
  431. // E_FAIL otherwise
  432. //
  433. //***************************************************************************
  434. HRESULT CSWbemPropertySet::get_Count (
  435. long *plCount
  436. )
  437. {
  438. HRESULT hr = E_FAIL;
  439. ResetLastErrors ();
  440. if (NULL != plCount)
  441. {
  442. *plCount = 0;
  443. if (m_pIWbemClassObject)
  444. {
  445. if (m_bSystemProperties)
  446. {
  447. // Rats - have to enumerate
  448. SAFEARRAY *pArray = NULL;
  449. if (WBEM_S_NO_ERROR == m_pIWbemClassObject->GetNames (NULL,
  450. WBEM_FLAG_SYSTEM_ONLY, NULL, &pArray))
  451. {
  452. long lUBound = 0, lLBound = 0;
  453. SafeArrayGetUBound (pArray, 1, &lUBound);
  454. SafeArrayGetLBound (pArray, 1, &lLBound);
  455. *plCount = lUBound - lLBound + 1;
  456. SafeArrayDestroy (pArray);
  457. hr = S_OK;
  458. }
  459. }
  460. else
  461. {
  462. // S'easy - just use __PROPERTY_COUNT
  463. VARIANT var;
  464. VariantInit (&var);
  465. BSTR propCount = SysAllocString (OLESTR("__PROPERTY_COUNT"));
  466. if (WBEM_S_NO_ERROR == m_pIWbemClassObject->Get (propCount, 0, &var, NULL, NULL))
  467. {
  468. *plCount = var.lVal;
  469. hr = S_OK;
  470. }
  471. VariantClear (&var);
  472. SysFreeString (propCount);
  473. }
  474. }
  475. }
  476. if (FAILED(hr))
  477. m_Dispatch.RaiseException (hr);
  478. return hr;
  479. }
  480. //***************************************************************************
  481. //
  482. // SCODE CSWbemPropertySet::CPropertySetDispatchHelp::HandleError
  483. //
  484. // DESCRIPTION:
  485. //
  486. // Provide bespoke handling of error conditions in the bolierplate
  487. // Dispatch implementation.
  488. //
  489. // PARAMETERS:
  490. //
  491. // dispidMember, wFlags,
  492. // pdispparams, pvarResult,
  493. // puArgErr, All passed directly from IDispatch::Invoke
  494. // hr The return code from the bolierplate invoke
  495. //
  496. // RETURN VALUES:
  497. // The new return code (to be ultimately returned from Invoke)
  498. //
  499. // WBEM_S_NO_ERROR success
  500. // WBEM_E_INVALID_PARAMETER bad input parameters
  501. // WBEM_E_FAILED otherwise
  502. //
  503. //***************************************************************************
  504. HRESULT CSWbemPropertySet::CPropertySetDispatchHelp::HandleError (
  505. DISPID dispidMember,
  506. unsigned short wFlags,
  507. DISPPARAMS FAR* pdispparams,
  508. VARIANT FAR* pvarResult,
  509. UINT FAR* puArgErr,
  510. HRESULT hr
  511. )
  512. {
  513. /*
  514. * We are looking for calls on the default member (the Item method) which
  515. * are PUTs that supplied an argument. These are triggered by attempts
  516. * to set a value of a property (Item) in the collection.
  517. * The first argument should be the new value for the item, and the second
  518. * argument should be the name of the item.
  519. */
  520. if ((DISPID_VALUE == dispidMember) && (DISP_E_MEMBERNOTFOUND == hr) && (2 == pdispparams->cArgs)
  521. && (DISPATCH_PROPERTYPUT == wFlags))
  522. {
  523. // Looks promising - get the object to try and resolve this
  524. ISWbemPropertySet *pPropertySet = NULL;
  525. if (SUCCEEDED (m_pObj->QueryInterface (IID_ISWbemPropertySet, (PPVOID) &pPropertySet)))
  526. {
  527. VARIANT valueVar;
  528. VariantInit (&valueVar);
  529. if (SUCCEEDED(VariantCopy(&valueVar, &pdispparams->rgvarg[0])))
  530. {
  531. VARIANT nameVar;
  532. VariantInit (&nameVar);
  533. if (SUCCEEDED(VariantCopy(&nameVar, &pdispparams->rgvarg[1])))
  534. {
  535. // Check name is a BSTR and use it to get the item
  536. if (VT_BSTR == V_VT(&nameVar))
  537. {
  538. ISWbemProperty *pProperty = NULL;
  539. if (SUCCEEDED (pPropertySet->Item (V_BSTR(&nameVar), 0, &pProperty)))
  540. {
  541. // Try and put the value
  542. if (SUCCEEDED (pProperty->put_Value (&valueVar)))
  543. hr = S_OK;
  544. else
  545. {
  546. hr = DISP_E_TYPEMISMATCH;
  547. if (puArgErr)
  548. *puArgErr = 0;
  549. }
  550. pProperty->Release ();
  551. }
  552. }
  553. else
  554. {
  555. hr = DISP_E_TYPEMISMATCH;
  556. if (puArgErr)
  557. *puArgErr = 1;
  558. }
  559. VariantClear (&nameVar);
  560. }
  561. VariantClear (&valueVar);
  562. }
  563. pPropertySet->Release ();
  564. }
  565. }
  566. return hr;
  567. }