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
433 lines
14 KiB
//******************************************************************************
|
|
//
|
|
// BINDING.H
|
|
//
|
|
// Copyright (C) 1996-1999 Microsoft Corporation
|
|
//
|
|
//******************************************************************************
|
|
#ifndef __WMI_ESS_BINDING__H_
|
|
#define __WMI_ESS_BINDING__H_
|
|
|
|
#include <wbemcomn.h>
|
|
#include "evtools.h"
|
|
#include "evsink.h"
|
|
#include <unload.h>
|
|
#include <wbemstr.h>
|
|
#include <sortarr.h>
|
|
#include <ql.h>
|
|
#include "qsink.h"
|
|
|
|
class CEventConsumer;
|
|
class CEventFilter;
|
|
class CEssNamespace;
|
|
|
|
//******************************************************************************
|
|
//
|
|
// Immutable after initialization
|
|
//
|
|
//******************************************************************************
|
|
|
|
class CBinding : public CEventSink
|
|
{
|
|
protected:
|
|
long m_lRef;
|
|
CEventConsumer* m_pConsumer; // immutable after init
|
|
CEventFilter* m_pFilter; // immutable after init
|
|
|
|
DWORD m_dwQoS; // immutable after init
|
|
bool m_bSecure; // immutable after init
|
|
bool m_bSlowDown; // immutable after init
|
|
bool m_bDisabledForSecurity;
|
|
|
|
public:
|
|
CBinding();
|
|
CBinding(ADDREF CEventConsumer* pConsumer, ADDREF CEventFilter* pFilter);
|
|
virtual ~CBinding();
|
|
|
|
HRESULT SetEndpoints(ADDREF CEventConsumer* pConsumer,
|
|
ADDREF CEventFilter* pFilter,
|
|
PSID pBinderSid);
|
|
void DisableForSecurity();
|
|
INTERNAL CEventConsumer* GetConsumer() NOCS {return m_pConsumer;}
|
|
INTERNAL CEventFilter* GetFilter() NOCS {return m_pFilter;}
|
|
DWORD GetQoS() NOCS;
|
|
bool IsSynch() NOCS;
|
|
bool IsSecure() NOCS;
|
|
bool ShouldSlowDown() NOCS;
|
|
|
|
HRESULT Indicate( long lNumEvents, IWbemEvent** apEvents,
|
|
CEventContext* pContext);
|
|
};
|
|
|
|
class CEventConsumer : public CQueueingEventSink
|
|
{
|
|
protected:
|
|
CRefedPointerSmallArray<CBinding> m_apBindings;
|
|
CInternalString m_isKey;
|
|
PBYTE m_pOwnerSid;
|
|
|
|
public:
|
|
|
|
CEventConsumer(CEssNamespace* pNamespace);
|
|
|
|
virtual ~CEventConsumer();
|
|
|
|
inline const CInternalString& GetKey() const {return m_isKey;}
|
|
inline const PSID GetOwner() {return m_pOwnerSid;}
|
|
|
|
virtual BOOL IsPermanent() const {return FALSE;}
|
|
virtual BOOL UnloadIfUnusedFor(CWbemInterval Interval) {return FALSE;}
|
|
virtual BOOL IsFullyUnloaded() {return TRUE;}
|
|
virtual HRESULT ResetProviderRecord(LPCWSTR wszProviderRef)
|
|
{return S_FALSE;}
|
|
virtual HRESULT Shutdown(bool bQuiet = false) {return S_OK;}
|
|
virtual HRESULT Validate(IWbemClassObject* pLogicalConsumer) {return S_OK;}
|
|
|
|
HRESULT EnsureReferences(CEventFilter* pFilter, CBinding* pBinding);
|
|
HRESULT EnsureNotReferences(CEventFilter* pFilter);
|
|
HRESULT Unbind();
|
|
|
|
HRESULT ConsumeFromBinding(CBinding* pBinding,
|
|
long lNumEvents, IWbemEvent** apEvents,
|
|
CEventContext* pContext);
|
|
HRESULT GetAssociatedFilters(
|
|
CRefedPointerSmallArray<CEventFilter>& apFilters);
|
|
|
|
virtual HRESULT ActuallyDeliver(long lNumEvents, IWbemEvent** apEvents,
|
|
BOOL bSecure, CEventContext* pContext) = 0;
|
|
virtual HRESULT ReportEventDrop(IWbemEvent* pEvent);
|
|
};
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// m_cs controls access to data members. No critical sections may be acquired
|
|
// while holding m_cs.
|
|
//
|
|
// m_csChangeBindings controls activation/deactivation requests on this filter.
|
|
// As long as an activation/deactivation request is proceeding, no other
|
|
// such request can get underway. This ensures that the activation state
|
|
// state of the filter always matches the state of its bindings. At the
|
|
// same time, the filter can filter events while such a request executes,
|
|
// since m_cs is not held. Only m_cs can be acquired while holding
|
|
// m_csActivation
|
|
//
|
|
//*****************************************************************************
|
|
|
|
class CEventFilter : public CEventSink, public CUpdateLockable
|
|
{
|
|
protected:
|
|
CEssNamespace* m_pNamespace; // immutable after init
|
|
CRefedPointerSmallArray<CBinding> m_apBindings; // changes
|
|
CCritSec m_cs;
|
|
// CCritSec m_csChangeBindings; // don't need since the namespace is locked
|
|
bool m_bSingleAsync;
|
|
CInternalString m_isKey;
|
|
PBYTE m_pOwnerSid;
|
|
long m_lSecurityChecksRemaining;
|
|
long m_lSubjectToSDSCount;
|
|
bool m_bCheckSDs;
|
|
HRESULT m_hresFilterError;
|
|
bool m_bHasBeenValid;
|
|
IWbemToken* m_pToken;
|
|
HRESULT m_hresTokenError;
|
|
DWORD m_dwLastTokenAttempt;
|
|
bool m_bReconstructOnHit;
|
|
HRESULT m_hresPollingError;
|
|
|
|
enum
|
|
{
|
|
e_Inactive, e_Active
|
|
} m_eState; //changes
|
|
|
|
enum
|
|
{
|
|
e_Unknown, e_PermanentlyInvalid, e_TemporarilyInvalid, e_Valid
|
|
} m_eValidity;
|
|
|
|
friend class CEventForwardingSink;
|
|
|
|
class CEventForwardingSink : public CAbstractEventSink
|
|
{
|
|
protected:
|
|
CEventFilter* m_pOwner;
|
|
|
|
public:
|
|
CEventForwardingSink(CEventFilter* pOwner) : m_pOwner(pOwner){}
|
|
|
|
ULONG STDMETHODCALLTYPE AddRef() {return m_pOwner->AddRef();}
|
|
ULONG STDMETHODCALLTYPE Release() {return m_pOwner->Release();}
|
|
HRESULT Indicate(long lNumEvents, IWbemEvent** apEvents,
|
|
CEventContext* pContext);
|
|
} m_ForwardingSink; // immutable
|
|
|
|
class CClassChangeSink : public CEmbeddedObjectSink<CEventFilter>
|
|
{
|
|
public:
|
|
CClassChangeSink(CEventFilter* pOwner) :
|
|
CEmbeddedObjectSink<CEventFilter>(pOwner){}
|
|
STDMETHOD(Indicate)(long lNumEvents, IWbemEvent** apEvents);
|
|
} m_ClassChangeSink; // immutable
|
|
|
|
CWbemPtr<IWbemObjectSink> m_pActualClassChangeSink;
|
|
|
|
friend CEventForwardingSink;
|
|
|
|
public:
|
|
|
|
CEventFilter(CEssNamespace* pEssNamespace);
|
|
virtual ~CEventFilter();
|
|
|
|
virtual bool IsInternal() { return false; }
|
|
|
|
//**************
|
|
// Acquire CSs
|
|
//**************
|
|
|
|
HRESULT EnsureReferences(CEventConsumer* pConsumer, CBinding* pBinding);
|
|
HRESULT EnsureNotReferences(CEventConsumer* pConsumer);
|
|
HRESULT Unbind(bool bShuttingDown = false);
|
|
bool IsBound();
|
|
|
|
virtual BOOL DoesNeedType(int nType) const = 0;
|
|
HRESULT Indicate(long lNumEvents, IWbemEvent** apEvents,
|
|
CEventContext* pContext) = 0;
|
|
|
|
virtual HRESULT LockForUpdate();
|
|
virtual HRESULT UnlockForUpdate();
|
|
|
|
//*******************
|
|
// Do not acquire CSs
|
|
//*******************
|
|
|
|
virtual HRESULT GetCoveringQuery(DELETE_ME LPWSTR& wszQueryLanguage,
|
|
DELETE_ME LPWSTR& wszQuery, BOOL& bExact,
|
|
DELETE_ME QL_LEVEL_1_RPN_EXPRESSION** ppExp) = 0;
|
|
virtual HRESULT GetEventNamespace(DELETE_ME LPWSTR* pwszNamespace);
|
|
virtual DWORD GetForceFlags() {return 0;}
|
|
virtual bool DoesAllowInvalid()
|
|
{return ((GetForceFlags() & WBEM_FLAG_STRONG_VALIDATION) == 0);}
|
|
bool HasBeenValid() {return m_bHasBeenValid;}
|
|
|
|
inline const CInternalString& GetKey() {return m_isKey;}
|
|
inline const PSID GetOwner() { return m_pOwnerSid; }
|
|
|
|
virtual CAbstractEventSink* GetNonFilteringSink() = 0;
|
|
virtual HRESULT GetReady(LPCWSTR wszQuery,
|
|
QL_LEVEL_1_RPN_EXPRESSION* pExp) = 0;
|
|
virtual HRESULT GetReadyToFilter() = 0;
|
|
virtual BOOL IsPermanent() = 0;
|
|
virtual HRESULT SetThreadSecurity( IUnknown** ppNewContext ) = 0;
|
|
virtual HRESULT ObtainToken(IWbemToken** ppToken) = 0;
|
|
virtual void Park(){}
|
|
virtual const PSECURITY_DESCRIPTOR GetEventAccessSD() { return NULL; }
|
|
void MarkAsPermanentlyInvalid(HRESULT hres);
|
|
void MarkAsTemporarilyInvalid(HRESULT hres);
|
|
void MarkAsValid();
|
|
void SetInactive();
|
|
BOOL IsActive();
|
|
HRESULT GetFilterError();
|
|
void MarkReconstructOnHit(bool bReconstruct = true);
|
|
void SetPollingError(HRESULT hres) {m_hresPollingError = hres;}
|
|
HRESULT GetPollingError() {return m_hresPollingError;}
|
|
|
|
void IncrementRemainingSecurityChecks();
|
|
void DecrementRemainingSecurityChecks(HRESULT hresProvider);
|
|
|
|
INTERNAL IWbemObjectSink* GetClassChangeSink() {return &m_ClassChangeSink;}
|
|
|
|
//
|
|
// this so the caller can wrap the class change sink however they want and
|
|
// store the resultant sink with the filter object.
|
|
//
|
|
HRESULT SetActualClassChangeSink( IWbemObjectSink* pSink,
|
|
IWbemObjectSink** ppOldSink );
|
|
|
|
HRESULT Reactivate();
|
|
|
|
protected:
|
|
HRESULT Deliver(long lNumEvents, IWbemEvent** apEvents,
|
|
CEventContext* pContext);
|
|
HRESULT AdjustActivation();
|
|
void AdjustSingleAsync();
|
|
BOOL DoesNeedDeactivation();
|
|
HRESULT AccessCheck( CEventContext* pEventContext, IWbemEvent* pEvent );
|
|
|
|
HRESULT CheckEventAccessToFilter( IServerSecurity* pProvCtx );
|
|
HRESULT CheckFilterAccessToEvent( PSECURITY_DESCRIPTOR pEventSD );
|
|
|
|
friend class CBindingTable;
|
|
};
|
|
|
|
|
|
|
|
class CConsumerWatchInstruction : public CBasicUnloadInstruction
|
|
{
|
|
protected:
|
|
class CBindingTableRef* m_pTableRef;
|
|
static CWbemInterval mstatic_Interval;
|
|
|
|
public:
|
|
CConsumerWatchInstruction(CBindingTable* pTable);
|
|
~CConsumerWatchInstruction();
|
|
HRESULT Fire(long, CWbemTime);
|
|
static void staticInitialize(IWbemServices* pRoot);
|
|
};
|
|
|
|
//******************************************************************************
|
|
//
|
|
// This class is a comparer (as required by the sorted array template) that
|
|
// compares an object with CInternalString* GetKey() method (e.g. filter or
|
|
// consumer) to another such object or an LPCWSTR
|
|
//
|
|
//******************************************************************************
|
|
|
|
template<class TObject>
|
|
class CInternalStringComparer
|
|
{
|
|
public:
|
|
int Compare(TObject* p1, TObject* p2) const
|
|
{
|
|
return p1->GetKey().Compare(p2->GetKey());
|
|
}
|
|
int Compare(const CInternalString& isKey, TObject* p) const
|
|
{
|
|
return - p->GetKey().Compare(isKey);
|
|
}
|
|
int Compare(LPCWSTR wszKey, TObject* p) const
|
|
{
|
|
return - p->GetKey().Compare(wszKey);
|
|
}
|
|
int Compare(const CInternalString& isKey1,
|
|
const CInternalString& isKey2) const
|
|
{
|
|
return isKey1.Compare(isKey2);
|
|
}
|
|
const CInternalString& Extract(TObject* p) const
|
|
{
|
|
return p->GetKey();
|
|
}
|
|
};
|
|
|
|
template<class TObject>
|
|
class CSortedRefedKeyedPointerArray :
|
|
public CRefedPointerSortedTree<CInternalString, TObject,
|
|
CInternalStringComparer<TObject> >
|
|
{
|
|
typedef CRefedPointerSortedTree<CInternalString, TObject,
|
|
CInternalStringComparer<TObject> > TParent;
|
|
public:
|
|
inline bool Find(LPCWSTR wszKey, TObject** ppObj)
|
|
{
|
|
CInternalString is(wszKey);
|
|
if (is.IsEmpty())
|
|
return false;
|
|
return TParent::Find(is, ppObj);
|
|
}
|
|
inline bool Remove(LPCWSTR wszKey, TObject** ppObj)
|
|
{
|
|
CInternalString is(wszKey);
|
|
if (is.IsEmpty())
|
|
return false;
|
|
return TParent::Remove(is, ppObj);
|
|
}
|
|
inline typename TParent::TIterator Remove(typename TParent::TIterator it, TObject** ppObj)
|
|
{
|
|
return TParent::Remove(it, ppObj);
|
|
}
|
|
};
|
|
|
|
/*
|
|
template<class TObject>
|
|
class CSortedRefedKeyedPointerArray :
|
|
public CRefedPointerSortedArray<LPCWSTR, TObject,
|
|
CInternalStringComparer<TObject> >
|
|
{
|
|
};
|
|
*/
|
|
|
|
class CBindingTableRef
|
|
{
|
|
protected:
|
|
long m_lRef;
|
|
CBindingTable* m_pTable;
|
|
CCritSec m_cs;
|
|
|
|
|
|
protected:
|
|
virtual ~CBindingTableRef();
|
|
|
|
public:
|
|
CBindingTableRef(CBindingTable* pTable);
|
|
void AddRef();
|
|
void Release();
|
|
void Disconnect();
|
|
HRESULT UnloadUnusedConsumers(CWbemInterval Interval);
|
|
HRESULT GetNamespace(RELEASE_ME CEssNamespace** ppNamespace);
|
|
};
|
|
|
|
class CBindingTable
|
|
{
|
|
protected:
|
|
CEssNamespace* m_pNamespace;
|
|
CCritSec m_cs;
|
|
|
|
CSortedRefedKeyedPointerArray<CEventFilter> m_apFilters;
|
|
typedef CSortedRefedKeyedPointerArray<CEventFilter>::TIterator
|
|
TFilterIterator;
|
|
CSortedRefedKeyedPointerArray<CEventConsumer> m_apConsumers;
|
|
typedef CSortedRefedKeyedPointerArray<CEventConsumer>::TIterator
|
|
TConsumerIterator;
|
|
|
|
long m_lNumPermConsumers;
|
|
CConsumerWatchInstruction* m_pInstruction;
|
|
BOOL m_bUnloadInstruction;
|
|
CBindingTableRef* m_pTableRef;
|
|
|
|
public:
|
|
|
|
//****************************************************
|
|
// all members should be assumed to acquire random CSs
|
|
//****************************************************
|
|
|
|
CBindingTable(CEssNamespace* pNamespace);
|
|
void Clear( bool bSkipClean );
|
|
~CBindingTable() { Clear(true); }
|
|
|
|
HRESULT AddEventFilter(CEventFilter* pFilter);
|
|
HRESULT AddEventConsumer(CEventConsumer* pConsumer);
|
|
|
|
HRESULT FindEventFilter(LPCWSTR wszKey, RELEASE_ME CEventFilter** ppFilter);
|
|
HRESULT FindEventConsumer(LPCWSTR wszKey,
|
|
RELEASE_ME CEventConsumer** ppConsumer);
|
|
|
|
HRESULT RemoveEventFilter(LPCWSTR wszKey);
|
|
HRESULT RemoveEventConsumer(LPCWSTR wszKey);
|
|
|
|
HRESULT Bind(LPCWSTR wszFilterKey, LPCWSTR wszConsumerKey,
|
|
CBinding* pBinding, PSID pBinderSid);
|
|
HRESULT Unbind(LPCWSTR wszFilterKey, LPCWSTR wszConsumerKey);
|
|
|
|
BOOL DoesHavePermanentConsumers();
|
|
HRESULT ListActiveNamespaces(CWStringArray& wsNamespaces);
|
|
HRESULT ResetProviderRecords(LPCWSTR wszProvider);
|
|
HRESULT RemoveConsumerWithFilters(LPCWSTR wszConsumerKey);
|
|
HRESULT ReactivateAllFilters();
|
|
HRESULT RemoveConsumersStartingWith(LPCWSTR wszPrefix);
|
|
|
|
HRESULT EnsureConsumerWatchInstruction();
|
|
void Park();
|
|
void DumpStatistics(FILE* f, long lFlags);
|
|
|
|
BOOL GetEventFilters( CRefedPointerArray< CEventFilter > & apEventFilters );
|
|
|
|
protected:
|
|
void MarkRemoval(CEventConsumer* pConsumer);
|
|
|
|
HRESULT UnloadUnusedConsumers(CWbemInterval Interval);
|
|
|
|
BOOL GetConsumers(CRefedPointerArray<CEventConsumer>& apConsumers);
|
|
friend CConsumerWatchInstruction;
|
|
friend CBindingTableRef;
|
|
};
|
|
|
|
#endif
|