Nikolay Sivov : oledb32: Implement GetErrorParameters().
Alexandre Julliard
julliard at winehq.org
Wed Nov 16 17:39:19 CST 2016
Module: wine
Branch: master
Commit: 275790c767aad404a9b680dc783bc0578de158ee
URL: http://source.winehq.org/git/wine.git/?a=commit;h=275790c767aad404a9b680dc783bc0578de158ee
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Nov 16 16:48:35 2016 +0300
oledb32: Implement GetErrorParameters().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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);
}
More information about the wine-cvs
mailing list