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.
 
 
 
 
 
 

355 lines
8.2 KiB

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
UNK.H
Abstract:
IUnknown Helpers
History:
--*/
#ifndef __WBEM_UNKNOWN__H_
#define __WBEM_UNKNOWN__H_
#include <objbase.h>
#include "corepol.h"
#pragma warning(disable : 4355)
class POLARITY CLifeControl
{
public:
virtual BOOL ObjectCreated(IUnknown* pv) = 0;
virtual void ObjectDestroyed(IUnknown* pv) = 0;
virtual void AddRef(IUnknown* pv) = 0;
virtual void Release(IUnknown* pv) = 0;
};
class POLARITY CContainerControl : public CLifeControl
{
protected:
IUnknown* m_pUnk;
public:
CContainerControl(IUnknown* pUnk) : m_pUnk(pUnk){}
virtual BOOL ObjectCreated(IUnknown* pv){ return TRUE;};
virtual void ObjectDestroyed(IUnknown* pv){};
virtual void AddRef(IUnknown* pv){m_pUnk->AddRef();}
virtual void Release(IUnknown* pv){m_pUnk->Release();}
};
class POLARITY CUnk : public IUnknown
{
public:// THIS IS DUE TO A VC++ BUG!!! protected:
long m_lRef;
CLifeControl* m_pControl;
IUnknown* m_pOuter;
IUnknown* GetUnknown() {return m_pOuter?m_pOuter:(IUnknown*)this;}
virtual void* GetInterface(REFIID riid) = 0;
virtual BOOL OnInitialize(){return TRUE;}
public:
CUnk(CLifeControl* pControl = NULL, IUnknown* pOuter = NULL);
virtual ~CUnk();
virtual BOOL Initialize();
// non-delegating interface
STDMETHOD(QueryInterface)(REFIID riid, void** ppv);
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
IUnknown* GetInnerUnknown() {return this;}
void SetControl(CLifeControl* pControl);
};
class POLARITY CUnkInternal : public IUnknown
{
protected:
long m_lRef;
CLifeControl* m_pControl;
public:
CUnkInternal( CLifeControl* pControl ) : m_pControl(pControl), m_lRef(0) {}
virtual ~CUnkInternal() {}
virtual void* GetInterface(REFIID riid) = 0;
IUnknown* GetUnknown() { return (IUnknown*)this; }
STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
{
HRESULT hr = InternalQueryInterface( riid, ppv );
if ( SUCCEEDED(hr) )
AddRef();
return hr;
}
STDMETHOD_(ULONG, AddRef)()
{
if ( m_pControl )
m_pControl->ObjectCreated((IUnknown*)this);
return InternalAddRef();
}
STDMETHOD_(ULONG, Release)()
{
CLifeControl* pControl = m_pControl;
ULONG ulRef = InternalRelease();
if ( pControl )
pControl->ObjectDestroyed((IUnknown*)this);
return ulRef;
}
HRESULT InternalQueryInterface( REFIID riid, void** ppv )
{
HRESULT hr;
if( riid == IID_IUnknown )
*ppv = (IUnknown*)this;
else
*ppv = GetInterface(riid);
if ( *ppv != NULL )
hr = S_OK;
else
hr = E_NOINTERFACE;
return hr;
}
ULONG InternalAddRef()
{
return InterlockedIncrement(&m_lRef);
}
ULONG InternalRelease()
{
long lRef = InterlockedDecrement(&m_lRef);
if(lRef == 0)
delete this;
return lRef;
}
};
template <class TInterface, class TObject>
class CImpl : public TInterface
{
protected:
TObject* m_pObject;
public:
CImpl(TObject* pObject) : m_pObject(pObject){}
~CImpl(){}
// delegating interface
STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
{
return m_pObject->GetUnknown()->QueryInterface(riid, ppv);
}
STDMETHOD_(ULONG, AddRef)()
{
return m_pObject->GetUnknown()->AddRef();
}
STDMETHOD_(ULONG, Release)()
{
return m_pObject->GetUnknown()->Release();
}
};
template <class TInterface, const IID* t_piid>
class CUnkBase : public TInterface
{
protected:
long m_lRef;
CLifeControl* m_pControl;
public:
typedef CUnkBase<TInterface, t_piid> TUnkBase;
CUnkBase(CLifeControl* pControl = NULL)
: m_pControl(pControl), m_lRef(0)
{
if ( m_pControl != NULL ) m_pControl->ObjectCreated(this);
}
virtual ~CUnkBase()
{
if ( m_pControl != NULL ) m_pControl->ObjectDestroyed(this);
}
ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement(&m_lRef);
}
ULONG STDMETHODCALLTYPE Release()
{
long lRef = InterlockedDecrement(&m_lRef);
if(lRef == 0)
delete this;
return lRef;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown || riid == *t_piid)
{
AddRef();
*ppv = this;
return S_OK;
}
else return E_NOINTERFACE;
}
};
template <class TInterface, const IID* t_piid, class TInterface2,
const IID* t_piid2>
class CUnkBase2 : public TInterface, public TInterface2
{
protected:
long m_lRef;
CLifeControl* m_pControl;
public:
typedef CUnkBase2<TInterface, t_piid, TInterface2, t_piid2> TUnkBase;
CUnkBase2(CLifeControl* pControl = NULL) : m_pControl(pControl), m_lRef(0)
{
if (m_pControl != NULL)
m_pControl->ObjectCreated((TInterface*)this);
}
virtual ~CUnkBase2()
{
if (m_pControl != NULL)
m_pControl->ObjectDestroyed((TInterface*)this);
}
ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement(&m_lRef);
}
ULONG STDMETHODCALLTYPE Release()
{
long lRef = InterlockedDecrement(&m_lRef);
if(lRef == 0)
delete this;
return lRef;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown || riid == *t_piid)
{
AddRef();
*ppv = (TInterface*)this;
return S_OK;
}
else if(riid == *t_piid2)
{
AddRef();
*ppv = (TInterface2*)this;
return S_OK;
}
else return E_NOINTERFACE;
}
};
template<class TInterface1, class TInterface2>
class CChild2 : public virtual TInterface1, public virtual TInterface2
{
};
template<class TInterfaces>
class CUnkTemplate : public TInterfaces
{
protected:
IUnknown* m_pOuter;
class CInnerUnk : public IUnknown
{
private:
CUnkTemplate<TInterfaces>* m_pObject;
long m_lRef;
CLifeControl* m_pControl;
public:
CInnerUnk(CUnkTemplate<TInterfaces>* pObject, CLifeControl* pControl)
{
if(m_pControl) m_pControl->ObjectCreated(this);
m_lRef++;
GetUnknown()->AddRef();
m_pObject->Initialize();
GetUnknown()->Release();
m_lRef--;
}
~CInnerUnk()
{
if(m_pControl) m_pControl->ObjectDestroyed(this);
}
// non-delegating interface
STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown)
*ppv = (IUnknown*)&m_Inner;
else
*ppv = m_pObject->GetInterface(riid);
if(*ppv)
{
AddRef();
return S_OK;
}
else return E_NOINTERFACE;
}
STDMETHOD_(ULONG, AddRef)()
{
if(m_pControl) m_pControl->AddRef((IUnknown*)this);
return InterlockedIncrement(&m_lRef);
}
STDMETHOD_(ULONG, Release)()
{
if(m_pControl) m_pControl->Release((IUnknown*)this);
long lRef = InterlockedDecrement(&m_lRef);
if(lRef == 0)
{
m_lRef++;
delete m_pObject;
}
return lRef;
}
} m_Inner;
IUnknown* GetUnknown()
{return m_pOuter?m_pOuter:(IUnknown*)&m_Inner;}
virtual void Initialize(){}
public:
CUnkTemplate(CLifeControl* pControl = NULL, IUnknown* pOuter = NULL)
: m_Inner(this, pControl), m_pOuter(pOuter){}
virtual ~CUnkTemplate(){}
// delegating interface
STDMETHOD(QueryInterface)(REFIID riid, void** ppv)
{
return GetUnknown()->QueryInterface(riid, ppv);
}
STDMETHOD_(ULONG, AddRef)()
{
return GetUnknown()->AddRef();
}
STDMETHOD_(ULONG, Release)()
{
return GetUnknown()->Release();
}
IUnknown* GetInnerUnknown() {return &m_Inner;}
};
#endif