mfreadwrite/reader: Add missing allocation check (Coverity).
[wine/zf.git] / dlls / combase / errorinfo.c
blob83e2f0b710343737a19e5828c38821804eb68858
1 /*
2 * ErrorInfo API
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
21 #define COBJMACROS
23 #include "oleauto.h"
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)
34 WCHAR *ret = NULL;
36 if (str)
38 size_t size;
40 size = (lstrlenW(str)+1)*sizeof(WCHAR);
41 ret = heap_alloc(size);
42 if (ret)
43 memcpy(ret, str, size);
46 return ret;
49 struct error_info
51 IErrorInfo IErrorInfo_iface;
52 ICreateErrorInfo ICreateErrorInfo_iface;
53 ISupportErrorInfo ISupportErrorInfo_iface;
54 LONG refcount;
56 GUID guid;
57 WCHAR *source;
58 WCHAR *description;
59 WCHAR *help_file;
60 DWORD help_context;
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);
84 *obj = NULL;
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;
99 if (*obj)
101 IUnknown_AddRef((IUnknown *)*obj);
102 return S_OK;
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);
116 return 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);
126 if (!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);
134 return refcount;
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;
145 return S_OK;
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);
154 if (!source)
155 return E_INVALIDARG;
156 *source = SysAllocString(error_info->source);
157 return S_OK;
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);
166 if (!description)
167 return E_INVALIDARG;
168 *description = SysAllocString(error_info->description);
169 return S_OK;
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);
178 if (!helpfile)
179 return E_INVALIDARG;
180 *helpfile = SysAllocString(error_info->help_file);
181 return S_OK;
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);
190 if (!help_context)
191 return E_INVALIDARG;
192 *help_context = error_info->help_context;
194 return S_OK;
197 static const IErrorInfoVtbl errorinfo_vtbl =
199 errorinfo_QueryInterface,
200 errorinfo_AddRef,
201 errorinfo_Release,
202 errorinfo_GetGUID,
203 errorinfo_GetSource,
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;
235 return S_OK;
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);
247 return S_OK;
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);
259 return S_OK;
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);
271 return S_OK;
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;
282 return S_OK;
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;
339 TRACE("%p.\n", ret);
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;
357 return S_OK;
360 /***********************************************************************
361 * GetErrorInfo (combase.@)
363 HRESULT WINAPI GetErrorInfo(ULONG reserved, IErrorInfo **error_info)
365 struct tlsdata *tlsdata;
366 HRESULT hr;
368 TRACE("%u, %p\n", reserved, error_info);
370 if (reserved || !error_info)
371 return E_INVALIDARG;
373 if (FAILED(hr = com_get_tlsdata(&tlsdata)))
374 return hr;
376 if (!tlsdata->errorinfo)
378 *error_info = NULL;
379 return S_FALSE;
382 *error_info = tlsdata->errorinfo;
383 tlsdata->errorinfo = NULL;
385 return S_OK;
388 /***********************************************************************
389 * SetErrorInfo (combase.@)
391 HRESULT WINAPI SetErrorInfo(ULONG reserved, IErrorInfo *error_info)
393 struct tlsdata *tlsdata;
394 HRESULT hr;
396 TRACE("%u, %p\n", reserved, error_info);
398 if (reserved)
399 return E_INVALIDARG;
401 if (FAILED(hr = com_get_tlsdata(&tlsdata)))
402 return hr;
404 if (tlsdata->errorinfo)
405 IErrorInfo_Release(tlsdata->errorinfo);
407 tlsdata->errorinfo = error_info;
408 if (error_info)
409 IErrorInfo_AddRef(error_info);
411 return S_OK;