Home | History | Annotate | Download | only in include
      1 /**
      2  * This file has no copyright assigned and is placed in the Public Domain.
      3  * This file is part of the mingw-w64 runtime package.
      4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
      5  */
      6 #ifndef _INC_COMIP
      7 #define _INC_COMIP
      8 
      9 #include <_mingw.h>
     10 
     11 #include <ole2.h>
     12 #include <malloc.h>
     13 
     14 #include <comutil.h>
     15 
     16 #ifdef __cplusplus
     17 
     18 #pragma push_macro("new")
     19 #undef new
     20 
     21 #include <new.h>
     22 
     23 class _com_error;
     24 
     25 #ifndef WINAPI
     26 #define WINAPI __stdcall
     27 #endif
     28 
     29 void WINAPI _com_issue_error(HRESULT);
     30 struct IUnknown;
     31 
     32 template<typename _Interface,const IID *_IID >
     33 class _com_IIID {
     34 public:
     35   typedef _Interface Interface;
     36   static _Interface *GetInterfacePtr() throw() { return NULL; }
     37   static _Interface& GetInterface() throw() { return *GetInterfacePtr(); }
     38   static const IID& GetIID() throw() { return *_IID; }
     39 };
     40 
     41 template<typename _IIID> class _com_ptr_t {
     42 public:
     43   typedef _IIID ThisIIID;
     44   typedef typename _IIID::Interface Interface;
     45   static const IID& GetIID() throw() { return ThisIIID::GetIID(); }
     46   template<typename _OtherIID> _com_ptr_t(const _com_ptr_t<_OtherIID> &p) : m_pInterface(NULL) {
     47     HRESULT hr = _QueryInterface(p);
     48     if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
     49   }
     50   template<typename _InterfaceType> _com_ptr_t(_InterfaceType *p) : m_pInterface(NULL) {
     51     HRESULT hr = _QueryInterface(p);
     52     if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
     53   }
     54   template<typename _X> _com_ptr_t(LPSTR str) { new(this) _com_ptr_t(static_cast<LPCSTR> (str),NULL); }
     55   template<typename _X> _com_ptr_t(LPWSTR str) { new(this) _com_ptr_t(static_cast<LPCWSTR> (str),NULL); }
     56   template<typename _X> explicit _com_ptr_t(_com_ptr_t *p) : m_pInterface(NULL) {
     57     if(!p) { _com_issue_error(E_POINTER); }
     58     else {
     59       m_pInterface = p->m_pInterface;
     60       AddRef();
     61     }
     62   }
     63   _com_ptr_t() throw() : m_pInterface(NULL) { }
     64   _com_ptr_t(int null) : m_pInterface(NULL) {
     65     if(null!=0) { _com_issue_error(E_POINTER); }
     66   }
     67 
     68 #ifdef _NATIVE_NULLPTR_SUPPORTED
     69   _com_ptr_t(decltype(nullptr)) : m_pInterface(NULL) {}
     70 #endif
     71 
     72   _com_ptr_t(const _com_ptr_t &cp) throw() : m_pInterface(cp.m_pInterface) { _AddRef(); }
     73   template<typename _X> _com_ptr_t(Interface *pInterface) throw() : m_pInterface(pInterface) { _AddRef(); }
     74   _com_ptr_t(Interface *pInterface,bool fAddRef) throw() : m_pInterface(pInterface) {
     75     if(fAddRef) _AddRef();
     76   }
     77   _com_ptr_t(const _variant_t& varSrc) : m_pInterface(NULL) {
     78     HRESULT hr = QueryStdInterfaces(varSrc);
     79     if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
     80   }
     81   explicit _com_ptr_t(const CLSID &clsid,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) : m_pInterface(NULL) {
     82     HRESULT hr = CreateInstance(clsid,pOuter,dwClsContext);
     83     if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
     84   }
     85   explicit _com_ptr_t(LPCWSTR str,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) : m_pInterface(NULL) {
     86     HRESULT hr = CreateInstance(str,pOuter,dwClsContext);
     87     if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
     88   }
     89   explicit _com_ptr_t(LPCSTR str,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) : m_pInterface(NULL) {
     90     HRESULT hr = CreateInstance(str,pOuter,dwClsContext);
     91     if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
     92   }
     93   template<typename _OtherIID> _com_ptr_t &operator=(const _com_ptr_t<_OtherIID> &p) {
     94     HRESULT hr = _QueryInterface(p);
     95     if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
     96     return *this;
     97   }
     98   template<typename _InterfaceType> _com_ptr_t &operator=(_InterfaceType *p) {
     99     HRESULT hr = _QueryInterface(p);
    100     if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
    101     return *this;
    102   }
    103   template<typename _X> _com_ptr_t &operator=(Interface *pInterface) throw() {
    104     if(m_pInterface!=pInterface) {
    105       Interface *pOldInterface = m_pInterface;
    106       m_pInterface = pInterface;
    107       _AddRef();
    108       if(pOldInterface!=NULL) pOldInterface->Release();
    109     }
    110     return *this;
    111   }
    112   _com_ptr_t &operator=(const _com_ptr_t &cp) throw() { return operator=(cp.m_pInterface); }
    113   _com_ptr_t &operator=(int null) {
    114     if(null!=0) { _com_issue_error(E_POINTER); }
    115     return operator=(reinterpret_cast<Interface*>(NULL));
    116   }
    117   _com_ptr_t &operator=(const _variant_t& varSrc) {
    118     HRESULT hr = QueryStdInterfaces(varSrc);
    119     if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
    120     return *this;
    121   }
    122   ~_com_ptr_t() throw() { _Release(); }
    123   void Attach(Interface *pInterface) throw() {
    124     _Release();
    125     m_pInterface = pInterface;
    126   }
    127   void Attach(Interface *pInterface,bool fAddRef) throw() {
    128     _Release();
    129     m_pInterface = pInterface;
    130     if(fAddRef) {
    131       if(!pInterface) { _com_issue_error(E_POINTER); }
    132       else pInterface->AddRef();
    133     }
    134   }
    135   Interface *Detach() throw() {
    136     Interface *const old = m_pInterface;
    137     m_pInterface = NULL;
    138     return old;
    139   }
    140   operator Interface*() const throw() { return m_pInterface; }
    141   operator Interface&() const {
    142     if(!m_pInterface) { _com_issue_error(E_POINTER); }
    143     return *m_pInterface;
    144   }
    145   Interface& operator*() const {
    146     if(!m_pInterface) { _com_issue_error(E_POINTER); }
    147     return *m_pInterface;
    148   }
    149   Interface **operator&() throw() {
    150     _Release();
    151     m_pInterface = NULL;
    152     return &m_pInterface;
    153   }
    154   Interface *operator->() const {
    155     if(!m_pInterface) { _com_issue_error(E_POINTER); }
    156     return m_pInterface;
    157   }
    158   operator bool() const throw() { return m_pInterface!=NULL; }
    159   template<typename _OtherIID> bool operator==(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)==0; }
    160   template<typename _OtherIID> bool operator==(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)==0; }
    161   template<typename _InterfaceType> bool operator==(_InterfaceType *p) { return _CompareUnknown(p)==0; }
    162   template<typename _X> bool operator==(Interface *p) { return (m_pInterface==p) ? true : _CompareUnknown(p)==0; }
    163   template<typename _X> bool operator==(const _com_ptr_t &p) throw() { return operator==(p.m_pInterface); }
    164   template<typename _X> bool operator==(_com_ptr_t &p) throw() { return operator==(p.m_pInterface); }
    165   bool operator==(int null) {
    166     if(null!=0) { _com_issue_error(E_POINTER); }
    167     return !m_pInterface;
    168   }
    169   template<typename _OtherIID> bool operator!=(const _com_ptr_t<_OtherIID> &p) { return !(operator==(p)); }
    170   template<typename _OtherIID> bool operator!=(_com_ptr_t<_OtherIID> &p) { return !(operator==(p)); }
    171   template<typename _InterfaceType> bool operator!=(_InterfaceType *p) { return !(operator==(p)); }
    172   bool operator!=(int null) { return !(operator==(null)); }
    173   template<typename _OtherIID> bool operator<(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)<0; }
    174   template<typename _OtherIID> bool operator<(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)<0; }
    175   template<typename _InterfaceType> bool operator<(_InterfaceType *p) { return _CompareUnknown(p)<0; }
    176   template<typename _OtherIID> bool operator>(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)>0; }
    177   template<typename _OtherIID> bool operator>(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)>0; }
    178   template<typename _InterfaceType> bool operator>(_InterfaceType *p) { return _CompareUnknown(p)>0; }
    179   template<typename _OtherIID> bool operator<=(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)<=0; }
    180   template<typename _OtherIID> bool operator<=(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)<=0; }
    181   template<typename _InterfaceType> bool operator<=(_InterfaceType *p) { return _CompareUnknown(p)<=0; }
    182   template<typename _OtherIID> bool operator>=(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)>=0; }
    183   template<typename _OtherIID> bool operator>=(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)>=0; }
    184   template<typename _InterfaceType> bool operator>=(_InterfaceType *p) { return _CompareUnknown(p)>=0; }
    185   void Release() {
    186     if(!m_pInterface) { _com_issue_error(E_POINTER); }
    187     else {
    188       m_pInterface->Release();
    189       m_pInterface = NULL;
    190     }
    191   }
    192   void AddRef() {
    193     if(!m_pInterface) { _com_issue_error(E_POINTER); }
    194     else m_pInterface->AddRef();
    195   }
    196   Interface *GetInterfacePtr() const throw() { return m_pInterface; }
    197   Interface*& GetInterfacePtr() throw() { return m_pInterface; }
    198   HRESULT CreateInstance(const CLSID &rclsid,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) throw() {
    199     HRESULT hr;
    200     _Release();
    201     if(dwClsContext & (CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)) {
    202       IUnknown *pIUnknown;
    203       hr = CoCreateInstance(rclsid,pOuter,dwClsContext,__uuidof(IUnknown),reinterpret_cast<void**>(&pIUnknown));
    204       if(SUCCEEDED(hr)) {
    205 	hr = OleRun(pIUnknown);
    206 	if(SUCCEEDED(hr)) hr = pIUnknown->QueryInterface(GetIID(),reinterpret_cast<void**>(&m_pInterface));
    207 	pIUnknown->Release();
    208       }
    209     } else hr = CoCreateInstance(rclsid,pOuter,dwClsContext,GetIID(),reinterpret_cast<void**>(&m_pInterface));
    210     if(FAILED(hr)) m_pInterface = NULL;
    211     return hr;
    212   }
    213   HRESULT CreateInstance(LPCWSTR clsidString,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) throw() {
    214     if(!clsidString) return E_INVALIDARG;
    215     CLSID clsid;
    216     HRESULT hr;
    217     if(clsidString[0]==L'{') hr = CLSIDFromString(const_cast<LPWSTR> (clsidString),&clsid);
    218     else hr = CLSIDFromProgID(const_cast<LPWSTR> (clsidString),&clsid);
    219     if(FAILED(hr)) return hr;
    220     return CreateInstance(clsid,pOuter,dwClsContext);
    221   }
    222   HRESULT CreateInstance(LPCSTR clsidStringA,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) throw() {
    223     if(!clsidStringA) return E_INVALIDARG;
    224     int size = lstrlenA(clsidStringA) + 1;
    225     int destSize = MultiByteToWideChar(CP_ACP,0,clsidStringA,size,NULL,0);
    226     if(destSize==0) return HRESULT_FROM_WIN32(GetLastError());
    227     LPWSTR clsidStringW;
    228     clsidStringW = static_cast<LPWSTR>(_malloca(destSize*sizeof(WCHAR)));
    229     if(!clsidStringW) return E_OUTOFMEMORY;
    230     if(MultiByteToWideChar(CP_ACP,0,clsidStringA,size,clsidStringW,destSize)==0) {
    231       _freea(clsidStringW);
    232       return HRESULT_FROM_WIN32(GetLastError());
    233     }
    234     HRESULT hr=CreateInstance(clsidStringW,pOuter,dwClsContext);
    235     _freea(clsidStringW);
    236     return hr;
    237   }
    238   HRESULT GetActiveObject(const CLSID &rclsid) throw() {
    239     _Release();
    240     IUnknown *pIUnknown;
    241     HRESULT hr = ::GetActiveObject(rclsid,NULL,&pIUnknown);
    242     if(SUCCEEDED(hr)) {
    243       hr = pIUnknown->QueryInterface(GetIID(),reinterpret_cast<void**>(&m_pInterface));
    244       pIUnknown->Release();
    245     }
    246     if(FAILED(hr)) m_pInterface = NULL;
    247     return hr;
    248   }
    249   HRESULT GetActiveObject(LPCWSTR clsidString) throw() {
    250     if(!clsidString) return E_INVALIDARG;
    251     CLSID clsid;
    252     HRESULT hr;
    253     if(clsidString[0]=='{') hr = CLSIDFromString(const_cast<LPWSTR> (clsidString),&clsid);
    254     else hr = CLSIDFromProgID(const_cast<LPWSTR> (clsidString),&clsid);
    255     if(FAILED(hr)) return hr;
    256     return GetActiveObject(clsid);
    257   }
    258   HRESULT GetActiveObject(LPCSTR clsidStringA) throw() {
    259     if(!clsidStringA) return E_INVALIDARG;
    260     int size = lstrlenA(clsidStringA) + 1;
    261     int destSize = MultiByteToWideChar(CP_ACP,0,clsidStringA,size,NULL,0);
    262     LPWSTR clsidStringW;
    263     try {
    264       clsidStringW = static_cast<LPWSTR>(_alloca(destSize*sizeof(WCHAR)));
    265     } catch (...) {
    266       clsidStringW = NULL;
    267     }
    268     if(!clsidStringW) return E_OUTOFMEMORY;
    269     if(MultiByteToWideChar(CP_ACP,0,clsidStringA,size,clsidStringW,destSize)==0) return HRESULT_FROM_WIN32(GetLastError());
    270     return GetActiveObject(clsidStringW);
    271   }
    272   template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid,_InterfaceType*& p) throw () {
    273     if(m_pInterface!=NULL) return m_pInterface->QueryInterface(iid,reinterpret_cast<void**>(&p));
    274     return E_POINTER;
    275   }
    276   template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid,_InterfaceType **p) throw() { return QueryInterface(iid,*p); }
    277 private:
    278   Interface *m_pInterface;
    279   void _Release() throw() {
    280     if(m_pInterface!=NULL) m_pInterface->Release();
    281   }
    282   void _AddRef() throw() {
    283     if(m_pInterface!=NULL) m_pInterface->AddRef();
    284   }
    285   template<typename _InterfacePtr> HRESULT _QueryInterface(_InterfacePtr p) throw() {
    286     HRESULT hr;
    287     if(p!=NULL) {
    288       Interface *pInterface;
    289       hr = p->QueryInterface(GetIID(),reinterpret_cast<void**>(&pInterface));
    290       Attach(SUCCEEDED(hr)? pInterface: NULL);
    291     } else {
    292       operator=(static_cast<Interface*>(NULL));
    293       hr = E_NOINTERFACE;
    294     }
    295     return hr;
    296   }
    297   template<typename _InterfacePtr> int _CompareUnknown(_InterfacePtr p) {
    298     IUnknown *pu1,*pu2;
    299     if(m_pInterface!=NULL) {
    300       HRESULT hr = m_pInterface->QueryInterface(__uuidof(IUnknown),reinterpret_cast<void**>(&pu1));
    301       if(FAILED(hr)) {
    302 	_com_issue_error(hr);
    303 	pu1 = NULL;
    304       } else pu1->Release();
    305     } else pu1 = NULL;
    306     if(p!=NULL) {
    307       HRESULT hr = p->QueryInterface(__uuidof(IUnknown),reinterpret_cast<void**>(&pu2));
    308       if(FAILED(hr)) {
    309 	_com_issue_error(hr);
    310 	pu2 = NULL;
    311       } else pu2->Release();
    312     } else pu2 = NULL;
    313     return pu1 - pu2;
    314   }
    315   HRESULT QueryStdInterfaces(const _variant_t& varSrc) throw() {
    316     if(V_VT(&varSrc)==VT_DISPATCH) return _QueryInterface(V_DISPATCH(&varSrc));
    317     if(V_VT(&varSrc)==VT_UNKNOWN) return _QueryInterface(V_UNKNOWN(&varSrc));
    318     VARIANT varDest;
    319     VariantInit(&varDest);
    320     HRESULT hr = VariantChangeType(&varDest,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)),0,VT_DISPATCH);
    321     if(SUCCEEDED(hr)) hr = _QueryInterface(V_DISPATCH(&varSrc));
    322     if(hr==E_NOINTERFACE) {
    323       VariantInit(&varDest);
    324       hr = VariantChangeType(&varDest,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)),0,VT_UNKNOWN);
    325       if(SUCCEEDED(hr)) hr = _QueryInterface(V_UNKNOWN(&varSrc));
    326     }
    327     VariantClear(&varDest);
    328     return hr;
    329   }
    330 };
    331 
    332 template<typename _InterfaceType> bool operator==(int null,_com_ptr_t<_InterfaceType> &p) {
    333   if(null!=0) { _com_issue_error(E_POINTER); }
    334   return !p;
    335 }
    336 
    337 template<typename _Interface,typename _InterfacePtr> bool operator==(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p==i; }
    338 
    339 template<typename _Interface> bool operator!=(int null,_com_ptr_t<_Interface> &p) {
    340   if(null!=0) { _com_issue_error(E_POINTER); }
    341   return p!=NULL;
    342 }
    343 
    344 template<typename _Interface,typename _InterfacePtr> bool operator!=(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p!=i; }
    345 
    346 template<typename _Interface> bool operator<(int null,_com_ptr_t<_Interface> &p) {
    347   if(null!=0) { _com_issue_error(E_POINTER); }
    348   return p>NULL;
    349 }
    350 
    351 template<typename _Interface,typename _InterfacePtr> bool operator<(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p>i; }
    352 
    353 template<typename _Interface> bool operator>(int null,_com_ptr_t<_Interface> &p) {
    354   if(null!=0) { _com_issue_error(E_POINTER); }
    355   return p<NULL;
    356 }
    357 
    358 template<typename _Interface,typename _InterfacePtr> bool operator>(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p<i; }
    359 
    360 template<typename _Interface> bool operator<=(int null,_com_ptr_t<_Interface> &p) {
    361   if(null!=0) { _com_issue_error(E_POINTER); }
    362   return p>=NULL;
    363 }
    364 
    365 template<typename _Interface,typename _InterfacePtr> bool operator<=(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p>=i; }
    366 
    367 template<typename _Interface> bool operator>=(int null,_com_ptr_t<_Interface> &p) {
    368   if(null!=0) { _com_issue_error(E_POINTER); }
    369   return p<=NULL;
    370 }
    371 
    372 template<typename _Interface,typename _InterfacePtr> bool operator>=(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p<=i; }
    373 
    374 #pragma pop_macro("new")
    375 
    376 #endif /* __cplusplus */
    377 
    378 #endif /* _INC_COMIP */
    379