ReactOS  0.4.14-dev-583-g2a1ba2c
errorinfo.c
Go to the documentation of this file.
1 /*
2  * ErrorInfo API
3  *
4  * Copyright 2000 Patrik Stridvall, Juergen Schmied
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * NOTES:
21  *
22  * The errorinfo is a per-thread object. The reference is stored in the
23  * TEB at offset 0xf80.
24  */
25 
26 #include <stdarg.h>
27 #include <string.h>
28 
29 #define COBJMACROS
30 
31 #include "windef.h"
32 #include "winbase.h"
33 #include "objbase.h"
34 #include "oleauto.h"
35 #include "winerror.h"
36 
37 #include "compobj_private.h"
38 
39 #include "wine/debug.h"
40 
42 
43 static inline WCHAR *heap_strdupW(const WCHAR *str)
44 {
45  WCHAR *ret = NULL;
46 
47  if(str) {
48  size_t size;
49 
50  size = (lstrlenW(str)+1)*sizeof(WCHAR);
51  ret = heap_alloc(size);
52  if(ret)
53  memcpy(ret, str, size);
54  }
55 
56  return ret;
57 }
58 
59 typedef struct ErrorInfoImpl
60 {
65 
72 
74 {
75  return CONTAINING_RECORD(iface, ErrorInfoImpl, IErrorInfo_iface);
76 }
77 
79 {
80  return CONTAINING_RECORD(iface, ErrorInfoImpl, ICreateErrorInfo_iface);
81 }
82 
84 {
85  return CONTAINING_RECORD(iface, ErrorInfoImpl, ISupportErrorInfo_iface);
86 }
87 
89  IErrorInfo* iface,
90  REFIID riid,
91  void** ppvoid)
92 {
94  TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid),ppvoid);
95 
96  *ppvoid = NULL;
97 
98  if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IErrorInfo))
99  {
100  *ppvoid = &This->IErrorInfo_iface;
101  }
102  else if(IsEqualIID(riid, &IID_ICreateErrorInfo))
103  {
104  *ppvoid = &This->ICreateErrorInfo_iface;
105  }
106  else if(IsEqualIID(riid, &IID_ISupportErrorInfo))
107  {
108  *ppvoid = &This->ISupportErrorInfo_iface;
109  }
110 
111  if(*ppvoid)
112  {
113  IUnknown_AddRef( (IUnknown*)*ppvoid );
114  TRACE("-- Interface: (%p)->(%p)\n",ppvoid,*ppvoid);
115  return S_OK;
116  }
117  TRACE("-- Interface: E_NOINTERFACE\n");
118  return E_NOINTERFACE;
119 }
120 
122  IErrorInfo* iface)
123 {
125  TRACE("(%p)->(count=%u)\n",This,This->ref);
126  return InterlockedIncrement(&This->ref);
127 }
128 
130  IErrorInfo* iface)
131 {
134 
135  TRACE("(%p)->(count=%u)\n",This,ref+1);
136 
137  if (!ref)
138  {
139  TRACE("-- destroying IErrorInfo(%p)\n",This);
140 
141  heap_free(This->source);
142  heap_free(This->description);
143  heap_free(This->help_file);
144  heap_free(This);
145  }
146  return ref;
147 }
148 
150  IErrorInfo* iface,
151  GUID * pGUID)
152 {
154  TRACE("(%p)->(count=%u)\n",This,This->ref);
155  if(!pGUID )return E_INVALIDARG;
156  *pGUID = This->m_Guid;
157  return S_OK;
158 }
159 
161  IErrorInfo* iface,
162  BSTR *pBstrSource)
163 {
165  TRACE("(%p)->(pBstrSource=%p)\n",This,pBstrSource);
166  if (pBstrSource == NULL)
167  return E_INVALIDARG;
168  *pBstrSource = SysAllocString(This->source);
169  return S_OK;
170 }
171 
173  IErrorInfo* iface,
174  BSTR *pBstrDescription)
175 {
177 
178  TRACE("(%p)->(pBstrDescription=%p)\n",This,pBstrDescription);
179  if (pBstrDescription == NULL)
180  return E_INVALIDARG;
181  *pBstrDescription = SysAllocString(This->description);
182 
183  return S_OK;
184 }
185 
187  IErrorInfo* iface,
188  BSTR *pBstrHelpFile)
189 {
191 
192  TRACE("(%p)->(pBstrHelpFile=%p)\n",This, pBstrHelpFile);
193  if (pBstrHelpFile == NULL)
194  return E_INVALIDARG;
195  *pBstrHelpFile = SysAllocString(This->help_file);
196 
197  return S_OK;
198 }
199 
201  IErrorInfo* iface,
202  DWORD *pdwHelpContext)
203 {
205  TRACE("(%p)->(pdwHelpContext=%p)\n",This, pdwHelpContext);
206  if (pdwHelpContext == NULL)
207  return E_INVALIDARG;
208  *pdwHelpContext = This->m_dwHelpContext;
209 
210  return S_OK;
211 }
212 
213 static const IErrorInfoVtbl ErrorInfoVtbl =
214 {
223 };
224 
225 
227  ICreateErrorInfo* iface,
228  REFIID riid,
229  VOID** ppvoid)
230 {
232  return IErrorInfo_QueryInterface(&This->IErrorInfo_iface, riid, ppvoid);
233 }
234 
236  ICreateErrorInfo* iface)
237 {
239  return IErrorInfo_AddRef(&This->IErrorInfo_iface);
240 }
241 
243  ICreateErrorInfo* iface)
244 {
246  return IErrorInfo_Release(&This->IErrorInfo_iface);
247 }
248 
249 
251  ICreateErrorInfo* iface,
252  REFGUID rguid)
253 {
255  TRACE("(%p)->(%s)\n", This, debugstr_guid(rguid));
256  This->m_Guid = *rguid;
257  return S_OK;
258 }
259 
261  ICreateErrorInfo* iface,
263 {
265  TRACE("(%p): %s\n",This, debugstr_w(szSource));
266 
267  heap_free(This->source);
268  This->source = heap_strdupW(szSource);
269 
270  return S_OK;
271 }
272 
274  ICreateErrorInfo* iface,
276 {
278  TRACE("(%p): %s\n",This, debugstr_w(szDescription));
279 
280  heap_free(This->description);
281  This->description = heap_strdupW(szDescription);
282  return S_OK;
283 }
284 
286  ICreateErrorInfo* iface,
288 {
290  TRACE("(%p,%s)\n",This,debugstr_w(szHelpFile));
291  heap_free(This->help_file);
292  This->help_file = heap_strdupW(szHelpFile);
293  return S_OK;
294 }
295 
297  ICreateErrorInfo* iface,
298  DWORD dwHelpContext)
299 {
301  TRACE("(%p,%d)\n",This,dwHelpContext);
302  This->m_dwHelpContext = dwHelpContext;
303  return S_OK;
304 }
305 
306 static const ICreateErrorInfoVtbl CreateErrorInfoVtbl =
307 {
316 };
317 
319  ISupportErrorInfo* iface,
320  REFIID riid,
321  VOID** ppvoid)
322 {
324  return IErrorInfo_QueryInterface(&This->IErrorInfo_iface, riid, ppvoid);
325 }
326 
328 {
330  return IErrorInfo_AddRef(&This->IErrorInfo_iface);
331 }
332 
334 {
336  return IErrorInfo_Release(&This->IErrorInfo_iface);
337 }
338 
340  ISupportErrorInfo* iface,
341  REFIID riid)
342 {
344  TRACE("(%p)->(%s)\n", This, debugstr_guid(riid));
345  return (IsEqualIID(riid, &This->m_Guid)) ? S_OK : S_FALSE;
346 }
347 
348 static const ISupportErrorInfoVtbl SupportErrorInfoVtbl =
349 {
354 };
355 
357 {
359 
360  if (!This) return NULL;
361 
362  This->IErrorInfo_iface.lpVtbl = &ErrorInfoVtbl;
363  This->ICreateErrorInfo_iface.lpVtbl = &CreateErrorInfoVtbl;
364  This->ISupportErrorInfo_iface.lpVtbl = &SupportErrorInfoVtbl;
365  This->ref = 1;
366  This->source = NULL;
367  This->description = NULL;
368  This->help_file = NULL;
369  This->m_dwHelpContext = 0;
370 
371  return &This->IErrorInfo_iface;
372 }
373 
374 /***********************************************************************
375  * CreateErrorInfo (OLE32.@)
376  *
377  * Creates an object used to set details for an error info object.
378  *
379  * PARAMS
380  * pperrinfo [O]. Address where error info creation object will be stored.
381  *
382  * RETURNS
383  * Success: S_OK.
384  * Failure: HRESULT code.
385  */
387 {
388  IErrorInfo * pei;
389  HRESULT res;
390  TRACE("(%p)\n", pperrinfo);
391  if(! pperrinfo ) return E_INVALIDARG;
392  if(!(pei=IErrorInfoImpl_Constructor()))return E_OUTOFMEMORY;
393 
394  res = IErrorInfo_QueryInterface(pei, &IID_ICreateErrorInfo, (LPVOID*)pperrinfo);
395  IErrorInfo_Release(pei);
396  return res;
397 }
398 
399 /***********************************************************************
400  * GetErrorInfo (OLE32.@)
401  *
402  * Retrieves the error information object for the current thread.
403  *
404  * PARAMS
405  * dwReserved [I]. Reserved. Must be zero.
406  * pperrinfo [O]. Address where error information object will be stored on return.
407  *
408  * RETURNS
409  * Success: S_OK if an error information object was set for the current thread.
410  * S_FALSE if otherwise.
411  * Failure: E_INVALIDARG if dwReserved is not zero.
412  *
413  * NOTES
414  * This function causes the current error info object for the thread to be
415  * cleared if one was set beforehand.
416  */
418 {
419  TRACE("(%d, %p, %p)\n", dwReserved, pperrinfo, COM_CurrentInfo()->errorinfo);
420 
421  if (dwReserved)
422  {
423  ERR("dwReserved (0x%x) != 0\n", dwReserved);
424  return E_INVALIDARG;
425  }
426 
427  if(!pperrinfo) return E_INVALIDARG;
428 
429  if (!COM_CurrentInfo()->errorinfo)
430  {
431  *pperrinfo = NULL;
432  return S_FALSE;
433  }
434 
435  *pperrinfo = COM_CurrentInfo()->errorinfo;
436 
437  /* clear thread error state */
438  COM_CurrentInfo()->errorinfo = NULL;
439  return S_OK;
440 }
441 
442 /***********************************************************************
443  * SetErrorInfo (OLE32.@)
444  *
445  * Sets the error information object for the current thread.
446  *
447  * PARAMS
448  * dwReserved [I] Reserved. Must be zero.
449  * perrinfo [I] Error info object.
450  *
451  * RETURNS
452  * Success: S_OK.
453  * Failure: E_INVALIDARG if dwReserved is not zero.
454  */
456 {
457  IErrorInfo * pei;
458 
459  TRACE("(%d, %p)\n", dwReserved, perrinfo);
460 
461  if (dwReserved)
462  {
463  ERR("dwReserved (0x%x) != 0\n", dwReserved);
464  return E_INVALIDARG;
465  }
466 
467  /* release old errorinfo */
468  pei = COM_CurrentInfo()->errorinfo;
469  if (pei) IErrorInfo_Release(pei);
470 
471  /* set to new value */
472  COM_CurrentInfo()->errorinfo = perrinfo;
473  if (perrinfo) IErrorInfo_AddRef(perrinfo);
474 
475  return S_OK;
476 }
#define REFIID
Definition: guiddef.h:118
#define E_NOINTERFACE
Definition: winerror.h:2364
WCHAR * source
Definition: errorinfo.c:67
static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpContext(ICreateErrorInfo *iface, DWORD dwHelpContext)
Definition: errorinfo.c:296
static HRESULT WINAPI ISupportErrorInfoImpl_QueryInterface(ISupportErrorInfo *iface, REFIID riid, VOID **ppvoid)
Definition: errorinfo.c:318
Definition: scsiwmi.h:51
static ULONG WINAPI ISupportErrorInfoImpl_Release(ISupportErrorInfo *iface)
Definition: errorinfo.c:333
static ULONG WINAPI IErrorInfoImpl_AddRef(IErrorInfo *iface)
Definition: errorinfo.c:121
REFIID riid
Definition: precomp.h:44
static HRESULT WINAPI IErrorInfoImpl_QueryInterface(IErrorInfo *iface, REFIID riid, void **ppvoid)
Definition: errorinfo.c:88
WCHAR * description
Definition: errorinfo.c:68
static HRESULT WINAPI IErrorInfoImpl_GetSource(IErrorInfo *iface, BSTR *pBstrSource)
Definition: errorinfo.c:160
static HRESULT WINAPI ICreateErrorInfoImpl_QueryInterface(ICreateErrorInfo *iface, REFIID riid, VOID **ppvoid)
Definition: errorinfo.c:226
OLECHAR * BSTR
Definition: compat.h:1942
static ULONG WINAPI ICreateErrorInfoImpl_AddRef(ICreateErrorInfo *iface)
Definition: errorinfo.c:235
static LPOLESTR
Definition: stg_prop.c:27
static const ISupportErrorInfoVtbl SupportErrorInfoVtbl
Definition: errorinfo.c:348
#define lstrlenW
Definition: compat.h:415
Definition: send.c:47
static struct oletls * COM_CurrentInfo(void)
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static HRESULT WINAPI ICreateErrorInfoImpl_SetDescription(ICreateErrorInfo *iface, LPOLESTR szDescription)
Definition: errorinfo.c:273
static ULONG WINAPI IErrorInfoImpl_Release(IErrorInfo *iface)
Definition: errorinfo.c:129
static HRESULT WINAPI IErrorInfoImpl_GetDescription(IErrorInfo *iface, BSTR *pBstrDescription)
Definition: errorinfo.c:172
static HRESULT WINAPI IErrorInfoImpl_GetHelpFile(IErrorInfo *iface, BSTR *pBstrHelpFile)
Definition: errorinfo.c:186
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo)
Definition: errorinfo.c:455
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
static ULONG WINAPI ISupportErrorInfoImpl_AddRef(ISupportErrorInfo *iface)
Definition: errorinfo.c:327
long LONG
Definition: pedump.c:60
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
#define S_FALSE
Definition: winerror.h:2357
static ErrorInfoImpl * impl_from_IErrorInfo(IErrorInfo *iface)
Definition: errorinfo.c:73
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
WINE_DEFAULT_DEBUG_CHANNEL(ole)
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static HRESULT WINAPI IErrorInfoImpl_GetHelpContext(IErrorInfo *iface, DWORD *pdwHelpContext)
Definition: errorinfo.c:200
static HRESULT WINAPI ICreateErrorInfoImpl_SetSource(ICreateErrorInfo *iface, LPOLESTR szSource)
Definition: errorinfo.c:260
IErrorInfo IErrorInfo_iface
Definition: errorinfo.c:61
struct ErrorInfoImpl ErrorInfoImpl
HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
Definition: errorinfo.c:417
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
static IErrorInfo * IErrorInfoImpl_Constructor(void)
Definition: errorinfo.c:356
ICreateErrorInfo ICreateErrorInfo_iface
Definition: errorinfo.c:62
static ErrorInfoImpl * impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
Definition: errorinfo.c:83
__wchar_t WCHAR
Definition: xmlstorage.h:180
static ULONG WINAPI ICreateErrorInfoImpl_Release(ICreateErrorInfo *iface)
Definition: errorinfo.c:242
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:6
DWORD m_dwHelpContext
Definition: errorinfo.c:70
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
static HRESULT WINAPI ISupportErrorInfoImpl_InterfaceSupportsErrorInfo(ISupportErrorInfo *iface, REFIID riid)
Definition: errorinfo.c:339
TCHAR szHelpFile[]
Definition: scrnsave.c:30
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: errorinfo.c:43
#define InterlockedDecrement
Definition: armddk.h:52
static const WCHAR szSource[]
Definition: automation.c:501
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static ErrorInfoImpl * impl_from_ICreateErrorInfo(ICreateErrorInfo *iface)
Definition: errorinfo.c:78
static const IErrorInfoVtbl ErrorInfoVtbl
Definition: errorinfo.c:213
#define ERR(fmt,...)
Definition: debug.h:109
HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
Definition: errorinfo.c:386
ISupportErrorInfo ISupportErrorInfo_iface
Definition: errorinfo.c:63
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
static HRESULT WINAPI ICreateErrorInfoImpl_SetGUID(ICreateErrorInfo *iface, REFGUID rguid)
Definition: errorinfo.c:250
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
static const ICreateErrorInfoVtbl CreateErrorInfoVtbl
Definition: errorinfo.c:306
static HRESULT WINAPI IErrorInfoImpl_GetGUID(IErrorInfo *iface, GUID *pGUID)
Definition: errorinfo.c:149
WCHAR * help_file
Definition: errorinfo.c:69
static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpFile(ICreateErrorInfo *iface, LPOLESTR szHelpFile)
Definition: errorinfo.c:285
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
static const WCHAR szDescription[]
Definition: provider.c:55
static BOOL heap_free(void *mem)
Definition: appwiz.h:75