Alistair Leslie-Hughes : msdasql: Implement IDBProperties GetProperties.

Alexandre Julliard julliard at winehq.org
Fri Nov 5 17:15:52 CDT 2021


Module: wine
Branch: master
Commit: 6e94e879947d9328aa3fbe8a7861bc2d5a464948
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6e94e879947d9328aa3fbe8a7861bc2d5a464948

Author: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Date:   Fri Nov  5 16:29:59 2021 +1100

msdasql: Implement IDBProperties GetProperties.

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msdasql/msdasql_main.c   | 76 +++++++++++++++++++++++++++++++++++++++++--
 dlls/msdasql/tests/provider.c | 57 ++++++++++++++++++++++++++++++--
 dlls/oledb32/tests/database.c |  4 +--
 3 files changed, 130 insertions(+), 7 deletions(-)

diff --git a/dlls/msdasql/msdasql_main.c b/dlls/msdasql/msdasql_main.c
index b8d68287e6a..d14f7957978 100644
--- a/dlls/msdasql/msdasql_main.c
+++ b/dlls/msdasql/msdasql_main.c
@@ -193,6 +193,12 @@ static const struct dbproperty dbproperties[] =
     { L"General Timeout",          DBPROP_INIT_GENERALTIMEOUT,             DBPROPOPTIONS_OPTIONAL, VT_I4 },
 };
 
+struct msdasql_prop
+{
+    VARTYPE id;
+    VARIANT value;
+};
+
 struct msdasql
 {
     IUnknown         MSDASQL_iface;
@@ -202,6 +208,7 @@ struct msdasql
     IPersist         IPersist_iface;
 
     LONG     ref;
+    struct msdasql_prop properties[14];
 };
 
 static inline struct msdasql *impl_from_IUnknown(IUnknown *iface)
@@ -324,10 +331,49 @@ static HRESULT WINAPI dbprops_GetProperties(IDBProperties *iface, ULONG cPropert
             const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertySets, DBPROPSET **prgPropertySets)
 {
     struct msdasql *provider = impl_from_IDBProperties(iface);
+    int i, j, k;
+    DBPROPSET *propset;
 
-    FIXME("(%p)->(%d %p %p %p)\n", provider, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);
+    TRACE("(%p)->(%d %p %p %p)\n", provider, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);
 
-    return E_NOTIMPL;
+    *pcPropertySets = 1;
+
+    if (cPropertyIDSets != 1)
+    {
+        FIXME("Currently only 1 property set supported.\n");
+        cPropertyIDSets = 1;
+    }
+
+    propset = CoTaskMemAlloc(cPropertyIDSets * sizeof(DBPROPSET));
+    propset->guidPropertySet = DBPROPSET_DBINIT;
+
+    for (i=0; i < cPropertyIDSets; i++)
+    {
+        TRACE("Property id %d (count %d, set %s)\n", i, rgPropertyIDSets[i].cPropertyIDs,
+                debugstr_guid(&rgPropertyIDSets[i].guidPropertySet));
+
+        propset->cProperties = rgPropertyIDSets[i].cPropertyIDs;
+        propset->rgProperties = CoTaskMemAlloc(propset->cProperties * sizeof(DBPROP));
+
+        for (j=0; j < propset->cProperties; j++)
+        {
+            propset->rgProperties[j].dwPropertyID = rgPropertyIDSets[i].rgPropertyIDs[j];
+
+            for(k = 0; k < ARRAY_SIZE(provider->properties); k++)
+            {
+                if (provider->properties[k].id == rgPropertyIDSets[i].rgPropertyIDs[j])
+                {
+                    V_VT(&propset->rgProperties[j].vValue) = VT_EMPTY;
+                    VariantCopy(&propset->rgProperties[j].vValue, &provider->properties[k].value);
+                    break;
+                }
+            }
+        }
+    }
+
+    *prgPropertySets = propset;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI dbprops_GetPropertyInfo(IDBProperties *iface, ULONG cPropertyIDSets,
@@ -531,6 +577,7 @@ static HRESULT create_msdasql_provider(REFIID riid, void **ppv)
 {
     struct msdasql *provider;
     HRESULT hr;
+    int i;
 
     provider = malloc(sizeof(struct msdasql));
     if (!provider)
@@ -543,6 +590,31 @@ static HRESULT create_msdasql_provider(REFIID riid, void **ppv)
     provider->IPersist_iface.lpVtbl = &persistVtbl;
     provider->ref = 1;
 
+    for(i=0; i < ARRAY_SIZE(dbproperties); i++)
+    {
+        provider->properties[i].id = dbproperties[i].id;
+        VariantInit(&provider->properties[i].value);
+
+        /* Only the follow are initialized to a value */
+        switch(dbproperties[i].id)
+        {
+            case DBPROP_INIT_PROMPT:
+                V_VT(&provider->properties[i].value) = dbproperties[i].type;
+                V_I2(&provider->properties[i].value) = 4;
+                break;
+            case DBPROP_INIT_LCID:
+                V_VT(&provider->properties[i].value) = dbproperties[i].type;
+                V_I4(&provider->properties[i].value) = GetUserDefaultLCID();
+                break;
+            case DBPROP_INIT_OLEDBSERVICES:
+                V_VT(&provider->properties[i].value) = dbproperties[i].type;
+                V_I4(&provider->properties[i].value) = -1;
+                break;
+            default:
+                V_VT(&provider->properties[i].value) = VT_EMPTY;
+        }
+    }
+
     hr = IUnknown_QueryInterface(&provider->MSDASQL_iface, riid, ppv);
     IUnknown_Release(&provider->MSDASQL_iface);
     return hr;
diff --git a/dlls/msdasql/tests/provider.c b/dlls/msdasql/tests/provider.c
index 6cf95e02a80..6ffe17e7028 100644
--- a/dlls/msdasql/tests/provider.c
+++ b/dlls/msdasql/tests/provider.c
@@ -75,6 +75,14 @@ static void test_Properties(void)
     ULONG infocount;
     DBPROPINFOSET *propinfoset;
     WCHAR *desc;
+    DBPROPID properties[14] =
+    {
+        DBPROP_AUTH_PASSWORD, DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, DBPROP_AUTH_USERID,
+        DBPROP_INIT_DATASOURCE, DBPROP_INIT_HWND, DBPROP_INIT_LOCATION,
+        DBPROP_INIT_MODE, DBPROP_INIT_PROMPT, DBPROP_INIT_TIMEOUT,
+        DBPROP_INIT_PROVIDERSTRING, DBPROP_INIT_LCID, DBPROP_INIT_CATALOG,
+        DBPROP_INIT_OLEDBSERVICES, DBPROP_INIT_GENERALTIMEOUT
+    };
 
     hr = CoCreateInstance( &CLSID_MSDASQL, NULL, CLSCTX_ALL, &IID_IDBProperties, (void **)&props);
     ok(hr == S_OK, "Failed to create object 0x%08x\n", hr);
@@ -88,18 +96,30 @@ static void test_Properties(void)
     ok(hr == S_OK, "got 0x%08x\n", hr);
     if (hr == S_OK)
     {
-        ULONG i;
         VARTYPE types[14] = { VT_BSTR, VT_BOOL, VT_BSTR, VT_BSTR, intptr_vartype, VT_BSTR, VT_I4, VT_I2 , VT_I4, VT_BSTR, VT_I4, VT_BSTR, VT_I4, VT_I4 };
+        ULONG i;
+        DBPROPIDSET propidlist;
+        ULONG propcnt;
+        DBPROPSET *propset;
 
         ok(IsEqualGUID(&propinfoset->guidPropertySet, &DBPROPSET_DBINIT), "got %s\n", debugstr_guid(&propinfoset->guidPropertySet));
         ok(propinfoset->cPropertyInfos == 14, "got %d\n", propinfoset->cPropertyInfos);
 
+        propidlist.guidPropertySet = DBPROPSET_DBINIT;
+        propidlist.cPropertyIDs = propinfoset->cPropertyInfos;
+        propidlist.rgPropertyIDs = CoTaskMemAlloc(propinfoset->cPropertyInfos * sizeof(DBPROP));
+
         for (i = 0; i < propinfoset->cPropertyInfos; i++)
         {
-            trace("%d: pwszDescription: %s\n", i, debugstr_w(propinfoset->rgPropertyInfos[i].pwszDescription) );
             ok(propinfoset->rgPropertyInfos[i].vtType == types[i], "got %d\n", propinfoset->rgPropertyInfos[i].vtType);
             ok(propinfoset->rgPropertyInfos[i].dwFlags == (DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE),
                 "got %d\n", propinfoset->rgPropertyInfos[i].dwFlags);
+            ok(properties[i] == propinfoset->rgPropertyInfos[i].dwPropertyID, "%d, got %d\n", i,
+                    propinfoset->rgPropertyInfos[i].dwPropertyID);
+            ok(propinfoset->rgPropertyInfos[i].vtType != VT_EMPTY, "%d, got %d\n", i,
+                    propinfoset->rgPropertyInfos[i].vtType);
+
+            propidlist.rgPropertyIDs[i] = propinfoset->rgPropertyInfos[i].dwPropertyID;
         }
 
         for (i = 0; i < propinfoset->cPropertyInfos; i++)
@@ -107,6 +127,39 @@ static void test_Properties(void)
 
         CoTaskMemFree(propinfoset->rgPropertyInfos);
         CoTaskMemFree(propinfoset);
+
+        hr = IDBProperties_GetProperties(props, 1, &propidlist, &propcnt, &propset);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        ok(propidlist.cPropertyIDs == 14, "got %d\n", propinfoset->cPropertyInfos);
+        ok(propset->cProperties == 14, "got %d\n", propinfoset->cPropertyInfos);
+
+        for (i = 0; i < propidlist.cPropertyIDs; i++)
+        {
+            VARTYPE vartype = VT_EMPTY;
+
+            ok(properties[i] == propidlist.rgPropertyIDs[i], "%d, got %d\n", i, propidlist.rgPropertyIDs[i]);
+
+            if(properties[i] == DBPROP_INIT_PROMPT)
+            {
+                ok(V_I2(&propset->rgProperties[i].vValue) == 4, "wrong value %s\n", debugstr_variant(&propset->rgProperties[i].vValue));
+                vartype = VT_I2;
+            }
+            else if(properties[i] == DBPROP_INIT_LCID)
+            {
+                ok(V_I4(&propset->rgProperties[i].vValue) == GetUserDefaultLCID(), "wrong value %s\n", debugstr_variant(&propset->rgProperties[i].vValue));
+                vartype = VT_I4;
+            }
+            else if(properties[i] == DBPROP_INIT_OLEDBSERVICES)
+            {
+                ok(V_I4(&propset->rgProperties[i].vValue) == -1, "wrong value %s\n", debugstr_variant(&propset->rgProperties[i].vValue));
+                vartype = VT_I4;
+            }
+
+            ok(V_VT(&propset->rgProperties[i].vValue) == vartype, "%d wrong type %d\n", i, V_VT(&propset->rgProperties[i].vValue));
+        }
+
+        CoTaskMemFree(propidlist.rgPropertyIDs);
+        CoTaskMemFree(propset);
     }
 
     IDBProperties_Release(props);
diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c
index 421f4258afd..8bdb1f948f4 100644
--- a/dlls/oledb32/tests/database.c
+++ b/dlls/oledb32/tests/database.c
@@ -1039,8 +1039,7 @@ static void test_odbc_provider(void)
         CoTaskMemFree(propinfoset);
 
         hr = IDBProperties_GetProperties(props, 1, &propidlist, &propcnt, &propset);
-        todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
-        if (hr == S_OK) { /* Remove if, once _GetProperties is implemented */
+        ok(hr == S_OK, "got 0x%08x\n", hr);
         ok(propidlist.cPropertyIDs == 14, "got %d\n", propinfoset->cPropertyInfos);
 
         for (i = 0; i < propidlist.cPropertyIDs; i++)
@@ -1050,7 +1049,6 @@ static void test_odbc_provider(void)
 
             propidlist.rgPropertyIDs[i] = propinfoset->rgPropertyInfos[i].dwPropertyID;
         }
-        }
 
         CoTaskMemFree(propidlist.rgPropertyIDs);
         CoTaskMemFree(propset);




More information about the wine-cvs mailing list