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.

351 lines
10 KiB

  1. #ifndef __OBJACCES_H__
  2. #define __OBJACCES_H__
  3. #include <wbemint.h>
  4. #include <wstring.h>
  5. #include <comutl.h>
  6. #include <arrtempl.h>
  7. #include <unk.h>
  8. #include <map>
  9. #include <vector>
  10. #include <set>
  11. #include <wstlallc.h>
  12. #include "wmimsg.h"
  13. typedef CWbemPtr<_IWmiObject> _IWmiObjectP;
  14. typedef std::vector< _IWmiObjectP, wbem_allocator<_IWmiObjectP> > ObjectArray;
  15. /****************************************************************************
  16. CPropAccessor - base class for all prop accessors. Property Accessors are
  17. passed back from the GetPropHandle() method of IWmiObjectAccessFactory.
  18. *****************************************************************************/
  19. class CPropAccessor : public CUnk
  20. {
  21. protected:
  22. //
  23. // if the object we're accessing is not a top level object, then we'll
  24. // have a parent accessor to get it. Cannot hold reference here,
  25. // because in some cases the parent may hold a reference on the child and
  26. // we'd have a circular reference. It will not be possible though for a
  27. // parent to be deleted out from the child.
  28. //
  29. CPropAccessor* m_pParent;
  30. //
  31. // Accessor to delegate to. Sometimes, once a prop accessor is
  32. // handed out, we learn more about the property ( e.g. its type )
  33. // and it would be beneficial to have the original accessor delegate
  34. // to a more efficient one. we don't hold a reference here because
  35. // the delegate will assume ownership of this object and will hold
  36. // a reference on it. Holding a reference to the delegate would cause
  37. // a circular reference.
  38. //
  39. CPropAccessor* m_pDelegateTo;
  40. //
  41. // whenever a prop accessor is replaced by a more efficient one, it
  42. // is removed from the map. Since the map holds onto the ref that
  43. // keeps the accessor alive, we need to the new accessor be responsible
  44. // for cleaning up the original one. The original one is potentially
  45. // still being used by the client ( but now delegates to the new accessor )
  46. // ane we have to keep it alive for the lifetime of the access factory.
  47. //
  48. CWbemPtr<CPropAccessor> m_pResponsibleFor;
  49. //
  50. // level of the property - 0 means its a property on a top level object.
  51. //
  52. int m_nLevel;
  53. HRESULT GetParentObject( ObjectArray& raObjects, _IWmiObject** ppParent );
  54. void* GetInterface( REFIID ) { return NULL; }
  55. public:
  56. CPropAccessor( CPropAccessor* pParent )
  57. : m_pParent( pParent ), m_pDelegateTo( NULL )
  58. {
  59. if ( pParent == NULL )
  60. m_nLevel = 0;
  61. else
  62. m_nLevel = pParent->GetLevel() + 1;
  63. }
  64. int GetLevel() const { return m_nLevel; }
  65. CPropAccessor* GetParent() { return m_pParent; }
  66. enum AccessorType_e { e_Simple, e_Fast, e_Embedded };
  67. virtual ~CPropAccessor() {}
  68. virtual HRESULT GetProp( ObjectArray& raObjects,
  69. DWORD dwFlags,
  70. VARIANT* pvar,
  71. CIMTYPE* pct ) = 0;
  72. virtual HRESULT PutProp( ObjectArray& raObjects,
  73. DWORD dwFlags,
  74. VARIANT* pvar,
  75. CIMTYPE ct ) = 0;
  76. virtual AccessorType_e GetType() = 0;
  77. void AssumeOwnership( CPropAccessor* pAccessor )
  78. {
  79. m_pResponsibleFor = pAccessor;
  80. }
  81. void DelegateTo( CPropAccessor* pAccessor )
  82. {
  83. m_pDelegateTo = pAccessor;
  84. }
  85. };
  86. typedef CWbemPtr<CPropAccessor> CPropAccessorP;
  87. typedef std::map< WString,
  88. CPropAccessorP,
  89. WSiless,
  90. wbem_allocator<CPropAccessorP> > PropAccessMap;
  91. /*****************************************************************************
  92. CEmbeddedPropAccessor - accessor for an embedded object property.
  93. This impl caches the embedded object that is accessed to optimize
  94. subsequent accesses.
  95. ******************************************************************************/
  96. class CEmbeddedPropAccessor : public CPropAccessor
  97. {
  98. //
  99. // name of the embedded object property.
  100. //
  101. WString m_wsName;
  102. //
  103. // the index in the object array where the embedded obj will be cached
  104. // when accessed for the first time.
  105. //
  106. long m_lObjIndex;
  107. //
  108. // child accessors for the embedded object.
  109. //
  110. PropAccessMap m_mapPropAccess;
  111. friend class CObjectAccessFactory;
  112. public:
  113. CEmbeddedPropAccessor( LPCWSTR wszName,
  114. long lObjIndex,
  115. CPropAccessor* pParent = NULL )
  116. : CPropAccessor( pParent ), m_wsName( wszName ), m_lObjIndex( lObjIndex )
  117. {
  118. }
  119. HRESULT GetProp( ObjectArray& raObjects,
  120. DWORD dwFlags,
  121. VARIANT* pvar,
  122. CIMTYPE* pct );
  123. HRESULT PutProp( ObjectArray& raObjects,
  124. DWORD dwFlags,
  125. VARIANT* pvar,
  126. CIMTYPE ct );
  127. AccessorType_e GetType() { return e_Embedded; }
  128. int GetObjectIndex() { return m_lObjIndex; }
  129. };
  130. /*****************************************************************************
  131. CSimplePropAccessor - simple accessor for non-embedded object properties.
  132. ******************************************************************************/
  133. class CSimplePropAccessor : public CPropAccessor
  134. {
  135. //
  136. // name of the embedded object property.
  137. //
  138. WString m_wsName;
  139. public:
  140. CSimplePropAccessor( LPCWSTR wszName, CPropAccessor* pParent = NULL )
  141. : CPropAccessor( pParent ), m_wsName( wszName ) { }
  142. HRESULT GetProp( ObjectArray& raObjects,
  143. DWORD dwFlags,
  144. VARIANT* pvar,
  145. CIMTYPE* pct );
  146. HRESULT PutProp( ObjectArray& raObjects,
  147. DWORD dwFlags,
  148. VARIANT* pvar,
  149. CIMTYPE ct );
  150. AccessorType_e GetType() { return e_Simple; }
  151. };
  152. /*****************************************************************************
  153. CFastPropAccessor - fast accessor base for non-embedded object properties.
  154. Is used when the type of the property is known at property handle creation.
  155. ******************************************************************************/
  156. class CFastPropAccessor : public CPropAccessor
  157. {
  158. protected:
  159. long m_lHandle;
  160. CIMTYPE m_ct;
  161. public:
  162. CFastPropAccessor( long lHandle, CIMTYPE ct, CPropAccessor* pParent=NULL )
  163. : CPropAccessor( pParent ), m_lHandle( lHandle ), m_ct( ct ) { }
  164. HRESULT GetProp( ObjectArray& raObjects,
  165. DWORD dwFlags,
  166. VARIANT* pvar,
  167. CIMTYPE* pct );
  168. HRESULT PutProp( ObjectArray& raObjects,
  169. DWORD dwFlags,
  170. VARIANT* pvar,
  171. CIMTYPE ct );
  172. AccessorType_e GetType() { return e_Fast; }
  173. virtual HRESULT ReadValue( _IWmiObject* pObj, VARIANT* pvar ) = 0;
  174. virtual HRESULT WriteValue( _IWmiObject* pObj, VARIANT* pvar ) = 0;
  175. };
  176. /*****************************************************************************
  177. CStringPropAccessor
  178. ******************************************************************************/
  179. class CStringPropAccessor : public CFastPropAccessor
  180. {
  181. public:
  182. CStringPropAccessor( long lHandle, CIMTYPE ct, CPropAccessor* pParent=NULL)
  183. : CFastPropAccessor( lHandle, ct, pParent ) { }
  184. HRESULT ReadValue( _IWmiObject* pObj, VARIANT* pvar );
  185. HRESULT WriteValue( _IWmiObject* pObj, VARIANT* pvar );
  186. };
  187. /****************************************************************************
  188. CObjectAccessFactory - impl for IWmiObjectAccessFactory
  189. *****************************************************************************/
  190. class CObjectAccessFactory
  191. : public CUnkBase<IWmiObjectAccessFactory, &IID_IWmiObjectAccessFactory>
  192. {
  193. _IWmiObjectP m_pTemplate;
  194. PropAccessMap m_mapPropAccess;
  195. long m_lIndexGenerator;
  196. HRESULT FindOrCreateAccessor( LPCWSTR wszPropElem,
  197. BOOL bEmbedded,
  198. CPropAccessor* pParent,
  199. CPropAccessor** ppAccessor );
  200. public:
  201. CObjectAccessFactory( CLifeControl* pControl )
  202. : CUnkBase<IWmiObjectAccessFactory,&IID_IWmiObjectAccessFactory>(pControl),
  203. m_lIndexGenerator(1)
  204. {
  205. }
  206. STDMETHOD(SetObjectTemplate)( IWbemClassObject* pTemplate );
  207. STDMETHOD(GetObjectAccess)( IWmiObjectAccess** ppAccess );
  208. STDMETHOD(GetPropHandle)( LPCWSTR wszProp, DWORD dwFlags, LPVOID* ppHdl );
  209. };
  210. /****************************************************************************
  211. CObjectAccess - impl for IWmiObjectAccess.
  212. *****************************************************************************/
  213. class CObjectAccess : public CUnkBase<IWmiObjectAccess,&IID_IWmiObjectAccess>
  214. {
  215. ObjectArray m_aObjects;
  216. class CEmbeddedPropAccessorCompare
  217. {
  218. public:
  219. bool operator() ( const CEmbeddedPropAccessor* pA,
  220. const CEmbeddedPropAccessor* pB ) const
  221. {
  222. bool bRet;
  223. if ( !(pA == pB) )
  224. if ( pA->GetLevel() == pB->GetLevel() )
  225. bRet = pA < pB;
  226. else
  227. bRet = pA->GetLevel() > pB->GetLevel();
  228. else
  229. bRet = FALSE;
  230. return bRet;
  231. }
  232. };
  233. typedef std::set< CEmbeddedPropAccessor*,
  234. CEmbeddedPropAccessorCompare,
  235. wbem_allocator<CEmbeddedPropAccessor*> > EmbeddedPropAccessSet;
  236. EmbeddedPropAccessSet m_setEmbeddedAccessorsToCommit;
  237. public:
  238. CObjectAccess( CLifeControl* pControl )
  239. : CUnkBase<IWmiObjectAccess,&IID_IWmiObjectAccess> ( pControl ) {}
  240. STDMETHOD(SetObject)( IWbemClassObject* pObj );
  241. STDMETHOD(GetObject)( IWbemClassObject** ppObj );
  242. //
  243. // should support flags that describe what is going to be done
  244. // with the value. If it's going to be put into another object then
  245. // we'll give back a value which can only be used for that purpose. More
  246. // efficient. e.g. we could use the get/put prop pointer methods
  247. //
  248. STDMETHOD(GetProp)( LPVOID pHdl,
  249. DWORD dwFlags,
  250. VARIANT* pvar,
  251. CIMTYPE* pct );
  252. STDMETHOD(PutProp)( LPVOID pHdl,
  253. DWORD dwFlags,
  254. VARIANT* pvar,
  255. CIMTYPE ct );
  256. STDMETHOD(CommitChanges)();
  257. };
  258. #endif // __OBJACCES_H__