From 6e94e879947d9328aa3fbe8a7861bc2d5a464948 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 5 Nov 2021 16:29:59 +1100 Subject: [PATCH] msdasql: Implement IDBProperties GetProperties. Signed-off-by: Alistair Leslie-Hughes Signed-off-by: Alexandre Julliard --- dlls/msdasql/msdasql_main.c | 76 ++++++++++++++++++++++++++++++++++- dlls/msdasql/tests/provider.c | 57 +++++++++++++++++++++++++- dlls/oledb32/tests/database.c | 4 +- 3 files changed, 130 insertions(+), 7 deletions(-) diff --git a/dlls/msdasql/msdasql_main.c b/dlls/msdasql/msdasql_main.c index b8d68287e6a..d14f7957978 100644 --- a/dlls/msdasql/msdasql_main.c +++ b/dlls/msdasql/msdasql_main.c @@ -193,6 +193,12 @@ static const struct dbproperty dbproperties[] = { L"General Timeout", DBPROP_INIT_GENERALTIMEOUT, DBPROPOPTIONS_OPTIONAL, VT_I4 }, }; +struct msdasql_prop +{ + VARTYPE id; + VARIANT value; +}; + struct msdasql { IUnknown MSDASQL_iface; @@ -202,6 +208,7 @@ struct msdasql IPersist IPersist_iface; LONG ref; + struct msdasql_prop properties[14]; }; static inline struct msdasql *impl_from_IUnknown(IUnknown *iface) @@ -324,10 +331,49 @@ static HRESULT WINAPI dbprops_GetProperties(IDBProperties *iface, ULONG cPropert const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertySets, DBPROPSET **prgPropertySets) { struct msdasql *provider = impl_from_IDBProperties(iface); + int i, j, k; + DBPROPSET *propset; - FIXME("(%p)->(%d %p %p %p)\n", provider, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets); + TRACE("(%p)->(%d %p %p %p)\n", provider, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets); - return E_NOTIMPL; + *pcPropertySets = 1; + + if (cPropertyIDSets != 1) + { + FIXME("Currently only 1 property set supported.\n"); + cPropertyIDSets = 1; + } + + propset = CoTaskMemAlloc(cPropertyIDSets * sizeof(DBPROPSET)); + propset->guidPropertySet = DBPROPSET_DBINIT; + + for (i=0; i < cPropertyIDSets; i++) + { + TRACE("Property id %d (count %d, set %s)\n", i, rgPropertyIDSets[i].cPropertyIDs, + debugstr_guid(&rgPropertyIDSets[i].guidPropertySet)); + + propset->cProperties = rgPropertyIDSets[i].cPropertyIDs; + propset->rgProperties = CoTaskMemAlloc(propset->cProperties * sizeof(DBPROP)); + + for (j=0; j < propset->cProperties; j++) + { + propset->rgProperties[j].dwPropertyID = rgPropertyIDSets[i].rgPropertyIDs[j]; + + for(k = 0; k < ARRAY_SIZE(provider->properties); k++) + { + if (provider->properties[k].id == rgPropertyIDSets[i].rgPropertyIDs[j]) + { + V_VT(&propset->rgProperties[j].vValue) = VT_EMPTY; + VariantCopy(&propset->rgProperties[j].vValue, &provider->properties[k].value); + break; + } + } + } + } + + *prgPropertySets = propset; + + return S_OK; } static HRESULT WINAPI dbprops_GetPropertyInfo(IDBProperties *iface, ULONG cPropertyIDSets, @@ -531,6 +577,7 @@ static HRESULT create_msdasql_provider(REFIID riid, void **ppv) { struct msdasql *provider; HRESULT hr; + int i; provider = malloc(sizeof(struct msdasql)); if (!provider) @@ -543,6 +590,31 @@ static HRESULT create_msdasql_provider(REFIID riid, void **ppv) provider->IPersist_iface.lpVtbl = &persistVtbl; provider->ref = 1; + for(i=0; i < ARRAY_SIZE(dbproperties); i++) + { + provider->properties[i].id = dbproperties[i].id; + VariantInit(&provider->properties[i].value); + + /* Only the follow are initialized to a value */ + switch(dbproperties[i].id) + { + case DBPROP_INIT_PROMPT: + V_VT(&provider->properties[i].value) = dbproperties[i].type; + V_I2(&provider->properties[i].value) = 4; + break; + case DBPROP_INIT_LCID: + V_VT(&provider->properties[i].value) = dbproperties[i].type; + V_I4(&provider->properties[i].value) = GetUserDefaultLCID(); + break; + case DBPROP_INIT_OLEDBSERVICES: + V_VT(&provider->properties[i].value) = dbproperties[i].type; + V_I4(&provider->properties[i].value) = -1; + break; + default: + V_VT(&provider->properties[i].value) = VT_EMPTY; + } + } + hr = IUnknown_QueryInterface(&provider->MSDASQL_iface, riid, ppv); IUnknown_Release(&provider->MSDASQL_iface); return hr; diff --git a/dlls/msdasql/tests/provider.c b/dlls/msdasql/tests/provider.c index 6cf95e02a80..6ffe17e7028 100644 --- a/dlls/msdasql/tests/provider.c +++ b/dlls/msdasql/tests/provider.c @@ -75,6 +75,14 @@ static void test_Properties(void) ULONG infocount; DBPROPINFOSET *propinfoset; WCHAR *desc; + DBPROPID properties[14] = + { + DBPROP_AUTH_PASSWORD, DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, DBPROP_AUTH_USERID, + DBPROP_INIT_DATASOURCE, DBPROP_INIT_HWND, DBPROP_INIT_LOCATION, + DBPROP_INIT_MODE, DBPROP_INIT_PROMPT, DBPROP_INIT_TIMEOUT, + DBPROP_INIT_PROVIDERSTRING, DBPROP_INIT_LCID, DBPROP_INIT_CATALOG, + DBPROP_INIT_OLEDBSERVICES, DBPROP_INIT_GENERALTIMEOUT + }; hr = CoCreateInstance( &CLSID_MSDASQL, NULL, CLSCTX_ALL, &IID_IDBProperties, (void **)&props); ok(hr == S_OK, "Failed to create object 0x%08x\n", hr); @@ -88,18 +96,30 @@ static void test_Properties(void) 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 }; + ULONG i; + DBPROPIDSET propidlist; + ULONG propcnt; + DBPROPSET *propset; ok(IsEqualGUID(&propinfoset->guidPropertySet, &DBPROPSET_DBINIT), "got %s\n", debugstr_guid(&propinfoset->guidPropertySet)); ok(propinfoset->cPropertyInfos == 14, "got %d\n", propinfoset->cPropertyInfos); + propidlist.guidPropertySet = DBPROPSET_DBINIT; + propidlist.cPropertyIDs = propinfoset->cPropertyInfos; + propidlist.rgPropertyIDs = CoTaskMemAlloc(propinfoset->cPropertyInfos * sizeof(DBPROP)); + 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); + ok(properties[i] == propinfoset->rgPropertyInfos[i].dwPropertyID, "%d, got %d\n", i, + propinfoset->rgPropertyInfos[i].dwPropertyID); + ok(propinfoset->rgPropertyInfos[i].vtType != VT_EMPTY, "%d, got %d\n", i, + propinfoset->rgPropertyInfos[i].vtType); + + propidlist.rgPropertyIDs[i] = propinfoset->rgPropertyInfos[i].dwPropertyID; } for (i = 0; i < propinfoset->cPropertyInfos; i++) @@ -107,6 +127,39 @@ static void test_Properties(void) CoTaskMemFree(propinfoset->rgPropertyInfos); CoTaskMemFree(propinfoset); + + hr = IDBProperties_GetProperties(props, 1, &propidlist, &propcnt, &propset); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(propidlist.cPropertyIDs == 14, "got %d\n", propinfoset->cPropertyInfos); + ok(propset->cProperties == 14, "got %d\n", propinfoset->cPropertyInfos); + + for (i = 0; i < propidlist.cPropertyIDs; i++) + { + VARTYPE vartype = VT_EMPTY; + + ok(properties[i] == propidlist.rgPropertyIDs[i], "%d, got %d\n", i, propidlist.rgPropertyIDs[i]); + + if(properties[i] == DBPROP_INIT_PROMPT) + { + ok(V_I2(&propset->rgProperties[i].vValue) == 4, "wrong value %s\n", debugstr_variant(&propset->rgProperties[i].vValue)); + vartype = VT_I2; + } + else if(properties[i] == DBPROP_INIT_LCID) + { + ok(V_I4(&propset->rgProperties[i].vValue) == GetUserDefaultLCID(), "wrong value %s\n", debugstr_variant(&propset->rgProperties[i].vValue)); + vartype = VT_I4; + } + else if(properties[i] == DBPROP_INIT_OLEDBSERVICES) + { + ok(V_I4(&propset->rgProperties[i].vValue) == -1, "wrong value %s\n", debugstr_variant(&propset->rgProperties[i].vValue)); + vartype = VT_I4; + } + + ok(V_VT(&propset->rgProperties[i].vValue) == vartype, "%d wrong type %d\n", i, V_VT(&propset->rgProperties[i].vValue)); + } + + CoTaskMemFree(propidlist.rgPropertyIDs); + CoTaskMemFree(propset); } IDBProperties_Release(props); diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c index 421f4258afd..8bdb1f948f4 100644 --- a/dlls/oledb32/tests/database.c +++ b/dlls/oledb32/tests/database.c @@ -1039,8 +1039,7 @@ static void test_odbc_provider(void) CoTaskMemFree(propinfoset); hr = IDBProperties_GetProperties(props, 1, &propidlist, &propcnt, &propset); - todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); - if (hr == S_OK) { /* Remove if, once _GetProperties is implemented */ + ok(hr == S_OK, "got 0x%08x\n", hr); ok(propidlist.cPropertyIDs == 14, "got %d\n", propinfoset->cPropertyInfos); for (i = 0; i < propidlist.cPropertyIDs; i++) @@ -1050,7 +1049,6 @@ static void test_odbc_provider(void) propidlist.rgPropertyIDs[i] = propinfoset->rgPropertyInfos[i].dwPropertyID; } - } CoTaskMemFree(propidlist.rgPropertyIDs); CoTaskMemFree(propset);