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(&params->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