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.
 
 
 
 
 
 

305 lines
7.2 KiB

//+---------------------------------------------------------------------------
//
// 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;
}
};