[PATCH] odbccp32: Map system DSN requests to user DSN requests in SQLConfigDataSource.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50116 Signed-off-by: Hans Leidekker <hans(a)codeweavers.com> --- dlls/odbccp32/odbccp32.c | 54 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c index c842872fa6e..0e4a12534c8 100644 --- a/dlls/odbccp32/odbccp32.c +++ b/dlls/odbccp32/odbccp32.c @@ -338,10 +338,40 @@ fail: return FALSE; } +static WORD map_request(WORD request) +{ + switch (request) + { + case ODBC_ADD_DSN: + case ODBC_ADD_SYS_DSN: + return ODBC_ADD_DSN; + + case ODBC_CONFIG_DSN: + case ODBC_CONFIG_SYS_DSN: + return ODBC_CONFIG_DSN; + + case ODBC_REMOVE_DSN: + case ODBC_REMOVE_SYS_DSN: + return ODBC_REMOVE_DSN; + + default: + FIXME("unhandled request %u\n", request); + return 0; + } +} + +static UWORD get_config_mode(WORD request) +{ + if (request == ODBC_ADD_DSN || request == ODBC_CONFIG_DSN || request == ODBC_REMOVE_DSN) return ODBC_USER_DSN; + return ODBC_SYSTEM_DSN; +} + BOOL WINAPI SQLConfigDataSourceW(HWND hwnd, WORD request, LPCWSTR driver, LPCWSTR attributes) { HMODULE mod; BOOL ret = FALSE; + UWORD config_mode_prev = config_mode; + WORD mapped_request; TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_w(driver), debugstr_w(attributes)); if (TRACE_ON(odbc)) @@ -353,16 +383,24 @@ BOOL WINAPI SQLConfigDataSourceW(HWND hwnd, WORD request, LPCWSTR driver, LPCWST clear_errors(); + mapped_request = map_request(request); + if (!mapped_request) + return FALSE; + mod = load_config_driver(driver); if (!mod) return FALSE; + config_mode = get_config_mode(request); + pConfigDSNW = (void*)GetProcAddress(mod, "ConfigDSNW"); if(pConfigDSNW) - ret = pConfigDSNW(hwnd, request, driver, attributes); + ret = pConfigDSNW(hwnd, mapped_request, driver, attributes); else ERR("Failed to find ConfigDSNW\n"); + config_mode = config_mode_prev; + if (!ret) push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed); @@ -376,6 +414,8 @@ BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR a HMODULE mod; BOOL ret = FALSE; WCHAR *driverW; + UWORD config_mode_prev = config_mode; + WORD mapped_request; TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_a(driver), debugstr_a(attributes)); @@ -388,6 +428,10 @@ BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR a clear_errors(); + mapped_request = map_request(request); + if (!mapped_request) + return FALSE; + driverW = heap_strdupAtoW(driver); if (!driverW) { @@ -402,11 +446,13 @@ BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR a return FALSE; } + config_mode = get_config_mode(request); + pConfigDSN = (void*)GetProcAddress(mod, "ConfigDSN"); if (pConfigDSN) { TRACE("Calling ConfigDSN\n"); - ret = pConfigDSN(hwnd, request, driver, attributes); + ret = pConfigDSN(hwnd, mapped_request, driver, attributes); } else { @@ -418,11 +464,13 @@ BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR a attr = SQLInstall_strdup_multi(attributes); if(attr) - ret = pConfigDSNW(hwnd, request, driverW, attr); + ret = pConfigDSNW(hwnd, mapped_request, driverW, attr); heap_free(attr); } } + config_mode = config_mode_prev; + if (!ret) push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed); -- 2.28.0
Hi Hans, Based off MSDN for function SQLConfigDataSource. The mode is explicitly set to ODBC_USER_DSN or ODBC_SYSTEM_DSN and reset to ODBC_BOTH_DSN at the end of the function. https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlconfigdatasour... Regards Alistair On 12/11/20 9:35 pm, Hans Leidekker wrote:
Wine-Bug: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.winehq.org%2Fshow_bug.cgi%3Fid%3D50116&data=04%7C01%7C%7C83ee7661cbfa4308c87308d886f6ae3b%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637407741321031825%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Thek5pne7iRp4TyF4K%2BH2VBErtFRQo7sRpJ6U8u4Kw8%3D&reserved=0 Signed-off-by: Hans Leidekker <hans(a)codeweavers.com> --- dlls/odbccp32/odbccp32.c | 54 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-)
diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c index c842872fa6e..0e4a12534c8 100644 --- a/dlls/odbccp32/odbccp32.c +++ b/dlls/odbccp32/odbccp32.c @@ -338,10 +338,40 @@ fail: return FALSE; }
+static WORD map_request(WORD request) +{ + switch (request) + { + case ODBC_ADD_DSN: + case ODBC_ADD_SYS_DSN: + return ODBC_ADD_DSN; + + case ODBC_CONFIG_DSN: + case ODBC_CONFIG_SYS_DSN: + return ODBC_CONFIG_DSN; + + case ODBC_REMOVE_DSN: + case ODBC_REMOVE_SYS_DSN: + return ODBC_REMOVE_DSN; + + default: + FIXME("unhandled request %u\n", request); + return 0; + } +} + +static UWORD get_config_mode(WORD request) +{ + if (request == ODBC_ADD_DSN || request == ODBC_CONFIG_DSN || request == ODBC_REMOVE_DSN) return ODBC_USER_DSN; + return ODBC_SYSTEM_DSN; +} + BOOL WINAPI SQLConfigDataSourceW(HWND hwnd, WORD request, LPCWSTR driver, LPCWSTR attributes) { HMODULE mod; BOOL ret = FALSE; + UWORD config_mode_prev = config_mode; + WORD mapped_request;
TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_w(driver), debugstr_w(attributes)); if (TRACE_ON(odbc)) @@ -353,16 +383,24 @@ BOOL WINAPI SQLConfigDataSourceW(HWND hwnd, WORD request, LPCWSTR driver, LPCWST
clear_errors();
+ mapped_request = map_request(request); + if (!mapped_request) + return FALSE; + mod = load_config_driver(driver); if (!mod) return FALSE;
+ config_mode = get_config_mode(request); + pConfigDSNW = (void*)GetProcAddress(mod, "ConfigDSNW"); if(pConfigDSNW) - ret = pConfigDSNW(hwnd, request, driver, attributes); + ret = pConfigDSNW(hwnd, mapped_request, driver, attributes); else ERR("Failed to find ConfigDSNW\n");
+ config_mode = config_mode_prev; + if (!ret) push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);
@@ -376,6 +414,8 @@ BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR a HMODULE mod; BOOL ret = FALSE; WCHAR *driverW; + UWORD config_mode_prev = config_mode; + WORD mapped_request;
TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_a(driver), debugstr_a(attributes));
@@ -388,6 +428,10 @@ BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR a
clear_errors();
+ mapped_request = map_request(request); + if (!mapped_request) + return FALSE; + driverW = heap_strdupAtoW(driver); if (!driverW) { @@ -402,11 +446,13 @@ BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR a return FALSE; }
+ config_mode = get_config_mode(request); + pConfigDSN = (void*)GetProcAddress(mod, "ConfigDSN"); if (pConfigDSN) { TRACE("Calling ConfigDSN\n"); - ret = pConfigDSN(hwnd, request, driver, attributes); + ret = pConfigDSN(hwnd, mapped_request, driver, attributes); } else { @@ -418,11 +464,13 @@ BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR a
attr = SQLInstall_strdup_multi(attributes); if(attr) - ret = pConfigDSNW(hwnd, request, driverW, attr); + ret = pConfigDSNW(hwnd, mapped_request, driverW, attr); heap_free(attr); } }
+ config_mode = config_mode_prev; + if (!ret) push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);
On Thu, 2020-11-12 at 21:57 +1100, Alistair Leslie-Hughes wrote:
Based off MSDN for function SQLConfigDataSource. The mode is explicitly set to ODBC_USER_DSN or ODBC_SYSTEM_DSN and reset to ODBC_BOTH_DSN at the end of the function.
https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlconfigdatasour...
Yes, I am currently restoring the old value, which is ODBC_BOTH_DSN, unless the app changed the default. I think that makes more sense than returning a hardcoded ODBC_BOTH_DSN.
participants (2)
-
Alistair Leslie-Hughes -
Hans Leidekker