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.

685 lines
16 KiB

  1. #include "precomp.h"
  2. #include <wbemutil.h>
  3. #include "objacces.h"
  4. /****************************************************************************
  5. CPropAccessor
  6. *****************************************************************************/
  7. HRESULT CPropAccessor::GetParentObject( ObjectArray& raObjects,
  8. _IWmiObject** ppParent )
  9. {
  10. HRESULT hr = WBEM_S_NO_ERROR;
  11. *ppParent = NULL;
  12. if ( m_pParent == NULL )
  13. {
  14. _DBG_ASSERT( raObjects.size() > 0 );
  15. *ppParent = raObjects[0];
  16. (*ppParent)->AddRef();
  17. }
  18. else
  19. {
  20. CPropVar vParent;
  21. hr = m_pParent->GetProp( raObjects, 0, &vParent, NULL );
  22. if ( SUCCEEDED(hr) )
  23. {
  24. _DBG_ASSERT( V_VT(&vParent) == VT_UNKNOWN );
  25. hr = V_UNKNOWN(&vParent)->QueryInterface( IID__IWmiObject, (void**)ppParent );
  26. }
  27. }
  28. return hr;
  29. }
  30. /****************************************************************************
  31. CFastPropAccessor
  32. *****************************************************************************/
  33. HRESULT CFastPropAccessor::GetProp( ObjectArray& raObjects,
  34. DWORD dwFlags,
  35. VARIANT* pvar,
  36. CIMTYPE* pct )
  37. {
  38. HRESULT hr = WBEM_S_NO_ERROR;
  39. if ( pvar != NULL )
  40. {
  41. CWbemPtr<_IWmiObject> pParent;
  42. hr = GetParentObject( raObjects, &pParent );
  43. if ( SUCCEEDED(hr) )
  44. {
  45. hr = ReadValue( pParent, pvar );
  46. }
  47. }
  48. if ( pct != NULL )
  49. {
  50. *pct = m_ct;
  51. }
  52. return hr;
  53. }
  54. HRESULT CFastPropAccessor::PutProp( ObjectArray& raObjects,
  55. DWORD dwFlags,
  56. VARIANT* pvar,
  57. CIMTYPE ct )
  58. {
  59. HRESULT hr = WBEM_S_NO_ERROR;
  60. if ( pvar != NULL )
  61. {
  62. CWbemPtr<_IWmiObject> pParent;
  63. hr = GetParentObject( raObjects, &pParent );
  64. if ( SUCCEEDED(hr) )
  65. {
  66. hr = WriteValue( pParent, pvar );
  67. }
  68. }
  69. return hr;
  70. }
  71. /****************************************************************************
  72. CStringPropAccessor
  73. *****************************************************************************/
  74. HRESULT CStringPropAccessor::ReadValue( _IWmiObject* pObj, VARIANT* pvar )
  75. {
  76. HRESULT hr;
  77. long cBuff;
  78. hr = pObj->ReadPropertyValue( m_lHandle, 0, &cBuff, NULL );
  79. if ( hr == WBEM_E_BUFFER_TOO_SMALL )
  80. {
  81. BSTR bstr = SysAllocStringByteLen( NULL, cBuff );
  82. if ( bstr != NULL )
  83. {
  84. hr = pObj->ReadPropertyValue( m_lHandle,
  85. cBuff,
  86. &cBuff,
  87. PBYTE(bstr) );
  88. if ( SUCCEEDED(hr) )
  89. {
  90. V_VT(pvar) = VT_BSTR;
  91. V_BSTR(pvar) = bstr;
  92. }
  93. else
  94. {
  95. SysFreeString( bstr );
  96. }
  97. }
  98. else
  99. {
  100. hr = WBEM_E_OUT_OF_MEMORY;
  101. }
  102. }
  103. else if ( SUCCEEDED(hr) )
  104. {
  105. V_VT(pvar) = VT_NULL;
  106. }
  107. return hr;
  108. }
  109. HRESULT CStringPropAccessor::WriteValue( _IWmiObject* pObj, VARIANT* pvar )
  110. {
  111. HRESULT hr = WBEM_S_NO_ERROR;
  112. if ( V_VT(pvar) == VT_BSTR )
  113. {
  114. ULONG cLen = wcslen( V_BSTR(pvar) );
  115. hr = pObj->WritePropertyValue( m_lHandle,
  116. cLen*2+2,
  117. PBYTE(V_BSTR(pvar)) );
  118. }
  119. else if ( V_VT(pvar) == VT_NULL )
  120. {
  121. //
  122. // how do we handle NULL ??
  123. //
  124. }
  125. else
  126. {
  127. hr = WBEM_E_TYPE_MISMATCH;
  128. }
  129. return hr;
  130. }
  131. /****************************************************************************
  132. CSimplePropAccessor
  133. *****************************************************************************/
  134. HRESULT CSimplePropAccessor::GetProp( ObjectArray& raObjects,
  135. DWORD dwFlags,
  136. VARIANT* pvar,
  137. CIMTYPE* pct )
  138. {
  139. HRESULT hr;
  140. if ( m_pDelegateTo == NULL )
  141. {
  142. CWbemPtr<_IWmiObject> pParent;
  143. hr = GetParentObject( raObjects, &pParent );
  144. if ( SUCCEEDED(hr) )
  145. {
  146. hr = pParent->Get( m_wsName, 0, pvar, pct, NULL );
  147. }
  148. }
  149. else
  150. {
  151. hr = m_pDelegateTo->GetProp( raObjects, dwFlags, pvar, pct );
  152. }
  153. return hr;
  154. }
  155. HRESULT CSimplePropAccessor::PutProp( ObjectArray& raObjects,
  156. DWORD dwFlags,
  157. VARIANT* pvar,
  158. CIMTYPE ct )
  159. {
  160. HRESULT hr;
  161. if ( m_pDelegateTo == NULL )
  162. {
  163. CWbemPtr<_IWmiObject> pParent;
  164. hr = GetParentObject( raObjects, &pParent );
  165. if ( SUCCEEDED(hr) )
  166. {
  167. hr = pParent->Put( m_wsName, 0, pvar, ct );
  168. }
  169. }
  170. else
  171. {
  172. hr = m_pDelegateTo->PutProp( raObjects, dwFlags, pvar, ct );
  173. }
  174. return hr;
  175. }
  176. /****************************************************************************
  177. CEmbeddedPropAccessor
  178. *****************************************************************************/
  179. HRESULT CEmbeddedPropAccessor::GetProp( ObjectArray& raObjects,
  180. DWORD dwFlags,
  181. VARIANT* pvar,
  182. CIMTYPE* pct )
  183. {
  184. HRESULT hr = WBEM_S_NO_ERROR;
  185. VariantInit( pvar );
  186. if ( raObjects.size() <= m_lObjIndex )
  187. {
  188. raObjects.resize( m_lObjIndex*2 );
  189. }
  190. _IWmiObjectP pObj = raObjects[m_lObjIndex];
  191. if ( pObj != NULL )
  192. {
  193. V_VT(pvar) = VT_UNKNOWN;
  194. V_UNKNOWN(pvar) = pObj;
  195. pObj->AddRef();
  196. }
  197. else
  198. {
  199. _IWmiObjectP pParent;
  200. hr = GetParentObject( raObjects, &pParent );
  201. if ( SUCCEEDED(hr) )
  202. {
  203. CPropVar vProp;
  204. hr = pParent->Get( m_wsName, 0, &vProp, pct, NULL );
  205. if ( SUCCEEDED(hr) )
  206. {
  207. if ( V_VT(&vProp) == VT_UNKNOWN )
  208. {
  209. hr = V_UNKNOWN(&vProp)->QueryInterface( IID__IWmiObject,
  210. (void**)&pObj );
  211. if ( SUCCEEDED(hr) )
  212. {
  213. raObjects[m_lObjIndex] = pObj;
  214. V_VT(pvar) = VT_UNKNOWN;
  215. V_UNKNOWN(pvar) = pObj;
  216. pObj->AddRef();
  217. }
  218. }
  219. else if ( V_VT(&vProp) == VT_NULL )
  220. {
  221. hr = WBEM_E_NOT_FOUND;
  222. }
  223. else
  224. {
  225. hr = WBEM_E_TYPE_MISMATCH;
  226. }
  227. }
  228. }
  229. }
  230. return hr;
  231. }
  232. HRESULT CEmbeddedPropAccessor::PutProp( ObjectArray& raObjects,
  233. DWORD dwFlags,
  234. VARIANT* pvar,
  235. CIMTYPE ct )
  236. {
  237. HRESULT hr;
  238. if ( raObjects.size() <= m_lObjIndex )
  239. {
  240. raObjects.resize( m_lObjIndex*2 );
  241. }
  242. _IWmiObjectP pParent;
  243. hr = GetParentObject( raObjects, &pParent );
  244. if ( SUCCEEDED(hr) )
  245. {
  246. hr = pParent->Put( m_wsName, 0, pvar, ct );
  247. if ( SUCCEEDED(hr) )
  248. {
  249. _IWmiObjectP pObj;
  250. if ( V_VT(pvar) == VT_UNKNOWN )
  251. {
  252. hr = V_UNKNOWN(pvar)->QueryInterface( IID__IWmiObject,
  253. (void**)&pObj );
  254. }
  255. if ( SUCCEEDED(hr) )
  256. {
  257. raObjects[m_lObjIndex] = pObj;
  258. }
  259. }
  260. }
  261. return hr;
  262. }
  263. /****************************************************************************
  264. CObjectAccessFactory - impl for IWmiObjectAccessFactory
  265. *****************************************************************************/
  266. STDMETHODIMP CObjectAccessFactory::SetObjectTemplate( IWbemClassObject* pTmpl )
  267. {
  268. HRESULT hr;
  269. if ( m_pTemplate == NULL )
  270. {
  271. hr = pTmpl->QueryInterface( IID__IWmiObject, (void**)&m_pTemplate );
  272. }
  273. else
  274. {
  275. hr = WBEM_E_INVALID_OPERATION;
  276. }
  277. return hr;
  278. }
  279. STDMETHODIMP CObjectAccessFactory::GetObjectAccess(IWmiObjectAccess** ppAccess)
  280. {
  281. HRESULT hr = WBEM_S_NO_ERROR;
  282. *ppAccess = new CObjectAccess( m_pControl );
  283. if ( *ppAccess != NULL )
  284. {
  285. (*ppAccess)->AddRef();
  286. }
  287. else
  288. {
  289. hr = WBEM_E_OUT_OF_MEMORY;
  290. }
  291. return hr;
  292. }
  293. HRESULT CObjectAccessFactory::FindOrCreateAccessor( LPCWSTR wszPropElem,
  294. BOOL bEmbedded,
  295. CPropAccessor* pParent,
  296. CPropAccessor** ppAccessor)
  297. {
  298. HRESULT hr = WBEM_S_NO_ERROR;
  299. *ppAccessor = NULL;
  300. //
  301. // determine the map the use for the prop accessors.
  302. //
  303. PropAccessMap* pmapPropAccess;
  304. if ( pParent != NULL )
  305. {
  306. _DBG_ASSERT( pParent->GetType() == CPropAccessor::e_Embedded );
  307. pmapPropAccess = &((CEmbeddedPropAccessor*)pParent)->m_mapPropAccess;
  308. }
  309. else
  310. {
  311. pmapPropAccess = &m_mapPropAccess;
  312. }
  313. //
  314. // see if an accessor already exists. If not create one.
  315. //
  316. PropAccessMap::iterator it = pmapPropAccess->find( wszPropElem );
  317. //
  318. // if we're untyped and the accessor is also a Simple
  319. // accessor, but now we know it to be embedded, convert the
  320. // accessor to an embedded one.
  321. //
  322. if ( it != pmapPropAccess->end() &&
  323. !( bEmbedded && it->second->GetType() == CPropAccessor::e_Simple ) )
  324. {
  325. *ppAccessor = it->second;
  326. (*ppAccessor)->AddRef();
  327. }
  328. else
  329. {
  330. long lHandle = -1;
  331. CIMTYPE cimtype = 0;
  332. if ( m_pTemplate != NULL )
  333. {
  334. //
  335. // get type information from the template. Also get handle
  336. // if possible. For now, we don't do anything special for
  337. // properties that are embedded.
  338. //
  339. if ( !bEmbedded )
  340. {
  341. hr = m_pTemplate->GetPropertyHandle( wszPropElem,
  342. &cimtype,
  343. &lHandle );
  344. if ( SUCCEEDED(hr) )
  345. {
  346. ;
  347. }
  348. else
  349. {
  350. cimtype = -1;
  351. hr = WBEM_S_NO_ERROR;
  352. }
  353. }
  354. }
  355. CWbemPtr<CPropAccessor> pAccessor;
  356. if ( SUCCEEDED(hr) )
  357. {
  358. if ( bEmbedded )
  359. {
  360. pAccessor = new CEmbeddedPropAccessor( wszPropElem,
  361. m_lIndexGenerator++,
  362. pParent );
  363. }
  364. else if ( m_pTemplate != NULL && lHandle != -1 && cimtype == CIM_STRING )
  365. {
  366. pAccessor = new CStringPropAccessor( lHandle, cimtype, pParent );
  367. }
  368. else
  369. {
  370. pAccessor = new CSimplePropAccessor( wszPropElem, pParent );
  371. }
  372. }
  373. //
  374. // add to the map. If an entry does exists already, then have it
  375. // delegate to our new one. The new entry becomes responsible for
  376. // the original one to keep it alive.
  377. //
  378. if ( pAccessor != NULL )
  379. {
  380. if ( it != pmapPropAccess->end() )
  381. {
  382. pAccessor->AssumeOwnership( it->second );
  383. it->second->DelegateTo( pAccessor );
  384. }
  385. (*pmapPropAccess)[wszPropElem] = pAccessor;
  386. pAccessor->AddRef();
  387. *ppAccessor = pAccessor;
  388. }
  389. else
  390. {
  391. hr = WBEM_E_OUT_OF_MEMORY;
  392. }
  393. }
  394. return hr;
  395. }
  396. STDMETHODIMP CObjectAccessFactory::GetPropHandle( LPCWSTR wszProp,
  397. DWORD dwFlags,
  398. LPVOID* ppHdl )
  399. {
  400. HRESULT hr;
  401. ENTER_API_CALL
  402. WString wsProp( wszProp );
  403. LPWSTR wszPropElem = wcstok( wsProp, L"." );
  404. CWbemPtr<CPropAccessor> pAccessor;
  405. CWbemPtr<CPropAccessor> pParentAccessor;
  406. do
  407. {
  408. LPWSTR wszNextPropElem = wcstok( NULL, L"." );
  409. pAccessor.Release();
  410. hr = FindOrCreateAccessor( wszPropElem,
  411. wszNextPropElem != NULL,
  412. pParentAccessor,
  413. &pAccessor );
  414. pParentAccessor = pAccessor;
  415. wszPropElem = wszNextPropElem;
  416. } while( SUCCEEDED(hr) && wszPropElem != NULL );
  417. if ( SUCCEEDED(hr) )
  418. {
  419. *ppHdl = pAccessor;
  420. }
  421. else
  422. {
  423. *ppHdl = NULL;
  424. }
  425. EXIT_API_CALL
  426. return hr;
  427. }
  428. /***************************************************************************
  429. CObjectAccess
  430. ****************************************************************************/
  431. STDMETHODIMP CObjectAccess::CommitChanges()
  432. {
  433. HRESULT hr = WBEM_S_NO_ERROR;
  434. ENTER_API_CALL
  435. //
  436. // commit our embeddeded objects. Since the set of embedded object
  437. // accessors is ordered by level, we will do things in the right order.
  438. //
  439. EmbeddedPropAccessSet::iterator it;
  440. for( it = m_setEmbeddedAccessorsToCommit.begin();
  441. it != m_setEmbeddedAccessorsToCommit.end(); it++ )
  442. {
  443. CEmbeddedPropAccessor* pAccessor = *it;
  444. IWbemClassObject* pProp = m_aObjects[pAccessor->GetObjectIndex()];
  445. _DBG_ASSERT( pProp != NULL );
  446. VARIANT vProp;
  447. V_VT(&vProp) = VT_UNKNOWN;
  448. V_UNKNOWN(&vProp) = pProp;
  449. hr = pAccessor->PutProp( m_aObjects, 0, &vProp, CIM_OBJECT );
  450. if ( SUCCEEDED(hr) )
  451. {
  452. ;
  453. }
  454. else
  455. {
  456. break;
  457. }
  458. }
  459. EXIT_API_CALL
  460. return hr;
  461. }
  462. STDMETHODIMP CObjectAccess::GetObject( IWbemClassObject** ppObj )
  463. {
  464. HRESULT hr;
  465. if ( m_aObjects.size() > 0 && m_aObjects[0] != NULL )
  466. {
  467. m_aObjects[0]->AddRef();
  468. *ppObj = m_aObjects[0];
  469. hr = WBEM_S_NO_ERROR;
  470. }
  471. else
  472. {
  473. *ppObj = NULL;
  474. hr = WBEM_S_FALSE;
  475. }
  476. return hr;
  477. }
  478. STDMETHODIMP CObjectAccess::SetObject( IWbemClassObject* pObj )
  479. {
  480. HRESULT hr = WBEM_S_NO_ERROR;
  481. ENTER_API_CALL
  482. m_aObjects.clear();
  483. m_setEmbeddedAccessorsToCommit.clear();
  484. if ( pObj != NULL )
  485. {
  486. CWbemPtr<_IWmiObject> pIntObj;
  487. hr = pObj->QueryInterface( IID__IWmiObject, (void**)&pIntObj );
  488. if ( SUCCEEDED(hr) )
  489. {
  490. m_aObjects.insert( m_aObjects.end(), pIntObj );
  491. }
  492. }
  493. EXIT_API_CALL
  494. return hr;
  495. }
  496. STDMETHODIMP CObjectAccess::GetProp( LPVOID pHdl,
  497. DWORD dwFlags,
  498. VARIANT* pvar,
  499. CIMTYPE* pct )
  500. {
  501. HRESULT hr;
  502. ENTER_API_CALL
  503. if ( m_aObjects.size() > 0 )
  504. {
  505. hr = ((CPropAccessor*)pHdl)->GetProp( m_aObjects, dwFlags, pvar, pct );
  506. }
  507. else
  508. {
  509. hr = WBEM_E_INVALID_OPERATION;
  510. }
  511. EXIT_API_CALL
  512. return hr;
  513. }
  514. STDMETHODIMP CObjectAccess::PutProp( LPVOID pHdl,
  515. DWORD dwFlags,
  516. VARIANT* pvar,
  517. CIMTYPE ct )
  518. {
  519. HRESULT hr;
  520. ENTER_API_CALL
  521. if ( m_aObjects.size() > 0 )
  522. {
  523. CPropAccessor* pAccessor = (CPropAccessor*)pHdl;
  524. CEmbeddedPropAccessor* pParent =
  525. (CEmbeddedPropAccessor*)pAccessor->GetParent();
  526. hr = pAccessor->PutProp( m_aObjects, dwFlags, pvar, ct );
  527. if ( SUCCEEDED(hr) )
  528. {
  529. //
  530. // if there is an
  531. if ( pParent == NULL )
  532. {
  533. ;
  534. }
  535. else
  536. {
  537. m_setEmbeddedAccessorsToCommit.insert( pParent );
  538. }
  539. }
  540. }
  541. else
  542. {
  543. hr = WBEM_E_INVALID_OPERATION;
  544. }
  545. EXIT_API_CALL
  546. return hr;
  547. }