From 64af6ff6f7ac46823bc98e5b70bff87c46652aab Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Sat, 4 Feb 2023 09:16:29 +1100 Subject: [PATCH] odbc32: Implement SQLDriverConnectW --- dlls/odbc32/proxyodbc.c | 367 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 365 insertions(+), 2 deletions(-) diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c index 070f0197742..30baf1866a4 100644 --- a/dlls/odbc32/proxyodbc.c +++ b/dlls/odbc32/proxyodbc.c @@ -53,10 +53,248 @@ struct SQLHDBC_data { int type; struct SQLHENV_data *environment; + HMODULE module; + SQLHENV driver_env; + SQLINTEGER driver_ver; /* ODBC version supported by driver */ + SQLHDBC driver_hdbc; + + SQLRETURN (WINAPI *pSQLAllocConnect)(SQLHENV,SQLHDBC*); + SQLRETURN (WINAPI *pSQLAllocEnv)(SQLHENV*); + SQLRETURN (WINAPI *pSQLAllocHandle)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*); + SQLRETURN (WINAPI *pSQLAllocHandleStd)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*); + SQLRETURN (WINAPI *pSQLAllocStmt)(SQLHDBC,SQLHSTMT*); + SQLRETURN (WINAPI *pSQLBindCol)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*); + SQLRETURN (WINAPI *pSQLBindParam)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN*); + SQLRETURN (WINAPI *pSQLBindParameter)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*); + SQLRETURN (WINAPI *pSQLBrowseConnect)(SQLHDBC,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLBrowseConnectW)(SQLHDBC,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLBulkOperations)(SQLHSTMT,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLCancel)(SQLHSTMT); + SQLRETURN (WINAPI *pSQLCloseCursor)(SQLHSTMT); + SQLRETURN (WINAPI *pSQLColAttribute)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*,SQLLEN*); + SQLRETURN (WINAPI *pSQLColAttributeW)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*,SQLLEN*); + SQLRETURN (WINAPI *pSQLColAttributes)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*,SQLLEN*); + SQLRETURN (WINAPI *pSQLColAttributesW)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*,SQLLEN*); + SQLRETURN (WINAPI *pSQLColumnPrivileges)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLColumnPrivilegesW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLColumns)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLColumnsW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLConnect)(SQLHDBC,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLConnectW)(SQLHDBC,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLCopyDesc)(SQLHDESC,SQLHDESC); + SQLRETURN (WINAPI *pSQLDescribeCol)(SQLHSTMT,SQLUSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLULEN*,SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLDescribeColW)(SQLHSTMT,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLULEN*,SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLDescribeParam)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT*,SQLULEN*,SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLDisconnect)(SQLHDBC); + SQLRETURN (WINAPI *pSQLDriverConnect)(SQLHDBC,SQLHWND,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLUSMALLINT); + SQLRETURN (WINAPI *pSQLDriverConnectW)(SQLHDBC,SQLHWND,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLUSMALLINT); + SQLRETURN (WINAPI *pSQLEndTran)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLError)(SQLHENV,SQLHDBC,SQLHSTMT,SQLCHAR*,SQLINTEGER*,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLErrorW)(SQLHENV,SQLHDBC,SQLHSTMT,SQLWCHAR*,SQLINTEGER*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLExecDirect)(SQLHSTMT,SQLCHAR*,SQLINTEGER); + SQLRETURN (WINAPI *pSQLExecDirectW)(SQLHSTMT,SQLWCHAR*,SQLINTEGER); + SQLRETURN (WINAPI *pSQLExecute)(SQLHSTMT); + SQLRETURN (WINAPI *pSQLExtendedFetch)(SQLHSTMT,SQLUSMALLINT,SQLLEN,SQLULEN*,SQLUSMALLINT*); + SQLRETURN (WINAPI *pSQLFetch)(SQLHSTMT); + SQLRETURN (WINAPI *pSQLFetchScroll)(SQLHSTMT,SQLSMALLINT,SQLLEN); + SQLRETURN (WINAPI *pSQLForeignKeys)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLForeignKeysW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLFreeConnect)(SQLHDBC); + SQLRETURN (WINAPI *pSQLFreeEnv)(SQLHENV); + SQLRETURN (WINAPI *pSQLFreeHandle)(SQLSMALLINT,SQLHANDLE); + SQLRETURN (WINAPI *pSQLFreeStmt)(SQLHSTMT,SQLUSMALLINT); + SQLRETURN (WINAPI *pSQLGetConnectAttr)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN (WINAPI *pSQLGetConnectAttrW)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN (WINAPI *pSQLGetConnectOption)(SQLHDBC,SQLUSMALLINT,SQLPOINTER); + SQLRETURN (WINAPI *pSQLGetConnectOptionW)(SQLHDBC,SQLUSMALLINT,SQLPOINTER); + SQLRETURN (WINAPI *pSQLGetCursorName)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetCursorNameW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetData)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*); + SQLRETURN (WINAPI *pSQLGetDescField)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN (WINAPI *pSQLGetDescFieldW)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN (WINAPI *pSQLGetDescRec)(SQLHDESC,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*,SQLLEN*,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetDescRecW)(SQLHDESC,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*,SQLLEN*,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetDiagField)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetDiagFieldW)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetDiagRec)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLCHAR*,SQLINTEGER*,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetDiagRecA)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLCHAR*,SQLINTEGER*, SQLCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetDiagRecW)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLWCHAR*,SQLINTEGER*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetEnvAttr)(SQLHENV,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN (WINAPI *pSQLGetFunctions)(SQLHDBC,SQLUSMALLINT,SQLUSMALLINT*); + SQLRETURN (WINAPI *pSQLGetInfo)(SQLHDBC,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetInfoW)(SQLHDBC,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLGetStmtAttr)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN (WINAPI *pSQLGetStmtAttrW)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*); + SQLRETURN (WINAPI *pSQLGetStmtOption)(SQLHSTMT,SQLUSMALLINT,SQLPOINTER); + SQLRETURN (WINAPI *pSQLGetTypeInfo)(SQLHSTMT,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLGetTypeInfoW)(SQLHSTMT,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLMoreResults)(SQLHSTMT); + SQLRETURN (WINAPI *pSQLNativeSql)(SQLHDBC,SQLCHAR*,SQLINTEGER,SQLCHAR*,SQLINTEGER,SQLINTEGER*); + SQLRETURN (WINAPI *pSQLNativeSqlW)(SQLHDBC,SQLWCHAR*,SQLINTEGER,SQLWCHAR*,SQLINTEGER,SQLINTEGER*); + SQLRETURN (WINAPI *pSQLNumParams)(SQLHSTMT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLNumResultCols)(SQLHSTMT,SQLSMALLINT*); + SQLRETURN (WINAPI *pSQLParamData)(SQLHSTMT,SQLPOINTER*); + SQLRETURN (WINAPI *pSQLParamOptions)(SQLHSTMT,SQLULEN,SQLULEN*); + SQLRETURN (WINAPI *pSQLPrepare)(SQLHSTMT,SQLCHAR*,SQLINTEGER); + SQLRETURN (WINAPI *pSQLPrepareW)(SQLHSTMT,SQLWCHAR*,SQLINTEGER); + SQLRETURN (WINAPI *pSQLPrimaryKeys)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLPrimaryKeysW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLProcedureColumns)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLProcedureColumnsW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLProcedures)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLProceduresW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLPutData)(SQLHSTMT,SQLPOINTER,SQLLEN); + SQLRETURN (WINAPI *pSQLRowCount)(SQLHSTMT,SQLLEN*); + SQLRETURN (WINAPI *pSQLSetConnectAttr)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN (WINAPI *pSQLSetConnectAttrW)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN (WINAPI *pSQLSetConnectOption)(SQLHDBC,SQLUSMALLINT,SQLULEN); + SQLRETURN (WINAPI *pSQLSetConnectOptionW)(SQLHDBC,SQLUSMALLINT,SQLULEN); + SQLRETURN (WINAPI *pSQLSetCursorName)(SQLHSTMT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLSetCursorNameW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLSetDescField)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER); + SQLRETURN (WINAPI *pSQLSetDescFieldW)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER); + SQLRETURN (WINAPI *pSQLSetDescRec)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLLEN,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN*,SQLLEN*); + SQLRETURN (WINAPI *pSQLSetEnvAttr)(SQLHENV,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN (WINAPI *pSQLSetParam)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN*); + SQLRETURN (WINAPI *pSQLSetPos)(SQLHSTMT,SQLSETPOSIROW,SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN (WINAPI *pSQLSetScrollOptions)(SQLHSTMT,SQLUSMALLINT,SQLLEN,SQLUSMALLINT); + SQLRETURN (WINAPI *pSQLSetStmtAttr)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN (WINAPI *pSQLSetStmtAttrW)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER); + SQLRETURN (WINAPI *pSQLSetStmtOption)(SQLHSTMT,SQLUSMALLINT,SQLULEN); + SQLRETURN (WINAPI *pSQLSpecialColumns)(SQLHSTMT,SQLUSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN (WINAPI *pSQLSpecialColumnsW)(SQLHSTMT,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN (WINAPI *pSQLStatistics)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN (WINAPI *pSQLStatisticsW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT); + SQLRETURN (WINAPI *pSQLTablePrivileges)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLTablePrivilegesW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLTables)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLTablesW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT); + SQLRETURN (WINAPI *pSQLTransact)(SQLHENV,SQLHDBC,SQLUSMALLINT); SQLUINTEGER login_timeout; }; +static void connection_bind_sql_funcs(struct SQLHDBC_data *connection) +{ +#define LOAD_FUNCPTR(f) if((connection->p##f = (void*)GetProcAddress(connection->module, #f)) == NULL) \ + { \ + WARN( "function '%s' not found in driver.\n", #f ); \ + } + + LOAD_FUNCPTR(SQLAllocConnect); + LOAD_FUNCPTR(SQLAllocEnv); + LOAD_FUNCPTR(SQLAllocHandle); + LOAD_FUNCPTR(SQLAllocHandleStd) + LOAD_FUNCPTR(SQLAllocStmt); + LOAD_FUNCPTR(SQLBindCol); + LOAD_FUNCPTR(SQLBindParam); + 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(SQLGetDiagRecA); + 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); +} + /************************************************************************* * SQLAllocConnect [ODBC32.001] */ @@ -77,6 +315,7 @@ SQLRETURN WINAPI SQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC *ConnectionH hdbc->type = SQL_HANDLE_DBC; hdbc->environment = EnvironmentHandle; hdbc->login_timeout = 0; + hdbc->module = NULL; *ConnectionHandle = hdbc; @@ -438,6 +677,8 @@ SQLRETURN WINAPI SQLFreeConnect(SQLHDBC ConnectionHandle) return SQL_ERROR; } + FreeLibrary(hdbc->module); + free(hdbc); return SQL_SUCCESS; @@ -1596,6 +1837,65 @@ SQLRETURN WINAPI SQLColumnsW(SQLHSTMT StatementHandle, WCHAR *CatalogName, SQLSM return ret; } +static HMODULE load_odbc_driver(const WCHAR *driver, BOOL use_dsn) +{ + long ret; + HMODULE hmod; + WCHAR *filename = NULL; + HKEY hkey; + WCHAR regpath[256]; + + if (use_dsn) + wcscpy(regpath, L"Software\\ODBC\\ODBC.INI\\"); + else + wcscpy(regpath, L"Software\\ODBC\\ODBCINST.INI\\"); + wcscat(regpath, driver); + + if ((ret = RegOpenKeyW(HKEY_CURRENT_USER, regpath, &hkey)) != ERROR_SUCCESS) + { + ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, regpath, &hkey); + } + + if (ret == ERROR_SUCCESS) + { + DWORD size = 0, type; + ret = RegGetValueW(hkey, NULL, L"Driver", RRF_RT_REG_SZ, &type, NULL, &size); + if(ret != ERROR_SUCCESS || type != REG_SZ) + { + RegCloseKey(hkey); + WARN("Invalid DSN %s\n", debugstr_w(driver)); + + return NULL; + } + + filename = malloc(size); + if(!filename) + { + RegCloseKey(hkey); + ERR("Out of memory\n"); + + return NULL; + } + ret = RegGetValueW(hkey, NULL, L"Driver", RRF_RT_REG_SZ, &type, filename, &size); + + RegCloseKey(hkey); + } + + if(ret != ERROR_SUCCESS) + { + free(filename); + ERR("Failed to open Registry Key\n"); + return NULL; + } + + hmod = LoadLibraryExW(filename, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + free(filename); + + if(!hmod) + ERR("Failed to load driver\n"); + + return hmod; +} /************************************************************************* * SQLDriverConnectW [ODBC32.141] */ @@ -1603,13 +1903,76 @@ SQLRETURN WINAPI SQLDriverConnectW(SQLHDBC ConnectionHandle, SQLHWND WindowHandl SQLSMALLINT Length, WCHAR *OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *Length2, SQLUSMALLINT DriverCompletion) { + struct SQLHDBC_data *connection = ConnectionHandle; + HMODULE driver; SQLRETURN ret = SQL_ERROR; + WCHAR dsn[128]; + WCHAR *p; + BOOL is_dsn = TRUE; - FIXME("(ConnectionHandle %p, WindowHandle %p, InConnectionString %s, Length %d, OutConnectionString %p," + TRACE("(ConnectionHandle %p, WindowHandle %p, InConnectionString %s, Length %d, OutConnectionString %p," " BufferLength %d, Length2 %p, DriverCompletion %d)\n", ConnectionHandle, WindowHandle, - debugstr_wn(InConnectionString, Length), Length, OutConnectionString, BufferLength, Length2, + Length == SQL_NTS ? debugstr_w(InConnectionString) : debugstr_wn(InConnectionString, Length), Length, OutConnectionString, BufferLength, Length2, DriverCompletion); + p = wcsstr(InConnectionString, L"DSN="); + if (p) + { + WCHAR *end = wcsstr(p, L";"); + + lstrcpynW(dsn, p+4, end - (p + 3)); + } + else + { + p = wcsstr(InConnectionString, L"Driver="); + if (p) + { + WCHAR *end = wcsstr(p, L";"); + + lstrcpynW(dsn, p+7, end - (p + 6)); + is_dsn = FALSE; + } + } + + driver = load_odbc_driver(dsn, is_dsn); + if (!driver) + return SQL_ERROR; + + connection->module = driver; + connection->driver_ver = SQL_OV_ODBC2; + connection_bind_sql_funcs(connection); + + /* ODBC 3.x */ + if (connection->pSQLAllocHandle) + { + connection->pSQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &connection->driver_env); + connection->pSQLAllocHandle(SQL_HANDLE_DBC, connection->driver_env, &connection->driver_hdbc); + + if (connection->pSQLGetEnvAttr) + connection->pSQLGetEnvAttr(connection->driver_env, SQL_ATTR_ODBC_VERSION, &connection->driver_ver, 0, NULL); + + } + /* ODBC 2.x */ + else if(connection->pSQLAllocConnect && connection->pSQLAllocEnv) + { + connection->pSQLAllocEnv(&connection->driver_env); + + connection->pSQLAllocConnect(connection->driver_env, &connection->driver_hdbc); + } + else + ERR("No functions to allocated Environment handles found.\n"); + + if(!connection->pSQLDriverConnectW) + { + ERR("Failed to find pSQLDriverConnectW\n"); + return SQL_ERROR; + } + + ret = connection->pSQLDriverConnectW(connection->driver_hdbc, WindowHandle, InConnectionString, Length, + OutConnectionString, BufferLength, Length2, DriverCompletion); + + TRACE("Driver returned %d\n", ret); + return ret; } -- 2.43.0