From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- dlls/msado15/connection.c | 49 ++++++++---- dlls/msado15/tests/Makefile.in | 2 +- dlls/msado15/tests/msado15.c | 139 +++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 15 deletions(-)
diff --git a/dlls/msado15/connection.c b/dlls/msado15/connection.c index bc74cb98e02..568eb8b12c9 100644 --- a/dlls/msado15/connection.c +++ b/dlls/msado15/connection.c @@ -59,6 +59,7 @@ struct connection ConnectModeEnum mode; CursorLocationEnum location; IUnknown *session; + IDBInitialize *dso; struct connection_point cp_connev; };
@@ -107,6 +108,11 @@ static ULONG WINAPI connection_Release( _Connection *iface ) IUnknown_Release( connection->cp_connev.sinks[i] ); } if (connection->session) IUnknown_Release( connection->session ); + if (connection->dso) + { + IDBInitialize_Uninitialize( connection->dso ); + IDBInitialize_Release( connection->dso ); + } free( connection->cp_connev.sinks ); free( connection->provider ); free( connection->datasource ); @@ -291,6 +297,12 @@ static HRESULT WINAPI connection_Close( _Connection *iface ) IUnknown_Release( connection->session ); connection->session = NULL; } + if (connection->dso) + { + IDBInitialize_Uninitialize( connection->dso ); + IDBInitialize_Release( connection->dso ); + connection->dso = NULL; + }
connection->state = adStateClosed; return S_OK; @@ -374,7 +386,6 @@ static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BST { struct connection *connection = impl_from_Connection( iface ); IDBProperties *props; - IDBInitialize *dbinit = NULL; IDataInitialize *datainit; IDBCreateSession *session = NULL; HRESULT hr; @@ -387,15 +398,15 @@ static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BST if ((hr = CoCreateInstance( &CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize, (void **)&datainit )) != S_OK) return hr; if ((hr = IDataInitialize_GetDataSource( datainit, NULL, CLSCTX_INPROC_SERVER, connect_str, &IID_IDBInitialize, - (IUnknown **)&dbinit )) != S_OK) goto done; - if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBProperties, (void **)&props )) != S_OK) goto done; + (IUnknown **)&connection->dso )) != S_OK) goto done; + if ((hr = IDBInitialize_QueryInterface( connection->dso, &IID_IDBProperties, (void **)&props )) != S_OK) goto done;
/* TODO - Update username/password if required. */ if ((userid && *userid) || (password && *password)) FIXME("Username/password parameters currently not supported\n");
- if ((hr = IDBInitialize_Initialize( dbinit )) != S_OK) goto done; - if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBCreateSession, (void **)&session )) != S_OK) goto done; + if ((hr = IDBInitialize_Initialize( connection->dso )) != S_OK) goto done; + if ((hr = IDBInitialize_QueryInterface( connection->dso, &IID_IDBCreateSession, (void **)&session )) != S_OK) goto done; if ((hr = IDBCreateSession_CreateSession( session, NULL, &IID_IUnknown, &connection->session )) == S_OK) { connection->state = adStateOpen; @@ -403,16 +414,20 @@ static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BST IDBCreateSession_Release( session );
done: - if (hr != S_OK && connection->session) + if (hr != S_OK) { - IUnknown_Release( connection->session ); + if(connection->session) + IUnknown_Release( connection->session ); connection->session = NULL; + + if (connection->dso) + { + IDBInitialize_Uninitialize( connection->dso ); + IDBInitialize_Release( connection->dso ); + } + connection->dso = NULL; } - if (dbinit) - { - IDBInitialize_Uninitialize( dbinit ); - IDBInitialize_Release( dbinit ); - } + IDataInitialize_Release( datainit );
TRACE("ret 0x%08lx\n", hr); @@ -914,8 +929,13 @@ static ULONG WINAPI adoconstruct_Release(ADOConnectionConstruction15 *iface) static HRESULT WINAPI adoconstruct_get_DSO(ADOConnectionConstruction15 *iface, IUnknown **dso) { struct connection *connection = impl_from_ADOConnectionConstruction15( iface ); - FIXME("%p, %p\n", connection, dso); - return E_NOTIMPL; + TRACE("%p, %p\n", connection, dso); + + *dso = NULL; + if (connection->dso) + IDBInitialize_QueryInterface( connection->dso, &IID_IUnknown, (void**)dso ); + + return S_OK; }
static HRESULT WINAPI adoconstruct_get_Session(ADOConnectionConstruction15 *iface, IUnknown **session) @@ -968,6 +988,7 @@ HRESULT Connection_create( void **obj ) connection->mode = adModeUnknown; connection->location = adUseServer; connection->session = NULL; + connection->dso = NULL;
connection->cp_connev.conn = connection; connection->cp_connev.riid = &DIID_ConnectionEvents; diff --git a/dlls/msado15/tests/Makefile.in b/dlls/msado15/tests/Makefile.in index 6af5852c224..a6c162d5b3f 100644 --- a/dlls/msado15/tests/Makefile.in +++ b/dlls/msado15/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = msado15.dll -IMPORTS = oleaut32 ole32 +IMPORTS = oleaut32 ole32 odbccp32
SOURCES = \ msado15.c diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index f7707a03388..ebfa7bdbce2 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -25,11 +25,15 @@ #include <msado15_backcompat.h> #include "wine/test.h" #include "msdasql.h" +#include "odbcinst.h"
DEFINE_GUID(DBPROPSET_ROWSET, 0xc8b522be, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
#define MAKE_ADO_HRESULT( err ) MAKE_HRESULT( SEVERITY_ERROR, FACILITY_CONTROL, err )
+static BOOL db_created; +static char mdbpath[MAX_PATH]; + #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
@@ -1408,7 +1412,14 @@ static void test_Connection(void) hr = _Connection_QueryInterface(connection, &IID_ADOConnectionConstruction15, (void**)&construct); ok(hr == S_OK, "Failed to get ADOConnectionConstruction15 interface %08lx\n", hr); if (hr == S_OK) + { + IUnknown *dso =( IUnknown *)0xdeadbeef; + + hr = ADOConnectionConstruction15_get_DSO(construct, &dso); + ok(hr == S_OK, "Unexpected hr 0x%08lx\n", hr); + ok(dso == NULL, "Unexpected value\n"); ADOConnectionConstruction15_Release(construct); + }
if (0) /* Crashes on windows */ { @@ -1566,6 +1577,57 @@ if (0) /* Crashes on windows */ ok(!_Connection_Release(connection), "_Connection not released\n"); }
+static void test_Connection_Open(void) +{ + HRESULT hr; + _Connection *connection; + ADOConnectionConstruction15 *construct = NULL; + IUnknown *dso = NULL; + IDBInitialize *dbinit; + BSTR str; + + if (!db_created) + { + skip("Database not available, skipping tests\n"); + return; + } + + hr = CoCreateInstance(&CLSID_Connection, NULL, CLSCTX_INPROC_SERVER, &IID__Connection, (void**)&connection); + ok( hr == S_OK, "got %08lx\n", hr ); + + str = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_msado_test;"); + hr = _Connection_Open(connection, str, NULL, NULL, adConnectUnspecified); + ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr); + if( hr != S_OK) + goto done; + + hr = _Connection_QueryInterface(connection, &IID_ADOConnectionConstruction15, (void**)&construct); + ok(hr == S_OK, "Failed to get ADOConnectionConstruction15 interface %08lx\n", hr); + + hr = ADOConnectionConstruction15_get_DSO(construct, &dso); + ok(hr == S_OK, "Unexpected hr 0x%08lx\n", hr); + ok(dso != NULL, "Unexpected value\n"); + + hr = IUnknown_QueryInterface(dso, &IID_IDBInitialize, (void**)&dbinit); + ok(hr == S_OK, "Unexpected hr 0x%08lx\n", hr); + IDBInitialize_Release(dbinit); + + IUnknown_Release(dso); + + hr = _Connection_Close(connection); + ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr); + + dso = (IUnknown *)0xdeadbeef; + hr = ADOConnectionConstruction15_get_DSO(construct, &dso); + ok(hr == S_OK, "Unexpected hr 0x%08lx\n", hr); + ok(dso == NULL, "Unexpected value\n"); + + ADOConnectionConstruction15_Release(construct); + +done: + ok(!_Connection_Release(connection), "_Connection not released\n"); +} + static void test_Command(void) { HRESULT hr; @@ -1889,10 +1951,84 @@ static void test_ConnectionPoint(void) ok( !conn_event.refs, "got %ld\n", conn_event.refs ); }
+static void setup_database(void) +{ + char *driver; + DWORD code; + char buffer[1024]; + WORD size; + + if (winetest_interactive) + { + trace("assuming odbc 'wine_msado_test' is available\n"); + db_created = TRUE; + return; + } + + /* + * 32 bit Windows has a default driver for "Microsoft Access Driver" (Windows 7+) + * and has the ability to create files on the fly. + * + * 64 bit Windows ONLY has a driver for "SQL Server", which we cannot use since we don't have a + * server to connect to. + * + * The filename passed to CREATE_DB must end in mdb. + */ + GetTempPathA(sizeof(mdbpath), mdbpath); + strcat(mdbpath, "wine_msado_test.mdb"); + + driver = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof("DSN=wine_msado_test\0CREATE_DB=") + strlen(mdbpath) + 2); + memcpy(driver, "DSN=wine_msado_test\0CREATE_DB=", sizeof("DSN=wine_msado_test\0CREATE_DB=")); + strcat(driver+sizeof("DSN=wine_msado_test\0CREATE_DB=")-1, mdbpath); + + SQLSetConfigMode(ODBC_USER_DSN); + db_created = SQLConfigDataSource(NULL, ODBC_ADD_DSN, "Microsoft Access Driver (*.mdb)", driver); + if (!db_created) + { + SQLInstallerError(1, &code, buffer, sizeof(buffer), &size); + trace("code %ld, buffer %s, size %d\n", code, debugstr_a(buffer), size); + + HeapFree(GetProcessHeap(), 0, driver); + + return; + } + + memcpy(driver, "DSN=wine_msado_test\0DBQ=", sizeof("DSN=wine_msado_test\0DBQ=")); + strcat(driver+sizeof("DSN=wine_msado_test\0DBQ=")-1, mdbpath); + db_created = SQLConfigDataSource(NULL, ODBC_ADD_DSN, "Microsoft Access Driver (*.mdb)", driver); + + HeapFree(GetProcessHeap(), 0, driver); +} + +static void cleanup_database(void) +{ + BOOL ret; + + if (winetest_interactive) + return; + + ret = SQLConfigDataSource(NULL, ODBC_REMOVE_DSN, "Microsoft Access Driver (*.mdb)", "DSN=wine_msado_test\0\0"); + if (!ret) + { + DWORD code; + char buffer[1024]; + WORD size; + + SQLInstallerError(1, &code, buffer, sizeof(buffer), &size); + trace("code %ld, buffer %s, size %d\n", code, debugstr_a(buffer), size); + } + + DeleteFileA(mdbpath); +} + START_TEST(msado15) { CoInitialize( NULL ); + + setup_database(); + test_Connection(); + test_Connection_Open(); test_ConnectionPoint(); test_ADORecordsetConstruction(FALSE); test_ADORecordsetConstruction(TRUE); @@ -1900,5 +2036,8 @@ START_TEST(msado15) test_Recordset(); test_Stream(); test_Command(); + + cleanup_database(); + CoUninitialize(); }