Alistair Leslie-Hughes : odbccp32: Implement SQLWriteDSNToIni/W.
Alexandre Julliard
julliard at winehq.org
Mon Jun 7 15:02:06 CDT 2021
Module: wine
Branch: stable
Commit: f4d30930a653aea1072ef3e08638fd373fd14da3
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f4d30930a653aea1072ef3e08638fd373fd14da3
Author: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Date: Fri Feb 5 16:19:45 2021 +1100
odbccp32: Implement SQLWriteDSNToIni/W.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50150
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit ea3096bdab8fb865f63496613d1db09a105330dc)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>
---
dlls/odbccp32/odbccp32.c | 72 +++++++++++++++++++++++++++---
dlls/odbccp32/tests/misc.c | 108 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 175 insertions(+), 5 deletions(-)
diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c
index 420f206b700..1c46584cd29 100644
--- a/dlls/odbccp32/odbccp32.c
+++ b/dlls/odbccp32/odbccp32.c
@@ -1691,16 +1691,78 @@ BOOL WINAPI SQLValidDSN(LPCSTR lpszDSN)
BOOL WINAPI SQLWriteDSNToIniW(LPCWSTR lpszDSN, LPCWSTR lpszDriver)
{
+ DWORD ret;
+ HKEY hkey, hkeydriver;
+ WCHAR filename[MAX_PATH];
+
+ TRACE("%s %s\n", debugstr_w(lpszDSN), debugstr_w(lpszDriver));
+
clear_errors();
- FIXME("%s %s\n", debugstr_w(lpszDSN), debugstr_w(lpszDriver));
- return TRUE;
+
+ if (!SQLValidDSNW(lpszDSN))
+ {
+ push_error(ODBC_ERROR_INVALID_DSN, odbc_error_invalid_dsn);
+ return FALSE;
+ }
+
+ /* It doesn't matter if we cannot find the driver, windows just writes a blank value. */
+ filename[0] = 0;
+ if (RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey) == ERROR_SUCCESS)
+ {
+ HKEY hkeydriver;
+
+ if (RegOpenKeyW(hkey, lpszDriver, &hkeydriver) == ERROR_SUCCESS)
+ {
+ DWORD size = MAX_PATH * sizeof(WCHAR);
+ RegGetValueW(hkeydriver, NULL, L"driver", RRF_RT_REG_SZ, NULL, filename, &size);
+ RegCloseKey(hkeydriver);
+ }
+ RegCloseKey(hkey);
+ }
+
+ if ((ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\ODBC\\ODBC.INI", &hkey)) == ERROR_SUCCESS)
+ {
+ HKEY sources;
+
+ if ((ret = RegCreateKeyW(hkey, L"ODBC Data Sources", &sources)) == ERROR_SUCCESS)
+ {
+ RegSetValueExW(sources, lpszDSN, 0, REG_SZ, (BYTE*)lpszDriver, (lstrlenW(lpszDriver)+1)*sizeof(WCHAR));
+ RegCloseKey(sources);
+
+ RegDeleteTreeW(hkey, lpszDSN);
+ if ((ret = RegCreateKeyW(hkey, lpszDSN, &hkeydriver)) == ERROR_SUCCESS)
+ {
+ RegSetValueExW(sources, L"driver", 0, REG_SZ, (BYTE*)filename, (lstrlenW(filename)+1)*sizeof(WCHAR));
+ RegCloseKey(hkeydriver);
+ }
+ }
+ RegCloseKey(hkey);
+ }
+
+ if (ret != ERROR_SUCCESS)
+ push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);
+
+ return ret == ERROR_SUCCESS;
}
BOOL WINAPI SQLWriteDSNToIni(LPCSTR lpszDSN, LPCSTR lpszDriver)
{
- clear_errors();
- FIXME("%s %s\n", debugstr_a(lpszDSN), debugstr_a(lpszDriver));
- return TRUE;
+ BOOL ret = FALSE;
+ WCHAR *dsn, *driver;
+
+ TRACE("%s %s\n", debugstr_a(lpszDSN), debugstr_a(lpszDriver));
+
+ dsn = SQLInstall_strdup(lpszDSN);
+ driver = SQLInstall_strdup(lpszDriver);
+ if (dsn && driver)
+ ret = SQLWriteDSNToIniW(dsn, driver);
+ else
+ push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
+
+ heap_free(dsn);
+ heap_free(driver);
+
+ return ret;
}
BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
diff --git a/dlls/odbccp32/tests/misc.c b/dlls/odbccp32/tests/misc.c
index 0120504227d..f52dcee7acd 100644
--- a/dlls/odbccp32/tests/misc.c
+++ b/dlls/odbccp32/tests/misc.c
@@ -771,6 +771,113 @@ static void test_SQLConfigDataSource(void)
check_error(ODBC_ERROR_COMPONENT_NOT_FOUND);
}
+static void test_SQLWriteDSNToIni(void)
+{
+ BOOL ret;
+ char buffer[MAX_PATH];
+ char path[MAX_PATH];
+ DWORD type, size;
+
+ SQLSetConfigMode(ODBC_SYSTEM_DSN);
+
+ ret = SQLWriteDSNToIni("wine_dbs", "SQL Server");
+ if (!ret)
+ {
+ win_skip("Doesn't have permission to write a System DSN\n");
+ return;
+ }
+
+ if(ret)
+ {
+ HKEY hkey;
+ LONG res;
+
+ res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\ODBC\\ODBC.INI\\ODBC Data Sources", 0,
+ KEY_READ, &hkey);
+ ok(res == ERROR_SUCCESS, "RegOpenKeyExW failed\n");
+ if (res == ERROR_SUCCESS)
+ {
+ type = 0xdeadbeef;
+ size = MAX_PATH;
+
+ memset(buffer, 0, sizeof(buffer));
+ res = RegQueryValueExA(hkey, "wine_dbs", NULL, &type, (BYTE *)buffer, &size);
+ ok(res == ERROR_SUCCESS, "RegGetValueA failed\n");
+ ok(type == REG_SZ, "got %u\n", type);
+ ok(!strcmp(buffer, "SQL Server"), "incorrect string '%s'\n", buffer);
+
+ RegCloseKey(hkey);
+ }
+
+ res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\ODBC\\ODBC.INI\\wine_dbs", 0,
+ KEY_READ, &hkey);
+ ok(res == ERROR_SUCCESS, "RegOpenKeyExW failed\n");
+ if (res == ERROR_SUCCESS)
+ {
+ type = 0xdeadbeef;
+ size = MAX_PATH;
+
+ memset(path, 0, sizeof(path));
+ res = RegQueryValueExA(hkey, "driver", NULL, &type, (BYTE *)path, &size);
+ ok(res == ERROR_SUCCESS, "RegGetValueA failed\n");
+ ok(type == REG_SZ, "got %u\n", type);
+ /* WINE doesn't have a 'SQL Server' driver available */
+ todo_wine ok(strlen(path) != 0, "Invalid value\n");
+
+ RegCloseKey(hkey);
+ }
+
+ ret = SQLRemoveDSNFromIni("wine_dbs");
+ ok(ret, "got %d\n", ret);
+ }
+
+ /* Show that values are writen, even though an invalid driver was specified. */
+ ret = SQLWriteDSNToIni("wine_mis", "Missing Access Driver (*.mis)");
+ ok(ret, "got %d\n", ret);
+ if(ret)
+ {
+ HKEY hkey;
+ LONG res;
+
+ res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\ODBC\\ODBC.INI\\ODBC Data Sources", 0,
+ KEY_READ, &hkey);
+ ok(res == ERROR_SUCCESS, "RegOpenKeyExW failed\n");
+ if (res == ERROR_SUCCESS)
+ {
+ type = 0xdeadbeef;
+ size = MAX_PATH;
+
+ memset(buffer, 0, sizeof(buffer));
+ res = RegQueryValueExA(hkey, "wine_mis", NULL, &type, (BYTE *)buffer, &size);
+ ok(res == ERROR_SUCCESS, "RegGetValueA failed\n");
+ ok(type == REG_SZ, "got %u\n", type);
+ ok(!strcmp(buffer, "Missing Access Driver (*.mis)"), "incorrect string '%s'\n", buffer);
+
+ RegCloseKey(hkey);
+ }
+
+ res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\ODBC\\ODBC.INI\\wine_mis", 0,
+ KEY_READ, &hkey);
+ ok(res == ERROR_SUCCESS, "RegOpenKeyExW failed\n");
+ if (res == ERROR_SUCCESS)
+ {
+ type = 0xdeadbeef;
+ size = MAX_PATH;
+
+ memset(path, 0, sizeof(path));
+ res = RegQueryValueExA(hkey, "driver", NULL, &type, (BYTE *)path, &size);
+ ok(res == ERROR_SUCCESS, "RegGetValueA failed\n");
+ ok(type == REG_SZ, "got %u\n", type);
+ ok(strlen(path) == 0, "Invalid value\n");
+
+ RegCloseKey(hkey);
+ }
+
+ ret = SQLRemoveDSNFromIni("wine_mis");
+ ok(ret, "got %d\n", ret);
+ }
+}
+
START_TEST(misc)
{
test_SQLConfigMode();
@@ -785,4 +892,5 @@ START_TEST(misc)
test_SQLValidDSN();
test_SQLValidDSNW();
test_SQLConfigDataSource();
+ test_SQLWriteDSNToIni();
}
More information about the wine-cvs
mailing list