Module: wine Branch: master Commit: ec4de1f9fe0f7dd4138c9d8a721515d40015aa75 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ec4de1f9fe0f7dd4138c9d8a72...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Wed Dec 26 20:53:45 2012 +0400
oledb32: Partial implementation of GetDataSource().
---
dlls/oledb32/datainit.c | 130 +++++++++++++++++++++++++++++++++------- dlls/oledb32/tests/database.c | 42 +++++++++----- include/oledberr.h | 2 + 3 files changed, 137 insertions(+), 37 deletions(-)
diff --git a/dlls/oledb32/datainit.c b/dlls/oledb32/datainit.c index 78a005d..1316c0f 100644 --- a/dlls/oledb32/datainit.c +++ b/dlls/oledb32/datainit.c @@ -273,21 +273,121 @@ static ULONG WINAPI datainit_Release(IDataInitialize *iface) return ref; }
+static void free_dbpropset(ULONG count, DBPROPSET *propset) +{ + int i; + + for (i = 0; i < count; i++) + { + int p; + + for (p = 0; p < propset[i].cProperties; p++) + VariantClear(&propset[i].rgProperties[p].vValue); + + CoTaskMemFree(propset[i].rgProperties); + } + CoTaskMemFree(propset); +} + /*** IDataInitialize methods ***/ -static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *pUnkOuter, DWORD dwClsCtx, - LPWSTR pwszInitializationString, REFIID riid, IUnknown **ppDataSource) +static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *outer, DWORD clsctx, + LPWSTR initstring, REFIID riid, IUnknown **datasource) { + 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); + WCHAR *prov = NULL; + CLSID provclsid; + HRESULT hr;
- FIXME("(%p)->(%p %d %s %s %p)\n", This, pUnkOuter, dwClsCtx, debugstr_w(pwszInitializationString), - debugstr_guid(riid), ppDataSource); + FIXME("(%p)->(%p 0x%x %s %s %p): semi-stub\n", This, outer, clsctx, debugstr_w(initstring), debugstr_guid(riid), datasource);
- if(IsEqualIID(riid, &IID_IDBInitialize)) + /* first get provider name */ + provclsid = IID_NULL; + if (initstring && (prov = strstrW(initstring, providerW))) { - return create_db_init( (LPVOID*)ppDataSource); + WCHAR *start, *progid; + int len; + + prov += sizeof(providerW)/sizeof(WCHAR)-1; + start = prov; + while (*prov && *prov != ';') + ++prov; + TRACE("got provider %s\n", debugstr_wn(start, prov-start)); + + len = prov - start; + progid = CoTaskMemAlloc((len+1)*sizeof(WCHAR)); + if (!progid) return E_OUTOFMEMORY; + + memcpy(progid, start, len*sizeof(WCHAR)); + progid[len] = 0; + + hr = CLSIDFromProgID(progid, &provclsid); + CoTaskMemFree(progid); + if (FAILED(hr)) + { + ERR("provider %s not registered\n", debugstr_wn(start, prov-start)); + return hr; + } + } + else + { + hr = CLSIDFromProgID(msdasqlW, &provclsid); + if (FAILED(hr)) + ERR("ODBC provider for OLE DB not registered\n"); }
- return E_NOTIMPL; + /* 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; + + hr = IUnknown_QueryInterface(*datasource, &IID_IDBProperties, (void**)&dbprops); + if (FAILED(hr)) + { + WARN("provider doesn't support IDBProperties\n"); + return hr; + } + + prop = DBPROP_INIT_DATASOURCE; + propidset.rgPropertyIDs = ∝ + propidset.cPropertyIDs = 1; + propidset.guidPropertySet = DBPROPSET_DBINIT; + count = 0; + propset = NULL; + hr = IDBProperties_GetProperties(dbprops, 1, &propidset, &count, &propset); + IDBProperties_Release(dbprops); + if (FAILED(hr)) + { + WARN("GetProperties failed for datasource, 0x%08x\n", hr); + return hr; + } + + TRACE("initial data source provider %s\n", debugstr_w(V_BSTR(&propset->rgProperties[0].vValue))); + initprov = IID_NULL; + CLSIDFromProgID(V_BSTR(&propset->rgProperties[0].vValue), &initprov); + free_dbpropset(count, propset); + + if (!IsEqualIID(&provclsid, &initprov)) return DB_E_MISMATCHEDPROVIDER; + } + + if (!*datasource) + { + if (!IsEqualIID(&provclsid, &IID_NULL)) + hr = CoCreateInstance(&provclsid, outer, clsctx, riid, (void**)datasource); + + if (FAILED(hr) && IsEqualIID(riid, &IID_IDBInitialize)) + hr = create_db_init((void**)datasource); + } + + /* FIXME: set properties from init string */ + + return hr; }
/* returns character length of string representation */ @@ -342,22 +442,6 @@ static WCHAR *get_propinfo_descr(DBPROP *prop, DBPROPINFOSET *propinfoset) return NULL; }
-static void free_dbpropset(ULONG count, DBPROPSET *propset) -{ - int i; - - for (i = 0; i < count; i++) - { - int p; - - for (p = 0; p < propset[i].cProperties; p++) - VariantClear(&propset[i].rgProperties[p].vValue); - - CoTaskMemFree(propset[i].rgProperties); - } - CoTaskMemFree(propset); -} - static void free_dbpropinfoset(ULONG count, DBPROPINFOSET *propinfoset) { int i; diff --git a/dlls/oledb32/tests/database.c b/dlls/oledb32/tests/database.c index f093d17..ede1074 100644 --- a/dlls/oledb32/tests/database.c +++ b/dlls/oledb32/tests/database.c @@ -30,22 +30,17 @@
#include "wine/test.h"
- -static void test_database(void) +static void test_GetDataSource(WCHAR *initstring) { - HRESULT hr; - IDBInitialize *dbinit = NULL; IDataInitialize *datainit = NULL; + IDBInitialize *dbinit = NULL; + HRESULT hr;
hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit); - if(FAILED(hr)) - { - win_skip("Unable to load oledb library\n"); - return; - } - - hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, NULL, &IID_IDBInitialize, (IUnknown **)&dbinit); ok(hr == S_OK, "got %08x\n", hr); + + /* a failure to create data source here may indicate provider is simply not present */ + hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring, &IID_IDBInitialize, (IUnknown**)&dbinit); if(SUCCEEDED(hr)) { IDBProperties *props = NULL; @@ -53,16 +48,35 @@ static void test_database(void) hr = IDBInitialize_QueryInterface(dbinit, &IID_IDBProperties, (void**)&props); ok(hr == S_OK, "got %08x\n", hr); if(SUCCEEDED(hr)) - { IDBProperties_Release(props); - } - IDBInitialize_Release(dbinit); }
IDataInitialize_Release(datainit); }
+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, + '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; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit); + if (FAILED(hr)) + { + win_skip("Unable to load oledb library\n"); + return; + } + IDataInitialize_Release(datainit); + + test_GetDataSource(NULL); + test_GetDataSource(initstring_jet); + test_GetDataSource(initstring_default); +} + START_TEST(database) { OleInitialize(NULL); diff --git a/include/oledberr.h b/include/oledberr.h index 94db602..c2033b6 100644 --- a/include/oledberr.h +++ b/include/oledberr.h @@ -35,6 +35,8 @@
#define DB_E_DATAOVERFLOW 0x80040e57
+#define DB_E_MISMATCHEDPROVIDER 0x80040e75 + #define DB_S_ERRORSOCCURRED 0x00040eda
#endif /* __WINE_OLEDBERR_H */