[PATCH] msado15: Implement _Connection Open

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Tue Oct 20 04:14:19 CDT 2020


Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at 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;
-- 
2.28.0




More information about the wine-devel mailing list