//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 2000. // // File: C O M U T I L I T Y . H // // Contents: COM support classes and functions // // Notes: // // Author: mbend 17 Aug 2000 // //---------------------------------------------------------------------------- #pragma once #include "ncbase.h" // Macro to make the validation of COM pointers easier #ifndef CHECK_POINTER #define CHECK_POINTER( p ) if(!p) {return E_POINTER;} #endif // CHECK_POINTER // Macros for use with iid_is style functions // For regular COM pointers #define SAFE_QI( p ) __uuidof( p ), reinterpret_cast(&p) // For smart com pointers #define SMART_QI( p ) p.IID(), p.VoidAddressOf() // String routines HRESULT HrCoTaskMemAllocArray(long nNumber, long nElemSize, void ** ppv); HRESULT HrCoTaskMemAllocString(long nChars, wchar_t ** psz); HRESULT HrCoTaskMemAllocString(wchar_t * sz, wchar_t ** psz); template inline HRESULT HrCoTaskMemAllocArray(long nNumber, Type ** parType) { return HrCoTaskMemAllocArray(nNumber, sizeof(Type), reinterpret_cast(parType)); } HRESULT HrCoCreateInstanceBase( REFCLSID clsid, DWORD dwClsContext, REFIID riid, void ** ppv); HRESULT HrCoCreateInstanceInprocBase( REFCLSID clsid, REFIID riid, void ** ppv); HRESULT HrCoCreateInstanceLocalBase( REFCLSID clsid, REFIID riid, void ** ppv); HRESULT HrCoCreateInstanceServerBase( REFCLSID clsid, REFIID riid, void ** ppv); template HRESULT HrCoCreateInstance( const CLSID & clsid, DWORD dwClsContext, Inter ** ppInter) { return HrCoCreateInstanceBase( clsid, dwClsContext, __uuidof(Inter), reinterpret_cast(ppInter)); } template HRESULT HrCoCreateInstanceInproc( const CLSID & clsid, Inter ** ppInter) { return HrCoCreateInstanceInprocBase( clsid, __uuidof(Inter), reinterpret_cast(ppInter)); } template HRESULT HrCoCreateInstanceLocal( const CLSID & clsid, Inter ** ppInter) { return HrCoCreateInstanceLocalBase( clsid, __uuidof(Inter), reinterpret_cast(ppInter)); } template HRESULT HrCoCreateInstanceServer( const CLSID & clsid, Inter ** ppInter) { return HrCoCreateInstanceServerBase( clsid, __uuidof(Inter), reinterpret_cast(ppInter)); } HRESULT HrIsSameObject(const IUnknown * pUnk1, const IUnknown * pUnk2); HRESULT HrSetProxyBlanket( IUnknown * pUnkProxy, DWORD dwAuthnLevel, DWORD dwImpLevel, DWORD dwCapabilities); HRESULT HrEnableStaticCloaking(IUnknown * pUnkProxy); HRESULT HrCopyProxyIdentity(IUnknown * pUnkDest, IUnknown * pUnkSrc); template class HideAddRefAndRelease : public Inter { STDMETHOD_(ULONG, AddRef)()=0; STDMETHOD_(ULONG, Release)()=0; }; template class SmartComPtr { typedef SmartComPtr SmartComPtrType; typedef Type * PType; typedef const Type * CPType; public: // Default Constructor SmartComPtr() : m_pType(NULL) {} // Copy Constructor SmartComPtr(const SmartComPtrType & ref) : m_pType(NULL) { Init(ref.m_pType); } // Assignment operators SmartComPtrType & operator=(const SmartComPtrType & ref) { if(this != &ref) { Release(); Init(ref.m_pType); } return *this; } SmartComPtrType & operator=(CPType pType) { Release(); Init(pType); return *this; } HRESULT HrAttach(const IUnknown * pUnk) { Release(); return InitUnknown(pUnk); } template HRESULT HrAttach(const SmartComPtr & ref) { return HrAttach(ref.GetRawPointer()); } ~SmartComPtr() { Release(); } // Conversion operators // Bypass const for COM compatibility operator PType() const { return const_cast(m_pType); } // Smart pointer accessor HideAddRefAndRelease* operator->() const { return reinterpret_cast*>(m_pType); } // Address of operator (should only be used to pass a NULL void** to a QI like function) PType * AddressOf() { // It is probably a bug if m_pType is not NULL Assert(!m_pType); Release(); m_pType = NULL; return &m_pType; } const IID & IID() const { return __uuidof(PType); } PType GetPointer() { PType pType = m_pType; if(pType) pType->AddRef(); return pType; } PType GetRawPointer() { return m_pType; } CPType GetRawPointer() const { return m_pType; } void ** VoidAddressOf() { return reinterpret_cast(AddressOf()); } // Pointer comparison - uses COM notion of identity template HRESULT HrIsEqual(const SmartComPtr & ref) const { return HrIsSameObject(m_pType, ref.m_pType); } HRESULT HrIsEqual(const IUnknown * pUnk) const { return HrIsSameObject(m_pType, pUnk); } template bool operator==(const SmartComPtr & ref) const { return S_OK == HrIsSameObject(m_pType, ref.m_pType); } bool operator==(const IUnknown * pUnk) const { return S_OK == HrIsSameObject(m_pType, pUnk); } operator bool() const { return !!m_pType; } bool operator!() const { return !m_pType; } HRESULT HrCreateInstance(const CLSID & clsid, DWORD clsctx) { Release(); return HrCoCreateInstance(clsid, clsctx, &m_pType); } HRESULT HrCreateInstanceInproc(const CLSID & clsid) { Release(); return HrCoCreateInstanceInproc(clsid, &m_pType); } HRESULT HrCreateInstanceLocal(const CLSID & clsid) { Release(); return HrCoCreateInstanceLocal(clsid, &m_pType); } HRESULT HrCreateInstanceServer(const CLSID & clsid) { Release(); return HrCoCreateInstanceServer(clsid, &m_pType); } HRESULT HrSetProxyBlanket( DWORD dwAuthnLevel, DWORD dwImpLevel, DWORD dwCapabilities) { return ::HrSetProxyBlanket(m_pType, dwAuthnLevel, dwImpLevel, dwCapabilities); } HRESULT HrEnableStaticCloaking() { return ::HrEnableStaticCloaking(m_pType); } HRESULT HrCopyProxyIdentity(IUnknown * pUnkSrc) { return ::HrCopyProxyIdentity(m_pType, pUnkSrc); } void Release() { ReleaseObj(m_pType); m_pType = NULL; } void Swap(SmartComPtrType & ref) { PType pType = m_pType; m_pType = ref.m_pType; ref.m_pType = pType; } private: PType m_pType; void Init(CPType pType) { Assert(!m_pType); m_pType = const_cast(pType); AddRefObj(m_pType); } HRESULT InitUnknown(const IUnknown * pUnk) { Assert(!m_pType); HRESULT hRes = E_POINTER; if(pUnk) { hRes = const_cast(pUnk)->QueryInterface(&m_pType); } return hRes; } };