Merge the following revisions from kernel-fun branch:
[reactos.git] / reactos / include / reactos / shellutils.h
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 <class Base>
46 class CComDebugObject : public Base
47 {
48 public:
49 CComDebugObject(void * = NULL)
50 {
51 #if DEBUG_CCOMOBJECT_CREATION
52 DbgPrint("%S, this=%08p\n", __FUNCTION__, static_cast<Base*>(this));
53 #endif
54 _pAtlModule->Lock();
55 }
56
57 virtual ~CComDebugObject()
58 {
59 this->FinalRelease();
60 _pAtlModule->Unlock();
61 }
62
63 STDMETHOD_(ULONG, AddRef)()
64 {
65 int rc = this->InternalAddRef();
66 #if DEBUG_CCOMOBJECT_REFCOUNTING
67 DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__, rc);
68 #endif
69 return rc;
70 }
71
72 STDMETHOD_(ULONG, Release)()
73 {
74 int rc = this->InternalRelease();
75
76 #if DEBUG_CCOMOBJECT_REFCOUNTING
77 DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__, rc);
78 #endif
79
80 if (rc == 0)
81 {
82 #if DEBUG_CCOMOBJECT_DESTRUCTION
83 DbgPrint("%s, RefCount reached 0 Deleting!\n", __FUNCTION__);
84 #endif
85 delete this;
86 }
87 return rc;
88 }
89
90 STDMETHOD(QueryInterface)(REFIID iid, void **ppvObject)
91 {
92 return this->_InternalQueryInterface(iid, ppvObject);
93 }
94
95 static HRESULT WINAPI CreateInstance(CComDebugObject<Base> **pp)
96 {
97 CComDebugObject<Base> *newInstance;
98 HRESULT hResult;
99
100 ATLASSERT(pp != NULL);
101 if (pp == NULL)
102 return E_POINTER;
103
104 hResult = E_OUTOFMEMORY;
105 newInstance = NULL;
106 ATLTRY(newInstance = new CComDebugObject<Base>());
107 if (newInstance != NULL)
108 {
109 newInstance->SetVoid(NULL);
110 newInstance->InternalFinalConstructAddRef();
111 hResult = newInstance->_AtlInitialConstruct();
112 if (SUCCEEDED(hResult))
113 hResult = newInstance->FinalConstruct();
114 if (SUCCEEDED(hResult))
115 hResult = newInstance->_AtlFinalConstruct();
116 newInstance->InternalFinalConstructRelease();
117 if (hResult != S_OK)
118 {
119 delete newInstance;
120 newInstance = NULL;
121 }
122 }
123 *pp = newInstance;
124 return hResult;
125 }
126 };
127
128 #ifdef DEBUG_CCOMOBJECT
129 # define _CComObject CComDebugObject
130 #else
131 # define _CComObject CComObject
132 #endif
133
134 template<class T>
135 void ReleaseCComPtrExpectZero(CComPtr<T>& cptr, BOOL forceRelease = FALSE)
136 {
137 if (cptr.p != NULL)
138 {
139 int nrc = cptr->Release();
140 if (nrc > 0)
141 {
142 DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc);
143 if (forceRelease)
144 {
145 while (nrc > 0)
146 {
147 nrc = cptr->Release();
148 }
149 }
150 }
151 cptr.Detach();
152 }
153 }
154
155 template<class T, class R>
156 HRESULT inline ShellDebugObjectCreator(REFIID riid, R ** ppv)
157 {
158 CComPtr<T> obj;
159 HRESULT hResult;
160
161 if (ppv == NULL)
162 return E_POINTER;
163 *ppv = NULL;
164 ATLTRY(obj = new CComDebugObject<T>);
165 if (obj.p == NULL)
166 return E_OUTOFMEMORY;
167 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
168 if (FAILED(hResult))
169 return hResult;
170 return S_OK;
171 }
172
173 template<class T, class R>
174 HRESULT inline ShellObjectCreator(REFIID riid, R ** ppv)
175 {
176 CComPtr<T> obj;
177 HRESULT hResult;
178
179 if (ppv == NULL)
180 return E_POINTER;
181 *ppv = NULL;
182 ATLTRY(obj = new _CComObject<T>);
183 if (obj.p == NULL)
184 return E_OUTOFMEMORY;
185 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
186 if (FAILED(hResult))
187 return hResult;
188 return S_OK;
189 }
190
191 template<class T, class R>
192 HRESULT inline ShellObjectCreatorInit(REFIID riid, R ** ppv)
193 {
194 CComPtr<T> obj;
195 CComPtr<R> result;
196 HRESULT hResult;
197
198 if (ppv == NULL)
199 return E_POINTER;
200 *ppv = NULL;
201 ATLTRY(obj = new _CComObject<T>);
202 if (obj.p == NULL)
203 return E_OUTOFMEMORY;
204 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
205 if (FAILED(hResult))
206 return hResult;
207
208 hResult = obj->Initialize();
209 if (FAILED(hResult))
210 return hResult;
211
212 *ppv = result.Detach();
213
214 return S_OK;
215 }
216
217 template<class T>
218 HRESULT inline ShellObjectCreatorInit(REFIID riid, void ** ppv)
219 {
220 CComPtr<T> obj;
221 CComPtr<IUnknown> result;
222 HRESULT hResult;
223
224 if (ppv == NULL)
225 return E_POINTER;
226 *ppv = NULL;
227 ATLTRY(obj = new _CComObject<T>);
228 if (obj.p == NULL)
229 return E_OUTOFMEMORY;
230 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
231 if (FAILED(hResult))
232 return hResult;
233
234 hResult = obj->Initialize();
235 if (FAILED(hResult))
236 return hResult;
237
238 *ppv = result.Detach();
239
240 return S_OK;
241 }
242
243 template<class T, class T1>
244 HRESULT inline ShellObjectCreatorInit(T1 initArg1, REFIID riid, void ** ppv)
245 {
246 CComPtr<T> obj;
247 HRESULT hResult;
248
249 if (ppv == NULL)
250 return E_POINTER;
251 *ppv = NULL;
252 ATLTRY(obj = new _CComObject<T>);
253 if (obj.p == NULL)
254 return E_OUTOFMEMORY;
255 hResult = obj->QueryInterface(riid, ppv);
256 if (FAILED(hResult))
257 return hResult;
258
259 hResult = obj->Initialize(initArg1);
260 if (FAILED(hResult))
261 return hResult;
262
263 return S_OK;
264 }
265
266 template<class T, class T1, class T2>
267 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, REFIID riid, void ** ppv)
268 {
269 CComPtr<T> obj;
270 HRESULT hResult;
271
272 if (ppv == NULL)
273 return E_POINTER;
274 *ppv = NULL;
275 ATLTRY(obj = new _CComObject<T>);
276 if (obj.p == NULL)
277 return E_OUTOFMEMORY;
278 hResult = obj->QueryInterface(riid, ppv);
279 if (FAILED(hResult))
280 return hResult;
281
282 hResult = obj->Initialize(initArg1, initArg2);
283 if (FAILED(hResult))
284 return hResult;
285
286 return S_OK;
287 }
288
289 template<class T, class T1, class T2, class T3>
290 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, REFIID riid, void ** ppv)
291 {
292 CComPtr<T> obj;
293 HRESULT hResult;
294
295 if (ppv == NULL)
296 return E_POINTER;
297 *ppv = NULL;
298 ATLTRY(obj = new _CComObject<T>);
299 if (obj.p == NULL)
300 return E_OUTOFMEMORY;
301 hResult = obj->QueryInterface(riid, ppv);
302 if (FAILED(hResult))
303 return hResult;
304
305 hResult = obj->Initialize(initArg1, initArg2, initArg3);
306 if (FAILED(hResult))
307 return hResult;
308
309 return S_OK;
310 }
311
312 template<class T, class T1, class R>
313 HRESULT inline ShellObjectCreatorInit(T1 initArg1, REFIID riid, R ** ppv)
314 {
315 CComPtr<T> obj;
316 CComPtr<R> result;
317 HRESULT hResult;
318
319 if (ppv == NULL)
320 return E_POINTER;
321 *ppv = NULL;
322 ATLTRY(obj = new _CComObject<T>);
323 if (obj.p == NULL)
324 return E_OUTOFMEMORY;
325 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
326 if (FAILED(hResult))
327 return hResult;
328
329 hResult = obj->Initialize(initArg1);
330 if (FAILED(hResult))
331 return hResult;
332
333 *ppv = result.Detach();
334
335 return S_OK;
336 }
337
338 template<class T, class T1, class T2, class R>
339 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, REFIID riid, R ** ppv)
340 {
341 CComPtr<T> obj;
342 CComPtr<R> result;
343 HRESULT hResult;
344
345 if (ppv == NULL)
346 return E_POINTER;
347 *ppv = NULL;
348 ATLTRY(obj = new _CComObject<T>);
349 if (obj.p == NULL)
350 return E_OUTOFMEMORY;
351 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
352 if (FAILED(hResult))
353 return hResult;
354
355 hResult = obj->Initialize(initArg1, initArg2);
356 if (FAILED(hResult))
357 return hResult;
358
359 *ppv = result.Detach();
360
361 return S_OK;
362 }
363
364 template<class T, class T1, class T2, class T3, class R>
365 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, REFIID riid, R ** ppv)
366 {
367 CComPtr<T> obj;
368 CComPtr<R> result;
369 HRESULT hResult;
370
371 if (ppv == NULL)
372 return E_POINTER;
373 *ppv = NULL;
374 ATLTRY(obj = new _CComObject<T>);
375 if (obj.p == NULL)
376 return E_OUTOFMEMORY;
377 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
378 if (FAILED(hResult))
379 return hResult;
380
381 hResult = obj->Initialize(initArg1, initArg2, initArg3);
382 if (FAILED(hResult))
383 return hResult;
384
385 *ppv = result.Detach();
386
387 return S_OK;
388 }
389
390 template<class T, class T1, class T2, class T3, class T4, class R>
391 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, REFIID riid, R ** ppv)
392 {
393 CComPtr<T> obj;
394 CComPtr<R> result;
395 HRESULT hResult;
396
397 if (ppv == NULL)
398 return E_POINTER;
399 *ppv = NULL;
400 ATLTRY(obj = new _CComObject<T>);
401 if (obj.p == NULL)
402 return E_OUTOFMEMORY;
403 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
404 if (FAILED(hResult))
405 return hResult;
406
407 hResult = obj->Initialize(initArg1, initArg2, initArg3, initArg4);
408 if (FAILED(hResult))
409 return hResult;
410
411 *ppv = result.Detach();
412
413 return S_OK;
414 }
415
416 template<class T, class T1, class T2, class T3, class T4, class T5, class R>
417 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, T5 initArg5, REFIID riid, R ** ppv)
418 {
419 CComPtr<T> obj;
420 CComPtr<R> result;
421 HRESULT hResult;
422
423 if (ppv == NULL)
424 return E_POINTER;
425 *ppv = NULL;
426 ATLTRY(obj = new _CComObject<T>);
427 if (obj.p == NULL)
428 return E_OUTOFMEMORY;
429 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
430 if (FAILED(hResult))
431 return hResult;
432
433 hResult = obj->Initialize(initArg1, initArg2, initArg3, initArg4, initArg5);
434 if (FAILED(hResult))
435 return hResult;
436
437 *ppv = result.Detach();
438
439 return S_OK;
440 }
441 #endif /* __cplusplus */
442
443 #endif /* __ROS_SHELL_UTILS_H */