|
|
#ifndef __OBJACCES_H__
#define __OBJACCES_H__
#include <wbemint.h>
#include <wstring.h>
#include <comutl.h>
#include <arrtempl.h>
#include <unk.h>
#include <map>
#include <vector>
#include <set>
#include <wstlallc.h>
#include "wmimsg.h"
typedef CWbemPtr<_IWmiObject> _IWmiObjectP; typedef std::vector< _IWmiObjectP, wbem_allocator<_IWmiObjectP> > ObjectArray;
/****************************************************************************
CPropAccessor - base class for all prop accessors. Property Accessors are passed back from the GetPropHandle() method of IWmiObjectAccessFactory. *****************************************************************************/
class CPropAccessor : public CUnk {
protected:
//
// if the object we're accessing is not a top level object, then we'll
// have a parent accessor to get it. Cannot hold reference here,
// because in some cases the parent may hold a reference on the child and
// we'd have a circular reference. It will not be possible though for a
// parent to be deleted out from the child.
//
CPropAccessor* m_pParent;
//
// Accessor to delegate to. Sometimes, once a prop accessor is
// handed out, we learn more about the property ( e.g. its type )
// and it would be beneficial to have the original accessor delegate
// to a more efficient one. we don't hold a reference here because
// the delegate will assume ownership of this object and will hold
// a reference on it. Holding a reference to the delegate would cause
// a circular reference.
//
CPropAccessor* m_pDelegateTo;
//
// whenever a prop accessor is replaced by a more efficient one, it
// is removed from the map. Since the map holds onto the ref that
// keeps the accessor alive, we need to the new accessor be responsible
// for cleaning up the original one. The original one is potentially
// still being used by the client ( but now delegates to the new accessor )
// ane we have to keep it alive for the lifetime of the access factory.
//
CWbemPtr<CPropAccessor> m_pResponsibleFor; //
// level of the property - 0 means its a property on a top level object.
//
int m_nLevel;
HRESULT GetParentObject( ObjectArray& raObjects, _IWmiObject** ppParent ); void* GetInterface( REFIID ) { return NULL; }
public:
CPropAccessor( CPropAccessor* pParent ) : m_pParent( pParent ), m_pDelegateTo( NULL ) { if ( pParent == NULL ) m_nLevel = 0; else m_nLevel = pParent->GetLevel() + 1; }
int GetLevel() const { return m_nLevel; } CPropAccessor* GetParent() { return m_pParent; }
enum AccessorType_e { e_Simple, e_Fast, e_Embedded };
virtual ~CPropAccessor() {}
virtual HRESULT GetProp( ObjectArray& raObjects, DWORD dwFlags, VARIANT* pvar, CIMTYPE* pct ) = 0;
virtual HRESULT PutProp( ObjectArray& raObjects, DWORD dwFlags, VARIANT* pvar, CIMTYPE ct ) = 0;
virtual AccessorType_e GetType() = 0;
void AssumeOwnership( CPropAccessor* pAccessor ) { m_pResponsibleFor = pAccessor; }
void DelegateTo( CPropAccessor* pAccessor ) { m_pDelegateTo = pAccessor; } };
typedef CWbemPtr<CPropAccessor> CPropAccessorP;
typedef std::map< WString, CPropAccessorP, WSiless, wbem_allocator<CPropAccessorP> > PropAccessMap;
/*****************************************************************************
CEmbeddedPropAccessor - accessor for an embedded object property. This impl caches the embedded object that is accessed to optimize subsequent accesses. ******************************************************************************/
class CEmbeddedPropAccessor : public CPropAccessor { //
// name of the embedded object property.
//
WString m_wsName; //
// the index in the object array where the embedded obj will be cached
// when accessed for the first time.
//
long m_lObjIndex;
//
// child accessors for the embedded object.
//
PropAccessMap m_mapPropAccess;
friend class CObjectAccessFactory;
public:
CEmbeddedPropAccessor( LPCWSTR wszName, long lObjIndex, CPropAccessor* pParent = NULL ) : CPropAccessor( pParent ), m_wsName( wszName ), m_lObjIndex( lObjIndex ) { }
HRESULT GetProp( ObjectArray& raObjects, DWORD dwFlags, VARIANT* pvar, CIMTYPE* pct );
HRESULT PutProp( ObjectArray& raObjects, DWORD dwFlags, VARIANT* pvar, CIMTYPE ct );
AccessorType_e GetType() { return e_Embedded; }
int GetObjectIndex() { return m_lObjIndex; } };
/*****************************************************************************
CSimplePropAccessor - simple accessor for non-embedded object properties. ******************************************************************************/
class CSimplePropAccessor : public CPropAccessor { //
// name of the embedded object property.
//
WString m_wsName;
public:
CSimplePropAccessor( LPCWSTR wszName, CPropAccessor* pParent = NULL ) : CPropAccessor( pParent ), m_wsName( wszName ) { }
HRESULT GetProp( ObjectArray& raObjects, DWORD dwFlags, VARIANT* pvar, CIMTYPE* pct );
HRESULT PutProp( ObjectArray& raObjects, DWORD dwFlags, VARIANT* pvar, CIMTYPE ct );
AccessorType_e GetType() { return e_Simple; } };
/*****************************************************************************
CFastPropAccessor - fast accessor base for non-embedded object properties. Is used when the type of the property is known at property handle creation. ******************************************************************************/
class CFastPropAccessor : public CPropAccessor { protected:
long m_lHandle; CIMTYPE m_ct;
public:
CFastPropAccessor( long lHandle, CIMTYPE ct, CPropAccessor* pParent=NULL ) : CPropAccessor( pParent ), m_lHandle( lHandle ), m_ct( ct ) { }
HRESULT GetProp( ObjectArray& raObjects, DWORD dwFlags, VARIANT* pvar, CIMTYPE* pct );
HRESULT PutProp( ObjectArray& raObjects, DWORD dwFlags, VARIANT* pvar, CIMTYPE ct );
AccessorType_e GetType() { return e_Fast; }
virtual HRESULT ReadValue( _IWmiObject* pObj, VARIANT* pvar ) = 0; virtual HRESULT WriteValue( _IWmiObject* pObj, VARIANT* pvar ) = 0; };
/*****************************************************************************
CStringPropAccessor ******************************************************************************/
class CStringPropAccessor : public CFastPropAccessor { public:
CStringPropAccessor( long lHandle, CIMTYPE ct, CPropAccessor* pParent=NULL) : CFastPropAccessor( lHandle, ct, pParent ) { }
HRESULT ReadValue( _IWmiObject* pObj, VARIANT* pvar ); HRESULT WriteValue( _IWmiObject* pObj, VARIANT* pvar ); };
/****************************************************************************
CObjectAccessFactory - impl for IWmiObjectAccessFactory *****************************************************************************/
class CObjectAccessFactory : public CUnkBase<IWmiObjectAccessFactory, &IID_IWmiObjectAccessFactory> { _IWmiObjectP m_pTemplate; PropAccessMap m_mapPropAccess; long m_lIndexGenerator;
HRESULT FindOrCreateAccessor( LPCWSTR wszPropElem, BOOL bEmbedded, CPropAccessor* pParent, CPropAccessor** ppAccessor ); public:
CObjectAccessFactory( CLifeControl* pControl ) : CUnkBase<IWmiObjectAccessFactory,&IID_IWmiObjectAccessFactory>(pControl), m_lIndexGenerator(1) { }
STDMETHOD(SetObjectTemplate)( IWbemClassObject* pTemplate ); STDMETHOD(GetObjectAccess)( IWmiObjectAccess** ppAccess ); STDMETHOD(GetPropHandle)( LPCWSTR wszProp, DWORD dwFlags, LPVOID* ppHdl ); };
/****************************************************************************
CObjectAccess - impl for IWmiObjectAccess. *****************************************************************************/
class CObjectAccess : public CUnkBase<IWmiObjectAccess,&IID_IWmiObjectAccess> { ObjectArray m_aObjects;
class CEmbeddedPropAccessorCompare { public: bool operator() ( const CEmbeddedPropAccessor* pA, const CEmbeddedPropAccessor* pB ) const { bool bRet; if ( !(pA == pB) ) if ( pA->GetLevel() == pB->GetLevel() ) bRet = pA < pB; else bRet = pA->GetLevel() > pB->GetLevel(); else bRet = FALSE; return bRet; } }; typedef std::set< CEmbeddedPropAccessor*, CEmbeddedPropAccessorCompare, wbem_allocator<CEmbeddedPropAccessor*> > EmbeddedPropAccessSet; EmbeddedPropAccessSet m_setEmbeddedAccessorsToCommit; public:
CObjectAccess( CLifeControl* pControl ) : CUnkBase<IWmiObjectAccess,&IID_IWmiObjectAccess> ( pControl ) {}
STDMETHOD(SetObject)( IWbemClassObject* pObj ); STDMETHOD(GetObject)( IWbemClassObject** ppObj );
//
// should support flags that describe what is going to be done
// with the value. If it's going to be put into another object then
// we'll give back a value which can only be used for that purpose. More
// efficient. e.g. we could use the get/put prop pointer methods
//
STDMETHOD(GetProp)( LPVOID pHdl, DWORD dwFlags, VARIANT* pvar, CIMTYPE* pct );
STDMETHOD(PutProp)( LPVOID pHdl, DWORD dwFlags, VARIANT* pvar, CIMTYPE ct );
STDMETHOD(CommitChanges)(); };
#endif // __OBJACCES_H__
|