#ifndef COMPTR_H
#define COMPTR_H
#if _MSC_VER >= 1100
#pragma warning(disable:4800)
#include <comdef.h>
#define CIP_RETYPEDEF(I) typedef I##Ptr I##CIP;
#define CIP_TYPEDEF(I) _COM_SMARTPTR_TYPEDEF(I, IID_##I); CIP_RETYPEDEF(I);
#define DEFINE_CIP(x)\
	CIP_TYPEDEF(x)

#define DECLARE_CIP(x) DEFINE_CIP(x) x##CIP

CIP_RETYPEDEF(IUnknown);
CIP_RETYPEDEF(IDataObject);
CIP_RETYPEDEF(IStorage);
CIP_RETYPEDEF(IStream);
CIP_RETYPEDEF(IPersistStorage);
CIP_RETYPEDEF(IPersistStream);
CIP_RETYPEDEF(IPersistStreamInit);
CIP_RETYPEDEF(IDispatch);

#else // _MSC_VER < 1100

#define USE_OLD_COMPILER (_MSC_VER<1100)
#define USE_INTERMEDIATE_COMPILER (USE_OLD_COMPILER && (_MSC_VER>1020))

// This avoids "warning C4290: C++ Exception Specification ignored"
// JonN 12/16/96
#pragma warning(4:4290)

#ifndef BOOL_H
#include <bool.h>
#endif
#ifndef __wtypes_h__
#include <wtypes.h>
#endif

template<typename _Interface, const IID* _IID/*=&__uuidof(_Interface)*/>
	class CIID
	// Provide Interface to IID association
	{
	public: typedef _Interface Interface;

	public: static _Interface* GetInterfacePtr() throw()
			{
			return NULL;
			}

	public: static _Interface& GetInterface() throw()
			{
			return *GetInterfacePtr();
			}

	public: static const IID& GetIID() throw()
			{
			return *_IID;
			}
	}; // class CIID

template<typename _CIID> class CIP
	{
	#if USE_OLD_COMPILER
	private: class _IUnknown: public IUnknown {};
		// Unique type used to provide for operations between different pointer
		// types.
	#endif // USE_OLD_COMPILER

	// Declare interface type so that the type may be available outside
	// the scope of this template.
	public: typedef _CIID ThisCIID;
	public: typedef _CIID::Interface Interface;

	public: static const IID& GetIID() throw()
		// When the compiler supports references in template params,
		// _CLSID will be changed to a reference.  To avoid conversion
		// difficulties this function should be used to obtain the
		// CLSID.
		{
		return ThisCIID::GetIID();
		}

	//REVIEW: add support for assignment of nonpointer interfaces
	// i.e. IUnknown, instead of simple IUnknown*

	public: CIP()  throw()
		// Construct empty in preperation for assignment.
		: _pInterface(NULL)
		{
		}

	public: CIP(int null) throw()
		// This constructor is provided to allow NULL assignment.  It will assert
		// if any value other than null is assigned to the object.
		: _pInterface(NULL)
		{
		ASSERT(!null);
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	template<typename _InterfacePtr> CIP(_InterfacePtr p) throw()
		// Queries for this interface.
	#else
	public: CIP(_IUnknown& p) throw()
		: _pInterface(NULL)
		{
		if (&p)
			{
			const HRESULT hr = _QueryInterface(&p);
			ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
			}
		else _pInterface = NULL;
		}

	public: CIP(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		: _pInterface(NULL)
		{
		if (p)
			{
			const HRESULT hr = _QueryInterface(p);
			ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
			}
		else _pInterface = NULL;
		}

	public: CIP(const CIP& cp)  throw()
		// Copy the pointer and AddRef().
		: _pInterface(cp._pInterface)
		{
		_AddRef();
		}

	public: CIP(Interface* pInterface)  throw()
		// Saves the interface
		: _pInterface(pInterface)
		{
		_AddRef();
		}

	public: CIP(Interface* pInterface, bool bAddRef) throw()
		// Copies the pointer.  If bAddRef is TRUE, the interface will
		// be AddRef()ed.
		: _pInterface(pInterface)
		{
		if (bAddRef)
			{
			ASSERT(!pInterface);
			if (pInterface)
				_AddRef();
			}
		}

	public: CIP(const CLSID& clsid, DWORD dwClsContext = CLSCTX_ALL) explicit throw()
		// Calls CoCreateClass with the provided CLSID.
		: _pInterface(NULL)
		{
		const HRESULT hr = CreateInstance(clsid, dwClsContext);
		ASSERT(SUCCEEDED(hr));
		}

	public: CIP(LPOLESTR str, DWORD dwClsContext = CLSCTX_ALL) explicit throw()
		// Calls CoCreateClass with the provided CLSID retrieved from
		// the string.
		: _pInterface(NULL)
		{
		const HRESULT hr = CreateInstance(str, dwClsContext);
		ASSERT(SUCCEEDED(hr));
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfacePtr> CIP& operator=(_InterfacePtr& p) throw()
		// Queries for interface.
	#else
	public: CIP& operator=(_IUnknown& p) throw()
		{
		return operator=(static_cast<IUnknown*>(&p));
		}

	public: CIP& operator=(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		{
		const HRESULT hr = _QueryInterface(p);
		ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
		return *this;
		}

	public: CIP& operator=(Interface* pInterface) throw()
		// Saves the interface.
		{
		if (_pInterface != pInterface)
			{
			Interface* pOldInterface = _pInterface;
			_pInterface = pInterface;
			_AddRef();
			if (pOldInterface)
				pOldInterface->Release();
			}
		return *this;
		}

	public: CIP& operator=(const CIP& cp) throw()
		// Copies and AddRef()'s the interface.
		{
		return operator=(cp._pInterface);
		}

	public: CIP& operator=(int null) throw()
		// This operator is provided to permit the assignment of NULL to the class.
		// It will assert if any value other than NULL is assigned to it.
		{
		ASSERT(!null);
		return operator=(reinterpret_cast<Interface*>(NULL));
		}

	public: ~CIP() throw()
		// If we still have an interface then Release() it.  The interface
		// may be NULL if Detach() has previosly been called, or if it was
		// never set.
		{
		_Release();
		}

	public: void Attach(Interface* pInterface) throw()
		// Saves/sets the interface without AddRef()ing.  This call
		// will release any previously aquired interface.
		{
		_Release();
		_pInterface = pInterface;
		}

	public: void Attach(Interface* pInterface, bool bAddRef) throw()
		// Saves/sets the interface only AddRef()ing if bAddRef is TRUE.
		// This call will release any previously aquired interface.
		{
		_Release();
		_pInterface = pInterface;
		if (bAddRef)
			{
			ASSERT(pInterface);
			if (pInterface)
				pInterface->AddRef();
			}
		}

	public: Interface* Detach() throw()
		// Simply NULL the interface pointer so that it isn't Released()'ed.
		{
		Interface* const old=_pInterface;
		_pInterface = NULL;
		return old;
		}

	public: operator Interface*() const throw()
		// Return the interface.  This value may be NULL
		{
		return _pInterface;
		}

	public: Interface& operator*() const throw()
		// Allows an instance of this class to act as though it were the
		// actual interface.  Also provides minimal assertion verification.
		{
		ASSERT(_pInterface);
		return *_pInterface;
		}

	public: Interface** operator&() throw()
		// Returns the address of the interface pointer contained in this
		// class.  This is useful when using the COM/OLE interfaces to create
		// this interface.
		{
		_Release();
		_pInterface = NULL;
		return &_pInterface;
		}

	public: Interface* operator->() const throw()
		// Allows this class to be used as the interface itself.
		// Also provides simple assertion verification.
		{
		ASSERT(_pInterface);
		return _pInterface;
		}

	public: operator bool() const throw()
		// This operator is provided so that simple boolean expressions will
		// work.  For example: "if (p) ...".
		// Returns TRUE if the pointer is not NULL.
		{
		return _pInterface;
		}

	public: bool operator!() throw()
		// Returns TRUE if the interface is NULL.
		// This operator will be removed when support for type bool
		// is added to the compiler.
		{
		return !_pInterface;
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfacePtr> bool operator==(_InterfacePtr p) throw()
		// Compare to pointers
	#else
	public: bool operator==(_IUnknown& p) throw()
		{
		return operator==(static_cast<IUnknown*>(&p));
		}

	public: bool operator==(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		{
		return !_CompareUnknown(p);
		}

	public: bool operator==(Interface* p) throw()
		// Compare with other interface
		{
		return (_pInterface == p) ? true : !_CompareUnknown(p);
		}

	public: bool operator==(CIP& p) throw()
		// Compares 2 CIPs
		{
		return operator==(p._pInterface);
		}

	public: bool operator==(int null) throw()
		// For comparison to NULL
		{
		ASSERT(!null);
		return !_pInterface;
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfacePtr> bool operator!=(_InterfacePtr p) throw()
		// Compare to pointers
	#else
	public: bool operator!=(_IUnknown& p) throw()
		{
		return operator!=(static_cast<IUnknown*>(&p));
		}

	public: bool operator!=(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		{
		return _CompareUnknown(p);
		}

	public: bool operator!=(Interface* p) throw()
		// Compare with other interface
		{
		return (_pInterface!=p)?true:_CompareUnknown(p);
		}

	public: bool operator!=(CIP& p) throw()
		// Compares 2 CIPs
		{
		return operator!=(p._pInterface);
		}

	public: bool operator!=(int null) throw()
		// For comparison to NULL
		{
		ASSERT(!null);
		return _pInterface;
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfacePtr> bool operator<(_InterfacePtr p) throw()
		// Compare to pointers
	#else
	public: bool operator<(_IUnknown& p) throw()
		{
		return operator<(static_cast<IUnknown*>(&p));
		}

	public: bool operator<(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		{
		return _CompareUnknown(p)<0;
		}

	public: bool operator<(Interface* p) throw()
		// Compare with other interface
		{
		return (_pInterface<p) ? true : _CompareUnknown(p) < 0;
		}

	public: bool operator<(CIP& p) throw()
		// Compares 2 CIPs
		{
		return operator<(p._pInterface);
		}

	public: bool operator<(int null) throw()
		// For comparison with NULL
		{
		ASSERT(!null);
		return _pInterface<NULL;
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfacePtr> bool operator>(_InterfacePtr p) throw()
		// Compare to pointers
	#else
	public: bool operator>(_IUnknown& p) throw()
		{
		return operator>(static_cast<IUnknown*>(&p));
		}

	public: bool operator>(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		{
		return _CompareUnknown(p) > 0;
		}

	public: bool operator>(Interface* p) throw()
		// Compare with other interface
		{
		return (_pInterface>p) ? true : _CompareUnknown(p) > 0;
		}

	public: bool operator>(CIP& p) throw()
		// Compares 2 CIPs
		{
		return operator>(p._pInterface);
		}

	public: bool operator>(int null) throw()
		// For comparison with NULL
		{
		ASSERT(!null);
		return _pInterface > NULL;
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfacePtr> bool operator<=(_InterfacePtr p) throw()
		// Compare to pointers
	#else
	public: bool operator<=(_IUnknown& p) throw()
		{
		return operator<=(static_cast<IUnknown*>(&p));
		}

	public: bool operator<=(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		{
		return _CompareUnknown(p)<=0;
		}

	public: bool operator<=(Interface* p) throw()
		// Compare with other interface
		{
		return (_pInterface<=p) ? true : _CompareUnknown(p) <= 0;
		}

	public: bool operator<=(CIP& p) throw()
		// Compares 2 CIPs
		{
		return operator<=(p._pInterface);
		}

	public: bool operator<=(int null) throw()
		// For comparison with NULL
		{
		ASSERT(!null);
		return _pInterface <= NULL;
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfacePtr> bool operator>=(_InterfacePtr p) throw()
		// Compare to pointers
	#else
	public: bool operator>=(_IUnknown& p) throw()
		{
		return operator>=(static_cast<IUnknown*>(&p));
		}

	public: bool operator>=(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		{
		return _CompareUnknown(p) >= 0;
		}

	public: bool operator>=(Interface* p) throw()
		// Compare with other interface
		{
		return (_pInterface>=p) ? true : _CompareUnknown(p) >= 0;
		}

	public: bool operator>=(CIP& p) throw()
		// Compares 2 CIPs
		{
		return operator>=(p._pInterface);
		}

	public: bool operator>=(int null) throw()
		// For comparison with NULL
		{
		ASSERT(!null);
		return _pInterface >= NULL;
		}

	#if USE_OLD_COMPILER
	public: operator _IUnknown&() const throw()
		// Provided for casts between different pointer types.
		{
		return *reinterpret_cast<_IUnknown*>(static_cast<IUnknown*>(_pInterface));
		}
	#endif // USE_OLD_COMPILER

	public: void Release() throw()
		// Provides assertion verified, Release()ing of this interface.
		{
		ASSERT(_pInterface);
		if (_pInterface)
			{
			_pInterface->Release();
			_pInterface = NULL;
			}
		}

	public: void AddRef() throw()
		// Provides assertion verified AddRef()ing of this interface.
		{
		ASSERT(_pInterface);
		if (_pInterface)
			_pInterface->AddRef();
		}

	public: Interface* GetInterfacePtr() const throw()
		// Another way to get the interface pointer without casting.
		{
		return _pInterface;
		}

	public: HRESULT CreateInstance(
		const CLSID& clsid, DWORD dwClsContext=CLSCTX_ALL) throw()
		// Loads an interface for the provided CLSID.
		// Returns an HRESULT.  Any previous interface is released.
		{
		_Release();
		const HRESULT hr = CoCreateInstance(clsid, NULL, dwClsContext,
			GetIID(), reinterpret_cast<void**>(&_pInterface));
		ASSERT(SUCCEEDED(hr));
		return hr;
		}

	public: HRESULT CreateInstance(
		LPOLESTR clsidString, DWORD dwClsContext=CLSCTX_ALL) throw()
		// Creates the class specified by clsidString.  clsidString may
		// contain a class id, or a prog id string.
		{
		// ISSUE-2002/03/29-JonN Should handle NULL case
		ASSERT(clsidString);
		CLSID clsid;
		HRESULT hr;
		if (clsidString[0] == '{')
			hr = CLSIDFromString(clsidString, &clsid);
		else
			hr = CLSIDFromProgID(clsidString, &clsid);
		ASSERT(SUCCEEDED(hr));
		if (FAILED(hr))
			return hr;
		return CreateInstance(clsid, dwClsContext);
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType*& p) throw()
		// Perfoms the QI for the specified IID and returns it in p.
		// As with all QIs, the interface will be AddRef'd.
	#else
	public: HRESULT QueryInterface(const IID& iid, IUnknown*& p) throw()
	#endif // !USE_OLD_COMPILER
		{
		return _pInterface ?
			_pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p)) :
			E_NOINTERFACE;
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType** p) throw()
		// Perfoms the QI for the specified IID and returns it in p.
		// As with all QIs, the interface will be AddRef'd.
	#else
	public: HRESULT QueryInterface(const IID& iid, IUnknown** p) throw()
	#endif // !USE_OLD_COMPILER
		{
		return QueryInterface(iid, *p);
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	public: template<typename _InterfaceType> _InterfaceType* QueryInterface(const IID& iid) throw()
		// Perfoms the QI for the specified IID and returns it.
		// As with all QIs, the interface will be AddRef'd.
	#else
	public: IUnknown* QueryInterface(const IID& iid) throw()
	#endif // !USE_OLD_COMPILER
		{
		#if USE_OLD_COMPILER
		typedef IUnknown _InterfaceType;
		#endif // USE_OLD_COMPILER
		_InterfaceType* pInterface;
		QueryInterface(iid, pInterface);
		return pInterface;
		}

	private: Interface* _pInterface;
		// The Interface.

	private: void _Release() throw()
		// Releases only if the interface is not null.
		// The interface is not set to NULL.
		{
		if (_pInterface)
			_pInterface->Release();
		}

	private: void _AddRef() throw()
		// AddRefs only if the interface is not NULL
		{
		if (_pInterface)
			_pInterface->AddRef();
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	private: template<typename _InterfacePtr> HRESULT _QueryInterface(_InterfacePtr p) throw()
		// Performs a QI on pUnknown for the interface type returned
		// for this class.  The interface is stored.  If pUnknown is
		// NULL, or the QI fails, E_NOINTERFACE is returned and
		// _pInterface is set to NULL.
	#else
	private: HRESULT _QueryInterface(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		{
		if (!p) // Can't QI NULL
			{
			operator=(static_cast<Interface*>(NULL));
			return E_NOINTERFACE;
			}

		// Query for this interface
		Interface* pInterface;
		const HRESULT hr = p->QueryInterface(GetIID(),
			reinterpret_cast<void**>(&pInterface));
		if (FAILED(hr))
			{
			// If failed intialize interface to NULL and return HRESULT.
			Attach(NULL);
			return hr;
			}

		// Save the interface without AddRef()ing.
		Attach(pInterface);
		return hr;
		}

	#if !USE_OLD_COMPILER //REVIEW: remove after v5
	private: template<typename _InterfacePtr> int _CompareUnknown(_InterfacePtr& p) throw()
		// Compares the provided pointer with this by obtaining IUnknown interfaces
		// for each pointer and then returning the difference.
	#else
	private: int _CompareUnknown(IUnknown* p) throw()
	#endif // !USE_OLD_COMPILER
		{
		IUnknown* pu1;
		if (_pInterface)
			{
			const HRESULT hr = QueryInterface(IID_IUnknown, pu1);
			ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
			if (pu1)
				pu1->Release();
			}
		else pu1=NULL;

		IUnknown* pu2;
		if (p)
			{
			const HRESULT hr = p->QueryInterface(IID_IUnknown, reinterpret_cast<void**>(&pu2));
			ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
			if (pu2)
				pu2->Release();
			}
		else pu2 = NULL;
		return pu1 - pu2;
		}
	}; // class CIP

// Reverse comparison operators for CIP
template<typename _Interface> bool operator==(int null, CIP<_Interface>& p)
	{
	ASSERT(!null);
	return p == NULL;
	}

template<typename _Interface, typename _InterfacePtr> bool operator==(_Interface* i, CIP<_InterfacePtr>& p)
	{
	return p == i;
	}

template<typename _Interface> bool operator!=(int null, CIP<_Interface>& p)
	{
	ASSERT(!null);
	return p != NULL;
	}

template<typename _Interface, typename _InterfacePtr> bool operator!=(_Interface* i, CIP<_InterfacePtr>& p)
	{
	return p != i;
	}

template<typename _Interface> bool operator<(int null, CIP<_Interface>& p)
	{
	ASSERT(!null);
	return p < NULL;
	}

template<typename _Interface, typename _InterfacePtr> bool operator<(_Interface* i, CIP<_InterfacePtr>& p)
	{
	return p < i;
	}

template<typename _Interface> bool operator>(int null, CIP<_Interface>& p)
	{
	ASSERT(!null);
	return p > NULL;
	}

template<typename _Interface, typename _InterfacePtr> bool operator>(_Interface* i, CIP<_InterfacePtr>& p)
	{
	return p > i;
	}

template<typename _Interface> bool operator<=(int null, CIP<_Interface>& p)
	{
	ASSERT(!null);
	return p <= NULL;
	}

template<typename _Interface, typename _InterfacePtr> bool operator<=(_Interface* i, CIP<_InterfacePtr>& p)
	{
	return p <= i;
	}

template<typename _Interface> bool operator>=(int null, CIP<_Interface>& p)
	{
	ASSERT(!null);
	return p >= NULL;
	}

template<typename _Interface, typename _InterfacePtr> bool operator>=(_Interface* i, CIP<_InterfacePtr>& p)
	{
	return p >= i;
	}

#define DEFINE_CIP(x)\
	typedef CIID<x, &IID_##x> x##IID;\
	typedef CIP<x##IID> x##CIP;

#define DECLARE_CIP(x) DEFINE_CIP(x) x##CIP

DEFINE_CIP(IUnknown);

#if USE_OLD_COMPILER
#if USE_INTERMEDIATE_COMPILER
template<>
#endif
class CIP<IUnknownIID>
{
private:
	#if USE_OLD_COMPILER
	// Unique type used to provide for operations between different pointer
	// types.
	class _IUnknown: public IUnknown {};
	#endif // USE_OLD_COMPILER

public:
	// Declare interface type so that the type may be available outside
	// the scope of this template.
	typedef IUnknownIID ThisCIID;
	typedef IUnknown Interface;

	// When the compiler supports references in template params,
	// _CLSID will be changed to a reference.  To avoid conversion
	// difficulties this function should be used to obtain the
	// CLSID.
	static const IID& GetIID() throw()
	{
		return ThisCIID::GetIID();
	}

	// Construct empty in preperation for assignment.
	CIP()  throw()
		: _pInterface(NULL)
	{
	}

	// This constructor is provided to allow NULL assignment.  It will assert
	// if any value other than null is assigned to the object.
	CIP(int null) throw()
		: _pInterface(NULL)
	{
		ASSERT(!null);
	}

	CIP(_IUnknown& p) throw()
		: _pInterface(NULL)
	{
		if (&p)
		{
			const HRESULT hr=_QueryInterface(&p);
			ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
		}
		else _pInterface=NULL;
	}

	// Copy the pointer and AddRef().
	CIP(const CIP& cp)  throw()
		: _pInterface(cp._pInterface)
	{
		_AddRef();
	}

	// Saves the interface
	CIP(Interface* pInterface)  throw()
		: _pInterface(pInterface)
	{
		_AddRef();
	}

	// Copies the pointer.  If bAddRef is TRUE, the interface will
	// be AddRef()ed.
	CIP(Interface* pInterface, bool bAddRef) throw()
		: _pInterface(pInterface)
	{
		if (bAddRef)
		{
			ASSERT(!pInterface);
			_AddRef();
		}
	}

	// Calls CoCreateClass with the provided CLSID.
	CIP(const CLSID& clsid, DWORD dwClsContext = CLSCTX_ALL) explicit throw()
		: _pInterface(NULL)
	{
		const HRESULT hr = CreateInstance(clsid, dwClsContext);
		ASSERT(SUCCEEDED(hr));
	}

	// Calls CoCreateClass with the provided CLSID retrieved from
	// the string.
	CIP(LPOLESTR str, DWORD dwClsContext = CLSCTX_ALL) explicit throw()
		: _pInterface(NULL)
	{
		const HRESULT hr = CreateInstance(str, dwClsContext);
		ASSERT(SUCCEEDED(hr));
	}

	CIP& operator=(_IUnknown& p) throw()
	{
		return operator=(static_cast<IUnknown*>(&p));
	}

	// Saves the interface.
	CIP& operator=(Interface* pInterface) throw()
	{
		if (_pInterface != pInterface)
		{
			Interface* pOldInterface = _pInterface;
			_pInterface = pInterface;
			_AddRef();
			if (pOldInterface)
				pOldInterface->Release();
		}
		return *this;
	}

	// Copies and AddRef()'s the interface.
	CIP& operator=(const CIP& cp) throw()
	{
		return operator=(cp._pInterface);
	}

	// This operator is provided to permit the assignment of NULL to the class.
	// It will assert if any value other than NULL is assigned to it.
	CIP& operator=(int null) throw()
	{
		ASSERT(!null);
		return operator=(reinterpret_cast<Interface*>(NULL));
	}

	// If we still have an interface then Release() it.  The interface
	// may be NULL if Detach() has previosly been called, or if it was
	// never set.
	~CIP() throw()
	{
		_Release();
	}

	// Saves/sets the interface without AddRef()ing.  This call
	// will release any previously aquired interface.
	void Attach(Interface* pInterface) throw()
	{
		_Release();
		_pInterface = pInterface;
	}

	// Saves/sets the interface only AddRef()ing if bAddRef is TRUE.
	// This call will release any previously aquired interface.
	void Attach(Interface* pInterface, bool bAddRef) throw()
	{
		_Release();
		_pInterface = pInterface;
		if (bAddRef)
		{
			ASSERT(pInterface);
			if (pInterface)
				pInterface->AddRef();
		}
	}

	// Simply NULL the interface pointer so that it isn't Released()'ed.
	IUnknown* Detach() throw()
	{
		ASSERT(_pInterface);
        IUnknown* const old = _pInterface;
		_pInterface = NULL;
        return old;
	}

	// Return the interface.  This value may be NULL
	operator Interface*() const throw()
	{
		return _pInterface;
	}

	// Queries for the unknown and return it
	// Provides minimal level assertion before use.
	operator Interface&() const throw()
	{
		ASSERT(_pInterface);
		return *_pInterface;
	}

	// Allows an instance of this class to act as though it were the
	// actual interface.  Also provides minimal assertion verification.
	Interface& operator*() const throw()
	{
		ASSERT(_pInterface);
		return *_pInterface;
	}

	// Returns the address of the interface pointer contained in this
	// class.  This is useful when using the COM/OLE interfaces to create
	// this interface.
	Interface** operator&() throw()
	{
		_Release();
		_pInterface = NULL;
		return &_pInterface;
	}

	// Allows this class to be used as the interface itself.
	// Also provides simple assertion verification.
	Interface* operator->() const throw()
	{
		ASSERT(_pInterface);
		return _pInterface;
	}

	// This operator is provided so that simple boolean expressions will
	// work.  For example: "if (p) ...".
	// Returns TRUE if the pointer is not NULL.
	operator bool() const throw()
	{
		return _pInterface;
	}

	// Returns TRUE if the interface is NULL.
	// This operator will be removed when support for type bool
	// is added to the compiler.
	bool operator!() throw()
	{
		return !_pInterface;
	}

	bool operator==(_IUnknown& p) throw()
	{
		return operator==(static_cast<IUnknown*>(&p));
	}

	// Compare with other interface
	bool operator==(Interface* p) throw()
	{
		return (_pInterface==p)?true:!_CompareUnknown(p);
	}

	// Compares 2 CIPs
	bool operator==(CIP& p) throw()
	{
		return operator==(p._pInterface);
	}

	// For comparison to NULL
	bool operator==(int null) throw()
	{
		ASSERT(!null);
		return !_pInterface;
	}

	bool operator!=(_IUnknown& p) throw()
	{
		return operator!=(static_cast<IUnknown*>(&p));
	}

	// Compare with other interface
	bool operator!=(Interface* p) throw()
	{
		return (_pInterface!=p)?true:_CompareUnknown(p);
	}

	// Compares 2 CIPs
	bool operator!=(CIP& p) throw()
	{
		return operator!=(p._pInterface);
	}

	// For comparison to NULL
	bool operator!=(int null) throw()
	{
		ASSERT(!null);
		return _pInterface;
	}

	bool operator<(_IUnknown& p) throw()
	{
		return operator<(static_cast<IUnknown*>(&p));
	}

	// Compare with other interface
	bool operator<(Interface* p) throw()
	{
		return (_pInterface<p)?true:_CompareUnknown(p)<0;
	}

	// Compares 2 CIPs
	bool operator<(CIP& p) throw()
	{
		return operator<(p._pInterface);
	}

	// For comparison with NULL
	bool operator<(int null) throw()
	{
		ASSERT(!null);
		return _pInterface<NULL;
	}

	bool operator>(_IUnknown& p) throw()
	{
		return operator>(static_cast<IUnknown*>(&p));
	}

	// Compare with other interface
	bool operator>(Interface* p) throw()
	{
		return (_pInterface>p)?true:_CompareUnknown(p)>0;
	}

	// Compares 2 CIPs
	bool operator>(CIP& p) throw()
	{
		return operator>(p._pInterface);
	}

	// For comparison with NULL
	bool operator>(int null) throw()
	{
		ASSERT(!null);
		return _pInterface>NULL;
	}

	bool operator<=(_IUnknown& p) throw()
	{
		return operator<=(static_cast<IUnknown*>(&p));
	}

	// Compare with other interface
	bool operator<=(Interface* p) throw()
	{
		return (_pInterface<=p)?true:_CompareUnknown(p)<=0;
	}

	// Compares 2 CIPs
	bool operator<=(CIP& p) throw()
	{
		return operator<=(p._pInterface);
	}

	// For comparison with NULL
	bool operator<=(int null) throw()
	{
		ASSERT(!null);
		return _pInterface<=NULL;
	}

	bool operator>=(_IUnknown& p) throw()
	{
		return operator>=(static_cast<IUnknown*>(&p));
	}

	// Compare with other interface
	bool operator>=(Interface* p) throw()
	{
		return (_pInterface>=p)?true:_CompareUnknown(p)>=0;
	}

	// Compares 2 CIPs
	bool operator>=(CIP& p) throw()
	{
		return operator>=(p._pInterface);
	}

	// For comparison with NULL
	bool operator>=(int null) throw()
	{
		ASSERT(!null);
		return _pInterface>=NULL;
	}

	// Provided for casts between different pointer types.
	operator _IUnknown&() const throw()
	{
		return *reinterpret_cast<_IUnknown*>(static_cast<IUnknown*>(_pInterface));
	}

	// Provides assertion verified, Release()ing of this interface.
	void Release() throw()
	{
		ASSERT(_pInterface);
		if (_pInterface)
			{
			_pInterface->Release();
			_pInterface = NULL;
			}
	}

	// Provides assertion verified AddRef()ing of this interface.
	void AddRef() throw()
	{
		ASSERT(_pInterface);
		if (_pInterface)
			_pInterface->AddRef();
	}

	// Another way to get the interface pointer without casting.
	Interface* GetInterfacePtr() const throw()
	{
		return _pInterface;
	}

	// Loads an interface for the provided CLSID.
	// Returns an HRESULT.  Any previous interface is released.
	HRESULT CreateInstance(
		const CLSID& clsid, DWORD dwClsContext=CLSCTX_ALL) throw()
	{
		_Release();
		const HRESULT hr = CoCreateInstance(clsid, NULL, dwClsContext,
			GetIID(), reinterpret_cast<void**>(&_pInterface));
		ASSERT(SUCCEEDED(hr));
		return hr;
	}

	// Creates the class specified by clsidString.  clsidString may
	// contain a class id, or a prog id string.
	HRESULT CreateInstance(
		LPOLESTR clsidString, DWORD dwClsContext=CLSCTX_ALL) throw()
	{
		// ISSUE-2002/03/29-JonN Should handle NULL case
		ASSERT(clsidString);
		CLSID clsid;
		HRESULT hr;
		if (clsidString[0] == '{')
			hr = CLSIDFromString(clsidString, &clsid);
		else
			hr = CLSIDFromProgID(clsidString, &clsid);
		ASSERT(SUCCEEDED(hr));
		if (FAILED(hr))
			return hr;
		return CreateInstance(clsid, dwClsContext);
	}

	HRESULT QueryInterface(const IID& iid, IUnknown*& p) throw()
	{
		return _pInterface ?
			_pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p)) :
			E_NOINTERFACE;
	}

	HRESULT QueryInterface(const IID& iid, IUnknown** p) throw()
	{
		return QueryInterface(iid, *p);
	}

	// Perfoms the QI for the specified IID and returns it.
	// As with all QIs, the interface will be AddRef'd.
	IUnknown* QueryInterface(const IID& iid) throw()
	{
		typedef IUnknown _InterfaceType;
		_InterfaceType* pInterface;
		QueryInterface(iid, pInterface);
		return pInterface;
	}

private:
	// The Interface.
	Interface* _pInterface;

	// Releases only if the interface is not null.
	// The interface is not set to NULL.
	void _Release() throw()
	{
		if (_pInterface)
			_pInterface->Release();
	}

	// AddRefs only if the interface is not NULL
	void _AddRef() throw()
	{
		if (_pInterface)
			_pInterface->AddRef();
	}

	// Performs a QI on pUnknown for the interface type returned
	// for this class.  The interface is stored.  If pUnknown is
	// NULL, or the QI fails, E_NOINTERFACE is returned and
	// _pInterface is set to NULL.
	HRESULT _QueryInterface(IUnknown* p) throw()
	{
		if (!p) // Can't QI NULL
		{
			operator=(static_cast<Interface*>(NULL));
			return E_NOINTERFACE;
		}

		// Query for this interface
		Interface* pInterface;
		const HRESULT hr = p->QueryInterface(GetIID(),
			reinterpret_cast<void**>(&pInterface));
		if (FAILED(hr))
		{
			// If failed intialize interface to NULL and return HRESULT.
			Attach(NULL);
			return hr;
		}

		// Save the interface without AddRef()ing.
		Attach(pInterface);
		return hr;
	}

	// Compares the provided pointer with this by obtaining IUnknown interfaces
	// for each pointer and then returning the difference.
	int _CompareUnknown(IUnknown* p) throw()
	{
		IUnknown* pu1;
		if (_pInterface)
		{
			const HRESULT hr=QueryInterface(IID_IUnknown, pu1);
			ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
			if (pu1)
				pu1->Release();
		}
		else pu1=NULL;

		IUnknown* pu2;
		if (p)
		{
			const HRESULT hr=p->QueryInterface(IID_IUnknown, reinterpret_cast<void**>(&pu2));
			ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
			if (pu2)
				pu2->Release();
		}
		else pu2=NULL;
		return pu1-pu2;
	}
}; // class CIP
#endif // USE_OLD_COMPILER

#endif // _MSC_VER < 1100
#endif // COMPTR_H