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.

503 lines
17 KiB

  1. //******************************************************************************
  2. //
  3. // PROVREG.H
  4. //
  5. // Copyright (C) 1996-1999 Microsoft Corporation
  6. //
  7. //******************************************************************************
  8. #ifndef __EVENTPROV_REG__H_
  9. #define __EVENTPROV_REG__H_
  10. #include <time.h>
  11. #include <wbemidl.h>
  12. #include <arrtempl.h>
  13. #include <analyser.h>
  14. #include <evaltree.h>
  15. #include <sync.h>
  16. #include <filtprox.h>
  17. #include <unload.h>
  18. #include <postpone.h>
  19. #include <mtgtpckt.h>
  20. #include <newobj.h>
  21. class CEventProviderCache;
  22. class CEventProviderWatchInstruction : public CBasicUnloadInstruction
  23. {
  24. protected:
  25. CEventProviderCache* m_pCache;
  26. static CWbemInterval mstatic_Interval;
  27. public:
  28. CEventProviderWatchInstruction(CEventProviderCache* pCache);
  29. static void staticInitialize(IWbemServices* pRoot);
  30. HRESULT Fire(long lNumTimes, CWbemTime NextFiringTime);
  31. };
  32. class CProviderSinkServer;
  33. class CFilterStub : public IWbemFilterStub, public IWbemMultiTarget,
  34. public IWbemFetchSmartMultiTarget, public IWbemSmartMultiTarget,
  35. public IWbemEventProviderRequirements
  36. {
  37. protected:
  38. CProviderSinkServer* m_pSink;
  39. CWbemClassCache m_ClassCache;
  40. public:
  41. CFilterStub(CProviderSinkServer* pSink) : m_pSink(pSink){}
  42. ULONG STDMETHODCALLTYPE AddRef();
  43. ULONG STDMETHODCALLTYPE Release();
  44. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv);
  45. HRESULT STDMETHODCALLTYPE RegisterProxy(IWbemFilterProxy* pProxy);
  46. HRESULT STDMETHODCALLTYPE UnregisterProxy(IWbemFilterProxy* pProxy);
  47. HRESULT STDMETHODCALLTYPE DeliverEvent(DWORD dwNumEvents,
  48. IWbemClassObject** apEvents,
  49. WBEM_REM_TARGETS* aTargets,
  50. long lSDLength, BYTE* pSD);
  51. HRESULT STDMETHODCALLTYPE DeliverStatus(long lFlags, HRESULT hresStatus,
  52. LPCWSTR wszStatus, IWbemClassObject* pErrorObj,
  53. WBEM_REM_TARGETS* aTargets,
  54. long lSDLength, BYTE* pSD);
  55. HRESULT STDMETHODCALLTYPE GetSmartMultiTarget(
  56. IWbemSmartMultiTarget** ppSmartMultiTarget );
  57. HRESULT STDMETHODCALLTYPE DeliverEvent(DWORD dwNumEvents, DWORD dwBuffSize,
  58. BYTE* pBuffer,
  59. WBEM_REM_TARGETS* aTargets,
  60. long lSDLength, BYTE* pSD);
  61. HRESULT STDMETHODCALLTYPE DeliverProviderRequest(long lFlags);
  62. };
  63. class CEssMetaData;
  64. class CProviderSinkServer : public IUnknown
  65. {
  66. public:
  67. struct CEventDestination
  68. {
  69. WBEM_REMOTE_TARGET_ID_TYPE m_id;
  70. CAbstractEventSink* m_pSink;
  71. CEventDestination(WBEM_REMOTE_TARGET_ID_TYPE Id,
  72. CAbstractEventSink* pSink);
  73. CEventDestination(const CEventDestination& Other);
  74. ~CEventDestination();
  75. };
  76. typedef CUniquePointerArray<CEventDestination> TDestinationArray;
  77. protected:
  78. long m_lRef;
  79. CRefedPointerArray<IWbemFilterProxy> m_apProxies;
  80. TDestinationArray m_apDestinations;
  81. TDestinationArray m_apPreviousDestinations;
  82. WBEM_REMOTE_TARGET_ID_TYPE m_idNext;
  83. CWStringArray m_awsDefinitionQueries;
  84. IWbemLocalFilterProxy* m_pPseudoProxy;
  85. IWbemEventSink* m_pPseudoSink;
  86. CEssMetaData* m_pMetaData;
  87. CEssNamespace* m_pNamespace;
  88. IWbemEventProviderRequirements* m_pReqSink;
  89. CCritSec m_cs;
  90. long m_lLocks;
  91. protected:
  92. CFilterStub m_Stub;
  93. CInstanceManager m_InstanceManager;
  94. public:
  95. CProviderSinkServer();
  96. HRESULT Initialize(CEssNamespace* pNamespace,
  97. IWbemEventProviderRequirements* pReqSink);
  98. ~CProviderSinkServer();
  99. void Clear();
  100. HRESULT GetMainProxy(IWbemEventSink** ppSink);
  101. void GetStatistics(long* plProxies, long* plDestinations,
  102. long* plFilters, long* plTargetLists, long* plTargets,
  103. long* plPostponed);
  104. HRESULT GetDestinations(
  105. TDestinationArray& apDestinations);
  106. INTERNAL CEssNamespace* GetNamespace() {return m_pNamespace;}
  107. protected:
  108. HRESULT AddDestination(CAbstractEventSink* pDest,
  109. WBEM_REMOTE_TARGET_ID_TYPE* pID);
  110. BOOL GetProxies(CRefedPointerArray<IWbemFilterProxy>& apProxies);
  111. HRESULT FindDestinations(long lNum,
  112. IN WBEM_REMOTE_TARGET_ID_TYPE* aidTargets,
  113. RELEASE_ME CAbstractEventSink** apSinks);
  114. public:
  115. ULONG STDMETHODCALLTYPE AddRef();
  116. ULONG STDMETHODCALLTYPE Release();
  117. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv);
  118. HRESULT AddFilter(LPCWSTR wszQuery, QL_LEVEL_1_RPN_EXPRESSION* pExp,
  119. CAbstractEventSink* pDest,
  120. WBEM_REMOTE_TARGET_ID_TYPE* pidRequest = NULL);
  121. HRESULT RemoveFilter(CAbstractEventSink* pDest,
  122. WBEM_REMOTE_TARGET_ID_TYPE* pidRequest = NULL);
  123. void RemoveAllFilters();
  124. HRESULT AddDefinitionQuery(LPCWSTR wszQuery);
  125. HRESULT AllowUtilizeGuarantee();
  126. void RemoveAllDefinitionQueries();
  127. HRESULT Lock();
  128. void Unlock();
  129. public: // IWbemMultiTarget (forwarded)
  130. HRESULT STDMETHODCALLTYPE DeliverEvent(DWORD dwNumEvents,
  131. IWbemClassObject** apEvents,
  132. WBEM_REM_TARGETS* aTargets,
  133. CEventContext* pContext);
  134. HRESULT DeliverOneEvent(IWbemClassObject* pEvent,
  135. WBEM_REM_TARGETS* pTargets,
  136. CEventContext* pContext);
  137. HRESULT STDMETHODCALLTYPE DeliverStatus(long lFlags, HRESULT hresStatus,
  138. LPCWSTR wszStatus, IWbemClassObject* pErrorObj,
  139. WBEM_REM_TARGETS* aTargets,
  140. CEventContext* pContext);
  141. HRESULT MultiTargetDeliver(IWbemEvent* pEvent, WBEM_REM_TARGETS* pTargets,
  142. CEventContext* pContext);
  143. public: // IWbemFilterStub (forwarded)
  144. HRESULT STDMETHODCALLTYPE RegisterProxy(IWbemFilterProxy* pProxy);
  145. HRESULT STDMETHODCALLTYPE UnregisterProxy(IWbemFilterProxy* pProxy);
  146. public: // IWbemEventProviderRequirements (forwarded)
  147. HRESULT STDMETHODCALLTYPE DeliverProviderRequest(long lFlags);
  148. };
  149. class CEventProviderCache
  150. {
  151. class CRequest
  152. {
  153. private:
  154. CAbstractEventSink* m_pDest;
  155. LPWSTR m_wszQuery;
  156. QL_LEVEL_1_RPN_EXPRESSION* m_pExpr;
  157. IWbemClassObject* m_pEventClass;
  158. DWORD m_dwEventMask;
  159. CClassInfoArray* m_papInstanceClasses;
  160. public:
  161. CRequest(IN CAbstractEventSink* pDest, LPWSTR wszQuery,
  162. QL_LEVEL_1_RPN_EXPRESSION* pExp);
  163. ~CRequest();
  164. INTERNAL LPWSTR GetQuery() {return m_wszQuery;}
  165. INTERNAL CAbstractEventSink* GetDest() {return m_pDest;}
  166. INTERNAL QL_LEVEL_1_RPN_EXPRESSION* GetQueryExpr();
  167. DWORD GetEventMask();
  168. HRESULT GetInstanceClasses(CEssNamespace* pNamespace,
  169. INTERNAL CClassInfoArray** ppClasses);
  170. INTERNAL IWbemClassObject* GetEventClass(CEssNamespace* pNamespace);
  171. HRESULT CheckValidity(CEssNamespace* pNamespace);
  172. };
  173. class CRecord : IWbemEventProviderRequirements
  174. {
  175. class CQueryRecord
  176. {
  177. BSTR m_strQuery;
  178. IWbemClassObject* m_pEventClass;
  179. DWORD m_dwEventMask;
  180. CClassInfoArray* m_paInstanceClasses;
  181. QL_LEVEL_1_RPN_EXPRESSION* m_pExpr;
  182. public:
  183. CQueryRecord();
  184. HRESULT Initialize( COPY LPCWSTR wszQuery,
  185. LPCWSTR wszProvName,
  186. CEssNamespace* pNamespace,
  187. bool bSystem);
  188. ~CQueryRecord();
  189. HRESULT Update(LPCWSTR wszClassName, IWbemClassObject* pClass);
  190. HRESULT DoesIntersectWithQuery(CRequest& Request,
  191. CEssNamespace* pNamespace);
  192. DWORD GetProvidedEventMask(IWbemClassObject* pClass,
  193. BSTR strClassName);
  194. LPCWSTR GetQuery() {return m_strQuery;}
  195. HRESULT EnsureClasses( CEssNamespace* pNamespace );
  196. void ReleaseClasses();
  197. };
  198. friend class CEventProviderCache;
  199. public:
  200. long m_lRef;
  201. BSTR m_strNamespace;
  202. BSTR m_strName;
  203. BOOL m_bProviderSet;
  204. CUniquePointerArray<CQueryRecord> m_apQueries;
  205. long m_lUsageCount;
  206. long m_lPermUsageCount;
  207. BOOL m_bRecorded;
  208. BOOL m_bNeedsResync;
  209. CWbemTime m_LastUse;
  210. IWbemEventProvider* m_pProvider;
  211. IWbemEventProviderQuerySink* m_pQuerySink;
  212. IWbemEventProviderSecurity* m_pSecurity;
  213. CExecLine m_Line;
  214. bool m_bStarted;
  215. CEssNamespace* m_pNamespace;
  216. CProviderSinkServer* m_pMainSink;
  217. public:
  218. CRecord();
  219. HRESULT Initialize( LPCWSTR wszName, CEssNamespace* pNamespace );
  220. HRESULT SetProvider(IWbemClassObject* pWin32Prov);
  221. HRESULT SetProviderPointer(CEssNamespace* pNamespace,
  222. IWbemEventProvider* pProvider);
  223. HRESULT ResetProvider();
  224. HRESULT SetQueries(CEssNamespace* pNamespace,
  225. IWbemClassObject* pRegistration);
  226. HRESULT SetQueries(CEssNamespace* pNamespace, long lNumQueries,
  227. LPCWSTR* awszQueries);
  228. HRESULT ResetQueries();
  229. HRESULT Load(CEssNamespace* pNamespace);
  230. HRESULT DeactivateFilter(CAbstractEventSink* pDest);
  231. HRESULT CancelAllQueries();
  232. HRESULT STDMETHODCALLTYPE DeliverProviderRequest(long lFlags);
  233. static HRESULT GetProviderInfo(IWbemClassObject* pWin32Prov,
  234. BSTR& strName);
  235. static HRESULT GetRegistrationInfo(IWbemClassObject* pRegistration,
  236. BSTR& strName);
  237. HRESULT ActivateIfNeeded(IN CRequest& Request,
  238. IN CEssNamespace* pNamespace);
  239. BOOL NeedsResync() { return m_bNeedsResync; }
  240. void ResetNeedsResync() { m_bNeedsResync = FALSE; }
  241. BOOL IsEmpty();
  242. void ResetUsage();
  243. void CheckPermanentUsage();
  244. virtual bool DeactivateIfNotUsed();
  245. virtual bool IsUnloadable();
  246. HRESULT Update(LPCWSTR wszClassName, IWbemClassObject* pClass);
  247. DWORD GetProvidedEventMask(IWbemClassObject* pClass, BSTR strClassName);
  248. INTERNAL CProviderSinkServer* GetMainSink() {return m_pMainSink;}
  249. void Lock() {m_pMainSink->Lock();}
  250. void Unlock() {m_pMainSink->Unlock();}
  251. BOOL IsActive() {return (m_pProvider != NULL);}
  252. long GetUsageCount() {return m_lUsageCount;}
  253. ULONG STDMETHODCALLTYPE AddRef();
  254. ULONG STDMETHODCALLTYPE Release();
  255. STDMETHOD(QueryInterface)(REFIID riid, void** ppv) {return E_FAIL;}
  256. ~CRecord();
  257. protected:
  258. HRESULT Activate(CEssNamespace* pNamespace, CRequest* pRequest,
  259. WBEM_REMOTE_TARGET_ID_TYPE idRequest);
  260. HRESULT Deactivate( CAbstractEventSink* pDest,
  261. WBEM_REMOTE_TARGET_ID_TYPE idRequest);
  262. HRESULT AddActiveProviderEntryToRegistry();
  263. HRESULT RemoveActiveProviderEntryFromRegistry();
  264. HRESULT AddDefinitionQuery(CEssNamespace* pNamespace, LPCWSTR wszQuery);
  265. HRESULT Exec_LoadProvider(CEssNamespace* pNamespace);
  266. HRESULT Exec_StartProvider(CEssNamespace* pNamespace);
  267. HRESULT Exec_NewQuery(CEssNamespace* pNamespace,
  268. CExecLine::CTurn* pTurn, DWORD dwID,
  269. LPCWSTR wszLanguage, LPCWSTR wszQuery,
  270. CAbstractEventSink* pDest);
  271. HRESULT ActualExecNewQuery(CEssNamespace* pNamespace,
  272. DWORD dwID, LPCWSTR wszLanguage, LPCWSTR wszQuery,
  273. CAbstractEventSink* pDest);
  274. HRESULT Exec_CancelQuery(CEssNamespace* pNamespace,
  275. CExecLine::CTurn* pTurn, DWORD dwId);
  276. CExecLine::CTurn* GetInLine();
  277. void DiscardTurn(CExecLine::CTurn* pTurn);
  278. virtual HRESULT PostponeNewQuery(CExecLine::CTurn* pTurn, DWORD dwId,
  279. LPCWSTR wszQueryLanguage, LPCWSTR wszQuery,
  280. CAbstractEventSink* pDest);
  281. virtual HRESULT PostponeCancelQuery(CExecLine::CTurn* pTurn,
  282. DWORD dwId);
  283. void UnloadProvider();
  284. virtual bool IsSystem() {return false;}
  285. friend class CPostponedNewQuery;
  286. friend class CPostponedCancelQuery;
  287. friend class CPostponedProvideEvents;
  288. protected:
  289. };
  290. class CSystemRecord : public CRecord
  291. {
  292. public:
  293. virtual bool DeactivateIfNotUsed();
  294. virtual bool IsUnloadable();
  295. /* HRESULT PostponeNewQuery(CExecLine::CTurn* pTurn, DWORD dwId,
  296. LPCWSTR wszQueryLanguage, LPCWSTR wszQuery,
  297. CAbstractEventSink* pDest);
  298. HRESULT PostponeCancelQuery(CExecLine::CTurn* pTurn, DWORD dwId); */
  299. virtual bool IsSystem() {return true;}
  300. };
  301. friend class CPostponedNewQuery;
  302. friend class CPostponedCancelQuery;
  303. friend class CEventProviderWatchInstruction;
  304. friend class CPostponedProvideEvents;
  305. CCritSec m_cs;
  306. CRefedPointerArray<CRecord> m_aRecords;
  307. CEssNamespace* m_pNamespace;
  308. CEventProviderWatchInstruction* m_pInstruction;
  309. BOOL m_bInResync;
  310. protected:
  311. long FindRecord(LPCWSTR wszName);
  312. public:
  313. CEventProviderCache(CEssNamespace* pNamespace);
  314. ~CEventProviderCache();
  315. HRESULT Shutdown();
  316. HRESULT AddProvider(IWbemClassObject* pWin32Prov);
  317. HRESULT AddSystemProvider(IWbemEventProvider* pProvider, LPCWSTR wszName,
  318. long lNumQueries, LPCWSTR* awszQueries);
  319. HRESULT RemoveProvider(IWbemClassObject* pWin32Prov);
  320. HRESULT CheckProviderRegistration(IWbemClassObject* pRegistration);
  321. HRESULT AddProviderRegistration(IWbemClassObject* pRegistration);
  322. HRESULT RemoveProviderRegistration(IWbemClassObject* pRegistration);
  323. HRESULT LoadProvidersForQuery(LPWSTR wszQuery,
  324. QL_LEVEL_1_RPN_EXPRESSION* pExp,
  325. CAbstractEventSink* pDest);
  326. HRESULT ReleaseProvidersForQuery(CAbstractEventSink* pDest);
  327. DWORD GetProvidedEventMask(IWbemClassObject* pClass);
  328. HRESULT VirtuallyReleaseProviders();
  329. HRESULT CommitProviderUsage();
  330. HRESULT UnloadUnusedProviders(CWbemInterval Interval);
  331. void EnsureUnloadInstruction();
  332. void DumpStatistics(FILE* f, long lFlags);
  333. };
  334. class CPostponedNewQuery : public CPostponedRequest
  335. {
  336. protected:
  337. CEventProviderCache::CRecord* m_pRecord;
  338. DWORD m_dwId;
  339. CCompressedString* m_pcsQuery;
  340. CExecLine::CTurn* m_pTurn;
  341. CAbstractEventSink* m_pDest;
  342. public:
  343. CPostponedNewQuery(CEventProviderCache::CRecord* pRecord, DWORD dwId,
  344. LPCWSTR wszQueryLanguage, LPCWSTR wszQuery,
  345. CExecLine::CTurn* pTurn, CAbstractEventSink* pDest);
  346. ~CPostponedNewQuery();
  347. HRESULT Execute(CEssNamespace* pNamespace);
  348. BOOL DoesHoldTurn() { return TRUE; }
  349. void* operator new(size_t nSize);
  350. void operator delete(void* p);
  351. };
  352. class CPostponedCancelQuery : public CPostponedRequest
  353. {
  354. protected:
  355. DWORD m_dwId;
  356. CEventProviderCache::CRecord* m_pRecord;
  357. CExecLine::CTurn* m_pTurn;
  358. public:
  359. CPostponedCancelQuery(CEventProviderCache::CRecord* pRecord,
  360. CExecLine::CTurn* pTurn, DWORD dwId)
  361. : m_pRecord(pRecord), m_dwId(dwId), m_pTurn(pTurn)
  362. {
  363. m_pRecord->AddRef();
  364. }
  365. ~CPostponedCancelQuery()
  366. {
  367. if(m_pTurn)
  368. m_pRecord->DiscardTurn(m_pTurn);
  369. m_pRecord->Release();
  370. }
  371. HRESULT Execute(CEssNamespace* pNamespace)
  372. {
  373. HRESULT hres = m_pRecord->Exec_CancelQuery(pNamespace, m_pTurn, m_dwId);
  374. m_pTurn = NULL;
  375. return hres;
  376. }
  377. BOOL DoesHoldTurn() { return TRUE; }
  378. };
  379. class CPostponedProvideEvents : public CPostponedRequest
  380. {
  381. protected:
  382. DWORD m_dwId;
  383. CEventProviderCache::CRecord* m_pRecord;
  384. CExecLine::CTurn* m_pTurn;
  385. public:
  386. CPostponedProvideEvents(CEventProviderCache::CRecord* pRecord)
  387. : m_pRecord(pRecord)
  388. {
  389. m_pRecord->AddRef();
  390. }
  391. ~CPostponedProvideEvents()
  392. {
  393. m_pRecord->Release();
  394. }
  395. HRESULT Execute(CEssNamespace* pNamespace)
  396. {
  397. HRESULT hres = m_pRecord->Exec_StartProvider(pNamespace);
  398. return hres;
  399. }
  400. BOOL DoesHoldTurn() { return TRUE; }
  401. };
  402. class CPostponedSinkServerShutdown : public CPostponedRequest
  403. {
  404. protected:
  405. CWbemPtr<CProviderSinkServer> m_pSinkServer;
  406. public:
  407. CPostponedSinkServerShutdown( CProviderSinkServer* pSinkServer )
  408. : m_pSinkServer( pSinkServer ) { }
  409. HRESULT Execute( CEssNamespace* pNamespace )
  410. {
  411. m_pSinkServer->Clear();
  412. return WBEM_S_NO_ERROR;
  413. }
  414. };
  415. #endif