306 lines
7.2 KiB
C++
306 lines
7.2 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// 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<void**>(&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<class Type>
|
|
inline HRESULT HrCoTaskMemAllocArray(long nNumber, Type ** parType)
|
|
{
|
|
return HrCoTaskMemAllocArray(nNumber, sizeof(Type), reinterpret_cast<void**>(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 <class Inter>
|
|
HRESULT HrCoCreateInstance(
|
|
const CLSID & clsid,
|
|
DWORD dwClsContext,
|
|
Inter ** ppInter)
|
|
{
|
|
return HrCoCreateInstanceBase(
|
|
clsid,
|
|
dwClsContext,
|
|
__uuidof(Inter),
|
|
reinterpret_cast<void**>(ppInter));
|
|
}
|
|
|
|
template <class Inter>
|
|
HRESULT HrCoCreateInstanceInproc(
|
|
const CLSID & clsid,
|
|
Inter ** ppInter)
|
|
{
|
|
return HrCoCreateInstanceInprocBase(
|
|
clsid,
|
|
__uuidof(Inter),
|
|
reinterpret_cast<void**>(ppInter));
|
|
}
|
|
|
|
template <class Inter>
|
|
HRESULT HrCoCreateInstanceLocal(
|
|
const CLSID & clsid,
|
|
Inter ** ppInter)
|
|
{
|
|
return HrCoCreateInstanceLocalBase(
|
|
clsid,
|
|
__uuidof(Inter),
|
|
reinterpret_cast<void**>(ppInter));
|
|
}
|
|
|
|
template <class Inter>
|
|
HRESULT HrCoCreateInstanceServer(
|
|
const CLSID & clsid,
|
|
Inter ** ppInter)
|
|
{
|
|
return HrCoCreateInstanceServerBase(
|
|
clsid,
|
|
__uuidof(Inter),
|
|
reinterpret_cast<void**>(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 Inter>
|
|
class HideAddRefAndRelease : public Inter {
|
|
STDMETHOD_(ULONG, AddRef)()=0;
|
|
STDMETHOD_(ULONG, Release)()=0;
|
|
};
|
|
|
|
template <class Type> class SmartComPtr
|
|
{
|
|
typedef SmartComPtr<Type> 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 <class Inter>
|
|
HRESULT HrAttach(const SmartComPtr<Inter> & ref)
|
|
{
|
|
return HrAttach(ref.GetRawPointer());
|
|
}
|
|
~SmartComPtr()
|
|
{
|
|
Release();
|
|
}
|
|
// Conversion operators
|
|
// Bypass const for COM compatibility
|
|
operator PType() const
|
|
{
|
|
return const_cast<PType>(m_pType);
|
|
}
|
|
// Smart pointer accessor
|
|
HideAddRefAndRelease<Type>* operator->() const
|
|
{
|
|
return reinterpret_cast<HideAddRefAndRelease<Type>*>(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<void**>(AddressOf());
|
|
}
|
|
// Pointer comparison - uses COM notion of identity
|
|
template <class Inter>
|
|
HRESULT HrIsEqual(const SmartComPtr<Inter> & ref) const
|
|
{
|
|
return HrIsSameObject(m_pType, ref.m_pType);
|
|
}
|
|
HRESULT HrIsEqual(const IUnknown * pUnk) const
|
|
{
|
|
return HrIsSameObject(m_pType, pUnk);
|
|
}
|
|
template <class Inter>
|
|
bool operator==(const SmartComPtr<Inter> & 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>(pType);
|
|
AddRefObj(m_pType);
|
|
}
|
|
HRESULT InitUnknown(const IUnknown * pUnk)
|
|
{
|
|
Assert(!m_pType);
|
|
HRESULT hRes = E_POINTER;
|
|
if(pUnk)
|
|
{
|
|
hRes = const_cast<IUnknown*>(pUnk)->QueryInterface(&m_pType);
|
|
}
|
|
return hRes;
|
|
}
|
|
};
|