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.

325 lines
9.8 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. INTERNALMERGER.H
  5. Abstract:
  6. CInternalMerger class.
  7. History:
  8. 30-Nov-00 sanjes Created.
  9. --*/
  10. #ifndef _INTERNALMERGER_H_
  11. #define _INTERNALMERGER_H_
  12. #include "mergerthrottling.h"
  13. #include "wstlallc.h"
  14. // Forward class definitions
  15. class CWmiMergerRecord;
  16. // Base class for merger sinks - all of these will be created by the
  17. // merger and will AddRef() the merger. The merger class will be used
  18. // to create the sinks. When the Merger is destroyed, it will delete
  19. // all of the sink. Internal Merger objects MUST NOT AddRef these sinks
  20. // so we don't create a circular dependency.
  21. typedef enum
  22. {
  23. eMergerFinalSink,
  24. eMergerOwnSink,
  25. eMergerChildSink,
  26. eMergerOwnInstanceSink
  27. } MergerSinkType;
  28. class CMergerSink : public CBasicObjectSink
  29. {
  30. protected:
  31. CWmiMerger* m_pMerger;
  32. long m_lRefCount;
  33. virtual HRESULT OnFinalRelease( void ) = 0;
  34. public:
  35. CMergerSink( CWmiMerger* pMerger );
  36. virtual ~CMergerSink();
  37. /* IUnknown methods */
  38. STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR* ppvObj);
  39. STDMETHOD_(ULONG, AddRef)(THIS);
  40. STDMETHOD_(ULONG, Release)(THIS);
  41. virtual HRESULT Indicate(long lObjectCount, IWbemClassObject** pObjArray, bool bLowestLevel, long* plNumIndicated ) = 0L;
  42. };
  43. class CMergerTargetSink : public CMergerSink
  44. {
  45. protected:
  46. IWbemObjectSink* m_pDest;
  47. virtual HRESULT OnFinalRelease( void );
  48. public:
  49. CMergerTargetSink( CWmiMerger* pMerger, IWbemObjectSink* pDest );
  50. ~CMergerTargetSink();
  51. HRESULT STDMETHODCALLTYPE Indicate(long lObjectCount, IWbemClassObject** pObjArray);
  52. HRESULT STDMETHODCALLTYPE SetStatus( long lFlags, long lParam, BSTR strParam,
  53. IWbemClassObject* pObjParam );
  54. // Function allows us to track the lowest level call in the merger so we can decide
  55. // if we need to automagically report all indicated objects to the arbitrator
  56. HRESULT Indicate(long lObjectCount, IWbemClassObject** pObjArray, bool bLowestLevel, long* plNumIndicated );
  57. };
  58. // Causes the stl Map to use our allocator instead of the default
  59. struct CInternalMergerRecord
  60. {
  61. CWbemInstance* m_pData;
  62. DWORD m_dwObjSize;
  63. BOOL m_bOwn;
  64. };
  65. // Defines an allocator so we can throw exceptions
  66. class CKeyToInstRecordAlloc : public wbem_allocator<CInternalMergerRecord>
  67. {
  68. };
  69. inline bool operator==(const CKeyToInstRecordAlloc&, const CKeyToInstRecordAlloc&)
  70. { return (true); }
  71. inline bool operator!=(const CKeyToInstRecordAlloc&, const CKeyToInstRecordAlloc&)
  72. { return (false); }
  73. typedef std::map<WString, CInternalMergerRecord, WSiless, CKeyToInstRecordAlloc> MRGRKEYTOINSTMAP;
  74. typedef std::map<WString, CInternalMergerRecord, WSiless, CKeyToInstRecordAlloc>::iterator MRGRKEYTOINSTMAPITER;
  75. // This is the actual workhorse class for merging instances returned from
  76. // queries.
  77. class CInternalMerger
  78. {
  79. protected:
  80. // Helper class for scoped cleanup of memory usage
  81. class CScopedMemoryUsage
  82. {
  83. CInternalMerger* m_pInternalMerger;
  84. bool m_bCleanup;
  85. long m_lMemUsage;
  86. public:
  87. CScopedMemoryUsage( CInternalMerger* pInternalMerger )
  88. : m_pInternalMerger( pInternalMerger ), m_bCleanup( false ), m_lMemUsage( 0L ) {};
  89. ~CScopedMemoryUsage();
  90. HRESULT ReportMemoryUsage( long lMemUsage );
  91. HRESULT Cleanup( void );
  92. };
  93. class CMemberSink : public CMergerSink
  94. {
  95. protected:
  96. CInternalMerger* m_pInternalMerger;
  97. public:
  98. CMemberSink( CInternalMerger* pMerger, CWmiMerger* pWmiMerger )
  99. : CMergerSink( pWmiMerger ), m_pInternalMerger( pMerger )
  100. {}
  101. STDMETHOD_(ULONG, AddRef)(THIS);
  102. STDMETHOD(SetStatus)(long lFlags, long lParam, BSTR strParam,
  103. IWbemClassObject* pObjParam);
  104. };
  105. friend CMemberSink;
  106. class COwnSink : public CMemberSink
  107. {
  108. protected:
  109. virtual HRESULT OnFinalRelease( void );
  110. public:
  111. COwnSink(CInternalMerger* pMerger, CWmiMerger* pWmiMerger) : CMemberSink(pMerger, pWmiMerger){};
  112. ~COwnSink();
  113. STDMETHOD(Indicate)(long lObjectCount, IWbemClassObject** pObjArray);
  114. // Function allows us to track the lowest level call in the merger so we can decide
  115. // if we need to automagically report all indicated objects to the arbitrator
  116. HRESULT Indicate(long lObjectCount, IWbemClassObject** pObjArray, bool bLowestLevel, long* plNumIndicated );
  117. };
  118. friend COwnSink;
  119. class CChildSink : public CMemberSink
  120. {
  121. protected:
  122. virtual HRESULT OnFinalRelease( void );
  123. public:
  124. CChildSink(CInternalMerger* pMerger, CWmiMerger* pWmiMerger) : CMemberSink(pMerger, pWmiMerger){};
  125. ~CChildSink();
  126. STDMETHOD(Indicate)(long lObjectCount, IWbemClassObject** pObjArray);
  127. // Function allows us to track the lowest level call in the merger so we can decide
  128. // if we need to automagically report all indicated objects to the arbitrator
  129. HRESULT Indicate(long lObjectCount, IWbemClassObject** pObjArray, bool bLowestLevel, long* plNumIndicated );
  130. };
  131. class COwnInstanceSink : public CMemberSink
  132. {
  133. CCritSec m_cs;
  134. WString m_wsInstPath;
  135. IWbemClassObject* m_pMergedInstance;
  136. bool m_bTriedRetrieve;
  137. HRESULT m_hFinalStatus;
  138. protected:
  139. virtual HRESULT OnFinalRelease( void );
  140. public:
  141. COwnInstanceSink(CInternalMerger* pMerger, CWmiMerger* pWmiMerger)
  142. : CMemberSink(pMerger, pWmiMerger), m_pMergedInstance( NULL ), m_wsInstPath(),
  143. m_cs(), m_bTriedRetrieve( false ), m_hFinalStatus( WBEM_S_NO_ERROR )
  144. {};
  145. ~COwnInstanceSink();
  146. STDMETHOD(Indicate)(long lObjectCount, IWbemClassObject** pObjArray);
  147. STDMETHOD(SetStatus)(long lFlags, long lParam, BSTR strParam,
  148. IWbemClassObject* pObjParam);
  149. // This should never be called here
  150. HRESULT Indicate(long lObjectCount, IWbemClassObject** pObjArray, bool bLowestLevel, long* plNumIndicated );
  151. HRESULT SetInstancePath( LPCWSTR pwszPath );
  152. HRESULT GetObject( IWbemClassObject** ppMergedInst );
  153. void SetFinalStatus( HRESULT hRes )
  154. { if ( SUCCEEDED( m_hFinalStatus ) ) m_hFinalStatus = hRes; };
  155. };
  156. friend CChildSink;
  157. public:
  158. // Helpers for creating sinks
  159. static HRESULT CreateMergingSink( MergerSinkType eType, CInternalMerger* pMerger, CWmiMerger* pWmiMerger, CMergerSink** ppSink );
  160. // 2 stage initialization
  161. HRESULT Initialize( void );
  162. protected:
  163. COwnSink* m_pOwnSink;
  164. CChildSink* m_pChildSink;
  165. CMergerSink* m_pDest;
  166. BOOL m_bDerivedFromTarget;
  167. CWbemClass* m_pOwnClass;
  168. CWbemNamespace* m_pNamespace;
  169. IWbemContext* m_pContext;
  170. CWmiMergerRecord* m_pWmiMergerRecord;
  171. MRGRKEYTOINSTMAP m_map;
  172. BOOL m_bOwnDone;
  173. BOOL m_bChildrenDone;
  174. WString m_wsClass;
  175. long m_lRef;
  176. IServerSecurity* m_pSecurity;
  177. // This is set when we encounter an error condition and are cancelled
  178. HRESULT m_hErrorRes;
  179. // m_Throttler - sounds like a Supervillain...hmmm...
  180. CMergerThrottling m_Throttler;
  181. // Helps debug how much data this internal merger is consuming
  182. long m_lTotalObjectData;
  183. // Iterator which may require state to be kept
  184. MRGRKEYTOINSTMAPITER m_DispatchOwnIter;
  185. protected:
  186. HRESULT AddOwnObjects(long lObjectCount, IWbemClassObject** pObjArray, bool bLowestLevel, long* plNumIndicated );
  187. HRESULT AddChildObjects(long lObjectCount, IWbemClassObject** pObjArray, bool bLowestLevel, long* plNumIndicated );
  188. HRESULT AddOwnInstance( IWbemClassObject* pObj, LPCWSTR wszTargetKey,
  189. IWbemClassObject** ppMergedInstance);
  190. HRESULT RemoveInstance( LPCWSTR pwszInstancePath );
  191. HRESULT GetObjectLength( IWbemClassObject* pObj, long* plObjectSize );
  192. // inline helper - adjusts throttler totals, then allows it to release itself if
  193. // apropriate
  194. void AdjustThrottle( long lNumParentObjects, long lNumChildObjects )
  195. {
  196. // Adjust the throttler now.
  197. m_Throttler.AdjustNumParentObjects( lNumParentObjects );
  198. m_Throttler.AdjustNumChildObjects( lNumChildObjects );
  199. // Let the Throttler release itself if it can
  200. m_Throttler.ReleaseThrottle();
  201. }
  202. // Helper function to perform Indicating and throttling - a lot of the code is more or
  203. // less the same so this at least attempts to encapsulate it.
  204. HRESULT IndicateArrayAndThrottle( long lObjectCount, CRefedPointerArray<IWbemClassObject>* pObjArray,
  205. CWStringArray* pwsKeyArray, long lMapAdjustmentSize, long lNewObjectSize, bool bThrottle,
  206. bool bParent, long* plNumIndicated );
  207. void Enter() { m_Throttler.Enter(); }
  208. void Leave() { m_Throttler.Leave(); }
  209. long AddRef();
  210. long Release();
  211. void OwnIsDone();
  212. void ChildrenAreDone();
  213. void DispatchChildren();
  214. void DispatchOwn();
  215. void GetKey(IWbemClassObject* pInst, WString& wsKey);
  216. HRESULT GetOwnInstance(LPCWSTR wszKey, IWbemClassObject** ppMergedInstance);
  217. BOOL IsDone() {return m_bOwnDone && m_bChildrenDone;}
  218. void AdjustLocalObjectSize( long lAdjust )
  219. {
  220. m_lTotalObjectData += lAdjust;
  221. _DBG_ASSERT( m_lTotalObjectData >= 0L );
  222. }
  223. HRESULT ReportMemoryUsage( long lMemUsage );
  224. public:
  225. CInternalMerger(CWmiMergerRecord* pWmiMergerRecord, CMergerSink* pDest, CWbemClass* pOwnClass,
  226. CWbemNamespace* pNamespace = NULL,
  227. IWbemContext* pContext = NULL);
  228. ~CInternalMerger();
  229. void SetIsDerivedFromTarget(BOOL bIs);
  230. void Cancel( HRESULT hRes = WBEM_E_CALL_CANCELLED );
  231. CMergerSink* GetOwnSink() { if ( NULL != m_pOwnSink ) m_pOwnSink->AddRef(); return m_pOwnSink;}
  232. CMergerSink* GetChildSink() { if ( NULL != m_pChildSink ) m_pChildSink->AddRef(); return m_pChildSink; }
  233. CWmiMerger* GetWmiMerger( void );
  234. // Helper to cancel a child sink when we don't need one (i.e. if we're fully static).
  235. //void CancelChildSink( void ) { ChildrenAreDone(); }
  236. };
  237. #endif
  238.