Commit 5bd1de64 authored by Alistair Leslie-Hughes's avatar Alistair Leslie-Hughes Committed by Alexandre Julliard

msdasql: Implement IDBProperties GetPropertyInfo.

parent 157466da
MODULE = msdasql.dll MODULE = msdasql.dll
IMPORTS = uuid IMPORTS = uuid ole32 oleaut32
EXTRADLLFLAGS = -Wb,--prefer-native EXTRADLLFLAGS = -Wb,--prefer-native
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(msdasql); 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) static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{ {
*ppv = NULL; *ppv = NULL;
...@@ -100,6 +102,72 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv ) ...@@ -100,6 +102,72 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
return CLASS_E_CLASSNOTAVAILABLE; 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 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, sizeof(void *) == 8 ? VT_I8 : VT_I4 },
{ 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 struct msdasql
{ {
IUnknown MSDASQL_iface; IUnknown MSDASQL_iface;
...@@ -222,11 +290,43 @@ static HRESULT WINAPI dbprops_GetPropertyInfo(IDBProperties *iface, ULONG cPrope ...@@ -222,11 +290,43 @@ static HRESULT WINAPI dbprops_GetPropertyInfo(IDBProperties *iface, ULONG cPrope
DBPROPINFOSET **prgPropertyInfoSets, OLECHAR **ppDescBuffer) DBPROPINFOSET **prgPropertyInfoSets, OLECHAR **ppDescBuffer)
{ {
struct msdasql *provider = impl_from_IDBProperties(iface); 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); 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, static HRESULT WINAPI dbprops_SetProperties(IDBProperties *iface, ULONG cPropertySets,
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "msdasc.h" #include "msdasc.h"
#include "oledb.h" #include "oledb.h"
#include "odbcinst.h" #include "odbcinst.h"
#include "wtypes.h"
#include "initguid.h" #include "initguid.h"
...@@ -30,10 +31,13 @@ ...@@ -30,10 +31,13 @@
#include "wine/test.h" #include "wine/test.h"
DEFINE_GUID(DBPROPSET_DBINITALL, 0xc8b522ca, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d); 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 BOOL db_created;
static char mdbpath[MAX_PATH]; static char mdbpath[MAX_PATH];
static const VARTYPE intptr_vartype = (sizeof(void *) == 8 ? VT_I8 : VT_I4);
static void test_Properties(void) static void test_Properties(void)
{ {
HRESULT hr; HRESULT hr;
...@@ -52,16 +56,21 @@ static void test_Properties(void) ...@@ -52,16 +56,21 @@ static void test_Properties(void)
infocount = 0; infocount = 0;
hr = IDBProperties_GetPropertyInfo(props, 1, &propidset, &infocount, &propinfoset, &desc); 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) if (hr == S_OK)
{ {
ULONG i; 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); ok(propinfoset->cPropertyInfos == 14, "got %d\n", propinfoset->cPropertyInfos);
for (i = 0; i < propinfoset->cPropertyInfos; i++) for (i = 0; i < propinfoset->cPropertyInfos; i++)
{ {
trace("%d: pwszDescription: %s\n", i, debugstr_w(propinfoset->rgPropertyInfos[i].pwszDescription) ); 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++) for (i = 0; i < propinfoset->cPropertyInfos; i++)
......
...@@ -82,7 +82,7 @@ static void test_GetDataSource(WCHAR *initstring) ...@@ -82,7 +82,7 @@ static void test_GetDataSource(WCHAR *initstring)
EXPECT_REF(dbinit, 2); EXPECT_REF(dbinit, 2);
EXPECT_REF(props, 2); EXPECT_REF(props, 2);
hr = IDBProperties_GetPropertyInfo(props, 0, NULL, &cnt, &pInfoset, &ary); 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) if(hr == S_OK)
{ {
ULONG i; ULONG i;
...@@ -1006,7 +1006,7 @@ static void test_odbc_provider(void) ...@@ -1006,7 +1006,7 @@ static void test_odbc_provider(void)
infocount = 0; infocount = 0;
hr = IDBProperties_GetPropertyInfo(props, 1, &propidset, &infocount, &propinfoset, &desc); 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) if (hr == S_OK)
{ {
ULONG i; ULONG i;
...@@ -1039,7 +1039,8 @@ static void test_odbc_provider(void) ...@@ -1039,7 +1039,8 @@ static void test_odbc_provider(void)
CoTaskMemFree(propinfoset); CoTaskMemFree(propinfoset);
hr = IDBProperties_GetProperties(props, 1, &propidlist, &propcnt, &propset); 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); ok(propidlist.cPropertyIDs == 14, "got %d\n", propinfoset->cPropertyInfos);
for (i = 0; i < propidlist.cPropertyIDs; i++) for (i = 0; i < propidlist.cPropertyIDs; i++)
...@@ -1049,6 +1050,7 @@ static void test_odbc_provider(void) ...@@ -1049,6 +1050,7 @@ static void test_odbc_provider(void)
propidlist.rgPropertyIDs[i] = propinfoset->rgPropertyInfos[i].dwPropertyID; propidlist.rgPropertyIDs[i] = propinfoset->rgPropertyInfos[i].dwPropertyID;
} }
}
CoTaskMemFree(propidlist.rgPropertyIDs); CoTaskMemFree(propidlist.rgPropertyIDs);
CoTaskMemFree(propset); CoTaskMemFree(propset);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment