d3dcompiler: Allow D3DCompile2() to succeed with null output shader blob pointer.
[wine.git] / dlls / combase / errorinfo.c
blob9383e8d5a7215b09269b627f83f7d5a16681c896
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
22 #define WINOLEAUTAPI
24 #include "oleauto.h"
26 #include "combase_private.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(ole);
32 struct error_info
34 IErrorInfo IErrorInfo_iface;
35 ICreateErrorInfo ICreateErrorInfo_iface;
36 ISupportErrorInfo ISupportErrorInfo_iface;
37 LONG refcount;
39 GUID guid;
40 WCHAR *source;
41 WCHAR *description;
42 WCHAR *help_file;
43 DWORD help_context;
46 static struct error_info *impl_from_IErrorInfo(IErrorInfo *iface)
48 return CONTAINING_RECORD(iface, struct error_info, IErrorInfo_iface);
51 static struct error_info *impl_from_ICreateErrorInfo(ICreateErrorInfo *iface)
53 return CONTAINING_RECORD(iface, struct error_info, ICreateErrorInfo_iface);
56 static struct error_info *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
58 return CONTAINING_RECORD(iface, struct error_info, ISupportErrorInfo_iface);
61 static HRESULT WINAPI errorinfo_QueryInterface(IErrorInfo *iface, REFIID riid, void **obj)
63 struct error_info *error_info = impl_from_IErrorInfo(iface);
65 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
67 *obj = NULL;
69 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IErrorInfo))
71 *obj = &error_info->IErrorInfo_iface;
73 else if (IsEqualIID(riid, &IID_ICreateErrorInfo))
75 *obj = &error_info->ICreateErrorInfo_iface;
77 else if (IsEqualIID(riid, &IID_ISupportErrorInfo))
79 *obj = &error_info->ISupportErrorInfo_iface;
82 if (*obj)
84 IUnknown_AddRef((IUnknown *)*obj);
85 return S_OK;
88 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
89 return E_NOINTERFACE;
92 static ULONG WINAPI errorinfo_AddRef(IErrorInfo *iface)
94 struct error_info *error_info = impl_from_IErrorInfo(iface);
95 ULONG refcount = InterlockedIncrement(&error_info->refcount);
97 TRACE("%p, refcount %lu.\n", iface, refcount);
99 return refcount;
102 static ULONG WINAPI errorinfo_Release(IErrorInfo *iface)
104 struct error_info *error_info = impl_from_IErrorInfo(iface);
105 ULONG refcount = InterlockedDecrement(&error_info->refcount);
107 TRACE("%p, refcount %lu.\n", iface, refcount);
109 if (!refcount)
111 free(error_info->source);
112 free(error_info->description);
113 free(error_info->help_file);
114 free(error_info);
117 return refcount;
120 static HRESULT WINAPI errorinfo_GetGUID(IErrorInfo *iface, GUID *guid)
122 struct error_info *error_info = impl_from_IErrorInfo(iface);
124 TRACE("%p, %p.\n", iface, guid);
126 if (!guid) return E_INVALIDARG;
127 *guid = error_info->guid;
128 return S_OK;
131 static HRESULT WINAPI errorinfo_GetSource(IErrorInfo* iface, BSTR *source)
133 struct error_info *error_info = impl_from_IErrorInfo(iface);
135 TRACE("%p, %p.\n", iface, source);
137 if (!source)
138 return E_INVALIDARG;
139 *source = SysAllocString(error_info->source);
140 return S_OK;
143 static HRESULT WINAPI errorinfo_GetDescription(IErrorInfo *iface, BSTR *description)
145 struct error_info *error_info = impl_from_IErrorInfo(iface);
147 TRACE("%p, %p.\n", iface, description);
149 if (!description)
150 return E_INVALIDARG;
151 *description = SysAllocString(error_info->description);
152 return S_OK;
155 static HRESULT WINAPI errorinfo_GetHelpFile(IErrorInfo *iface, BSTR *helpfile)
157 struct error_info *error_info = impl_from_IErrorInfo(iface);
159 TRACE("%p, %p.\n", iface, helpfile);
161 if (!helpfile)
162 return E_INVALIDARG;
163 *helpfile = SysAllocString(error_info->help_file);
164 return S_OK;
167 static HRESULT WINAPI errorinfo_GetHelpContext(IErrorInfo *iface, DWORD *help_context)
169 struct error_info *error_info = impl_from_IErrorInfo(iface);
171 TRACE("%p, %p.\n", iface, help_context);
173 if (!help_context)
174 return E_INVALIDARG;
175 *help_context = error_info->help_context;
177 return S_OK;
180 static const IErrorInfoVtbl errorinfo_vtbl =
182 errorinfo_QueryInterface,
183 errorinfo_AddRef,
184 errorinfo_Release,
185 errorinfo_GetGUID,
186 errorinfo_GetSource,
187 errorinfo_GetDescription,
188 errorinfo_GetHelpFile,
189 errorinfo_GetHelpContext
192 static HRESULT WINAPI create_errorinfo_QueryInterface(ICreateErrorInfo *iface, REFIID riid, void **obj)
194 struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
195 return IErrorInfo_QueryInterface(&error_info->IErrorInfo_iface, riid, obj);
198 static ULONG WINAPI create_errorinfo_AddRef(ICreateErrorInfo *iface)
200 struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
201 return IErrorInfo_AddRef(&error_info->IErrorInfo_iface);
204 static ULONG WINAPI create_errorinfo_Release(ICreateErrorInfo *iface)
206 struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
207 return IErrorInfo_Release(&error_info->IErrorInfo_iface);
210 static HRESULT WINAPI create_errorinfo_SetGUID(ICreateErrorInfo *iface, REFGUID guid)
212 struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
214 TRACE("%p, %s.\n", iface, debugstr_guid(guid));
216 error_info->guid = *guid;
218 return S_OK;
221 static HRESULT WINAPI create_errorinfo_SetSource(ICreateErrorInfo *iface, LPOLESTR source)
223 struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
225 TRACE("%p, %s.\n", iface, debugstr_w(source));
227 free(error_info->source);
228 error_info->source = wcsdup(source);
230 return S_OK;
233 static HRESULT WINAPI create_errorinfo_SetDescription(ICreateErrorInfo *iface, LPOLESTR description)
235 struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
237 TRACE("%p, %s.\n", iface, debugstr_w(description));
239 free(error_info->description);
240 error_info->description = wcsdup(description);
242 return S_OK;
245 static HRESULT WINAPI create_errorinfo_SetHelpFile(ICreateErrorInfo *iface, LPOLESTR helpfile)
247 struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
249 TRACE("%p, %s.\n", iface, debugstr_w(helpfile));
251 free(error_info->help_file);
252 error_info->help_file = wcsdup(helpfile);
254 return S_OK;
257 static HRESULT WINAPI create_errorinfo_SetHelpContext(ICreateErrorInfo *iface, DWORD help_context)
259 struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
261 TRACE("%p, %#lx.\n", iface, help_context);
263 error_info->help_context = help_context;
265 return S_OK;
268 static const ICreateErrorInfoVtbl create_errorinfo_vtbl =
270 create_errorinfo_QueryInterface,
271 create_errorinfo_AddRef,
272 create_errorinfo_Release,
273 create_errorinfo_SetGUID,
274 create_errorinfo_SetSource,
275 create_errorinfo_SetDescription,
276 create_errorinfo_SetHelpFile,
277 create_errorinfo_SetHelpContext
280 static HRESULT WINAPI support_errorinfo_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void **obj)
282 struct error_info *error_info = impl_from_ISupportErrorInfo(iface);
283 return IErrorInfo_QueryInterface(&error_info->IErrorInfo_iface, riid, obj);
286 static ULONG WINAPI support_errorinfo_AddRef(ISupportErrorInfo *iface)
288 struct error_info *error_info = impl_from_ISupportErrorInfo(iface);
289 return IErrorInfo_AddRef(&error_info->IErrorInfo_iface);
292 static ULONG WINAPI support_errorinfo_Release(ISupportErrorInfo *iface)
294 struct error_info *error_info = impl_from_ISupportErrorInfo(iface);
295 return IErrorInfo_Release(&error_info->IErrorInfo_iface);
298 static HRESULT WINAPI support_errorinfo_InterfaceSupportsErrorInfo(ISupportErrorInfo *iface, REFIID riid)
300 struct error_info *error_info = impl_from_ISupportErrorInfo(iface);
302 TRACE("%p, %s.\n", iface, debugstr_guid(riid));
304 return IsEqualIID(riid, &error_info->guid) ? S_OK : S_FALSE;
307 static const ISupportErrorInfoVtbl support_errorinfo_vtbl =
309 support_errorinfo_QueryInterface,
310 support_errorinfo_AddRef,
311 support_errorinfo_Release,
312 support_errorinfo_InterfaceSupportsErrorInfo
315 /***********************************************************************
316 * CreateErrorInfo (combase.@)
318 HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **ret)
320 struct error_info *error_info;
322 TRACE("%p.\n", ret);
324 if (!ret) return E_INVALIDARG;
326 if (!(error_info = malloc(sizeof(*error_info))))
327 return E_OUTOFMEMORY;
329 error_info->IErrorInfo_iface.lpVtbl = &errorinfo_vtbl;
330 error_info->ICreateErrorInfo_iface.lpVtbl = &create_errorinfo_vtbl;
331 error_info->ISupportErrorInfo_iface.lpVtbl = &support_errorinfo_vtbl;
332 error_info->refcount = 1;
333 error_info->source = NULL;
334 error_info->description = NULL;
335 error_info->help_file = NULL;
336 error_info->help_context = 0;
338 *ret = &error_info->ICreateErrorInfo_iface;
340 return S_OK;
343 /***********************************************************************
344 * GetErrorInfo (combase.@)
346 HRESULT WINAPI GetErrorInfo(ULONG reserved, IErrorInfo **error_info)
348 struct tlsdata *tlsdata;
349 HRESULT hr;
351 TRACE("%lu, %p\n", reserved, error_info);
353 if (reserved || !error_info)
354 return E_INVALIDARG;
356 if (FAILED(hr = com_get_tlsdata(&tlsdata)))
357 return hr;
359 if (!tlsdata->errorinfo)
361 *error_info = NULL;
362 return S_FALSE;
365 *error_info = tlsdata->errorinfo;
366 tlsdata->errorinfo = NULL;
368 return S_OK;
371 /***********************************************************************
372 * SetErrorInfo (combase.@)
374 HRESULT WINAPI SetErrorInfo(ULONG reserved, IErrorInfo *error_info)
376 struct tlsdata *tlsdata;
377 HRESULT hr;
379 TRACE("%lu, %p\n", reserved, error_info);
381 if (reserved)
382 return E_INVALIDARG;
384 if (FAILED(hr = com_get_tlsdata(&tlsdata)))
385 return hr;
387 if (tlsdata->errorinfo)
388 IErrorInfo_Release(tlsdata->errorinfo);
390 tlsdata->errorinfo = error_info;
391 if (error_info)
392 IErrorInfo_AddRef(error_info);
394 return S_OK;