Alistair Leslie-Hughes : msdasql: Implement IDBProperties GetPropertyInfo.

Alexandre Julliard julliard at winehq.org
Wed Oct 27 16:26:02 CDT 2021


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

Author: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Date:   Wed Oct 27 17:17:51 2021 +1100

msdasql: Implement IDBProperties GetPropertyInfo.

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

---

 dlls/msdasql/Makefile.in      |   2 +-
 dlls/msdasql/msdasql_main.c   | 104 +++++++++++++++++++++++++++++++++++++++++-
 dlls/msdasql/tests/provider.c |  11 ++++-
 dlls/oledb32/tests/database.c |   8 ++--
 4 files changed, 118 insertions(+), 7 deletions(-)

diff --git a/dlls/msdasql/Makefile.in b/dlls/msdasql/Makefile.in
index 8c99c8ea6f0..04d9cb29f2a 100644
--- a/dlls/msdasql/Makefile.in
+++ b/dlls/msdasql/Makefile.in
@@ -1,5 +1,5 @@
 MODULE    = msdasql.dll
-IMPORTS   = uuid
+IMPORTS   = uuid ole32 oleaut32
 
 EXTRADLLFLAGS = -Wb,--prefer-native
 
diff --git a/dlls/msdasql/msdasql_main.c b/dlls/msdasql/msdasql_main.c
index 00dbcec6780..7e78caa8f24 100644
--- a/dlls/msdasql/msdasql_main.c
+++ b/dlls/msdasql/msdasql_main.c
@@ -32,6 +32,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(msdasql);
 
+DEFINE_GUID(DBPROPSET_DBINIT,    0xc8b522bc, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
+
 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
 {
     *ppv = NULL;
@@ -100,6 +102,72 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
     return CLASS_E_CLASSNOTAVAILABLE;
 }
 
+struct dbproperty
+{
+    const WCHAR *name;
+    DBPROPID id;
+    DBPROPOPTIONS options;
+    VARTYPE type;
+    HRESULT (*convert_dbproperty)(const WCHAR *src, VARIANT *dest);
+};
+
+struct mode_propval
+{
+    const WCHAR *name;
+    DWORD value;
+};
+
+static int __cdecl dbmodeprop_compare(const void *a, const void *b)
+{
+    const WCHAR *src = a;
+    const struct mode_propval *propval = b;
+    return wcsicmp(src, propval->name);
+}
+
+static HRESULT convert_dbproperty_mode(const WCHAR *src, VARIANT *dest)
+{
+    struct mode_propval mode_propvals[] =
+    {
+        { L"Read", DB_MODE_READ },
+        { L"ReadWrite", DB_MODE_READWRITE },
+        { L"Share Deny None", DB_MODE_SHARE_DENY_NONE },
+        { L"Share Deny Read", DB_MODE_SHARE_DENY_READ },
+        { L"Share Deny Write", DB_MODE_SHARE_DENY_WRITE },
+        { L"Share Exclusive", DB_MODE_SHARE_EXCLUSIVE },
+        { L"Write", DB_MODE_WRITE },
+    };
+    struct mode_propval *prop;
+
+    if ((prop = bsearch(src, mode_propvals, ARRAY_SIZE(mode_propvals),
+                        sizeof(struct mode_propval), dbmodeprop_compare)))
+    {
+        V_VT(dest) = VT_I4;
+        V_I4(dest) = prop->value;
+        TRACE("%s = %#x\n", debugstr_w(src), prop->value);
+        return S_OK;
+    }
+
+    return E_FAIL;
+}
+
+static const struct dbproperty dbproperties[] =
+{
+    { L"Password",                 DBPROP_AUTH_PASSWORD,                   DBPROPOPTIONS_OPTIONAL, VT_BSTR },
+    { L"Persist Security Info",    DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, DBPROPOPTIONS_OPTIONAL, VT_BOOL },
+    { L"User ID",                  DBPROP_AUTH_USERID,                     DBPROPOPTIONS_OPTIONAL, VT_BSTR },
+    { L"Data Source",              DBPROP_INIT_DATASOURCE,                 DBPROPOPTIONS_REQUIRED, VT_BSTR },
+    { L"Window Handle",            DBPROP_INIT_HWND,                       DBPROPOPTIONS_OPTIONAL, sizeof(void *) == 8 ? VT_I8 : VT_I4 },
+    { L"Location",                 DBPROP_INIT_LOCATION,                   DBPROPOPTIONS_OPTIONAL, VT_BSTR },
+    { L"Mode",                     DBPROP_INIT_MODE,                       DBPROPOPTIONS_OPTIONAL, VT_I4, convert_dbproperty_mode },
+    { L"Prompt",                   DBPROP_INIT_PROMPT,                     DBPROPOPTIONS_OPTIONAL, VT_I2 },
+    { L"Connect Timeout",          DBPROP_INIT_TIMEOUT,                    DBPROPOPTIONS_OPTIONAL, VT_I4 },
+    { L"Extended Properties",      DBPROP_INIT_PROVIDERSTRING,             DBPROPOPTIONS_REQUIRED, VT_BSTR },
+    { L"Locale Identifier",        DBPROP_INIT_LCID,                       DBPROPOPTIONS_OPTIONAL, VT_I4 },
+    { L"Initial Catalog",          DBPROP_INIT_CATALOG,                    DBPROPOPTIONS_OPTIONAL, VT_BSTR },
+    { L"OLE DB Services",          DBPROP_INIT_OLEDBSERVICES,              DBPROPOPTIONS_OPTIONAL, VT_I4 },
+    { L"General Timeout",          DBPROP_INIT_GENERALTIMEOUT,             DBPROPOPTIONS_OPTIONAL, VT_I4 },
+};
+
 struct msdasql
 {
     IUnknown         MSDASQL_iface;
@@ -222,11 +290,43 @@ static HRESULT WINAPI dbprops_GetPropertyInfo(IDBProperties *iface, ULONG cPrope
             DBPROPINFOSET **prgPropertyInfoSets, OLECHAR **ppDescBuffer)
 {
     struct msdasql *provider = impl_from_IDBProperties(iface);
+    int i;
+    DBPROPINFOSET *infoset;
+    int size = 1;
+    OLECHAR *ptr;
 
-    FIXME("(%p)->(%d %p %p %p %p)\n", provider, cPropertyIDSets, rgPropertyIDSets, pcPropertyInfoSets,
+    TRACE("(%p)->(%d %p %p %p %p)\n", provider, cPropertyIDSets, rgPropertyIDSets, pcPropertyInfoSets,
                 prgPropertyInfoSets, ppDescBuffer);
 
-    return E_NOTIMPL;
+    infoset = CoTaskMemAlloc(sizeof(DBPROPINFOSET));
+    memcpy(&infoset->guidPropertySet, &DBPROPSET_DBINIT, sizeof(GUID));
+    infoset->cPropertyInfos = ARRAY_SIZE(dbproperties);
+    infoset->rgPropertyInfos = CoTaskMemAlloc(sizeof(DBPROPINFO) * ARRAY_SIZE(dbproperties));
+
+    for(i=0; i < ARRAY_SIZE(dbproperties); i++)
+    {
+        size += lstrlenW(dbproperties[i].name) + 1;
+    }
+
+    ptr = *ppDescBuffer = CoTaskMemAlloc(size * sizeof(WCHAR));
+    memset(*ppDescBuffer, 0, size * sizeof(WCHAR));
+
+    for(i=0; i < ARRAY_SIZE(dbproperties); i++)
+    {
+        lstrcpyW(ptr, dbproperties[i].name);
+        infoset->rgPropertyInfos[i].pwszDescription = ptr;
+        infoset->rgPropertyInfos[i].dwPropertyID =  dbproperties[i].id;
+        infoset->rgPropertyInfos[i].dwFlags = DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE;
+        infoset->rgPropertyInfos[i].vtType =  dbproperties[i].type;
+        V_VT(&infoset->rgPropertyInfos[i].vValues) =  VT_EMPTY;
+
+        ptr += lstrlenW(dbproperties[i].name) + 1;
+    }
+
+    *pcPropertyInfoSets = 1;
+    *prgPropertyInfoSets = infoset;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI dbprops_SetProperties(IDBProperties *iface, ULONG cPropertySets,
diff --git a/dlls/msdasql/tests/provider.c b/dlls/msdasql/tests/provider.c
index 96d33f6bd10..2e90d2f848d 100644
--- a/dlls/msdasql/tests/provider.c
+++ b/dlls/msdasql/tests/provider.c
@@ -22,6 +22,7 @@
 #include "msdasc.h"
 #include "oledb.h"
 #include "odbcinst.h"
+#include "wtypes.h"
 
 #include "initguid.h"
 
@@ -30,10 +31,13 @@
 #include "wine/test.h"
 
 DEFINE_GUID(DBPROPSET_DBINITALL, 0xc8b522ca, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
+DEFINE_GUID(DBPROPSET_DBINIT,    0xc8b522bc, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
 
 static BOOL db_created;
 static char mdbpath[MAX_PATH];
 
+static const VARTYPE intptr_vartype = (sizeof(void *) == 8 ? VT_I8 : VT_I4);
+
 static void test_Properties(void)
 {
     HRESULT hr;
@@ -52,16 +56,21 @@ static void test_Properties(void)
 
     infocount = 0;
     hr = IDBProperties_GetPropertyInfo(props, 1, &propidset, &infocount, &propinfoset, &desc);
-    todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
+    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 };
 
+        ok(IsEqualGUID(&propinfoset->guidPropertySet, &DBPROPSET_DBINIT), "got %s\n", debugstr_guid(&propinfoset->guidPropertySet));
         ok(propinfoset->cPropertyInfos == 14, "got %d\n", propinfoset->cPropertyInfos);
 
         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);
         }
 
         for (i = 0; i < propinfoset->cPropertyInfos; i++)
diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c
index 3baa91b87a4..775da0f7b61 100644
--- a/dlls/oledb32/tests/database.c
+++ b/dlls/oledb32/tests/database.c
@@ -82,7 +82,7 @@ static void test_GetDataSource(WCHAR *initstring)
             EXPECT_REF(dbinit, 2);
             EXPECT_REF(props, 2);
             hr = IDBProperties_GetPropertyInfo(props, 0, NULL, &cnt, &pInfoset, &ary);
-            todo_wine ok(hr == S_OK, "got %08x\n", hr);
+            ok(hr == S_OK, "got %08x\n", hr);
             if(hr == S_OK)
             {
                 ULONG i;
@@ -1006,7 +1006,7 @@ static void test_odbc_provider(void)
 
     infocount = 0;
     hr = IDBProperties_GetPropertyInfo(props, 1, &propidset, &infocount, &propinfoset, &desc);
-    todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
     if (hr == S_OK)
     {
         ULONG i;
@@ -1039,7 +1039,8 @@ static void test_odbc_provider(void)
         CoTaskMemFree(propinfoset);
 
         hr = IDBProperties_GetProperties(props, 1, &propidlist, &propcnt, &propset);
-        ok(hr == S_OK, "got 0x%08x\n", hr);
+        todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
+        if (hr == S_OK) { /* Remove if, once _GetProperties is implemented */
         ok(propidlist.cPropertyIDs == 14, "got %d\n", propinfoset->cPropertyInfos);
 
         for (i = 0; i < propidlist.cPropertyIDs; i++)
@@ -1049,6 +1050,7 @@ 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