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.

433 lines
14 KiB

  1. //******************************************************************************
  2. //
  3. // BINDING.H
  4. //
  5. // Copyright (C) 1996-1999 Microsoft Corporation
  6. //
  7. //******************************************************************************
  8. #ifndef __WMI_ESS_BINDING__H_
  9. #define __WMI_ESS_BINDING__H_
  10. #include <wbemcomn.h>
  11. #include "evtools.h"
  12. #include "evsink.h"
  13. #include <unload.h>
  14. #include <wbemstr.h>
  15. #include <sortarr.h>
  16. #include <ql.h>
  17. #include "qsink.h"
  18. class CEventConsumer;
  19. class CEventFilter;
  20. class CEssNamespace;
  21. //******************************************************************************
  22. //
  23. // Immutable after initialization
  24. //
  25. //******************************************************************************
  26. class CBinding : public CEventSink
  27. {
  28. protected:
  29. long m_lRef;
  30. CEventConsumer* m_pConsumer; // immutable after init
  31. CEventFilter* m_pFilter; // immutable after init
  32. DWORD m_dwQoS; // immutable after init
  33. bool m_bSecure; // immutable after init
  34. bool m_bSlowDown; // immutable after init
  35. bool m_bDisabledForSecurity;
  36. public:
  37. CBinding();
  38. CBinding(ADDREF CEventConsumer* pConsumer, ADDREF CEventFilter* pFilter);
  39. virtual ~CBinding();
  40. HRESULT SetEndpoints(ADDREF CEventConsumer* pConsumer,
  41. ADDREF CEventFilter* pFilter,
  42. PSID pBinderSid);
  43. void DisableForSecurity();
  44. INTERNAL CEventConsumer* GetConsumer() NOCS {return m_pConsumer;}
  45. INTERNAL CEventFilter* GetFilter() NOCS {return m_pFilter;}
  46. DWORD GetQoS() NOCS;
  47. bool IsSynch() NOCS;
  48. bool IsSecure() NOCS;
  49. bool ShouldSlowDown() NOCS;
  50. HRESULT Indicate( long lNumEvents, IWbemEvent** apEvents,
  51. CEventContext* pContext);
  52. };
  53. class CEventConsumer : public CQueueingEventSink
  54. {
  55. protected:
  56. CRefedPointerSmallArray<CBinding> m_apBindings;
  57. CInternalString m_isKey;
  58. PBYTE m_pOwnerSid;
  59. public:
  60. CEventConsumer(CEssNamespace* pNamespace);
  61. virtual ~CEventConsumer();
  62. inline const CInternalString& GetKey() const {return m_isKey;}
  63. inline const PSID GetOwner() {return m_pOwnerSid;}
  64. virtual BOOL IsPermanent() const {return FALSE;}
  65. virtual BOOL UnloadIfUnusedFor(CWbemInterval Interval) {return FALSE;}
  66. virtual BOOL IsFullyUnloaded() {return TRUE;}
  67. virtual HRESULT ResetProviderRecord(LPCWSTR wszProviderRef)
  68. {return S_FALSE;}
  69. virtual HRESULT Shutdown(bool bQuiet = false) {return S_OK;}
  70. virtual HRESULT Validate(IWbemClassObject* pLogicalConsumer) {return S_OK;}
  71. HRESULT EnsureReferences(CEventFilter* pFilter, CBinding* pBinding);
  72. HRESULT EnsureNotReferences(CEventFilter* pFilter);
  73. HRESULT Unbind();
  74. HRESULT ConsumeFromBinding(CBinding* pBinding,
  75. long lNumEvents, IWbemEvent** apEvents,
  76. CEventContext* pContext);
  77. HRESULT GetAssociatedFilters(
  78. CRefedPointerSmallArray<CEventFilter>& apFilters);
  79. virtual HRESULT ActuallyDeliver(long lNumEvents, IWbemEvent** apEvents,
  80. BOOL bSecure, CEventContext* pContext) = 0;
  81. virtual HRESULT ReportEventDrop(IWbemEvent* pEvent);
  82. };
  83. //*****************************************************************************
  84. //
  85. // m_cs controls access to data members. No critical sections may be acquired
  86. // while holding m_cs.
  87. //
  88. // m_csChangeBindings controls activation/deactivation requests on this filter.
  89. // As long as an activation/deactivation request is proceeding, no other
  90. // such request can get underway. This ensures that the activation state
  91. // state of the filter always matches the state of its bindings. At the
  92. // same time, the filter can filter events while such a request executes,
  93. // since m_cs is not held. Only m_cs can be acquired while holding
  94. // m_csActivation
  95. //
  96. //*****************************************************************************
  97. class CEventFilter : public CEventSink, public CUpdateLockable
  98. {
  99. protected:
  100. CEssNamespace* m_pNamespace; // immutable after init
  101. CRefedPointerSmallArray<CBinding> m_apBindings; // changes
  102. CCritSec m_cs;
  103. // CCritSec m_csChangeBindings; // don't need since the namespace is locked
  104. bool m_bSingleAsync;
  105. CInternalString m_isKey;
  106. PBYTE m_pOwnerSid;
  107. long m_lSecurityChecksRemaining;
  108. long m_lSubjectToSDSCount;
  109. bool m_bCheckSDs;
  110. HRESULT m_hresFilterError;
  111. bool m_bHasBeenValid;
  112. IWbemToken* m_pToken;
  113. HRESULT m_hresTokenError;
  114. DWORD m_dwLastTokenAttempt;
  115. bool m_bReconstructOnHit;
  116. HRESULT m_hresPollingError;
  117. enum
  118. {
  119. e_Inactive, e_Active
  120. } m_eState; //changes
  121. enum
  122. {
  123. e_Unknown, e_PermanentlyInvalid, e_TemporarilyInvalid, e_Valid
  124. } m_eValidity;
  125. friend class CEventForwardingSink;
  126. class CEventForwardingSink : public CAbstractEventSink
  127. {
  128. protected:
  129. CEventFilter* m_pOwner;
  130. public:
  131. CEventForwardingSink(CEventFilter* pOwner) : m_pOwner(pOwner){}
  132. ULONG STDMETHODCALLTYPE AddRef() {return m_pOwner->AddRef();}
  133. ULONG STDMETHODCALLTYPE Release() {return m_pOwner->Release();}
  134. HRESULT Indicate(long lNumEvents, IWbemEvent** apEvents,
  135. CEventContext* pContext);
  136. } m_ForwardingSink; // immutable
  137. class CClassChangeSink : public CEmbeddedObjectSink<CEventFilter>
  138. {
  139. public:
  140. CClassChangeSink(CEventFilter* pOwner) :
  141. CEmbeddedObjectSink<CEventFilter>(pOwner){}
  142. STDMETHOD(Indicate)(long lNumEvents, IWbemEvent** apEvents);
  143. } m_ClassChangeSink; // immutable
  144. CWbemPtr<IWbemObjectSink> m_pActualClassChangeSink;
  145. friend CEventForwardingSink;
  146. public:
  147. CEventFilter(CEssNamespace* pEssNamespace);
  148. virtual ~CEventFilter();
  149. virtual bool IsInternal() { return false; }
  150. //**************
  151. // Acquire CSs
  152. //**************
  153. HRESULT EnsureReferences(CEventConsumer* pConsumer, CBinding* pBinding);
  154. HRESULT EnsureNotReferences(CEventConsumer* pConsumer);
  155. HRESULT Unbind(bool bShuttingDown = false);
  156. bool IsBound();
  157. virtual BOOL DoesNeedType(int nType) const = 0;
  158. HRESULT Indicate(long lNumEvents, IWbemEvent** apEvents,
  159. CEventContext* pContext) = 0;
  160. virtual HRESULT LockForUpdate();
  161. virtual HRESULT UnlockForUpdate();
  162. //*******************
  163. // Do not acquire CSs
  164. //*******************
  165. virtual HRESULT GetCoveringQuery(DELETE_ME LPWSTR& wszQueryLanguage,
  166. DELETE_ME LPWSTR& wszQuery, BOOL& bExact,
  167. DELETE_ME QL_LEVEL_1_RPN_EXPRESSION** ppExp) = 0;
  168. virtual HRESULT GetEventNamespace(DELETE_ME LPWSTR* pwszNamespace);
  169. virtual DWORD GetForceFlags() {return 0;}
  170. virtual bool DoesAllowInvalid()
  171. {return ((GetForceFlags() & WBEM_FLAG_STRONG_VALIDATION) == 0);}
  172. bool HasBeenValid() {return m_bHasBeenValid;}
  173. inline const CInternalString& GetKey() {return m_isKey;}
  174. inline const PSID GetOwner() { return m_pOwnerSid; }
  175. virtual CAbstractEventSink* GetNonFilteringSink() = 0;
  176. virtual HRESULT GetReady(LPCWSTR wszQuery,
  177. QL_LEVEL_1_RPN_EXPRESSION* pExp) = 0;
  178. virtual HRESULT GetReadyToFilter() = 0;
  179. virtual BOOL IsPermanent() = 0;
  180. virtual HRESULT SetThreadSecurity( IUnknown** ppNewContext ) = 0;
  181. virtual HRESULT ObtainToken(IWbemToken** ppToken) = 0;
  182. virtual void Park(){}
  183. virtual const PSECURITY_DESCRIPTOR GetEventAccessSD() { return NULL; }
  184. void MarkAsPermanentlyInvalid(HRESULT hres);
  185. void MarkAsTemporarilyInvalid(HRESULT hres);
  186. void MarkAsValid();
  187. void SetInactive();
  188. BOOL IsActive();
  189. HRESULT GetFilterError();
  190. void MarkReconstructOnHit(bool bReconstruct = true);
  191. void SetPollingError(HRESULT hres) {m_hresPollingError = hres;}
  192. HRESULT GetPollingError() {return m_hresPollingError;}
  193. void IncrementRemainingSecurityChecks();
  194. void DecrementRemainingSecurityChecks(HRESULT hresProvider);
  195. INTERNAL IWbemObjectSink* GetClassChangeSink() {return &m_ClassChangeSink;}
  196. //
  197. // this so the caller can wrap the class change sink however they want and
  198. // store the resultant sink with the filter object.
  199. //
  200. HRESULT SetActualClassChangeSink( IWbemObjectSink* pSink,
  201. IWbemObjectSink** ppOldSink );
  202. HRESULT Reactivate();
  203. protected:
  204. HRESULT Deliver(long lNumEvents, IWbemEvent** apEvents,
  205. CEventContext* pContext);
  206. HRESULT AdjustActivation();
  207. void AdjustSingleAsync();
  208. BOOL DoesNeedDeactivation();
  209. HRESULT AccessCheck( CEventContext* pEventContext, IWbemEvent* pEvent );
  210. HRESULT CheckEventAccessToFilter( IServerSecurity* pProvCtx );
  211. HRESULT CheckFilterAccessToEvent( PSECURITY_DESCRIPTOR pEventSD );
  212. friend class CBindingTable;
  213. };
  214. class CConsumerWatchInstruction : public CBasicUnloadInstruction
  215. {
  216. protected:
  217. class CBindingTableRef* m_pTableRef;
  218. static CWbemInterval mstatic_Interval;
  219. public:
  220. CConsumerWatchInstruction(CBindingTable* pTable);
  221. ~CConsumerWatchInstruction();
  222. HRESULT Fire(long, CWbemTime);
  223. static void staticInitialize(IWbemServices* pRoot);
  224. };
  225. //******************************************************************************
  226. //
  227. // This class is a comparer (as required by the sorted array template) that
  228. // compares an object with CInternalString* GetKey() method (e.g. filter or
  229. // consumer) to another such object or an LPCWSTR
  230. //
  231. //******************************************************************************
  232. template<class TObject>
  233. class CInternalStringComparer
  234. {
  235. public:
  236. int Compare(TObject* p1, TObject* p2) const
  237. {
  238. return p1->GetKey().Compare(p2->GetKey());
  239. }
  240. int Compare(const CInternalString& isKey, TObject* p) const
  241. {
  242. return - p->GetKey().Compare(isKey);
  243. }
  244. int Compare(LPCWSTR wszKey, TObject* p) const
  245. {
  246. return - p->GetKey().Compare(wszKey);
  247. }
  248. int Compare(const CInternalString& isKey1,
  249. const CInternalString& isKey2) const
  250. {
  251. return isKey1.Compare(isKey2);
  252. }
  253. const CInternalString& Extract(TObject* p) const
  254. {
  255. return p->GetKey();
  256. }
  257. };
  258. template<class TObject>
  259. class CSortedRefedKeyedPointerArray :
  260. public CRefedPointerSortedTree<CInternalString, TObject,
  261. CInternalStringComparer<TObject> >
  262. {
  263. typedef CRefedPointerSortedTree<CInternalString, TObject,
  264. CInternalStringComparer<TObject> > TParent;
  265. public:
  266. inline bool Find(LPCWSTR wszKey, TObject** ppObj)
  267. {
  268. CInternalString is(wszKey);
  269. if (is.IsEmpty())
  270. return false;
  271. return TParent::Find(is, ppObj);
  272. }
  273. inline bool Remove(LPCWSTR wszKey, TObject** ppObj)
  274. {
  275. CInternalString is(wszKey);
  276. if (is.IsEmpty())
  277. return false;
  278. return TParent::Remove(is, ppObj);
  279. }
  280. inline typename TParent::TIterator Remove(typename TParent::TIterator it, TObject** ppObj)
  281. {
  282. return TParent::Remove(it, ppObj);
  283. }
  284. };
  285. /*
  286. template<class TObject>
  287. class CSortedRefedKeyedPointerArray :
  288. public CRefedPointerSortedArray<LPCWSTR, TObject,
  289. CInternalStringComparer<TObject> >
  290. {
  291. };
  292. */
  293. class CBindingTableRef
  294. {
  295. protected:
  296. long m_lRef;
  297. CBindingTable* m_pTable;
  298. CCritSec m_cs;
  299. protected:
  300. virtual ~CBindingTableRef();
  301. public:
  302. CBindingTableRef(CBindingTable* pTable);
  303. void AddRef();
  304. void Release();
  305. void Disconnect();
  306. HRESULT UnloadUnusedConsumers(CWbemInterval Interval);
  307. HRESULT GetNamespace(RELEASE_ME CEssNamespace** ppNamespace);
  308. };
  309. class CBindingTable
  310. {
  311. protected:
  312. CEssNamespace* m_pNamespace;
  313. CCritSec m_cs;
  314. CSortedRefedKeyedPointerArray<CEventFilter> m_apFilters;
  315. typedef CSortedRefedKeyedPointerArray<CEventFilter>::TIterator
  316. TFilterIterator;
  317. CSortedRefedKeyedPointerArray<CEventConsumer> m_apConsumers;
  318. typedef CSortedRefedKeyedPointerArray<CEventConsumer>::TIterator
  319. TConsumerIterator;
  320. long m_lNumPermConsumers;
  321. CConsumerWatchInstruction* m_pInstruction;
  322. BOOL m_bUnloadInstruction;
  323. CBindingTableRef* m_pTableRef;
  324. public:
  325. //****************************************************
  326. // all members should be assumed to acquire random CSs
  327. //****************************************************
  328. CBindingTable(CEssNamespace* pNamespace);
  329. void Clear( bool bSkipClean );
  330. ~CBindingTable() { Clear(true); }
  331. HRESULT AddEventFilter(CEventFilter* pFilter);
  332. HRESULT AddEventConsumer(CEventConsumer* pConsumer);
  333. HRESULT FindEventFilter(LPCWSTR wszKey, RELEASE_ME CEventFilter** ppFilter);
  334. HRESULT FindEventConsumer(LPCWSTR wszKey,
  335. RELEASE_ME CEventConsumer** ppConsumer);
  336. HRESULT RemoveEventFilter(LPCWSTR wszKey);
  337. HRESULT RemoveEventConsumer(LPCWSTR wszKey);
  338. HRESULT Bind(LPCWSTR wszFilterKey, LPCWSTR wszConsumerKey,
  339. CBinding* pBinding, PSID pBinderSid);
  340. HRESULT Unbind(LPCWSTR wszFilterKey, LPCWSTR wszConsumerKey);
  341. BOOL DoesHavePermanentConsumers();
  342. HRESULT ListActiveNamespaces(CWStringArray& wsNamespaces);
  343. HRESULT ResetProviderRecords(LPCWSTR wszProvider);
  344. HRESULT RemoveConsumerWithFilters(LPCWSTR wszConsumerKey);
  345. HRESULT ReactivateAllFilters();
  346. HRESULT RemoveConsumersStartingWith(LPCWSTR wszPrefix);
  347. HRESULT EnsureConsumerWatchInstruction();
  348. void Park();
  349. void DumpStatistics(FILE* f, long lFlags);
  350. BOOL GetEventFilters( CRefedPointerArray< CEventFilter > & apEventFilters );
  351. protected:
  352. void MarkRemoval(CEventConsumer* pConsumer);
  353. HRESULT UnloadUnusedConsumers(CWbemInterval Interval);
  354. BOOL GetConsumers(CRefedPointerArray<CEventConsumer>& apConsumers);
  355. friend CConsumerWatchInstruction;
  356. friend CBindingTableRef;
  357. };
  358. #endif