4 * Copyright 2000 Patrik Stridvall, Juergen Schmied
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.
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.
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
22 * The errorinfo is a per-thread object. The reference is stored in the
23 * TEB at offset 0xf80.
37 #include "wine/unicode.h"
38 #include "compobj_private.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
44 static inline WCHAR
*heap_strdupW(const WCHAR
*str
)
51 size
= (strlenW(str
)+1)*sizeof(WCHAR
);
52 ret
= heap_alloc(size
);
54 memcpy(ret
, str
, size
);
60 typedef struct ErrorInfoImpl
62 IErrorInfo IErrorInfo_iface
;
63 ICreateErrorInfo ICreateErrorInfo_iface
;
64 ISupportErrorInfo ISupportErrorInfo_iface
;
71 DWORD m_dwHelpContext
;
74 static inline ErrorInfoImpl
*impl_from_IErrorInfo( IErrorInfo
*iface
)
76 return CONTAINING_RECORD(iface
, ErrorInfoImpl
, IErrorInfo_iface
);
79 static inline ErrorInfoImpl
*impl_from_ICreateErrorInfo( ICreateErrorInfo
*iface
)
81 return CONTAINING_RECORD(iface
, ErrorInfoImpl
, ICreateErrorInfo_iface
);
84 static inline ErrorInfoImpl
*impl_from_ISupportErrorInfo( ISupportErrorInfo
*iface
)
86 return CONTAINING_RECORD(iface
, ErrorInfoImpl
, ISupportErrorInfo_iface
);
89 static HRESULT WINAPI
IErrorInfoImpl_QueryInterface(
94 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
95 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid(riid
),ppvoid
);
99 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IErrorInfo
))
101 *ppvoid
= &This
->IErrorInfo_iface
;
103 else if(IsEqualIID(riid
, &IID_ICreateErrorInfo
))
105 *ppvoid
= &This
->ICreateErrorInfo_iface
;
107 else if(IsEqualIID(riid
, &IID_ISupportErrorInfo
))
109 *ppvoid
= &This
->ISupportErrorInfo_iface
;
114 IUnknown_AddRef( (IUnknown
*)*ppvoid
);
115 TRACE("-- Interface: (%p)->(%p)\n",ppvoid
,*ppvoid
);
118 TRACE("-- Interface: E_NOINTERFACE\n");
119 return E_NOINTERFACE
;
122 static ULONG WINAPI
IErrorInfoImpl_AddRef(
125 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
126 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
127 return InterlockedIncrement(&This
->ref
);
130 static ULONG WINAPI
IErrorInfoImpl_Release(
133 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
134 ULONG ref
= InterlockedDecrement(&This
->ref
);
136 TRACE("(%p)->(count=%u)\n",This
,ref
+1);
140 TRACE("-- destroying IErrorInfo(%p)\n",This
);
142 heap_free(This
->source
);
143 heap_free(This
->description
);
144 heap_free(This
->help_file
);
150 static HRESULT WINAPI
IErrorInfoImpl_GetGUID(
154 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
155 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
156 if(!pGUID
)return E_INVALIDARG
;
157 *pGUID
= This
->m_Guid
;
161 static HRESULT WINAPI
IErrorInfoImpl_GetSource(
165 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
166 TRACE("(%p)->(pBstrSource=%p)\n",This
,pBstrSource
);
167 if (pBstrSource
== NULL
)
169 *pBstrSource
= SysAllocString(This
->source
);
173 static HRESULT WINAPI
IErrorInfoImpl_GetDescription(
175 BSTR
*pBstrDescription
)
177 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
179 TRACE("(%p)->(pBstrDescription=%p)\n",This
,pBstrDescription
);
180 if (pBstrDescription
== NULL
)
182 *pBstrDescription
= SysAllocString(This
->description
);
187 static HRESULT WINAPI
IErrorInfoImpl_GetHelpFile(
191 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
193 TRACE("(%p)->(pBstrHelpFile=%p)\n",This
, pBstrHelpFile
);
194 if (pBstrHelpFile
== NULL
)
196 *pBstrHelpFile
= SysAllocString(This
->help_file
);
201 static HRESULT WINAPI
IErrorInfoImpl_GetHelpContext(
203 DWORD
*pdwHelpContext
)
205 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
206 TRACE("(%p)->(pdwHelpContext=%p)\n",This
, pdwHelpContext
);
207 if (pdwHelpContext
== NULL
)
209 *pdwHelpContext
= This
->m_dwHelpContext
;
214 static const IErrorInfoVtbl ErrorInfoVtbl
=
216 IErrorInfoImpl_QueryInterface
,
217 IErrorInfoImpl_AddRef
,
218 IErrorInfoImpl_Release
,
219 IErrorInfoImpl_GetGUID
,
220 IErrorInfoImpl_GetSource
,
221 IErrorInfoImpl_GetDescription
,
222 IErrorInfoImpl_GetHelpFile
,
223 IErrorInfoImpl_GetHelpContext
227 static HRESULT WINAPI
ICreateErrorInfoImpl_QueryInterface(
228 ICreateErrorInfo
* iface
,
232 ErrorInfoImpl
*This
= impl_from_ICreateErrorInfo(iface
);
233 return IErrorInfo_QueryInterface(&This
->IErrorInfo_iface
, riid
, ppvoid
);
236 static ULONG WINAPI
ICreateErrorInfoImpl_AddRef(
237 ICreateErrorInfo
* iface
)
239 ErrorInfoImpl
*This
= impl_from_ICreateErrorInfo(iface
);
240 return IErrorInfo_AddRef(&This
->IErrorInfo_iface
);
243 static ULONG WINAPI
ICreateErrorInfoImpl_Release(
244 ICreateErrorInfo
* iface
)
246 ErrorInfoImpl
*This
= impl_from_ICreateErrorInfo(iface
);
247 return IErrorInfo_Release(&This
->IErrorInfo_iface
);
251 static HRESULT WINAPI
ICreateErrorInfoImpl_SetGUID(
252 ICreateErrorInfo
* iface
,
255 ErrorInfoImpl
*This
= impl_from_ICreateErrorInfo(iface
);
256 TRACE("(%p)->(%s)\n", This
, debugstr_guid(rguid
));
257 This
->m_Guid
= *rguid
;
261 static HRESULT WINAPI
ICreateErrorInfoImpl_SetSource(
262 ICreateErrorInfo
* iface
,
265 ErrorInfoImpl
*This
= impl_from_ICreateErrorInfo(iface
);
266 TRACE("(%p): %s\n",This
, debugstr_w(szSource
));
268 heap_free(This
->source
);
269 This
->source
= heap_strdupW(szSource
);
274 static HRESULT WINAPI
ICreateErrorInfoImpl_SetDescription(
275 ICreateErrorInfo
* iface
,
276 LPOLESTR szDescription
)
278 ErrorInfoImpl
*This
= impl_from_ICreateErrorInfo(iface
);
279 TRACE("(%p): %s\n",This
, debugstr_w(szDescription
));
281 heap_free(This
->description
);
282 This
->description
= heap_strdupW(szDescription
);
286 static HRESULT WINAPI
ICreateErrorInfoImpl_SetHelpFile(
287 ICreateErrorInfo
* iface
,
290 ErrorInfoImpl
*This
= impl_from_ICreateErrorInfo(iface
);
291 TRACE("(%p,%s)\n",This
,debugstr_w(szHelpFile
));
292 heap_free(This
->help_file
);
293 This
->help_file
= heap_strdupW(szHelpFile
);
297 static HRESULT WINAPI
ICreateErrorInfoImpl_SetHelpContext(
298 ICreateErrorInfo
* iface
,
301 ErrorInfoImpl
*This
= impl_from_ICreateErrorInfo(iface
);
302 TRACE("(%p,%d)\n",This
,dwHelpContext
);
303 This
->m_dwHelpContext
= dwHelpContext
;
307 static const ICreateErrorInfoVtbl CreateErrorInfoVtbl
=
309 ICreateErrorInfoImpl_QueryInterface
,
310 ICreateErrorInfoImpl_AddRef
,
311 ICreateErrorInfoImpl_Release
,
312 ICreateErrorInfoImpl_SetGUID
,
313 ICreateErrorInfoImpl_SetSource
,
314 ICreateErrorInfoImpl_SetDescription
,
315 ICreateErrorInfoImpl_SetHelpFile
,
316 ICreateErrorInfoImpl_SetHelpContext
319 static HRESULT WINAPI
ISupportErrorInfoImpl_QueryInterface(
320 ISupportErrorInfo
* iface
,
324 ErrorInfoImpl
*This
= impl_from_ISupportErrorInfo(iface
);
325 return IErrorInfo_QueryInterface(&This
->IErrorInfo_iface
, riid
, ppvoid
);
328 static ULONG WINAPI
ISupportErrorInfoImpl_AddRef(ISupportErrorInfo
* iface
)
330 ErrorInfoImpl
*This
= impl_from_ISupportErrorInfo(iface
);
331 return IErrorInfo_AddRef(&This
->IErrorInfo_iface
);
334 static ULONG WINAPI
ISupportErrorInfoImpl_Release(ISupportErrorInfo
* iface
)
336 ErrorInfoImpl
*This
= impl_from_ISupportErrorInfo(iface
);
337 return IErrorInfo_Release(&This
->IErrorInfo_iface
);
340 static HRESULT WINAPI
ISupportErrorInfoImpl_InterfaceSupportsErrorInfo(
341 ISupportErrorInfo
* iface
,
344 ErrorInfoImpl
*This
= impl_from_ISupportErrorInfo(iface
);
345 TRACE("(%p)->(%s)\n", This
, debugstr_guid(riid
));
346 return (IsEqualIID(riid
, &This
->m_Guid
)) ? S_OK
: S_FALSE
;
349 static const ISupportErrorInfoVtbl SupportErrorInfoVtbl
=
351 ISupportErrorInfoImpl_QueryInterface
,
352 ISupportErrorInfoImpl_AddRef
,
353 ISupportErrorInfoImpl_Release
,
354 ISupportErrorInfoImpl_InterfaceSupportsErrorInfo
357 static IErrorInfo
* IErrorInfoImpl_Constructor(void)
359 ErrorInfoImpl
*This
= heap_alloc(sizeof(ErrorInfoImpl
));
361 if (!This
) return NULL
;
363 This
->IErrorInfo_iface
.lpVtbl
= &ErrorInfoVtbl
;
364 This
->ICreateErrorInfo_iface
.lpVtbl
= &CreateErrorInfoVtbl
;
365 This
->ISupportErrorInfo_iface
.lpVtbl
= &SupportErrorInfoVtbl
;
368 This
->description
= NULL
;
369 This
->help_file
= NULL
;
370 This
->m_dwHelpContext
= 0;
372 return &This
->IErrorInfo_iface
;
375 /***********************************************************************
376 * CreateErrorInfo (OLE32.@)
378 * Creates an object used to set details for an error info object.
381 * pperrinfo [O]. Address where error info creation object will be stored.
385 * Failure: HRESULT code.
387 HRESULT WINAPI
CreateErrorInfo(ICreateErrorInfo
**pperrinfo
)
391 TRACE("(%p)\n", pperrinfo
);
392 if(! pperrinfo
) return E_INVALIDARG
;
393 if(!(pei
=IErrorInfoImpl_Constructor()))return E_OUTOFMEMORY
;
395 res
= IErrorInfo_QueryInterface(pei
, &IID_ICreateErrorInfo
, (LPVOID
*)pperrinfo
);
396 IErrorInfo_Release(pei
);
400 /***********************************************************************
401 * GetErrorInfo (OLE32.@)
403 * Retrieves the error information object for the current thread.
406 * dwReserved [I]. Reserved. Must be zero.
407 * pperrinfo [O]. Address where error information object will be stored on return.
410 * Success: S_OK if an error information object was set for the current thread.
411 * S_FALSE if otherwise.
412 * Failure: E_INVALIDARG if dwReserved is not zero.
415 * This function causes the current error info object for the thread to be
416 * cleared if one was set beforehand.
418 HRESULT WINAPI
GetErrorInfo(ULONG dwReserved
, IErrorInfo
**pperrinfo
)
420 TRACE("(%d, %p, %p)\n", dwReserved
, pperrinfo
, COM_CurrentInfo()->errorinfo
);
424 ERR("dwReserved (0x%x) != 0\n", dwReserved
);
428 if(!pperrinfo
) return E_INVALIDARG
;
430 if (!COM_CurrentInfo()->errorinfo
)
436 *pperrinfo
= COM_CurrentInfo()->errorinfo
;
438 /* clear thread error state */
439 COM_CurrentInfo()->errorinfo
= NULL
;
443 /***********************************************************************
444 * SetErrorInfo (OLE32.@)
446 * Sets the error information object for the current thread.
449 * dwReserved [I] Reserved. Must be zero.
450 * perrinfo [I] Error info object.
454 * Failure: E_INVALIDARG if dwReserved is not zero.
456 HRESULT WINAPI
SetErrorInfo(ULONG dwReserved
, IErrorInfo
*perrinfo
)
460 TRACE("(%d, %p)\n", dwReserved
, perrinfo
);
464 ERR("dwReserved (0x%x) != 0\n", dwReserved
);
468 /* release old errorinfo */
469 pei
= COM_CurrentInfo()->errorinfo
;
470 if (pei
) IErrorInfo_Release(pei
);
472 /* set to new value */
473 COM_CurrentInfo()->errorinfo
= perrinfo
;
474 if (perrinfo
) IErrorInfo_AddRef(perrinfo
);