oledb32: Partial implementation of GetDataSource() (try2)
Nikolay Sivov
nsivov at codeweavers.com
Tue Dec 25 01:00:57 CST 2012
try2: fixed test crashes
-------------- next part --------------
>From 34abe2a3d703cc9263c6a565152e8a6b56a85b8b Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue, 25 Dec 2012 11:01:54 +0400
Subject: [PATCH 1/1] 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..a3a5687 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)*sizeof(WCHAR);
+ progid = CoTaskMemAlloc(len + sizeof(WCHAR));
+ if (!progid) return E_OUTOFMEMORY;
+
+ memcpy(progid, start, len);
+ 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 */
--
1.7.10.4
More information about the wine-patches
mailing list