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.
 
 
 
 
 
 

478 lines
17 KiB

//=============================================================================
//
// Copyright (c) 1996-1999, Microsoft Corporation, All rights reserved
//
// NSREP.H
//
// Represents the ESS functionality for a given namespace
//
// Classes defined:
//
// CEssNamespace
//
// History:
//
// 11/27/96 a-levn Compiles.
// 1/6/97 a-levn Updated to initialize TSS.
//
//=============================================================================
#ifndef __NSREP_ESS__H_
#define __NSREP_ESS__H_
#include "pragmas.h"
#include "binding.h"
#include "permfilt.h"
#include "permcons.h"
#include "tempfilt.h"
#include "tempcons.h"
#include "corefind.h"
#include "consprov.h"
#include "provreg.h"
#include "wbemtss.h"
#include "poller.h"
#include "essutils.h"
#include "clscache.h"
#include <map>
#include <set>
#define WMIESS_REPORT(X)
class CEss;
class CEssNamespace : public CUpdateLockable
{
protected:
CEss* m_pEss;
long m_lRef;
PSECURITY_DESCRIPTOR m_pAdminOnlySD;
DWORD m_cAdminOnlySD;
//
// protects level 1 members. These are members that can be used even
// when level2 members are locked.
//
CCritSec m_csLevel1;
//
// protects level 2 members. When both a level1 and level2 lock need to
// be aquired, the level2 lock MUST be obtained first. This is a wbem cs
// because we hold this lock across calls to core ( which can conceivably
// take longer than 2 minutes - the deadline for normal critical sections )
//
CWbemCriticalSection m_csLevel2;
//
// level 1 members
//
HANDLE m_hInitComplete;
//
// If events are signaled when we are in the unitialized state, then
// they are temporarily stored here.
//
CPointerArray<CEventRepresentation> m_aDeferredEvents;
LPWSTR m_wszName;
_IWmiProviderFactory* m_pProviderFactory;
IWbemServices* m_pCoreSvc;
IWbemServices* m_pFullSvc;
IWbemInternalServices* m_pInternalCoreSvc;
IWbemInternalServices* m_pInternalFullSvc;
//
// Level 2 members.
//
BOOL m_bInResync;
BOOL m_bStage1Complete;
int m_cActive;
CBindingTable m_Bindings;
CConsumerProviderCache m_ConsumerProviderCache;
CEventProviderCache m_EventProviderCache;
CPoller m_Poller;
CEssClassCache m_ClassCache;
CCoreEventProvider* m_pCoreEventProvider;
CNtSid m_sidAdministrators;
//
// this structure maps tells us if we need to do anything for a provider
// when a class changes.
//
typedef std::set<WString,WSiless,wbem_allocator<WString> > ProviderSet;
typedef std::map<WString,ProviderSet,WSiless,wbem_allocator<ProviderSet> >
ClassToProviderMap;
ClassToProviderMap m_mapProviderInterestClasses;
//
// the state and init members are both level 1 and level2. They can be
// read when the level1 lock is held. They can only be modified when the
// level2 and level1 locks are held.
//
HRESULT m_hresInit;
enum {
//
// Initialization is Pending. Can service
// events from core in this state (though will be defferred ).
// it is expected that Initialize() will be called
// sometime in the near future. We also can support limited ops
// while in this state. Any operations that deal with event
// subsciptions or provider objects can be serviced. Any ops that
// deal with event provider registrations must wait for initialization.
//
e_InitializePending,
//
// Quiet - Initialization is not pending. The namespace is known to
// be empty of any ess related onjects. Can service events in this
// state, but they are simply discarded.
//
e_Quiet,
//
// We have loaded subscription objects. All ess operations can be
// performed. Events from core now can be processed.
//
e_Initialized,
//
// Shutdown has been called. All operations return error.
//
e_Shutdown
} m_eState;
protected:
class CConsumerClassDeletionSink : public CEmbeddedObjectSink<CEssNamespace>
{
public:
CConsumerClassDeletionSink(CEssNamespace* pNamespace) :
CEmbeddedObjectSink<CEssNamespace>(pNamespace){}
STDMETHOD(Indicate)(long lNumObjects, IWbemClassObject** apObjects);
} m_ClassDeletionSink;
friend CConsumerClassDeletionSink;
protected:
inline void LogOp( LPCWSTR wszOp, IWbemClassObject* pObj );
HRESULT EnsureInitPending();
HRESULT CheckMonitor(IWbemClassObject* pPrevMonitorObj,
IWbemClassObject* pMonitorObj);
HRESULT CheckEventFilter(IWbemClassObject* pPrevFilterObj,
IWbemClassObject* pFilterObj);
HRESULT CheckEventConsumer(IWbemClassObject* pPrevConsumerObj,
IWbemClassObject* pConsumerObj);
HRESULT CheckBinding(IWbemClassObject* pPrevBindingObj,
IWbemClassObject* pBindingObj);
HRESULT CheckEventProviderRegistration(IWbemClassObject* pReg);
HRESULT CheckTimerInstruction(IWbemClassObject* pInst);
HRESULT ActOnSystemEvent(CEventRepresentation& Event, long lFlags);
HRESULT HandleClassChange(LPCWSTR wszClassName, IWbemClassObject* pClass);
HRESULT HandleClassCreation(LPCWSTR wszClassName,IWbemClassObject* pClass);
HRESULT HandleConsumerClassDeletion(LPCWSTR wszClassName);
HRESULT PrepareForResync();
HRESULT ReactivateAllFilters();
HRESULT CommitResync();
HRESULT ReloadMonitor(ADDREF IWbemClassObject* pEventMonitorObj);
HRESULT ReloadEventFilter(ADDREF IWbemClassObject* pEventFilterObj);
HRESULT ReloadEventConsumer(READ_ONLY IWbemClassObject* pConsumerObj,
long lFlags);
HRESULT ReloadBinding(READ_ONLY IWbemClassObject* pBindingObj);
HRESULT ReloadTimerInstruction(READ_ONLY IWbemClassObject* pInstObj);
HRESULT ReloadProvider(READ_ONLY IWbemClassObject* pInstObj);
HRESULT ReloadEventProviderRegistration(IWbemClassObject* pInstObj);
HRESULT ReloadConsumerProviderRegistration(IWbemClassObject* pInstObj);
HRESULT AddMonitor(ADDREF IWbemClassObject* pEventMonitorObj);
HRESULT AddEventFilter(ADDREF IWbemClassObject* pEventFilterObj,
BOOL bInRestart = FALSE);
HRESULT AddEventConsumer(READ_ONLY IWbemClassObject* pConsumerObj,
long lFlags,
BOOL bInRestart = FALSE);
HRESULT AddBinding(LPCWSTR wszFilterKey, LPCWSTR wszConsumerKey,
READ_ONLY IWbemClassObject* pBindingObj);
HRESULT AddBinding(IWbemClassObject* pBindingObj);
HRESULT AddTimerInstruction(READ_ONLY IWbemClassObject* pInstObj);
HRESULT AddProvider(READ_ONLY IWbemClassObject* pInstObj);
HRESULT AddEventProviderRegistration(READ_ONLY IWbemClassObject* pInstObj);
HRESULT RemoveMonitor(IWbemClassObject* pEventMonitorObj);
HRESULT RemoveEventFilter(IWbemClassObject* pEventFilterObj);
HRESULT RemoveEventConsumer(IWbemClassObject* pConsumerObj);
HRESULT RemoveBinding(LPCWSTR wszFilterKey, LPCWSTR wszConsumerKey);
HRESULT RemoveTimerInstruction(IWbemClassObject* pInstObj);
HRESULT RemoveProvider(IWbemClassObject* pInstObj);
HRESULT RemoveEventProviderRegistration(IWbemClassObject* pInstObj);
HRESULT RemoveConsumerProviderRegistration(IWbemClassObject* pInstObj);
HRESULT AssertBindings(IWbemClassObject* pEndpoint);
HRESULT DeleteConsumerProvider(IWbemClassObject* pReg);
HRESULT PerformSubscriptionInitialization();
HRESULT PerformProviderInitialization();
BOOL IsNeededOnStartup();
HRESULT GetCurrentState(IWbemClassObject* pTemplate,
IWbemClassObject** ppObj);
HRESULT CheckSecurity(IWbemClassObject* pPrevObj,
IWbemClassObject* pObj);
HRESULT CheckSidForPrivilege( PSID sid );
HRESULT EnsureSessionSid(IWbemClassObject* pPrevObj, CNtSid& ActingSid);
HRESULT CheckOverwriteSecurity( IWbemClassObject* pPrevObj,
CNtSid& ActingSid);
HRESULT PutSidInObject(IWbemClassObject* pObj, CNtSid& Sid);
HRESULT IsCallerAdministrator();
HRESULT AttemptToActivateFilter(READ_ONLY CEventFilter* pFilter);
HRESULT GetFilterEventNamespace(CEventFilter* pFilter,
RELEASE_ME CEssNamespace** ppNamespace);
void FireNCFilterEvent(DWORD dwIndex, CEventFilter *pFilter);
CQueueingEventSink* GetQueueingEventSink( LPCWSTR wszSinkName );
HRESULT ScheduleFirePostponed();
~CEssNamespace();
public:
CEssNamespace(CEss* pEss);
ULONG AddRef();
ULONG Release();
CEss* GetEss() { return m_pEss; }
//
// On return, namespace can be used for limited operations. Events
// can be signaled ( though they may be defferred internally ) and
// operations dealing with subscriptions can be performed.
//
HRESULT PreInitialize( LPCWSTR wszName );
//
// Performs initialization but does NOT transition state to Initialized.
// This is done by calling MarkAsInitialized(). This allows a caller to
// atomically perform initalization of multiple namespaces.
//
HRESULT Initialize();
//
// Finishes loading event provider registrations and processes
// subcriptions. Transitions to FullyInitialized() state.
//
HRESULT CompleteInitialization();
//
// Transitions state to Initialized.
//
void MarkAsInitialized( HRESULT hres );
//
// Transitions state to Initialize Pending if previously in the Quiet
// state. Returns TRUE if transition was made.
//
BOOL MarkAsInitPendingIfQuiet();
//
// Waits for Initialization to complete.
//
HRESULT WaitForInitialization();
HRESULT Park();
HRESULT Shutdown();
LPCWSTR GetName() {return m_wszName;}
HRESULT GetNamespacePointer(RELEASE_ME IWbemServices** ppNamespace);
HRESULT LoadEventProvider(LPCWSTR wszProviderName,
IWbemEventProvider** ppProv);
HRESULT LoadConsumerProvider(LPCWSTR wszProviderName,
IUnknown** ppProv);
HRESULT DecorateObject(IWbemClassObject* pObject);
HRESULT ProcessEvent(CEventRepresentation& Event, long lFlags);
HRESULT ProcessQueryObjectSinkEvent( READ_ONLY CEventRepresentation& Event );
HRESULT SignalEvent( CEventRepresentation& Event,
long lFlags,
BOOL bAdminOnly = FALSE );
HRESULT ValidateSystemEvent(CEventRepresentation& Event);
void SetActive();
void SetInactive();
HRESULT ActivateFilter(READ_ONLY CEventFilter* pFilter);
HRESULT DeactivateFilter(READ_ONLY CEventFilter* pFilter);
//
// public versions of register/remove notification sink. Do NOT use
// these versions if calling from within ESS. The reason is that these
// versions wait for initialization and lock the namespace which might
// cause deadlocks if called from within ESS. We also don't want to
// generate self instrumentation events for internal calls.
//
HRESULT RegisterNotificationSink(
WBEM_CWSTR wszQueryLanguage, WBEM_CWSTR wszQuery,
long lFlags, WMIMSG_QOS_FLAG lQosFlags,
IWbemContext* pContext,
IWbemObjectSink* pSink );
HRESULT RemoveNotificationSink( IWbemObjectSink* pSink );
HRESULT ReloadProvider( long lFlags, LPCWSTR wszProvider );
//
// Internal versions of register/remove notification sink. They do
// not lock, wait for initialization, or fire self instrumentation events.
// If calling these methods from within ess, specify bInternal as TRUE.
// The pOwnerSid is used when access checks for the subscription should
// be performed based on a particular SID. currently this is only used
// for cross-namespace subscriptions.
//
HRESULT InternalRegisterNotificationSink(
WBEM_CWSTR wszQueryLanguage, WBEM_CWSTR wszQuery,
long lFlags, WMIMSG_QOS_FLAG lQosFlags,
IWbemContext* pContext, IWbemObjectSink* pSink,
bool bInternal, PSID pOwnerSid );
HRESULT InternalRemoveNotificationSink(IWbemObjectSink* pSink);
CWinMgmtTimerGenerator& GetTimerGenerator();
CConsumerProviderCache& GetConsumerProviderCache()
{return m_ConsumerProviderCache;}
DWORD GetProvidedEventMask(IWbemClassObject* pClass);
HRESULT EnsureConsumerWatchInstruction();
HRESULT InitializeTimerGenerator();
HRESULT ScheduleDelivery(CQueueingEventSink* pDest);
HRESULT RaiseErrorEvent(IWbemEvent* pEvent, BOOL bAdminOnly = FALSE );
void IncrementObjectCount();
void DecrementObjectCount();
HRESULT AddSleepCharge(DWORD dwSleep);
HRESULT AddCache();
HRESULT RemoveCache();
HRESULT AddToCache(DWORD dwAdd, DWORD dwMemberTotal,
DWORD* pdwSleep = NULL);
HRESULT RemoveFromCache(DWORD dwRemove);
HRESULT LockForUpdate();
HRESULT UnlockForUpdate();
bool IsShutdown() { return m_eState == e_Shutdown; }
HRESULT GetProviderNamespacePointer(IWbemServices** ppServices);
HRESULT GetClass( LPCWSTR wszClassName, _IWmiObject** ppClass)
{ return m_ClassCache.GetClass(wszClassName, GetCurrentEssContext(),
ppClass);}
HRESULT GetClassFromCore(LPCWSTR wszClassName, _IWmiObject** ppClass);
HRESULT GetInstance(LPCWSTR wszPath, _IWmiObject** ppInstance);
HRESULT GetDbInstance(LPCWSTR wszDbKey, _IWmiObject** ppInstance);
HRESULT CreateInstanceEnum(LPCWSTR wszClass, long lFlags,
IWbemObjectSink* pSink);
HRESULT ExecQuery(LPCWSTR wszQuery, long lFlags, IWbemObjectSink* pSink);
CNtSid& GetAdministratorsSid() {return m_sidAdministrators;}
HRESULT GetToken(PSID pSid, IWbemToken** ppToken);
HRESULT RegisterFilterForAllClassChanges(CEventFilter* pFilter,
QL_LEVEL_1_RPN_EXPRESSION* pExpr);
HRESULT RegisterSinkForAllClassChanges(IWbemObjectSink* pSink,
QL_LEVEL_1_RPN_EXPRESSION* pExpr);
HRESULT RegisterSinkForClassChanges(IWbemObjectSink* pSink,
LPCWSTR wszClassName);
HRESULT UnregisterFilterFromAllClassChanges(CEventFilter* pFilter);
HRESULT UnregisterSinkFromAllClassChanges(IWbemObjectSink* pSink);
HRESULT RegisterProviderForClassChanges( LPCWSTR wszClassName,
LPCWSTR wszProvName );
HRESULT FirePostponedOperations();
HRESULT PostponeRelease(IUnknown* pUnk);
static PSID GetSidFromObject(IWbemClassObject* pObj);
BOOL DoesThreadOwnNamespaceLock();
void DumpStatistics(FILE* f, long lFlags);
friend class CEss;
friend class CEssMetaData;
friend class CFilterEnumSink;
friend class CConsumerEnumSink;
friend class CBindingEnumSink;
friend class CMonitorEnumSink;
friend class CInResync;
friend class CAssertBindingsSink;
friend class CFirePostponed;
};
class CInResync
{
protected:
CEssNamespace* m_pNamespace;
public:
CInResync(CEssNamespace* pNamespace) : m_pNamespace(pNamespace)
{
m_pNamespace->PrepareForResync();
}
void Commit()
{
if ( m_pNamespace != NULL )
{
m_pNamespace->ReactivateAllFilters();
m_pNamespace->CommitResync();
m_pNamespace = NULL;
}
}
~CInResync()
{
try
{
Commit();
}
catch( ... )
{
}
}
};
//
// The IWbemMetadata pointers are unmarshaled out when
// an external client calls RegisterProxy with an IWbemFilterProxy that is a COM-Proxy
// since a CStdIdentity wrapping them will be created, we need to keep the DLL alive
//
extern CLifeControl * g_pLifeControl;
class CEssMetaData : public CMetaData
{
protected:
CEssNamespace* m_pNamespace;
CLifeControl * m_pControl;
public:
CEssMetaData(CEssNamespace* pNamespace):
m_pControl(g_pLifeControl),
m_pNamespace(pNamespace)
{
m_pControl->ObjectCreated(this);
};
~CEssMetaData()
{
m_pControl->ObjectDestroyed(this);
};
virtual HRESULT GetClass( LPCWSTR wszName,
IWbemContext* pContext,
_IWmiObject** ppClass );
};
#endif