From: Hans Leidekker hans@codeweavers.com
--- dlls/odbc32/proxyodbc.c | 112 ++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 39 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index 9dea285b6ee..ccd17909461 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -40,7 +40,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(odbc);
#define ODBC_CALL( func, params ) WINE_UNIX_CALL( unix_ ## func, params )
-static BOOL is_wow64; +static BOOL is_wow64, is_old_wow64;
struct win32_funcs { @@ -777,25 +777,33 @@ static BOOL alloc_binding( struct param_binding *binding, USHORT type, UINT colu static SQLRETURN bind_col_unix( struct statement *stmt, SQLUSMALLINT column, SQLSMALLINT type, SQLPOINTER value, SQLLEN buflen, SQLLEN *retlen ) { - struct SQLBindCol_params params = { stmt->hdr.unix_handle, column, type, value, buflen }; - UINT i = column - 1; - SQLRETURN ret; - - if (!column) + if (is_wow64 && !is_old_wow64) { - FIXME( "column 0 not handled\n" ); - return SQL_ERROR; - } + struct SQLBindCol_params params = { stmt->hdr.unix_handle, column, type, value, buflen }; + UINT i = column - 1; + SQLRETURN ret;
- if (!alloc_binding( &stmt->bind_col, SQL_PARAM_INPUT_OUTPUT, column, stmt->row_count )) - return SQL_ERROR; - stmt->bind_col.param[i].col.target_type = type; - stmt->bind_col.param[i].col.target_value = value; - stmt->bind_col.param[i].col.buffer_length = buflen; + if (!column) + { + FIXME( "column 0 not handled\n" ); + return SQL_ERROR; + }
- if (retlen) params.StrLen_or_Ind = stmt->bind_col.param[i].len; - if (SUCCESS(( ret = ODBC_CALL( SQLBindCol, ¶ms )))) stmt->bind_col.param[i].ptr = retlen; - return ret; + if (!alloc_binding( &stmt->bind_col, SQL_PARAM_INPUT_OUTPUT, column, stmt->row_count )) + return SQL_ERROR; + stmt->bind_col.param[i].col.target_type = type; + stmt->bind_col.param[i].col.target_value = value; + stmt->bind_col.param[i].col.buffer_length = buflen; + + if (retlen) params.StrLen_or_Ind = stmt->bind_col.param[i].len; + if (SUCCESS(( ret = ODBC_CALL( SQLBindCol, ¶ms )))) stmt->bind_col.param[i].ptr = retlen; + return ret; + } + else + { + struct SQLBindCol_params params = { stmt->hdr.unix_handle, column, type, value, buflen, retlen }; + return ODBC_CALL( SQLBindCol, ¶ms ); + } }
static SQLRETURN bind_col_win32( struct statement *stmt, SQLUSMALLINT column, SQLSMALLINT type, SQLPOINTER value, @@ -1856,7 +1864,9 @@ static void len_from_user( UINT8 *len, SQLLEN *ptr, UINT row_count, UINT width )
static void update_result_lengths( struct statement *stmt, USHORT type ) { - UINT i, width = sizeof(void *) == 8 ? 8 : is_wow64 ? 8 : 4; + UINT i, width = is_old_wow64 ? 4 : 8; + + if (!is_wow64 || is_old_wow64) return;
switch (type) { @@ -3839,6 +3849,11 @@ SQLRETURN WINAPI SQLSetParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNum static BOOL resize_result_lengths( struct statement *stmt, UINT size ) { UINT i; + + if (!is_wow64 || is_old_wow64) return TRUE; + + TRACE( "resizing result length array\n" ); + for (i = 0; i < stmt->bind_col.count; i++) { UINT8 *tmp; @@ -3862,6 +3877,7 @@ static BOOL resize_result_lengths( struct statement *stmt, UINT size ) } stmt->bind_col.param[i].len = tmp; } + for (i = 0; i < stmt->bind_parameter.count; i++) { UINT8 *tmp; @@ -3901,7 +3917,6 @@ static SQLRETURN set_stmt_attr_unix_a( struct statement *stmt, SQLINTEGER attr, SQLULEN row_count = (SQLULEN)value; if (attr == SQL_ATTR_ROW_ARRAY_SIZE && row_count != stmt->row_count) { - TRACE( "resizing result length array\n" ); if (!resize_result_lengths( stmt, row_count )) ret = SQL_ERROR; else stmt->row_count = row_count; } @@ -5469,29 +5484,38 @@ static SQLRETURN bind_parameter_unix( struct statement *stmt, SQLUSMALLINT param SQLSMALLINT value_type, SQLSMALLINT param_type, SQLULEN size, SQLSMALLINT digits, SQLPOINTER value, SQLLEN buflen, SQLLEN *len ) { - struct SQLBindParameter_params params = { stmt->hdr.unix_handle, param, io_type, value_type, param_type, size, - digits, value, buflen }; - UINT i = param - 1; - SQLRETURN ret; + if (is_wow64 && !is_old_wow64) + { + struct SQLBindParameter_params params = { stmt->hdr.unix_handle, param, io_type, value_type, param_type, + size, digits, value, buflen }; + UINT i = param - 1; + SQLRETURN ret;
- if (!param) + if (!param) + { + FIXME( "parameter 0 not handled\n" ); + return SQL_ERROR; + } + if (!alloc_binding( &stmt->bind_parameter, io_type, param, stmt->row_count )) return SQL_ERROR; + stmt->bind_parameter.param[i].parameter.input_output_type = io_type; + stmt->bind_parameter.param[i].parameter.value_type = value_type; + stmt->bind_parameter.param[i].parameter.parameter_type = param_type; + stmt->bind_parameter.param[i].parameter.column_size = size; + stmt->bind_parameter.param[i].parameter.decimal_digits = digits; + stmt->bind_parameter.param[i].parameter.parameter_value = value; + stmt->bind_parameter.param[i].parameter.buffer_length = buflen; + + params.StrLen_or_Ind = stmt->bind_parameter.param[i].len; + *(UINT64 *)params.StrLen_or_Ind = *len; + if (SUCCESS((ret = ODBC_CALL( SQLBindParameter, ¶ms )))) stmt->bind_parameter.param[i].ptr = len; + return ret; + } + else { - FIXME( "parameter 0 not handled\n" ); - return SQL_ERROR; + struct SQLBindParameter_params params = { stmt->hdr.unix_handle, param, io_type, value_type, param_type, + size, digits, value, buflen, len }; + return ODBC_CALL( SQLBindParameter, ¶ms ); } - if (!alloc_binding( &stmt->bind_parameter, io_type, param, stmt->row_count )) return SQL_ERROR; - stmt->bind_parameter.param[i].parameter.input_output_type = io_type; - stmt->bind_parameter.param[i].parameter.value_type = value_type; - stmt->bind_parameter.param[i].parameter.parameter_type = param_type; - stmt->bind_parameter.param[i].parameter.column_size = size; - stmt->bind_parameter.param[i].parameter.decimal_digits = digits; - stmt->bind_parameter.param[i].parameter.parameter_value = value; - stmt->bind_parameter.param[i].parameter.buffer_length = buflen; - - params.StrLen_or_Ind = stmt->bind_parameter.param[i].len; - *(UINT64 *)params.StrLen_or_Ind = *len; - if (SUCCESS((ret = ODBC_CALL( SQLBindParameter, ¶ms )))) stmt->bind_parameter.param[i].ptr = len; - return ret; }
static SQLRETURN bind_parameter_win32( struct statement *stmt, SQLUSMALLINT param, SQLSMALLINT io_type, @@ -7914,7 +7938,17 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved) { if (WINE_UNIX_CALL( process_attach, NULL )) __wine_unixlib_handle = 0; } + IsWow64Process( GetCurrentProcess(), &is_wow64 ); + if (is_wow64) + { + TEB64 *teb64 = ULongToPtr( NtCurrentTeb()->GdiBatchCount ); + if (teb64) + { + PEB64 *peb64 = ULongToPtr( teb64->Peb ); + is_old_wow64 = !peb64->LdrData; + } + } break;
case DLL_PROCESS_DETACH: