Module: wine Branch: master Commit: ffd3e8543cadc98b167d016eb2c1ca9c0a413e9b URL: http://source.winehq.org/git/wine.git/?a=commit;h=ffd3e8543cadc98b167d016eb2...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Thu Apr 20 13:05:32 2017 +0300
oledb32: Support textual representation of Mode property values.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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 7ed4099..650c220 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 f39c2f5..b8c0e61 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);