[PATCH 2/2] oledb32: Support textual representation of Mode property values

Nikolay Sivov nsivov at codeweavers.com
Thu Apr 20 05:05:32 CDT 2017


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/oledb32/datainit.c       | 58 +++++++++++++++++++++++++++++++++++++++++--
 dlls/oledb32/tests/database.c | 26 +++++++++++++++++++
 2 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/dlls/oledb32/datainit.c b/dlls/oledb32/datainit.c
index 7ed4099b0d..650c220741 100644
--- a/dlls/oledb32/datainit.c
+++ b/dlls/oledb32/datainit.c
@@ -289,8 +289,56 @@ struct dbproperty {
     DBPROPID id;
     DBPROPOPTIONS options;
     VARTYPE type;
+    HRESULT (*convert_dbproperty)(const WCHAR *src, VARIANT *dest);
 };
 
+struct mode_propval
+{
+    const WCHAR *name;
+    DWORD value;
+};
+
+static int dbmodeprop_compare(const void *a, const void *b)
+{
+    const WCHAR *src = a;
+    const struct mode_propval *propval = b;
+    return strcmpiW(src, propval->name);
+}
+
+static HRESULT convert_dbproperty_mode(const WCHAR *src, VARIANT *dest)
+{
+    static const WCHAR readW[] = {'R','e','a','d',0};
+    static const WCHAR readwriteW[] = {'R','e','a','d','W','r','i','t','e',0};
+    static const WCHAR sharedenynoneW[] = {'S','h','a','r','e',' ','D','e','n','y',' ','N','o','n','e',0};
+    static const WCHAR sharedenyreadW[] = {'S','h','a','r','e',' ','D','e','n','y',' ','R','e','a','d',0};
+    static const WCHAR sharedenywriteW[] = {'S','h','a','r','e',' ','D','e','n','y',' ','W','r','i','t','e',0};
+    static const WCHAR shareexclusiveW[] = {'S','h','a','r','e',' ','E','x','c','l','u','s','i','v','e',0};
+    static const WCHAR writeW[] = {'W','r','i','t','e',0};
+
+    struct mode_propval mode_propvals[] =
+    {
+        { readW, DB_MODE_READ },
+        { readwriteW, DB_MODE_READWRITE },
+        { sharedenynoneW, DB_MODE_SHARE_DENY_NONE },
+        { sharedenyreadW, DB_MODE_SHARE_DENY_READ },
+        { sharedenywriteW, DB_MODE_SHARE_DENY_WRITE },
+        { shareexclusiveW, DB_MODE_SHARE_EXCLUSIVE },
+        { writeW, DB_MODE_WRITE },
+    };
+    struct mode_propval *prop;
+
+    if ((prop = bsearch(src, mode_propvals, sizeof(mode_propvals) / sizeof(*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 WCHAR asyncW[]  = {'A','s','y','n','c','h','r','o','n','o','u','s',' ','P','r','o','c','e','s','s','i','n','g',0};
 static const WCHAR bindW[]  = {'B','i','n','d',' ','F','l','a','g','s',0};
 static const WCHAR cacheW[]  = {'C','a','c','h','e',' ','A','u','t','h','e','n','i','c','a','t','i','o','n',0};
@@ -332,7 +380,7 @@ static const struct dbproperty dbproperties[] = {
     { locationW,   DBPROP_INIT_LOCATION,                   DBPROPOPTIONS_OPTIONAL, VT_BSTR },
     { lockownerW,  DBPROP_INIT_LOCKOWNER,                  DBPROPOPTIONS_OPTIONAL, VT_BSTR },
     { maskpassW,   DBPROP_AUTH_MASK_PASSWORD,              DBPROPOPTIONS_OPTIONAL, VT_BOOL },
-    { modeW,       DBPROP_INIT_MODE,                       DBPROPOPTIONS_OPTIONAL, VT_I4 },
+    { modeW,       DBPROP_INIT_MODE,                       DBPROPOPTIONS_OPTIONAL, VT_I4, convert_dbproperty_mode },
     { oledbservW,  DBPROP_INIT_OLEDBSERVICES,              DBPROPOPTIONS_OPTIONAL, VT_I4 },
     { passwordW,   DBPROP_AUTH_PASSWORD,                   DBPROPOPTIONS_OPTIONAL, VT_BSTR },
     { persistEncW, DBPROP_AUTH_PERSIST_ENCRYPTED,          DBPROPOPTIONS_OPTIONAL, VT_BOOL },
@@ -418,7 +466,10 @@ static HRESULT parse_init_string(const WCHAR *initstring, struct dbprops *props)
         else
             delim = strchrW(eq, ';');
 
-        value = SysAllocStringLen(eq, delim ? delim - eq : -1);
+        if (delim)
+            value = SysAllocStringLen(eq, delim - eq);
+        else
+            value = SysAllocString(eq);
 
         /* skip semicolon if present */
         if (delim)
@@ -534,6 +585,9 @@ static HRESULT get_dbpropset_from_proplist(struct dbprops *props, DBPROPSET **pr
 
         VariantInit(&dest);
         hr = VariantChangeType(&dest, &src, 0, descr->type);
+        if (FAILED(hr) && descr->convert_dbproperty)
+            hr = descr->convert_dbproperty(pair->value, &dest);
+
         if (FAILED(hr))
         {
             ERR("failed to init property %s value as type %d\n", debugstr_w(pair->name), descr->type);
diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c
index f39c2f5c7e..b8c0e61c3d 100644
--- a/dlls/oledb32/tests/database.c
+++ b/dlls/oledb32/tests/database.c
@@ -500,6 +500,15 @@ static void test_initializationstring(void)
          'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
     static const WCHAR initstring_sqloledb[] = {'P','r','o','v','i','d','e','r','=','S','Q','L','O','L','E','D','B','.','1',';',
          'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
+    static const WCHAR initstring_mode[] = {'P','r','o','v','i','d','e','r','=','M','S','D','A','S','Q','L','.','1',';',
+         'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',
+         'M','o','d','e','=','i','n','v','a','l','i','d',0};
+    static const WCHAR initstring_mode2[] = {'P','r','o','v','i','d','e','r','=','M','S','D','A','S','Q','L','.','1',';',
+         'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',
+         'M','o','d','e','=','W','r','i','t','e','R','e','a','d',0};
+    static const WCHAR initstring_mode3[] = {'P','r','o','v','i','d','e','r','=','M','S','D','A','S','Q','L','.','1',';',
+         'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',
+         'M','o','d','e','=','R','e','a','d','W','R','I','T','E',0};
     IDataInitialize *datainit = NULL;
     IDBInitialize *dbinit;
     HRESULT hr;
@@ -537,6 +546,23 @@ static void test_initializationstring(void)
                 &IID_IDBInitialize, (IUnknown**)&dbinit);
             ok(hr == S_OK, "got 0x%08x\n", hr);
             IDBInitialize_Release(dbinit);
+
+            /* Invalid Mode value */
+            dbinit = NULL;
+            hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR *)initstring_mode,
+                &IID_IDBInitialize, (IUnknown **)&dbinit);
+            ok(FAILED(hr), "got 0x%08x\n", hr);
+
+            dbinit = NULL;
+            hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR *)initstring_mode2,
+                &IID_IDBInitialize, (IUnknown **)&dbinit);
+            ok(FAILED(hr), "got 0x%08x\n", hr);
+
+            dbinit = NULL;
+            hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR *)initstring_mode3,
+                &IID_IDBInitialize, (IUnknown **)&dbinit);
+            ok(hr == S_OK, "got 0x%08x\n", hr);
+            IDBInitialize_Release(dbinit);
         }
         else
             ok(dbinit == NULL, "got %p\n", dbinit);
-- 
2.11.0




More information about the wine-patches mailing list