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.

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