[PATCH 3/3] odbccp32: Implement SQLConfigDriver/W

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Tue Mar 21 19:15:18 CDT 2017


Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/odbccp32/odbccp32.c | 125 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 115 insertions(+), 10 deletions(-)

diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c
index 4e00f2a29f..baebd01310 100644
--- a/dlls/odbccp32/odbccp32.c
+++ b/dlls/odbccp32/odbccp32.c
@@ -63,6 +63,9 @@ static const WCHAR odbc_error_out_of_mem[] = {'O','u','t',' ','o','f',' ','m','e
 static const WCHAR odbc_error_invalid_param_sequence[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','e','q','u','e','n','c','e',0};
 static const WCHAR odbc_error_invalid_param_string[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','t','r','i','n','g',0};
 
+static BOOL (WINAPI *pConfigDriverW)(HWND hwnd, WORD request, const WCHAR *driver, const WCHAR *args, const WCHAR *msg, WORD msgmax, WORD *msgout);
+static BOOL (WINAPI *pConfigDriverA)(HWND hwnd, WORD request, const char *driver, const char *args, const char *msg, WORD msgmax, WORD *msgout);
+
 /* Push an error onto the error stack, taking care of ranges etc. */
 static void push_error(int code, LPCWSTR msg)
 {
@@ -248,22 +251,124 @@ BOOL WINAPI SQLConfigDataSource(HWND hwndParent, WORD fRequest,
     return TRUE;
 }
 
-BOOL WINAPI SQLConfigDriverW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver,
-               LPCWSTR lpszArgs, LPWSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut)
+BOOL WINAPI SQLConfigDriverW(HWND hwnd, WORD request, LPCWSTR driver,
+               LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
 {
+    static WCHAR reg_driver[] = {'d','r','i','v','e','r',0};
+    long ret;
+    HMODULE hmod;
+    HKEY hkey;
+    WCHAR *filename = NULL;
+    DWORD size = 0, type;
+    BOOL funcret = FALSE;
+
     clear_errors();
-    FIXME("(%p %d %s %s %p %d %p)\n", hwndParent, fRequest, debugstr_w(lpszDriver),
-          debugstr_w(lpszArgs), lpszMsg, cbMsgMax, pcbMsgOut);
-    return TRUE;
+    TRACE("(%p %d %s %s %p %d %p)\n", hwnd, request, debugstr_w(driver),
+          debugstr_w(args), msg, msgmax, msgout);
+
+    if ((ret = RegOpenKeyW(HKEY_CURRENT_USER, odbcini, &hkey)) == ERROR_SUCCESS)
+    {
+        HKEY hkeydriver;
+
+        if ((ret = RegOpenKeyW(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
+        {
+            ret = RegGetValueW(hkeydriver, NULL, reg_driver, RRF_RT_REG_SZ, &type, NULL, &size);
+            if(ret == ERROR_MORE_DATA)
+            {
+                filename = HeapAlloc(GetProcessHeap(), 0, size);
+                if(!filename)
+                {
+                    RegCloseKey(hkeydriver);
+                    RegCloseKey(hkey);
+                    return ODBC_ERROR_OUT_OF_MEM;
+                }
+                ret = RegGetValueW(hkeydriver, NULL, driver, RRF_RT_REG_SZ, &type, filename, &size);
+            }
+
+            RegCloseKey(hkeydriver);
+        }
+
+        RegCloseKey(hkey);
+    }
+
+    if(ret != ERROR_SUCCESS)
+    {
+        HeapFree(GetProcessHeap(), 0, filename);
+        return ODBC_ERROR_INVALID_DSN;
+    }
+
+    hmod = LoadLibraryW(filename);
+    HeapFree(GetProcessHeap(), 0, filename);
+    if(!hmod)
+        return ODBC_ERROR_LOAD_LIB_FAILED;
+
+    pConfigDriverW = (void*) GetProcAddress(hmod, "ConfigDriverW");
+    if(pConfigDriverW)
+        funcret = pConfigDriverW(hwnd, request, driver, args, msg, msgmax, msgout);
+
+    FreeLibrary(hmod);
+
+    return funcret;
 }
 
-BOOL WINAPI SQLConfigDriver(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver,
-               LPCSTR lpszArgs, LPSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut)
+BOOL WINAPI SQLConfigDriver(HWND hwnd, WORD request, LPCSTR driver,
+               LPCSTR args, LPSTR msg, WORD msgmax, WORD *msgout)
 {
+    long ret;
+    HMODULE hmod;
+    HKEY hkey;
+    char *filename = NULL;
+    DWORD size = 0, type;
+    BOOL funcret = FALSE;
+
     clear_errors();
-    FIXME("(%p %d %s %s %p %d %p)\n", hwndParent, fRequest, debugstr_a(lpszDriver),
-          debugstr_a(lpszArgs), lpszMsg, cbMsgMax, pcbMsgOut);
-    return TRUE;
+    TRACE("(%p %d %s %s %p %d %p)\n", hwnd, request, debugstr_a(driver),
+          debugstr_a(args), msg, msgmax, msgout);
+
+    if ((ret = RegOpenKeyW(HKEY_CURRENT_USER, odbcini, &hkey)) == ERROR_SUCCESS)
+    {
+        HKEY hkeydriver;
+
+        if ((ret = RegOpenKeyA(hkey, driver, &hkeydriver)) == ERROR_SUCCESS)
+        {
+            ret = RegGetValueA(hkeydriver, NULL, "Driver", RRF_RT_REG_SZ, &type, NULL, &size);
+            if(ret == ERROR_MORE_DATA)
+            {
+                filename = HeapAlloc(GetProcessHeap(), 0, size);
+                if(!filename)
+                {
+                    RegCloseKey(hkeydriver);
+                    RegCloseKey(hkey);
+                    return ODBC_ERROR_OUT_OF_MEM;
+                }
+
+                ret = RegGetValueA(hkeydriver, NULL, driver, RRF_RT_REG_SZ, &type, filename, &size);
+            }
+
+            RegCloseKey(hkeydriver);
+        }
+
+        RegCloseKey(hkey);
+    }
+
+    if(ret != ERROR_SUCCESS)
+    {
+        HeapFree(GetProcessHeap(), 0, filename);
+        return ODBC_ERROR_INVALID_DSN;
+    }
+
+    hmod = LoadLibraryA(filename);
+    HeapFree(GetProcessHeap(), 0, filename);
+    if(!hmod)
+        return ODBC_ERROR_LOAD_LIB_FAILED;
+
+    pConfigDriverA = (void*) GetProcAddress(hmod, "ConfigDriver");
+    if(pConfigDriverA)
+        funcret = pConfigDriverA(hwnd, request, driver, args, msg, msgmax, msgout);
+
+    FreeLibrary(hmod);
+
+    return funcret;
 }
 
 BOOL WINAPI SQLCreateDataSourceW(HWND hwnd, LPCWSTR lpszDS)
-- 
2.11.0




More information about the wine-patches mailing list