From: Hans Leidekker hans@codeweavers.com
This function is not exported by current Windows drivers. --- dlls/odbc32/proxyodbc.c | 66 ++------------------------------------ dlls/odbc32/tests/odbc32.c | 35 -------------------- dlls/odbc32/unixlib.c | 39 ---------------------- dlls/odbc32/unixlib.h | 24 -------------- 4 files changed, 3 insertions(+), 161 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index 47e0aff0b18..e295f052ee7 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -261,35 +261,10 @@ SQLRETURN WINAPI SQLBindParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNu SQLSMALLINT ParameterType, SQLULEN LengthPrecision, SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, SQLLEN *StrLen_or_Ind) { - struct SQLBindParam_params params = { 0, ParameterNumber, ValueType, ParameterType, LengthPrecision, - ParameterScale, ParameterValue }; - struct handle *handle = StatementHandle; - UINT i = ParameterNumber - 1; - SQLRETURN ret; - - TRACE("(StatementHandle %p, ParameterNumber %d, ValueType %d, ParameterType %d, LengthPrecision %s," - " ParameterScale %d, ParameterValue %p, StrLen_or_Ind %p)\n", StatementHandle, ParameterNumber, ValueType, + FIXME("(StatementHandle %p, ParameterNumber %d, ValueType %d, ParameterType %d, LengthPrecision %s," + " ParameterScale %d, ParameterValue %p, StrLen_or_Ind %p) stub\n", StatementHandle, ParameterNumber, ValueType, ParameterType, debugstr_sqlulen(LengthPrecision), ParameterScale, ParameterValue, StrLen_or_Ind); - - if (!handle) return SQL_INVALID_HANDLE; - if (!ParameterNumber) - { - FIXME( "parameter 0 not handled\n" ); - return SQL_ERROR; - } - if (!alloc_binding( &handle->bind_param, SQL_PARAM_INPUT, ParameterNumber, handle->row_count )) return SQL_ERROR; - handle->bind_param.param[i].param.value_type = ValueType; - handle->bind_param.param[i].param.parameter_type = ParameterType; - handle->bind_param.param[i].param.length_precision = LengthPrecision; - handle->bind_param.param[i].param.parameter_scale = ParameterScale; - handle->bind_param.param[i].param.parameter_value = ParameterValue; - - params.StatementHandle = handle->unix_handle; - params.StrLen_or_Ind = handle->bind_param.param[i].len; - *(UINT64 *)params.StrLen_or_Ind = *StrLen_or_Ind; - if (SUCCESS(( ret = ODBC_CALL( SQLBindParam, ¶ms )))) handle->bind_param.param[i].ptr = StrLen_or_Ind; - TRACE ("Returning %d\n", ret); - return ret; + return SQL_ERROR; }
/************************************************************************* @@ -624,10 +599,6 @@ static void update_result_lengths( struct handle *handle, USHORT type ) { len_to_user( handle->bind_col.param[i].ptr, handle->bind_col.param[i].len, handle->row_count, width ); } - for (i = 0; i < handle->bind_param.count; i++) - { - len_to_user( handle->bind_param.param[i].ptr, handle->bind_param.param[i].len, handle->row_count, width ); - } for (i = 0; i < handle->bind_parameter.count; i++) { if (handle->bind_parameter.param[i].type != SQL_PARAM_OUTPUT && @@ -642,7 +613,6 @@ static void update_result_lengths( struct handle *handle, USHORT type ) { len_from_user( handle->bind_col.param[i].len, handle->bind_col.param[i].ptr, handle->row_count, width ); } - /* FIXME: handle bind_param */ for (i = 0; i < handle->bind_parameter.count; i++) { if (handle->bind_parameter.param[i].type != SQL_PARAM_INPUT && @@ -761,11 +731,6 @@ static void free_bindings( struct handle *handle ) free( handle->bind_col.param->len ); free( handle->bind_col.param ); } - if (handle->bind_param.param) - { - free( handle->bind_param.param->len ); - free( handle->bind_param.param ); - } if (handle->bind_parameter.param) { free( handle->bind_parameter.param->len ); @@ -1406,31 +1371,6 @@ static BOOL resize_result_lengths( struct handle *handle, UINT size ) } handle->bind_col.param[i].len = tmp; } - for (i = 0; i < handle->bind_param.count; i++) - { - UINT8 *tmp; - if (!handle->bind_param.param[i].ptr) continue; - if (!(tmp = realloc( handle->bind_param.param[i].len, size * sizeof(UINT64) ))) return FALSE; - if (tmp != handle->bind_param.param[i].len) - { - struct SQLBindParam_params params; - - params.StatementHandle = handle->unix_handle; - params.ParameterNumber = i + 1; - params.ValueType = handle->bind_param.param[i].param.value_type; - params.ParameterType = handle->bind_param.param[i].param.parameter_type; - params.LengthPrecision = handle->bind_param.param[i].param.length_precision; - params.ParameterScale = handle->bind_param.param[i].param.parameter_scale; - params.ParameterValue = handle->bind_param.param[i].param.parameter_value; - params.StrLen_or_Ind = tmp; - if (!SUCCESS(ODBC_CALL( SQLBindParam, ¶ms ))) - { - free( tmp ); - return FALSE; - } - } - handle->bind_param.param[i].len = tmp; - } for (i = 0; i < handle->bind_parameter.count; i++) { UINT8 *tmp; diff --git a/dlls/odbc32/tests/odbc32.c b/dlls/odbc32/tests/odbc32.c index 57bb17ef617..fafc63003b7 100644 --- a/dlls/odbc32/tests/odbc32.c +++ b/dlls/odbc32/tests/odbc32.c @@ -313,41 +313,6 @@ static void test_SQLExecDirect( void ) ok( ret == SQL_SUCCESS, "got %d\n", ret ); if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT );
- id[0] = 1; - len_id[0] = sizeof(id[0]); - ret = SQLBindParam( stmt, 1, SQL_INTEGER, SQL_INTEGER, 0, 0, id, len_id ); - ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); - - memcpy( name, "Mary", sizeof("Mary") ); - len_name[0] = sizeof( "Mary" ) - 1; - ret = SQLBindParam( stmt, 2, SQL_CHAR, SQL_VARCHAR, 0, 0, name, len_name ); - ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); - - ret = SQLExecute( stmt ); - ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); - - ret = SQLFetch( stmt ); - ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); - ok( id[0] == 1, "got %d\n", id[0] ); - ok( len_id[0] == sizeof(id[0]), "got %d\n", (int)len_id[0] ); - ok( !strcmp( (const char *)name, "Mary" ), "got %s\n", name ); - ok( len_name[0] == sizeof("Mary") - 1, "got %d\n", (int)len_name[0] ); - - ret = SQLFreeStmt( stmt, 0 ); - ok( ret == SQL_SUCCESS, "got %d\n", ret ); - - ret = SQLAllocStmt( con, &stmt ); - ok( ret == SQL_SUCCESS, "got %d\n", ret ); - - ret = SQLPrepare( stmt, (SQLCHAR *)"SELECT * FROM winetest WHERE Id = ? AND Name = ?", - ARRAYSIZE("SELECT * FROM winetest WHERE Id = ? AND Name = ?") - 1 ); - ok( ret == SQL_SUCCESS, "got %d\n", ret ); - if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); - id[0] = 1; len_id[0] = sizeof(id[0]); ret = SQLBindParameter( stmt, 1, SQL_PARAM_INPUT, SQL_INTEGER, SQL_INTEGER, 0, 0, id, 0, len_id ); diff --git a/dlls/odbc32/unixlib.c b/dlls/odbc32/unixlib.c index cc963c5a893..3f793ef382d 100644 --- a/dlls/odbc32/unixlib.c +++ b/dlls/odbc32/unixlib.c @@ -371,14 +371,6 @@ static NTSTATUS wrap_SQLBindCol( void *args ) params->TargetValue, params->BufferLength, params->StrLen_or_Ind ); }
-static NTSTATUS wrap_SQLBindParam( void *args ) -{ - struct SQLBindParam_params *params = args; - return SQLBindParam( (SQLHSTMT)(ULONG_PTR)params->StatementHandle, params->ParameterNumber, params->ValueType, - params->ParameterType, params->LengthPrecision, params->ParameterScale, - params->ParameterValue, params->StrLen_or_Ind ); -} - static NTSTATUS wrap_SQLBindParameter( void *args ) { struct SQLBindParameter_params *params = args; @@ -1155,7 +1147,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = wrap_SQLAllocHandleStd, wrap_SQLAllocStmt, wrap_SQLBindCol, - wrap_SQLBindParam, wrap_SQLBindParameter, wrap_SQLBrowseConnect, wrap_SQLBrowseConnectW, @@ -1297,35 +1288,6 @@ static NTSTATUS wow64_SQLBindCol( void *args ) return wrap_SQLBindCol( ¶ms ); }
-static NTSTATUS wow64_SQLBindParam( void *args ) -{ - struct - { - UINT64 StatementHandle; - UINT16 ParameterNumber; - INT16 ValueType; - INT16 ParameterType; - UINT64 LengthPrecision; - INT16 ParameterScale; - PTR32 ParameterValue; - PTR32 StrLen_or_Ind; - } const *params32 = args; - - struct SQLBindParam_params params = - { - params32->StatementHandle, - params32->ParameterNumber, - params32->ValueType, - params32->ParameterType, - params32->LengthPrecision, - params32->ParameterScale, - ULongToPtr(params32->ParameterValue), - ULongToPtr(params32->StrLen_or_Ind) - }; - - return wrap_SQLBindParam( ¶ms ); -} - static NTSTATUS wow64_SQLBindParameter( void *args ) { struct @@ -3557,7 +3519,6 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = wrap_SQLAllocHandleStd, wrap_SQLAllocStmt, wow64_SQLBindCol, - wow64_SQLBindParam, wow64_SQLBindParameter, wow64_SQLBrowseConnect, wow64_SQLBrowseConnectW, diff --git a/dlls/odbc32/unixlib.h b/dlls/odbc32/unixlib.h index b1f42363429..7cb245c52f3 100644 --- a/dlls/odbc32/unixlib.h +++ b/dlls/odbc32/unixlib.h @@ -40,7 +40,6 @@ enum sql_funcs unix_SQLAllocHandleStd, unix_SQLAllocStmt, unix_SQLBindCol, - unix_SQLBindParam, unix_SQLBindParameter, unix_SQLBrowseConnect, unix_SQLBrowseConnectW, @@ -159,15 +158,6 @@ struct bind_col_args INT64 buffer_length; };
-struct bind_param_args -{ - INT16 value_type; - INT16 parameter_type; - UINT64 length_precision; - INT16 parameter_scale; - void *parameter_value; -}; - struct bind_parameter_args { INT16 input_output_type; @@ -185,7 +175,6 @@ struct param union { struct bind_col_args col; - struct bind_param_args param; struct bind_parameter_args parameter; }; UINT8 *len; /* result length array stored in Unix lib */ @@ -202,7 +191,6 @@ struct handle { UINT64 unix_handle; struct param_binding bind_col; - struct param_binding bind_param; struct param_binding bind_parameter; UINT32 row_count; /* number of rows returned by SQLFetch() */ }; @@ -248,18 +236,6 @@ struct SQLBindCol_params void *StrLen_or_Ind; };
-struct SQLBindParam_params -{ - UINT64 StatementHandle; - UINT16 ParameterNumber; - INT16 ValueType; - INT16 ParameterType; - UINT64 LengthPrecision; - INT16 ParameterScale; - void *ParameterValue; - void *StrLen_or_Ind; -}; - struct SQLBindParameter_params { UINT64 StatementHandle;
From: Hans Leidekker hans@codeweavers.com
--- dlls/odbc32/unixlib.c | 340 ++++++++++++++++++++++++++++-------------- 1 file changed, 225 insertions(+), 115 deletions(-)
diff --git a/dlls/odbc32/unixlib.c b/dlls/odbc32/unixlib.c index 3f793ef382d..e5612678899 100644 --- a/dlls/odbc32/unixlib.c +++ b/dlls/odbc32/unixlib.c @@ -101,7 +101,7 @@ static HANDLE create_hklm_key( const WCHAR *path, ULONG path_size ) return NULL; }
-static HANDLE create_key( HANDLE root, const WCHAR *path, ULONG path_size, ULONG options, ULONG *disposition ) +static HANDLE create_key( HANDLE root, const WCHAR *path, ULONG path_size ) { UNICODE_STRING name = { path_size, path_size, (WCHAR *)path }; OBJECT_ATTRIBUTES attr; @@ -113,7 +113,23 @@ static HANDLE create_key( HANDLE root, const WCHAR *path, ULONG path_size, ULONG attr.Attributes = 0; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; - if (NtCreateKey( &ret, MAXIMUM_ALLOWED, &attr, 0, NULL, options, disposition )) return NULL; + if (NtCreateKey( &ret, MAXIMUM_ALLOWED, &attr, 0, NULL, 0, NULL )) return NULL; + return ret; +} + +static HANDLE open_key( HANDLE root, const WCHAR *path, ULONG path_size ) +{ + UNICODE_STRING name = { path_size, path_size, (WCHAR *)path }; + OBJECT_ATTRIBUTES attr; + HANDLE ret; + + attr.Length = sizeof(attr); + attr.RootDirectory = root; + attr.ObjectName = &name; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + if (NtOpenKey( &ret, MAXIMUM_ALLOWED, &attr )) return NULL; return ret; }
@@ -131,6 +147,25 @@ static BOOL set_value( HANDLE key, const WCHAR *name, ULONG name_size, ULONG typ return !NtSetValueKey( key, &str, 0, type, value, count ); }
+static HANDLE open_odbcinst_key( void ) +{ + static const WCHAR odbcW[] = {'S','o','f','t','w','a','r','e','\','O','D','B','C'}; + static const WCHAR odbcinstW[] = {'O','D','B','C','I','N','S','T','.','I','N','I'}; + HANDLE ret, root = create_hklm_key( odbcW, sizeof(odbcW) ); + ret = create_key( root, odbcinstW, sizeof(odbcinstW) ); + NtClose( root ); + return ret; +} + +static HANDLE open_drivers_key( void ) +{ + static const WCHAR driversW[] = {'O','D','B','C',' ','D','r','i','v','e','r','s'}; + HANDLE ret, root = open_odbcinst_key(); + ret = create_key( root, driversW, sizeof(driversW) ); + NtClose( root ); + return ret; +} + /*********************************************************************** * odbc_replicate_odbcinst_to_registry * @@ -144,155 +179,230 @@ static BOOL set_value( HANDLE key, const WCHAR *name, ULONG name_size, ULONG typ */ static void replicate_odbcinst_to_registry( SQLHENV env ) { - static const WCHAR odbcW[] = {'S','o','f','t','w','a','r','e','\','O','D','B','C'}; - static const WCHAR odbcinstW[] = {'O','D','B','C','I','N','S','T','.','I','N','I'}; - static const WCHAR driversW[] = {'O','D','B','C',' ','D','r','i','v','e','r','s'}; - HANDLE key_odbc, key_odbcinst, key_drivers; - BOOL success = FALSE; + HANDLE key_odbcinst, key_drivers; + SQLRETURN ret; + SQLUSMALLINT dir = SQL_FETCH_FIRST; + WCHAR desc[256], attrs[1024]; + SQLSMALLINT len_desc, len_attrs;
- if (!(key_odbc = create_hklm_key( odbcW, sizeof(odbcW) ))) return; + if (!(key_odbcinst = open_odbcinst_key())) return; + if (!(key_drivers = open_drivers_key())) + { + NtClose( key_odbcinst ); + return; + }
- if ((key_odbcinst = create_key( key_odbc, odbcinstW, sizeof(odbcinstW), 0, NULL ))) + while (SUCCESS((ret = SQLDriversW( env, dir, (SQLWCHAR *)desc, ARRAY_SIZE(desc), &len_desc, attrs, + ARRAY_SIZE(attrs), &len_attrs )))) { - if ((key_drivers = create_key( key_odbcinst, driversW, sizeof(driversW), 0, NULL ))) + static const WCHAR installedW[] = {'I','n','s','t','a','l','l','e','d',0}; + HANDLE key_driver; + WCHAR buffer[1024]; + KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + + dir = SQL_FETCH_NEXT; + if (!query_value( key_drivers, desc, len_desc * sizeof(WCHAR), info, sizeof(buffer) )) { - SQLRETURN ret; - SQLUSMALLINT dir = SQL_FETCH_FIRST; - WCHAR desc [256]; - SQLSMALLINT len; + set_value( key_drivers, desc, len_desc * sizeof(WCHAR), REG_SZ, (const BYTE *)installedW, + sizeof(installedW) ); + } + + if ((key_driver = create_key( key_odbcinst, desc, wcslen( desc ) * sizeof(WCHAR) ))) + { + static const WCHAR driverW[] = {'D','r','i','v','e','r',0}, driver_eqW[] = {'D','r','i','v','e','r','='}; + const WCHAR *driver = NULL, *ptr = attrs;
- success = TRUE; - while (SUCCESS((ret = SQLDriversW( env, dir, (SQLWCHAR *)desc, sizeof(desc), &len, NULL, 0, NULL )))) + while (*ptr) { - dir = SQL_FETCH_NEXT; - if (len == lstrlenW( desc )) + if (len_attrs > ARRAY_SIZE(driver_eqW) && !memcmp( driver_eqW, ptr, sizeof(driver_eqW) )) { - static const WCHAR installedW[] = {'I','n','s','t','a','l','l','e','d',0}; - HANDLE key_driver; - WCHAR buffer[256]; - KEY_VALUE_PARTIAL_INFORMATION *info = (void *)buffer; - - if (!query_value( key_drivers, desc, len * sizeof(WCHAR), info, sizeof(buffer) )) - { - if (!set_value( key_drivers, desc, len * sizeof(WCHAR), REG_SZ, (const BYTE *)installedW, - sizeof(installedW) )) - { - TRACE( "error replicating driver %s\n", debugstr_w(desc) ); - success = FALSE; - } - } - if ((key_driver = create_key( key_odbcinst, desc, lstrlenW( desc ) * sizeof(WCHAR), 0, NULL ))) - NtClose( key_driver ); - else - { - TRACE( "error ensuring driver key %s\n", debugstr_w(desc) ); - success = FALSE; - } - } - else - { - WARN( "unusually long driver name %s not replicated\n", debugstr_w(desc) ); - success = FALSE; + driver = ptr + 7; + break; } + len_attrs -= wcslen( ptr ) + 1; + ptr += wcslen( ptr ) + 1; } - NtClose( key_drivers ); + if (driver) set_value( key_driver, driverW, sizeof(driverW), REG_SZ, (const BYTE *)driver, + wcslen(driver) * sizeof(WCHAR) ); + NtClose( key_driver ); } - else TRACE( "error opening Drivers key\n" ); + }
- NtClose( key_odbcinst ); + NtClose( key_drivers ); + NtClose( key_odbcinst ); +} + +struct drivers +{ + ULONG count; + WCHAR **names; +}; + +static void get_drivers( struct drivers *drivers ) +{ + ULONG idx = 0, count = 0, capacity, info_size, info_max_size; + KEY_VALUE_BASIC_INFORMATION *info = NULL; + WCHAR **names; + NTSTATUS status = STATUS_SUCCESS; + HANDLE key; + + drivers->count = 0; + drivers->names = NULL; + + if (!(key = open_drivers_key())) return; + + capacity = 4; + if (!(names = malloc( capacity * sizeof(*names) ))) goto done; + info_max_size = offsetof(KEY_VALUE_BASIC_INFORMATION, Name) + 512; + if (!(info = malloc( info_max_size ))) goto done; + + while (!status && info) + { + status = NtEnumerateValueKey( key, idx, KeyValueBasicInformation, info, info_max_size, &info_size ); + while (status == STATUS_BUFFER_OVERFLOW) + { + info_max_size = info_size; + if (!(info = realloc( info, info_max_size ))) goto error; + status = NtEnumerateValueKey( key, idx, KeyValueFullInformation, info, info_max_size, &info_size ); + } + + if (status == STATUS_NO_MORE_ENTRIES) + { + drivers->count = count; + drivers->names = names; + goto done; + } + idx++; + if (status) break; + if (info->Type != REG_SZ) continue; + + if (count >= capacity) + { + capacity = capacity * 3 / 2; + if (!(names = realloc( names, capacity * sizeof(*names) ))) break; + } + + if (!(names[count] = malloc( info->NameLength + sizeof(WCHAR) ))) break; + memcpy( names[count], info->Name, info->NameLength ); + names[count][info->NameLength / sizeof(WCHAR)] = 0; + count++; } - else TRACE( "error creating/opening ODBCINST.INI key\n" );
- if (!success) WARN( "may not have replicated all ODBC drivers to the registry\n" ); - NtClose( key_odbc ); +error: + if (names) while (count) free( names[--count] ); + free( names ); + +done: + free( info ); + NtClose( key ); +} + +/* unixODBC returns the driver filename in the description, use it to look up the driver name */ +static WCHAR *get_driver_name( const WCHAR *filename ) +{ + struct drivers drivers; + HANDLE key_odbcinst, key_driver; + WCHAR *ret = NULL; + ULONG i; + + get_drivers( &drivers ); + if (!drivers.count) return NULL; + + key_odbcinst = open_odbcinst_key(); + for (i = 0; i < drivers.count; i++) + { + static const WCHAR driverW[] = {'D','r','i','v','e','r',0}; + WCHAR buffer[1024]; + KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + + 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 && + !wcsnicmp( (const WCHAR *)info->Data, filename, info->DataLength / sizeof(WCHAR) ) && + (ret = malloc( (wcslen(drivers.names[i]) + 1) * sizeof(WCHAR) ))) + { + wcscpy( ret, drivers.names[i] ); + break; + } + NtClose( key_driver ); + } + } + + for (i = 0; i < drivers.count; i++) free( drivers.names[i] ); + free( drivers.names ); + NtClose( key_odbcinst ); + return ret; +} + +static HANDLE open_odbcini_key( BOOL user ) +{ + static const WCHAR odbcW[] = {'S','o','f','t','w','a','r','e','\','O','D','B','C'}; + static const WCHAR odbcinstW[] = {'O','D','B','C','.','I','N','I'}; + HANDLE ret, root = user ? create_hkcu_key( odbcW, sizeof(odbcW) ) : create_hklm_key( odbcW, sizeof(odbcW) ); + ret = create_key( root, odbcinstW, sizeof(odbcinstW) ); + NtClose( root ); + return ret; +} + +static HANDLE open_sources_key( BOOL user ) +{ + static const WCHAR sourcesW[] = {'O','D','B','C',' ','D','a','t','a',' ','S','o','u','r','c','e','s'}; + HANDLE ret, root = open_odbcini_key( user ); + ret = create_key( root, sourcesW, sizeof(sourcesW) ); + NtClose( root ); + return ret; }
/*********************************************************************** * replicate_odbc_to_registry * - * Utility to replicate_to_registry() to replicate either the USER or - * SYSTEM data sources. - * - * For now simply place the "Driver description" (as returned by SQLDataSources) - * into the registry as the driver. This is enough to satisfy Crystal's - * requirement that there be a driver entry. (It doesn't seem to care what - * the setting is). - * A slightly more accurate setting would be to access the registry to find - * the actual driver library for the given description (which appears to map - * to one of the HKLM/Software/ODBC/ODBCINST.INI keys). (If you do this note - * that this will add a requirement that this function be called after - * replicate_odbcinst_to_registry()) + * Utility to replicate either the USER or SYSTEM data sources. + * This function must be called after replicate_odbcinst_to_registry(). */ static void replicate_odbc_to_registry( BOOL is_user, SQLHENV env ) { - static const WCHAR odbcW[] = {'S','o','f','t','w','a','r','e','\','O','D','B','C'}; - static const WCHAR odbciniW[] = {'O','D','B','C','.','I','N','I'}; - HANDLE key_odbc, key_odbcini, key_source; + HANDLE key_odbcini, key_sources; SQLRETURN ret; SQLUSMALLINT dir; WCHAR dsn[SQL_MAX_DSN_LENGTH + 1], desc[256]; SQLSMALLINT len_dsn, len_desc; - BOOL success = FALSE; - const char *which;
- if (is_user) - { - key_odbc = create_hkcu_key( odbcW, sizeof(odbcW) ); - which = "user"; - } - else + if (!(key_odbcini = open_odbcini_key( is_user ))) return; + if (!(key_sources = open_sources_key( is_user ))) { - key_odbc = create_hklm_key( odbcW, sizeof(odbcW) ); - which = "system"; + NtClose( key_odbcini ); + return; } - if (!key_odbc) return;
- if ((key_odbcini = create_key( key_odbc, odbciniW, sizeof(odbciniW), 0, NULL ))) + dir = is_user ? SQL_FETCH_FIRST_USER : SQL_FETCH_FIRST_SYSTEM; + while (SUCCESS((ret = SQLDataSourcesW( env, dir, dsn, sizeof(dsn), &len_dsn, desc, sizeof(desc), &len_desc )))) { - success = TRUE; - dir = is_user ? SQL_FETCH_FIRST_USER : SQL_FETCH_FIRST_SYSTEM; - while (SUCCESS((ret = SQLDataSourcesW( env, dir, (SQLWCHAR *)dsn, sizeof(dsn), &len_dsn, (SQLWCHAR *)desc, - sizeof(desc), &len_desc )))) + HANDLE key_source; + WCHAR buffer[1024], *name = get_driver_name( desc ); + KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + + dir = SQL_FETCH_NEXT; + if (!query_value( key_sources, dsn, len_dsn * sizeof(WCHAR), info, sizeof(buffer) ) && name) { - dir = SQL_FETCH_NEXT; - if (len_dsn == lstrlenW( dsn ) && len_desc == lstrlenW( desc )) - { - if ((key_source = create_key( key_odbcini, dsn, len_dsn * sizeof(WCHAR), 0, NULL ))) - { - static const WCHAR driverW[] = {'D','r','i','v','e','r'}; - WCHAR buffer[256]; - KEY_VALUE_PARTIAL_INFORMATION *info = (void *)buffer; - ULONG size; - - if (!(size = query_value( key_source, driverW, sizeof(driverW), info, sizeof(buffer) ))) - { - if (!set_value( key_source, driverW, sizeof(driverW), REG_SZ, (const BYTE *)desc, - len_desc * sizeof(WCHAR) )) - { - TRACE( "error replicating description of %s (%s)\n", debugstr_w(dsn), debugstr_w(desc) ); - success = FALSE; - } - } - NtClose( key_source ); - } - else - { - TRACE( "error opening %s DSN key %s\n", which, debugstr_w(dsn) ); - success = FALSE; - } - } - else + set_value( key_sources, dsn, len_dsn * sizeof(WCHAR), REG_SZ, (const BYTE *)name, + (wcslen(name) + 1) * sizeof(WCHAR) ); + } + free( name ); + + 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) )) { - WARN( "unusually long %s data source name %s (%s) not replicated\n", which, debugstr_w(dsn), debugstr_w(desc) ); - success = FALSE; + set_value( key_source, driverW, sizeof(driverW), REG_SZ, (const BYTE *)desc, + (len_desc + 1) * sizeof(WCHAR) ); } + NtClose( key_source ); } - NtClose( key_odbcini ); } - else TRACE( "error creating/opening %s ODBC.INI registry key\n", which );
- if (!success) WARN( "may not have replicated all %s ODBC DSNs to the registry\n", which ); - NtClose( key_odbc ); + NtClose( key_sources ); + NtClose( key_odbcini ); }
/***********************************************************************
From: Hans Leidekker hans@codeweavers.com
--- dlls/odbc32/proxyodbc.c | 98 ++++++++++++++++++++++++++++++++------ dlls/odbc32/tests/odbc32.c | 3 +- dlls/odbc32/unixlib.h | 2 + 3 files changed, 87 insertions(+), 16 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index e295f052ee7..23ca8974f33 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -1934,6 +1934,14 @@ SQLRETURN WINAPI SQLTablePrivileges(SQLHSTMT StatementHandle, SQLCHAR *CatalogNa return ret; }
+static HKEY open_drivers_key( void ) +{ + static const WCHAR driversW[] = L"Software\ODBC\ODBCINST.INI\ODBC Drivers"; + HKEY key; + if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, driversW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL )) return key; + return NULL; +} + /************************************************************************* * SQLDrivers [ODBC32.071] */ @@ -1942,10 +1950,10 @@ SQLRETURN WINAPI SQLDrivers(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, S SQLCHAR *DriverAttributes, SQLSMALLINT BufferLength2, SQLSMALLINT *AttributesLength) { - struct SQLDrivers_params params = { 0, Direction, DriverDescription, BufferLength1, DescriptionLength, - DriverAttributes, BufferLength2, AttributesLength }; struct handle *handle = EnvironmentHandle; - SQLRETURN ret; + DWORD len_desc = BufferLength1; + SQLRETURN ret = SQL_ERROR; + LONG res;
TRACE("(EnvironmentHandle %p, Direction %d, DriverDescription %p, BufferLength1 %d, DescriptionLength %p," " DriverAttributes %p, BufferLength2 %d, AttributesLength %p)\n", EnvironmentHandle, Direction, @@ -1953,12 +1961,43 @@ SQLRETURN WINAPI SQLDrivers(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, S
if (!handle) return SQL_INVALID_HANDLE;
- params.EnvironmentHandle = handle->unix_handle; - ret = ODBC_CALL( SQLDrivers, ¶ms ); + if (Direction == SQL_FETCH_FIRST) + { + handle->drivers_idx = 0; + RegCloseKey( handle->drivers_key ); + if (!(handle->drivers_key = open_drivers_key())) return SQL_ERROR; + } + + res = RegEnumValueA( handle->drivers_key, handle->drivers_idx, (char *)DriverDescription, &len_desc, + NULL, NULL, NULL, NULL ); + if (res == ERROR_NO_MORE_ITEMS) + { + ret = SQL_NO_DATA; + goto done; + } + else if (res == ERROR_SUCCESS) + { + if (DescriptionLength) *DescriptionLength = len_desc; + + handle->drivers_idx++; + ret = SQL_SUCCESS; + } + else goto done;
- if (ret == SQL_NO_DATA && Direction == SQL_FETCH_FIRST) - ERR_(winediag)("No ODBC drivers could be found. Check the settings for your libodbc provider.\n"); + if (DriverAttributes) + { + FIXME( "read attributes from registry\n" ); + if (BufferLength2 >= 2) memset( DriverAttributes, 0, 2 ); + } + if (AttributesLength) *AttributesLength = 2;
+done: + if (ret) + { + RegCloseKey( handle->drivers_key ); + handle->drivers_key = NULL; + handle->drivers_idx = 0; + } TRACE("Returning %d\n", ret); return ret; } @@ -2940,10 +2979,10 @@ SQLRETURN WINAPI SQLDriversW(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, SQLSMALLINT BufferLength1, SQLSMALLINT *DescriptionLength, SQLWCHAR *DriverAttributes, SQLSMALLINT BufferLength2, SQLSMALLINT *AttributesLength) { - struct SQLDriversW_params params = { 0, Direction, DriverDescription, BufferLength1, DescriptionLength, - DriverAttributes, BufferLength2, AttributesLength }; struct handle *handle = EnvironmentHandle; - SQLRETURN ret; + DWORD len_desc = BufferLength1; + SQLRETURN ret = SQL_ERROR; + LONG res;
TRACE("(EnvironmentHandle %p, Direction %d, DriverDescription %p, BufferLength1 %d, DescriptionLength %p," " DriverAttributes %p, BufferLength2 %d, AttributesLength %p)\n", EnvironmentHandle, Direction, @@ -2951,12 +2990,43 @@ SQLRETURN WINAPI SQLDriversW(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction,
if (!handle) return SQL_INVALID_HANDLE;
- params.EnvironmentHandle = handle->unix_handle; - ret = ODBC_CALL( SQLDriversW, ¶ms ); + if (Direction == SQL_FETCH_FIRST) + { + handle->drivers_idx = 0; + RegCloseKey( handle->drivers_key ); + if (!(handle->drivers_key = open_drivers_key())) return SQL_ERROR; + }
- if (ret == SQL_NO_DATA && Direction == SQL_FETCH_FIRST) - ERR_(winediag)("No ODBC drivers could be found. Check the settings for your libodbc provider.\n"); + res = RegEnumValueW( handle->drivers_key, handle->drivers_idx, DriverDescription, &len_desc, + NULL, NULL, NULL, NULL ); + if (res == ERROR_NO_MORE_ITEMS) + { + ret = SQL_NO_DATA; + goto done; + } + else if (res == ERROR_SUCCESS) + { + if (DescriptionLength) *DescriptionLength = len_desc;
+ handle->drivers_idx++; + ret = SQL_SUCCESS; + } + else goto done; + + if (DriverAttributes) + { + FIXME( "read attributes from registry\n" ); + if (BufferLength2 >= 2) memset( DriverAttributes, 0, 2 * sizeof(WCHAR) ); + } + if (AttributesLength) *AttributesLength = 2; + +done: + if (ret) + { + RegCloseKey( handle->drivers_key ); + handle->drivers_key = NULL; + handle->drivers_idx = 0; + } TRACE("Returning %d\n", ret); return ret; } diff --git a/dlls/odbc32/tests/odbc32.c b/dlls/odbc32/tests/odbc32.c index fafc63003b7..5a3b0c6f817 100644 --- a/dlls/odbc32/tests/odbc32.c +++ b/dlls/odbc32/tests/odbc32.c @@ -184,8 +184,7 @@ static void test_SQLDrivers( void ) ok( len, "unexpected len\n" ); ok( len2, "unexpected len\n" ); ok( desc[0], "empty string\n" ); - ok( attrs[0], "empty string\n" ); - trace( "desc %s len %d attrs %s len %d\n", desc, len, attrs, len2 ); + trace( "desc %s len %d\n", desc, len ); }
ret = SQLFreeEnv( env ); diff --git a/dlls/odbc32/unixlib.h b/dlls/odbc32/unixlib.h index 7cb245c52f3..5e4d799b509 100644 --- a/dlls/odbc32/unixlib.h +++ b/dlls/odbc32/unixlib.h @@ -190,6 +190,8 @@ struct param_binding struct handle { UINT64 unix_handle; + UINT32 drivers_idx; + void *drivers_key; struct param_binding bind_col; struct param_binding bind_parameter; UINT32 row_count; /* number of rows returned by SQLFetch() */
From: Hans Leidekker hans@codeweavers.com
--- dlls/odbc32/proxyodbc.c | 120 +++++++++++++++++++++++++------ dlls/odbc32/unixlib.c | 156 ---------------------------------------- dlls/odbc32/unixlib.h | 58 ++------------- 3 files changed, 105 insertions(+), 229 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index 23ca8974f33..fb2b5e09929 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -403,6 +403,14 @@ SQLRETURN WINAPI SQLCopyDesc(SQLHDESC SourceDescHandle, SQLHDESC TargetDescHandl return ret; }
+static HKEY open_sources_key( HKEY root ) +{ + static const WCHAR sourcesW[] = L"Software\ODBC\ODBC.INI\ODBC Data Sources"; + HKEY key; + if (!RegCreateKeyExW( root, sourcesW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL )) return key; + return NULL; +} + /************************************************************************* * SQLDataSources [ODBC32.057] */ @@ -410,10 +418,10 @@ SQLRETURN WINAPI SQLDataSources(SQLHENV EnvironmentHandle, SQLUSMALLINT Directio SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, SQLCHAR *Description, SQLSMALLINT BufferLength2, SQLSMALLINT *NameLength2) { - struct SQLDataSources_params params = { 0, Direction, ServerName, BufferLength1, NameLength1, Description, - BufferLength2, NameLength2 }; struct handle *handle = EnvironmentHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR; + DWORD len_source = BufferLength1, len_desc = BufferLength2; + LONG res;
TRACE("(EnvironmentHandle %p, Direction %d, ServerName %p, BufferLength1 %d, NameLength1 %p, Description %p," " BufferLength2 %d, NameLength2 %p)\n", EnvironmentHandle, Direction, ServerName, BufferLength1, @@ -421,16 +429,52 @@ SQLRETURN WINAPI SQLDataSources(SQLHENV EnvironmentHandle, SQLUSMALLINT Directio
if (!handle) return SQL_INVALID_HANDLE;
- params.EnvironmentHandle = handle->unix_handle; - if (SUCCESS((ret = ODBC_CALL( SQLDataSources, ¶ms ))) && TRACE_ON(odbc)) + if (Direction == SQL_FETCH_FIRST) { - if (ServerName && NameLength1 && *NameLength1 > 0) - TRACE(" DataSource %s", debugstr_an((const char *)ServerName, *NameLength1)); - if (Description && NameLength2 && *NameLength2 > 0) - TRACE(" Description %s", debugstr_an((const char *)Description, *NameLength2)); - TRACE("\n"); + handle->sources_idx = 0; + handle->sources_system = FALSE; + RegCloseKey( handle->sources_key ); + if (!(handle->sources_key = open_sources_key( HKEY_CURRENT_USER ))) return SQL_ERROR; }
+ res = RegEnumValueA( handle->sources_key, handle->sources_idx, (char *)ServerName, &len_source, NULL, + NULL, (BYTE *)Description, &len_desc ); + if (res == ERROR_NO_MORE_ITEMS) + { + if (handle->sources_system) + { + ret = SQL_NO_DATA; + goto done; + } + /* user key exhausted, continue with system key */ + RegCloseKey( handle->sources_key ); + if (!(handle->sources_key = open_sources_key( HKEY_LOCAL_MACHINE ))) goto done; + handle->sources_idx = 0; + handle->sources_system = TRUE; + res = RegEnumValueA( handle->sources_key, handle->sources_idx, (char *)ServerName, &len_source, NULL, + NULL, (BYTE *)Description, &len_desc ); + } + if (res == ERROR_NO_MORE_ITEMS) + { + ret = SQL_NO_DATA; + goto done; + } + else if (res == ERROR_SUCCESS) + { + if (NameLength1) *NameLength1 = len_source; + if (NameLength2) *NameLength2 = len_desc - 1; + + handle->sources_idx++; + ret = SQL_SUCCESS; + } + +done: + if (ret) + { + RegCloseKey( handle->sources_key ); + handle->sources_key = NULL; + handle->sources_idx = 0; + } TRACE("Returning %d\n", ret); return ret; } @@ -2788,10 +2832,10 @@ SQLRETURN WINAPI SQLDataSourcesW(SQLHENV EnvironmentHandle, SQLUSMALLINT Directi SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, WCHAR *Description, SQLSMALLINT BufferLength2, SQLSMALLINT *NameLength2) { - struct SQLDataSourcesW_params params = { 0, Direction, ServerName, BufferLength1, NameLength1, Description, - BufferLength2, NameLength2 }; struct handle *handle = EnvironmentHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR; + DWORD len_source = BufferLength1, len_desc = BufferLength2; + LONG res;
TRACE("(EnvironmentHandle %p, Direction %d, ServerName %p, BufferLength1 %d, NameLength1 %p, Description %p," " BufferLength2 %d, NameLength2 %p)\n", EnvironmentHandle, Direction, ServerName, BufferLength1, @@ -2799,18 +2843,52 @@ SQLRETURN WINAPI SQLDataSourcesW(SQLHENV EnvironmentHandle, SQLUSMALLINT Directi
if (!handle) return SQL_INVALID_HANDLE;
- params.EnvironmentHandle = handle->unix_handle; - ret = ODBC_CALL( SQLDataSourcesW, ¶ms ); + if (Direction == SQL_FETCH_FIRST) + { + handle->sources_idx = 0; + handle->sources_system = FALSE; + RegCloseKey( handle->sources_key ); + if (!(handle->sources_key = open_sources_key( HKEY_CURRENT_USER ))) return SQL_ERROR; + }
- if (ret >= 0 && TRACE_ON(odbc)) + res = RegEnumValueW( handle->sources_key, handle->sources_idx, ServerName, &len_source, NULL, NULL, + (BYTE *)Description, &len_desc ); + if (res == ERROR_NO_MORE_ITEMS) { - if (ServerName && NameLength1 && *NameLength1 > 0) - TRACE(" DataSource %s", debugstr_wn(ServerName, *NameLength1)); - if (Description && NameLength2 && *NameLength2 > 0) - TRACE(" Description %s", debugstr_wn(Description, *NameLength2)); - TRACE("\n"); + if (handle->sources_system) + { + ret = SQL_NO_DATA; + goto done; + } + /* user key exhausted, continue with system key */ + RegCloseKey( handle->sources_key ); + if (!(handle->sources_key = open_sources_key( HKEY_LOCAL_MACHINE ))) goto done; + handle->sources_idx = 0; + handle->sources_system = TRUE; + res = RegEnumValueW( handle->sources_key, handle->sources_idx, ServerName, &len_source, NULL, NULL, + (BYTE *)Description, &len_desc ); } + if (res == ERROR_NO_MORE_ITEMS) + { + ret = SQL_NO_DATA; + goto done; + } + else if (res == ERROR_SUCCESS) + { + if (NameLength1) *NameLength1 = len_source; + if (NameLength2) *NameLength2 = len_desc - 1;
+ handle->sources_idx++; + ret = SQL_SUCCESS; + } + +done: + if (ret) + { + RegCloseKey( handle->sources_key ); + handle->sources_key = NULL; + handle->sources_idx = 0; + } TRACE("Returning %d\n", ret); return ret; } diff --git a/dlls/odbc32/unixlib.c b/dlls/odbc32/unixlib.c index e5612678899..24f935fb1d2 100644 --- a/dlls/odbc32/unixlib.c +++ b/dlls/odbc32/unixlib.c @@ -609,22 +609,6 @@ static NTSTATUS wrap_SQLCopyDesc( void *args ) return SQLCopyDesc( (SQLHDESC)(ULONG_PTR)params->SourceDescHandle, (SQLHDESC)(ULONG_PTR)params->TargetDescHandle ); }
-static NTSTATUS wrap_SQLDataSources( void *args ) -{ - struct SQLDataSources_params *params = args; - return SQLDataSources( (SQLHENV)(ULONG_PTR)params->EnvironmentHandle, params->Direction, params->ServerName, - params->BufferLength1, params->NameLength1, params->Description, - params->BufferLength2, params->NameLength2 ); -} - -static NTSTATUS wrap_SQLDataSourcesW( void *args ) -{ - struct SQLDataSourcesW_params *params = args; - return SQLDataSourcesW( (SQLHENV)(ULONG_PTR)params->EnvironmentHandle, params->Direction, params->ServerName, - params->BufferLength1, params->NameLength1, params->Description, - params->BufferLength2, params->NameLength2 ); -} - static NTSTATUS wrap_SQLDescribeCol( void *args ) { struct SQLDescribeCol_params *params = args; @@ -670,22 +654,6 @@ static NTSTATUS wrap_SQLDriverConnectW( void *args ) params->BufferLength, params->Length2, params->DriverCompletion ); }
-static NTSTATUS wrap_SQLDrivers( void *args ) -{ - struct SQLDrivers_params *params = args; - return SQLDrivers( (SQLHENV)(ULONG_PTR)params->EnvironmentHandle, params->Direction, params->DriverDescription, - params->BufferLength1, params->DescriptionLength, params->DriverAttributes, - params->BufferLength2, params->AttributesLength ); -} - -static NTSTATUS wrap_SQLDriversW( void *args ) -{ - struct SQLDriversW_params *params = args; - return SQLDriversW( (SQLHENV)(ULONG_PTR)params->EnvironmentHandle, params->Direction, params->DriverDescription, - params->BufferLength1, params->DescriptionLength, params->DriverAttributes, - params->BufferLength2, params->AttributesLength ); -} - static NTSTATUS wrap_SQLEndTran( void *args ) { struct SQLEndTran_params *params = args; @@ -1274,16 +1242,12 @@ const unixlib_entry_t __wine_unix_call_funcs[] = wrap_SQLConnect, wrap_SQLConnectW, wrap_SQLCopyDesc, - wrap_SQLDataSources, - wrap_SQLDataSourcesW, wrap_SQLDescribeCol, wrap_SQLDescribeColW, wrap_SQLDescribeParam, wrap_SQLDisconnect, wrap_SQLDriverConnect, wrap_SQLDriverConnectW, - wrap_SQLDrivers, - wrap_SQLDriversW, wrap_SQLEndTran, wrap_SQLError, wrap_SQLErrorW, @@ -1767,64 +1731,6 @@ static NTSTATUS wow64_SQLConnectW( void *args ) return wrap_SQLConnectW( ¶ms ); }
-static NTSTATUS wow64_SQLDataSources( void *args ) -{ - struct - { - UINT64 EnvironmentHandle; - UINT16 Direction; - PTR32 ServerName; - INT16 BufferLength1; - PTR32 NameLength1; - PTR32 Description; - INT16 BufferLength2; - PTR32 NameLength2; - } const *params32 = args; - - struct SQLDataSources_params params = - { - params32->EnvironmentHandle, - params32->Direction, - ULongToPtr(params32->ServerName), - params32->BufferLength1, - ULongToPtr(params32->NameLength1), - ULongToPtr(params32->Description), - params32->BufferLength2, - ULongToPtr(params32->NameLength2) - }; - - return wrap_SQLDataSources( ¶ms ); -} - -static NTSTATUS wow64_SQLDataSourcesW( void *args ) -{ - struct - { - UINT64 EnvironmentHandle; - UINT16 Direction; - PTR32 ServerName; - INT16 BufferLength1; - PTR32 NameLength1; - PTR32 Description; - INT16 BufferLength2; - PTR32 NameLength2; - } const *params32 = args; - - struct SQLDataSourcesW_params params = - { - params32->EnvironmentHandle, - params32->Direction, - ULongToPtr(params32->ServerName), - params32->BufferLength1, - ULongToPtr(params32->NameLength1), - ULongToPtr(params32->Description), - params32->BufferLength2, - ULongToPtr(params32->NameLength2) - }; - - return wrap_SQLDataSourcesW( ¶ms ); -} - static NTSTATUS wow64_SQLDescribeCol( void *args ) { struct @@ -1912,64 +1818,6 @@ static NTSTATUS wow64_SQLDescribeParam( void *args ) return wrap_SQLDescribeParam( ¶ms ); }
-static NTSTATUS wow64_SQLDrivers( void *args ) -{ - struct - { - UINT64 EnvironmentHandle; - UINT16 Direction; - PTR32 DriverDescription; - INT16 BufferLength1; - PTR32 DescriptionLength; - PTR32 DriverAttributes; - INT16 BufferLength2; - PTR32 AttributesLength; - } const *params32 = args; - - struct SQLDrivers_params params = - { - params32->EnvironmentHandle, - params32->Direction, - ULongToPtr(params32->DriverDescription), - params32->BufferLength1, - ULongToPtr(params32->DescriptionLength), - ULongToPtr(params32->DriverAttributes), - params32->BufferLength2, - ULongToPtr(params32->AttributesLength) - }; - - return wrap_SQLDrivers( ¶ms ); -} - -static NTSTATUS wow64_SQLDriversW( void *args ) -{ - struct - { - UINT64 EnvironmentHandle; - UINT16 Direction; - PTR32 DriverDescription; - INT16 BufferLength1; - PTR32 DescriptionLength; - PTR32 DriverAttributes; - INT16 BufferLength2; - PTR32 AttributesLength; - } const *params32 = args; - - struct SQLDriversW_params params = - { - params32->EnvironmentHandle, - params32->Direction, - ULongToPtr(params32->DriverDescription), - params32->BufferLength1, - ULongToPtr(params32->DescriptionLength), - ULongToPtr(params32->DriverAttributes), - params32->BufferLength2, - ULongToPtr(params32->AttributesLength) - }; - - return wrap_SQLDriversW( ¶ms ); -} - static NTSTATUS wow64_SQLDriverConnect( void *args ) { struct @@ -3646,16 +3494,12 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = wow64_SQLConnect, wow64_SQLConnectW, wrap_SQLCopyDesc, - wow64_SQLDataSources, - wow64_SQLDataSourcesW, wow64_SQLDescribeCol, wow64_SQLDescribeColW, wow64_SQLDescribeParam, wrap_SQLDisconnect, wow64_SQLDriverConnect, wow64_SQLDriverConnectW, - wow64_SQLDrivers, - wow64_SQLDriversW, wrap_SQLEndTran, wow64_SQLError, wow64_SQLErrorW, diff --git a/dlls/odbc32/unixlib.h b/dlls/odbc32/unixlib.h index 5e4d799b509..5cc27902ca1 100644 --- a/dlls/odbc32/unixlib.h +++ b/dlls/odbc32/unixlib.h @@ -57,16 +57,12 @@ enum sql_funcs unix_SQLConnect, unix_SQLConnectW, unix_SQLCopyDesc, - unix_SQLDataSources, - unix_SQLDataSourcesW, unix_SQLDescribeCol, unix_SQLDescribeColW, unix_SQLDescribeParam, unix_SQLDisconnect, unix_SQLDriverConnect, unix_SQLDriverConnectW, - unix_SQLDrivers, - unix_SQLDriversW, unix_SQLEndTran, unix_SQLError, unix_SQLErrorW, @@ -189,9 +185,15 @@ struct param_binding
struct handle { + /* handles */ UINT64 unix_handle; + /* drivers and data sources */ UINT32 drivers_idx; void *drivers_key; + UINT32 sources_idx; + void *sources_key; + BOOL sources_system; + /* parameter bindings */ struct param_binding bind_col; struct param_binding bind_parameter; UINT32 row_count; /* number of rows returned by SQLFetch() */ @@ -412,30 +414,6 @@ struct SQLCopyDesc_params UINT64 TargetDescHandle; };
-struct SQLDataSources_params -{ - UINT64 EnvironmentHandle; - UINT16 Direction; - UCHAR *ServerName; - INT16 BufferLength1; - INT16 *NameLength1; - UCHAR *Description; - INT16 BufferLength2; - INT16 *NameLength2; -}; - -struct SQLDataSourcesW_params -{ - UINT64 EnvironmentHandle; - UINT16 Direction; - WCHAR *ServerName; - INT16 BufferLength1; - INT16 *NameLength1; - WCHAR *Description; - INT16 BufferLength2; - INT16 *NameLength2; -}; - struct SQLDescribeCol_params { UINT64 StatementHandle; @@ -501,30 +479,6 @@ struct SQLDriverConnectW_params UINT16 DriverCompletion; };
-struct SQLDrivers_params -{ - UINT64 EnvironmentHandle; - UINT16 Direction; - UCHAR *DriverDescription; - INT16 BufferLength1; - INT16 *DescriptionLength; - UCHAR *DriverAttributes; - INT16 BufferLength2; - INT16 *AttributesLength; -}; - -struct SQLDriversW_params -{ - UINT64 EnvironmentHandle; - UINT16 Direction; - WCHAR *DriverDescription; - INT16 BufferLength1; - INT16 *DescriptionLength; - WCHAR *DriverAttributes; - INT16 BufferLength2; - INT16 *AttributesLength; -}; - struct SQLEndTran_params { INT16 HandleType;
From: Hans Leidekker hans@codeweavers.com
Forwarding is decided by looking at the driver filename. If the data source specifies a driver filename ending in .dll, assume it's a Windows driver, otherwise assume it's a Unix driver. --- dlls/odbc32/proxyodbc.c | 664 +++++++++++++++++++++++++++++++++++----- dlls/odbc32/unixlib.c | 10 +- dlls/odbc32/unixlib.h | 25 +- 3 files changed, 600 insertions(+), 99 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index fb2b5e09929..7bc8d5125f2 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -16,13 +16,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * NOTES: - * Proxy ODBC driver manager. This manager delegates all ODBC - * calls to a real ODBC driver manager named by the environment - * variable LIB_ODBC_DRIVER_MANAGER, or to libodbc.so if the - * variable is not set. - * */
#include <stdarg.h> @@ -35,6 +28,7 @@ #include "winbase.h" #include "winternl.h" #include "winreg.h" +#include "winnls.h" #include "wine/debug.h"
#include "sql.h" @@ -49,10 +43,349 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
static BOOL is_wow64;
-static struct handle *alloc_handle( void ) +struct win32_funcs +{ + SQLRETURN WINAPI (*SQLAllocConnect)(SQLHENV,SQLHDBC*); + SQLRETURN WINAPI (*SQLAllocEnv)(SQLHENV*); + SQLRETURN WINAPI (*SQLAllocHandle)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*); + SQLRETURN WINAPI (*SQLAllocHandleStd)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*); + SQLRETURN WINAPI (*SQLAllocStmt)(SQLHDBC,SQLHSTMT*); + SQLRETURN WINAPI (*SQLBindCol)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*); + SQLRETURN WINAPI (*SQLBindParameter)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN, + SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*); + SQLRETURN WINAPI (*SQLBrowseConnect)(SQLHDBC,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLBrowseConnectW)(SQLHDBC,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLBulkOperations)(SQLHSTMT,SQLSMALLINT); + SQLRETURN WINAPI (*SQLCancel)(SQLHSTMT); + SQLRETURN WINAPI (*SQLCloseCursor)(SQLHSTMT); + SQLRETURN WINAPI (*SQLColAttribute)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*, + SQLLEN*); + SQLRETURN WINAPI (*SQLColAttributeW)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*, + SQLLEN*); + SQLRETURN WINAPI (*SQLColAttributes)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*, + SQLLEN*); + SQLRETURN WINAPI (*SQLColAttributesW)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*, + SQLLEN*); + SQLRETURN WINAPI (*SQLColumnPrivileges)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT, + SQLCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLColumnPrivilegesW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT, + SQLWCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLColumns)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*, + SQLSMALLINT); + SQLRETURN WINAPI (*SQLColumnsW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT, + SQLWCHAR*, SQLSMALLINT); + SQLRETURN WINAPI (*SQLConnect)(SQLHDBC,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLConnectW)(SQLHDBC,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLCopyDesc)(SQLHDESC,SQLHDESC); + SQLRETURN WINAPI (*SQLDescribeCol)(SQLHSTMT,SQLUSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLULEN*, + SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLDescribeColW)(SQLHSTMT,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLULEN*, + SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLDescribeParam)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT*,SQLULEN*,SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLDisconnect)(SQLHDBC); + SQLRETURN WINAPI (*SQLDriverConnect)(SQLHDBC,SQLHWND,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*, + SQLUSMALLINT); + SQLRETURN WINAPI (*SQLDriverConnectW)(SQLHDBC,SQLHWND,WCHAR*,SQLSMALLINT,WCHAR*,SQLSMALLINT,SQLSMALLINT*, + SQLUSMALLINT); + SQLRETURN WINAPI (*SQLEndTran)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT); + SQLRETURN WINAPI (*SQLError)(SQLHENV,SQLHDBC,SQLHSTMT,SQLCHAR*,SQLINTEGER*,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLErrorW)(SQLHENV,SQLHDBC,SQLHSTMT,SQLWCHAR*,SQLINTEGER*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLExecDirect)(SQLHSTMT,SQLCHAR*,SQLINTEGER); + SQLRETURN WINAPI (*SQLExecDirectW)(SQLHSTMT,SQLWCHAR*,SQLINTEGER); + SQLRETURN WINAPI (*SQLExecute)(SQLHSTMT); + SQLRETURN WINAPI (*SQLExtendedFetch)(SQLHSTMT,SQLUSMALLINT,SQLLEN,SQLULEN*,SQLUSMALLINT*); + SQLRETURN WINAPI (*SQLFetch)(SQLHSTMT); + SQLRETURN WINAPI (*SQLFetchScroll)(SQLHSTMT,SQLSMALLINT,SQLLEN); + SQLRETURN WINAPI (*SQLForeignKeys)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT, + SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLForeignKeysW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT, + SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLFreeConnect)(SQLHDBC); + SQLRETURN WINAPI (*SQLFreeEnv)(SQLHENV); + SQLRETURN WINAPI (*SQLFreeHandle)(SQLSMALLINT,SQLHANDLE); + SQLRETURN WINAPI (*SQLFreeStmt)(SQLHSTMT,SQLUSMALLINT); + SQLRETURN WINAPI (*SQLGetConnectAttr)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN WINAPI (*SQLGetConnectAttrW)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN WINAPI (*SQLGetConnectOption)(SQLHDBC,SQLUSMALLINT,SQLPOINTER); + SQLRETURN WINAPI (*SQLGetConnectOptionW)(SQLHDBC,SQLUSMALLINT,SQLPOINTER); + SQLRETURN WINAPI (*SQLGetCursorName)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetCursorNameW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetData)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*); + SQLRETURN WINAPI (*SQLGetDescField)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN WINAPI (*SQLGetDescFieldW)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN WINAPI (*SQLGetDescRec)(SQLHDESC,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*, + SQLSMALLINT*,SQLLEN*,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetDescRecW)(SQLHDESC,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*, + SQLSMALLINT*,SQLLEN*,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetDiagField)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLSMALLINT, + SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetDiagFieldW)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLSMALLINT, + SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetDiagRec)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLCHAR*,SQLINTEGER*,SQLCHAR*,SQLSMALLINT, + SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetDiagRecW)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLWCHAR*,SQLINTEGER*,SQLWCHAR*,SQLSMALLINT, + SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetEnvAttr)(SQLHENV,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN WINAPI (*SQLGetFunctions)(SQLHDBC,SQLUSMALLINT,SQLUSMALLINT*); + SQLRETURN WINAPI (*SQLGetInfo)(SQLHDBC,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetInfoW)(SQLHDBC,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLGetStmtAttr)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN WINAPI (*SQLGetStmtAttrW)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN WINAPI (*SQLGetStmtOption)(SQLHSTMT,SQLUSMALLINT,SQLPOINTER); + SQLRETURN WINAPI (*SQLGetTypeInfo)(SQLHSTMT,SQLSMALLINT); + SQLRETURN WINAPI (*SQLGetTypeInfoW)(SQLHSTMT,SQLSMALLINT); + SQLRETURN WINAPI (*SQLMoreResults)(SQLHSTMT); + SQLRETURN WINAPI (*SQLNativeSql)(SQLHDBC,SQLCHAR*,SQLINTEGER,SQLCHAR*,SQLINTEGER,SQLINTEGER*); + SQLRETURN WINAPI (*SQLNativeSqlW)(SQLHDBC,SQLWCHAR*,SQLINTEGER,SQLWCHAR*,SQLINTEGER,SQLINTEGER*); + SQLRETURN WINAPI (*SQLNumParams)(SQLHSTMT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLNumResultCols)(SQLHSTMT,SQLSMALLINT*); + SQLRETURN WINAPI (*SQLParamData)(SQLHSTMT,SQLPOINTER*); + SQLRETURN WINAPI (*SQLParamOptions)(SQLHSTMT,SQLULEN,SQLULEN*); + SQLRETURN WINAPI (*SQLPrepare)(SQLHSTMT,SQLCHAR*,SQLINTEGER); + SQLRETURN WINAPI (*SQLPrepareW)(SQLHSTMT,SQLWCHAR*,SQLINTEGER); + SQLRETURN WINAPI (*SQLPrimaryKeys)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLPrimaryKeysW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLProcedureColumns)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT, + SQLCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLProcedureColumnsW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT, + SQLWCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLProcedures)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLProceduresW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLPutData)(SQLHSTMT,SQLPOINTER,SQLLEN); + SQLRETURN WINAPI (*SQLRowCount)(SQLHSTMT,SQLLEN*); + SQLRETURN WINAPI (*SQLSetConnectAttr)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN WINAPI (*SQLSetConnectAttrW)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN WINAPI (*SQLSetConnectOption)(SQLHDBC,SQLUSMALLINT,SQLULEN); + SQLRETURN WINAPI (*SQLSetConnectOptionW)(SQLHDBC,SQLUSMALLINT,SQLULEN); + SQLRETURN WINAPI (*SQLSetCursorName)(SQLHSTMT,SQLCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLSetCursorNameW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLSetDescField)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER); + SQLRETURN WINAPI (*SQLSetDescFieldW)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER); + SQLRETURN WINAPI (*SQLSetDescRec)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLLEN,SQLSMALLINT,SQLSMALLINT, + SQLPOINTER,SQLLEN*,SQLLEN*); + SQLRETURN WINAPI (*SQLSetEnvAttr)(SQLHENV,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN WINAPI (*SQLSetParam)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER, + SQLLEN*); + SQLRETURN WINAPI (*SQLSetPos)(SQLHSTMT,SQLSETPOSIROW,SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN WINAPI (*SQLSetScrollOptions)(SQLHSTMT,SQLUSMALLINT,SQLLEN,SQLUSMALLINT); + SQLRETURN WINAPI (*SQLSetStmtAttr)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN WINAPI (*SQLSetStmtAttrW)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN WINAPI (*SQLSetStmtOption)(SQLHSTMT,SQLUSMALLINT,SQLULEN); + SQLRETURN WINAPI (*SQLSpecialColumns)(SQLHSTMT,SQLUSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*, + SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN WINAPI (*SQLSpecialColumnsW)(SQLHSTMT,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*, + SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN WINAPI (*SQLStatistics)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT, + SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN WINAPI (*SQLStatisticsW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT, + SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN WINAPI (*SQLTablePrivileges)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLTablePrivilegesW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN WINAPI (*SQLTables)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*, + SQLSMALLINT); + SQLRETURN WINAPI (*SQLTablesW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*, + SQLSMALLINT); + SQLRETURN WINAPI (*SQLTransact)(SQLHENV,SQLHDBC,SQLUSMALLINT); +}; + +struct win32_driver +{ + const WCHAR *filename; + struct win32_funcs funcs; +}; + +static BOOL load_function_table( HMODULE module, struct win32_driver *driver ) +{ +#define LOAD_FUNCPTR(f) \ + if (!(driver->funcs.f = (typeof(f) *)GetProcAddress( module, #f ))) \ + { \ + TRACE( "failed to load %s\n", #f ); \ + } + LOAD_FUNCPTR( SQLAllocConnect ) + LOAD_FUNCPTR( SQLAllocEnv ) + LOAD_FUNCPTR( SQLAllocHandle ) + LOAD_FUNCPTR( SQLAllocHandleStd ) + LOAD_FUNCPTR( SQLAllocStmt ) + LOAD_FUNCPTR( SQLBindCol ) + LOAD_FUNCPTR( SQLBindParameter ) + LOAD_FUNCPTR( SQLBrowseConnect ) + LOAD_FUNCPTR( SQLBrowseConnectW ) + LOAD_FUNCPTR( SQLBulkOperations ) + LOAD_FUNCPTR( SQLCancel ) + LOAD_FUNCPTR( SQLCloseCursor ) + LOAD_FUNCPTR( SQLColAttribute ) + LOAD_FUNCPTR( SQLColAttributeW ) + LOAD_FUNCPTR( SQLColAttributes ) + LOAD_FUNCPTR( SQLColAttributesW ) + LOAD_FUNCPTR( SQLColumnPrivileges ) + LOAD_FUNCPTR( SQLColumnPrivilegesW ) + LOAD_FUNCPTR( SQLColumns ) + LOAD_FUNCPTR( SQLColumnsW ) + LOAD_FUNCPTR( SQLConnect ) + LOAD_FUNCPTR( SQLConnectW ) + LOAD_FUNCPTR( SQLCopyDesc ) + LOAD_FUNCPTR( SQLDescribeCol ) + LOAD_FUNCPTR( SQLDescribeColW ) + LOAD_FUNCPTR( SQLDescribeParam ) + LOAD_FUNCPTR( SQLDisconnect ) + LOAD_FUNCPTR( SQLDriverConnect ) + LOAD_FUNCPTR( SQLDriverConnectW ) + LOAD_FUNCPTR( SQLEndTran ) + LOAD_FUNCPTR( SQLError ) + LOAD_FUNCPTR( SQLErrorW ) + LOAD_FUNCPTR( SQLExecDirect ) + LOAD_FUNCPTR( SQLExecDirectW ) + LOAD_FUNCPTR( SQLExecute ) + LOAD_FUNCPTR( SQLExtendedFetch ) + LOAD_FUNCPTR( SQLFetch ) + LOAD_FUNCPTR( SQLFetchScroll ) + LOAD_FUNCPTR( SQLForeignKeys ) + LOAD_FUNCPTR( SQLForeignKeysW ) + LOAD_FUNCPTR( SQLFreeConnect ) + LOAD_FUNCPTR( SQLFreeEnv ) + LOAD_FUNCPTR( SQLFreeHandle ) + LOAD_FUNCPTR( SQLFreeStmt ) + LOAD_FUNCPTR( SQLGetConnectAttr ) + LOAD_FUNCPTR( SQLGetConnectAttrW ) + LOAD_FUNCPTR( SQLGetConnectOption ) + LOAD_FUNCPTR( SQLGetConnectOptionW ) + LOAD_FUNCPTR( SQLGetCursorName ) + LOAD_FUNCPTR( SQLGetCursorNameW ) + LOAD_FUNCPTR( SQLGetData ) + LOAD_FUNCPTR( SQLGetDescField ) + LOAD_FUNCPTR( SQLGetDescFieldW ) + LOAD_FUNCPTR( SQLGetDescRec ) + LOAD_FUNCPTR( SQLGetDescRecW ) + LOAD_FUNCPTR( SQLGetDiagField ) + LOAD_FUNCPTR( SQLGetDiagFieldW ) + LOAD_FUNCPTR( SQLGetDiagRec ) + LOAD_FUNCPTR( SQLGetDiagRecW ) + LOAD_FUNCPTR( SQLGetEnvAttr ) + LOAD_FUNCPTR( SQLGetFunctions ) + LOAD_FUNCPTR( SQLGetInfo ) + LOAD_FUNCPTR( SQLGetInfoW ) + LOAD_FUNCPTR( SQLGetStmtAttr ) + LOAD_FUNCPTR( SQLGetStmtAttrW ) + LOAD_FUNCPTR( SQLGetStmtOption ) + LOAD_FUNCPTR( SQLGetTypeInfo ) + LOAD_FUNCPTR( SQLGetTypeInfoW ) + LOAD_FUNCPTR( SQLMoreResults ) + LOAD_FUNCPTR( SQLNativeSql ) + LOAD_FUNCPTR( SQLNativeSqlW ) + LOAD_FUNCPTR( SQLNumParams ) + LOAD_FUNCPTR( SQLNumResultCols ) + LOAD_FUNCPTR( SQLParamData ) + LOAD_FUNCPTR( SQLParamOptions ) + LOAD_FUNCPTR( SQLPrepare ) + LOAD_FUNCPTR( SQLPrepareW ) + LOAD_FUNCPTR( SQLPrimaryKeys ) + LOAD_FUNCPTR( SQLPrimaryKeysW ) + LOAD_FUNCPTR( SQLProcedureColumns ) + LOAD_FUNCPTR( SQLProcedureColumnsW ) + LOAD_FUNCPTR( SQLProcedures ) + LOAD_FUNCPTR( SQLProceduresW ) + LOAD_FUNCPTR( SQLPutData ) + LOAD_FUNCPTR( SQLRowCount ) + LOAD_FUNCPTR( SQLSetConnectAttr ) + LOAD_FUNCPTR( SQLSetConnectAttrW ) + LOAD_FUNCPTR( SQLSetConnectOption ) + LOAD_FUNCPTR( SQLSetConnectOptionW ) + LOAD_FUNCPTR( SQLSetCursorName ) + LOAD_FUNCPTR( SQLSetCursorNameW ) + LOAD_FUNCPTR( SQLSetDescField ) + LOAD_FUNCPTR( SQLSetDescFieldW ) + LOAD_FUNCPTR( SQLSetDescRec ) + LOAD_FUNCPTR( SQLSetEnvAttr ) + LOAD_FUNCPTR( SQLSetParam ) + LOAD_FUNCPTR( SQLSetPos ) + LOAD_FUNCPTR( SQLSetScrollOptions ) + LOAD_FUNCPTR( SQLSetStmtAttr ) + LOAD_FUNCPTR( SQLSetStmtAttrW ) + LOAD_FUNCPTR( SQLSetStmtOption ) + LOAD_FUNCPTR( SQLSpecialColumns ) + LOAD_FUNCPTR( SQLSpecialColumnsW ) + LOAD_FUNCPTR( SQLStatistics ) + LOAD_FUNCPTR( SQLStatisticsW ) + LOAD_FUNCPTR( SQLTablePrivileges ) + LOAD_FUNCPTR( SQLTablePrivilegesW ) + LOAD_FUNCPTR( SQLTables ) + LOAD_FUNCPTR( SQLTablesW ) + LOAD_FUNCPTR( SQLTransact ) + return TRUE; +#undef LOAD_FUNCPTR +} + +static struct +{ + UINT32 count; + struct win32_driver **drivers; +} win32_drivers; + +static BOOL append_driver( struct win32_driver *driver ) +{ + struct win32_driver **tmp; + UINT32 new_count = win32_drivers.count + 1; + + if (!(tmp = realloc( win32_drivers.drivers, new_count * sizeof(*win32_drivers.drivers) ))) + return FALSE; + + tmp[win32_drivers.count] = driver; + win32_drivers.drivers = tmp; + win32_drivers.count = new_count; + return TRUE; +} + +static const struct win32_funcs *load_driver( const WCHAR *filename ) +{ + HMODULE module; + struct win32_driver *driver; + WCHAR *ptr, *path = wcsdup( filename ); + UINT32 i; + + for (i = 0; i < win32_drivers.count; i++) + { + if (!wcsicmp( filename, win32_drivers.drivers[i]->filename )) + { + free( path ); + return &win32_drivers.drivers[i]->funcs; + } + } + + if (!(driver = malloc( sizeof(*driver) + (wcslen(filename) + 1) * sizeof(WCHAR) ))) + { + free( path ); + return NULL; + } + ptr = (WCHAR *)(driver + 1); + wcscpy( ptr, filename ); + driver->filename = ptr; + + if ((ptr = wcsrchr( path, '\' )) || (ptr = wcsrchr( path, '/' ))) *ptr = 0; + SetDllDirectoryW( path ); + module = LoadLibraryW( filename ); + SetDllDirectoryW( NULL ); + free( path ); + if (!module) + { + free( driver ); + return NULL; + } + + if (!load_function_table( module, driver ) || !append_driver( driver )) + { + FreeLibrary( module ); + free( driver ); + return NULL; + } + + return &driver->funcs; +} + +static struct handle *create_handle( struct handle *parent ) { struct handle *ret; if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL; + ret->parent = parent; ret->row_count = 1; return ret; } @@ -62,22 +395,12 @@ static struct handle *alloc_handle( void ) */ SQLRETURN WINAPI SQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC *ConnectionHandle) { - struct SQLAllocConnect_params params; - struct handle *con, *env = EnvironmentHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(EnvironmentHandle %p, ConnectionHandle %p)\n", EnvironmentHandle, ConnectionHandle);
- *ConnectionHandle = 0; - if (!(con = alloc_handle())) return SQL_ERROR; - - params.EnvironmentHandle = env->unix_handle; - if (SUCCESS((ret = ODBC_CALL( SQLAllocConnect, ¶ms )))) - { - con->unix_handle = params.ConnectionHandle; - *ConnectionHandle = con; - } - else free( con ); + /* delay creating handle in lower layer until SQLConnect() is called */ + if ((*ConnectionHandle = create_handle( EnvironmentHandle ))) ret = SQL_SUCCESS;
TRACE("Returning %d, ConnectionHandle %p\n", ret, *ConnectionHandle); return ret; @@ -88,21 +411,12 @@ SQLRETURN WINAPI SQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC *ConnectionH */ SQLRETURN WINAPI SQLAllocEnv(SQLHENV *EnvironmentHandle) { - struct SQLAllocEnv_params params; - struct handle *env; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(EnvironmentHandle %p)\n", EnvironmentHandle);
- *EnvironmentHandle = 0; - if (!(env = alloc_handle())) return SQL_ERROR; - - if (SUCCESS((ret = ODBC_CALL( SQLAllocEnv, ¶ms )))) - { - env->unix_handle = params.EnvironmentHandle; - *EnvironmentHandle = env; - } - else free( env ); + /* delay creating handle in lower layer until SQLConnect() is called */ + if ((*EnvironmentHandle = create_handle( NULL ))) ret = SQL_SUCCESS;
TRACE("Returning %d, EnvironmentHandle %p\n", ret, *EnvironmentHandle); return ret; @@ -113,22 +427,34 @@ SQLRETURN WINAPI SQLAllocEnv(SQLHENV *EnvironmentHandle) */ SQLRETURN WINAPI SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle) { - struct SQLAllocHandle_params params; struct handle *output, *input = InputHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(HandleType %d, InputHandle %p, OutputHandle %p)\n", HandleType, InputHandle, OutputHandle);
*OutputHandle = 0; - if (!(output = alloc_handle())) return SQL_ERROR; + if (!(output = create_handle( input ))) return SQL_ERROR;
- params.HandleType = HandleType; - params.InputHandle = input ? input->unix_handle : 0; - if (SUCCESS((ret = ODBC_CALL( SQLAllocHandle, ¶ms )))) + /* delay creating these handles in lower layer until SQLConnect() is called */ + if (HandleType == SQL_HANDLE_ENV || HandleType == SQL_HANDLE_DBC) { - output->unix_handle = params.OutputHandle; *OutputHandle = output; + TRACE("Returning 0, OutputHandle %p\n", *OutputHandle); + return SQL_SUCCESS; } + + if (input->unix_handle) + { + struct SQLAllocHandle_params params = { HandleType, input->unix_handle, &output->unix_handle }; + ret = ODBC_CALL( SQLAllocHandle, ¶ms ); + } + else if (input->win32_handle) + { + ret = input->win32_funcs->SQLAllocHandle( HandleType, input->win32_handle, &output->win32_handle ); + if (SUCCESS( ret )) output->win32_funcs = input->win32_funcs; + } + + if (SUCCESS( ret )) *OutputHandle = output; else free( output );
TRACE("Returning %d, OutputHandle %p\n", ret, *OutputHandle); @@ -140,21 +466,26 @@ SQLRETURN WINAPI SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, S */ SQLRETURN WINAPI SQLAllocStmt(SQLHDBC ConnectionHandle, SQLHSTMT *StatementHandle) { - struct SQLAllocStmt_params params; struct handle *stmt, *con = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, StatementHandle %p)\n", ConnectionHandle, StatementHandle);
*StatementHandle = 0; - if (!(stmt = alloc_handle())) return SQL_ERROR; + if (!(stmt = create_handle( con ))) return SQL_ERROR;
- params.ConnectionHandle = con->unix_handle; - if (SUCCESS((ret = ODBC_CALL( SQLAllocStmt, ¶ms )))) + if (con->unix_handle) { - stmt->unix_handle = params.StatementHandle; - *StatementHandle = stmt; + struct SQLAllocStmt_params params = { con->unix_handle, &stmt->unix_handle }; + ret = ODBC_CALL( SQLAllocStmt, ¶ms ); } + else if (con->win32_handle) + { + ret = con->win32_funcs->SQLAllocStmt( con->win32_handle, &stmt->win32_handle ); + if (SUCCESS( ret )) stmt->win32_funcs = con->win32_funcs; + } + + if (SUCCESS( ret )) *StatementHandle = stmt; else free( stmt );
TRACE ("Returning %d, StatementHandle %p\n", ret, *StatementHandle); @@ -166,22 +497,34 @@ SQLRETURN WINAPI SQLAllocStmt(SQLHDBC ConnectionHandle, SQLHSTMT *StatementHandl */ SQLRETURN WINAPI SQLAllocHandleStd(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle) { - struct SQLAllocHandleStd_params params; struct handle *output, *input = InputHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(HandleType %d, InputHandle %p, OutputHandle %p)\n", HandleType, InputHandle, OutputHandle);
*OutputHandle = 0; - if (!(output = alloc_handle())) return SQL_ERROR; + if (!(output = create_handle( input ))) return SQL_ERROR;
- params.HandleType = HandleType; - params.InputHandle = input ? input->unix_handle : 0; - if (SUCCESS((ret = ODBC_CALL( SQLAllocHandleStd, ¶ms )))) + /* delay creating these handles in lower layer until SQLConnect() is called */ + if (HandleType == SQL_HANDLE_ENV || HandleType == SQL_HANDLE_DBC) { - output->unix_handle = params.OutputHandle; *OutputHandle = output; + TRACE("Returning 0, OutputHandle %p\n", *OutputHandle); + return SQL_SUCCESS; } + + if (input->unix_handle) + { + struct SQLAllocHandleStd_params params = { HandleType, input->unix_handle, &output->unix_handle }; + ret = ODBC_CALL( SQLAllocHandleStd, ¶ms ); + } + else if (input->win32_handle) + { + ret = input->win32_funcs->SQLAllocHandleStd( HandleType, input->win32_handle, &output->win32_handle ); + if (SUCCESS( ret )) output->win32_funcs = input->win32_funcs; + } + + if (SUCCESS( ret )) *OutputHandle = output; else free( output );
TRACE ("Returning %d, OutputHandle %p\n", ret, *OutputHandle); @@ -358,6 +701,64 @@ SQLRETURN WINAPI SQLColumns(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLS return ret; }
+static WCHAR *strdupAW( const char *src ) +{ + int len; + WCHAR *dst; + if (!src) return NULL; + len = MultiByteToWideChar( CP_ACP, 0, src, -1, NULL, 0 ); + if ((dst = malloc( len * sizeof(*dst) ))) MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len ); + return dst; +} + +static HKEY open_odbcini_key( HKEY root ) +{ + static const WCHAR sourcesW[] = L"Software\ODBC\ODBC.INI"; + HKEY key; + if (!RegCreateKeyExW( root, sourcesW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL )) return key; + return NULL; +} + +static WCHAR *get_reg_value( HKEY key, const WCHAR *name ) +{ + WCHAR *ret; + DWORD len = 0; + if (RegGetValueW( key, NULL, name, RRF_RT_REG_SZ, NULL, NULL, &len ) || !(ret = malloc( len ))) return NULL; + if (!RegGetValueW( key, NULL, name, RRF_RT_REG_SZ, NULL, ret, &len )) return ret; + free( ret ); + return NULL; +} + +static WCHAR *get_driver_filename( const SQLWCHAR *source ) +{ + HKEY key_root, key_source; + WCHAR *ret = NULL; + + if (!(key_root = open_odbcini_key( HKEY_CURRENT_USER ))) return NULL; + if (!RegOpenKeyExW( key_root, source, 0, KEY_READ, &key_source )) + { + ret = get_reg_value( key_source, L"Driver" ); + RegCloseKey( key_source ); + } + RegCloseKey( key_root ); + if (ret) return ret; + + if (!(key_root = open_odbcini_key( HKEY_LOCAL_MACHINE ))) return NULL; + if (!RegOpenKeyExW( key_root, source, 0, KEY_READ, &key_source )) + { + ret = get_reg_value( key_source, L"Driver" ); + RegCloseKey( key_source ); + } + RegCloseKey( key_root ); + return ret; +} + +static int has_suffix( const WCHAR *str, const WCHAR *suffix ) +{ + int len = wcslen( str ), len2 = wcslen( suffix ); + return len >= len2 && !wcsicmp( str + len - len2, suffix ); +} + /************************************************************************* * SQLConnect [ODBC32.007] */ @@ -365,9 +766,9 @@ SQLRETURN WINAPI SQLConnect(SQLHDBC ConnectionHandle, SQLCHAR *ServerName, SQLSM SQLCHAR *UserName, SQLSMALLINT NameLength2, SQLCHAR *Authentication, SQLSMALLINT NameLength3) { - struct SQLConnect_params params = { 0, ServerName, NameLength1, UserName, NameLength2, Authentication, NameLength3 }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + WCHAR *filename, *servername = strdupAW( (const char *)ServerName ); + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, ServerName %s, NameLength1 %d, UserName %s, NameLength2 %d, Authentication %s," " NameLength3 %d)\n", ConnectionHandle, @@ -377,8 +778,51 @@ SQLRETURN WINAPI SQLConnect(SQLHDBC ConnectionHandle, SQLCHAR *ServerName, SQLSM
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLConnect, ¶ms ); + if (!servername || !(filename = get_driver_filename( servername ))) + { + WARN( "can't find driver filename\n" ); + goto done; + } + + if (has_suffix( filename, L".dll" )) + { + if (!(handle->win32_funcs = load_driver( filename ))) + { + WARN( "failed to load driver %s\n", debugstr_w(filename) ); + goto done; + } + TRACE( "using Windows driver %s\n", debugstr_w(filename) ); + + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_ENV, NULL, + &handle->parent->win32_handle )))) goto done; + + handle->parent->win32_funcs = handle->win32_funcs; + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_DBC, handle->parent->win32_handle, + &handle->win32_handle )))) goto done; + + ret = handle->win32_funcs->SQLConnect( handle->win32_handle, ServerName, NameLength1, UserName, NameLength2, + Authentication, NameLength3 ); + } + else + { + struct SQLAllocEnv_params params_alloc_env = { &handle->parent->unix_handle }; + struct SQLAllocConnect_params params_alloc_connect = { 0, &handle->unix_handle }; + struct SQLConnect_params params_connect = { 0, ServerName, NameLength1, UserName, NameLength2, + Authentication, NameLength3 }; + + TRACE( "using Unix driver %s\n", debugstr_w(filename) ); + if (!SUCCESS((ret = ODBC_CALL( SQLAllocEnv, ¶ms_alloc_env )))) goto done; + + params_alloc_connect.EnvironmentHandle = handle->parent->unix_handle; + if (!SUCCESS((ret = ODBC_CALL( SQLAllocConnect, ¶ms_alloc_connect )))) goto done; + + params_connect.ConnectionHandle = handle->unix_handle; + ret = ODBC_CALL( SQLConnect, ¶ms_connect ); + } + +done: + free( servername ); + free( filename ); TRACE("Returning %d\n", ret); return ret; } @@ -733,16 +1177,23 @@ SQLRETURN WINAPI SQLFetchScroll(SQLHSTMT StatementHandle, SQLSMALLINT FetchOrien */ SQLRETURN WINAPI SQLFreeConnect(SQLHDBC ConnectionHandle) { - struct SQLFreeConnect_params params; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_SUCCESS;
TRACE("(ConnectionHandle %p)\n", ConnectionHandle);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLFreeConnect, ¶ms ); + if (handle->unix_handle) + { + struct SQLFreeConnect_params params = { handle->unix_handle }; + ret = ODBC_CALL( SQLFreeConnect, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLFreeConnect( handle->win32_handle ); + } + free( handle ); TRACE("Returning %d\n", ret); return ret; @@ -753,17 +1204,27 @@ SQLRETURN WINAPI SQLFreeConnect(SQLHDBC ConnectionHandle) */ SQLRETURN WINAPI SQLFreeEnv(SQLHENV EnvironmentHandle) { - struct SQLFreeEnv_params params; struct handle *handle = EnvironmentHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_SUCCESS;
TRACE("(EnvironmentHandle %p)\n", EnvironmentHandle);
if (!handle) return SQL_INVALID_HANDLE;
- params.EnvironmentHandle = handle->unix_handle; - ret = ODBC_CALL( SQLFreeEnv, ¶ms ); + if (handle->unix_handle) + { + struct SQLFreeEnv_params params = { handle->unix_handle }; + ret = ODBC_CALL( SQLFreeEnv, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLFreeEnv( handle->win32_handle ); + } + + RegCloseKey( handle->drivers_key ); + RegCloseKey( handle->sources_key ); free( handle ); + TRACE("Returning %d\n", ret); return ret; } @@ -787,20 +1248,29 @@ static void free_bindings( struct handle *handle ) */ SQLRETURN WINAPI SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle) { - struct SQLFreeHandle_params params; struct handle *handle = Handle; - SQLRETURN ret; + SQLRETURN ret = SQL_SUCCESS;
TRACE("(HandleType %d, Handle %p)\n", HandleType, Handle);
if (!handle) return SQL_INVALID_HANDLE;
- params.HandleType = HandleType; - params.Handle = handle->unix_handle; - ret = ODBC_CALL( SQLFreeHandle, ¶ms ); - free_bindings( handle ); + if (handle->unix_handle) + { + struct SQLFreeHandle_params params = { HandleType, handle->unix_handle }; + ret = ODBC_CALL( SQLFreeHandle, ¶ms ); + free_bindings( handle ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLFreeHandle( HandleType, handle->win32_handle ); + } + + RegCloseKey( handle->drivers_key ); + RegCloseKey( handle->sources_key ); free( handle ); - TRACE ("Returning %d\n", ret); + + TRACE("Returning %d\n", ret); return ret; }
@@ -809,19 +1279,26 @@ SQLRETURN WINAPI SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle) */ SQLRETURN WINAPI SQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option) { - struct SQLFreeStmt_params params; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Option %d)\n", StatementHandle, Option);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.Option = Option; - ret = ODBC_CALL( SQLFreeStmt, ¶ms ); - free_bindings( handle ); + if (handle->unix_handle) + { + struct SQLFreeStmt_params params = { handle->unix_handle, Option }; + ret = ODBC_CALL( SQLFreeStmt, ¶ms ); + free_bindings( handle ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLFreeStmt( handle->win32_handle, Option ); + } + free( handle ); + TRACE("Returning %d\n", ret); return ret; } @@ -1011,17 +1488,38 @@ SQLRETURN WINAPI SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMAL SQLRETURN WINAPI SQLGetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength) { - struct SQLGetEnvAttr_params params = { 0, Attribute, Value, BufferLength, StringLength }; struct handle *handle = EnvironmentHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_SUCCESS;
TRACE("(EnvironmentHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n", EnvironmentHandle, Attribute, Value, BufferLength, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.EnvironmentHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetEnvAttr, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetEnvAttr_params params = { handle->unix_handle, Attribute, Value, BufferLength, StringLength }; + ret = ODBC_CALL( SQLGetEnvAttr, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetEnvAttr( handle->win32_handle, Attribute, Value, BufferLength, StringLength ); + } + else + { + switch (Attribute) + { + case SQL_ATTR_ODBC_VERSION: + *(SQLINTEGER *)Value = 2; + break; + + default: + FIXME( "unhandled attribute %d\n", Attribute ); + ret = SQL_ERROR; + break; + } + } + TRACE("Returning %d\n", ret); return ret; } diff --git a/dlls/odbc32/unixlib.c b/dlls/odbc32/unixlib.c index 24f935fb1d2..6f244514d7d 100644 --- a/dlls/odbc32/unixlib.c +++ b/dlls/odbc32/unixlib.c @@ -445,33 +445,33 @@ static NTSTATUS odbc_process_attach( void *args ) static NTSTATUS wrap_SQLAllocConnect( void *args ) { struct SQLAllocConnect_params *params = args; - return SQLAllocConnect( (SQLHENV)(ULONG_PTR)params->EnvironmentHandle, (SQLHDBC *)¶ms->ConnectionHandle ); + return SQLAllocConnect( (SQLHENV)(ULONG_PTR)params->EnvironmentHandle, (SQLHDBC *)params->ConnectionHandle ); }
static NTSTATUS wrap_SQLAllocEnv( void *args ) { struct SQLAllocEnv_params *params = args; - return SQLAllocEnv( (SQLHENV *)¶ms->EnvironmentHandle ); + return SQLAllocEnv( (SQLHENV *)params->EnvironmentHandle ); }
static NTSTATUS wrap_SQLAllocHandle( void *args ) { struct SQLAllocHandle_params *params = args; return SQLAllocHandle( params->HandleType, (SQLHANDLE)(ULONG_PTR)params->InputHandle, - (SQLHANDLE *)¶ms->OutputHandle ); + (SQLHANDLE *)params->OutputHandle ); }
static NTSTATUS wrap_SQLAllocHandleStd( void *args ) { struct SQLAllocHandleStd_params *params = args; return SQLAllocHandleStd( params->HandleType, (SQLHANDLE)(ULONG_PTR)params->InputHandle, - (SQLHANDLE *)¶ms->OutputHandle ); + (SQLHANDLE *)params->OutputHandle ); }
static NTSTATUS wrap_SQLAllocStmt( void *args ) { struct SQLAllocStmt_params *params = args; - return SQLAllocStmt( (SQLHDBC)(ULONG_PTR)params->ConnectionHandle, (SQLHSTMT *)¶ms->StatementHandle ); + return SQLAllocStmt( (SQLHDBC)(ULONG_PTR)params->ConnectionHandle, (SQLHSTMT *)params->StatementHandle ); }
static NTSTATUS wrap_SQLBindCol( void *args ) diff --git a/dlls/odbc32/unixlib.h b/dlls/odbc32/unixlib.h index 5cc27902ca1..380856ec71f 100644 --- a/dlls/odbc32/unixlib.h +++ b/dlls/odbc32/unixlib.h @@ -187,6 +187,9 @@ struct handle { /* handles */ UINT64 unix_handle; + void *win32_handle; + const struct win32_funcs *win32_funcs; + struct handle *parent; /* drivers and data sources */ UINT32 drivers_idx; void *drivers_key; @@ -201,33 +204,33 @@ struct handle
struct SQLAllocConnect_params { - UINT64 EnvironmentHandle; - UINT64 ConnectionHandle; + UINT64 EnvironmentHandle; + UINT64 *ConnectionHandle; };
struct SQLAllocEnv_params { - UINT64 EnvironmentHandle; + UINT64 *EnvironmentHandle; };
struct SQLAllocHandle_params { - INT16 HandleType; - UINT64 InputHandle; - UINT64 OutputHandle; + INT16 HandleType; + UINT64 InputHandle; + UINT64 *OutputHandle; };
struct SQLAllocHandleStd_params { - INT16 HandleType; - UINT64 InputHandle; - UINT64 OutputHandle; + INT16 HandleType; + UINT64 InputHandle; + UINT64 *OutputHandle; };
struct SQLAllocStmt_params { - UINT64 ConnectionHandle; - UINT64 StatementHandle; + UINT64 ConnectionHandle; + UINT64 *StatementHandle; };
struct SQLBindCol_params
From: Hans Leidekker hans@codeweavers.com
--- dlls/odbc32/proxyodbc.c | 271 +++++++++++++++++++++++++++------------- 1 file changed, 183 insertions(+), 88 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index 7bc8d5125f2..028163412a9 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -562,28 +562,40 @@ static BOOL alloc_binding( struct param_binding *binding, USHORT type, UINT colu SQLRETURN WINAPI SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind) { - struct SQLBindCol_params params = { 0, ColumnNumber, TargetType, TargetValue, BufferLength }; struct handle *handle = StatementHandle; - UINT i = ColumnNumber - 1; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ColumnNumber %d, TargetType %d, TargetValue %p, BufferLength %s, StrLen_or_Ind %p)\n", StatementHandle, ColumnNumber, TargetType, TargetValue, debugstr_sqllen(BufferLength), StrLen_or_Ind);
if (!handle) return SQL_INVALID_HANDLE; - if (!ColumnNumber) + + if (handle->unix_handle) { - FIXME( "column 0 not handled\n" ); - return SQL_ERROR; + UINT i = ColumnNumber - 1; + struct SQLBindCol_params params = { handle->unix_handle, ColumnNumber, TargetType, TargetValue, BufferLength }; + + if (!ColumnNumber) + { + FIXME( "column 0 not handled\n" ); + return SQL_ERROR; + } + + if (!alloc_binding( &handle->bind_col, SQL_PARAM_INPUT_OUTPUT, ColumnNumber, handle->row_count )) + return SQL_ERROR; + handle->bind_col.param[i].col.target_type = TargetType; + handle->bind_col.param[i].col.target_value = TargetValue; + handle->bind_col.param[i].col.buffer_length = BufferLength; + + if (StrLen_or_Ind) params.StrLen_or_Ind = handle->bind_col.param[i].len; + if (SUCCESS(( ret = ODBC_CALL( SQLBindCol, ¶ms )))) handle->bind_col.param[i].ptr = StrLen_or_Ind; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLBindCol( handle->win32_handle, ColumnNumber, TargetType, TargetValue, + BufferLength, StrLen_or_Ind ); } - if (!alloc_binding( &handle->bind_col, SQL_PARAM_INPUT_OUTPUT, ColumnNumber, handle->row_count )) return SQL_ERROR; - handle->bind_col.param[i].col.target_type = TargetType; - handle->bind_col.param[i].col.target_value = TargetValue; - handle->bind_col.param[i].col.buffer_length = BufferLength;
- params.StatementHandle = handle->unix_handle; - if (StrLen_or_Ind) params.StrLen_or_Ind = handle->bind_col.param[i].len; - if (SUCCESS(( ret = ODBC_CALL( SQLBindCol, ¶ms )))) handle->bind_col.param[i].ptr = StrLen_or_Ind; TRACE ("Returning %d\n", ret); return ret; } @@ -615,16 +627,23 @@ SQLRETURN WINAPI SQLBindParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNu */ SQLRETURN WINAPI SQLCancel(SQLHSTMT StatementHandle) { - struct SQLCancel_params params; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p)\n", StatementHandle);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLCancel, ¶ms ); + if (handle->unix_handle) + { + struct SQLCancel_params params = { handle->unix_handle }; + ret = ODBC_CALL( SQLCancel, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLCancel( handle->win32_handle ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -634,16 +653,23 @@ SQLRETURN WINAPI SQLCancel(SQLHSTMT StatementHandle) */ SQLRETURN WINAPI SQLCloseCursor(SQLHSTMT StatementHandle) { - struct SQLCloseCursor_params params; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p)\n", StatementHandle);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLCloseCursor, ¶ms ); + if (handle->unix_handle) + { + struct SQLCloseCursor_params params = { handle->unix_handle }; + ret = ODBC_CALL( SQLCloseCursor, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLCloseCursor( handle->win32_handle ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -655,11 +681,8 @@ SQLRETURN WINAPI SQLColAttribute(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNu SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLLEN *NumericAttribute) { - struct SQLColAttribute_params params = { 0, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength, - StringLength }; struct handle *handle = StatementHandle; - INT64 num_attr = 0; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ColumnNumber %d, FieldIdentifier %d, CharacterAttribute %p, BufferLength %d," " StringLength %p, NumericAttribute %p)\n", StatementHandle, ColumnNumber, FieldIdentifier, @@ -667,9 +690,20 @@ SQLRETURN WINAPI SQLColAttribute(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNu
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.NumericAttribute = &num_attr; - if (SUCCESS(( ret = ODBC_CALL( SQLColAttribute, ¶ms ))) && NumericAttribute) *NumericAttribute = num_attr; + if (handle->unix_handle) + { + INT64 num_attr = 0; + struct SQLColAttribute_params params = { handle->unix_handle, ColumnNumber, FieldIdentifier, + CharacterAttribute, BufferLength, StringLength, &num_attr }; + if (SUCCESS(( ret = ODBC_CALL( SQLColAttribute, ¶ms ))) && NumericAttribute) + *NumericAttribute = num_attr; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLColAttribute( handle->win32_handle, ColumnNumber, FieldIdentifier, + CharacterAttribute, BufferLength, StringLength, NumericAttribute ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -681,10 +715,8 @@ SQLRETURN WINAPI SQLColumns(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLS SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLCHAR *ColumnName, SQLSMALLINT NameLength4) { - struct SQLColumns_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, TableName, - NameLength3, ColumnName, NameLength4 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," " NameLength3 %d, ColumnName %s, NameLength4 %d)\n", StatementHandle, @@ -695,8 +727,18 @@ SQLRETURN WINAPI SQLColumns(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLS
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLColumns, ¶ms ); + if (handle->unix_handle) + { + struct SQLColumns_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, NameLength2, + TableName, NameLength3, ColumnName, NameLength4 }; + ret = ODBC_CALL( SQLColumns, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLColumns( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, ColumnName, NameLength4 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -832,17 +874,23 @@ done: */ SQLRETURN WINAPI SQLCopyDesc(SQLHDESC SourceDescHandle, SQLHDESC TargetDescHandle) { - struct SQLCopyDesc_params params; struct handle *source = SourceDescHandle, *target = TargetDescHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(SourceDescHandle %p, TargetDescHandle %p)\n", SourceDescHandle, TargetDescHandle);
if (!source || !target) return SQL_INVALID_HANDLE;
- params.SourceDescHandle = source->unix_handle; - params.TargetDescHandle = target->unix_handle; - ret = ODBC_CALL( SQLCopyDesc, ¶ms ); + if (source->unix_handle) + { + struct SQLCopyDesc_params params = { source->unix_handle, target->unix_handle }; + ret = ODBC_CALL( SQLCopyDesc, ¶ms ); + } + else if (source->win32_handle) + { + ret = source->win32_funcs->SQLCopyDesc( source->win32_handle, target->win32_handle ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -938,12 +986,8 @@ SQLRETURN WINAPI SQLDescribeCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNum SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, SQLSMALLINT *DataType, SQLULEN *ColumnSize, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable) { - struct SQLDescribeCol_params params = { 0, ColumnNumber, ColumnName, BufferLength, NameLength, DataType, - NULL, DecimalDigits, Nullable }; struct handle *handle = StatementHandle; - UINT64 size; - SQLSMALLINT dummy; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ColumnNumber %d, ColumnName %p, BufferLength %d, NameLength %p, DataType %p," " ColumnSize %p, DecimalDigits %p, Nullable %p)\n", StatementHandle, ColumnNumber, ColumnName, @@ -951,20 +995,20 @@ SQLRETURN WINAPI SQLDescribeCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNum
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - if (!params.NameLength) params.NameLength = &dummy; /* workaround for drivers that don't accept NULL NameLength */ - params.ColumnSize = &size; - if (SUCCESS((ret = ODBC_CALL( SQLDescribeCol, ¶ms )))) + if (handle->unix_handle) { - if (ColumnName && NameLength) TRACE(" ColumnName %s\n", debugstr_an((const char *)ColumnName, *NameLength)); - if (DataType) TRACE(" DataType %d\n", *DataType); - if (ColumnSize) - { - *ColumnSize = size; - TRACE(" ColumnSize %s\n", debugstr_sqlulen(*ColumnSize)); - } - if (DecimalDigits) TRACE(" DecimalDigits %d\n", *DecimalDigits); - if (Nullable) TRACE(" Nullable %d\n", *Nullable); + UINT64 size; + SQLSMALLINT dummy; + struct SQLDescribeCol_params params = { handle->unix_handle, ColumnNumber, ColumnName, BufferLength, + NameLength, DataType, &size, DecimalDigits, Nullable }; + if (!params.NameLength) params.NameLength = &dummy; /* workaround for drivers that don't accept NULL NameLength */ + + if (SUCCESS((ret = ODBC_CALL( SQLDescribeCol, ¶ms ))) && ColumnSize) *ColumnSize = size; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLDescribeCol( handle->win32_handle, ColumnNumber, ColumnName, BufferLength, + NameLength, DataType, ColumnSize, DecimalDigits, Nullable ); }
TRACE("Returning %d\n", ret); @@ -976,16 +1020,23 @@ SQLRETURN WINAPI SQLDescribeCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNum */ SQLRETURN WINAPI SQLDisconnect(SQLHDBC ConnectionHandle) { - struct SQLDisconnect_params params; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p)\n", ConnectionHandle);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLDisconnect, ¶ms ); + if (handle->unix_handle) + { + struct SQLDisconnect_params params = { handle->unix_handle }; + ret = ODBC_CALL( SQLDisconnect, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLDisconnect( handle->win32_handle ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -995,16 +1046,23 @@ SQLRETURN WINAPI SQLDisconnect(SQLHDBC ConnectionHandle) */ SQLRETURN WINAPI SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType) { - struct SQLEndTran_params params = { HandleType, 0, CompletionType }; struct handle *handle = Handle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(HandleType %d, Handle %p, CompletionType %d)\n", HandleType, Handle, CompletionType);
if (!handle) return SQL_INVALID_HANDLE;
- params.Handle = handle->unix_handle; - ret = ODBC_CALL( SQLEndTran, ¶ms ); + if (handle->unix_handle) + { + struct SQLEndTran_params params = { HandleType, handle->unix_handle, CompletionType }; + ret = ODBC_CALL( SQLEndTran, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLEndTran( HandleType, handle->win32_handle, CompletionType ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1016,24 +1074,33 @@ SQLRETURN WINAPI SQLError(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, S SQLCHAR *SqlState, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength) { - struct SQLError_params params = { 0, 0, 0, SqlState, NativeError, MessageText, BufferLength, TextLength }; struct handle *env = EnvironmentHandle, *con = ConnectionHandle, *stmt = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(EnvironmentHandle %p, ConnectionHandle %p, StatementHandle %p, SqlState %p, NativeError %p," " MessageText %p, BufferLength %d, TextLength %p)\n", EnvironmentHandle, ConnectionHandle, StatementHandle, SqlState, NativeError, MessageText, BufferLength, TextLength);
- if (env) params.EnvironmentHandle = env->unix_handle; - if (con) params.ConnectionHandle = con->unix_handle; - if (stmt) params.StatementHandle = stmt->unix_handle; - if (SUCCESS((ret = ODBC_CALL( SQLError, ¶ms )))) + if ((env && env->unix_handle) || (con && con->unix_handle) || (stmt && stmt->unix_handle)) + { + struct SQLError_params params = { env ? env->unix_handle : 0, + con ? con->unix_handle : 0, + stmt ? stmt->unix_handle : 0, + SqlState, NativeError, MessageText, BufferLength, TextLength }; + ret = ODBC_CALL( SQLError, ¶ms ); + } + else if ((env && env->win32_handle) || (con && con->win32_handle) || (stmt && stmt->win32_handle)) + { + ret = env->win32_funcs->SQLError( env->win32_handle, con->win32_handle, stmt->win32_handle, SqlState, + NativeError, MessageText, BufferLength, TextLength ); + } + + if (SUCCESS( ret )) { TRACE(" SqlState %s\n", debugstr_an((const char *)SqlState, 5)); TRACE(" Error %d\n", *NativeError); TRACE(" MessageText %s\n", debugstr_an((const char *)MessageText, *TextLength)); } - TRACE("Returning %d\n", ret); return ret; } @@ -1043,17 +1110,24 @@ SQLRETURN WINAPI SQLError(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, S */ SQLRETURN WINAPI SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength) { - struct SQLExecDirect_params params = { 0, StatementText, TextLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, StatementText %s, TextLength %d)\n", StatementHandle, debugstr_an((const char *)StatementText, TextLength), TextLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLExecDirect, ¶ms ); + if (handle->unix_handle) + { + struct SQLExecDirect_params params = { handle->unix_handle, StatementText, TextLength }; + ret = ODBC_CALL( SQLExecDirect, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLExecDirect( handle->win32_handle, StatementText, TextLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1118,17 +1192,24 @@ static void update_result_lengths( struct handle *handle, USHORT type ) */ SQLRETURN WINAPI SQLExecute(SQLHSTMT StatementHandle) { - struct SQLExecute_params params; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p)\n", StatementHandle);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - update_result_lengths( handle, SQL_PARAM_INPUT ); - if (SUCCESS(( ret = ODBC_CALL( SQLExecute, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); + if (handle->unix_handle) + { + struct SQLExecute_params params = { handle->unix_handle }; + update_result_lengths( handle, SQL_PARAM_INPUT ); + if (SUCCESS(( ret = ODBC_CALL( SQLExecute, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLExecute( handle->win32_handle ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1138,16 +1219,23 @@ SQLRETURN WINAPI SQLExecute(SQLHSTMT StatementHandle) */ SQLRETURN WINAPI SQLFetch(SQLHSTMT StatementHandle) { - struct SQLFetch_params params; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p)\n", StatementHandle);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - if (SUCCESS(( ret = ODBC_CALL( SQLFetch, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); + if (handle->unix_handle) + { + struct SQLFetch_params params = { handle->unix_handle }; + if (SUCCESS(( ret = ODBC_CALL( SQLFetch, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLFetch( handle->win32_handle ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1157,17 +1245,24 @@ SQLRETURN WINAPI SQLFetch(SQLHSTMT StatementHandle) */ SQLRETURN WINAPI SQLFetchScroll(SQLHSTMT StatementHandle, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset) { - struct SQLFetchScroll_params params = { 0, FetchOrientation, FetchOffset }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, FetchOrientation %d, FetchOffset %s)\n", StatementHandle, FetchOrientation, debugstr_sqllen(FetchOffset));
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - if (SUCCESS(( ret = ODBC_CALL( SQLFetchScroll, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); + if (handle->unix_handle) + { + struct SQLFetchScroll_params params = { handle->unix_handle, FetchOrientation, FetchOffset }; + if (SUCCESS(( ret = ODBC_CALL( SQLFetchScroll, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLFetchScroll( handle->win32_handle, FetchOrientation, FetchOffset ); + } + TRACE("Returning %d\n", ret); return ret; }
From: Hans Leidekker hans@codeweavers.com
--- dlls/odbc32/proxyodbc.c | 991 +++++++++++++++++++++++++++++----------- 1 file changed, 736 insertions(+), 255 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index 028163412a9..f5fc73b86cb 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -1404,17 +1404,26 @@ SQLRETURN WINAPI SQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option) SQLRETURN WINAPI SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength) { - struct SQLGetConnectAttr_params params = { 0, Attribute, Value, BufferLength, StringLength }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n", ConnectionHandle, Attribute, Value, BufferLength, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetConnectAttr, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetConnectAttr_params params = { handle->unix_handle, Attribute, Value, BufferLength, + StringLength }; + ret = ODBC_CALL( SQLGetConnectAttr, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetConnectAttr( handle->win32_handle, Attribute, Value, BufferLength, + StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1424,16 +1433,23 @@ SQLRETURN WINAPI SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribut */ SQLRETURN WINAPI SQLGetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLPOINTER Value) { - struct SQLGetConnectOption_params params = { 0, Option, Value }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, Option %d, Value %p)\n", ConnectionHandle, Option, Value);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetConnectOption, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetConnectOption_params params = { handle->unix_handle, Option, Value }; + ret = ODBC_CALL( SQLGetConnectOption, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetConnectOption( handle->win32_handle, Option, Value ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1444,17 +1460,24 @@ SQLRETURN WINAPI SQLGetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Opti SQLRETURN WINAPI SQLGetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLSMALLINT BufferLength, SQLSMALLINT *NameLength) { - struct SQLGetCursorName_params params = { 0, CursorName, BufferLength, NameLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CursorName %p, BufferLength %d, NameLength %p)\n", StatementHandle, CursorName, BufferLength, NameLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetCursorName, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetCursorName_params params = { handle->unix_handle, CursorName, BufferLength, NameLength }; + ret = ODBC_CALL( SQLGetCursorName, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetCursorName( handle->win32_handle, CursorName, BufferLength, NameLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1465,19 +1488,27 @@ SQLRETURN WINAPI SQLGetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLRETURN WINAPI SQLGetData(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind) { - struct SQLGetData_params params = { 0, ColumnNumber, TargetType, TargetValue, BufferLength }; struct handle *handle = StatementHandle; - INT64 len; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ColumnNumber %d, TargetType %d, TargetValue %p, BufferLength %s, StrLen_or_Ind %p)\n", StatementHandle, ColumnNumber, TargetType, TargetValue, debugstr_sqllen(BufferLength), StrLen_or_Ind);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.StrLen_or_Ind = &len; - if (SUCCESS((ret = ODBC_CALL( SQLGetData, ¶ms )))) *StrLen_or_Ind = len; + if (handle->unix_handle) + { + INT64 len; + struct SQLGetData_params params = { handle->unix_handle, ColumnNumber, TargetType, TargetValue, + BufferLength, &len }; + if (SUCCESS((ret = ODBC_CALL( SQLGetData, ¶ms )))) *StrLen_or_Ind = len; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetData( handle->win32_handle, ColumnNumber, TargetType, TargetValue, + BufferLength, StrLen_or_Ind ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1488,17 +1519,26 @@ SQLRETURN WINAPI SQLGetData(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLRETURN WINAPI SQLGetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength) { - struct SQLGetDescField_params params = { 0, RecNumber, FieldIdentifier, Value, BufferLength, StringLength }; struct handle *handle = DescriptorHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(DescriptorHandle %p, RecNumber %d, FieldIdentifier %d, Value %p, BufferLength %d, StringLength %p)\n", DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.DescriptorHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetDescField, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetDescField_params params = { handle->unix_handle, RecNumber, FieldIdentifier, Value, + BufferLength, StringLength }; + ret = ODBC_CALL( SQLGetDescField, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetDescField( handle->win32_handle, RecNumber, FieldIdentifier, Value, + BufferLength, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1511,11 +1551,8 @@ SQLRETURN WINAPI SQLGetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT *SubType, SQLLEN *Length, SQLSMALLINT *Precision, SQLSMALLINT *Scale, SQLSMALLINT *Nullable) { - struct SQLGetDescRec_params params = { 0, RecNumber, Name, BufferLength, StringLength, Type, SubType, NULL, - Precision, Scale, Nullable }; struct handle *handle = DescriptorHandle; - INT64 len; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(DescriptorHandle %p, RecNumber %d, Name %p, BufferLength %d, StringLength %p, Type %p, SubType %p," " Length %p, Precision %p, Scale %p, Nullable %p)\n", DescriptorHandle, RecNumber, Name, BufferLength, @@ -1523,9 +1560,19 @@ SQLRETURN WINAPI SQLGetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber,
if (!handle) return SQL_INVALID_HANDLE;
- params.DescriptorHandle = handle->unix_handle; - params.Length = &len; - if (SUCCESS((ret = ODBC_CALL( SQLGetDescRec, ¶ms )))) *Length = len; + if (handle->unix_handle) + { + INT64 len; + struct SQLGetDescRec_params params = { handle->unix_handle, RecNumber, Name, BufferLength, StringLength, + Type, SubType, &len, Precision, Scale, Nullable }; + if (SUCCESS((ret = ODBC_CALL( SQLGetDescRec, ¶ms )))) *Length = len; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetDescRec( handle->win32_handle, RecNumber, Name, BufferLength, StringLength, + Type, SubType, Length, Precision, Scale, Nullable ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1537,18 +1584,26 @@ SQLRETURN WINAPI SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSM SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) { - struct SQLGetDiagField_params params = { HandleType, 0, RecNumber, DiagIdentifier, DiagInfo, BufferLength, - StringLength }; struct handle *handle = Handle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(HandleType %d, Handle %p, RecNumber %d, DiagIdentifier %d, DiagInfo %p, BufferLength %d," " StringLength %p)\n", HandleType, Handle, RecNumber, DiagIdentifier, DiagInfo, BufferLength, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.Handle = handle->unix_handle; - ret = ODBC_CALL( SQLGetDiagField, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetDiagField_params params = { HandleType, handle->unix_handle, RecNumber, DiagIdentifier, + DiagInfo, BufferLength, StringLength }; + ret = ODBC_CALL( SQLGetDiagField, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetDiagField( HandleType, handle->win32_handle, RecNumber, DiagIdentifier, + DiagInfo, BufferLength, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1560,10 +1615,8 @@ SQLRETURN WINAPI SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMAL SQLCHAR *SqlState, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength) { - struct SQLGetDiagRec_params params = { HandleType, 0, RecNumber, SqlState, NativeError, MessageText, - BufferLength, TextLength }; struct handle *handle = Handle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(HandleType %d, Handle %p, RecNumber %d, SqlState %p, NativeError %p, MessageText %p, BufferLength %d," " TextLength %p)\n", HandleType, Handle, RecNumber, SqlState, NativeError, MessageText, BufferLength, @@ -1571,8 +1624,18 @@ SQLRETURN WINAPI SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMAL
if (!handle) return SQL_INVALID_HANDLE;
- params.Handle = handle->unix_handle; - ret = ODBC_CALL( SQLGetDiagRec, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetDiagRec_params params = { HandleType, handle->unix_handle, RecNumber, SqlState, NativeError, + MessageText, BufferLength, TextLength }; + ret = ODBC_CALL( SQLGetDiagRec, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetDiagRec( HandleType, handle->win32_handle, RecNumber, SqlState, NativeError, + MessageText, BufferLength, TextLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1624,16 +1687,23 @@ SQLRETURN WINAPI SQLGetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, */ SQLRETURN WINAPI SQLGetFunctions(SQLHDBC ConnectionHandle, SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported) { - struct SQLGetFunctions_params params = { 0, FunctionId, Supported }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, FunctionId %d, Supported %p)\n", ConnectionHandle, FunctionId, Supported);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetFunctions, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetFunctions_params params = { handle->unix_handle, FunctionId, Supported }; + ret = ODBC_CALL( SQLGetFunctions, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetFunctions( handle->win32_handle, FunctionId, Supported ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1644,17 +1714,24 @@ SQLRETURN WINAPI SQLGetFunctions(SQLHDBC ConnectionHandle, SQLUSMALLINT Function SQLRETURN WINAPI SQLGetInfo(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) { - struct SQLGetInfo_params params = { 0, InfoType, InfoValue, BufferLength, StringLength }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle, %p, InfoType %d, InfoValue %p, BufferLength %d, StringLength %p)\n", ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetInfo, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetInfo_params params = { handle->unix_handle, InfoType, InfoValue, BufferLength, StringLength }; + ret = ODBC_CALL( SQLGetInfo, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetInfo( handle->win32_handle, InfoType, InfoValue, BufferLength, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1665,9 +1742,8 @@ SQLRETURN WINAPI SQLGetInfo(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQL SQLRETURN WINAPI SQLGetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength) { - struct SQLGetStmtAttr_params params = { 0, Attribute, Value, BufferLength, StringLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n", StatementHandle, Attribute, Value, BufferLength, StringLength); @@ -1680,8 +1756,16 @@ SQLRETURN WINAPI SQLGetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute,
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetStmtAttr, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetStmtAttr_params params = { handle->unix_handle, Attribute, Value, BufferLength, StringLength }; + ret = ODBC_CALL( SQLGetStmtAttr, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetStmtAttr( handle->win32_handle, Attribute, Value, BufferLength, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1691,16 +1775,23 @@ SQLRETURN WINAPI SQLGetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, */ SQLRETURN WINAPI SQLGetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLPOINTER Value) { - struct SQLGetStmtOption_params params = { 0, Option, Value }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Option %d, Value %p)\n", StatementHandle, Option, Value);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetStmtOption, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetStmtOption_params params = { handle->unix_handle, Option, Value }; + ret = ODBC_CALL( SQLGetStmtOption, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetStmtOption( handle->win32_handle, Option, Value ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1710,16 +1801,23 @@ SQLRETURN WINAPI SQLGetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, */ SQLRETURN WINAPI SQLGetTypeInfo(SQLHSTMT StatementHandle, SQLSMALLINT DataType) { - struct SQLGetTypeInfo_params params = { 0, DataType }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, DataType %d)\n", StatementHandle, DataType);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetTypeInfo, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetTypeInfo_params params = { handle->unix_handle, DataType }; + ret = ODBC_CALL( SQLGetTypeInfo, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetTypeInfo( handle->win32_handle, DataType ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1729,16 +1827,23 @@ SQLRETURN WINAPI SQLGetTypeInfo(SQLHSTMT StatementHandle, SQLSMALLINT DataType) */ SQLRETURN WINAPI SQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount) { - struct SQLNumResultCols_params params = { 0, ColumnCount }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ColumnCount %p)\n", StatementHandle, ColumnCount);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLNumResultCols, ¶ms ); + if (handle->unix_handle) + { + struct SQLNumResultCols_params params = { handle->unix_handle, ColumnCount }; + ret = ODBC_CALL( SQLNumResultCols, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLNumResultCols( handle->win32_handle, ColumnCount ); + } + TRACE("Returning %d ColumnCount %d\n", ret, *ColumnCount); return ret; } @@ -1748,16 +1853,23 @@ SQLRETURN WINAPI SQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT *ColumnC */ SQLRETURN WINAPI SQLParamData(SQLHSTMT StatementHandle, SQLPOINTER *Value) { - struct SQLParamData_params params = { 0, Value }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Value %p)\n", StatementHandle, Value);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLParamData, ¶ms ); + if (handle->unix_handle) + { + struct SQLParamData_params params = { handle->unix_handle, Value }; + ret = ODBC_CALL( SQLParamData, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLParamData( handle->win32_handle, Value ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1767,17 +1879,24 @@ SQLRETURN WINAPI SQLParamData(SQLHSTMT StatementHandle, SQLPOINTER *Value) */ SQLRETURN WINAPI SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength) { - struct SQLPrepare_params params = { 0, StatementText, TextLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, StatementText %s, TextLength %d)\n", StatementHandle, debugstr_an((const char *)StatementText, TextLength), TextLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLPrepare, ¶ms ); + if (handle->unix_handle) + { + struct SQLPrepare_params params = { handle->unix_handle, StatementText, TextLength }; + ret = ODBC_CALL( SQLPrepare, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLPrepare( handle->win32_handle, StatementText, TextLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1787,16 +1906,23 @@ SQLRETURN WINAPI SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQ */ SQLRETURN WINAPI SQLPutData(SQLHSTMT StatementHandle, SQLPOINTER Data, SQLLEN StrLen_or_Ind) { - struct SQLPutData_params params = { 0, Data, StrLen_or_Ind }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Data %p, StrLen_or_Ind %s)\n", StatementHandle, Data, debugstr_sqllen(StrLen_or_Ind));
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLPutData, ¶ms ); + if (handle->unix_handle) + { + struct SQLPutData_params params = { handle->unix_handle, Data, StrLen_or_Ind }; + ret = ODBC_CALL( SQLPutData, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLPutData( handle->win32_handle, Data, StrLen_or_Ind ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1806,22 +1932,28 @@ SQLRETURN WINAPI SQLPutData(SQLHSTMT StatementHandle, SQLPOINTER Data, SQLLEN St */ SQLRETURN WINAPI SQLRowCount(SQLHSTMT StatementHandle, SQLLEN *RowCount) { - struct SQLRowCount_params params; struct handle *handle = StatementHandle; - INT64 count; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, RowCount %p)\n", StatementHandle, RowCount);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.RowCount = &count; - if (SUCCESS((ret = ODBC_CALL( SQLRowCount, ¶ms ))) && RowCount) + if (handle->unix_handle) + { + INT64 count; + struct SQLRowCount_params params = { handle->unix_handle, &count }; + if (SUCCESS((ret = ODBC_CALL( SQLRowCount, ¶ms ))) && RowCount) + { + *RowCount = count; + TRACE(" RowCount %s\n", debugstr_sqllen(*RowCount)); + } + } + else if (handle->win32_handle) { - *RowCount = count; - TRACE(" RowCount %s\n", debugstr_sqllen(*RowCount)); + ret = handle->win32_funcs->SQLRowCount( handle->win32_handle, RowCount ); } + TRACE("Returning %d\n", ret); return ret; } @@ -1832,17 +1964,24 @@ SQLRETURN WINAPI SQLRowCount(SQLHSTMT StatementHandle, SQLLEN *RowCount) SQLRETURN WINAPI SQLSetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength) { - struct SQLSetConnectAttr_params params = { 0, Attribute, Value, StringLength }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, Attribute %d, Value %p, StringLength %d)\n", ConnectionHandle, Attribute, Value, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetConnectAttr, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetConnectAttr_params params = { handle->unix_handle, Attribute, Value, StringLength }; + ret = ODBC_CALL( SQLSetConnectAttr, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetConnectAttr( handle->win32_handle, Attribute, Value, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1852,16 +1991,23 @@ SQLRETURN WINAPI SQLSetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribut */ SQLRETURN WINAPI SQLSetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLULEN Value) { - struct SQLSetConnectOption_params params = { 0, Option, Value }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, Option %d, Value %s)\n", ConnectionHandle, Option, debugstr_sqlulen(Value));
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetConnectOption, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetConnectOption_params params = { handle->unix_handle, Option, Value }; + ret = ODBC_CALL( SQLSetConnectOption, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetConnectOption( handle->win32_handle, Option, Value ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1871,17 +2017,24 @@ SQLRETURN WINAPI SQLSetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Opti */ SQLRETURN WINAPI SQLSetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLSMALLINT NameLength) { - struct SQLSetCursorName_params params = { 0, CursorName, NameLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CursorName %s, NameLength %d)\n", StatementHandle, debugstr_an((const char *)CursorName, NameLength), NameLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetCursorName, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetCursorName_params params = { handle->unix_handle, CursorName, NameLength }; + ret = ODBC_CALL( SQLSetCursorName, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetCursorName( handle->win32_handle, CursorName, NameLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1892,17 +2045,26 @@ SQLRETURN WINAPI SQLSetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLRETURN WINAPI SQLSetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength) { - struct SQLSetDescField_params params = { 0, RecNumber, FieldIdentifier, Value, BufferLength }; struct handle *handle = DescriptorHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(DescriptorHandle %p, RecNumber %d, FieldIdentifier %d, Value %p, BufferLength %d)\n", DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.DescriptorHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetDescField, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetDescField_params params = { handle->unix_handle, RecNumber, FieldIdentifier, Value, + BufferLength }; + ret = ODBC_CALL( SQLSetDescField, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetDescField( handle->win32_handle, RecNumber, FieldIdentifier, Value, + BufferLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1914,10 +2076,8 @@ SQLRETURN WINAPI SQLSetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT SubType, SQLLEN Length, SQLSMALLINT Precision, SQLSMALLINT Scale, SQLPOINTER Data, SQLLEN *StringLength, SQLLEN *Indicator) { - struct SQLSetDescRec_params params = { 0, RecNumber, Type, SubType, Length, Precision, Scale, Data }; struct handle *handle = DescriptorHandle; - INT64 stringlen, indicator; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(DescriptorHandle %p, RecNumber %d, Type %d, SubType %d, Length %s, Precision %d, Scale %d, Data %p," " StringLength %p, Indicator %p)\n", DescriptorHandle, RecNumber, Type, SubType, debugstr_sqllen(Length), @@ -1925,14 +2085,23 @@ SQLRETURN WINAPI SQLSetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber,
if (!handle) return SQL_INVALID_HANDLE;
- params.DescriptorHandle = handle->unix_handle; - params.StringLength = &stringlen; - params.Indicator = &indicator; - if (SUCCESS((ret = ODBC_CALL( SQLSetDescRec, ¶ms )))) + if (handle->unix_handle) + { + INT64 stringlen, indicator; + struct SQLSetDescRec_params params = { handle->unix_handle, RecNumber, Type, SubType, Length, Precision, + Scale, Data, &stringlen, &indicator }; + if (SUCCESS((ret = ODBC_CALL( SQLSetDescRec, ¶ms )))) + { + *StringLength = stringlen; + *Indicator = indicator; + } + } + else if (handle->win32_handle) { - *StringLength = stringlen; - *Indicator = indicator; + ret = handle->win32_funcs->SQLSetDescRec( handle->win32_handle, RecNumber, Type, SubType, Length, Precision, + Scale, Data, StringLength, Indicator ); } + TRACE("Returning %d\n", ret); return ret; } @@ -1943,15 +2112,22 @@ SQLRETURN WINAPI SQLSetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLRETURN WINAPI SQLSetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength) { - struct SQLSetEnvAttr_params params = { 0, Attribute, Value, StringLength }; struct handle *handle = EnvironmentHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(EnvironmentHandle %p, Attribute %d, Value %p, StringLength %d)\n", EnvironmentHandle, Attribute, Value, StringLength);
- params.EnvironmentHandle = handle ? handle->unix_handle : 0; - ret = ODBC_CALL( SQLSetEnvAttr, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetEnvAttr_params params = { handle->unix_handle, Attribute, Value, StringLength }; + ret = ODBC_CALL( SQLSetEnvAttr, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetEnvAttr( handle->win32_handle, Attribute, Value, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -1963,11 +2139,8 @@ SQLRETURN WINAPI SQLSetParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNum SQLSMALLINT ParameterType, SQLULEN LengthPrecision, SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue, SQLLEN *StrLen_or_Ind) { - struct SQLSetParam_params params = { 0, ParameterNumber, ValueType, ParameterType, LengthPrecision, ParameterScale, - ParameterValue }; struct handle *handle = StatementHandle; - INT64 len; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ParameterNumber %d, ValueType %d, ParameterType %d, LengthPrecision %s," " ParameterScale %d, ParameterValue %p, StrLen_or_Ind %p)\n", StatementHandle, ParameterNumber, ValueType, @@ -1975,9 +2148,19 @@ SQLRETURN WINAPI SQLSetParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNum
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.StrLen_or_Ind = &len; - if (SUCCESS((ret = ODBC_CALL( SQLSetParam, ¶ms )))) *StrLen_or_Ind = len; + if (handle->unix_handle) + { + INT64 len; + struct SQLSetParam_params params = { handle->unix_handle, ParameterNumber, ValueType, ParameterType, + LengthPrecision, ParameterScale, ParameterValue, &len }; + if (SUCCESS((ret = ODBC_CALL( SQLSetParam, ¶ms )))) *StrLen_or_Ind = len; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetParam( handle->win32_handle, ParameterNumber, ValueType, ParameterType, + LengthPrecision, ParameterScale, ParameterValue, StrLen_or_Ind ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2043,26 +2226,33 @@ static BOOL resize_result_lengths( struct handle *handle, UINT size ) SQLRETURN WINAPI SQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength) { - struct SQLSetStmtAttr_params params = { 0, Attribute, Value, StringLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Attribute %d, Value %p, StringLength %d)\n", StatementHandle, Attribute, Value, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - if (SUCCESS((ret = ODBC_CALL( SQLSetStmtAttr, ¶ms )))) + if (handle->unix_handle) { - SQLULEN row_count = (SQLULEN)Value; - if (Attribute == SQL_ATTR_ROW_ARRAY_SIZE && row_count != handle->row_count) + struct SQLSetStmtAttr_params params = { handle->unix_handle, Attribute, Value, StringLength }; + if (SUCCESS((ret = ODBC_CALL( SQLSetStmtAttr, ¶ms )))) { - TRACE( "resizing result length array\n" ); - if (!resize_result_lengths( handle, row_count )) ret = SQL_ERROR; - else handle->row_count = row_count; + SQLULEN row_count = (SQLULEN)Value; + if (Attribute == SQL_ATTR_ROW_ARRAY_SIZE && row_count != handle->row_count) + { + TRACE( "resizing result length array\n" ); + if (!resize_result_lengths( handle, row_count )) ret = SQL_ERROR; + else handle->row_count = row_count; + } } } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetStmtAttr( handle->win32_handle, Attribute, Value, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2072,16 +2262,23 @@ SQLRETURN WINAPI SQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, */ SQLRETURN WINAPI SQLSetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLULEN Value) { - struct SQLSetStmtOption_params params = { 0, Option, Value }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Option %d, Value %s)\n", StatementHandle, Option, debugstr_sqlulen(Value));
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetStmtOption, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetStmtOption_params params = { handle->unix_handle, Option, Value }; + ret = ODBC_CALL( SQLSetStmtOption, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetStmtOption( handle->win32_handle, Option, Value ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2094,10 +2291,8 @@ SQLRETURN WINAPI SQLSpecialColumns(SQLHSTMT StatementHandle, SQLUSMALLINT Identi SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Scope, SQLUSMALLINT Nullable) { - struct SQLSpecialColumns_params params = { 0, IdentifierType, CatalogName, NameLength1, SchemaName, NameLength2, - TableName, NameLength3, Scope, Nullable }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, IdentifierType %d, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d," " TableName %s, NameLength3 %d, Scope %d, Nullable %d)\n", StatementHandle, IdentifierType, @@ -2107,8 +2302,18 @@ SQLRETURN WINAPI SQLSpecialColumns(SQLHSTMT StatementHandle, SQLUSMALLINT Identi
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSpecialColumns, ¶ms ); + if (handle->unix_handle) + { + struct SQLSpecialColumns_params params = { handle->unix_handle, IdentifierType, CatalogName, NameLength1, + SchemaName, NameLength2, TableName, NameLength3, Scope, Nullable }; + ret = ODBC_CALL( SQLSpecialColumns, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSpecialColumns( handle->win32_handle, IdentifierType, CatalogName, NameLength1, + SchemaName, NameLength2, TableName, NameLength3, Scope, Nullable ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2120,10 +2325,8 @@ SQLRETURN WINAPI SQLStatistics(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, S SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Unique, SQLUSMALLINT Reserved) { - struct SQLStatistics_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, TableName, - NameLength3, Unique, Reserved }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d SchemaName %s, NameLength2 %d, TableName %s" " NameLength3 %d, Unique %d, Reserved %d)\n", StatementHandle, @@ -2133,8 +2336,18 @@ SQLRETURN WINAPI SQLStatistics(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, S
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLStatistics, ¶ms ); + if (handle->unix_handle) + { + struct SQLStatistics_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, Unique, Reserved }; + ret = ODBC_CALL( SQLStatistics, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLStatistics( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, Unique, Reserved ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2146,10 +2359,8 @@ SQLRETURN WINAPI SQLTables(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLSM SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLCHAR *TableType, SQLSMALLINT NameLength4) { - struct SQLTables_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, TableName, - NameLength3, TableType, NameLength4 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," " NameLength3 %d, TableType %s, NameLength4 %d)\n", StatementHandle, @@ -2160,8 +2371,18 @@ SQLRETURN WINAPI SQLTables(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLSM
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLTables, ¶ms ); + if (handle->unix_handle) + { + struct SQLTables_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, NameLength2, + TableName, NameLength3, TableType, NameLength4 }; + ret = ODBC_CALL( SQLTables, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLTables( handle->win32_handle, CatalogName, NameLength1, SchemaName, NameLength2, + TableName, NameLength3, TableType, NameLength4 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2171,32 +2392,63 @@ SQLRETURN WINAPI SQLTables(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLSM */ SQLRETURN WINAPI SQLTransact(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, SQLUSMALLINT CompletionType) { - struct SQLTransact_params params = { 0, 0, CompletionType }; struct handle *env = EnvironmentHandle, *con = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(EnvironmentHandle %p, ConnectionHandle %p, CompletionType %d)\n", EnvironmentHandle, ConnectionHandle, CompletionType);
if (!env || !con) return SQL_INVALID_HANDLE;
- params.EnvironmentHandle = env->unix_handle; - params.ConnectionHandle = con->unix_handle; - ret = ODBC_CALL( SQLTransact, ¶ms ); + if (env->unix_handle) + { + struct SQLTransact_params params = { env->unix_handle, con->unix_handle, CompletionType }; + ret = ODBC_CALL( SQLTransact, ¶ms ); + } + else if (env->win32_handle) + { + ret = env->win32_funcs->SQLTransact( env->win32_handle, con->win32_handle, CompletionType ); + } + TRACE("Returning %d\n", ret); return ret; }
+static WCHAR *get_datasource( const WCHAR *connection_string ) +{ + const WCHAR *p = connection_string, *q; + WCHAR *ret = NULL; + unsigned int len; + + if (!p) return NULL; + while (*p) + { + if (!wcsnicmp( p, L"DSN=", 4 )) + { + p += 4; + q = wcschr( p, ';' ); + len = q ? (q - p) : wcslen( p ); + if ((ret = malloc( (len + 1) * sizeof(WCHAR) ))) + { + memcpy( ret, p, len * sizeof(WCHAR) ); + ret[len] = 0; + break; + } + } + p++; + } + return ret; +} + /************************************************************************* * SQLBrowseConnect [ODBC32.055] */ SQLRETURN WINAPI SQLBrowseConnect(SQLHDBC ConnectionHandle, SQLCHAR *InConnectionString, SQLSMALLINT StringLength1, SQLCHAR *OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength2) { - struct SQLBrowseConnect_params params = { 0, InConnectionString, StringLength1, OutConnectionString, BufferLength, - StringLength2 }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + WCHAR *datasource = NULL, *filename = NULL, *connection_string = strdupAW( (const char *)InConnectionString ); + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, InConnectionString %s, StringLength1 %d, OutConnectionString %p, BufferLength, %d, " "StringLength2 %p)\n", ConnectionHandle, debugstr_an((const char *)InConnectionString, StringLength1), @@ -2204,8 +2456,58 @@ SQLRETURN WINAPI SQLBrowseConnect(SQLHDBC ConnectionHandle, SQLCHAR *InConnectio
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLBrowseConnect, ¶ms ); + /* FIXME: try DRIVER attribute if DSN is absent */ + if (!connection_string || !(datasource = get_datasource( connection_string ))) + { + WARN( "can't find data source\n" ); + goto done; + } + if (!(filename = get_driver_filename( datasource ))) + { + WARN( "can't find driver filename\n" ); + goto done; + } + + if (has_suffix( filename, L".dll" )) + { + if (!(handle->win32_funcs = load_driver( filename ))) + { + WARN( "failed to load driver %s\n", debugstr_w(filename) ); + goto done; + } + TRACE( "using Windows driver %s\n", debugstr_w(filename) ); + + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_ENV, NULL, + &handle->parent->win32_handle )))) goto done; + + handle->parent->win32_funcs = handle->win32_funcs; + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_DBC, handle->parent->win32_handle, + &handle->win32_handle )))) goto done; + + ret = handle->win32_funcs->SQLBrowseConnect( handle->win32_handle, InConnectionString, StringLength1, + OutConnectionString, BufferLength, StringLength2 ); + } + else + { + struct SQLAllocEnv_params params_alloc_env = { &handle->parent->unix_handle }; + struct SQLAllocConnect_params params_alloc_connect = { 0, &handle->unix_handle }; + struct SQLBrowseConnect_params params = { 0, InConnectionString, StringLength1, OutConnectionString, + BufferLength, StringLength2 }; + + TRACE( "using Unix driver %s\n", debugstr_w(filename) ); + if (!SUCCESS((ret = ODBC_CALL( SQLAllocEnv, ¶ms_alloc_env )))) goto done; + + params_alloc_connect.EnvironmentHandle = handle->parent->unix_handle; + if (!SUCCESS((ret = ODBC_CALL( SQLAllocConnect, ¶ms_alloc_connect )))) goto done; + + params.ConnectionHandle = handle->unix_handle; + ret = ODBC_CALL( SQLBrowseConnect, ¶ms ); + } + +done: + free( connection_string ); + free( filename ); + free( datasource ); TRACE("Returning %d\n", ret); return ret; } @@ -2215,16 +2517,23 @@ SQLRETURN WINAPI SQLBrowseConnect(SQLHDBC ConnectionHandle, SQLCHAR *InConnectio */ SQLRETURN WINAPI SQLBulkOperations(SQLHSTMT StatementHandle, SQLSMALLINT Operation) { - struct SQLBulkOperations_params params = { 0, Operation }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Operation %d)\n", StatementHandle, Operation);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - if (SUCCESS(( ret = ODBC_CALL( SQLBulkOperations, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); + if (handle->unix_handle) + { + struct SQLBulkOperations_params params = { handle->unix_handle, Operation }; + if (SUCCESS(( ret = ODBC_CALL( SQLBulkOperations, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLBulkOperations( handle->win32_handle, Operation ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2236,11 +2545,8 @@ SQLRETURN WINAPI SQLColAttributes(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnN SQLPOINTER CharacterAttributes, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLLEN *NumericAttributes) { - struct SQLColAttributes_params params = { 0, ColumnNumber, FieldIdentifier, CharacterAttributes, BufferLength, - StringLength }; struct handle *handle = StatementHandle; - INT64 attrs; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ColumnNumber %d, FieldIdentifier %d, CharacterAttributes %p, BufferLength %d, " "StringLength %p, NumericAttributes %p)\n", StatementHandle, ColumnNumber, FieldIdentifier, @@ -2248,9 +2554,20 @@ SQLRETURN WINAPI SQLColAttributes(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnN
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.NumericAttributes = &attrs; - if (SUCCESS((ret = ODBC_CALL( SQLColAttributes, ¶ms )))) *NumericAttributes = attrs; + if (handle->unix_handle) + { + INT64 attrs; + struct SQLColAttributes_params params = { handle->unix_handle, ColumnNumber, FieldIdentifier, + CharacterAttributes, BufferLength, StringLength, &attrs }; + if (SUCCESS((ret = ODBC_CALL( SQLColAttributes, ¶ms )))) *NumericAttributes = attrs; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLColAttributes( handle->win32_handle, ColumnNumber, FieldIdentifier, + CharacterAttributes, BufferLength, StringLength, + NumericAttributes ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2262,10 +2579,8 @@ SQLRETURN WINAPI SQLColumnPrivileges(SQLHSTMT StatementHandle, SQLCHAR *CatalogN SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLCHAR *ColumnName, SQLSMALLINT NameLength4) { - struct SQLColumnPrivileges_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, - TableName, NameLength3, ColumnName, NameLength4 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," " NameLength3 %d, ColumnName %s, NameLength4 %d)\n", StatementHandle, @@ -2276,8 +2591,18 @@ SQLRETURN WINAPI SQLColumnPrivileges(SQLHSTMT StatementHandle, SQLCHAR *CatalogN
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLColumnPrivileges, ¶ms ); + if (handle->unix_handle) + { + struct SQLColumnPrivileges_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, ColumnName, NameLength4 }; + ret = ODBC_CALL( SQLColumnPrivileges, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLColumnPrivileges( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, ColumnName, NameLength4 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2288,19 +2613,27 @@ SQLRETURN WINAPI SQLColumnPrivileges(SQLHSTMT StatementHandle, SQLCHAR *CatalogN SQLRETURN WINAPI SQLDescribeParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNumber, SQLSMALLINT *DataType, SQLULEN *ParameterSize, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable) { - struct SQLDescribeParam_params params = { 0, ParameterNumber, DataType, NULL, DecimalDigits, Nullable }; struct handle *handle = StatementHandle; - UINT64 size; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ParameterNumber %d, DataType %p, ParameterSize %p, DecimalDigits %p, Nullable %p)\n", StatementHandle, ParameterNumber, DataType, ParameterSize, DecimalDigits, Nullable);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.ParameterSize = &size; - if (SUCCESS((ret = ODBC_CALL( SQLDescribeParam, ¶ms )))) *ParameterSize = size; + if (handle->unix_handle) + { + UINT64 size; + struct SQLDescribeParam_params params = { handle->unix_handle, ParameterNumber, DataType, &size, + DecimalDigits, Nullable }; + if (SUCCESS((ret = ODBC_CALL( SQLDescribeParam, ¶ms )))) *ParameterSize = size; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLDescribeParam( handle->win32_handle, ParameterNumber, DataType, ParameterSize, + DecimalDigits, Nullable ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2311,19 +2644,27 @@ SQLRETURN WINAPI SQLDescribeParam(SQLHSTMT StatementHandle, SQLUSMALLINT Paramet SQLRETURN WINAPI SQLExtendedFetch(SQLHSTMT StatementHandle, SQLUSMALLINT FetchOrientation, SQLLEN FetchOffset, SQLULEN *RowCount, SQLUSMALLINT *RowStatusArray) { - struct SQLExtendedFetch_params params = { 0, FetchOrientation, FetchOffset, NULL, RowStatusArray }; struct handle *handle = StatementHandle; - UINT64 count; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, FetchOrientation %d, FetchOffset %s, RowCount %p, RowStatusArray %p)\n", StatementHandle, FetchOrientation, debugstr_sqllen(FetchOffset), RowCount, RowStatusArray);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.RowCount = &count; - if (SUCCESS((ret = ODBC_CALL( SQLExtendedFetch, ¶ms )))) *RowCount = count; + if (handle->unix_handle) + { + UINT64 count; + struct SQLExtendedFetch_params params = { handle->unix_handle, FetchOrientation, FetchOffset, &count, + RowStatusArray }; + if (SUCCESS((ret = ODBC_CALL( SQLExtendedFetch, ¶ms )))) *RowCount = count; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLExtendedFetch( handle->win32_handle, FetchOrientation, FetchOffset, RowCount, + RowStatusArray ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2337,11 +2678,8 @@ SQLRETURN WINAPI SQLForeignKeys(SQLHSTMT StatementHandle, SQLCHAR *PkCatalogName SQLCHAR *FkSchemaName, SQLSMALLINT NameLength5, SQLCHAR *FkTableName, SQLSMALLINT NameLength6) { - struct SQLForeignKeys_params params = { 0, PkCatalogName, NameLength1, PkSchemaName, NameLength2, - PkTableName, NameLength3, FkCatalogName, NameLength4, - FkSchemaName, NameLength5, FkTableName, NameLength6 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, PkCatalogName %s, NameLength1 %d, PkSchemaName %s, NameLength2 %d," " PkTableName %s, NameLength3 %d, FkCatalogName %s, NameLength4 %d, FkSchemaName %s," @@ -2355,8 +2693,20 @@ SQLRETURN WINAPI SQLForeignKeys(SQLHSTMT StatementHandle, SQLCHAR *PkCatalogName
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLForeignKeys, ¶ms ); + if (handle->unix_handle) + { + struct SQLForeignKeys_params params = { handle->unix_handle, PkCatalogName, NameLength1, PkSchemaName, + NameLength2, PkTableName, NameLength3, FkCatalogName, NameLength4, + FkSchemaName, NameLength5, FkTableName, NameLength6 }; + ret = ODBC_CALL( SQLForeignKeys, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLForeignKeys( handle->win32_handle, PkCatalogName, NameLength1, PkSchemaName, + NameLength2, PkTableName, NameLength3, FkCatalogName, NameLength4, + FkSchemaName, NameLength5, FkTableName, NameLength6 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2366,16 +2716,23 @@ SQLRETURN WINAPI SQLForeignKeys(SQLHSTMT StatementHandle, SQLCHAR *PkCatalogName */ SQLRETURN WINAPI SQLMoreResults(SQLHSTMT StatementHandle) { - struct SQLMoreResults_params params; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(%p)\n", StatementHandle);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLMoreResults, ¶ms ); + if (handle->unix_handle) + { + struct SQLMoreResults_params params = { handle->unix_handle }; + ret = ODBC_CALL( SQLMoreResults, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLMoreResults( handle->win32_handle ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2386,10 +2743,8 @@ SQLRETURN WINAPI SQLMoreResults(SQLHSTMT StatementHandle) SQLRETURN WINAPI SQLNativeSql(SQLHDBC ConnectionHandle, SQLCHAR *InStatementText, SQLINTEGER TextLength1, SQLCHAR *OutStatementText, SQLINTEGER BufferLength, SQLINTEGER *TextLength2) { - struct SQLNativeSql_params params = { 0, InStatementText, TextLength1, OutStatementText, BufferLength, - TextLength2 }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, InStatementText %s, TextLength1 %d, OutStatementText %p, BufferLength, %d, " "TextLength2 %p)\n", ConnectionHandle, debugstr_an((const char *)InStatementText, TextLength1), @@ -2397,8 +2752,18 @@ SQLRETURN WINAPI SQLNativeSql(SQLHDBC ConnectionHandle, SQLCHAR *InStatementText
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLNativeSql, ¶ms ); + if (handle->unix_handle) + { + struct SQLNativeSql_params params = { handle->unix_handle, InStatementText, TextLength1, OutStatementText, + BufferLength, TextLength2 }; + ret = ODBC_CALL( SQLNativeSql, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLNativeSql( handle->win32_handle, InStatementText, TextLength1, OutStatementText, + BufferLength, TextLength2 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2408,16 +2773,23 @@ SQLRETURN WINAPI SQLNativeSql(SQLHDBC ConnectionHandle, SQLCHAR *InStatementText */ SQLRETURN WINAPI SQLNumParams(SQLHSTMT StatementHandle, SQLSMALLINT *ParameterCount) { - struct SQLNumParams_params params = { 0, ParameterCount }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, pcpar %p)\n", StatementHandle, ParameterCount);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLNumParams, ¶ms ); + if (handle->unix_handle) + { + struct SQLNumParams_params params = { handle->unix_handle, ParameterCount }; + ret = ODBC_CALL( SQLNumParams, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLNumParams( handle->win32_handle, ParameterCount ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2427,19 +2799,25 @@ SQLRETURN WINAPI SQLNumParams(SQLHSTMT StatementHandle, SQLSMALLINT *ParameterCo */ SQLRETURN WINAPI SQLParamOptions(SQLHSTMT StatementHandle, SQLULEN RowCount, SQLULEN *RowNumber) { - struct SQLParamOptions_params params = { 0, RowCount }; struct handle *handle = StatementHandle; - UINT64 row; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, RowCount %s, RowNumber %p)\n", StatementHandle, debugstr_sqlulen(RowCount), RowNumber);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.RowNumber = &row; - if (SUCCESS((ret = ODBC_CALL( SQLParamOptions, ¶ms )))) *RowNumber = row; + if (handle->unix_handle) + { + UINT64 row; + struct SQLParamOptions_params params = { handle->unix_handle, RowCount, &row }; + if (SUCCESS((ret = ODBC_CALL( SQLParamOptions, ¶ms )))) *RowNumber = row; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLParamOptions( handle->win32_handle, RowCount, RowNumber ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2451,10 +2829,8 @@ SQLRETURN WINAPI SQLPrimaryKeys(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3) { - struct SQLPrimaryKeys_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, TableName, - NameLength3 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," " NameLength3 %d)\n", StatementHandle, @@ -2464,8 +2840,18 @@ SQLRETURN WINAPI SQLPrimaryKeys(SQLHSTMT StatementHandle, SQLCHAR *CatalogName,
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLPrimaryKeys, ¶ms ); + if (handle->unix_handle) + { + struct SQLPrimaryKeys_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3 }; + ret = ODBC_CALL( SQLPrimaryKeys, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLPrimaryKeys( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2477,10 +2863,8 @@ SQLRETURN WINAPI SQLProcedureColumns(SQLHSTMT StatementHandle, SQLCHAR *CatalogN SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *ProcName, SQLSMALLINT NameLength3, SQLCHAR *ColumnName, SQLSMALLINT NameLength4) { - struct SQLProcedureColumns_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, - ProcName, NameLength3, ColumnName, NameLength4 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, ProcName %s," " NameLength3 %d, ColumnName %s, NameLength4 %d)\n", StatementHandle, @@ -2491,8 +2875,18 @@ SQLRETURN WINAPI SQLProcedureColumns(SQLHSTMT StatementHandle, SQLCHAR *CatalogN
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLProcedureColumns, ¶ms ); + if (handle->unix_handle) + { + struct SQLProcedureColumns_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, ProcName, NameLength3, ColumnName, NameLength4 }; + ret = ODBC_CALL( SQLProcedureColumns, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLProcedureColumns( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, ProcName, NameLength3, ColumnName, NameLength4 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2504,10 +2898,8 @@ SQLRETURN WINAPI SQLProcedures(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, S SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *ProcName, SQLSMALLINT NameLength3) { - struct SQLProcedures_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, ProcName, - NameLength3 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, ProcName %s," " NameLength3 %d)\n", StatementHandle, @@ -2517,8 +2909,18 @@ SQLRETURN WINAPI SQLProcedures(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, S
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLProcedures, ¶ms ); + if (handle->unix_handle) + { + struct SQLProcedures_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, ProcName, NameLength3 }; + ret = ODBC_CALL( SQLProcedures, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLProcedures( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, ProcName, NameLength3 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2529,18 +2931,25 @@ SQLRETURN WINAPI SQLProcedures(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, S SQLRETURN WINAPI SQLSetPos(SQLHSTMT StatementHandle, SQLSETPOSIROW RowNumber, SQLUSMALLINT Operation, SQLUSMALLINT LockType) { - struct SQLSetPos_params params = { 0, RowNumber, Operation, LockType }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, RowNumber %s, Operation %d, LockType %d)\n", StatementHandle, debugstr_sqlulen(RowNumber), Operation, LockType);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - if (SUCCESS(( ret = ODBC_CALL( SQLSetPos, ¶ms ))) && Operation == SQL_REFRESH) - update_result_lengths( handle, SQL_PARAM_OUTPUT ); + if (handle->unix_handle) + { + struct SQLSetPos_params params = { handle->unix_handle, RowNumber, Operation, LockType }; + if (SUCCESS(( ret = ODBC_CALL( SQLSetPos, ¶ms ))) && Operation == SQL_REFRESH) + update_result_lengths( handle, SQL_PARAM_OUTPUT ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetPos( handle->win32_handle, RowNumber, Operation, LockType ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2552,10 +2961,8 @@ SQLRETURN WINAPI SQLTablePrivileges(SQLHSTMT StatementHandle, SQLCHAR *CatalogNa SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3) { - struct SQLTablePrivileges_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, - TableName, NameLength3 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," "NameLength3 %d)\n", StatementHandle, @@ -2565,8 +2972,18 @@ SQLRETURN WINAPI SQLTablePrivileges(SQLHSTMT StatementHandle, SQLCHAR *CatalogNa
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLTablePrivileges, ¶ms ); + if (handle->unix_handle) + { + struct SQLTablePrivileges_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3 }; + ret = ODBC_CALL( SQLTablePrivileges, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLTablePrivileges( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2647,11 +3064,9 @@ SQLRETURN WINAPI SQLBindParameter(SQLHSTMT StatementHandle, SQLUSMALLINT Paramet SQLSMALLINT DecimalDigits, SQLPOINTER ParameterValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind) { - struct SQLBindParameter_params params = { 0, ParameterNumber, InputOutputType, ValueType, ParameterType, - ColumnSize, DecimalDigits, ParameterValue, BufferLength }; struct handle *handle = StatementHandle; UINT i = ParameterNumber - 1; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ParameterNumber %d, InputOutputType %d, ValueType %d, ParameterType %d, " "ColumnSize %s, DecimalDigits %d, ParameterValue, %p, BufferLength %s, StrLen_or_Ind %p)\n", @@ -2673,10 +3088,21 @@ SQLRETURN WINAPI SQLBindParameter(SQLHSTMT StatementHandle, SQLUSMALLINT Paramet handle->bind_parameter.param[i].parameter.parameter_value = ParameterValue; handle->bind_parameter.param[i].parameter.buffer_length = BufferLength;
- params.StatementHandle = handle->unix_handle; - params.StrLen_or_Ind = handle->bind_parameter.param[i].len; - *(UINT64 *)params.StrLen_or_Ind = *StrLen_or_Ind; - if (SUCCESS((ret = ODBC_CALL( SQLBindParameter, ¶ms )))) handle->bind_parameter.param[i].ptr = StrLen_or_Ind; + if (handle->unix_handle) + { + struct SQLBindParameter_params params = { handle->unix_handle, ParameterNumber, InputOutputType, ValueType, + ParameterType, ColumnSize, DecimalDigits, ParameterValue, + BufferLength, handle->bind_parameter.param[i].len }; + *(UINT64 *)params.StrLen_or_Ind = *StrLen_or_Ind; + if (SUCCESS((ret = ODBC_CALL( SQLBindParameter, ¶ms )))) handle->bind_parameter.param[i].ptr = StrLen_or_Ind; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLBindParameter( handle->win32_handle, ParameterNumber, InputOutputType, ValueType, + ParameterType, ColumnSize, DecimalDigits, ParameterValue, + BufferLength, StrLen_or_Ind ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -2684,24 +3110,72 @@ SQLRETURN WINAPI SQLBindParameter(SQLHSTMT StatementHandle, SQLUSMALLINT Paramet /************************************************************************* * SQLDriverConnect [ODBC32.041] */ -SQLRETURN WINAPI SQLDriverConnect(SQLHDBC ConnectionHandle, SQLHWND WindowHandle, SQLCHAR *ConnectionString, +SQLRETURN WINAPI SQLDriverConnect(SQLHDBC ConnectionHandle, SQLHWND WindowHandle, SQLCHAR *InConnectionString, SQLSMALLINT Length, SQLCHAR *OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *Length2, SQLUSMALLINT DriverCompletion) { - struct SQLDriverConnect_params params = { 0, WindowHandle, ConnectionString, Length, OutConnectionString, - BufferLength, Length2, DriverCompletion }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + WCHAR *datasource = NULL, *filename = NULL, *connection_string = strdupAW( (const char *)InConnectionString ); + SQLRETURN ret = SQL_ERROR;
- TRACE("(ConnectionHandle %p, hwnd %p, ConnectionString %s, Length %d, conn_str_out %p, conn_str_out_max %d," - " ptr_conn_str_out %p, driver_completion %d)\n", ConnectionHandle, WindowHandle, - debugstr_an((const char *)ConnectionString, Length), Length, OutConnectionString, BufferLength, + TRACE("(ConnectionHandle %p, WindowHandle %p, InConnectionString %s, Length %d, OutConnectionString, %p," + " BufferLength, %d, Length2 %p, DriverCompletion %d)\n", ConnectionHandle, WindowHandle, + debugstr_an((const char *)InConnectionString, Length), Length, OutConnectionString, BufferLength, Length2, DriverCompletion);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLDriverConnect, ¶ms ); + /* FIXME: try DRIVER attribute if DSN is absent */ + if (!connection_string || !(datasource = get_datasource( connection_string ))) + { + WARN( "can't find data source\n" ); + goto done; + } + if (!(filename = get_driver_filename( datasource ))) + { + WARN( "can't find driver filename\n" ); + goto done; + } + + if (has_suffix( filename, L".dll" )) + { + if (!(handle->win32_funcs = load_driver( filename ))) + { + WARN( "failed to load driver %s\n", debugstr_w(filename) ); + goto done; + } + TRACE( "using Windows driver %s\n", debugstr_w(filename) ); + + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_ENV, NULL, + &handle->parent->win32_handle )))) goto done; + + handle->parent->win32_funcs = handle->win32_funcs; + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_DBC, handle->parent->win32_handle, + &handle->win32_handle )))) goto done; + + ret = handle->win32_funcs->SQLDriverConnect( handle->win32_handle, WindowHandle, InConnectionString, Length, + OutConnectionString, BufferLength, Length2, DriverCompletion ); + } + else + { + struct SQLAllocEnv_params params_alloc_env = { &handle->parent->unix_handle }; + struct SQLAllocConnect_params params_alloc_connect = { 0, &handle->unix_handle }; + struct SQLDriverConnect_params params = { 0, WindowHandle, InConnectionString, Length, OutConnectionString, + BufferLength, Length2, DriverCompletion }; + + TRACE( "using Unix driver %s\n", debugstr_w(filename) ); + if (!SUCCESS((ret = ODBC_CALL( SQLAllocEnv, ¶ms_alloc_env )))) goto done; + + params_alloc_connect.EnvironmentHandle = handle->parent->unix_handle; + if (!SUCCESS((ret = ODBC_CALL( SQLAllocConnect, ¶ms_alloc_connect )))) goto done; + + params.ConnectionHandle = handle->unix_handle; + ret = ODBC_CALL( SQLDriverConnect, ¶ms ); + } + +done: + free( filename ); + free( datasource ); TRACE("Returning %d\n", ret); return ret; } @@ -2712,17 +3186,24 @@ SQLRETURN WINAPI SQLDriverConnect(SQLHDBC ConnectionHandle, SQLHWND WindowHandle SQLRETURN WINAPI SQLSetScrollOptions(SQLHSTMT StatementHandle, SQLUSMALLINT Concurrency, SQLLEN KeySetSize, SQLUSMALLINT RowSetSize) { - struct SQLSetScrollOptions_params params = { 0, Concurrency, KeySetSize, RowSetSize }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Concurrency %d, KeySetSize %s, RowSetSize %d)\n", StatementHandle, Concurrency, debugstr_sqllen(KeySetSize), RowSetSize);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetScrollOptions, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetScrollOptions_params params = { handle->unix_handle, Concurrency, KeySetSize, RowSetSize }; + ret = ODBC_CALL( SQLSetScrollOptions, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetScrollOptions( handle->win32_handle, Concurrency, KeySetSize, RowSetSize ); + } + TRACE("Returning %d\n", ret); return ret; }
From: Hans Leidekker hans@codeweavers.com
--- dlls/odbc32/proxyodbc.c | 767 ++++++++++++++++++++++++++++++---------- 1 file changed, 571 insertions(+), 196 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index f5fc73b86cb..c7fc17467a9 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -3245,11 +3245,8 @@ SQLRETURN WINAPI SQLColAttributesW(SQLHSTMT StatementHandle, SQLUSMALLINT Column SQLPOINTER CharacterAttributes, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLLEN *NumericAttributes) { - struct SQLColAttributesW_params params = { 0, ColumnNumber, FieldIdentifier, CharacterAttributes, BufferLength, - StringLength }; struct handle *handle = StatementHandle; - INT64 attrs; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ColumnNumber %d, FieldIdentifier %d, CharacterAttributes %p, BufferLength %d, " "StringLength %p, NumericAttributes %p)\n", StatementHandle, ColumnNumber, FieldIdentifier, @@ -3257,15 +3254,25 @@ SQLRETURN WINAPI SQLColAttributesW(SQLHSTMT StatementHandle, SQLUSMALLINT Column
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.NumericAttributes = &attrs; - if (SUCCESS((ret = ODBC_CALL( SQLColAttributesW, ¶ms )))) *NumericAttributes = attrs; + if (handle->unix_handle) + { + INT64 attrs; + struct SQLColAttributesW_params params = { handle->unix_handle, ColumnNumber, FieldIdentifier, + CharacterAttributes, BufferLength, StringLength, &attrs }; + if (SUCCESS((ret = ODBC_CALL( SQLColAttributesW, ¶ms )))) *NumericAttributes = attrs;
- if (ret == SQL_SUCCESS && SQLColAttributes_KnownStringAttribute(FieldIdentifier) && CharacterAttributes && - StringLength && *StringLength != wcslen(CharacterAttributes) * 2) + if (ret == SQL_SUCCESS && SQLColAttributes_KnownStringAttribute(FieldIdentifier) && CharacterAttributes && + StringLength && *StringLength != wcslen(CharacterAttributes) * 2) + { + TRACE("CHEAT: resetting name length for ADO\n"); + *StringLength = wcslen(CharacterAttributes) * 2; + } + } + else if (handle->win32_handle) { - TRACE("CHEAT: resetting name length for ADO\n"); - *StringLength = wcslen(CharacterAttributes) * 2; + ret = handle->win32_funcs->SQLColAttributesW( handle->win32_handle, ColumnNumber, FieldIdentifier, + CharacterAttributes, BufferLength, StringLength, + NumericAttributes ); }
TRACE("Returning %d\n", ret); @@ -3279,10 +3286,9 @@ SQLRETURN WINAPI SQLConnectW(SQLHDBC ConnectionHandle, WCHAR *ServerName, SQLSMA WCHAR *UserName, SQLSMALLINT NameLength2, WCHAR *Authentication, SQLSMALLINT NameLength3) { - struct SQLConnectW_params params = { 0, ServerName, NameLength1, UserName, NameLength2, Authentication, - NameLength3 }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + WCHAR *filename; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, ServerName %s, NameLength1 %d, UserName %s, NameLength2 %d, Authentication %s," " NameLength3 %d)\n", ConnectionHandle, debugstr_wn(ServerName, NameLength1), NameLength1, @@ -3290,8 +3296,50 @@ SQLRETURN WINAPI SQLConnectW(SQLHDBC ConnectionHandle, WCHAR *ServerName, SQLSMA
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLConnectW, ¶ms ); + if (!(filename = get_driver_filename( ServerName ))) + { + WARN( "can't find driver filename\n" ); + goto done; + } + + if (has_suffix( filename, L".dll" )) + { + if (!(handle->win32_funcs = load_driver( filename ))) + { + WARN( "failed to load driver %s\n", debugstr_w(filename) ); + goto done; + } + TRACE( "using Windows driver %s\n", debugstr_w(filename) ); + + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_ENV, NULL, + &handle->parent->win32_handle )))) goto done; + + handle->parent->win32_funcs = handle->win32_funcs; + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_DBC, handle->parent->win32_handle, + &handle->win32_handle )))) goto done; + + ret = handle->win32_funcs->SQLConnectW( handle->win32_handle, ServerName, NameLength1, UserName, NameLength2, + Authentication, NameLength3 ); + } + else + { + struct SQLAllocEnv_params params_alloc_env = { &handle->parent->unix_handle }; + struct SQLAllocConnect_params params_alloc_connect = { 0, &handle->unix_handle }; + struct SQLConnectW_params params_connect = { 0, ServerName, NameLength1, UserName, NameLength2, + Authentication, NameLength3 }; + + TRACE( "using Unix driver %s\n", debugstr_w(filename) ); + if (!SUCCESS((ret = ODBC_CALL( SQLAllocEnv, ¶ms_alloc_env )))) goto done; + + params_alloc_connect.EnvironmentHandle = handle->parent->unix_handle; + if (!SUCCESS((ret = ODBC_CALL( SQLAllocConnect, ¶ms_alloc_connect )))) goto done; + + params_connect.ConnectionHandle = handle->unix_handle; + ret = ODBC_CALL( SQLConnectW, ¶ms_connect ); + } + +done: + free( filename ); TRACE("Returning %d\n", ret); return ret; } @@ -3303,12 +3351,8 @@ SQLRETURN WINAPI SQLDescribeColW(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNu SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, SQLSMALLINT *DataType, SQLULEN *ColumnSize, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable) { - struct SQLDescribeColW_params params = { 0, ColumnNumber, ColumnName, BufferLength, NameLength, DataType, - NULL, DecimalDigits, Nullable }; struct handle *handle = StatementHandle; - SQLSMALLINT dummy; - UINT64 size; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, ColumnNumber %d, ColumnName %p, BufferLength %d, NameLength %p, DataType %p," " ColumnSize %p, DecimalDigits %p, Nullable %p)\n", StatementHandle, ColumnNumber, ColumnName, @@ -3316,20 +3360,20 @@ SQLRETURN WINAPI SQLDescribeColW(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNu
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - if (!NameLength) params.NameLength = &dummy; /* workaround for drivers that don't accept NULL NameLength */ - params.ColumnSize = &size; - if (SUCCESS((ret = ODBC_CALL( SQLDescribeColW, ¶ms )))) + if (handle->unix_handle) { - if (ColumnName && NameLength) TRACE("ColumnName %s\n", debugstr_wn(ColumnName, *NameLength)); - if (DataType) TRACE("DataType %d\n", *DataType); - if (ColumnSize) - { - *ColumnSize = size; - TRACE("ColumnSize %s\n", debugstr_sqlulen(*ColumnSize)); - } - if (DecimalDigits) TRACE("DecimalDigits %d\n", *DecimalDigits); - if (Nullable) TRACE("Nullable %d\n", *Nullable); + SQLSMALLINT dummy; + UINT64 size; + struct SQLDescribeColW_params params = { handle->unix_handle, ColumnNumber, ColumnName, BufferLength, + NameLength, DataType, &size, DecimalDigits, Nullable }; + if (!NameLength) params.NameLength = &dummy; /* workaround for drivers that don't accept NULL NameLength */ + + if (SUCCESS((ret = ODBC_CALL( SQLDescribeCol, ¶ms ))) && ColumnSize) *ColumnSize = size; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLDescribeColW( handle->win32_handle, ColumnNumber, ColumnName, BufferLength, + NameLength, DataType, ColumnSize, DecimalDigits, Nullable ); }
TRACE("Returning %d\n", ret); @@ -3343,24 +3387,35 @@ SQLRETURN WINAPI SQLErrorW(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, WCHAR *SqlState, SQLINTEGER *NativeError, WCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength) { - struct SQLErrorW_params params = { 0, 0, 0, SqlState, NativeError, MessageText, BufferLength, TextLength }; struct handle *env = EnvironmentHandle, *con = ConnectionHandle, *stmt = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(EnvironmentHandle %p, ConnectionHandle %p, StatementHandle %p, SqlState %p, NativeError %p," " MessageText %p, BufferLength %d, TextLength %p)\n", EnvironmentHandle, ConnectionHandle, StatementHandle, SqlState, NativeError, MessageText, BufferLength, TextLength);
- if (env) params.EnvironmentHandle = env->unix_handle; - if (con) params.ConnectionHandle = con->unix_handle; - if (stmt) params.StatementHandle = stmt->unix_handle; - if (SUCCESS((ret = ODBC_CALL( SQLErrorW, ¶ms )))) + if ((env && env->unix_handle) || (con && con->unix_handle) || (stmt && stmt->unix_handle)) + { + struct SQLErrorW_params params = { env ? env->unix_handle : 0, + con ? con->unix_handle : 0, + stmt ? stmt->unix_handle : 0, + SqlState, NativeError, MessageText, BufferLength, TextLength }; + ret = ODBC_CALL( SQLErrorW, ¶ms ); + } + else if ((env && env->win32_handle) || (con && con->win32_handle) || (stmt && stmt->win32_handle)) + { + ret = env->win32_funcs->SQLErrorW( env ? env->win32_handle : NULL, + con ? con->win32_handle : NULL, + stmt ? stmt->win32_handle : NULL, + SqlState, NativeError, MessageText, BufferLength, TextLength ); + } + + if (SUCCESS(ret )) { TRACE(" SqlState %s\n", debugstr_wn(SqlState, 5)); TRACE(" Error %d\n", *NativeError); TRACE(" MessageText %s\n", debugstr_wn(MessageText, *TextLength)); } - TRACE("Returning %d\n", ret); return ret; } @@ -3370,17 +3425,24 @@ SQLRETURN WINAPI SQLErrorW(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, */ SQLRETURN WINAPI SQLExecDirectW(SQLHSTMT StatementHandle, WCHAR *StatementText, SQLINTEGER TextLength) { - struct SQLExecDirectW_params params = { 0, StatementText, TextLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, StatementText %s, TextLength %d)\n", StatementHandle, debugstr_wn(StatementText, TextLength), TextLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLExecDirectW, ¶ms ); + if (handle->unix_handle) + { + struct SQLExecDirectW_params params = { handle->unix_handle, StatementText, TextLength }; + ret = ODBC_CALL( SQLExecDirectW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLExecDirectW( handle->win32_handle, StatementText, TextLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3391,17 +3453,24 @@ SQLRETURN WINAPI SQLExecDirectW(SQLHSTMT StatementHandle, WCHAR *StatementText, SQLRETURN WINAPI SQLGetCursorNameW(SQLHSTMT StatementHandle, WCHAR *CursorName, SQLSMALLINT BufferLength, SQLSMALLINT *NameLength) { - struct SQLGetCursorNameW_params params = { 0, CursorName, BufferLength, NameLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CursorName %p, BufferLength %d, NameLength %p)\n", StatementHandle, CursorName, BufferLength, NameLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetCursorNameW, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetCursorNameW_params params = { handle->unix_handle, CursorName, BufferLength, NameLength }; + ret = ODBC_CALL( SQLGetCursorNameW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetCursorNameW( handle->win32_handle, CursorName, BufferLength, NameLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3411,17 +3480,24 @@ SQLRETURN WINAPI SQLGetCursorNameW(SQLHSTMT StatementHandle, WCHAR *CursorName, */ SQLRETURN WINAPI SQLPrepareW(SQLHSTMT StatementHandle, WCHAR *StatementText, SQLINTEGER TextLength) { - struct SQLPrepareW_params params = { 0, StatementText, TextLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, StatementText %s, TextLength %d)\n", StatementHandle, debugstr_wn(StatementText, TextLength), TextLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLPrepareW, ¶ms ); + if (handle->unix_handle) + { + struct SQLPrepareW_params params = { handle->unix_handle, StatementText, TextLength }; + ret = ODBC_CALL( SQLPrepareW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLPrepareW( handle->win32_handle, StatementText, TextLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3431,17 +3507,24 @@ SQLRETURN WINAPI SQLPrepareW(SQLHSTMT StatementHandle, WCHAR *StatementText, SQL */ SQLRETURN WINAPI SQLSetCursorNameW(SQLHSTMT StatementHandle, WCHAR *CursorName, SQLSMALLINT NameLength) { - struct SQLSetCursorNameW_params params = { 0, CursorName, NameLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CursorName %s, NameLength %d)\n", StatementHandle, debugstr_wn(CursorName, NameLength), NameLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetCursorNameW, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetCursorNameW_params params = { handle->unix_handle, CursorName, NameLength }; + ret = ODBC_CALL( SQLSetCursorNameW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetCursorNameW( handle->win32_handle, CursorName, NameLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3454,11 +3537,8 @@ SQLRETURN WINAPI SQLColAttributeW(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnN SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLLEN *NumericAttribute) { - struct SQLColAttributeW_params params = { 0, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength, - StringLength }; struct handle *handle = StatementHandle; - INT64 attr; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("StatementHandle %p ColumnNumber %d FieldIdentifier %d CharacterAttribute %p BufferLength %d" " StringLength %p NumericAttribute %p\n", StatementHandle, ColumnNumber, FieldIdentifier, @@ -3466,15 +3546,26 @@ SQLRETURN WINAPI SQLColAttributeW(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnN
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - params.NumericAttribute = &attr; - if (SUCCESS((ret = ODBC_CALL( SQLColAttributeW, ¶ms ))) && NumericAttribute) *NumericAttribute = attr; + if (handle->unix_handle) + { + INT64 attr; + struct SQLColAttributeW_params params = { handle->unix_handle, ColumnNumber, FieldIdentifier, + CharacterAttribute, BufferLength, StringLength, &attr }; + + if (SUCCESS((ret = ODBC_CALL( SQLColAttributeW, ¶ms ))) && NumericAttribute) *NumericAttribute = attr;
- if (ret == SQL_SUCCESS && CharacterAttribute != NULL && SQLColAttributes_KnownStringAttribute(FieldIdentifier) && - StringLength && *StringLength != wcslen(CharacterAttribute) * 2) + if (ret == SQL_SUCCESS && CharacterAttribute != NULL && SQLColAttributes_KnownStringAttribute(FieldIdentifier) && + StringLength && *StringLength != wcslen(CharacterAttribute) * 2) + { + TRACE("CHEAT: resetting name length for ADO\n"); + *StringLength = wcslen(CharacterAttribute) * 2; + } + } + else if (handle->win32_handle) { - TRACE("CHEAT: resetting name length for ADO\n"); - *StringLength = wcslen(CharacterAttribute) * 2; + ret = handle->win32_funcs->SQLColAttributeW( handle->win32_handle, ColumnNumber, FieldIdentifier, + CharacterAttribute, BufferLength, StringLength, + NumericAttribute ); }
TRACE("Returning %d\n", ret); @@ -3487,17 +3578,26 @@ SQLRETURN WINAPI SQLColAttributeW(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnN SQLRETURN WINAPI SQLGetConnectAttrW(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength) { - struct SQLGetConnectAttrW_params params = { 0, Attribute, Value, BufferLength, StringLength }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n", ConnectionHandle, Attribute, Value, BufferLength, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetConnectAttrW, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetConnectAttrW_params params = { handle->unix_handle, Attribute, Value, BufferLength, + StringLength }; + ret = ODBC_CALL( SQLGetConnectAttrW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetConnectAttrW( handle->win32_handle, Attribute, Value, BufferLength, + StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3508,17 +3608,26 @@ SQLRETURN WINAPI SQLGetConnectAttrW(SQLHDBC ConnectionHandle, SQLINTEGER Attribu SQLRETURN WINAPI SQLGetDescFieldW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength) { - struct SQLGetDescFieldW_params params = { 0, RecNumber, FieldIdentifier, Value, BufferLength, StringLength }; struct handle *handle = DescriptorHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(DescriptorHandle %p, RecNumber %d, FieldIdentifier %d, Value %p, BufferLength %d, StringLength %p)\n", DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.DescriptorHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetDescFieldW, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetDescFieldW_params params = { handle->unix_handle, RecNumber, FieldIdentifier, Value, + BufferLength, StringLength }; + ret = ODBC_CALL( SQLGetDescFieldW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetDescFieldW( handle->win32_handle, RecNumber, FieldIdentifier, Value, + BufferLength, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3531,11 +3640,8 @@ SQLRETURN WINAPI SQLGetDescRecW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber SQLSMALLINT *SubType, SQLLEN *Length, SQLSMALLINT *Precision, SQLSMALLINT *Scale, SQLSMALLINT *Nullable) { - struct SQLGetDescRecW_params params = { 0, RecNumber, Name, BufferLength, StringLength, Type, SubType, - NULL, Precision, Scale, Nullable }; struct handle *handle = DescriptorHandle; - INT64 len; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(DescriptorHandle %p, RecNumber %d, Name %p, BufferLength %d, StringLength %p, Type %p, SubType %p," " Length %p, Precision %p, Scale %p, Nullable %p)\n", DescriptorHandle, RecNumber, Name, BufferLength, @@ -3543,9 +3649,19 @@ SQLRETURN WINAPI SQLGetDescRecW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber
if (!handle) return SQL_INVALID_HANDLE;
- params.DescriptorHandle = handle->unix_handle; - params.Length = &len; - if (SUCCESS((ret = ODBC_CALL( SQLGetDescRecW, ¶ms )))) *Length = len; + if (handle->unix_handle) + { + INT64 len; + struct SQLGetDescRecW_params params = { handle->unix_handle, RecNumber, Name, BufferLength, StringLength, + Type, SubType, &len, Precision, Scale, Nullable }; + if (SUCCESS((ret = ODBC_CALL( SQLGetDescRecW, ¶ms )))) *Length = len; + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetDescRecW( handle->win32_handle, RecNumber, Name, BufferLength, StringLength, + Type, SubType, Length, Precision, Scale, Nullable ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3557,18 +3673,26 @@ SQLRETURN WINAPI SQLGetDiagFieldW(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLS SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) { - struct SQLGetDiagFieldW_params params = { HandleType, 0, RecNumber, DiagIdentifier, DiagInfo, BufferLength, - StringLength }; struct handle *handle = Handle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(HandleType %d, Handle %p, RecNumber %d, DiagIdentifier %d, DiagInfo %p, BufferLength %d," " StringLength %p)\n", HandleType, Handle, RecNumber, DiagIdentifier, DiagInfo, BufferLength, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.Handle = handle->unix_handle; - ret = ODBC_CALL( SQLGetDiagFieldW, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetDiagFieldW_params params = { HandleType, handle->unix_handle, RecNumber, DiagIdentifier, + DiagInfo, BufferLength, StringLength }; + ret = ODBC_CALL( SQLGetDiagFieldW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetDiagFieldW( HandleType, handle->win32_handle, RecNumber, DiagIdentifier, + DiagInfo, BufferLength, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3580,10 +3704,8 @@ SQLRETURN WINAPI SQLGetDiagRecW(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMA SQLINTEGER *NativeError, WCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength) { - struct SQLGetDiagRecW_params params = { HandleType, 0, RecNumber, SqlState, NativeError, MessageText, - BufferLength, TextLength }; struct handle *handle = Handle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(HandleType %d, Handle %p, RecNumber %d, SqlState %p, NativeError %p, MessageText %p, BufferLength %d," " TextLength %p)\n", HandleType, Handle, RecNumber, SqlState, NativeError, MessageText, BufferLength, @@ -3591,8 +3713,18 @@ SQLRETURN WINAPI SQLGetDiagRecW(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMA
if (!handle) return SQL_INVALID_HANDLE;
- params.Handle = handle->unix_handle; - ret = ODBC_CALL( SQLGetDiagRecW, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetDiagRecW_params params = { HandleType, handle->unix_handle, RecNumber, SqlState, NativeError, + MessageText, BufferLength, TextLength }; + ret = ODBC_CALL( SQLGetDiagRecW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetDiagRecW( HandleType, handle->win32_handle, RecNumber, SqlState, NativeError, + MessageText, BufferLength, TextLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3603,9 +3735,8 @@ SQLRETURN WINAPI SQLGetDiagRecW(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMA SQLRETURN WINAPI SQLGetStmtAttrW(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength) { - struct SQLGetStmtAttrW_params params = { 0, Attribute, Value, BufferLength, StringLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n", StatementHandle, Attribute, Value, BufferLength, StringLength); @@ -3618,8 +3749,16 @@ SQLRETURN WINAPI SQLGetStmtAttrW(SQLHSTMT StatementHandle, SQLINTEGER Attribute,
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetStmtAttrW, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetStmtAttrW_params params = { handle->unix_handle, Attribute, Value, BufferLength, StringLength }; + ret = ODBC_CALL( SQLGetStmtAttrW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetStmtAttrW( handle->win32_handle, Attribute, Value, BufferLength, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3630,17 +3769,24 @@ SQLRETURN WINAPI SQLGetStmtAttrW(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLRETURN WINAPI SQLSetConnectAttrW(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength) { - struct SQLSetConnectAttrW_params params = { 0, Attribute, Value, StringLength }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, Attribute %d, Value %p, StringLength %d)\n", ConnectionHandle, Attribute, Value, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetConnectAttrW, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetConnectAttrW_params params = { handle->unix_handle, Attribute, Value, StringLength }; + ret = ODBC_CALL( SQLSetConnectAttrW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetConnectAttrW( handle->win32_handle, Attribute, Value, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3652,10 +3798,8 @@ SQLRETURN WINAPI SQLColumnsW(SQLHSTMT StatementHandle, WCHAR *CatalogName, SQLSM WCHAR *SchemaName, SQLSMALLINT NameLength2, WCHAR *TableName, SQLSMALLINT NameLength3, WCHAR *ColumnName, SQLSMALLINT NameLength4) { - struct SQLColumnsW_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, TableName, - NameLength3, ColumnName, NameLength4 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," " NameLength3 %d, ColumnName %s, NameLength4 %d)\n", StatementHandle, @@ -3664,8 +3808,18 @@ SQLRETURN WINAPI SQLColumnsW(SQLHSTMT StatementHandle, WCHAR *CatalogName, SQLSM
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLColumnsW, ¶ms ); + if (handle->unix_handle) + { + struct SQLColumnsW_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, NameLength2, + TableName, NameLength3, ColumnName, NameLength4 }; + ret = ODBC_CALL( SQLColumnsW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLColumnsW( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, ColumnName, NameLength4 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3677,10 +3831,9 @@ SQLRETURN WINAPI SQLDriverConnectW(SQLHDBC ConnectionHandle, SQLHWND WindowHandl SQLSMALLINT Length, WCHAR *OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *Length2, SQLUSMALLINT DriverCompletion) { - struct SQLDriverConnectW_params params = { 0, WindowHandle, InConnectionString, Length, OutConnectionString, - BufferLength, Length2, DriverCompletion }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + WCHAR *datasource, *filename = NULL; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, WindowHandle %p, InConnectionString %s, Length %d, OutConnectionString %p," " BufferLength %d, Length2 %p, DriverCompletion %d)\n", ConnectionHandle, WindowHandle, @@ -3689,8 +3842,57 @@ SQLRETURN WINAPI SQLDriverConnectW(SQLHDBC ConnectionHandle, SQLHWND WindowHandl
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLDriverConnectW, ¶ms ); + /* FIXME: try DRIVER attribute if DSN is absent */ + if (!(datasource = get_datasource( InConnectionString ))) + { + WARN( "can't find data source\n" ); + goto done; + } + if (!(filename = get_driver_filename( datasource ))) + { + WARN( "can't find driver filename\n" ); + goto done; + } + + if (has_suffix( filename, L".dll" )) + { + if (!(handle->win32_funcs = load_driver( filename ))) + { + WARN( "failed to load driver %s\n", debugstr_w(filename) ); + goto done; + } + TRACE( "using Windows driver %s\n", debugstr_w(filename) ); + + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_ENV, NULL, + &handle->parent->win32_handle )))) goto done; + + handle->parent->win32_funcs = handle->win32_funcs; + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_DBC, handle->parent->win32_handle, + &handle->win32_handle )))) goto done; + + ret = handle->win32_funcs->SQLDriverConnectW( handle->win32_handle, WindowHandle, InConnectionString, Length, + OutConnectionString, BufferLength, Length2, DriverCompletion ); + } + else + { + struct SQLAllocEnv_params params_alloc_env = { &handle->parent->unix_handle }; + struct SQLAllocConnect_params params_alloc_connect = { 0, &handle->unix_handle }; + struct SQLDriverConnectW_params params = { 0, WindowHandle, InConnectionString, Length, OutConnectionString, + BufferLength, Length2, DriverCompletion }; + + TRACE( "using Unix driver %s\n", debugstr_w(filename) ); + if (!SUCCESS((ret = ODBC_CALL( SQLAllocEnv, ¶ms_alloc_env )))) goto done; + + params_alloc_connect.EnvironmentHandle = handle->parent->unix_handle; + if (!SUCCESS((ret = ODBC_CALL( SQLAllocConnect, ¶ms_alloc_connect )))) goto done; + + params.ConnectionHandle = handle->unix_handle; + ret = ODBC_CALL( SQLDriverConnectW, ¶ms ); + } + +done: + free( filename ); + free( datasource ); TRACE("Returning %d\n", ret); return ret; } @@ -3700,16 +3902,23 @@ SQLRETURN WINAPI SQLDriverConnectW(SQLHDBC ConnectionHandle, SQLHWND WindowHandl */ SQLRETURN WINAPI SQLGetConnectOptionW(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLPOINTER Value) { - struct SQLGetConnectOptionW_params params = { 0, Option, Value }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, Option %d, Value %p)\n", ConnectionHandle, Option, Value);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetConnectOptionW, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetConnectOptionW_params params = { handle->unix_handle, Option, Value }; + ret = ODBC_CALL( SQLGetConnectOptionW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetConnectOptionW( handle->win32_handle, Option, Value ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3720,17 +3929,24 @@ SQLRETURN WINAPI SQLGetConnectOptionW(SQLHDBC ConnectionHandle, SQLUSMALLINT Opt SQLRETURN WINAPI SQLGetInfoW(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) { - struct SQLGetInfoW_params params = { 0, InfoType, InfoValue, BufferLength, StringLength }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle, %p, InfoType %d, InfoValue %p, BufferLength %d, StringLength %p)\n", ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetInfoW, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetInfoW_params params = { handle->unix_handle, InfoType, InfoValue, BufferLength, StringLength }; + ret = ODBC_CALL( SQLGetInfoW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetInfoW( handle->win32_handle, InfoType, InfoValue, BufferLength, StringLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3740,16 +3956,23 @@ SQLRETURN WINAPI SQLGetInfoW(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQ */ SQLRETURN WINAPI SQLGetTypeInfoW(SQLHSTMT StatementHandle, SQLSMALLINT DataType) { - struct SQLGetTypeInfoW_params params = { 0, DataType }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, DataType %d)\n", StatementHandle, DataType);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLGetTypeInfoW, ¶ms ); + if (handle->unix_handle) + { + struct SQLGetTypeInfoW_params params = { handle->unix_handle, DataType }; + ret = ODBC_CALL( SQLGetTypeInfoW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLGetTypeInfoW( handle->win32_handle, DataType ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3759,16 +3982,23 @@ SQLRETURN WINAPI SQLGetTypeInfoW(SQLHSTMT StatementHandle, SQLSMALLINT DataType) */ SQLRETURN WINAPI SQLSetConnectOptionW(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLULEN Value) { - struct SQLSetConnectOptionW_params params = { 0, Option, Value }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, Option %d, Value %s)\n", ConnectionHandle, Option, debugstr_sqllen(Value));
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetConnectOptionW, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetConnectOptionW_params params = { handle->unix_handle, Option, Value }; + ret = ODBC_CALL( SQLSetConnectOptionW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetConnectOptionW( handle->win32_handle, Option, Value ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3781,10 +4011,8 @@ SQLRETURN WINAPI SQLSpecialColumnsW(SQLHSTMT StatementHandle, SQLUSMALLINT Ident SQLSMALLINT NameLength2, SQLWCHAR *TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Scope, SQLUSMALLINT Nullable) { - struct SQLSpecialColumnsW_params params = { 0, IdentifierType, CatalogName, NameLength1, SchemaName, NameLength2, - TableName, NameLength3, Scope, Nullable }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, IdentifierType %d, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d," " TableName %s, NameLength3 %d, Scope %d, Nullable %d)\n", StatementHandle, IdentifierType, @@ -3793,8 +4021,19 @@ SQLRETURN WINAPI SQLSpecialColumnsW(SQLHSTMT StatementHandle, SQLUSMALLINT Ident
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSpecialColumnsW, ¶ms ); + if (handle->unix_handle) + { + struct SQLSpecialColumnsW_params params = { handle->unix_handle, IdentifierType, CatalogName, NameLength1, + SchemaName, NameLength2, TableName, NameLength3, Scope, Nullable }; + ret = ODBC_CALL( SQLSpecialColumnsW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSpecialColumnsW( handle->win32_handle, IdentifierType, CatalogName, + NameLength1, SchemaName, NameLength2, TableName, NameLength3, + Scope, Nullable ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3806,10 +4045,8 @@ SQLRETURN WINAPI SQLStatisticsW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName, SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Unique, SQLUSMALLINT Reserved) { - struct SQLStatisticsW_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, TableName, - NameLength3, Unique, Reserved }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d SchemaName %s, NameLength2 %d, TableName %s" " NameLength3 %d, Unique %d, Reserved %d)\n", StatementHandle, @@ -3818,8 +4055,18 @@ SQLRETURN WINAPI SQLStatisticsW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName,
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLStatisticsW, ¶ms ); + if (handle->unix_handle) + { + struct SQLStatisticsW_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, Unique, Reserved }; + ret = ODBC_CALL( SQLStatisticsW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLStatisticsW( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, Unique, Reserved ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3831,10 +4078,8 @@ SQLRETURN WINAPI SQLTablesW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName, SQL SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *TableName, SQLSMALLINT NameLength3, SQLWCHAR *TableType, SQLSMALLINT NameLength4) { - struct SQLTablesW_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, TableName, - NameLength3, TableType, NameLength4 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," " NameLength3 %d, TableType %s, NameLength4 %d)\n", StatementHandle, @@ -3843,8 +4088,18 @@ SQLRETURN WINAPI SQLTablesW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName, SQL
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLTablesW, ¶ms ); + if (handle->unix_handle) + { + struct SQLTablesW_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, NameLength2, + TableName, NameLength3, TableType, NameLength4 }; + ret = ODBC_CALL( SQLTablesW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLTablesW( handle->win32_handle, CatalogName, NameLength1, SchemaName, NameLength2, + TableName, NameLength3, TableType, NameLength4 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3855,10 +4110,9 @@ SQLRETURN WINAPI SQLTablesW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName, SQL SQLRETURN WINAPI SQLBrowseConnectW(SQLHDBC ConnectionHandle, SQLWCHAR *InConnectionString, SQLSMALLINT StringLength1, SQLWCHAR *OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength2) { - struct SQLBrowseConnectW_params params = { 0, InConnectionString, StringLength1, OutConnectionString, - BufferLength, StringLength2 }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + WCHAR *datasource, *filename = NULL; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, InConnectionString %s, StringLength1 %d, OutConnectionString %p, BufferLength %d, " "StringLength2 %p)\n", ConnectionHandle, debugstr_wn(InConnectionString, StringLength1), StringLength1, @@ -3866,8 +4120,57 @@ SQLRETURN WINAPI SQLBrowseConnectW(SQLHDBC ConnectionHandle, SQLWCHAR *InConnect
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLBrowseConnectW, ¶ms ); + /* FIXME: try DRIVER attribute if DSN is absent */ + if (!(datasource = get_datasource( InConnectionString ))) + { + WARN( "can't find data source\n" ); + goto done; + } + if (!(filename = get_driver_filename( datasource ))) + { + WARN( "can't find driver filename\n" ); + goto done; + } + + if (has_suffix( filename, L".dll" )) + { + if (!(handle->win32_funcs = load_driver( filename ))) + { + WARN( "failed to load driver %s\n", debugstr_w(filename) ); + goto done; + } + TRACE( "using Windows driver %s\n", debugstr_w(filename) ); + + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_ENV, NULL, + &handle->parent->win32_handle )))) goto done; + + handle->parent->win32_funcs = handle->win32_funcs; + if (!SUCCESS((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_DBC, handle->parent->win32_handle, + &handle->win32_handle )))) goto done; + + ret = handle->win32_funcs->SQLBrowseConnectW( handle->win32_handle, InConnectionString, StringLength1, + OutConnectionString, BufferLength, StringLength2 ); + } + else + { + struct SQLAllocEnv_params params_alloc_env = { &handle->parent->unix_handle }; + struct SQLAllocConnect_params params_alloc_connect = { 0, &handle->unix_handle }; + struct SQLBrowseConnectW_params params = { 0, InConnectionString, StringLength1, OutConnectionString, + BufferLength, StringLength2 }; + + TRACE( "using Unix driver %s\n", debugstr_w(filename) ); + if (!SUCCESS((ret = ODBC_CALL( SQLAllocEnv, ¶ms_alloc_env )))) goto done; + + params_alloc_connect.EnvironmentHandle = handle->parent->unix_handle; + if (!SUCCESS((ret = ODBC_CALL( SQLAllocConnect, ¶ms_alloc_connect )))) goto done; + + params.ConnectionHandle = handle->unix_handle; + ret = ODBC_CALL( SQLBrowseConnectW, ¶ms ); + } + +done: + free( filename ); + free( datasource ); TRACE("Returning %d\n", ret); return ret; } @@ -3879,10 +4182,8 @@ SQLRETURN WINAPI SQLColumnPrivilegesW(SQLHSTMT StatementHandle, SQLWCHAR *Catalo SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *TableName, SQLSMALLINT NameLength3, SQLWCHAR *ColumnName, SQLSMALLINT NameLength4) { - struct SQLColumnPrivilegesW_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, - TableName, NameLength3, ColumnName, NameLength4 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," " NameLength3 %d, ColumnName %s, NameLength3 %d)\n", StatementHandle, @@ -3893,8 +4194,18 @@ SQLRETURN WINAPI SQLColumnPrivilegesW(SQLHSTMT StatementHandle, SQLWCHAR *Catalo
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLColumnPrivilegesW, ¶ms ); + if (handle->unix_handle) + { + struct SQLColumnPrivilegesW_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, ColumnName, NameLength4 }; + ret = ODBC_CALL( SQLColumnPrivilegesW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLColumnPrivilegesW( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3, ColumnName, NameLength4 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -3976,11 +4287,8 @@ SQLRETURN WINAPI SQLForeignKeysW(SQLHSTMT StatementHandle, SQLWCHAR *PkCatalogNa SQLWCHAR *FkSchemaName, SQLSMALLINT NameLength5, SQLWCHAR *FkTableName, SQLSMALLINT NameLength6) { - struct SQLForeignKeysW_params params = { 0, PkCatalogName, NameLength1, PkSchemaName, NameLength2, - PkTableName, NameLength2, FkCatalogName, NameLength3, - FkSchemaName, NameLength5, FkTableName, NameLength6 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, PkCatalogName %s, NameLength1 %d, PkSchemaName %s, NameLength2 %d," " PkTableName %s, NameLength3 %d, FkCatalogName %s, NameLength4 %d, FkSchemaName %s," @@ -3994,8 +4302,20 @@ SQLRETURN WINAPI SQLForeignKeysW(SQLHSTMT StatementHandle, SQLWCHAR *PkCatalogNa
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLForeignKeysW, ¶ms ); + if (handle->unix_handle) + { + struct SQLForeignKeysW_params params = { handle->unix_handle, PkCatalogName, NameLength1, PkSchemaName, + NameLength2, PkTableName, NameLength2, FkCatalogName, NameLength3, + FkSchemaName, NameLength5, FkTableName, NameLength6 }; + ret = ODBC_CALL( SQLForeignKeysW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLForeignKeysW( handle->win32_handle, PkCatalogName, NameLength1, PkSchemaName, + NameLength2, PkTableName, NameLength3, FkCatalogName, NameLength4, + FkSchemaName, NameLength5, FkTableName, NameLength6 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -4006,10 +4326,8 @@ SQLRETURN WINAPI SQLForeignKeysW(SQLHSTMT StatementHandle, SQLWCHAR *PkCatalogNa SQLRETURN WINAPI SQLNativeSqlW(SQLHDBC ConnectionHandle, SQLWCHAR *InStatementText, SQLINTEGER TextLength1, SQLWCHAR *OutStatementText, SQLINTEGER BufferLength, SQLINTEGER *TextLength2) { - struct SQLNativeSqlW_params params = { 0, InStatementText, TextLength1, OutStatementText, BufferLength, - TextLength2 }; struct handle *handle = ConnectionHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(ConnectionHandle %p, InStatementText %s, TextLength1 %d, OutStatementText %p, BufferLength %d, " "TextLength2 %p)\n", ConnectionHandle, debugstr_wn(InStatementText, TextLength1), TextLength1, @@ -4017,8 +4335,18 @@ SQLRETURN WINAPI SQLNativeSqlW(SQLHDBC ConnectionHandle, SQLWCHAR *InStatementTe
if (!handle) return SQL_INVALID_HANDLE;
- params.ConnectionHandle = handle->unix_handle; - ret = ODBC_CALL( SQLNativeSqlW, ¶ms ); + if (handle->unix_handle) + { + struct SQLNativeSqlW_params params = { handle->unix_handle, InStatementText, TextLength1, OutStatementText, + BufferLength, TextLength2 }; + ret = ODBC_CALL( SQLNativeSqlW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLNativeSqlW( handle->win32_handle, InStatementText, TextLength1, OutStatementText, + BufferLength, TextLength2 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -4030,10 +4358,8 @@ SQLRETURN WINAPI SQLPrimaryKeysW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *TableName, SQLSMALLINT NameLength3) { - struct SQLPrimaryKeysW_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, TableName, - NameLength2 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," " NameLength3 %d)\n", StatementHandle, @@ -4043,8 +4369,18 @@ SQLRETURN WINAPI SQLPrimaryKeysW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLPrimaryKeysW, ¶ms ); + if (handle->unix_handle) + { + struct SQLPrimaryKeysW_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength2 }; + ret = ODBC_CALL( SQLPrimaryKeysW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLPrimaryKeysW( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength2 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -4056,10 +4392,8 @@ SQLRETURN WINAPI SQLProcedureColumnsW(SQLHSTMT StatementHandle, SQLWCHAR *Catalo SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *ProcName, SQLSMALLINT NameLength3, SQLWCHAR *ColumnName, SQLSMALLINT NameLength4 ) { - struct SQLProcedureColumnsW_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, - ProcName, NameLength3, ColumnName, NameLength4 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, ProcName %s," " NameLength3 %d, ColumnName %s, NameLength4 %d)\n", StatementHandle, @@ -4070,8 +4404,18 @@ SQLRETURN WINAPI SQLProcedureColumnsW(SQLHSTMT StatementHandle, SQLWCHAR *Catalo
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLProcedureColumnsW, ¶ms ); + if (handle->unix_handle) + { + struct SQLProcedureColumnsW_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, ProcName, NameLength3, ColumnName, NameLength4 }; + ret = ODBC_CALL( SQLProcedureColumnsW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLProcedureColumnsW( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, ProcName, NameLength3, ColumnName, NameLength4 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -4083,10 +4427,8 @@ SQLRETURN WINAPI SQLProceduresW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName, SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *ProcName, SQLSMALLINT NameLength3) { - struct SQLProceduresW_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, ProcName, - NameLength3 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, ProcName %s," " NameLength3 %d)\n", StatementHandle, debugstr_wn(CatalogName, NameLength1), NameLength1, @@ -4094,8 +4436,18 @@ SQLRETURN WINAPI SQLProceduresW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName,
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLProceduresW, ¶ms ); + if (handle->unix_handle) + { + struct SQLProceduresW_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, ProcName, NameLength3 }; + ret = ODBC_CALL( SQLProceduresW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLProceduresW( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, ProcName, NameLength3 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -4107,10 +4459,8 @@ SQLRETURN WINAPI SQLTablePrivilegesW(SQLHSTMT StatementHandle, SQLWCHAR *Catalog SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *TableName, SQLSMALLINT NameLength3) { - struct SQLTablePrivilegesW_params params = { 0, CatalogName, NameLength1, SchemaName, NameLength2, TableName, - NameLength3 }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s," " NameLength3 %d)\n", StatementHandle, debugstr_wn(CatalogName, NameLength1), NameLength1, @@ -4118,8 +4468,18 @@ SQLRETURN WINAPI SQLTablePrivilegesW(SQLHSTMT StatementHandle, SQLWCHAR *Catalog
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLTablePrivilegesW, ¶ms ); + if (handle->unix_handle) + { + struct SQLTablePrivilegesW_params params = { handle->unix_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3 }; + ret = ODBC_CALL( SQLTablePrivilegesW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLTablePrivilegesW( handle->win32_handle, CatalogName, NameLength1, SchemaName, + NameLength2, TableName, NameLength3 ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -4189,17 +4549,26 @@ done: SQLRETURN WINAPI SQLSetDescFieldW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER Value, SQLINTEGER BufferLength) { - struct SQLSetDescFieldW_params params = { 0, RecNumber, FieldIdentifier, Value, BufferLength }; struct handle *handle = DescriptorHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(DescriptorHandle %p, RecNumber %d, FieldIdentifier %d, Value %p, BufferLength %d)\n", DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.DescriptorHandle = handle->unix_handle; - ret = ODBC_CALL( SQLSetDescFieldW, ¶ms ); + if (handle->unix_handle) + { + struct SQLSetDescFieldW_params params = { handle->unix_handle, RecNumber, FieldIdentifier, Value, + BufferLength }; + ret = ODBC_CALL( SQLSetDescFieldW, ¶ms ); + } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetDescFieldW( handle->win32_handle, RecNumber, FieldIdentifier, Value, + BufferLength ); + } + TRACE("Returning %d\n", ret); return ret; } @@ -4210,26 +4579,32 @@ SQLRETURN WINAPI SQLSetDescFieldW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumb SQLRETURN WINAPI SQLSetStmtAttrW(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength) { - struct SQLSetStmtAttrW_params params = { 0, Attribute, Value, StringLength }; struct handle *handle = StatementHandle; - SQLRETURN ret; + SQLRETURN ret = SQL_ERROR;
TRACE("(StatementHandle %p, Attribute %d, Value %p, StringLength %d)\n", StatementHandle, Attribute, Value, StringLength);
if (!handle) return SQL_INVALID_HANDLE;
- params.StatementHandle = handle->unix_handle; - if (SUCCESS((ret = ODBC_CALL( SQLSetStmtAttrW, ¶ms )))) + if (handle->unix_handle) { - SQLULEN row_count = (SQLULEN)Value; - if (Attribute == SQL_ATTR_ROW_ARRAY_SIZE && row_count != handle->row_count) + struct SQLSetStmtAttrW_params params = { handle->unix_handle, Attribute, Value, StringLength }; + if (SUCCESS((ret = ODBC_CALL( SQLSetStmtAttrW, ¶ms )))) { - TRACE( "resizing result length array\n" ); - if (!resize_result_lengths( handle, row_count )) ret = SQL_ERROR; - else handle->row_count = row_count; + SQLULEN row_count = (SQLULEN)Value; + if (Attribute == SQL_ATTR_ROW_ARRAY_SIZE && row_count != handle->row_count) + { + TRACE( "resizing result length array\n" ); + if (!resize_result_lengths( handle, row_count )) ret = SQL_ERROR; + else handle->row_count = row_count; + } } } + else if (handle->win32_handle) + { + ret = handle->win32_funcs->SQLSetStmtAttrW( handle->win32_handle, Attribute, Value, StringLength ); + }
TRACE("Returning %d\n", ret); return ret;
From: Hans Leidekker hans@codeweavers.com
--- dlls/odbc32/tests/odbc32.c | 126 +++++++++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 13 deletions(-)
diff --git a/dlls/odbc32/tests/odbc32.c b/dlls/odbc32/tests/odbc32.c index 5a3b0c6f817..8f238b6c501 100644 --- a/dlls/odbc32/tests/odbc32.c +++ b/dlls/odbc32/tests/odbc32.c @@ -55,6 +55,7 @@ static void test_SQLAllocHandle( void ) ok( ret == SQL_SUCCESS, "got %d\n", ret ); ret = SQLFreeConnect( 0 ); ok( ret == SQL_INVALID_HANDLE, "got %d\n", ret ); + ret = SQLFreeEnv( env ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); ret = SQLFreeEnv( 0 ); @@ -68,7 +69,8 @@ static void diag( SQLHANDLE handle, SQLSMALLINT type ) SQLCHAR state[5], msg[256]; SQLRETURN ret;
- memset( state, 0, sizeof(state) ); + state[0] = 0; + msg[0] = 0; err = -1; len = 0; ret = SQLGetDiagRec( type, handle, 1, state, &err, msg, sizeof(msg), &len ); @@ -101,7 +103,7 @@ static void test_SQLConnect( void ) ret = SQLAllocConnect( env, &con ); ok( ret == SQL_SUCCESS, "got %d\n", ret );
- ret = SQLConnect( con, (SQLCHAR *)"winetest", 8, NULL, 0, NULL, 0 ); + ret = SQLConnect( con, (SQLCHAR *)"winetest", 8, (SQLCHAR *)"winetest", 8, (SQLCHAR *)"winetest", 8 ); if (ret == SQL_ERROR) diag( con, SQL_HANDLE_DBC ); if (ret != SQL_SUCCESS) { @@ -121,10 +123,84 @@ static void test_SQLConnect( void ) len = -1; memset( str, 0, sizeof(str) ); ret = SQLGetInfo( con, SQL_ODBC_VER, str, sizeof(str), &len ); + if (ret == SQL_SUCCESS) + { + ok( str[0], "empty string\n" ); + ok( len != -1, "len not set\n" ); + trace( "version %s\n", str ); + } + + ret = SQLDisconnect( con ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); - ok( str[0], "empty string\n" ); - ok( len != -1, "len not set\n" ); - trace( "version %s\n", str ); + + ret = SQLFreeConnect( con ); + ok( ret == SQL_SUCCESS, "got %d\n", ret ); + + ret = SQLFreeEnv( env ); + ok( ret == SQL_SUCCESS, "got %d\n", ret ); +} + +static void test_SQLDriverConnect( void ) +{ + SQLHENV env; + SQLHDBC con; + SQLRETURN ret; + SQLSMALLINT len; + SQLCHAR str[256]; + + ret = SQLAllocEnv( &env ); + ok( ret == SQL_SUCCESS, "got %d\n", ret ); + + ret = SQLAllocConnect( env, &con ); + ok( ret == SQL_SUCCESS, "got %d\n", ret ); + + len = 0; + str[0] = 0; + ret = SQLDriverConnect( con, NULL, (SQLCHAR *)"DSN=winetest", strlen("DSN=winetest"), str, sizeof(str), &len, 0 ); + if (ret == SQL_ERROR) diag( con, SQL_HANDLE_DBC ); + if (ret != SQL_SUCCESS) + { + SQLFreeConnect( con ); + SQLFreeEnv( env ); + skip( "data source winetest not available\n" ); + return; + } + + ret = SQLDisconnect( con ); + ok( ret == SQL_SUCCESS, "got %d\n", ret ); + + ret = SQLFreeConnect( con ); + ok( ret == SQL_SUCCESS, "got %d\n", ret ); + + ret = SQLFreeEnv( env ); + ok( ret == SQL_SUCCESS, "got %d\n", ret ); +} + +static void test_SQLBrowseConnect( void ) +{ + SQLHENV env; + SQLHDBC con; + SQLRETURN ret; + SQLSMALLINT len; + SQLCHAR str[256]; + + ret = SQLAllocEnv( &env ); + ok( ret == SQL_SUCCESS, "got %d\n", ret ); + + ret = SQLAllocConnect( env, &con ); + ok( ret == SQL_SUCCESS, "got %d\n", ret ); + + len = 0; + str[0] = 0; + ret = SQLBrowseConnect( con, (SQLCHAR *)"DSN=winetest", 12, str, sizeof(str), &len ); + if (ret == SQL_ERROR) diag( con, SQL_HANDLE_DBC ); + if (ret != SQL_SUCCESS) + { + SQLFreeConnect( con ); + SQLFreeEnv( env ); + skip( "data source winetest not available\n" ); + return; + }
ret = SQLDisconnect( con ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); @@ -151,13 +227,19 @@ static void test_SQLDataSources( void ) memset( desc, 0, sizeof(desc) ); ret = SQLDataSources( env, SQL_FETCH_FIRST, server, sizeof(server), &len, desc, sizeof(desc), &len2 ); ok( ret == SQL_SUCCESS || ret == SQL_NO_DATA, "got %d\n", ret ); - if (ret == SQL_SUCCESS) + while (ret == SQL_SUCCESS) { - ok( len, "unexpected len\n" ); - ok( len2, "unexpected len\n" ); + ok( len == strlen((const char *)server), "unexpected len\n" ); + ok( len2 == strlen((const char *)desc), "unexpected len\n" ); ok( server[0], "empty string\n" ); ok( desc[0], "empty string\n" ); trace( "server %s len %d desc %s len %d\n", server, len, desc, len2 ); + + len = len2 = -1; + memset( server, 0, sizeof(server) ); + memset( desc, 0, sizeof(desc) ); + ret = SQLDataSources( env, SQL_FETCH_NEXT, server, sizeof(server), &len, desc, sizeof(desc), &len2 ); + ok( ret == SQL_SUCCESS || ret == SQL_NO_DATA, "got %d\n", ret ); }
ret = SQLFreeEnv( env ); @@ -179,12 +261,25 @@ static void test_SQLDrivers( void ) memset( attrs, 0, sizeof(attrs) ); ret = SQLDrivers( env, SQL_FETCH_FIRST, desc, sizeof(desc), &len, attrs, sizeof(attrs), &len2 ); ok( ret == SQL_SUCCESS || ret == SQL_NO_DATA, "got %d\n", ret ); - if (ret == SQL_SUCCESS) + while (ret == SQL_SUCCESS) { - ok( len, "unexpected len\n" ); - ok( len2, "unexpected len\n" ); + SQLCHAR *ptr; + + trace( "desc %s len %d len2 %d\n", desc, len, len2 ); + ok( len == strlen((const char *)desc), "unexpected len %u\n", len ); ok( desc[0], "empty string\n" ); - trace( "desc %s len %d\n", desc, len ); + ptr = attrs; + while (*ptr) + { + trace( " attr %s\n", ptr ); + ptr += strlen( (const char *)ptr ) + 1; + } + + len = len2 = 0; + memset( desc, 0, sizeof(desc) ); + memset( attrs, 0, sizeof(attrs) ); + ret = SQLDrivers( env, SQL_FETCH_NEXT, desc, sizeof(desc), &len, attrs, sizeof(attrs), &len2 ); + ok( ret == SQL_SUCCESS || ret == SQL_NO_DATA, "got %d\n", ret ); }
ret = SQLFreeEnv( env ); @@ -208,7 +303,8 @@ static void test_SQLExecDirect( void ) ret = SQLAllocConnect( env, &con ); ok( ret == SQL_SUCCESS, "got %d\n", ret );
- ret = SQLConnect( con, (SQLCHAR *)"winetest", 8, NULL, 0, NULL, 0 ); + ret = SQLConnect( con, (SQLCHAR *)"winetest", 8, (SQLCHAR *)"winetest", 8, (SQLCHAR *)"winetest", 8 ); + if (ret == SQL_ERROR) diag( con, SQL_HANDLE_DBC ); if (ret != SQL_SUCCESS) { SQLFreeConnect( con ); @@ -221,9 +317,11 @@ static void test_SQLExecDirect( void ) ret = SQLAllocStmt( con, &stmt ); ok( ret == SQL_SUCCESS, "got %d\n", ret );
+ SQLExecDirect( stmt, (SQLCHAR *)"USE winetest", ARRAYSIZE("USE winetest") - 1 ); SQLExecDirect( stmt, (SQLCHAR *)"DROP TABLE winetest", ARRAYSIZE("DROP TABLE winetest") - 1 ); ret = SQLExecDirect( stmt, (SQLCHAR *)"CREATE TABLE winetest ( Id int, Name varchar(255) )", ARRAYSIZE("CREATE TABLE winetest ( Id int, Name varchar(255) )") - 1 ); + if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT ); ok( ret == SQL_SUCCESS, "got %d\n", ret ); if (ret == SQL_ERROR) diag( stmt, SQL_HANDLE_STMT );
@@ -361,6 +459,8 @@ START_TEST(odbc32) { test_SQLAllocHandle(); test_SQLConnect(); + test_SQLDriverConnect(); + test_SQLBrowseConnect(); test_SQLDataSources(); test_SQLDrivers(); test_SQLExecDirect();
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146873
Your paranoid android.
=== debian11 (32 bit report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
=== debian11 (32 bit ar:MA report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
=== debian11 (32 bit de report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
=== debian11 (32 bit fr report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
=== debian11 (32 bit he:IL report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
=== debian11 (32 bit hi:IN report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
=== debian11 (32 bit ja:JP report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
=== debian11 (32 bit zh:CN report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
=== debian11b (32 bit WoW report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
=== debian11b (64 bit WoW report) ===
odbc32: odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1 odbc32.c:77: Test failed: got -1
user32: win.c:4037: Test failed: Expected active window 00000000028B016C, got 000000000173016E. win.c:4038: Test failed: Expected focus window 00000000028B016C, got 000000000173016E.