From 3e8d4e76e5daf46ca3d2776a0aedcde51226c48d Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 28 Dec 2012 14:59:23 +0400 Subject: [PATCH] oledb32: Support data source properties from init string passed to GetDataSource(). --- dlls/oledb32/datainit.c | 84 +++++++++++++++++++++++++++++++++-- dlls/oledb32/tests/database.c | 2 +- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/dlls/oledb32/datainit.c b/dlls/oledb32/datainit.c index 1316c0fb6b7..c710367b3a0 100644 --- a/dlls/oledb32/datainit.c +++ b/dlls/oledb32/datainit.c @@ -289,6 +289,32 @@ static void free_dbpropset(ULONG count, DBPROPSET *propset) CoTaskMemFree(propset); } +static HRESULT set_dbpropset(BSTR name, BSTR value, DBPROPSET **propset) +{ + static const WCHAR datasourceW[] = {'D','a','t','a',' ','S','o','u','r','c','e',0}; + + *propset = CoTaskMemAlloc(sizeof(DBPROPSET)); + (*propset)->rgProperties = CoTaskMemAlloc(sizeof(DBPROP)); + + if (!strcmpW(datasourceW, name)) + { + (*propset)->cProperties = 1; + (*propset)->guidPropertySet = DBPROPSET_DBINIT; + (*propset)->rgProperties[0].dwPropertyID = DBPROP_INIT_DATASOURCE; + (*propset)->rgProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED; + (*propset)->rgProperties[0].dwStatus = 0; + memset(&(*propset)->rgProperties[0].colid, 0, sizeof(DBID)); + V_VT(&(*propset)->rgProperties[0].vValue) = VT_BSTR; + V_BSTR(&(*propset)->rgProperties[0].vValue) = SysAllocString(value); + return S_OK; + } + else + { + FIXME("unsupported property %s\n", debugstr_w(name)); + return E_FAIL; + } +} + /*** IDataInitialize methods ***/ static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *outer, DWORD clsctx, LPWSTR initstring, REFIID riid, IUnknown **datasource) @@ -296,11 +322,13 @@ static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *o static const WCHAR providerW[] = {'P','r','o','v','i','d','e','r','=',0}; static const WCHAR msdasqlW[] = {'M','S','D','A','S','Q','L',0}; datainit *This = impl_from_IDataInitialize(iface); + IDBProperties *dbprops; + DBPROPSET *propset; WCHAR *prov = NULL; CLSID provclsid; HRESULT hr; - FIXME("(%p)->(%p 0x%x %s %s %p): semi-stub\n", This, outer, clsctx, debugstr_w(initstring), debugstr_guid(riid), datasource); + TRACE("(%p)->(%p 0x%x %s %s %p)\n", This, outer, clsctx, debugstr_w(initstring), debugstr_guid(riid), datasource); /* first get provider name */ provclsid = IID_NULL; @@ -340,9 +368,7 @@ static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *o /* check for provider mismatch if it was specified in init string */ if (*datasource && prov) { - IDBProperties *dbprops; DBPROPIDSET propidset; - DBPROPSET *propset; enum DBPROPENUM prop; CLSID initprov; ULONG count; @@ -385,7 +411,57 @@ static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *o hr = create_db_init((void**)datasource); } - /* FIXME: set properties from init string */ + /* now set properties */ + if (initstring) + { + static const WCHAR scolW[] = {';',0}; + static const WCHAR eqW[] = {'=',0}; + WCHAR *eq, *start; + + hr = IUnknown_QueryInterface(*datasource, &IID_IDBProperties, (void**)&dbprops); + if (FAILED(hr)) + { + WARN("provider doesn't support IDBProperties\n"); + return hr; + } + + start = initstring; + while ((eq = strstrW(start, eqW))) + { + static const WCHAR providerW[] = {'P','r','o','v','i','d','e','r',0}; + WCHAR *scol = strstrW(eq+1, scolW); + BSTR value, name; + + name = SysAllocStringLen(start, eq - start); + /* skip equal sign to get value */ + eq++; + value = SysAllocStringLen(eq, scol ? scol - eq : -1); + + /* skip semicolon if present */ + if (scol) scol++; + start = scol; + + if (!strcmpW(name, providerW)) + { + SysFreeString(name); + SysFreeString(value); + continue; + } + + TRACE("property (name=%s, value=%s)\n", debugstr_w(name), debugstr_w(value)); + + hr = set_dbpropset(name, value, &propset); + SysFreeString(name); + SysFreeString(value); + if (FAILED(hr)) return hr; + + hr = IDBProperties_SetProperties(dbprops, 1, propset); + free_dbpropset(1, propset); + TRACE("provider ret 0x%08x\n", hr); + } + + IDBProperties_Release(dbprops); + } return hr; } diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c index ede10742a96..4d3694cf440 100644 --- a/dlls/oledb32/tests/database.c +++ b/dlls/oledb32/tests/database.c @@ -58,7 +58,7 @@ static void test_GetDataSource(WCHAR *initstring) static void test_database(void) { static WCHAR initstring_jet[] = {'P','r','o','v','i','d','e','r','=','M','i','c','r','o','s','o','f','t','.', - 'J','e','t','.','O','L','E','D','B','.','4','.','0',';',0, + 'J','e','t','.','O','L','E','D','B','.','4','.','0',';', 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',0}; static WCHAR initstring_default[] = {'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',0}; IDataInitialize *datainit = NULL;