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
25 #include "combase_private.h"
27 #include "wine/debug.h"
28 #include "wine/heap.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
32 static WCHAR
*heap_strdupW(const WCHAR
*str
)
40 size
= (lstrlenW(str
)+1)*sizeof(WCHAR
);
41 ret
= heap_alloc(size
);
43 memcpy(ret
, str
, size
);
51 IErrorInfo IErrorInfo_iface
;
52 ICreateErrorInfo ICreateErrorInfo_iface
;
53 ISupportErrorInfo ISupportErrorInfo_iface
;
63 static struct error_info
*impl_from_IErrorInfo(IErrorInfo
*iface
)
65 return CONTAINING_RECORD(iface
, struct error_info
, IErrorInfo_iface
);
68 static struct error_info
*impl_from_ICreateErrorInfo(ICreateErrorInfo
*iface
)
70 return CONTAINING_RECORD(iface
, struct error_info
, ICreateErrorInfo_iface
);
73 static struct error_info
*impl_from_ISupportErrorInfo(ISupportErrorInfo
*iface
)
75 return CONTAINING_RECORD(iface
, struct error_info
, ISupportErrorInfo_iface
);
78 static HRESULT WINAPI
errorinfo_QueryInterface(IErrorInfo
*iface
, REFIID riid
, void **obj
)
80 struct error_info
*error_info
= impl_from_IErrorInfo(iface
);
82 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
86 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IErrorInfo
))
88 *obj
= &error_info
->IErrorInfo_iface
;
90 else if (IsEqualIID(riid
, &IID_ICreateErrorInfo
))
92 *obj
= &error_info
->ICreateErrorInfo_iface
;
94 else if (IsEqualIID(riid
, &IID_ISupportErrorInfo
))
96 *obj
= &error_info
->ISupportErrorInfo_iface
;
101 IUnknown_AddRef((IUnknown
*)*obj
);
105 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
106 return E_NOINTERFACE
;
109 static ULONG WINAPI
errorinfo_AddRef(IErrorInfo
*iface
)
111 struct error_info
*error_info
= impl_from_IErrorInfo(iface
);
112 ULONG refcount
= InterlockedIncrement(&error_info
->refcount
);
114 TRACE("%p, refcount %u.\n", iface
, refcount
);
119 static ULONG WINAPI
errorinfo_Release(IErrorInfo
*iface
)
121 struct error_info
*error_info
= impl_from_IErrorInfo(iface
);
122 ULONG refcount
= InterlockedDecrement(&error_info
->refcount
);
124 TRACE("%p, refcount %u.\n", iface
, refcount
);
128 heap_free(error_info
->source
);
129 heap_free(error_info
->description
);
130 heap_free(error_info
->help_file
);
131 heap_free(error_info
);
137 static HRESULT WINAPI
errorinfo_GetGUID(IErrorInfo
*iface
, GUID
*guid
)
139 struct error_info
*error_info
= impl_from_IErrorInfo(iface
);
141 TRACE("%p, %p.\n", iface
, guid
);
143 if (!guid
) return E_INVALIDARG
;
144 *guid
= error_info
->guid
;
148 static HRESULT WINAPI
errorinfo_GetSource(IErrorInfo
* iface
, BSTR
*source
)
150 struct error_info
*error_info
= impl_from_IErrorInfo(iface
);
152 TRACE("%p, %p.\n", iface
, source
);
156 *source
= SysAllocString(error_info
->source
);
160 static HRESULT WINAPI
errorinfo_GetDescription(IErrorInfo
*iface
, BSTR
*description
)
162 struct error_info
*error_info
= impl_from_IErrorInfo(iface
);
164 TRACE("%p, %p.\n", iface
, description
);
168 *description
= SysAllocString(error_info
->description
);
172 static HRESULT WINAPI
errorinfo_GetHelpFile(IErrorInfo
*iface
, BSTR
*helpfile
)
174 struct error_info
*error_info
= impl_from_IErrorInfo(iface
);
176 TRACE("%p, %p.\n", iface
, helpfile
);
180 *helpfile
= SysAllocString(error_info
->help_file
);
184 static HRESULT WINAPI
errorinfo_GetHelpContext(IErrorInfo
*iface
, DWORD
*help_context
)
186 struct error_info
*error_info
= impl_from_IErrorInfo(iface
);
188 TRACE("%p, %p.\n", iface
, help_context
);
192 *help_context
= error_info
->help_context
;
197 static const IErrorInfoVtbl errorinfo_vtbl
=
199 errorinfo_QueryInterface
,
204 errorinfo_GetDescription
,
205 errorinfo_GetHelpFile
,
206 errorinfo_GetHelpContext
209 static HRESULT WINAPI
create_errorinfo_QueryInterface(ICreateErrorInfo
*iface
, REFIID riid
, void **obj
)
211 struct error_info
*error_info
= impl_from_ICreateErrorInfo(iface
);
212 return IErrorInfo_QueryInterface(&error_info
->IErrorInfo_iface
, riid
, obj
);
215 static ULONG WINAPI
create_errorinfo_AddRef(ICreateErrorInfo
*iface
)
217 struct error_info
*error_info
= impl_from_ICreateErrorInfo(iface
);
218 return IErrorInfo_AddRef(&error_info
->IErrorInfo_iface
);
221 static ULONG WINAPI
create_errorinfo_Release(ICreateErrorInfo
*iface
)
223 struct error_info
*error_info
= impl_from_ICreateErrorInfo(iface
);
224 return IErrorInfo_Release(&error_info
->IErrorInfo_iface
);
227 static HRESULT WINAPI
create_errorinfo_SetGUID(ICreateErrorInfo
*iface
, REFGUID guid
)
229 struct error_info
*error_info
= impl_from_ICreateErrorInfo(iface
);
231 TRACE("%p, %s.\n", iface
, debugstr_guid(guid
));
233 error_info
->guid
= *guid
;
238 static HRESULT WINAPI
create_errorinfo_SetSource(ICreateErrorInfo
*iface
, LPOLESTR source
)
240 struct error_info
*error_info
= impl_from_ICreateErrorInfo(iface
);
242 TRACE("%p, %s.\n", iface
, debugstr_w(source
));
244 heap_free(error_info
->source
);
245 error_info
->source
= heap_strdupW(source
);
250 static HRESULT WINAPI
create_errorinfo_SetDescription(ICreateErrorInfo
*iface
, LPOLESTR description
)
252 struct error_info
*error_info
= impl_from_ICreateErrorInfo(iface
);
254 TRACE("%p, %s.\n", iface
, debugstr_w(description
));
256 heap_free(error_info
->description
);
257 error_info
->description
= heap_strdupW(description
);
262 static HRESULT WINAPI
create_errorinfo_SetHelpFile(ICreateErrorInfo
*iface
, LPOLESTR helpfile
)
264 struct error_info
*error_info
= impl_from_ICreateErrorInfo(iface
);
266 TRACE("%p, %s.\n", iface
, debugstr_w(helpfile
));
268 heap_free(error_info
->help_file
);
269 error_info
->help_file
= heap_strdupW(helpfile
);
274 static HRESULT WINAPI
create_errorinfo_SetHelpContext(ICreateErrorInfo
*iface
, DWORD help_context
)
276 struct error_info
*error_info
= impl_from_ICreateErrorInfo(iface
);
278 TRACE("%p, %#x.\n", iface
, help_context
);
280 error_info
->help_context
= help_context
;
285 static const ICreateErrorInfoVtbl create_errorinfo_vtbl
=
287 create_errorinfo_QueryInterface
,
288 create_errorinfo_AddRef
,
289 create_errorinfo_Release
,
290 create_errorinfo_SetGUID
,
291 create_errorinfo_SetSource
,
292 create_errorinfo_SetDescription
,
293 create_errorinfo_SetHelpFile
,
294 create_errorinfo_SetHelpContext
297 static HRESULT WINAPI
support_errorinfo_QueryInterface(ISupportErrorInfo
*iface
, REFIID riid
, void **obj
)
299 struct error_info
*error_info
= impl_from_ISupportErrorInfo(iface
);
300 return IErrorInfo_QueryInterface(&error_info
->IErrorInfo_iface
, riid
, obj
);
303 static ULONG WINAPI
support_errorinfo_AddRef(ISupportErrorInfo
*iface
)
305 struct error_info
*error_info
= impl_from_ISupportErrorInfo(iface
);
306 return IErrorInfo_AddRef(&error_info
->IErrorInfo_iface
);
309 static ULONG WINAPI
support_errorinfo_Release(ISupportErrorInfo
*iface
)
311 struct error_info
*error_info
= impl_from_ISupportErrorInfo(iface
);
312 return IErrorInfo_Release(&error_info
->IErrorInfo_iface
);
315 static HRESULT WINAPI
support_errorinfo_InterfaceSupportsErrorInfo(ISupportErrorInfo
*iface
, REFIID riid
)
317 struct error_info
*error_info
= impl_from_ISupportErrorInfo(iface
);
319 TRACE("%p, %s.\n", iface
, debugstr_guid(riid
));
321 return IsEqualIID(riid
, &error_info
->guid
) ? S_OK
: S_FALSE
;
324 static const ISupportErrorInfoVtbl support_errorinfo_vtbl
=
326 support_errorinfo_QueryInterface
,
327 support_errorinfo_AddRef
,
328 support_errorinfo_Release
,
329 support_errorinfo_InterfaceSupportsErrorInfo
332 /***********************************************************************
333 * CreateErrorInfo (combase.@)
335 HRESULT WINAPI
CreateErrorInfo(ICreateErrorInfo
**ret
)
337 struct error_info
*error_info
;
341 if (!ret
) return E_INVALIDARG
;
343 if (!(error_info
= heap_alloc(sizeof(*error_info
))))
344 return E_OUTOFMEMORY
;
346 error_info
->IErrorInfo_iface
.lpVtbl
= &errorinfo_vtbl
;
347 error_info
->ICreateErrorInfo_iface
.lpVtbl
= &create_errorinfo_vtbl
;
348 error_info
->ISupportErrorInfo_iface
.lpVtbl
= &support_errorinfo_vtbl
;
349 error_info
->refcount
= 1;
350 error_info
->source
= NULL
;
351 error_info
->description
= NULL
;
352 error_info
->help_file
= NULL
;
353 error_info
->help_context
= 0;
355 *ret
= &error_info
->ICreateErrorInfo_iface
;
360 /***********************************************************************
361 * GetErrorInfo (combase.@)
363 HRESULT WINAPI
GetErrorInfo(ULONG reserved
, IErrorInfo
**error_info
)
365 struct tlsdata
*tlsdata
;
368 TRACE("%u, %p\n", reserved
, error_info
);
370 if (reserved
|| !error_info
)
373 if (FAILED(hr
= com_get_tlsdata(&tlsdata
)))
376 if (!tlsdata
->errorinfo
)
382 *error_info
= tlsdata
->errorinfo
;
383 tlsdata
->errorinfo
= NULL
;
388 /***********************************************************************
389 * SetErrorInfo (combase.@)
391 HRESULT WINAPI
SetErrorInfo(ULONG reserved
, IErrorInfo
*error_info
)
393 struct tlsdata
*tlsdata
;
396 TRACE("%u, %p\n", reserved
, error_info
);
401 if (FAILED(hr
= com_get_tlsdata(&tlsdata
)))
404 if (tlsdata
->errorinfo
)
405 IErrorInfo_Release(tlsdata
->errorinfo
);
407 tlsdata
->errorinfo
= error_info
;
409 IErrorInfo_AddRef(error_info
);