Partial merge of condrv_restructure branch r65657.
[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) && (DbgPrint("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 R>
267 HRESULT inline ShellObjectCreatorInit(T1 initArg1, REFIID riid, R ** ppv)
268 {
269 CComPtr<T> obj;
270 CComPtr<R> result;
271 HRESULT hResult;
272
273 if (ppv == NULL)
274 return E_POINTER;
275 *ppv = NULL;
276 ATLTRY(obj = new _CComObject<T>);
277 if (obj.p == NULL)
278 return E_OUTOFMEMORY;
279 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
280 if (FAILED(hResult))
281 return hResult;
282
283 hResult = obj->Initialize(initArg1);
284 if (FAILED(hResult))
285 return hResult;
286
287 *ppv = result.Detach();
288
289 return S_OK;
290 }
291
292 template<class T, class T1, class T2, class R>
293 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, REFIID riid, R ** ppv)
294 {
295 CComPtr<T> obj;
296 CComPtr<R> result;
297 HRESULT hResult;
298
299 if (ppv == NULL)
300 return E_POINTER;
301 *ppv = NULL;
302 ATLTRY(obj = new _CComObject<T>);
303 if (obj.p == NULL)
304 return E_OUTOFMEMORY;
305 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
306 if (FAILED(hResult))
307 return hResult;
308
309 hResult = obj->Initialize(initArg1, initArg2);
310 if (FAILED(hResult))
311 return hResult;
312
313 *ppv = result.Detach();
314
315 return S_OK;
316 }
317
318 template<class T, class T1, class T2, class T3, class R>
319 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, REFIID riid, R ** ppv)
320 {
321 CComPtr<T> obj;
322 CComPtr<R> result;
323 HRESULT hResult;
324
325 if (ppv == NULL)
326 return E_POINTER;
327 *ppv = NULL;
328 ATLTRY(obj = new _CComObject<T>);
329 if (obj.p == NULL)
330 return E_OUTOFMEMORY;
331 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
332 if (FAILED(hResult))
333 return hResult;
334
335 hResult = obj->Initialize(initArg1, initArg2, initArg3);
336 if (FAILED(hResult))
337 return hResult;
338
339 *ppv = result.Detach();
340
341 return S_OK;
342 }
343
344 template<class T, class T1, class T2, class T3, class T4, class R>
345 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, REFIID riid, R ** ppv)
346 {
347 CComPtr<T> obj;
348 CComPtr<R> result;
349 HRESULT hResult;
350
351 if (ppv == NULL)
352 return E_POINTER;
353 *ppv = NULL;
354 ATLTRY(obj = new _CComObject<T>);
355 if (obj.p == NULL)
356 return E_OUTOFMEMORY;
357 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
358 if (FAILED(hResult))
359 return hResult;
360
361 hResult = obj->Initialize(initArg1, initArg2, initArg3, initArg4);
362 if (FAILED(hResult))
363 return hResult;
364
365 *ppv = result.Detach();
366
367 return S_OK;
368 }
369
370 template<class T, class T1, class T2, class T3, class T4, class T5, class R>
371 HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, T5 initArg5, REFIID riid, R ** ppv)
372 {
373 CComPtr<T> obj;
374 CComPtr<R> result;
375 HRESULT hResult;
376
377 if (ppv == NULL)
378 return E_POINTER;
379 *ppv = NULL;
380 ATLTRY(obj = new _CComObject<T>);
381 if (obj.p == NULL)
382 return E_OUTOFMEMORY;
383 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
384 if (FAILED(hResult))
385 return hResult;
386
387 hResult = obj->Initialize(initArg1, initArg2, initArg3, initArg4, initArg5);
388 if (FAILED(hResult))
389 return hResult;
390
391 *ppv = result.Detach();
392
393 return S_OK;
394 }
395 #endif /* __cplusplus */
396
397 #endif /* __ROS_SHELL_UTILS_H */