Pointers can be filled after the call to SQLBindParameter() so it needs to be read at SQLExecute().
From: Daniel Lehman dlehman@esri.com
Pointers can be filled after the call to SQLBindParameter() so it needs to be read at SQLExecute(). --- dlls/odbc32/proxyodbc.c | 119 ++++++++++++++++++++++++---------------- dlls/odbc32/unixlib.h | 1 + 2 files changed, 72 insertions(+), 48 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index 658dda29a6c..ab89c93a4a8 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -198,7 +198,7 @@ static const char *debugstr_sqllen( SQLLEN len ) }
#define MAX_BINDING_PARAMS 1024 -static BOOL alloc_binding( struct param_binding *binding, UINT column, UINT row_count ) +static BOOL alloc_binding( struct param_binding *binding, USHORT type, UINT column, UINT row_count ) { if (column > MAX_BINDING_PARAMS) { @@ -208,6 +208,7 @@ static BOOL alloc_binding( struct param_binding *binding, UINT column, UINT row_ if (!binding->param && !(binding->param = calloc( MAX_BINDING_PARAMS, sizeof(*binding->param)))) return FALSE;
if (!(binding->param[column - 1].len = calloc( row_count, sizeof(UINT64) ))) return FALSE; + binding->param[column - 1].type = type; binding->count = column; return TRUE; } @@ -232,7 +233,7 @@ SQLRETURN WINAPI SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, FIXME( "column 0 not handled\n" ); return SQL_ERROR; } - if (!alloc_binding( &handle->bind_col, ColumnNumber, handle->row_count )) return SQL_ERROR; + if (!alloc_binding( &handle->bind_col, SQL_PARAM_INPUT_OUTPUT, ColumnNumber, handle->row_count )) return SQL_ERROR; params.StatementHandle = handle->unix_handle; params.StrLen_or_Ind = handle->bind_col.param[i].len; *(UINT64 *)params.StrLen_or_Ind = *StrLen_or_Ind; @@ -273,7 +274,7 @@ SQLRETURN WINAPI SQLBindParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNu FIXME( "parameter 0 not handled\n" ); return SQL_ERROR; } - if (!alloc_binding( &handle->bind_param, ParameterNumber, handle->row_count )) return SQL_ERROR; + if (!alloc_binding( &handle->bind_param, SQL_PARAM_INPUT, ParameterNumber, handle->row_count )) return SQL_ERROR;
params.StatementHandle = handle->unix_handle; params.StrLen_or_Ind = handle->bind_param.param[i].len; @@ -586,6 +587,66 @@ SQLRETURN WINAPI SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR *StatementText, return ret; }
+static void len_to_user( SQLLEN *ptr, UINT8 *len, UINT row_count, UINT width ) +{ + UINT i; + for (i = 0; i < row_count; i++) + { + *ptr++ = *(SQLLEN *)(len + i * width); + } +} + +static void len_from_user( UINT8 *len, SQLLEN *ptr, UINT row_count, UINT width ) +{ + UINT i; + for (i = 0; i < row_count; i++) + { + *(SQLLEN *)(len + i * width) = *ptr++; + } +} + +static void update_result_lengths( struct handle *handle, USHORT type ) +{ + UINT i, width = sizeof(void *) == 8 ? 8 : is_wow64 ? 8 : 4; + + switch (type) + { + case SQL_PARAM_OUTPUT: + for (i = 0; i < handle->bind_col.count; i++) + { + 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 && + handle->bind_parameter.param[i].type != SQL_PARAM_INPUT_OUTPUT) continue; + + len_to_user( handle->bind_parameter.param[i].ptr, handle->bind_parameter.param[i].len, handle->row_count, width ); + } + break; + + case SQL_PARAM_INPUT: + for (i = 0; i < handle->bind_col.count; i++) + { + 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 && + handle->bind_parameter.param[i].type != SQL_PARAM_INPUT_OUTPUT) continue; + + len_from_user( handle->bind_parameter.param[i].len, handle->bind_parameter.param[i].ptr, handle->row_count, width ); + } + + default: break; + } +} + /************************************************************************* * SQLExecute [ODBC32.012] */ @@ -600,50 +661,12 @@ SQLRETURN WINAPI SQLExecute(SQLHSTMT StatementHandle) if (!handle) return SQL_INVALID_HANDLE;
params.StatementHandle = handle->unix_handle; - ret = ODBC_CALL( SQLExecute, ¶ms ); + update_result_lengths( handle, SQL_PARAM_INPUT ); + if (SUCCESS(( ret = ODBC_CALL( SQLExecute, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); TRACE("Returning %d\n", ret); return ret; }
-static void update_result_lengths( struct handle *handle ) -{ - UINT i, j, width = sizeof(void *) == 8 ? 8 : is_wow64 ? 8 : 4; - - for (i = 0; i < handle->bind_col.count; i++) - { - SQLLEN *ptr = handle->bind_col.param[i].ptr; - if (ptr) - { - for (j = 0; j < handle->row_count; j++) - { - *ptr++ = *(SQLLEN *)(handle->bind_col.param[i].len + j * width); - } - } - } - for (i = 0; i < handle->bind_param.count; i++) - { - SQLLEN *ptr = handle->bind_param.param[i].ptr; - if (ptr) - { - for (j = 0; j < handle->row_count; j++) - { - *ptr++ = *(SQLLEN *)(handle->bind_param.param[i].len + j * width); - } - } - } - for (i = 0; i < handle->bind_parameter.count; i++) - { - SQLLEN *ptr = handle->bind_parameter.param[i].ptr; - if (ptr) - { - for (j = 0; j < handle->row_count; j++) - { - *ptr++ = *(SQLLEN *)(handle->bind_parameter.param[i].len + j * width); - } - } - } -} - /************************************************************************* * SQLFetch [ODBC32.013] */ @@ -658,7 +681,7 @@ SQLRETURN WINAPI SQLFetch(SQLHSTMT StatementHandle) if (!handle) return SQL_INVALID_HANDLE;
params.StatementHandle = handle->unix_handle; - if (SUCCESS(( ret = ODBC_CALL( SQLFetch, ¶ms )))) update_result_lengths( handle ); + if (SUCCESS(( ret = ODBC_CALL( SQLFetch, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); TRACE("Returning %d\n", ret); return ret; } @@ -678,7 +701,7 @@ SQLRETURN WINAPI SQLFetchScroll(SQLHSTMT StatementHandle, SQLSMALLINT FetchOrien if (!handle) return SQL_INVALID_HANDLE;
params.StatementHandle = handle->unix_handle; - if (SUCCESS(( ret = ODBC_CALL( SQLFetchScroll, ¶ms )))) update_result_lengths( handle ); + if (SUCCESS(( ret = ODBC_CALL( SQLFetchScroll, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); TRACE("Returning %d\n", ret); return ret; } @@ -1560,7 +1583,7 @@ SQLRETURN WINAPI SQLBulkOperations(SQLHSTMT StatementHandle, SQLSMALLINT Operati if (!handle) return SQL_INVALID_HANDLE;
params.StatementHandle = handle->unix_handle; - if (SUCCESS(( ret = ODBC_CALL( SQLBulkOperations, ¶ms )))) update_result_lengths( handle ); + if (SUCCESS(( ret = ODBC_CALL( SQLBulkOperations, ¶ms )))) update_result_lengths( handle, SQL_PARAM_OUTPUT ); TRACE("Returning %d\n", ret); return ret; } @@ -1876,7 +1899,7 @@ SQLRETURN WINAPI SQLSetPos(SQLHSTMT StatementHandle, SQLSETPOSIROW RowNumber, SQ
params.StatementHandle = handle->unix_handle; if (SUCCESS(( ret = ODBC_CALL( SQLSetPos, ¶ms ))) && Operation == SQL_REFRESH) - update_result_lengths( handle ); + update_result_lengths( handle, SQL_PARAM_OUTPUT ); TRACE("Returning %d\n", ret); return ret; } @@ -1961,7 +1984,7 @@ SQLRETURN WINAPI SQLBindParameter(SQLHSTMT StatementHandle, SQLUSMALLINT Paramet FIXME( "parameter 0 not handled\n" ); return SQL_ERROR; } - if (!alloc_binding( &handle->bind_parameter, ParameterNumber, handle->row_count )) return SQL_ERROR; + if (!alloc_binding( &handle->bind_parameter, InputOutputType, ParameterNumber, handle->row_count )) return SQL_ERROR;
params.StatementHandle = handle->unix_handle; params.StrLen_or_Ind = handle->bind_parameter.param[i].len; diff --git a/dlls/odbc32/unixlib.h b/dlls/odbc32/unixlib.h index c021eb22c50..0c683340cbe 100644 --- a/dlls/odbc32/unixlib.h +++ b/dlls/odbc32/unixlib.h @@ -154,6 +154,7 @@ enum sql_funcs
struct param { + INT16 type; UINT8 *len; /* result length array stored in Unix lib */ void *ptr; /* result length ptr passed by client */ };
From: Daniel Lehman dlehman@esri.com
--- dlls/odbc32/proxyodbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index ab89c93a4a8..4b847b3b874 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -343,7 +343,7 @@ SQLRETURN WINAPI SQLColAttribute(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNu
params.StatementHandle = handle->unix_handle; params.NumericAttribute = &num_attr; - if (SUCCESS(( ret = ODBC_CALL( SQLColAttribute, ¶ms )))) *NumericAttribute = num_attr; + if (SUCCESS(( ret = ODBC_CALL( SQLColAttribute, ¶ms ))) && NumericAttribute) *NumericAttribute = num_attr; TRACE("Returning %d\n", ret); return ret; } @@ -2300,7 +2300,7 @@ SQLRETURN WINAPI SQLColAttributeW(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnN
params.StatementHandle = handle->unix_handle; params.NumericAttribute = &attr; - if (SUCCESS((ret = ODBC_CALL( SQLColAttributeW, ¶ms )))) *NumericAttribute = 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)
From: Daniel Lehman dlehman@esri.com
--- dlls/odbc32/proxyodbc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index 4b847b3b874..d97837e5bca 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -235,8 +235,7 @@ SQLRETURN WINAPI SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, } if (!alloc_binding( &handle->bind_col, SQL_PARAM_INPUT_OUTPUT, ColumnNumber, handle->row_count )) return SQL_ERROR; params.StatementHandle = handle->unix_handle; - params.StrLen_or_Ind = handle->bind_col.param[i].len; - *(UINT64 *)params.StrLen_or_Ind = *StrLen_or_Ind; + 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;
This merge request was approved by Hans Leidekker.