Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/msdasql/Makefile.in | 2 +- dlls/msdasql/msdasql_main.c | 106 +++++++++++++++++++++++++++++++++- dlls/msdasql/tests/provider.c | 11 +++- dlls/oledb32/tests/database.c | 10 ++-- 4 files changed, 121 insertions(+), 8 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..96a1bc392e2 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,74 @@ 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 VARTYPE intptr_vartype = (sizeof(void *) == 8 ? VT_I8 : VT_I4); + +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, intptr_vartype }, + { 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 +292,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..44b783dba85 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; @@ -279,7 +279,7 @@ static void test_GetDataSource2(WCHAR *initstring)
dbinit = &dbinittest; hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring, &IID_IDBInitialize, (IUnknown**)&dbinit); - ok(hr == S_OK, "got %08x\n", hr); + todo_wine ok(hr == S_OK, "got %08x\n", hr);
IDataInitialize_Release(datainit); } @@ -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);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=100818
Your paranoid android.
=== debiant2 (32 bit report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000
=== debiant2 (32 bit Arabic:Morocco report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000
=== debiant2 (32 bit German report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000
=== debiant2 (32 bit French report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000
=== debiant2 (32 bit Hebrew:Israel report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000
=== debiant2 (32 bit Hindi:India report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000
=== debiant2 (32 bit Japanese:Japan report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000
=== debiant2 (32 bit Chinese:China report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000
=== debiant2 (32 bit WoW report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000
=== debiant2 (64 bit WoW report) ===
oledb32: database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000 database.c:282: Test succeeded inside todo block: got 00000000