/*++ Copyright (c) 2000 Microsoft Corporation Module Name: COMWrappers.h Abstract: Wrapper objects for COM Author: Hakki T. Bostanci (hakkib) 06-Apr-2000 Revision History: --*/ #ifndef _COM_WRAPPERS_H_ #define _COM_WRAPPERS_H_ ////////////////////////////////////////////////////////////////////////// // // cross-references // #include "Wrappers.h" ////////////////////////////////////////////////////////////////////////// // // vt_traits // // Traits class for mapping value types to the vt field and value offsets #define VT_F2O(field) FIELD_OFFSET(PROPVARIANT, field) #define VT_O2F(address, type, offset) (*(type *)((PBYTE) address + offset)) template struct vt_traits { }; template <> struct vt_traits { enum { vt = VT_I1, ofs = VT_F2O(cVal) }; }; template <> struct vt_traits { enum { vt = VT_UI1, ofs = VT_F2O(bVal) }; }; template <> struct vt_traits { enum { vt = VT_I2, ofs = VT_F2O(iVal) }; }; template <> struct vt_traits { enum { vt = VT_UI2, ofs = VT_F2O(uiVal) }; }; template <> struct vt_traits { enum { vt = VT_I4, ofs = VT_F2O(lVal) }; }; template <> struct vt_traits { enum { vt = VT_UI4, ofs = VT_F2O(ulVal) }; }; template <> struct vt_traits { enum { vt = VT_INT, ofs = VT_F2O(intVal) }; }; template <> struct vt_traits { enum { vt = VT_UINT, ofs = VT_F2O(uintVal) }; }; template <> struct vt_traits { enum { vt = VT_I8, ofs = VT_F2O(hVal) }; }; template <> struct vt_traits { enum { vt = VT_UI8, ofs = VT_F2O(uhVal) }; }; template <> struct vt_traits { enum { vt = VT_R4, ofs = VT_F2O(fltVal) }; }; template <> struct vt_traits { enum { vt = VT_R8, ofs = VT_F2O(dblVal) }; }; template <> struct vt_traits { enum { vt = VT_BOOL, ofs = VT_F2O(boolVal) }; }; //template <> struct vt_traits { enum { vt = VT_ERROR, ofs = VT_F2O(scode) }; }; template <> struct vt_traits { enum { vt = VT_CY, ofs = VT_F2O(cyVal) }; }; //template <> struct vt_traits { enum { vt = VT_DATE, ofs = VT_F2O(date) }; }; template <> struct vt_traits { enum { vt = VT_FILETIME, ofs = VT_F2O(filetime) }; }; //template <> struct vt_traits { enum { vt = VT_CLSID, ofs = VT_F2O(puuid) }; }; template <> struct vt_traits { enum { vt = VT_CF, ofs = VT_F2O(pclipdata) }; }; template <> struct vt_traits { enum { vt = VT_BSTR, ofs = VT_F2O(bstrVal) }; }; //?template <> struct vt_traits { enum { vt = VT_, ofs = VT_F2O(bstrblobVal) }; }; template <> struct vt_traits { enum { vt = VT_BLOB, ofs = VT_F2O(blob) }; }; template <> struct vt_traits { enum { vt = VT_LPSTR, ofs = VT_F2O(pszVal) }; }; template <> struct vt_traits { enum { vt = VT_LPWSTR, ofs = VT_F2O(pwszVal) }; }; template <> struct vt_traits > { enum { vt = VT_UNKNOWN, ofs = VT_F2O(punkVal) }; }; template <> struct vt_traits > { enum { vt = VT_DISPATCH, ofs = VT_F2O(pdispVal) }; }; template <> struct vt_traits > { enum { vt = VT_STREAM, ofs = VT_F2O(pStream) }; }; template <> struct vt_traits > { enum { vt = VT_STORAGE, ofs = VT_F2O(pStorage) }; }; //?template <> struct vt_traits { enum { vt = VT_, ofs = VT_F2O(pVersionedStream) }; }; //?template <> struct vt_traits { enum { vt = VT_ARRAY | VT_, ofs = VT_F2O(parray) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_I1, ofs = VT_F2O(cac) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_UI1, ofs = VT_F2O(caub) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_I2, ofs = VT_F2O(cai) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_UI2, ofs = VT_F2O(caui) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_I4, ofs = VT_F2O(cal) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_UI4, ofs = VT_F2O(caul) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_I8, ofs = VT_F2O(cah) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_UI8, ofs = VT_F2O(cauh) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_R4, ofs = VT_F2O(caflt) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_R8, ofs = VT_F2O(cadbl) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_BOOL, ofs = VT_F2O(cabool) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_ERROR, ofs = VT_F2O(cascode) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_CY, ofs = VT_F2O(cacy) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_DATE, ofs = VT_F2O(cadate) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_FILETIME, ofs = VT_F2O(cafiletime) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_CLSID, ofs = VT_F2O(cauuid) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_CF, ofs = VT_F2O(caclipdata) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_BSTR, ofs = VT_F2O(cabstr) }; }; //?template <> struct vt_traits { enum { vt = VT_VECTOR | VT_, ofs = VT_F2O(cabstrblob) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_LPSTR, ofs = VT_F2O(calpstr) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_LPWSTR, ofs = VT_F2O(calpwstr) }; }; template <> struct vt_traits { enum { vt = VT_VECTOR | VT_VARIANT, ofs = VT_F2O(capropvar) }; }; //template <> struct vt_traits { enum { vt = VT_BYREF | VT_I1, ofs = VT_F2O(cVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_UI1, ofs = VT_F2O(bVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_I2, ofs = VT_F2O(iVal) }; }; //template <> struct vt_traits { enum { vt = VT_BYREF | VT_UI2, ofs = VT_F2O(uiVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_I4, ofs = VT_F2O(lVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_UI4, ofs = VT_F2O(ulVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_INT, ofs = VT_F2O(intVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_UINT, ofs = VT_F2O(uintVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_R4, ofs = VT_F2O(fltVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_R8, ofs = VT_F2O(dblVal) }; }; //template <> struct vt_traits { enum { vt = VT_BYREF | VT_BOOL, ofs = VT_F2O(boolVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_DECIMAL, ofs = VT_F2O(scode) }; }; //template <> struct vt_traits { enum { vt = VT_BYREF | VT_ERROR, ofs = VT_F2O(scode) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_CY, ofs = VT_F2O(cyVal) }; }; //template <> struct vt_traits { enum { vt = VT_BYREF | VT_DATE, ofs = VT_F2O(date) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_BSTR, ofs = VT_F2O(bstrVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_UNKNOWN, ofs = VT_F2O(bstrVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_DISPATCH, ofs = VT_F2O(bstrVal) }; }; //?template <> struct vt_traits { enum { vt = VT_BYREF | VT_ARRAY | VT_, ofs = VT_F2O(bstrVal) }; }; template <> struct vt_traits { enum { vt = VT_BYREF | VT_VARIANT, ofs = VT_F2O(bstrVal) }; }; template <> struct vt_traits { enum { vt = VT_DECIMAL, ofs = VT_F2O(decVal) }; }; ////////////////////////////////////////////////////////////////////////// // // CPropVariant // // Wrapper class for the PROPVARIANT struct // class CPropVariant : public PROPVARIANT { // Constructors public: CPropVariant() { PropVariantInit(this); } ~CPropVariant() { PropVariantClear(this); } template <> CPropVariant(const CPropVariant &rhs) { PropVariantCopy(this, &rhs); } template CPropVariant(const T &rhs) { PropVariantInit(this); vt = vt_traits::vt; VT_O2F(this, T, vt_traits::ofs) = rhs; } template <> CPropVariant(const PROPVARIANT &rhs) { PropVariantCopy(this, &rhs); } template <> CPropVariant(const CLSID &rhs) { PropVariantInit(this); vt = VT_CLSID; puuid = (CLSID *) CoTaskMemAlloc(sizeof(CLSID)); *puuid = rhs; } // Assignment Operators public: CPropVariant& operator =(const CPropVariant &rhs) { if (&rhs != this) { PropVariantClear(this); PropVariantCopy(this, &rhs); } return *this; } template CPropVariant& operator =(const T &rhs) { PropVariantClear(this); vt = vt_traits::vt; VT_O2F(this, T, vt_traits::ofs) = rhs; return *this; } template <> CPropVariant& operator =(const PROPVARIANT& rhs) { PropVariantClear(this); PropVariantCopy(this, &rhs); return *this; } template <> CPropVariant& operator =(const CLSID &rhs) { PropVariantClear(this); vt = VT_CLSID; puuid = (CLSID *) CoTaskMemAlloc(sizeof(CLSID)); *puuid = rhs; return *this; } // Comparison Operators public: bool operator==(const PROPVARIANT& rhs) const { if (vt != rhs.vt) { return false; } switch (vt) { case VT_I1: return cVal == rhs.cVal; case VT_UI1: return bVal == rhs.bVal; case VT_I2: return iVal == rhs.iVal; case VT_UI2: return uiVal == rhs.uiVal; case VT_I4: return lVal == rhs.lVal; case VT_UI4: return ulVal == rhs.ulVal; case VT_INT: return intVal == rhs.intVal; case VT_UINT: return uintVal == rhs.uintVal; case VT_I8: return hVal.QuadPart == rhs.hVal.QuadPart; case VT_UI8: return uhVal.QuadPart == rhs.uhVal.QuadPart; case VT_R4: return fltVal == rhs.fltVal; case VT_R8: return dblVal == rhs.dblVal; case VT_BOOL: return boolVal == rhs.boolVal; case VT_ERROR: return scode == rhs.scode; case VT_CY: return cyVal.int64 == rhs.cyVal.int64; case VT_DATE: return date == rhs.date; case VT_FILETIME: return StructCmp(&filetime, &rhs.filetime) == 0; case VT_CLSID: return StructCmp(puuid, rhs.puuid) == 0; case VT_CF: return StructCmp(pclipdata, rhs.pclipdata) == 0; case VT_BSTR: return wcssafecmp(bstrVal, rhs.bstrVal) == 0; case VT_LPSTR: return strsafecmp(pszVal, rhs.pszVal) == 0; case VT_LPWSTR: return wcssafecmp(pwszVal, rhs.pwszVal) == 0; }; ASSERT(FALSE); return false; } bool operator!=(const PROPVARIANT& rhs) const { return !(*this == rhs); } // Operations public: HRESULT Clear() { return PropVariantClear(this); } HRESULT Copy(const PROPVARIANT &rhs) { return PropVariantCopy(this, &rhs); } HRESULT ChangeType(VARTYPE vtNew) { // bugbug: VariantChangeType() cannot do all the work... return vt == vtNew ? S_OK : VariantChangeType((VARIANT*) this, (VARIANT*) this, 0, vtNew); } }; ////////////////////////////////////////////////////////////////////////// // // CPropSpec // // Wrapper class for the PROPSPEC struct // class CPropSpec : public PROPSPEC { public: CPropSpec() { } CPropSpec(LPOLESTR _lpwstr) { ulKind = PRSPEC_LPWSTR; lpwstr = _lpwstr; } CPropSpec(PROPID _propid) { ulKind = PRSPEC_PROPID; propid = _propid; } CPropSpec &operator =(LPOLESTR _lpwstr) { ulKind = PRSPEC_LPWSTR; lpwstr = _lpwstr; return *this; } CPropSpec &operator =(PROPID _propid) { ulKind = PRSPEC_PROPID; propid = _propid; return *this; } }; ////////////////////////////////////////////////////////////////////////// // // CStgMedium // // Wrapper class for the STGMEDIUM // class CStgMedium : public STGMEDIUM { DISABLE_COPY_CONTRUCTION(CStgMedium); public: CStgMedium() { ZeroMemory(this, sizeof(*this)); } ~CStgMedium() { ReleaseStgMedium(this); } }; ////////////////////////////////////////////////////////////////////////// // // CStatPropStg // // Wrapper class for the STATPROPSTG struct // class CStatPropStg : public STATPROPSTG { DISABLE_COPY_CONTRUCTION(CStatPropStg); public: CStatPropStg() { ZeroMemory(this, sizeof(*this)); } ~CStatPropStg() { CoTaskMemFree(lpwstrName); } bool operator ==(const CStatPropStg &rhs) { return vt == rhs.vt && propid == rhs.propid && wcssafecmp(lpwstrName, rhs.lpwstrName) == 0; } bool operator !=(const CStatPropStg &rhs) { return !(*this == rhs); } }; ////////////////////////////////////////////////////////////////////////// // // CComPtrArray // // Helper class for automatically releasing an array of interface pointers // template class CComPtrArray { DISABLE_COPY_CONTRUCTION(CComPtrArray); public: CComPtrArray() { m_pArray = 0; m_nItemCount = 0; } ~CComPtrArray() { Release(); } void Release() { if (m_pArray) { for (int i = 0; i < m_nItemCount; ++i) { if (m_pArray[i]) { m_pArray[i]->Release(); } } CoTaskMemFree(m_pArray); m_pArray = 0; } m_nItemCount = 0; } operator T**() { return m_pArray; } bool operator!() { return m_pArray == 0; } T*** operator&() { ASSERT(m_pArray == 0); return &m_pArray; } LONG &ItemCount() { ASSERT(m_nItemCount == 0); return m_nItemCount; } private: T** m_pArray; LONG m_nItemCount; }; ////////////////////////////////////////////////////////////////////////// #endif //_COM_WRAPPERS_H_