3 * Copyright 2013 Alistair Leslie-Hughes
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "oledb_private.h"
34 #include "wine/unicode.h"
35 #include "wine/list.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(oledb
);
45 DISPPARAMS dispparams
;
50 typedef struct ErrorInfoImpl
52 IErrorInfo IErrorInfo_iface
;
53 IErrorRecords IErrorRecords_iface
;
65 static inline ErrorInfoImpl
*impl_from_IErrorInfo( IErrorInfo
*iface
)
67 return CONTAINING_RECORD(iface
, ErrorInfoImpl
, IErrorInfo_iface
);
70 static inline ErrorInfoImpl
*impl_from_IErrorRecords( IErrorRecords
*iface
)
72 return CONTAINING_RECORD(iface
, ErrorInfoImpl
, IErrorRecords_iface
);
75 static HRESULT WINAPI
IErrorInfoImpl_QueryInterface(IErrorInfo
* iface
, REFIID riid
, void **ppvoid
)
77 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
78 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
),ppvoid
);
82 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IErrorInfo
))
84 *ppvoid
= &This
->IErrorInfo_iface
;
86 else if (IsEqualIID(riid
, &IID_IErrorRecords
))
88 *ppvoid
= &This
->IErrorRecords_iface
;
93 IUnknown_AddRef( (IUnknown
*)*ppvoid
);
97 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
101 static ULONG WINAPI
IErrorInfoImpl_AddRef(IErrorInfo
* iface
)
103 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
104 TRACE("(%p)->%u\n",This
,This
->ref
);
105 return InterlockedIncrement(&This
->ref
);
108 static ULONG WINAPI
IErrorInfoImpl_Release(IErrorInfo
* iface
)
110 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
111 ULONG ref
= InterlockedDecrement(&This
->ref
);
112 struct ErrorEntry
*cursor
, *cursor2
;
114 TRACE("(%p)->%u\n",This
,ref
+1);
118 SysFreeString(This
->source
);
119 SysFreeString(This
->description
);
120 SysFreeString(This
->help_file
);
122 LIST_FOR_EACH_ENTRY_SAFE(cursor
, cursor2
, &This
->errors
, struct ErrorEntry
, entry
)
124 list_remove(&cursor
->entry
);
126 IUnknown_Release(cursor
->unknown
);
135 static HRESULT WINAPI
IErrorInfoImpl_GetGUID(IErrorInfo
* iface
, GUID
* pGUID
)
137 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
139 TRACE("(%p)\n",This
);
144 *pGUID
= This
->m_Guid
;
149 static HRESULT WINAPI
IErrorInfoImpl_GetSource(IErrorInfo
* iface
, BSTR
*pBstrSource
)
151 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
153 TRACE("(%p)->(%p)\n",This
, pBstrSource
);
155 if (pBstrSource
== NULL
)
158 *pBstrSource
= SysAllocString(This
->source
);
163 static HRESULT WINAPI
IErrorInfoImpl_GetDescription(IErrorInfo
* iface
, BSTR
*pBstrDescription
)
165 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
167 TRACE("(%p)->(%p)\n",This
, pBstrDescription
);
169 if (pBstrDescription
== NULL
)
172 *pBstrDescription
= SysAllocString(This
->description
);
177 static HRESULT WINAPI
IErrorInfoImpl_GetHelpFile(IErrorInfo
* iface
, BSTR
*pBstrHelpFile
)
179 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
181 TRACE("(%p)->(%p)\n",This
, pBstrHelpFile
);
183 if (pBstrHelpFile
== NULL
)
186 *pBstrHelpFile
= SysAllocString(This
->help_file
);
191 static HRESULT WINAPI
IErrorInfoImpl_GetHelpContext(IErrorInfo
* iface
, DWORD
*pdwHelpContext
)
193 ErrorInfoImpl
*This
= impl_from_IErrorInfo(iface
);
195 TRACE("(%p)->(%p)\n",This
, pdwHelpContext
);
197 if (pdwHelpContext
== NULL
)
200 *pdwHelpContext
= This
->help_context
;
205 static const IErrorInfoVtbl ErrorInfoVtbl
=
207 IErrorInfoImpl_QueryInterface
,
208 IErrorInfoImpl_AddRef
,
209 IErrorInfoImpl_Release
,
210 IErrorInfoImpl_GetGUID
,
211 IErrorInfoImpl_GetSource
,
212 IErrorInfoImpl_GetDescription
,
213 IErrorInfoImpl_GetHelpFile
,
214 IErrorInfoImpl_GetHelpContext
217 static HRESULT WINAPI
errorrec_QueryInterface(IErrorRecords
*iface
, REFIID riid
, void **ppvObject
)
219 ErrorInfoImpl
*This
= impl_from_IErrorRecords(iface
);
220 return IErrorInfo_QueryInterface(&This
->IErrorInfo_iface
, riid
, ppvObject
);
223 static ULONG WINAPI WINAPI
errorrec_AddRef(IErrorRecords
*iface
)
225 ErrorInfoImpl
*This
= impl_from_IErrorRecords(iface
);
226 return IErrorInfo_AddRef(&This
->IErrorInfo_iface
);
229 static ULONG WINAPI WINAPI
errorrec_Release(IErrorRecords
*iface
)
231 ErrorInfoImpl
*This
= impl_from_IErrorRecords(iface
);
232 return IErrorInfo_Release(&This
->IErrorInfo_iface
);
235 static HRESULT WINAPI
errorrec_AddErrorRecord(IErrorRecords
*iface
, ERRORINFO
*pErrorInfo
,
236 DWORD dwLookupID
, DISPPARAMS
*pdispparams
, IUnknown
*punkCustomError
, DWORD dwDynamicErrorID
)
238 ErrorInfoImpl
*This
= impl_from_IErrorRecords(iface
);
239 struct ErrorEntry
*entry
;
241 TRACE("(%p)->(%p %d %p %p %d)\n", This
, pErrorInfo
, dwLookupID
, pdispparams
, punkCustomError
, dwDynamicErrorID
);
246 entry
= heap_alloc(sizeof(*entry
));
248 return E_OUTOFMEMORY
;
250 entry
->info
= *pErrorInfo
;
252 entry
->dispparams
= *pdispparams
;
253 entry
->unknown
= punkCustomError
;
255 IUnknown_AddRef(entry
->unknown
);
256 entry
->lookupID
= dwDynamicErrorID
;
258 list_add_head(&This
->errors
, &entry
->entry
);
263 static HRESULT WINAPI
errorrec_GetBasicErrorInfo(IErrorRecords
*iface
, ULONG ulRecordNum
,
264 ERRORINFO
*pErrorInfo
)
266 ErrorInfoImpl
*This
= impl_from_IErrorRecords(iface
);
268 FIXME("(%p)->(%d %p)\n", This
, ulRecordNum
, pErrorInfo
);
273 if(ulRecordNum
> list_count(&This
->errors
))
274 return DB_E_BADRECORDNUM
;
279 static HRESULT WINAPI
errorrec_GetCustomErrorObject(IErrorRecords
*iface
, ULONG ulRecordNum
,
280 REFIID riid
, IUnknown
**ppObject
)
282 ErrorInfoImpl
*This
= impl_from_IErrorRecords(iface
);
284 FIXME("(%p)->(%d %s, %p)\n", This
, ulRecordNum
, debugstr_guid(riid
), ppObject
);
291 if(ulRecordNum
> list_count(&This
->errors
))
292 return DB_E_BADRECORDNUM
;
297 static HRESULT WINAPI
errorrec_GetErrorInfo(IErrorRecords
*iface
, ULONG ulRecordNum
,
298 LCID lcid
, IErrorInfo
**ppErrorInfo
)
300 ErrorInfoImpl
*This
= impl_from_IErrorRecords(iface
);
302 FIXME("(%p)->(%d %d, %p)\n", This
, ulRecordNum
, lcid
, ppErrorInfo
);
307 if(ulRecordNum
> list_count(&This
->errors
))
308 return DB_E_BADRECORDNUM
;
313 static HRESULT WINAPI
errorrec_GetErrorParameters(IErrorRecords
*iface
, ULONG ulRecordNum
,
314 DISPPARAMS
*pdispparams
)
316 ErrorInfoImpl
*This
= impl_from_IErrorRecords(iface
);
318 FIXME("(%p)->(%d %p)\n", This
, ulRecordNum
, pdispparams
);
323 if(ulRecordNum
> list_count(&This
->errors
))
324 return DB_E_BADRECORDNUM
;
329 static HRESULT WINAPI
errorrec_GetRecordCount(IErrorRecords
*iface
, ULONG
*records
)
331 ErrorInfoImpl
*This
= impl_from_IErrorRecords(iface
);
333 TRACE("(%p)->(%p)\n", This
, records
);
338 *records
= list_count(&This
->errors
);
340 TRACE("<--(%d)\n", *records
);
345 static const IErrorRecordsVtbl ErrorRecordsVtbl
=
347 errorrec_QueryInterface
,
350 errorrec_AddErrorRecord
,
351 errorrec_GetBasicErrorInfo
,
352 errorrec_GetCustomErrorObject
,
353 errorrec_GetErrorInfo
,
354 errorrec_GetErrorParameters
,
355 errorrec_GetRecordCount
358 HRESULT
create_error_info(IUnknown
*outer
, void **obj
)
362 TRACE("(%p, %p)\n", outer
, obj
);
366 if(outer
) return CLASS_E_NOAGGREGATION
;
368 This
= heap_alloc(sizeof(*This
));
369 if(!This
) return E_OUTOFMEMORY
;
371 This
->IErrorInfo_iface
.lpVtbl
= &ErrorInfoVtbl
;
372 This
->IErrorRecords_iface
.lpVtbl
= &ErrorRecordsVtbl
;
375 This
->description
= NULL
;
376 This
->help_file
= NULL
;
377 This
->help_context
= 0;
379 list_init(&This
->errors
);
381 *obj
= &This
->IErrorInfo_iface
;