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