Module: wine Branch: master Commit: 275790c767aad404a9b680dc783bc0578de158ee URL: http://source.winehq.org/git/wine.git/?a=commit;h=275790c767aad404a9b680dc78...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Wed Nov 16 16:48:35 2016 +0300
oledb32: Implement GetErrorParameters().
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/oledb32/errorinfo.c | 51 +++++++++++++++++++++++++++++++++++++++---- dlls/oledb32/tests/database.c | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 4 deletions(-)
diff --git a/dlls/oledb32/errorinfo.c b/dlls/oledb32/errorinfo.c index 02939ed..e1c3204 100644 --- a/dlls/oledb32/errorinfo.c +++ b/dlls/oledb32/errorinfo.c @@ -113,8 +113,16 @@ static ULONG WINAPI errorrecords_Release(IErrorInfo* iface)
for (i = 0; i < This->count; i++) { + DISPPARAMS *dispparams = &This->records[i].dispparams; + unsigned int j; + if (This->records[i].custom_error) IUnknown_Release(This->records[i].custom_error); + + for (j = 0; j < dispparams->cArgs && dispparams->rgvarg; j++) + VariantClear(&dispparams->rgvarg[i]); + CoTaskMemFree(dispparams->rgvarg); + CoTaskMemFree(dispparams->rgdispidNamedArgs); } heap_free(This->records); heap_free(This); @@ -222,11 +230,43 @@ static ULONG WINAPI WINAPI errorrec_Release(IErrorRecords *iface) return IErrorInfo_Release(&This->IErrorInfo_iface); }
+static HRESULT dup_dispparams(DISPPARAMS *src, DISPPARAMS *dest) +{ + unsigned int i; + + if (!src) + { + memset(dest, 0, sizeof(*dest)); + return S_OK; + } + + *dest = *src; + + if (src->cArgs) + { + dest->rgvarg = CoTaskMemAlloc(dest->cArgs * sizeof(*dest->rgvarg)); + for (i = 0; i < src->cArgs; i++) + { + VariantInit(&dest->rgvarg[i]); + VariantCopy(&dest->rgvarg[i], &src->rgvarg[i]); + } + } + + if (src->cNamedArgs) + { + dest->rgdispidNamedArgs = CoTaskMemAlloc(dest->cNamedArgs * sizeof(*dest->rgdispidNamedArgs)); + memcpy(dest->rgdispidNamedArgs, src->rgdispidNamedArgs, dest->cNamedArgs * sizeof(*dest->rgdispidNamedArgs)); + } + + return S_OK; +} + static HRESULT WINAPI errorrec_AddErrorRecord(IErrorRecords *iface, ERRORINFO *pErrorInfo, DWORD dwLookupID, DISPPARAMS *pdispparams, IUnknown *punkCustomError, DWORD dwDynamicErrorID) { errorrecords *This = impl_from_IErrorRecords(iface); struct ErrorEntry *entry; + HRESULT hr;
TRACE("(%p)->(%p %d %p %p %d)\n", This, pErrorInfo, dwLookupID, pdispparams, punkCustomError, dwDynamicErrorID);
@@ -255,8 +295,10 @@ static HRESULT WINAPI errorrec_AddErrorRecord(IErrorRecords *iface, ERRORINFO *p
entry = This->records + This->count; entry->info = *pErrorInfo; - if(pdispparams) - entry->dispparams = *pdispparams; + + if (FAILED(hr = dup_dispparams(pdispparams, &entry->dispparams))) + return hr; + entry->custom_error = punkCustomError; if (entry->custom_error) IUnknown_AddRef(entry->custom_error); @@ -326,7 +368,7 @@ static HRESULT WINAPI errorrec_GetErrorParameters(IErrorRecords *iface, ULONG in { errorrecords *This = impl_from_IErrorRecords(iface);
- FIXME("(%p)->(%u %p)\n", This, index, pdispparams); + TRACE("(%p)->(%u %p)\n", This, index, pdispparams);
if (!pdispparams) return E_INVALIDARG; @@ -334,7 +376,8 @@ static HRESULT WINAPI errorrec_GetErrorParameters(IErrorRecords *iface, ULONG in if (index >= This->count) return DB_E_BADRECORDNUM;
- return E_NOTIMPL; + index = This->count - index - 1; + return dup_dispparams(&This->records[index].dispparams, pdispparams); }
static HRESULT WINAPI errorrec_GetRecordCount(IErrorRecords *iface, ULONG *count) diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c index b45ef4d..44a2561 100644 --- a/dlls/oledb32/tests/database.c +++ b/dlls/oledb32/tests/database.c @@ -314,6 +314,16 @@ static void test_database(void) test_GetDataSource2(extended_prop); }
+static void free_dispparams(DISPPARAMS *params) +{ + unsigned int i; + + for (i = 0; i < params->cArgs && params->rgvarg; i++) + VariantClear(¶ms->rgvarg[i]); + CoTaskMemFree(params->rgvarg); + CoTaskMemFree(params->rgdispidNamedArgs); +} + static void test_errorinfo(void) { ICreateErrorInfo *createerror; @@ -322,8 +332,10 @@ static void test_errorinfo(void) IErrorRecords *errrecs; IUnknown *unk = NULL, *unk2; DISPPARAMS dispparams; + DISPID dispid; DWORD context; ULONG cnt = 0; + VARIANT arg; HRESULT hr; GUID guid; BSTR str; @@ -437,6 +449,42 @@ static void test_errorinfo(void) ok(hr == S_OK, "got %08x\n", hr); ok(info3.dwMinor == 2, "expected 2 got %d\n", info3.dwMinor);
+ hr = IErrorRecords_GetErrorParameters(errrecs, 0, NULL); + ok(hr == E_INVALIDARG, "got %08x\n", hr); + + memset(&dispparams, 0xcc, sizeof(dispparams)); + hr = IErrorRecords_GetErrorParameters(errrecs, 0, &dispparams); + ok(hr == S_OK, "got %08x\n", hr); + ok(dispparams.rgvarg == NULL, "Got arguments %p\n", dispparams.rgvarg); + ok(dispparams.rgdispidNamedArgs == NULL, "Got named arguments %p\n", dispparams.rgdispidNamedArgs); + ok(dispparams.cArgs == 0, "Got argument count %u\n", dispparams.cArgs); + ok(dispparams.cNamedArgs == 0, "Got named argument count %u\n", dispparams.cNamedArgs); + + V_VT(&arg) = VT_BSTR; + V_BSTR(&arg) = SysAllocStringLen(NULL, 0); + dispid = 0x123; + + dispparams.rgvarg = &arg; + dispparams.cArgs = 1; + dispparams.rgdispidNamedArgs = &dispid; + dispparams.cNamedArgs = 1; + hr = IErrorRecords_AddErrorRecord(errrecs, &info2, 0, &dispparams, NULL, 0); + ok(hr == S_OK, "got %08x\n", hr); + + memset(&dispparams, 0, sizeof(dispparams)); + hr = IErrorRecords_GetErrorParameters(errrecs, 0, &dispparams); + ok(hr == S_OK, "got %08x\n", hr); + + ok(V_VT(&dispparams.rgvarg[0]) == VT_BSTR, "Got arg type %d\n", V_VT(&dispparams.rgvarg[0])); + ok(V_BSTR(&dispparams.rgvarg[0]) != V_BSTR(&arg), "Got arg bstr %d\n", V_VT(&dispparams.rgvarg[0])); + + ok(dispparams.rgdispidNamedArgs[0] == 0x123, "Got named argument %d\n", dispparams.rgdispidNamedArgs[0]); + ok(dispparams.cArgs == 1, "Got argument count %u\n", dispparams.cArgs); + ok(dispparams.cNamedArgs == 1, "Got named argument count %u\n", dispparams.cNamedArgs); + + free_dispparams(&dispparams); + VariantClear(&arg); + IErrorRecords_Release(errrecs); IUnknown_Release(unk); }