[PATCH v3 0/3] MR10743: small odbc fixes
1)odbc32: compare strings case-insensitively in get_driver_filename() Driver names should be compared without case-sensetivity. unixODBC has no problems when testDSN got "Driver = SQLite3" instead of "Driver = SQLITE3" https://learn.microsoft.com/en-us/openspecs/sql_server_protocols/ms-odbcstr/... 2)odbc32: skip set_value for NULL filename in replicate_odbc_to_registry() get_driver_filename can return NULL, for example when \~/.odbc.ini contains driver that has been deleted. We want to prevent SIGSEGV because of wcslen(filename) when filename is NULL. 3)odbc32: check if row_number is NULL in param_options_unix() According to documentation, SQLParamOptions can accept NULL row_number. Now when NULL row_nuber is passed, crash happens 4)odbc32: make sure ODBC_CALL returns SQLRETURN Not sure about this one, need opinion. The targeted problem: now ODBC_CALL return SQLRETURN which is truncated from NTSTATUS. If WINE_UNIX_CALL fails at some point, ODBC_CALL returns truncated NTSTATUS error code, STATUS_ACCESS_VIOLATION (0xC0000005) truncated to 5, then function gets invalid SQLRETURN. The following solution checks of NTSTATUS is actually short SQLRETURN casted to NTSTATUS. -- v3: odbc32: Check if row_number is NULL in param_options_unix(). odbc32: Skip set_value for NULL filename in replicate_odbc_to_registry(). odbc32: Compare strings case-insensitively in get_driver_filename(). https://gitlab.winehq.org/wine/wine/-/merge_requests/10743
From: Ivan Ivlev <iviv@etersoft.ru> Signed-off-by: Ivan Ivlev <iviv@etersoft.ru> --- dlls/odbc32/unixlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/odbc32/unixlib.c b/dlls/odbc32/unixlib.c index 94965951794..b0e28b9f42f 100644 --- a/dlls/odbc32/unixlib.c +++ b/dlls/odbc32/unixlib.c @@ -568,7 +568,7 @@ static WCHAR *get_driver_filename( const WCHAR *name ) WCHAR buffer[1024]; KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; - if (wcscmp( name, drivers.names[i] )) continue; + if (wcsicmp( name, drivers.names[i] )) continue; if ((key_driver = open_key( key_odbcinst, drivers.names[i], wcslen(drivers.names[i]) * sizeof(WCHAR) ))) { if (query_value( key_driver, driverW, sizeof(driverW), info, sizeof(buffer) ) && info->Type == REG_SZ && -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10743
From: Ivan Ivlev <iviv@etersoft.ru> Signed-off-by: Ivan Ivlev <iviv@etersoft.ru> --- dlls/odbc32/unixlib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dlls/odbc32/unixlib.c b/dlls/odbc32/unixlib.c index b0e28b9f42f..a8a7393231e 100644 --- a/dlls/odbc32/unixlib.c +++ b/dlls/odbc32/unixlib.c @@ -633,6 +633,7 @@ static void replicate_odbc_to_registry( BOOL is_user, SQLHENV env ) { HANDLE key_source; WCHAR buffer[1024], *filename = get_driver_filename( desc ); + if (!filename) WARN("%s: driver not registered, skipping Driver path write\n", debugstr_w(dsn)); KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; dir = SQL_FETCH_NEXT; @@ -645,7 +646,7 @@ static void replicate_odbc_to_registry( BOOL is_user, SQLHENV env ) if ((key_source = create_key( key_odbcini, dsn, len_dsn * sizeof(WCHAR) ))) { static const WCHAR driverW[] = {'D','r','i','v','e','r'}; - if (!query_value( key_source, driverW, sizeof(driverW), info, sizeof(buffer) )) + if (filename && !query_value( key_source, driverW, sizeof(driverW), info, sizeof(buffer) )) { set_value( key_source, driverW, sizeof(driverW), REG_SZ, (const BYTE *)filename, (wcslen(filename) + 1) * sizeof(WCHAR) ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10743
From: Ivan Ivlev <iviv@etersoft.ru> Signed-off-by: Ivan Ivlev <iviv@etersoft.ru> --- dlls/odbc32/proxyodbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index 9f1d3f1377f..2ced00dc3fd 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -5524,7 +5524,7 @@ static SQLRETURN param_options_unix( struct statement *stmt, SQLULEN row_count, struct SQLParamOptions_params params = { stmt->hdr.unix_handle, row_count, &row }; SQLRETURN ret; - if (SUCCESS((ret = ODBC_CALL( SQLParamOptions, ¶ms )))) *row_number = row; + if (SUCCESS((ret = ODBC_CALL( SQLParamOptions, ¶ms ))) && row_number) *row_number = row; return ret; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10743
Removed commit "odbc32: make sure ODBC_CALL returns SQLRETURN" -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10743#note_137744
participants (2)
-
Ivan Ivlev -
Ivan Ivlev (@iviv)