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.

462 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. bool m_bCheckSDs;
  109. HRESULT m_hresFilterError;
  110. bool m_bHasBeenValid;
  111. IWbemToken* m_pToken;
  112. HRESULT m_hresTokenError;
  113. DWORD m_dwLastTokenAttempt;
  114. WString m_wsGuardQuery;
  115. WString m_wsGuardNamespace;
  116. bool m_bDeactivatedByGuard;
  117. bool m_bGuardError;
  118. bool m_bReconstructOnHit;
  119. HRESULT m_hresPollingError;
  120. enum
  121. {
  122. e_Inactive, e_Active
  123. } m_eState; //changes
  124. enum
  125. {
  126. e_Unknown, e_PermanentlyInvalid, e_TemporarilyInvalid, e_Valid
  127. } m_eValidity;
  128. friend class CEventForwardingSink;
  129. class CEventForwardingSink : public CAbstractEventSink
  130. {
  131. protected:
  132. CEventFilter* m_pOwner;
  133. public:
  134. CEventForwardingSink(CEventFilter* pOwner) : m_pOwner(pOwner){}
  135. ULONG STDMETHODCALLTYPE AddRef() {return m_pOwner->AddRef();}
  136. ULONG STDMETHODCALLTYPE Release() {return m_pOwner->Release();}
  137. HRESULT Indicate(long lNumEvents, IWbemEvent** apEvents,
  138. CEventContext* pContext);
  139. } m_ForwardingSink; // immutable
  140. class CClassChangeSink : public CEmbeddedObjectSink<CEventFilter>
  141. {
  142. public:
  143. CClassChangeSink(CEventFilter* pOwner) :
  144. CEmbeddedObjectSink<CEventFilter>(pOwner){}
  145. STDMETHOD(Indicate)(long lNumEvents, IWbemEvent** apEvents);
  146. } m_ClassChangeSink; // immutable
  147. CWbemPtr<IWbemObjectSink> m_pActualClassChangeSink;
  148. friend CEventForwardingSink;
  149. class CFilterGuardingSink : public CObjectSink
  150. {
  151. protected:
  152. CEventFilter* m_pFilter;
  153. protected:
  154. bool IsCountZero(_IWmiObject* pObj);
  155. public:
  156. CFilterGuardingSink(CEventFilter* m_pFilter);
  157. virtual ~CFilterGuardingSink();
  158. STDMETHOD(Indicate)(long lNumObject, IWbemClassObject** apEvents);
  159. };
  160. friend CFilterGuardingSink;
  161. CFilterGuardingSink* m_pGuardingSink;
  162. public:
  163. CEventFilter(CEssNamespace* pEssNamespace);
  164. virtual ~CEventFilter();
  165. virtual bool IsInternal() { return false; }
  166. //**************
  167. // Acquire CSs
  168. //**************
  169. HRESULT EnsureReferences(CEventConsumer* pConsumer, CBinding* pBinding);
  170. HRESULT EnsureNotReferences(CEventConsumer* pConsumer);
  171. HRESULT Unbind(bool bShuttingDown = false);
  172. bool IsBound();
  173. virtual BOOL DoesNeedType(int nType) const = 0;
  174. HRESULT Indicate(long lNumEvents, IWbemEvent** apEvents,
  175. CEventContext* pContext) = 0;
  176. virtual HRESULT LockForUpdate();
  177. virtual HRESULT UnlockForUpdate();
  178. //*******************
  179. // Do not acquire CSs
  180. //*******************
  181. virtual HRESULT GetCoveringQuery(DELETE_ME LPWSTR& wszQueryLanguage,
  182. DELETE_ME LPWSTR& wszQuery, BOOL& bExact,
  183. DELETE_ME QL_LEVEL_1_RPN_EXPRESSION** ppExp) = 0;
  184. virtual HRESULT GetEventNamespace(DELETE_ME LPWSTR* pwszNamespace);
  185. virtual DWORD GetForceFlags() {return 0;}
  186. virtual bool DoesAllowInvalid()
  187. {return ((GetForceFlags() & WBEM_FLAG_STRONG_VALIDATION) == 0);}
  188. bool HasBeenValid() {return m_bHasBeenValid;}
  189. inline const CInternalString& GetKey() {return m_isKey;}
  190. inline const PSID GetOwner() { return m_pOwnerSid; }
  191. virtual CAbstractEventSink* GetNonFilteringSink() = 0;
  192. virtual HRESULT GetReady(LPCWSTR wszQuery,
  193. QL_LEVEL_1_RPN_EXPRESSION* pExp) = 0;
  194. virtual HRESULT GetReadyToFilter() = 0;
  195. virtual BOOL IsPermanent() = 0;
  196. virtual HRESULT SetThreadSecurity() = 0;
  197. virtual HRESULT ObtainToken(IWbemToken** ppToken) = 0;
  198. virtual void Park(){}
  199. virtual const PSECURITY_DESCRIPTOR GetEventAccessSD() { return NULL; }
  200. void MarkAsPermanentlyInvalid(HRESULT hres);
  201. void MarkAsTemporarilyInvalid(HRESULT hres);
  202. void MarkAsValid();
  203. void SetInactive();
  204. void SetGuardStatus(bool bEnable, bool bError = false);
  205. void GetGuardStatus(bool *pbEnable, bool *pbError);
  206. BOOL IsActive();
  207. HRESULT GetFilterError();
  208. void MarkReconstructOnHit(bool bReconstruct = true);
  209. HRESULT SetGuardQuery(LPCWSTR wszQuery, LPCWSTR wszNamespace);
  210. bool IsGuarded();
  211. bool IsGuardActive();
  212. HRESULT ActivateGuard();
  213. HRESULT DeactivateGuard();
  214. void SetPollingError(HRESULT hres) {m_hresPollingError = hres;}
  215. HRESULT GetPollingError() {return m_hresPollingError;}
  216. void IncrementRemainingSecurityChecks();
  217. void DecrementRemainingSecurityChecks(HRESULT hresProvider);
  218. INTERNAL IWbemObjectSink* GetClassChangeSink() {return &m_ClassChangeSink;}
  219. //
  220. // this so the caller can wrap the class change sink however they want and
  221. // store the resultant sink with the filter object.
  222. //
  223. HRESULT SetActualClassChangeSink( IWbemObjectSink* pSink,
  224. IWbemObjectSink** ppOldSink );
  225. HRESULT Reactivate();
  226. protected:
  227. HRESULT Deliver(long lNumEvents, IWbemEvent** apEvents,
  228. CEventContext* pContext);
  229. HRESULT AdjustActivation();
  230. void AdjustSingleAsync();
  231. BOOL DoesNeedDeactivation();
  232. HRESULT AccessCheck( CEventContext* pEventContext, IWbemEvent* pEvent );
  233. HRESULT CheckEventAccessToFilter( IServerSecurity* pProvCtx );
  234. HRESULT CheckFilterAccessToEvent( PSECURITY_DESCRIPTOR pEventSD );
  235. friend class CBindingTable;
  236. };
  237. class CConsumerWatchInstruction : public CBasicUnloadInstruction
  238. {
  239. protected:
  240. class CBindingTableRef* m_pTableRef;
  241. static CWbemInterval mstatic_Interval;
  242. public:
  243. CConsumerWatchInstruction(CBindingTable* pTable);
  244. ~CConsumerWatchInstruction();
  245. HRESULT Fire(long, CWbemTime);
  246. static void staticInitialize(IWbemServices* pRoot);
  247. };
  248. //******************************************************************************
  249. //
  250. // This class is a comparer (as required by the sorted array template) that
  251. // compares an object with CInternalString* GetKey() method (e.g. filter or
  252. // consumer) to another such object or an LPCWSTR
  253. //
  254. //******************************************************************************
  255. template<class TObject>
  256. class CInternalStringComparer
  257. {
  258. public:
  259. int Compare(TObject* p1, TObject* p2) const
  260. {
  261. return p1->GetKey().Compare(p2->GetKey());
  262. }
  263. int Compare(const CInternalString& isKey, TObject* p) const
  264. {
  265. return - p->GetKey().Compare(isKey);
  266. }
  267. int Compare(LPCWSTR wszKey, TObject* p) const
  268. {
  269. return - p->GetKey().Compare(wszKey);
  270. }
  271. int Compare(const CInternalString& isKey1,
  272. const CInternalString& isKey2) const
  273. {
  274. return isKey1.Compare(isKey2);
  275. }
  276. const CInternalString& Extract(TObject* p) const
  277. {
  278. return p->GetKey();
  279. }
  280. };
  281. template<class TObject>
  282. class CSortedRefedKeyedPointerArray :
  283. public CRefedPointerSortedTree<CInternalString, TObject,
  284. CInternalStringComparer<TObject> >
  285. {
  286. typedef CRefedPointerSortedTree<CInternalString, TObject,
  287. CInternalStringComparer<TObject> > TParent;
  288. public:
  289. inline bool Find(LPCWSTR wszKey, TObject** ppObj)
  290. {
  291. CInternalString is(wszKey);
  292. if (is.IsEmpty())
  293. return false;
  294. return TParent::Find(is, ppObj);
  295. }
  296. inline bool Remove(LPCWSTR wszKey, TObject** ppObj)
  297. {
  298. CInternalString is(wszKey);
  299. if (is.IsEmpty())
  300. return false;
  301. return TParent::Remove(is, ppObj);
  302. }
  303. inline TParent::TIterator Remove(TParent::TIterator it, TObject** ppObj)
  304. {
  305. return TParent::Remove(it, ppObj);
  306. }
  307. };
  308. /*
  309. template<class TObject>
  310. class CSortedRefedKeyedPointerArray :
  311. public CRefedPointerSortedArray<LPCWSTR, TObject,
  312. CInternalStringComparer<TObject> >
  313. {
  314. };
  315. */
  316. class CBindingTableRef
  317. {
  318. protected:
  319. long m_lRef;
  320. CBindingTable* m_pTable;
  321. CCritSec m_cs;
  322. protected:
  323. virtual ~CBindingTableRef();
  324. public:
  325. CBindingTableRef(CBindingTable* pTable);
  326. void AddRef();
  327. void Release();
  328. void Disconnect();
  329. HRESULT UnloadUnusedConsumers(CWbemInterval Interval);
  330. HRESULT GetNamespace(RELEASE_ME CEssNamespace** ppNamespace);
  331. };
  332. class CBindingTable
  333. {
  334. protected:
  335. CEssNamespace* m_pNamespace;
  336. CCritSec m_cs;
  337. CSortedRefedKeyedPointerArray<CEventFilter> m_apFilters;
  338. typedef CSortedRefedKeyedPointerArray<CEventFilter>::TIterator
  339. TFilterIterator;
  340. CSortedRefedKeyedPointerArray<CEventConsumer> m_apConsumers;
  341. typedef CSortedRefedKeyedPointerArray<CEventConsumer>::TIterator
  342. TConsumerIterator;
  343. long m_lNumPermConsumers;
  344. CConsumerWatchInstruction* m_pInstruction;
  345. BOOL m_bUnloadInstruction;
  346. CBindingTableRef* m_pTableRef;
  347. public:
  348. //****************************************************
  349. // all members should be assumed to acquire random CSs
  350. //****************************************************
  351. CBindingTable(CEssNamespace* pNamespace);
  352. void Clear( bool bSkipClean );
  353. ~CBindingTable() { Clear(true); }
  354. HRESULT AddEventFilter(CEventFilter* pFilter);
  355. HRESULT AddEventConsumer(CEventConsumer* pConsumer);
  356. HRESULT FindEventFilter(LPCWSTR wszKey, RELEASE_ME CEventFilter** ppFilter);
  357. HRESULT FindEventConsumer(LPCWSTR wszKey,
  358. RELEASE_ME CEventConsumer** ppConsumer);
  359. HRESULT RemoveEventFilter(LPCWSTR wszKey);
  360. HRESULT RemoveEventConsumer(LPCWSTR wszKey);
  361. HRESULT Bind(LPCWSTR wszFilterKey, LPCWSTR wszConsumerKey,
  362. CBinding* pBinding, PSID pBinderSid);
  363. HRESULT Unbind(LPCWSTR wszFilterKey, LPCWSTR wszConsumerKey);
  364. BOOL DoesHavePermanentConsumers();
  365. HRESULT ListActiveNamespaces(CWStringArray& wsNamespaces);
  366. HRESULT ResetProviderRecords(LPCWSTR wszProvider);
  367. HRESULT RemoveConsumerWithFilters(LPCWSTR wszConsumerKey);
  368. HRESULT ReactivateAllFilters();
  369. HRESULT RemoveConsumersStartingWith(LPCWSTR wszPrefix);
  370. HRESULT EnsureConsumerWatchInstruction();
  371. void Park();
  372. void DumpStatistics(FILE* f, long lFlags);
  373. BOOL GetEventFilters( CRefedPointerArray< CEventFilter > & apEventFilters );
  374. protected:
  375. void MarkRemoval(CEventConsumer* pConsumer);
  376. HRESULT UnloadUnusedConsumers(CWbemInterval Interval);
  377. BOOL GetConsumers(CRefedPointerArray<CEventConsumer>& apConsumers);
  378. friend CConsumerWatchInstruction;
  379. friend CBindingTableRef;
  380. };
  381. #endif