2 * Copyright 1999, 2000 Juergen Schmied
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #ifndef __ROS_SHELL_UTILS_H
20 #define __ROS_SHELL_UTILS_H
24 #endif /* defined(__cplusplus) */
27 # define IID_PPV_ARG(Itype, ppType) IID_##Itype, reinterpret_cast<void**>((static_cast<Itype**>(ppType)))
28 # define IID_NULL_PPV_ARG(Itype, ppType) IID_##Itype, NULL, reinterpret_cast<void**>((static_cast<Itype**>(ppType)))
30 # define IID_PPV_ARG(Itype, ppType) IID_##Itype, (void**)(ppType)
31 # define IID_NULL_PPV_ARG(Itype, ppType) IID_##Itype, NULL, (void**)(ppType)
35 #define FAILED_UNEXPECTEDLY(hr) (FAILED(hr) && (Win32DbgPrint(__FILE__, __LINE__, "Unexpected failure %08x.\n", hr), TRUE))
37 #define FAILED_UNEXPECTEDLY(hr) FAILED(hr)
42 #endif /* defined(__cplusplus) */
46 class CComCreatorCentralInstance
49 static IUnknown
*s_pInstance
;
50 static bool s_IsTerminated
;
53 static HRESULT WINAPI
CreateInstance(void *pv
, REFIID riid
, LPVOID
*ppv
)
57 return CLASS_E_NOAGGREGATION
;
62 s_IsTerminated
= true;
63 hr
= ATL::CComCreator
< T
>::CreateInstance(NULL
, IID_IUnknown
, &pObj
);
66 s_IsTerminated
= false;
69 if (InterlockedCompareExchangePointer((PVOID
*)&s_pInstance
, pObj
, NULL
))
70 static_cast<IUnknown
*>(pObj
)->Release();
71 s_IsTerminated
= false;
73 return s_pInstance
->QueryInterface(riid
, ppv
);
79 ASSERT(!s_IsTerminated
);
81 s_IsTerminated
= true;
84 ref
= s_pInstance
->Release();
91 static bool IsTerminated() { return s_IsTerminated
; }
95 IUnknown
*CComCreatorCentralInstance
<T
>::s_pInstance
= NULL
;
98 bool CComCreatorCentralInstance
<T
>::s_IsTerminated
= false;
100 #define DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(x) \
102 typedef CComCreatorCentralInstance< ATL::CComObject<x> > _CreatorClass;
106 template <class Base
>
107 class CComDebugObject
: public Base
110 CComDebugObject(void * = NULL
)
112 #if DEBUG_CCOMOBJECT_CREATION
113 DbgPrint("%S, this=%08p\n", __FUNCTION__
, static_cast<Base
*>(this));
118 virtual ~CComDebugObject()
120 this->FinalRelease();
121 _pAtlModule
->Unlock();
124 STDMETHOD_(ULONG
, AddRef
)()
126 int rc
= this->InternalAddRef();
127 #if DEBUG_CCOMOBJECT_REFCOUNTING
128 DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__
, rc
);
133 STDMETHOD_(ULONG
, Release
)()
135 int rc
= this->InternalRelease();
137 #if DEBUG_CCOMOBJECT_REFCOUNTING
138 DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__
, rc
);
143 #if DEBUG_CCOMOBJECT_DESTRUCTION
144 DbgPrint("%s, RefCount reached 0 Deleting!\n", __FUNCTION__
);
151 STDMETHOD(QueryInterface
)(REFIID iid
, void **ppvObject
)
153 return this->_InternalQueryInterface(iid
, ppvObject
);
156 static HRESULT WINAPI
CreateInstance(CComDebugObject
<Base
> **pp
)
158 CComDebugObject
<Base
> *newInstance
;
161 ATLASSERT(pp
!= NULL
);
165 hResult
= E_OUTOFMEMORY
;
167 ATLTRY(newInstance
= new CComDebugObject
<Base
>());
168 if (newInstance
!= NULL
)
170 newInstance
->SetVoid(NULL
);
171 newInstance
->InternalFinalConstructAddRef();
172 hResult
= newInstance
->_AtlInitialConstruct();
173 if (SUCCEEDED(hResult
))
174 hResult
= newInstance
->FinalConstruct();
175 if (SUCCEEDED(hResult
))
176 hResult
= newInstance
->_AtlFinalConstruct();
177 newInstance
->InternalFinalConstructRelease();
189 #ifdef DEBUG_CCOMOBJECT
190 # define _CComObject CComDebugObject
192 # define _CComObject CComObject
196 void ReleaseCComPtrExpectZero(CComPtr
<T
>& cptr
, BOOL forceRelease
= FALSE
)
200 int nrc
= cptr
->Release();
203 DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc
);
208 nrc
= cptr
->Release();
216 template<class T
, class R
>
217 HRESULT
inline ShellDebugObjectCreator(REFIID riid
, R
** ppv
)
225 ATLTRY(obj
= new CComDebugObject
<T
>);
227 return E_OUTOFMEMORY
;
228 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
234 template<class T
, class R
>
235 HRESULT
inline ShellObjectCreator(REFIID riid
, R
** ppv
)
243 ATLTRY(obj
= new _CComObject
<T
>);
245 return E_OUTOFMEMORY
;
246 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
252 template<class T
, class R
>
253 HRESULT
inline ShellObjectCreatorInit(REFIID riid
, R
** ppv
)
262 ATLTRY(obj
= new _CComObject
<T
>);
264 return E_OUTOFMEMORY
;
265 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
269 hResult
= obj
->Initialize();
273 *ppv
= result
.Detach();
279 HRESULT
inline ShellObjectCreatorInit(REFIID riid
, void ** ppv
)
282 CComPtr
<IUnknown
> result
;
288 ATLTRY(obj
= new _CComObject
<T
>);
290 return E_OUTOFMEMORY
;
291 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
295 hResult
= obj
->Initialize();
299 *ppv
= result
.Detach();
304 template<class T
, class T1
>
305 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, REFIID riid
, void ** ppv
)
313 ATLTRY(obj
= new _CComObject
<T
>);
315 return E_OUTOFMEMORY
;
316 hResult
= obj
->QueryInterface(riid
, ppv
);
320 hResult
= obj
->Initialize(initArg1
);
327 template<class T
, class T1
, class T2
>
328 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, REFIID riid
, void ** ppv
)
336 ATLTRY(obj
= new _CComObject
<T
>);
338 return E_OUTOFMEMORY
;
339 hResult
= obj
->QueryInterface(riid
, ppv
);
343 hResult
= obj
->Initialize(initArg1
, initArg2
);
350 template<class T
, class T1
, class T2
, class T3
>
351 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, REFIID riid
, void ** ppv
)
359 ATLTRY(obj
= new _CComObject
<T
>);
361 return E_OUTOFMEMORY
;
362 hResult
= obj
->QueryInterface(riid
, ppv
);
366 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
);
373 template<class T
, class T1
, class R
>
374 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, REFIID riid
, R
** ppv
)
383 ATLTRY(obj
= new _CComObject
<T
>);
385 return E_OUTOFMEMORY
;
386 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
390 hResult
= obj
->Initialize(initArg1
);
394 *ppv
= result
.Detach();
399 template<class T
, class T1
, class T2
, class R
>
400 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, REFIID riid
, R
** ppv
)
409 ATLTRY(obj
= new _CComObject
<T
>);
411 return E_OUTOFMEMORY
;
412 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
416 hResult
= obj
->Initialize(initArg1
, initArg2
);
420 *ppv
= result
.Detach();
425 template<class T
, class T1
, class T2
, class T3
, class R
>
426 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, REFIID riid
, R
** ppv
)
435 ATLTRY(obj
= new _CComObject
<T
>);
437 return E_OUTOFMEMORY
;
438 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
442 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
);
446 *ppv
= result
.Detach();
451 template<class T
, class T1
, class T2
, class T3
, class T4
, class R
>
452 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, T4 initArg4
, REFIID riid
, R
** ppv
)
461 ATLTRY(obj
= new _CComObject
<T
>);
463 return E_OUTOFMEMORY
;
464 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
468 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
, initArg4
);
472 *ppv
= result
.Detach();
477 template<class T
, class T1
, class T2
, class T3
, class T4
, class T5
, class R
>
478 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, T4 initArg4
, T5 initArg5
, REFIID riid
, R
** ppv
)
487 ATLTRY(obj
= new _CComObject
<T
>);
489 return E_OUTOFMEMORY
;
490 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
494 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
, initArg4
, initArg5
);
498 *ppv
= result
.Detach();
502 #endif /* __cplusplus */
504 #endif /* __ROS_SHELL_UTILS_H */