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.
18 #pragma push_macro("new")
26 #define WINAPI __stdcall
29 void WINAPI
_com_issue_error(HRESULT
);
32 template<typename _Interface
,const IID
*_IID
>
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
; }
41 template<typename _IIID
> class _com_ptr_t
{
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
); }
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
); }
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
); }
59 m_pInterface
= p
->m_pInterface
;
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
); }
68 #ifdef _NATIVE_NULLPTR_SUPPORTED
69 _com_ptr_t(decltype(nullptr)) : m_pInterface(NULL
) {}
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();
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
); }
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
); }
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
); }
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
); }
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
); }
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
); }
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
;
108 if(pOldInterface
!=NULL
) pOldInterface
->Release();
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
));
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
); }
122 ~_com_ptr_t() throw() { _Release(); }
123 void Attach(Interface
*pInterface
) throw() {
125 m_pInterface
= pInterface
;
127 void Attach(Interface
*pInterface
,bool fAddRef
) throw() {
129 m_pInterface
= pInterface
;
131 if(!pInterface
) { _com_issue_error(E_POINTER
); }
132 else pInterface
->AddRef();
135 Interface
*Detach() throw() {
136 Interface
*const old
= m_pInterface
;
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
;
145 Interface
& operator*() const {
146 if(!m_pInterface
) { _com_issue_error(E_POINTER
); }
147 return *m_pInterface
;
149 Interface
**operator&() throw() {
152 return &m_pInterface
;
154 Interface
*operator->() const {
155 if(!m_pInterface
) { _com_issue_error(E_POINTER
); }
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
;
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; }
186 if(!m_pInterface
) { _com_issue_error(E_POINTER
); }
188 m_pInterface
->Release();
193 if(!m_pInterface
) { _com_issue_error(E_POINTER
); }
194 else m_pInterface
->AddRef();
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() {
201 if(dwClsContext
& (CLSCTX_LOCAL_SERVER
| CLSCTX_REMOTE_SERVER
)) {
203 hr
= CoCreateInstance(rclsid
,pOuter
,dwClsContext
,IID_IUnknown
,reinterpret_cast<void**>(&pIUnknown
));
205 hr
= OleRun(pIUnknown
);
206 if(SUCCEEDED(hr
)) hr
= pIUnknown
->QueryInterface(GetIID(),reinterpret_cast<void**>(&m_pInterface
));
207 pIUnknown
->Release();
209 } else hr
= CoCreateInstance(rclsid
,pOuter
,dwClsContext
,GetIID(),reinterpret_cast<void**>(&m_pInterface
));
210 if(FAILED(hr
)) m_pInterface
= NULL
;
213 HRESULT
CreateInstance(LPCWSTR clsidString
,IUnknown
*pOuter
= NULL
,DWORD dwClsContext
= CLSCTX_ALL
) throw() {
214 if(!clsidString
) return E_INVALIDARG
;
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
);
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());
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());
234 HRESULT hr
=CreateInstance(clsidStringW
,pOuter
,dwClsContext
);
235 _freea(clsidStringW
);
238 HRESULT
GetActiveObject(const CLSID
&rclsid
) throw() {
241 HRESULT hr
= ::GetActiveObject(rclsid
,NULL
,&pIUnknown
);
243 hr
= pIUnknown
->QueryInterface(GetIID(),reinterpret_cast<void**>(&m_pInterface
));
244 pIUnknown
->Release();
246 if(FAILED(hr
)) m_pInterface
= NULL
;
249 HRESULT
GetActiveObject(LPCWSTR clsidString
) throw() {
250 if(!clsidString
) return E_INVALIDARG
;
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
);
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);
264 clsidStringW
= static_cast<LPWSTR
>(_alloca(destSize
*sizeof(WCHAR
)));
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
);
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
));
276 template<typename _InterfaceType
> HRESULT
QueryInterface(const IID
& iid
,_InterfaceType
**p
) throw() { return QueryInterface(iid
,*p
); }
278 Interface
*m_pInterface
;
279 void _Release() throw() {
280 if(m_pInterface
!=NULL
) m_pInterface
->Release();
282 void _AddRef() throw() {
283 if(m_pInterface
!=NULL
) m_pInterface
->AddRef();
285 template<typename _InterfacePtr
> HRESULT
_QueryInterface(_InterfacePtr p
) throw() {
288 Interface
*pInterface
;
289 hr
= p
->QueryInterface(GetIID(),reinterpret_cast<void**>(&pInterface
));
290 Attach(SUCCEEDED(hr
)? pInterface
: NULL
);
292 operator=(static_cast<Interface
*>(NULL
));
297 template<typename _InterfacePtr
> int _CompareUnknown(_InterfacePtr p
) {
299 if(m_pInterface
!=NULL
) {
300 HRESULT hr
= m_pInterface
->QueryInterface(IID_IUnknown
,reinterpret_cast<void**>(&pu1
));
302 _com_issue_error(hr
);
304 } else pu1
->Release();
307 HRESULT hr
= p
->QueryInterface(IID_IUnknown
,reinterpret_cast<void**>(&pu2
));
309 _com_issue_error(hr
);
311 } else pu2
->Release();
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
));
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
));
327 VariantClear(&varDest
);
332 template<typename _InterfaceType
> bool operator==(int null
,_com_ptr_t
<_InterfaceType
> &p
) {
333 if(null
!=0) { _com_issue_error(E_POINTER
); }
337 template<typename _Interface
,typename _InterfacePtr
> bool operator==(_Interface
*i
,_com_ptr_t
<_InterfacePtr
> &p
) { return p
==i
; }
339 template<typename _Interface
> bool operator!=(int null
,_com_ptr_t
<_Interface
> &p
) {
340 if(null
!=0) { _com_issue_error(E_POINTER
); }
344 template<typename _Interface
,typename _InterfacePtr
> bool operator!=(_Interface
*i
,_com_ptr_t
<_InterfacePtr
> &p
) { return p
!=i
; }
346 template<typename _Interface
> bool operator<(int null
,_com_ptr_t
<_Interface
> &p
) {
347 if(null
!=0) { _com_issue_error(E_POINTER
); }
351 template<typename _Interface
,typename _InterfacePtr
> bool operator<(_Interface
*i
,_com_ptr_t
<_InterfacePtr
> &p
) { return p
>i
; }
353 template<typename _Interface
> bool operator>(int null
,_com_ptr_t
<_Interface
> &p
) {
354 if(null
!=0) { _com_issue_error(E_POINTER
); }
358 template<typename _Interface
,typename _InterfacePtr
> bool operator>(_Interface
*i
,_com_ptr_t
<_InterfacePtr
> &p
) { return p
<i
; }
360 template<typename _Interface
> bool operator<=(int null
,_com_ptr_t
<_Interface
> &p
) {
361 if(null
!=0) { _com_issue_error(E_POINTER
); }
365 template<typename _Interface
,typename _InterfacePtr
> bool operator<=(_Interface
*i
,_com_ptr_t
<_InterfacePtr
> &p
) { return p
>=i
; }
367 template<typename _Interface
> bool operator>=(int null
,_com_ptr_t
<_Interface
> &p
) {
368 if(null
!=0) { _com_issue_error(E_POINTER
); }
372 template<typename _Interface
,typename _InterfacePtr
> bool operator>=(_Interface
*i
,_com_ptr_t
<_InterfacePtr
> &p
) { return p
<=i
; }
374 #pragma pop_macro("new")
376 #endif /* __cplusplus */
378 #endif /* _INC_COMIP */