4 * Copyright 2000 Patrik Stridvall, Juergen Schmied
7 * The errorinfo is a per-thread object. The reference is stored in the
12 #include "debugtools.h"
17 #include "debugtools.h"
18 #include "wine/obj_base.h"
19 #include "wine/obj_oleaut.h"
20 #include "wine/obj_errorinfo.h"
21 #include "wine/unicode.h"
23 DEFAULT_DEBUG_CHANNEL(ole
);
25 /* this code is from SysAllocStringLen (ole2disp.c in oleaut32) */
26 static BSTR WINAPI
ERRORINFO_SysAllocString(const OLECHAR
* in
)
36 * Find the lenth of the buffer passed-in in bytes.
39 bufferSize
= len
* sizeof (WCHAR
);
42 * Allocate a new buffer to hold the string.
43 * dont't forget to keep an empty spot at the begining of the
44 * buffer for the character count and an extra character at the
47 newBuffer
= (DWORD
*)HeapAlloc(GetProcessHeap(),
49 bufferSize
+ sizeof(WCHAR
) + sizeof(DWORD
));
52 * If the memory allocation failed, return a null pointer.
58 * Copy the length of the string in the placeholder.
60 *newBuffer
= bufferSize
;
63 * Skip the byte count.
68 * Copy the information in the buffer.
69 * Since it is valid to pass a NULL pointer here, we'll initialize the
70 * buffer to nul if it is the case.
73 memcpy(newBuffer
, in
, bufferSize
);
75 memset(newBuffer
, 0, bufferSize
);
78 * Make sure that there is a nul character at the end of the
81 stringBuffer
= (WCHAR
*)newBuffer
;
82 stringBuffer
[len
] = 0;
84 return (LPWSTR
)stringBuffer
;
87 /* this code is from SysFreeString (ole2disp.c in oleaut32)*/
88 static VOID WINAPI
ERRORINFO_SysFreeString(BSTR in
)
92 /* NULL is a valid parameter */
96 * We have to be careful when we free a BSTR pointer, it points to
97 * the beginning of the string but it skips the byte count contained
100 bufferPointer
= (DWORD
*)in
;
105 * Free the memory from it's "real" origin.
107 HeapFree(GetProcessHeap(), 0, bufferPointer
);
111 typedef struct ErrorInfoImpl
113 ICOM_VTABLE(IErrorInfo
) *lpvtei
;
114 ICOM_VTABLE(ICreateErrorInfo
) *lpvtcei
;
115 ICOM_VTABLE(ISupportErrorInfo
) *lpvtsei
;
120 BSTR bstrDescription
;
122 DWORD m_dwHelpContext
;
125 static ICOM_VTABLE(IErrorInfo
) IErrorInfoImpl_VTable
;
126 static ICOM_VTABLE(ICreateErrorInfo
) ICreateErrorInfoImpl_VTable
;
127 static ICOM_VTABLE(ISupportErrorInfo
) ISupportErrorInfoImpl_VTable
;
130 converts a objectpointer to This
132 #define _IErrorInfo_Offset ((int)(&(((ErrorInfoImpl*)0)->lpvtei)))
133 #define _ICOM_THIS_From_IErrorInfo(class, name) class* This = (class*)(((char*)name)-_IErrorInfo_Offset);
135 #define _ICreateErrorInfo_Offset ((int)(&(((ErrorInfoImpl*)0)->lpvtcei)))
136 #define _ICOM_THIS_From_ICreateErrorInfo(class, name) class* This = (class*)(((char*)name)-_ICreateErrorInfo_Offset);
138 #define _ISupportErrorInfo_Offset ((int)(&(((ErrorInfoImpl*)0)->lpvtsei)))
139 #define _ICOM_THIS_From_ISupportErrorInfo(class, name) class* This = (class*)(((char*)name)-_ISupportErrorInfo_Offset);
142 converts This to a objectpointer
144 #define _IErrorInfo_(This) (IErrorInfo*)&(This->lpvtei)
145 #define _ICreateErrorInfo_(This) (ICreateErrorInfo*)&(This->lpvtcei)
146 #define _ISupportErrorInfo_(This) (ISupportErrorInfo*)&(This->lpvtsei)
148 IErrorInfo
* IErrorInfoImpl_Constructor()
150 ErrorInfoImpl
* ei
= HeapAlloc(GetProcessHeap(), 0, sizeof(ErrorInfoImpl
));
153 ei
->lpvtei
= &IErrorInfoImpl_VTable
;
154 ei
->lpvtcei
= &ICreateErrorInfoImpl_VTable
;
155 ei
->lpvtsei
= &ISupportErrorInfoImpl_VTable
;
157 ei
->bstrSource
= NULL
;
158 ei
->bstrDescription
= NULL
;
159 ei
->bstrHelpFile
= NULL
;
160 ei
->m_dwHelpContext
= 0;
162 return (IErrorInfo
*)ei
;
166 static HRESULT WINAPI
IErrorInfoImpl_QueryInterface(
171 _ICOM_THIS_From_IErrorInfo(ErrorInfoImpl
, iface
);
172 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvoid
);
176 if(IsEqualIID(riid
, &IID_IErrorInfo
))
178 *ppvoid
= _IErrorInfo_(This
);
180 else if(IsEqualIID(riid
, &IID_ICreateErrorInfo
))
182 *ppvoid
= _ICreateErrorInfo_(This
);
184 else if(IsEqualIID(riid
, &IID_ISupportErrorInfo
))
186 *ppvoid
= _ISupportErrorInfo_(This
);
191 IUnknown_AddRef( (IUnknown
*)*ppvoid
);
192 TRACE("-- Interface: (%p)->(%p)\n",ppvoid
,*ppvoid
);
195 TRACE("-- Interface: E_NOINTERFACE\n");
196 return E_NOINTERFACE
;
199 static ULONG WINAPI
IErrorInfoImpl_AddRef(
202 _ICOM_THIS_From_IErrorInfo(ErrorInfoImpl
, iface
);
203 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
204 return InterlockedIncrement(&This
->ref
);
207 static ULONG WINAPI
IErrorInfoImpl_Release(
210 _ICOM_THIS_From_IErrorInfo(ErrorInfoImpl
, iface
);
211 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
213 if (!InterlockedDecrement(&This
->ref
))
215 TRACE("-- destroying IErrorInfo(%p)\n",This
);
216 HeapFree(GetProcessHeap(),0,This
);
222 static HRESULT WINAPI
IErrorInfoImpl_GetGUID(
226 _ICOM_THIS_From_IErrorInfo(ErrorInfoImpl
, iface
);
227 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
228 if(!pGUID
)return E_INVALIDARG
;
229 memcpy(pGUID
, &This
->m_Guid
, sizeof(GUID
));
233 static HRESULT WINAPI
IErrorInfoImpl_GetSource(
237 _ICOM_THIS_From_IErrorInfo(ErrorInfoImpl
, iface
);
238 TRACE("(%p)->(pBstrSource=%p)\n",This
,pBstrSource
);
239 if (pBstrSource
== NULL
)
241 *pBstrSource
= ERRORINFO_SysAllocString(This
->bstrSource
);
245 static HRESULT WINAPI
IErrorInfoImpl_GetDescription(
247 BSTR
*pBstrDescription
)
249 _ICOM_THIS_From_IErrorInfo(ErrorInfoImpl
, iface
);
251 TRACE("(%p)->(pBstrDescription=%p)\n",This
,pBstrDescription
);
252 if (pBstrDescription
== NULL
)
254 *pBstrDescription
= ERRORINFO_SysAllocString(This
->bstrDescription
);
259 static HRESULT WINAPI
IErrorInfoImpl_GetHelpFile(
263 _ICOM_THIS_From_IErrorInfo(ErrorInfoImpl
, iface
);
265 TRACE("(%p)->(pBstrHelpFile=%p)\n",This
, pBstrHelpFile
);
266 if (pBstrHelpFile
== NULL
)
268 *pBstrHelpFile
= ERRORINFO_SysAllocString(This
->bstrHelpFile
);
273 static HRESULT WINAPI
IErrorInfoImpl_GetHelpContext(
275 DWORD
*pdwHelpContext
)
277 _ICOM_THIS_From_IErrorInfo(ErrorInfoImpl
, iface
);
278 TRACE("(%p)->(pdwHelpContext=%p)\n",This
, pdwHelpContext
);
279 if (pdwHelpContext
== NULL
)
281 *pdwHelpContext
= This
->m_dwHelpContext
;
286 static ICOM_VTABLE(IErrorInfo
) IErrorInfoImpl_VTable
=
288 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
289 IErrorInfoImpl_QueryInterface
,
290 IErrorInfoImpl_AddRef
,
291 IErrorInfoImpl_Release
,
293 IErrorInfoImpl_GetGUID
,
294 IErrorInfoImpl_GetSource
,
295 IErrorInfoImpl_GetDescription
,
296 IErrorInfoImpl_GetHelpFile
,
297 IErrorInfoImpl_GetHelpContext
301 static HRESULT WINAPI
ICreateErrorInfoImpl_QueryInterface(
302 ICreateErrorInfo
* iface
,
306 _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl
, iface
);
307 TRACE("(%p)\n", This
);
308 return IErrorInfo_QueryInterface(_IErrorInfo_(This
), riid
, ppvoid
);
311 static ULONG WINAPI
ICreateErrorInfoImpl_AddRef(
312 ICreateErrorInfo
* iface
)
314 _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl
, iface
);
315 TRACE("(%p)\n", This
);
316 return IErrorInfo_AddRef(_IErrorInfo_(This
));
319 static ULONG WINAPI
ICreateErrorInfoImpl_Release(
320 ICreateErrorInfo
* iface
)
322 _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl
, iface
);
323 TRACE("(%p)\n", This
);
324 return IErrorInfo_Release(_IErrorInfo_(This
));
328 static HRESULT WINAPI
ICreateErrorInfoImpl_SetGUID(
329 ICreateErrorInfo
* iface
,
332 _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl
, iface
);
333 TRACE("(%p)->(%s)\n", This
, debugstr_guid(rguid
));
334 memcpy(&This
->m_Guid
, rguid
, sizeof(GUID
));
338 static HRESULT WINAPI
ICreateErrorInfoImpl_SetSource(
339 ICreateErrorInfo
* iface
,
342 _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl
, iface
);
343 TRACE("(%p)\n",This
);
344 if (This
->bstrSource
!= NULL
)
345 ERRORINFO_SysFreeString(This
->bstrSource
);
346 This
->bstrSource
= ERRORINFO_SysAllocString(szSource
);
351 static HRESULT WINAPI
ICreateErrorInfoImpl_SetDescription(
352 ICreateErrorInfo
* iface
,
353 LPOLESTR szDescription
)
355 _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl
, iface
);
356 TRACE("(%p)\n",This
);
357 if (This
->bstrDescription
!= NULL
)
358 ERRORINFO_SysFreeString(This
->bstrDescription
);
359 This
->bstrDescription
= ERRORINFO_SysAllocString(szDescription
);
364 static HRESULT WINAPI
ICreateErrorInfoImpl_SetHelpFile(
365 ICreateErrorInfo
* iface
,
368 _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl
, iface
);
369 TRACE("(%p)\n",This
);
370 if (This
->bstrHelpFile
!= NULL
)
371 ERRORINFO_SysFreeString(This
->bstrHelpFile
);
372 This
->bstrHelpFile
= ERRORINFO_SysAllocString(szHelpFile
);
377 static HRESULT WINAPI
ICreateErrorInfoImpl_SetHelpContext(
378 ICreateErrorInfo
* iface
,
381 _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl
, iface
);
382 TRACE("(%p)\n",This
);
383 This
->m_dwHelpContext
= dwHelpContext
;
388 static ICOM_VTABLE(ICreateErrorInfo
) ICreateErrorInfoImpl_VTable
=
390 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
391 ICreateErrorInfoImpl_QueryInterface
,
392 ICreateErrorInfoImpl_AddRef
,
393 ICreateErrorInfoImpl_Release
,
395 ICreateErrorInfoImpl_SetGUID
,
396 ICreateErrorInfoImpl_SetSource
,
397 ICreateErrorInfoImpl_SetDescription
,
398 ICreateErrorInfoImpl_SetHelpFile
,
399 ICreateErrorInfoImpl_SetHelpContext
402 static HRESULT WINAPI
ISupportErrorInfoImpl_QueryInterface(
403 ISupportErrorInfo
* iface
,
407 _ICOM_THIS_From_ISupportErrorInfo(ErrorInfoImpl
, iface
);
408 TRACE("(%p)\n", This
);
410 return IErrorInfo_QueryInterface(_IErrorInfo_(This
), riid
, ppvoid
);
413 static ULONG WINAPI
ISupportErrorInfoImpl_AddRef(
414 ISupportErrorInfo
* iface
)
416 _ICOM_THIS_From_ISupportErrorInfo(ErrorInfoImpl
, iface
);
417 TRACE("(%p)\n", This
);
418 return IErrorInfo_AddRef(_IErrorInfo_(This
));
421 static ULONG WINAPI
ISupportErrorInfoImpl_Release(
422 ISupportErrorInfo
* iface
)
424 _ICOM_THIS_From_ISupportErrorInfo(ErrorInfoImpl
, iface
);
425 TRACE("(%p)\n", This
);
426 return IErrorInfo_Release(_IErrorInfo_(This
));
430 static HRESULT WINAPI
ISupportErrorInfoImpl_InterfaceSupportsErrorInfo(
431 ISupportErrorInfo
* iface
,
434 _ICOM_THIS_From_ISupportErrorInfo(ErrorInfoImpl
, iface
);
435 TRACE("(%p)->(%s)\n", This
, debugstr_guid(riid
));
436 return (IsEqualIID(riid
, &This
->m_Guid
)) ? S_OK
: S_FALSE
;
439 static ICOM_VTABLE(ISupportErrorInfo
) ISupportErrorInfoImpl_VTable
=
441 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
442 ISupportErrorInfoImpl_QueryInterface
,
443 ISupportErrorInfoImpl_AddRef
,
444 ISupportErrorInfoImpl_Release
,
447 ISupportErrorInfoImpl_InterfaceSupportsErrorInfo
449 /***********************************************************************
452 HRESULT WINAPI
CreateErrorInfo(ICreateErrorInfo
**pperrinfo
)
456 TRACE("(%p): stub:\n", pperrinfo
);
457 if(! pperrinfo
) return E_INVALIDARG
;
458 if(!(pei
=IErrorInfoImpl_Constructor()))return E_OUTOFMEMORY
;
460 res
= IErrorInfo_QueryInterface(pei
, &IID_ICreateErrorInfo
, (LPVOID
*)pperrinfo
);
461 IErrorInfo_Release(pei
);
465 /***********************************************************************
468 HRESULT WINAPI
GetErrorInfo(ULONG dwReserved
, IErrorInfo
**pperrinfo
)
470 TRACE("(%ld, %p, %p): stub:\n", dwReserved
, pperrinfo
, NtCurrentTeb()->ErrorInfo
);
472 if(! pperrinfo
) return E_INVALIDARG
;
473 if(!(*pperrinfo
= (IErrorInfo
*)(NtCurrentTeb()->ErrorInfo
))) return S_FALSE
;
475 /* clear thread error state */
476 NtCurrentTeb()->ErrorInfo
= NULL
;
480 /***********************************************************************
483 HRESULT WINAPI
SetErrorInfo(ULONG dwReserved
, IErrorInfo
*perrinfo
)
486 TRACE("(%ld, %p): stub:\n", dwReserved
, perrinfo
);
488 /* release old errorinfo */
489 pei
= (IErrorInfo
*)NtCurrentTeb()->ErrorInfo
;
490 if(pei
) IErrorInfo_Release(pei
);
492 /* set to new value */
493 NtCurrentTeb()->ErrorInfo
= perrinfo
;
494 if(perrinfo
) IErrorInfo_AddRef(perrinfo
);