Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/combase/errorinfo.c
4393 views
1
/*
2
* ErrorInfo API
3
*
4
* Copyright 2000 Patrik Stridvall, Juergen Schmied
5
*
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.
10
*
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.
15
*
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
19
*/
20
21
#define COBJMACROS
22
#define WINOLEAUTAPI
23
24
#include "oleauto.h"
25
26
#include "combase_private.h"
27
28
#include "wine/debug.h"
29
30
WINE_DEFAULT_DEBUG_CHANNEL(ole);
31
32
struct error_info
33
{
34
IErrorInfo IErrorInfo_iface;
35
ICreateErrorInfo ICreateErrorInfo_iface;
36
ISupportErrorInfo ISupportErrorInfo_iface;
37
LONG refcount;
38
39
GUID guid;
40
WCHAR *source;
41
WCHAR *description;
42
WCHAR *help_file;
43
DWORD help_context;
44
};
45
46
static struct error_info *impl_from_IErrorInfo(IErrorInfo *iface)
47
{
48
return CONTAINING_RECORD(iface, struct error_info, IErrorInfo_iface);
49
}
50
51
static struct error_info *impl_from_ICreateErrorInfo(ICreateErrorInfo *iface)
52
{
53
return CONTAINING_RECORD(iface, struct error_info, ICreateErrorInfo_iface);
54
}
55
56
static struct error_info *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
57
{
58
return CONTAINING_RECORD(iface, struct error_info, ISupportErrorInfo_iface);
59
}
60
61
static HRESULT WINAPI errorinfo_QueryInterface(IErrorInfo *iface, REFIID riid, void **obj)
62
{
63
struct error_info *error_info = impl_from_IErrorInfo(iface);
64
65
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
66
67
*obj = NULL;
68
69
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IErrorInfo))
70
{
71
*obj = &error_info->IErrorInfo_iface;
72
}
73
else if (IsEqualIID(riid, &IID_ICreateErrorInfo))
74
{
75
*obj = &error_info->ICreateErrorInfo_iface;
76
}
77
else if (IsEqualIID(riid, &IID_ISupportErrorInfo))
78
{
79
*obj = &error_info->ISupportErrorInfo_iface;
80
}
81
82
if (*obj)
83
{
84
IUnknown_AddRef((IUnknown *)*obj);
85
return S_OK;
86
}
87
88
WARN("Unsupported interface %s.\n", debugstr_guid(riid));
89
return E_NOINTERFACE;
90
}
91
92
static ULONG WINAPI errorinfo_AddRef(IErrorInfo *iface)
93
{
94
struct error_info *error_info = impl_from_IErrorInfo(iface);
95
ULONG refcount = InterlockedIncrement(&error_info->refcount);
96
97
TRACE("%p, refcount %lu.\n", iface, refcount);
98
99
return refcount;
100
}
101
102
static ULONG WINAPI errorinfo_Release(IErrorInfo *iface)
103
{
104
struct error_info *error_info = impl_from_IErrorInfo(iface);
105
ULONG refcount = InterlockedDecrement(&error_info->refcount);
106
107
TRACE("%p, refcount %lu.\n", iface, refcount);
108
109
if (!refcount)
110
{
111
free(error_info->source);
112
free(error_info->description);
113
free(error_info->help_file);
114
free(error_info);
115
}
116
117
return refcount;
118
}
119
120
static HRESULT WINAPI errorinfo_GetGUID(IErrorInfo *iface, GUID *guid)
121
{
122
struct error_info *error_info = impl_from_IErrorInfo(iface);
123
124
TRACE("%p, %p.\n", iface, guid);
125
126
if (!guid) return E_INVALIDARG;
127
*guid = error_info->guid;
128
return S_OK;
129
}
130
131
static HRESULT WINAPI errorinfo_GetSource(IErrorInfo* iface, BSTR *source)
132
{
133
struct error_info *error_info = impl_from_IErrorInfo(iface);
134
135
TRACE("%p, %p.\n", iface, source);
136
137
if (!source)
138
return E_INVALIDARG;
139
*source = SysAllocString(error_info->source);
140
return S_OK;
141
}
142
143
static HRESULT WINAPI errorinfo_GetDescription(IErrorInfo *iface, BSTR *description)
144
{
145
struct error_info *error_info = impl_from_IErrorInfo(iface);
146
147
TRACE("%p, %p.\n", iface, description);
148
149
if (!description)
150
return E_INVALIDARG;
151
*description = SysAllocString(error_info->description);
152
return S_OK;
153
}
154
155
static HRESULT WINAPI errorinfo_GetHelpFile(IErrorInfo *iface, BSTR *helpfile)
156
{
157
struct error_info *error_info = impl_from_IErrorInfo(iface);
158
159
TRACE("%p, %p.\n", iface, helpfile);
160
161
if (!helpfile)
162
return E_INVALIDARG;
163
*helpfile = SysAllocString(error_info->help_file);
164
return S_OK;
165
}
166
167
static HRESULT WINAPI errorinfo_GetHelpContext(IErrorInfo *iface, DWORD *help_context)
168
{
169
struct error_info *error_info = impl_from_IErrorInfo(iface);
170
171
TRACE("%p, %p.\n", iface, help_context);
172
173
if (!help_context)
174
return E_INVALIDARG;
175
*help_context = error_info->help_context;
176
177
return S_OK;
178
}
179
180
static const IErrorInfoVtbl errorinfo_vtbl =
181
{
182
errorinfo_QueryInterface,
183
errorinfo_AddRef,
184
errorinfo_Release,
185
errorinfo_GetGUID,
186
errorinfo_GetSource,
187
errorinfo_GetDescription,
188
errorinfo_GetHelpFile,
189
errorinfo_GetHelpContext
190
};
191
192
static HRESULT WINAPI create_errorinfo_QueryInterface(ICreateErrorInfo *iface, REFIID riid, void **obj)
193
{
194
struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
195
return IErrorInfo_QueryInterface(&error_info->IErrorInfo_iface, riid, obj);
196
}
197
198
static ULONG WINAPI create_errorinfo_AddRef(ICreateErrorInfo *iface)
199
{
200
struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
201
return IErrorInfo_AddRef(&error_info->IErrorInfo_iface);
202
}
203
204
static ULONG WINAPI create_errorinfo_Release(ICreateErrorInfo *iface)
205
{
206
struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
207
return IErrorInfo_Release(&error_info->IErrorInfo_iface);
208
}
209
210
static HRESULT WINAPI create_errorinfo_SetGUID(ICreateErrorInfo *iface, REFGUID guid)
211
{
212
struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
213
214
TRACE("%p, %s.\n", iface, debugstr_guid(guid));
215
216
error_info->guid = *guid;
217
218
return S_OK;
219
}
220
221
static HRESULT WINAPI create_errorinfo_SetSource(ICreateErrorInfo *iface, LPOLESTR source)
222
{
223
struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
224
225
TRACE("%p, %s.\n", iface, debugstr_w(source));
226
227
free(error_info->source);
228
error_info->source = wcsdup(source);
229
230
return S_OK;
231
}
232
233
static HRESULT WINAPI create_errorinfo_SetDescription(ICreateErrorInfo *iface, LPOLESTR description)
234
{
235
struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
236
237
TRACE("%p, %s.\n", iface, debugstr_w(description));
238
239
free(error_info->description);
240
error_info->description = wcsdup(description);
241
242
return S_OK;
243
}
244
245
static HRESULT WINAPI create_errorinfo_SetHelpFile(ICreateErrorInfo *iface, LPOLESTR helpfile)
246
{
247
struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
248
249
TRACE("%p, %s.\n", iface, debugstr_w(helpfile));
250
251
free(error_info->help_file);
252
error_info->help_file = wcsdup(helpfile);
253
254
return S_OK;
255
}
256
257
static HRESULT WINAPI create_errorinfo_SetHelpContext(ICreateErrorInfo *iface, DWORD help_context)
258
{
259
struct error_info *error_info = impl_from_ICreateErrorInfo(iface);
260
261
TRACE("%p, %#lx.\n", iface, help_context);
262
263
error_info->help_context = help_context;
264
265
return S_OK;
266
}
267
268
static const ICreateErrorInfoVtbl create_errorinfo_vtbl =
269
{
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
278
};
279
280
static HRESULT WINAPI support_errorinfo_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void **obj)
281
{
282
struct error_info *error_info = impl_from_ISupportErrorInfo(iface);
283
return IErrorInfo_QueryInterface(&error_info->IErrorInfo_iface, riid, obj);
284
}
285
286
static ULONG WINAPI support_errorinfo_AddRef(ISupportErrorInfo *iface)
287
{
288
struct error_info *error_info = impl_from_ISupportErrorInfo(iface);
289
return IErrorInfo_AddRef(&error_info->IErrorInfo_iface);
290
}
291
292
static ULONG WINAPI support_errorinfo_Release(ISupportErrorInfo *iface)
293
{
294
struct error_info *error_info = impl_from_ISupportErrorInfo(iface);
295
return IErrorInfo_Release(&error_info->IErrorInfo_iface);
296
}
297
298
static HRESULT WINAPI support_errorinfo_InterfaceSupportsErrorInfo(ISupportErrorInfo *iface, REFIID riid)
299
{
300
struct error_info *error_info = impl_from_ISupportErrorInfo(iface);
301
302
TRACE("%p, %s.\n", iface, debugstr_guid(riid));
303
304
return IsEqualIID(riid, &error_info->guid) ? S_OK : S_FALSE;
305
}
306
307
static const ISupportErrorInfoVtbl support_errorinfo_vtbl =
308
{
309
support_errorinfo_QueryInterface,
310
support_errorinfo_AddRef,
311
support_errorinfo_Release,
312
support_errorinfo_InterfaceSupportsErrorInfo
313
};
314
315
/***********************************************************************
316
* CreateErrorInfo (combase.@)
317
*/
318
HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **ret)
319
{
320
struct error_info *error_info;
321
322
TRACE("%p.\n", ret);
323
324
if (!ret) return E_INVALIDARG;
325
326
if (!(error_info = malloc(sizeof(*error_info))))
327
return E_OUTOFMEMORY;
328
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;
337
338
*ret = &error_info->ICreateErrorInfo_iface;
339
340
return S_OK;
341
}
342
343
/***********************************************************************
344
* GetErrorInfo (combase.@)
345
*/
346
HRESULT WINAPI GetErrorInfo(ULONG reserved, IErrorInfo **error_info)
347
{
348
struct tlsdata *tlsdata;
349
HRESULT hr;
350
351
TRACE("%lu, %p\n", reserved, error_info);
352
353
if (reserved || !error_info)
354
return E_INVALIDARG;
355
356
if (FAILED(hr = com_get_tlsdata(&tlsdata)))
357
return hr;
358
359
if (!tlsdata->errorinfo)
360
{
361
*error_info = NULL;
362
return S_FALSE;
363
}
364
365
*error_info = tlsdata->errorinfo;
366
tlsdata->errorinfo = NULL;
367
368
return S_OK;
369
}
370
371
/***********************************************************************
372
* SetErrorInfo (combase.@)
373
*/
374
HRESULT WINAPI SetErrorInfo(ULONG reserved, IErrorInfo *error_info)
375
{
376
struct tlsdata *tlsdata;
377
HRESULT hr;
378
379
TRACE("%lu, %p\n", reserved, error_info);
380
381
if (reserved)
382
return E_INVALIDARG;
383
384
if (FAILED(hr = com_get_tlsdata(&tlsdata)))
385
return hr;
386
387
if (tlsdata->errorinfo)
388
IErrorInfo_Release(tlsdata->errorinfo);
389
390
tlsdata->errorinfo = error_info;
391
if (error_info)
392
IErrorInfo_AddRef(error_info);
393
394
return S_OK;
395
}
396
397