oledb32: Support textual representation of Mode property values.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2017-04-20 13:05:32 +03:00 committed by Alexandre Julliard
parent 4798111692
commit ffd3e8543c
2 changed files with 82 additions and 2 deletions

View File

@ -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);

View File

@ -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);