ReactOS  0.4.13-dev-257-gfabbd7c
shellutils.h
Go to the documentation of this file.
1 /*
2  * Copyright 1999, 2000 Juergen Schmied
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #ifndef __ROS_SHELL_UTILS_H
20 #define __ROS_SHELL_UTILS_H
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif /* defined(__cplusplus) */
25 
26 #ifdef __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)))
29 #else
30 # define IID_PPV_ARG(Itype, ppType) IID_##Itype, (void**)(ppType)
31 # define IID_NULL_PPV_ARG(Itype, ppType) IID_##Itype, NULL, (void**)(ppType)
32 #endif
33 
34 #if 1
35 #define FAILED_UNEXPECTEDLY(hr) (FAILED(hr) && (Win32DbgPrint(__FILE__, __LINE__, "Unexpected failure %08x.\n", hr), TRUE))
36 #else
37 #define FAILED_UNEXPECTEDLY(hr) FAILED(hr)
38 #endif
39 
40 #ifdef __cplusplus
41 } /* extern "C" */
42 #endif /* defined(__cplusplus) */
43 
44 #ifdef __cplusplus
45 template <typename T>
46 class CComCreatorCentralInstance
47 {
48 private:
49  static IUnknown *s_pInstance;
50 
51 public:
52  static HRESULT WINAPI CreateInstance(void *pv, REFIID riid, LPVOID *ppv)
53  {
54  *ppv = NULL;
55  if (pv != NULL)
56  return CLASS_E_NOAGGREGATION;
57  if (!s_pInstance)
58  {
59  PVOID pObj;
60  HRESULT hr;
62  if (FAILED(hr))
63  return hr;
64  if (InterlockedCompareExchangePointer((PVOID *)&s_pInstance, pObj, NULL))
65  static_cast<IUnknown *>(pObj)->Release();
66  }
67  return s_pInstance->QueryInterface(riid, ppv);
68  }
69  static void Term()
70  {
71  if (s_pInstance)
72  {
73  s_pInstance->Release();
74  s_pInstance = NULL;
75  }
76  }
77 };
78 
79 template <typename T>
80 IUnknown *CComCreatorCentralInstance<T>::s_pInstance = NULL;
81 
82 #define DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(x) \
83 public: \
84  typedef CComCreatorCentralInstance< ATL::CComObject<x> > _CreatorClass;
85 #endif
86 
87 #ifdef __cplusplus
88 template <class Base>
89 class CComDebugObject : public Base
90 {
91 public:
92  CComDebugObject(void * = NULL)
93  {
94 #if DEBUG_CCOMOBJECT_CREATION
95  DbgPrint("%S, this=%08p\n", __FUNCTION__, static_cast<Base*>(this));
96 #endif
97  _pAtlModule->Lock();
98  }
99 
100  virtual ~CComDebugObject()
101  {
102  this->FinalRelease();
103  _pAtlModule->Unlock();
104  }
105 
107  {
108  int rc = this->InternalAddRef();
109 #if DEBUG_CCOMOBJECT_REFCOUNTING
110  DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__, rc);
111 #endif
112  return rc;
113  }
114 
116  {
117  int rc = this->InternalRelease();
118 
119 #if DEBUG_CCOMOBJECT_REFCOUNTING
120  DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__, rc);
121 #endif
122 
123  if (rc == 0)
124  {
125 #if DEBUG_CCOMOBJECT_DESTRUCTION
126  DbgPrint("%s, RefCount reached 0 Deleting!\n", __FUNCTION__);
127 #endif
128  delete this;
129  }
130  return rc;
131  }
132 
134  {
135  return this->_InternalQueryInterface(iid, ppvObject);
136  }
137 
138  static HRESULT WINAPI CreateInstance(CComDebugObject<Base> **pp)
139  {
140  CComDebugObject<Base> *newInstance;
141  HRESULT hResult;
142 
143  ATLASSERT(pp != NULL);
144  if (pp == NULL)
145  return E_POINTER;
146 
147  hResult = E_OUTOFMEMORY;
148  newInstance = NULL;
149  ATLTRY(newInstance = new CComDebugObject<Base>());
150  if (newInstance != NULL)
151  {
152  newInstance->SetVoid(NULL);
153  newInstance->InternalFinalConstructAddRef();
154  hResult = newInstance->_AtlInitialConstruct();
155  if (SUCCEEDED(hResult))
156  hResult = newInstance->FinalConstruct();
157  if (SUCCEEDED(hResult))
158  hResult = newInstance->_AtlFinalConstruct();
159  newInstance->InternalFinalConstructRelease();
160  if (hResult != S_OK)
161  {
162  delete newInstance;
163  newInstance = NULL;
164  }
165  }
166  *pp = newInstance;
167  return hResult;
168  }
169 };
170 
171 #ifdef DEBUG_CCOMOBJECT
172 # define _CComObject CComDebugObject
173 #else
174 # define _CComObject CComObject
175 #endif
176 
177 template<class T>
178 void ReleaseCComPtrExpectZero(CComPtr<T>& cptr, BOOL forceRelease = FALSE)
179 {
180  if (cptr.p != NULL)
181  {
182  int nrc = cptr->Release();
183  if (nrc > 0)
184  {
185  DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc);
186  if (forceRelease)
187  {
188  while (nrc > 0)
189  {
190  nrc = cptr->Release();
191  }
192  }
193  }
194  cptr.Detach();
195  }
196 }
197 
198 template<class T, class R>
199 HRESULT inline ShellDebugObjectCreator(REFIID riid, R ** ppv)
200 {
201  CComPtr<T> obj;
202  HRESULT hResult;
203 
204  if (ppv == NULL)
205  return E_POINTER;
206  *ppv = NULL;
207  ATLTRY(obj = new CComDebugObject<T>);
208  if (obj.p == NULL)
209  return E_OUTOFMEMORY;
210  hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
211  if (FAILED(hResult))
212  return hResult;
213  return S_OK;
214 }
215 
216 template<class T>
217 HRESULT inline ShellObjectCreator(REFIID riid, void ** ppv)
218 {
219  _CComObject<T> *pobj;
220  HRESULT hResult;
221 
222  hResult = _CComObject<T>::CreateInstance(&pobj);
223  if (FAILED(hResult))
224  return hResult;
225 
226  pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
227 
228  hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
229 
230  pobj->Release(); /* In case of failure the object will be released */
231 
232  return hResult;
233 }
234 
235 template<class T>
236 HRESULT inline ShellObjectCreatorInit(REFIID riid, void ** ppv)
237 {
238  _CComObject<T> *pobj;
239  HRESULT hResult;
240 
241  hResult = _CComObject<T>::CreateInstance(&pobj);
242  if (FAILED(hResult))
243  return hResult;
244 
245  pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
246 
247  hResult = pobj->Initialize();
248 
249  if (SUCCEEDED(hResult))
250  hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
251 
252  pobj->Release(); /* In case of failure the object will be released */
253 
254  return hResult;
255 }
256 
257 template<class T, class T1>
258 HRESULT inline ShellObjectCreatorInit(T1 initArg1, REFIID riid, void ** ppv)
259 {
260  _CComObject<T> *pobj;
261  HRESULT hResult;
262 
263  hResult = _CComObject<T>::CreateInstance(&pobj);
264  if (FAILED(hResult))
265  return hResult;
266 
267  pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
268 
269  hResult = pobj->Initialize(initArg1);
270 
271  if (SUCCEEDED(hResult))
272  hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
273 
274  pobj->Release(); /* In case of failure the object will be released */
275 
276  return hResult;
277 }
278 
279 template<class T, class T1, class T2>
280 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, REFIID riid, void ** ppv)
281 {
282  _CComObject<T> *pobj;
283  HRESULT hResult;
284 
285  hResult = _CComObject<T>::CreateInstance(&pobj);
286  if (FAILED(hResult))
287  return hResult;
288 
289  pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
290 
291  hResult = pobj->Initialize(initArg1, initArg2);
292 
293  if (SUCCEEDED(hResult))
294  hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
295 
296  pobj->Release(); /* In case of failure the object will be released */
297 
298  return hResult;
299 }
300 
301 template<class T, class T1, class T2, class T3>
302 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, REFIID riid, void ** ppv)
303 {
304  _CComObject<T> *pobj;
305  HRESULT hResult;
306 
307  hResult = _CComObject<T>::CreateInstance(&pobj);
308  if (FAILED(hResult))
309  return hResult;
310 
311  pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
312 
313  hResult = pobj->Initialize(initArg1, initArg2, initArg3);
314 
315  if (SUCCEEDED(hResult))
316  hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
317 
318  pobj->Release(); /* In case of failure the object will be released */
319 
320  return hResult;
321 }
322 
323 template<class T, class T1, class T2, class T3, class T4>
324 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, REFIID riid, void ** ppv)
325 {
326  _CComObject<T> *pobj;
327  HRESULT hResult;
328 
329  hResult = _CComObject<T>::CreateInstance(&pobj);
330  if (FAILED(hResult))
331  return hResult;
332 
333  pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
334 
335  hResult = pobj->Initialize(initArg1, initArg2, initArg3, initArg4);
336 
337  if (SUCCEEDED(hResult))
338  hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
339 
340  pobj->Release(); /* In case of failure the object will be released */
341 
342  return hResult;
343 }
344 
345 HRESULT inline SHSetStrRet(LPSTRRET pStrRet, LPCSTR pstrValue)
346 {
347  pStrRet->uType = STRRET_CSTR;
348  strcpy(pStrRet->cStr, pstrValue);
349  return S_OK;
350 }
351 
352 HRESULT inline SHSetStrRet(LPSTRRET pStrRet, LPCWSTR pwstrValue)
353 {
354  ULONG cchr = wcslen(pwstrValue);
355  LPWSTR buffer = static_cast<LPWSTR>(CoTaskMemAlloc((cchr + 1) * sizeof(WCHAR)));
356  if (buffer == NULL)
357  return E_OUTOFMEMORY;
358 
359  pStrRet->uType = STRRET_WSTR;
360  pStrRet->pOleStr = buffer;
361  wcscpy(buffer, pwstrValue);
362  return S_OK;
363 }
364 
365 HRESULT inline SHSetStrRet(LPSTRRET pStrRet, HINSTANCE hInstance, DWORD resId)
366 {
368 
369  if (!LoadStringW(hInstance, resId, Buffer, MAX_PATH))
370  return E_FAIL;
371 
372  return SHSetStrRet(pStrRet, Buffer);
373 }
374 
375 #endif /* __cplusplus */
376 
377 #define S_LESSTHAN 0xffff
378 #define S_EQUAL S_OK
379 #define S_GREATERTHAN S_FALSE
380 #define MAKE_COMPARE_HRESULT(x) ((x)>0 ? S_GREATERTHAN : ((x)<0 ? S_LESSTHAN : S_EQUAL))
381 
382 #endif /* __ROS_SHELL_UTILS_H */
#define ATLTRY(x)
Definition: atlcomcli.h:44
#define R(b, x)
Definition: sha2.c:134
#define REFIID
Definition: guiddef.h:113
HRESULT hr
Definition: shlfolder.c:183
_In_ BOOLEAN Release
Definition: classpnp.h:929
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static HRESULT WINAPI CreateInstance(void *pv, REFIID riid, LPVOID *ppv)
Definition: atlcom.h:418
#define DbgPrint
Definition: loader.c:25
#define ATLASSERT(x)
Definition: CComVariant.cpp:9
REFIID riid
Definition: precomp.h:44
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
REFIID LPVOID * ppv
Definition: atlbase.h:39
LPWSTR pOleStr
Definition: shtypes.idl:96
GLuint buffer
Definition: glext.h:5915
NTSTATUS QueryInterface(IN PDEVICE_OBJECT DeviceObject, IN CONST GUID InterfaceType, IN LONG Size, IN LONG Version, OUT PVOID Interface)
Definition: fdo.c:532
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define STDMETHOD(m)
Definition: basetyps.h:62
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
char cStr[MAX_PATH]
Definition: shtypes.idl:98
HINSTANCE hInstance
Definition: charmap.c:20
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define pp
Definition: hlsl.yy.c:978
ULONG Release()
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
REFIID LPVOID * ppvObject
Definition: precomp.h:44
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define S_OK
Definition: intsafe.h:59
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
WCHAR * LPWSTR
Definition: xmlstorage.h:184
UINT uType
Definition: shtypes.idl:93
#define STDMETHOD_(t, m)
Definition: basetyps.h:63
#define E_POINTER
Definition: winerror.h:2365
#define __FUNCTION__
Definition: types.h:112
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define SUCCEEDED(hr)
Definition: intsafe.h:57