2025-04-27 07:49:33 -04:00

424 lines
12 KiB
C++

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
REFRCLI.H
Abstract:
Refresher Client Side Code.
History:
--*/
#ifndef __UNIVERSAL_REFRESHER__H_
#define __UNIVERSAL_REFRESHER__H_
#include <unk.h>
#include <wbemcomn.h>
// Update this for client side refresher code. Make sure to update server
// version in refrcache.h as well.
#define WBEM_REFRESHER_VERSION 1
class CHiPerfProviderRecord
{
public:
long m_lRef;
CLSID m_clsid;
WString m_wsNamespace;
IWbemHiPerfProvider* m_pProvider;
public:
CHiPerfProviderRecord(REFCLSID rclsid, LPCWSTR wszNamespace,
IWbemHiPerfProvider* pProvider);
~CHiPerfProviderRecord();
long AddRef() {return InterlockedIncrement(&m_lRef);}
long Release();
BOOL IsReleased( void ) { return 0 == m_lRef; }
};
class CClientLoadableProviderCache
{
protected:
CUniquePointerArray<CHiPerfProviderRecord>* m_papRecords;
SHARED_LOCK_DATA m_LockData;
CSharedLock m_Lock;
public:
CClientLoadableProviderCache();
~CClientLoadableProviderCache();
HRESULT FindProvider(REFCLSID rclsid, LPCWSTR wszNamespace,
IUnknown* pNamespace, CHiPerfProviderRecord** ppProvider);
HRESULT FindProvider(REFCLSID rclsid, IWbemHiPerfProvider* pProvider,
LPCWSTR wszNamespace, CHiPerfProviderRecord** ppProvider);
void Flush();
void RemoveRecord( CHiPerfProviderRecord* pRecord );
class CLock
{
public:
CLock( CSharedLock* pLock ) : m_pLock( pLock ) { if ( NULL != m_pLock ) m_pLock->Lock(); }
~CLock() { if ( NULL != m_pLock ) m_pLock->Unlock(); }
CSharedLock* m_pLock;
};
};
class CUniversalRefresher : public CUnk
{
protected:
static CClientLoadableProviderCache mstatic_Cache;
public:
static CClientLoadableProviderCache* GetProviderCache()
{return &mstatic_Cache;}
class CClientRequest
{
protected:
CWbemObject* m_pClientObject;
long m_lClientId;
public:
CClientRequest(CWbemObject* pTemplate = NULL);
virtual ~CClientRequest();
void SetClientObject(CWbemObject* pClientObject);
void GetClientInfo(RELEASE_ME IWbemClassObject** ppRefresher,
long* plId);
long GetClientId() {return m_lClientId;}
INTERNAL CWbemObject* GetClientObject() {return m_pClientObject;}
};
class CDirect
{
public:
class CRequest : public CClientRequest
{
protected:
long m_lProviderId;
CWbemObject* m_pProviderObject;
public:
CRequest(CWbemObject* pProviderObject, CWbemObject* pClientObject, long lProviderId);
~CRequest();
virtual void Copy();
HRESULT Cancel(CDirect* pDirect);
};
class CEnumRequest : public CRequest
{
protected:
CClientLoadableHiPerfEnum* m_pHPEnum;
CReadOnlyHiPerfEnum* m_pClientEnum;
public:
CEnumRequest(CClientLoadableHiPerfEnum* pHPEnum, long lProviderId, CLifeControl* pLifeControl);
~CEnumRequest();
HRESULT GetClientInfo(RELEASE_ME IWbemHiPerfEnum** ppEnum,
long* plId);
void Copy();
};
protected:
CHiPerfProviderRecord* m_pProvider;
IWbemRefresher* m_pRefresher;
CUniquePointerArray<CRequest> m_apRequests;
public:
INTERNAL CHiPerfProviderRecord* GetProvider() {return m_pProvider;}
INTERNAL IWbemRefresher* GetRefresher() {return m_pRefresher;}
public:
CDirect(CHiPerfProviderRecord* pProvider, IWbemRefresher* pRefresher);
~CDirect();
HRESULT AddRequest(CWbemObject* pRefreshedObject, CWbemObject* pClientObject,
long lCancelId, IWbemClassObject** ppRefresher, long* plId);
HRESULT AddEnumRequest(CClientLoadableHiPerfEnum* pHPEnum, long lCancelId,
IWbemHiPerfEnum** ppEnum, long* plId,
CLifeControl* pLifeControl );
HRESULT Refresh(long lFlags);
HRESULT Remove(long lId, CUniversalRefresher* pContainer);
};
class CRemote
{
public:
class CRequest : public CClientRequest
{
protected:
long m_lRemoteId;
WString m_wstrRequestName;
public:
CRequest(CWbemObject* pTemplate, long lRemoteId, LPCWSTR pwcsRequestName);
~CRequest(){}
HRESULT Cancel(CRemote* pDirect);
long GetRemoteId() {return m_lRemoteId;}
void SetRemoteId( long lId ) { m_lRemoteId = lId; }
LPCWSTR GetName( void ) { return m_wstrRequestName; }
virtual BOOL IsEnum( void ) { return FALSE; }
virtual HRESULT Refresh( WBEM_REFRESHED_OBJECT* pRefrObj );
};
class CEnumRequest : public CRequest
{
protected:
long m_lRemoteId;
CReadOnlyHiPerfEnum* m_pClientEnum;
public:
CEnumRequest( CWbemObject* pTemplate, long lRemoteId, LPCWSTR pwcsRequestName,
CLifeControl* pLifeControl );
~CEnumRequest();
BOOL IsOk( void ) { return ( NULL != m_pClientEnum ); }
HRESULT GetEnum( IWbemHiPerfEnum** ppEnum );
virtual BOOL IsEnum( void ) { return TRUE; }
// Override for enumerators
HRESULT Refresh( WBEM_REFRESHED_OBJECT* pRefrObj );
};
protected:
// The actual remote refresher
IWbemRemoteRefresher* m_pRemRefresher;
// Remote Refresher GUID
GUID m_RemoteGuid;
// Security Info
COAUTHINFO m_CoAuthInfo;
// Namespace and server for reconnect
BSTR m_bstrNamespace;
// Server for Reconnect workaround
BSTR m_bstrServer;
// Are we connected
BOOL m_fConnected;
// Flag tells us to quit if reconnecting
BOOL m_fQuit;
// Requests
CUniquePointerArray<CRequest> m_apRequests;
// Cache of ids we removed.
CFlexArray m_alRemovedIds;
// Our wrapper object
CUniversalRefresher* m_pObject;
// Internal Critical Section
CCritSec m_cs;
// For marshaling/unmarshaling across apartment-models
// during the reconnect phase
IStream* m_pReconnectedRemote;
IStream* m_pReconnectSrv;
GUID m_ReconnectGuid;
long m_lRefCount;
protected:
// Helper workaround for COM/RPC inadequacies.
HRESULT IsAlive( void );
static unsigned __stdcall ThreadProc( void * pThis )
{
return ((CRemote*) pThis)->ReconnectEntry();
}
unsigned ReconnectEntry( void );
// Cleans up all the remote connections we may be holding onto
void ClearRemoteConnections( void );
public:
CRemote( IWbemRemoteRefresher* pRemRefresher, COAUTHINFO* pACoAuthInfo, const GUID* pGuid,
LPCWSTR pwszNamespace, LPCWSTR pwszServer, CUniversalRefresher* pObject );
~CRemote();
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT AddRequest(CWbemObject* pTemplate, LPCWSTR pwcsRequestName, long lCancelId,
IWbemClassObject** ppRefresher, long* plId );
HRESULT AddEnumRequest(CWbemObject* pTemplate, LPCWSTR pwcsRequestName, long lCancelId,
IWbemHiPerfEnum** ppEnum, long* plId,
CLifeControl* pLifeControl );
HRESULT Refresh(long lFlags);
HRESULT Remove(long lId, long lFlags, CUniversalRefresher* pContainer);
HRESULT ApplySecurity( void );
HRESULT Rebuild( IWbemServices* pNamespace );
HRESULT Rebuild( IWbemRefreshingServices* pRefServ, IWbemRemoteRefresher* pRemRefresher,
const GUID* pReconnectGuid );
HRESULT Reconnect( void );
BOOL IsConnectionError( HRESULT hr )
{
return ( RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr) || RPC_E_DISCONNECTED == hr ||
RPC_S_CALL_FAILED == HRESULT_CODE(hr) );
}
void CheckConnectionError( HRESULT, BOOL fStartReconnect = FALSE );
BOOL IsConnected( void )
{
return m_fConnected;
}
LPCWSTR GetNamespace( void )
{
return m_bstrNamespace;
}
void Quit( void )
{
m_fQuit = TRUE;
}
public:
INTERNAL IWbemRemoteRefresher* GetRemoteRefresher()
{return m_pRemRefresher;}
};
class CNestedRefresher
{
public:
CNestedRefresher( IWbemRefresher* pRefresher );
~CNestedRefresher();
HRESULT Refresh( long lFlags );
long GetId( void )
{ return m_lClientId; }
private:
IWbemRefresher* m_pRefresher;
long m_lClientId;
};
protected:
CUniquePointerArray<CDirect> m_apDirect;
CRefedPointerArray<CRemote> m_apRemote;
CUniquePointerArray<CNestedRefresher> m_apNestedRefreshers;
CRefresherId m_Id;
CHiPerfLock m_Lock;
static long mstatic_lLastId;
protected:
class XRefresher : public CImpl<IWbemRefresher, CUniversalRefresher>
{
public:
XRefresher(CUniversalRefresher* pObject) :
CImpl<IWbemRefresher, CUniversalRefresher>(pObject)
{}
STDMETHOD(Refresh)(long lFlags);
} m_XRefresher;
friend XRefresher;
class XCreate : public CImpl<IWbemConfigureRefresher, CUniversalRefresher>
{
public:
XCreate(CUniversalRefresher* pObject) :
CImpl<IWbemConfigureRefresher, CUniversalRefresher>(pObject)
{}
STDMETHOD(AddObjectByPath)(IWbemServices* pNamespace, LPCWSTR wszPath,
long lFlags, IWbemContext* pContext,
IWbemClassObject** ppRefreshable, long* plId);
STDMETHOD(AddObjectByTemplate)(IWbemServices* pNamespace,
IWbemClassObject* pTemplate,
long lFlags, IWbemContext* pContext,
IWbemClassObject** ppRefreshable, long* plId);
STDMETHOD(AddRefresher)(IWbemRefresher* pRefresher, long lFlags,
long* plId);
STDMETHOD(Remove)(long lId, long lFlags);
STDMETHOD(AddEnum)( IWbemServices* pNamespace, LPCWSTR wscClassName,
long lFlags, IWbemContext* pContext, IWbemHiPerfEnum** ppEnum,
long* plId );
} m_XCreate;
friend XCreate;
protected:
void* GetInterface(REFIID riid);
HRESULT AddInProcObject( CHiPerfProviderRecord* pProvider,
IWbemObjectAccess* pTemplate,
IWbemServices* pNamespace,
IWbemClassObject** ppRefreshable, long* plId);
HRESULT AddInProcEnum( CHiPerfProviderRecord* pProvider,
IWbemObjectAccess* pTemplate,
IWbemServices* pNamespace, LPCWSTR wszClassName,
IWbemHiPerfEnum** ppEnum, long* plId);
HRESULT AddClientLoadable(const WBEM_REFRESH_INFO_CLIENT_LOADABLE& Info,
IWbemServices* pNamespace,
IWbemClassObject** ppRefreshable, long* plId);
HRESULT AddClientLoadableEnum( const WBEM_REFRESH_INFO_CLIENT_LOADABLE& Info,
IWbemServices* pNamespace, LPCWSTR wszClassName,
IWbemHiPerfEnum** ppEnum, long* plId);
HRESULT AddDirect(const WBEM_REFRESH_INFO_DIRECT& Info,
IWbemServices* pNamespace,
IWbemClassObject** ppRefreshable, long* plId);
HRESULT AddDirectEnum( const WBEM_REFRESH_INFO_DIRECT& Info,
IWbemServices* pNamespace, LPCWSTR wszClassName,
IWbemHiPerfEnum** ppEnum, long* plId);
HRESULT FindRemoteEntry( const WBEM_REFRESH_INFO_REMOTE& Info,
COAUTHINFO* pAuthInfo,
CRemote** ppRemoteRecord );
HRESULT AddRemote( IWbemRefreshingServices* pRefServ, const WBEM_REFRESH_INFO_REMOTE& Info,
LPCWSTR pwcsRequestName, long lCancelId, IWbemClassObject** ppRefreshable, long* plId,
COAUTHINFO* pCoAuthInfo );
HRESULT AddRemoteEnum ( IWbemRefreshingServices* pRefServ, const WBEM_REFRESH_INFO_REMOTE& Info,
LPCWSTR pwcsRequestName, long lCancelId, IWbemHiPerfEnum** ppEnum,
long* plId, COAUTHINFO* pCoAuthInfo );
HRESULT AddRefresher( IWbemRefresher* pRefresher, long lFlags, long* plId );
HRESULT Remove(long lId, long lFlags);
HRESULT Refresh(long lFlags);
public:
CUniversalRefresher(CLifeControl* pControl, IUnknown* pOuter = NULL)
: CUnk(pControl, pOuter), m_XRefresher(this), m_XCreate(this)
{}
~CUniversalRefresher();
HRESULT GetRefreshingServices( IWbemServices* pNamespace,
IWbemRefreshingServices** ppRefSvc,
COAUTHINFO* pCoAuthInfo );
HRESULT FindProvider(REFCLSID rclsid, LPCWSTR wszNamespace,
IWbemHiPerfProvider** ppProvider);
INTERNAL CRefresherId* GetId() {return &m_Id;}
static long GetNewId();
static void Flush();
};
#endif