Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/msado15/Makefile.in | 2 +- dlls/msado15/connection.c | 135 ++++++++++++++++++++++++++++++++++- dlls/msado15/tests/msado15.c | 6 +- 3 files changed, 137 insertions(+), 6 deletions(-)
diff --git a/dlls/msado15/Makefile.in b/dlls/msado15/Makefile.in index 9852e0863dd..e64da605473 100644 --- a/dlls/msado15/Makefile.in +++ b/dlls/msado15/Makefile.in @@ -1,5 +1,5 @@ MODULE = msado15.dll -IMPORTS = oleaut32 +IMPORTS = oleaut32 ole32
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/msado15/connection.c b/dlls/msado15/connection.c index 2773850236d..3eb17d8e8be 100644 --- a/dlls/msado15/connection.c +++ b/dlls/msado15/connection.c @@ -23,6 +23,7 @@ #include "initguid.h" #include "ocidl.h" #include "objbase.h" +#include "msdasc.h" #include "olectl.h" #include "msado15_backcompat.h"
@@ -33,6 +34,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(msado15);
+DEFINE_GUID(DBPROPSET_DBINIT, 0xc8b522bc, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d); + struct connection;
struct connection_point @@ -54,8 +57,10 @@ struct connection LONG timeout; WCHAR *datasource; WCHAR *provider; + WCHAR *dsn; ConnectModeEnum mode; CursorLocationEnum location; + IUnknown *session; struct connection_point cp_connev; };
@@ -98,8 +103,10 @@ static ULONG WINAPI connection_Release( _Connection *iface ) if (connection->cp_connev.sinks[i]) IUnknown_Release( connection->cp_connev.sinks[i] ); } + if (connection->session) IUnknown_Release(connection->session); heap_free( connection->cp_connev.sinks ); heap_free( connection->provider ); + heap_free( connection->dsn ); heap_free( connection->datasource ); heap_free( connection ); } @@ -240,6 +247,12 @@ static HRESULT WINAPI connection_Close( _Connection *iface )
if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
+ if (connection->session) + { + IUnknown_Release(connection->session); + connection->session = NULL; + } + connection->state = adStateClosed; return S_OK; } @@ -269,17 +282,133 @@ static HRESULT WINAPI connection_RollbackTrans( _Connection *iface ) return E_NOTIMPL; }
+static void parse_connection_string(struct connection *connection, BSTR connect_str) +{ + WCHAR *temp, *save; + + temp = wcstok_s(connect_str, L";", &save); + while(temp) + { + if (!wcsncmp(temp, L"Provider=", 9)) + { + heap_free( connection->provider ); + connection->provider = SysAllocString(temp+9); + + TRACE("Provider: %s\n", debugstr_w(connection->provider)); + } + else if (!wcsncmp(temp, L"Data Source=", 12)) + { + heap_free( connection->dsn ); + connection->dsn = SysAllocString(temp+12); + + TRACE("Data Source: %s\n", debugstr_w(connection->dsn)); + } + else if (!wcsncmp(temp, L"Persist Security Info=", 22)) + { + FIXME("Persist Security not handled yet.\n"); + } + else + FIXME("%s unsupport option\n", debugstr_w(temp)); + + temp = wcstok_s(NULL, L";", &save); + } +} + static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BSTR userid, BSTR password, LONG options ) { struct connection *connection = impl_from_Connection( iface ); - FIXME( "%p, %s, %s, %p, %08x\n", iface, debugstr_w(connect_str), debugstr_w(userid), + IDBProperties *props; + IDBInitialize *dbinit; + IDBCreateSession *session = NULL; + HRESULT hr; + int i; + DBPROP dbprop[2]; + DBPROPSET propset; + GUID provider; + + TRACE( "%p, %s, %s, %p, %08x\n", iface, debugstr_w(connect_str), debugstr_w(userid), password, options );
if (connection->state == adStateOpen) return MAKE_ADO_HRESULT( adErrObjectOpen );
+ if (!connect_str) + return E_FAIL; + + parse_connection_string(connection, connect_str); + if (FAILED(CLSIDFromProgID(connection->provider, &provider))) + return E_FAIL; + + hr = CoCreateInstance(&provider, NULL, CLSCTX_INPROC_SERVER, &IID_IDBInitialize,(void**)&dbinit); + if (FAILED(hr)) + return E_FAIL; + + hr = IDBInitialize_QueryInterface(dbinit, &IID_IDBProperties, (void**)&props); + if (FAILED(hr)) + goto done; + + /* TODO - Update username/password if required. */ + if ((userid && userid[0] != NULL) || (password && password[0] != NULL)) + FIXME("Username/password parameters currently not supported\n"); + + for (i = 0 ; i < ARRAY_SIZE(dbprop); i++) + { + VariantInit(&dbprop[i].vValue); + dbprop[i].dwOptions = DBPROPOPTIONS_REQUIRED; + } + + dbprop[0].dwPropertyID = DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO; + V_VT(&(dbprop[0].vValue)) = VT_BOOL; + V_BOOL(&(dbprop[0].vValue)) = VARIANT_TRUE; + + dbprop[1].dwPropertyID = DBPROP_INIT_DATASOURCE; + V_VT(&(dbprop[1].vValue)) = VT_BSTR; + V_BSTR(&(dbprop[1].vValue)) = SysAllocString(connection->dsn); + + propset.rgProperties = dbprop; + propset.cProperties = 2; + propset.guidPropertySet = DBPROPSET_DBINIT; + + hr = IDBProperties_SetProperties(props, 1, &propset); + if (FAILED(hr)) + goto done; + + for (i = 0 ; i < ARRAY_SIZE(dbprop) ; i++) + VariantClear(&dbprop[i].vValue); + + hr = IDBInitialize_Initialize(dbinit); + if (FAILED(hr)) + goto done; + + hr = IDBInitialize_QueryInterface(dbinit, &IID_IDBCreateSession, (void**)&session); + if (FAILED(hr)) + goto done; + + hr = IDBCreateSession_CreateSession(session, NULL, &IID_IUnknown, &connection->session); + if (FAILED(hr)) + goto done; + + /* TODO ISessionProperties_SetProperties(...) */ + connection->state = adStateOpen; - return S_OK; + hr = S_OK; + +done: + if (FAILED(hr) && connection->session) + { + IUnknown_Release(connection->session); + connection->session = NULL; + } + + if (session) IDBCreateSession_Release(session); + + if (dbinit) { + IDBInitialize_Uninitialize(dbinit); + IDBInitialize_Release(dbinit); + } + + TRACE("ret 0x%08x\n", hr); + return hr; }
static HRESULT WINAPI connection_get_Errors( _Connection *iface, Errors **obj ) @@ -681,9 +810,11 @@ HRESULT Connection_create( void **obj ) connection->state = adStateClosed; connection->timeout = 30; connection->datasource = NULL; + connection->dsn = NULL; connection->provider = SysAllocString(L"MSDASQL"); connection->mode = adModeUnknown; connection->location = adUseServer; + connection->session = NULL;
connection->cp_connev.conn = connection; connection->cp_connev.riid = &DIID_ConnectionEvents; diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 378c2eb918c..bf8a8e4ea61 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -808,12 +808,12 @@ if (0) /* Crashes on windows */ ok(!wcscmp(str, str2), "wrong string %s\n", wine_dbgstr_w(str2));
hr = _Connection_Open(connection, NULL, NULL, NULL, 0); - todo_wine ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr); + ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
/* Open adds trailing ; if it's missing */ str3 = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test;"); hr = _Connection_Open(connection, NULL, NULL, NULL, adConnectUnspecified); - todo_wine ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr); + ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
str2 = NULL; hr = _Connection_get_ConnectionString(connection, &str2); @@ -821,7 +821,7 @@ if (0) /* Crashes on windows */ todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
hr = _Connection_Open(connection, str, NULL, NULL, adConnectUnspecified); - todo_wine ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr); + ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr); SysFreeString(str);
str2 = NULL;