xref: /reactos/dll/win32/odbc32/proxyodbc.c (revision 1734f297)
1 /*
2  * Win32 ODBC functions
3  *
4  * Copyright 1999 Xiang Li, Corel Corporation
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * NOTES:
21  *   Proxy ODBC driver manager.  This manager delegates all ODBC
22  *   calls to a real ODBC driver manager named by the environment
23  *   variable LIB_ODBC_DRIVER_MANAGER, or to libodbc.so if the
24  *   variable is not set.
25  *
26  */
27 
28 #include "config.h"
29 #include "wine/port.h"
30 
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <assert.h>
36 
37 #include "windef.h"
38 #include "winbase.h"
39 #include "winreg.h"
40 #ifndef __REACTOS__
41 #include "wine/debug.h"
42 #endif
43 #include "wine/library.h"
44 #include "wine/unicode.h"
45 
46 #include "sql.h"
47 #include "sqltypes.h"
48 #include "sqlext.h"
49 
50 #ifdef __REACTOS__
51 #undef TRACE_ON
52 #include <wine/debug.h>
53 #endif
54 
55 static BOOL ODBC_LoadDriverManager(void);
56 static BOOL ODBC_LoadDMFunctions(void);
57 
58 WINE_DEFAULT_DEBUG_CHANNEL(odbc);
59 WINE_DECLARE_DEBUG_CHANNEL(winediag);
60 
61 static SQLRETURN (*pSQLAllocConnect)(SQLHENV,SQLHDBC*);
62 static SQLRETURN (*pSQLAllocEnv)(SQLHENV*);
63 static SQLRETURN (*pSQLAllocHandle)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*);
64 static SQLRETURN (*pSQLAllocHandleStd)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*);
65 static SQLRETURN (*pSQLAllocStmt)(SQLHDBC,SQLHSTMT*);
66 static SQLRETURN (*pSQLBindCol)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
67 static SQLRETURN (*pSQLBindParam)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN*);
68 static SQLRETURN (*pSQLBindParameter)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
69 static SQLRETURN (*pSQLBrowseConnect)(SQLHDBC,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*);
70 static SQLRETURN (*pSQLBrowseConnectW)(SQLHDBC,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
71 static SQLRETURN (*pSQLBulkOperations)(SQLHSTMT,SQLSMALLINT);
72 static SQLRETURN (*pSQLCancel)(SQLHSTMT);
73 static SQLRETURN (*pSQLCloseCursor)(SQLHSTMT);
74 static SQLRETURN (*pSQLColAttribute)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*,SQLLEN*);
75 static SQLRETURN (*pSQLColAttributeW)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*,SQLLEN*);
76 static SQLRETURN (*pSQLColAttributes)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*,SQLLEN*);
77 static SQLRETURN (*pSQLColAttributesW)(SQLHSTMT,SQLUSMALLINT,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*,SQLLEN*);
78 static SQLRETURN (*pSQLColumnPrivileges)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT);
79 static SQLRETURN (*pSQLColumnPrivilegesW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT);
80 static SQLRETURN (*pSQLColumns)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT);
81 static SQLRETURN (*pSQLColumnsW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT);
82 static SQLRETURN (*pSQLConnect)(SQLHDBC,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT);
83 static SQLRETURN (*pSQLConnectW)(SQLHDBC,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT);
84 static SQLRETURN (*pSQLCopyDesc)(SQLHDESC,SQLHDESC);
85 static SQLRETURN (*pSQLDataSources)(SQLHENV,SQLUSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*);
86 static SQLRETURN (*pSQLDataSourcesA)(SQLHENV,SQLUSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*);
87 static SQLRETURN (*pSQLDataSourcesW)(SQLHENV,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
88 static SQLRETURN (*pSQLDescribeCol)(SQLHSTMT,SQLUSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLULEN*,SQLSMALLINT*,SQLSMALLINT*);
89 static SQLRETURN (*pSQLDescribeColW)(SQLHSTMT,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLULEN*,SQLSMALLINT*,SQLSMALLINT*);
90 static SQLRETURN (*pSQLDescribeParam)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT*,SQLULEN*,SQLSMALLINT*,SQLSMALLINT*);
91 static SQLRETURN (*pSQLDisconnect)(SQLHDBC);
92 static SQLRETURN (*pSQLDriverConnect)(SQLHDBC,SQLHWND,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLUSMALLINT);
93 static SQLRETURN (*pSQLDriverConnectW)(SQLHDBC,SQLHWND,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLUSMALLINT);
94 static SQLRETURN (*pSQLDrivers)(SQLHENV,SQLUSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*);
95 static SQLRETURN (*pSQLDriversW)(SQLHENV,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
96 static SQLRETURN (*pSQLEndTran)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT);
97 static SQLRETURN (*pSQLError)(SQLHENV,SQLHDBC,SQLHSTMT,SQLCHAR*,SQLINTEGER*,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*);
98 static SQLRETURN (*pSQLErrorW)(SQLHENV,SQLHDBC,SQLHSTMT,SQLWCHAR*,SQLINTEGER*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
99 static SQLRETURN (*pSQLExecDirect)(SQLHSTMT,SQLCHAR*,SQLINTEGER);
100 static SQLRETURN (*pSQLExecDirectW)(SQLHSTMT,SQLWCHAR*,SQLINTEGER);
101 static SQLRETURN (*pSQLExecute)(SQLHSTMT);
102 static SQLRETURN (*pSQLExtendedFetch)(SQLHSTMT,SQLUSMALLINT,SQLLEN,SQLULEN*,SQLUSMALLINT*);
103 static SQLRETURN (*pSQLFetch)(SQLHSTMT);
104 static SQLRETURN (*pSQLFetchScroll)(SQLHSTMT,SQLSMALLINT,SQLLEN);
105 static SQLRETURN (*pSQLForeignKeys)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT);
106 static SQLRETURN (*pSQLForeignKeysW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT);
107 static SQLRETURN (*pSQLFreeConnect)(SQLHDBC);
108 static SQLRETURN (*pSQLFreeEnv)(SQLHENV);
109 static SQLRETURN (*pSQLFreeHandle)(SQLSMALLINT,SQLHANDLE);
110 static SQLRETURN (*pSQLFreeStmt)(SQLHSTMT,SQLUSMALLINT);
111 static SQLRETURN (*pSQLGetConnectAttr)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*);
112 static SQLRETURN (*pSQLGetConnectAttrW)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*);
113 static SQLRETURN (*pSQLGetConnectOption)(SQLHDBC,SQLUSMALLINT,SQLPOINTER);
114 static SQLRETURN (*pSQLGetConnectOptionW)(SQLHDBC,SQLUSMALLINT,SQLPOINTER);
115 static SQLRETURN (*pSQLGetCursorName)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*);
116 static SQLRETURN (*pSQLGetCursorNameW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
117 static SQLRETURN (*pSQLGetData)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
118 static SQLRETURN (*pSQLGetDescField)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER,SQLINTEGER*);
119 static SQLRETURN (*pSQLGetDescFieldW)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER,SQLINTEGER*);
120 static SQLRETURN (*pSQLGetDescRec)(SQLHDESC,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*,SQLLEN*,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*);
121 static SQLRETURN (*pSQLGetDescRecW)(SQLHDESC,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*,SQLLEN*,SQLSMALLINT*,SQLSMALLINT*,SQLSMALLINT*);
122 static SQLRETURN (*pSQLGetDiagField)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*);
123 static SQLRETURN (*pSQLGetDiagFieldW)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*);
124 static SQLRETURN (*pSQLGetDiagRec)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLCHAR*,SQLINTEGER*,SQLCHAR*,SQLSMALLINT,SQLSMALLINT*);
125 static SQLRETURN (*pSQLGetDiagRecW)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLWCHAR*,SQLINTEGER*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
126 static SQLRETURN (*pSQLGetEnvAttr)(SQLHENV,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*);
127 static SQLRETURN (*pSQLGetFunctions)(SQLHDBC,SQLUSMALLINT,SQLUSMALLINT*);
128 static SQLRETURN (*pSQLGetInfo)(SQLHDBC,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*);
129 static SQLRETURN (*pSQLGetInfoW)(SQLHDBC,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*);
130 static SQLRETURN (*pSQLGetStmtAttr)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*);
131 static SQLRETURN (*pSQLGetStmtAttrW)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*);
132 static SQLRETURN (*pSQLGetStmtOption)(SQLHSTMT,SQLUSMALLINT,SQLPOINTER);
133 static SQLRETURN (*pSQLGetTypeInfo)(SQLHSTMT,SQLSMALLINT);
134 static SQLRETURN (*pSQLGetTypeInfoW)(SQLHSTMT,SQLSMALLINT);
135 static SQLRETURN (*pSQLMoreResults)(SQLHSTMT);
136 static SQLRETURN (*pSQLNativeSql)(SQLHDBC,SQLCHAR*,SQLINTEGER,SQLCHAR*,SQLINTEGER,SQLINTEGER*);
137 static SQLRETURN (*pSQLNativeSqlW)(SQLHDBC,SQLWCHAR*,SQLINTEGER,SQLWCHAR*,SQLINTEGER,SQLINTEGER*);
138 static SQLRETURN (*pSQLNumParams)(SQLHSTMT,SQLSMALLINT*);
139 static SQLRETURN (*pSQLNumResultCols)(SQLHSTMT,SQLSMALLINT*);
140 static SQLRETURN (*pSQLParamData)(SQLHSTMT,SQLPOINTER*);
141 static SQLRETURN (*pSQLParamOptions)(SQLHSTMT,SQLULEN,SQLULEN*);
142 static SQLRETURN (*pSQLPrepare)(SQLHSTMT,SQLCHAR*,SQLINTEGER);
143 static SQLRETURN (*pSQLPrepareW)(SQLHSTMT,SQLWCHAR*,SQLINTEGER);
144 static SQLRETURN (*pSQLPrimaryKeys)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT);
145 static SQLRETURN (*pSQLPrimaryKeysW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT);
146 static SQLRETURN (*pSQLProcedureColumns)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT);
147 static SQLRETURN (*pSQLProcedureColumnsW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT);
148 static SQLRETURN (*pSQLProcedures)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT);
149 static SQLRETURN (*pSQLProceduresW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT);
150 static SQLRETURN (*pSQLPutData)(SQLHSTMT,SQLPOINTER,SQLLEN);
151 static SQLRETURN (*pSQLRowCount)(SQLHSTMT,SQLLEN*);
152 static SQLRETURN (*pSQLSetConnectAttr)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER);
153 static SQLRETURN (*pSQLSetConnectAttrW)(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER);
154 static SQLRETURN (*pSQLSetConnectOption)(SQLHDBC,SQLUSMALLINT,SQLULEN);
155 static SQLRETURN (*pSQLSetConnectOptionW)(SQLHDBC,SQLUSMALLINT,SQLULEN);
156 static SQLRETURN (*pSQLSetCursorName)(SQLHSTMT,SQLCHAR*,SQLSMALLINT);
157 static SQLRETURN (*pSQLSetCursorNameW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT);
158 static SQLRETURN (*pSQLSetDescField)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER);
159 static SQLRETURN (*pSQLSetDescFieldW)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLINTEGER);
160 static SQLRETURN (*pSQLSetDescRec)(SQLHDESC,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLLEN,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN*,SQLLEN*);
161 static SQLRETURN (*pSQLSetEnvAttr)(SQLHENV,SQLINTEGER,SQLPOINTER,SQLINTEGER);
162 static SQLRETURN (*pSQLSetParam)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN*);
163 static SQLRETURN (*pSQLSetPos)(SQLHSTMT,SQLSETPOSIROW,SQLUSMALLINT,SQLUSMALLINT);
164 static SQLRETURN (*pSQLSetScrollOptions)(SQLHSTMT,SQLUSMALLINT,SQLLEN,SQLUSMALLINT);
165 static SQLRETURN (*pSQLSetStmtAttr)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER);
166 static SQLRETURN (*pSQLSetStmtAttrW)(SQLHSTMT,SQLINTEGER,SQLPOINTER,SQLINTEGER);
167 static SQLRETURN (*pSQLSetStmtOption)(SQLHSTMT,SQLUSMALLINT,SQLULEN);
168 static SQLRETURN (*pSQLSpecialColumns)(SQLHSTMT,SQLUSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT);
169 static SQLRETURN (*pSQLSpecialColumnsW)(SQLHSTMT,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT);
170 static SQLRETURN (*pSQLStatistics)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT);
171 static SQLRETURN (*pSQLStatisticsW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLUSMALLINT,SQLUSMALLINT);
172 static SQLRETURN (*pSQLTablePrivileges)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT);
173 static SQLRETURN (*pSQLTablePrivilegesW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT);
174 static SQLRETURN (*pSQLTables)(SQLHSTMT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT,SQLCHAR*,SQLSMALLINT);
175 static SQLRETURN (*pSQLTablesW)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT);
176 static SQLRETURN (*pSQLTransact)(SQLHENV,SQLHDBC,SQLUSMALLINT);
177 static SQLRETURN (*pSQLGetDiagRecA)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLCHAR*,SQLINTEGER*,
178                                     SQLCHAR*,SQLSMALLINT,SQLSMALLINT*);
179 
180 #define ERROR_FREE 0
181 #define ERROR_SQLERROR  1
182 #define ERROR_LIBRARY_NOT_FOUND 2
183 
184 static void *dmHandle;
185 static int nErrorType;
186 
187 SQLRETURN WINAPI ODBC32_SQLAllocEnv(SQLHENV *);
188 SQLRETURN WINAPI ODBC32_SQLFreeEnv(SQLHENV);
189 SQLRETURN WINAPI ODBC32_SQLDataSources(SQLHENV, SQLUSMALLINT, SQLCHAR *, SQLSMALLINT,
190                                        SQLSMALLINT *, SQLCHAR *, SQLSMALLINT, SQLSMALLINT *);
191 SQLRETURN WINAPI ODBC32_SQLDrivers(SQLHENV, SQLUSMALLINT, SQLCHAR *, SQLSMALLINT, SQLSMALLINT *,
192                                    SQLCHAR *, SQLSMALLINT, SQLSMALLINT *);
193 
194 /***********************************************************************
195  * ODBC_ReplicateODBCInstToRegistry
196  *
197  * PARAMS
198  *
199  * RETURNS
200  *
201  * Utility to ODBC_ReplicateToRegistry to replicate the drivers of the
202  * ODBCINST.INI settings
203  *
204  * The driver settings are not replicated to the registry.  If we were to
205  * replicate them we would need to decide whether to replicate all settings
206  * or to do some translation; whether to remove any entries present only in
207  * the windows registry, etc.
208  */
209 
210 static void ODBC_ReplicateODBCInstToRegistry (SQLHENV hEnv)
211 {
212     HKEY hODBCInst;
213     LONG reg_ret;
214     BOOL success;
215 
216     success = FALSE;
217     TRACE ("Driver settings are not currently replicated to the registry\n");
218     if ((reg_ret = RegCreateKeyExA (HKEY_LOCAL_MACHINE,
219             "Software\\ODBC\\ODBCINST.INI", 0, NULL,
220             REG_OPTION_NON_VOLATILE,
221             KEY_ALL_ACCESS /* a couple more than we need */, NULL,
222             &hODBCInst, NULL)) == ERROR_SUCCESS)
223     {
224         HKEY hDrivers;
225         if ((reg_ret = RegCreateKeyExA (hODBCInst, "ODBC Drivers", 0,
226                 NULL, REG_OPTION_NON_VOLATILE,
227                 KEY_ALL_ACCESS /* overkill */, NULL, &hDrivers, NULL))
228                 == ERROR_SUCCESS)
229         {
230             SQLRETURN sql_ret;
231             SQLUSMALLINT dirn;
232             CHAR desc [256];
233             SQLSMALLINT sizedesc;
234 
235             success = TRUE;
236             dirn = SQL_FETCH_FIRST;
237             while ((sql_ret = ODBC32_SQLDrivers (hEnv, dirn, (SQLCHAR*)desc, sizeof(desc),
238                     &sizedesc, NULL, 0, NULL)) == SQL_SUCCESS ||
239                     sql_ret == SQL_SUCCESS_WITH_INFO)
240             {
241                 /* FIXME Do some proper handling of the SUCCESS_WITH_INFO */
242                 dirn = SQL_FETCH_NEXT;
243                 if (sizedesc == lstrlenA(desc))
244                 {
245                     HKEY hThis;
246                     if ((reg_ret = RegQueryValueExA (hDrivers, desc, NULL,
247                             NULL, NULL, NULL)) == ERROR_FILE_NOT_FOUND)
248                     {
249                         if ((reg_ret = RegSetValueExA (hDrivers, desc, 0,
250                                 REG_SZ, (const BYTE *)"Installed", 10)) != ERROR_SUCCESS)
251                         {
252                             TRACE ("Error %d replicating driver %s\n",
253                                     reg_ret, desc);
254                             success = FALSE;
255                         }
256                     }
257                     else if (reg_ret != ERROR_SUCCESS)
258                     {
259                         TRACE ("Error %d checking for %s in drivers\n",
260                                 reg_ret, desc);
261                         success = FALSE;
262                     }
263                     if ((reg_ret = RegCreateKeyExA (hODBCInst, desc, 0,
264                             NULL, REG_OPTION_NON_VOLATILE,
265                             KEY_ALL_ACCESS, NULL, &hThis, NULL))
266                             == ERROR_SUCCESS)
267                     {
268                         /* FIXME This is where the settings go.
269                          * I suggest that if the disposition says it
270                          * exists then we leave it alone.  Alternatively
271                          * include an extra value to flag that it is
272                          * a replication of the unixODBC/iODBC/...
273                          */
274                         if ((reg_ret = RegCloseKey (hThis)) !=
275                                 ERROR_SUCCESS)
276                             TRACE ("Error %d closing %s key\n", reg_ret,
277                                     desc);
278                     }
279                     else
280                     {
281                         TRACE ("Error %d ensuring driver key %s\n",
282                                 reg_ret, desc);
283                         success = FALSE;
284                     }
285                 }
286                 else
287                 {
288                     WARN ("Unusually long driver name %s not replicated\n",
289                             desc);
290                     success = FALSE;
291                 }
292             }
293             if (sql_ret != SQL_NO_DATA)
294             {
295                 TRACE ("Error %d enumerating drivers\n", (int)sql_ret);
296                 success = FALSE;
297             }
298             if ((reg_ret = RegCloseKey (hDrivers)) != ERROR_SUCCESS)
299             {
300                 TRACE ("Error %d closing hDrivers\n", reg_ret);
301             }
302         }
303         else
304         {
305             TRACE ("Error %d opening HKLM\\S\\O\\OI\\Drivers\n", reg_ret);
306         }
307         if ((reg_ret = RegCloseKey (hODBCInst)) != ERROR_SUCCESS)
308         {
309             TRACE ("Error %d closing HKLM\\S\\O\\ODBCINST.INI\n", reg_ret);
310         }
311     }
312     else
313     {
314         TRACE ("Error %d opening HKLM\\S\\O\\ODBCINST.INI\n", reg_ret);
315     }
316     if (!success)
317     {
318         WARN ("May not have replicated all ODBC drivers to the registry\n");
319     }
320 }
321 
322 /***********************************************************************
323  * ODBC_ReplicateODBCToRegistry
324  *
325  * PARAMS
326  *
327  * RETURNS
328  *
329  * Utility to ODBC_ReplicateToRegistry to replicate either the USER or
330  * SYSTEM dsns
331  *
332  * For now simply place the "Driver description" (as returned by SQLDataSources)
333  * into the registry as the driver.  This is enough to satisfy Crystal's
334  * requirement that there be a driver entry.  (It doesn't seem to care what
335  * the setting is).
336  * A slightly more accurate setting would be to access the registry to find
337  * the actual driver library for the given description (which appears to map
338  * to one of the HKLM/Software/ODBC/ODBCINST.INI keys).  (If you do this note
339  * that this will add a requirement that this function be called after
340  * ODBC_ReplicateODBCInstToRegistry)
341  */
342 static void ODBC_ReplicateODBCToRegistry (BOOL is_user, SQLHENV hEnv)
343 {
344     HKEY hODBC;
345     LONG reg_ret;
346     SQLRETURN sql_ret;
347     SQLUSMALLINT dirn;
348     CHAR dsn [SQL_MAX_DSN_LENGTH + 1];
349     SQLSMALLINT sizedsn;
350     CHAR desc [256];
351     SQLSMALLINT sizedesc;
352     BOOL success;
353     const char *which = is_user ? "user" : "system";
354 
355     success = FALSE;
356     if ((reg_ret = RegCreateKeyExA (
357             is_user ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
358             "Software\\ODBC\\ODBC.INI", 0, NULL, REG_OPTION_NON_VOLATILE,
359             KEY_ALL_ACCESS /* a couple more than we need */, NULL, &hODBC,
360             NULL)) == ERROR_SUCCESS)
361     {
362         success = TRUE;
363         dirn = is_user ? SQL_FETCH_FIRST_USER : SQL_FETCH_FIRST_SYSTEM;
364         while ((sql_ret = ODBC32_SQLDataSources (hEnv, dirn,
365                 (SQLCHAR*)dsn, sizeof(dsn), &sizedsn,
366                 (SQLCHAR*)desc, sizeof(desc), &sizedesc)) == SQL_SUCCESS
367                 || sql_ret == SQL_SUCCESS_WITH_INFO)
368         {
369             /* FIXME Do some proper handling of the SUCCESS_WITH_INFO */
370             dirn = SQL_FETCH_NEXT;
371             if (sizedsn == lstrlenA(dsn) && sizedesc == lstrlenA(desc))
372             {
373                 HKEY hDSN;
374                 if ((reg_ret = RegCreateKeyExA (hODBC, dsn, 0,
375                         NULL, REG_OPTION_NON_VOLATILE,
376                         KEY_ALL_ACCESS, NULL, &hDSN, NULL))
377                         == ERROR_SUCCESS)
378                 {
379                     static const char DRIVERKEY[] = "Driver";
380                     if ((reg_ret = RegQueryValueExA (hDSN, DRIVERKEY,
381                             NULL, NULL, NULL, NULL))
382                             == ERROR_FILE_NOT_FOUND)
383                     {
384                         if ((reg_ret = RegSetValueExA (hDSN, DRIVERKEY, 0,
385                                 REG_SZ, (LPBYTE)desc, sizedesc)) != ERROR_SUCCESS)
386                         {
387                             TRACE ("Error %d replicating description of "
388                                     "%s(%s)\n", reg_ret, dsn, desc);
389                             success = FALSE;
390                         }
391                     }
392                     else if (reg_ret != ERROR_SUCCESS)
393                     {
394                         TRACE ("Error %d checking for description of %s\n",
395                                 reg_ret, dsn);
396                         success = FALSE;
397                     }
398                     if ((reg_ret = RegCloseKey (hDSN)) != ERROR_SUCCESS)
399                     {
400                         TRACE ("Error %d closing %s DSN key %s\n",
401                                 reg_ret, which, dsn);
402                     }
403                 }
404                 else
405                 {
406                     TRACE ("Error %d opening %s DSN key %s\n",
407                             reg_ret, which, dsn);
408                     success = FALSE;
409                 }
410             }
411             else
412             {
413                 WARN ("Unusually long %s data source name %s (%s) not "
414                         "replicated\n", which, dsn, desc);
415                 success = FALSE;
416             }
417         }
418         if (sql_ret != SQL_NO_DATA)
419         {
420             TRACE ("Error %d enumerating %s datasources\n",
421                     (int)sql_ret, which);
422             success = FALSE;
423         }
424         if ((reg_ret = RegCloseKey (hODBC)) != ERROR_SUCCESS)
425         {
426             TRACE ("Error %d closing %s ODBC.INI registry key\n", reg_ret,
427                     which);
428         }
429     }
430     else
431     {
432         TRACE ("Error %d creating/opening %s ODBC.INI registry key\n",
433                 reg_ret, which);
434     }
435     if (!success)
436     {
437         WARN ("May not have replicated all %s ODBC DSNs to the registry\n",
438                 which);
439     }
440 }
441 
442 /***********************************************************************
443  * ODBC_ReplicateToRegistry
444  *
445  * PARAMS
446  *
447  * RETURNS
448  *
449  * Unfortunately some of the functions that Windows documents as being part
450  * of the ODBC API it implements directly during compilation or something
451  * in terms of registry access functions.
452  * e.g. SQLGetInstalledDrivers queries the list at
453  * HKEY_LOCAL_MACHINE\Software\ODBC\ODBCINST.INI\ODBC Drivers
454  *
455  * This function is called when the driver manager is loaded and is used
456  * to replicate the appropriate details into the Wine registry
457  */
458 
459 static void ODBC_ReplicateToRegistry (void)
460 {
461     SQLRETURN sql_ret;
462     SQLHENV hEnv;
463 
464     if ((sql_ret = ODBC32_SQLAllocEnv (&hEnv)) == SQL_SUCCESS)
465     {
466         ODBC_ReplicateODBCInstToRegistry (hEnv);
467         ODBC_ReplicateODBCToRegistry (FALSE /* system dsns */, hEnv);
468         ODBC_ReplicateODBCToRegistry (TRUE /* user dsns */, hEnv);
469 
470         if ((sql_ret = ODBC32_SQLFreeEnv (hEnv)) != SQL_SUCCESS)
471         {
472             TRACE ("Error %d freeing the SQL environment.\n", (int)sql_ret);
473         }
474     }
475     else
476     {
477         TRACE ("Error %d opening an SQL environment.\n", (int)sql_ret);
478         WARN ("The external ODBC settings have not been replicated to the"
479                 " Wine registry\n");
480     }
481 }
482 
483 /***********************************************************************
484  * DllMain [Internal] Initializes the internal 'ODBC32.DLL'.
485  */
486 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
487 {
488     TRACE("proxy ODBC: %p,%x,%p\n", hinstDLL, reason, reserved);
489 
490     switch (reason)
491     {
492     case DLL_PROCESS_ATTACH:
493        DisableThreadLibraryCalls(hinstDLL);
494        if (ODBC_LoadDriverManager())
495        {
496           ODBC_LoadDMFunctions();
497           ODBC_ReplicateToRegistry();
498        }
499        break;
500 
501     case DLL_PROCESS_DETACH:
502       if (reserved) break;
503       if (dmHandle) wine_dlclose(dmHandle,NULL,0);
504     }
505 
506     return TRUE;
507 }
508 
509 /***********************************************************************
510  * ODBC_LoadDriverManager [Internal] Load ODBC library.
511  *
512  * PARAMS
513  *
514  * RETURNS
515  *     Success: TRUE
516  *     Failure: FALSE
517  */
518 
519 static BOOL ODBC_LoadDriverManager(void)
520 {
521    const char *s = getenv("LIB_ODBC_DRIVER_MANAGER");
522    char error[256];
523 
524 #ifdef SONAME_LIBODBC
525    if (!s || !s[0]) s = SONAME_LIBODBC;
526 #endif
527    if (!s || !s[0]) goto failed;
528 
529    dmHandle = wine_dlopen(s, RTLD_LAZY | RTLD_GLOBAL, error, sizeof(error));
530 
531    if (dmHandle != NULL)
532    {
533       TRACE("Opened library %s\n", s);
534       nErrorType = ERROR_FREE;
535       return TRUE;
536    }
537 failed:
538    ERR_(winediag)("failed to open library %s: %s\n", debugstr_a(s), error);
539    nErrorType = ERROR_LIBRARY_NOT_FOUND;
540    return FALSE;
541 }
542 
543 
544 /***********************************************************************
545  * ODBC_LoadDMFunctions [Internal] Populate function table.
546  *
547  * PARAMS
548  *
549  * RETURNS
550  *     Success: TRUE
551  *     Failure: FALSE
552  */
553 
554 static BOOL ODBC_LoadDMFunctions(void)
555 {
556     char error[256];
557 
558     if (dmHandle == NULL)
559         return FALSE;
560 
561 #define LOAD_FUNC(name) \
562     if ((p##name = wine_dlsym( dmHandle, #name, error, sizeof(error) ))); \
563     else WARN( "Failed to load %s: %s\n", #name, error )
564 
565     LOAD_FUNC(SQLAllocConnect);
566     LOAD_FUNC(SQLAllocEnv);
567     LOAD_FUNC(SQLAllocHandle);
568     LOAD_FUNC(SQLAllocHandleStd);
569     LOAD_FUNC(SQLAllocStmt);
570     LOAD_FUNC(SQLBindCol);
571     LOAD_FUNC(SQLBindParam);
572     LOAD_FUNC(SQLBindParameter);
573     LOAD_FUNC(SQLBrowseConnect);
574     LOAD_FUNC(SQLBrowseConnectW);
575     LOAD_FUNC(SQLBulkOperations);
576     LOAD_FUNC(SQLCancel);
577     LOAD_FUNC(SQLCloseCursor);
578     LOAD_FUNC(SQLColAttribute);
579     LOAD_FUNC(SQLColAttributeW);
580     LOAD_FUNC(SQLColAttributes);
581     LOAD_FUNC(SQLColAttributesW);
582     LOAD_FUNC(SQLColumnPrivileges);
583     LOAD_FUNC(SQLColumnPrivilegesW);
584     LOAD_FUNC(SQLColumns);
585     LOAD_FUNC(SQLColumnsW);
586     LOAD_FUNC(SQLConnect);
587     LOAD_FUNC(SQLConnectW);
588     LOAD_FUNC(SQLCopyDesc);
589     LOAD_FUNC(SQLDataSources);
590     LOAD_FUNC(SQLDataSourcesA);
591     LOAD_FUNC(SQLDataSourcesW);
592     LOAD_FUNC(SQLDescribeCol);
593     LOAD_FUNC(SQLDescribeColW);
594     LOAD_FUNC(SQLDescribeParam);
595     LOAD_FUNC(SQLDisconnect);
596     LOAD_FUNC(SQLDriverConnect);
597     LOAD_FUNC(SQLDriverConnectW);
598     LOAD_FUNC(SQLDrivers);
599     LOAD_FUNC(SQLDriversW);
600     LOAD_FUNC(SQLEndTran);
601     LOAD_FUNC(SQLError);
602     LOAD_FUNC(SQLErrorW);
603     LOAD_FUNC(SQLExecDirect);
604     LOAD_FUNC(SQLExecDirectW);
605     LOAD_FUNC(SQLExecute);
606     LOAD_FUNC(SQLExtendedFetch);
607     LOAD_FUNC(SQLFetch);
608     LOAD_FUNC(SQLFetchScroll);
609     LOAD_FUNC(SQLForeignKeys);
610     LOAD_FUNC(SQLForeignKeysW);
611     LOAD_FUNC(SQLFreeConnect);
612     LOAD_FUNC(SQLFreeEnv);
613     LOAD_FUNC(SQLFreeHandle);
614     LOAD_FUNC(SQLFreeStmt);
615     LOAD_FUNC(SQLGetConnectAttr);
616     LOAD_FUNC(SQLGetConnectAttrW);
617     LOAD_FUNC(SQLGetConnectOption);
618     LOAD_FUNC(SQLGetConnectOptionW);
619     LOAD_FUNC(SQLGetCursorName);
620     LOAD_FUNC(SQLGetCursorNameW);
621     LOAD_FUNC(SQLGetData);
622     LOAD_FUNC(SQLGetDescField);
623     LOAD_FUNC(SQLGetDescFieldW);
624     LOAD_FUNC(SQLGetDescRec);
625     LOAD_FUNC(SQLGetDescRecW);
626     LOAD_FUNC(SQLGetDiagField);
627     LOAD_FUNC(SQLGetDiagFieldW);
628     LOAD_FUNC(SQLGetDiagRec);
629     LOAD_FUNC(SQLGetDiagRecA);
630     LOAD_FUNC(SQLGetDiagRecW);
631     LOAD_FUNC(SQLGetEnvAttr);
632     LOAD_FUNC(SQLGetFunctions);
633     LOAD_FUNC(SQLGetInfo);
634     LOAD_FUNC(SQLGetInfoW);
635     LOAD_FUNC(SQLGetStmtAttr);
636     LOAD_FUNC(SQLGetStmtAttrW);
637     LOAD_FUNC(SQLGetStmtOption);
638     LOAD_FUNC(SQLGetTypeInfo);
639     LOAD_FUNC(SQLGetTypeInfoW);
640     LOAD_FUNC(SQLMoreResults);
641     LOAD_FUNC(SQLNativeSql);
642     LOAD_FUNC(SQLNativeSqlW);
643     LOAD_FUNC(SQLNumParams);
644     LOAD_FUNC(SQLNumResultCols);
645     LOAD_FUNC(SQLParamData);
646     LOAD_FUNC(SQLParamOptions);
647     LOAD_FUNC(SQLPrepare);
648     LOAD_FUNC(SQLPrepareW);
649     LOAD_FUNC(SQLPrimaryKeys);
650     LOAD_FUNC(SQLPrimaryKeysW);
651     LOAD_FUNC(SQLProcedureColumns);
652     LOAD_FUNC(SQLProcedureColumnsW);
653     LOAD_FUNC(SQLProcedures);
654     LOAD_FUNC(SQLProceduresW);
655     LOAD_FUNC(SQLPutData);
656     LOAD_FUNC(SQLRowCount);
657     LOAD_FUNC(SQLSetConnectAttr);
658     LOAD_FUNC(SQLSetConnectAttrW);
659     LOAD_FUNC(SQLSetConnectOption);
660     LOAD_FUNC(SQLSetConnectOptionW);
661     LOAD_FUNC(SQLSetCursorName);
662     LOAD_FUNC(SQLSetCursorNameW);
663     LOAD_FUNC(SQLSetDescField);
664     LOAD_FUNC(SQLSetDescFieldW);
665     LOAD_FUNC(SQLSetDescRec);
666     LOAD_FUNC(SQLSetEnvAttr);
667     LOAD_FUNC(SQLSetParam);
668     LOAD_FUNC(SQLSetPos);
669     LOAD_FUNC(SQLSetScrollOptions);
670     LOAD_FUNC(SQLSetStmtAttr);
671     LOAD_FUNC(SQLSetStmtAttrW);
672     LOAD_FUNC(SQLSetStmtOption);
673     LOAD_FUNC(SQLSpecialColumns);
674     LOAD_FUNC(SQLSpecialColumnsW);
675     LOAD_FUNC(SQLStatistics);
676     LOAD_FUNC(SQLStatisticsW);
677     LOAD_FUNC(SQLTablePrivileges);
678     LOAD_FUNC(SQLTablePrivilegesW);
679     LOAD_FUNC(SQLTables);
680     LOAD_FUNC(SQLTablesW);
681     LOAD_FUNC(SQLTransact);
682 #undef LOAD_FUNC
683 
684     return TRUE;
685 }
686 
687 /*************************************************************************
688  *				SQLAllocConnect           [ODBC32.001]
689  */
690 SQLRETURN WINAPI ODBC32_SQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC *ConnectionHandle)
691 {
692     SQLRETURN ret;
693 
694     TRACE("(EnvironmentHandle %p, ConnectionHandle %p)\n", EnvironmentHandle, ConnectionHandle);
695 
696     if (!pSQLAllocConnect)
697     {
698         *ConnectionHandle = SQL_NULL_HDBC;
699         TRACE("Not ready\n");
700         return SQL_ERROR;
701     }
702 
703     ret = pSQLAllocConnect(EnvironmentHandle, ConnectionHandle);
704     TRACE("Returning %d, ConnectionHandle %p\n", ret, *ConnectionHandle);
705     return ret;
706 }
707 
708 /*************************************************************************
709  *				SQLAllocEnv           [ODBC32.002]
710  */
711 SQLRETURN WINAPI ODBC32_SQLAllocEnv(SQLHENV *EnvironmentHandle)
712 {
713     SQLRETURN ret;
714 
715     TRACE("(EnvironmentHandle %p)\n", EnvironmentHandle);
716 
717     if (!pSQLAllocEnv)
718     {
719         *EnvironmentHandle = SQL_NULL_HENV;
720         TRACE("Not ready\n");
721         return SQL_ERROR;
722     }
723 
724     ret = pSQLAllocEnv(EnvironmentHandle);
725     TRACE("Returning %d, EnvironmentHandle %p\n", ret, *EnvironmentHandle);
726     return ret;
727 }
728 
729 /*************************************************************************
730  *				SQLAllocHandle           [ODBC32.024]
731  */
732 SQLRETURN WINAPI ODBC32_SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
733 {
734     SQLRETURN ret;
735 
736     TRACE("(HandleType %d, InputHandle %p, OutputHandle %p)\n", HandleType, InputHandle, OutputHandle);
737 
738     if (!pSQLAllocHandle)
739     {
740         if (nErrorType == ERROR_LIBRARY_NOT_FOUND)
741             WARN("ProxyODBC: Cannot load ODBC driver manager library.\n");
742 
743         if (HandleType == SQL_HANDLE_ENV)
744             *OutputHandle = SQL_NULL_HENV;
745         else if (HandleType == SQL_HANDLE_DBC)
746             *OutputHandle = SQL_NULL_HDBC;
747         else if (HandleType == SQL_HANDLE_STMT)
748             *OutputHandle = SQL_NULL_HSTMT;
749         else if (HandleType == SQL_HANDLE_DESC)
750             *OutputHandle = SQL_NULL_HDESC;
751 
752         TRACE ("Not ready\n");
753         return SQL_ERROR;
754     }
755 
756     ret = pSQLAllocHandle(HandleType, InputHandle, OutputHandle);
757     TRACE("Returning %d, Handle %p\n", ret, *OutputHandle);
758     return ret;
759 }
760 
761 /*************************************************************************
762  *				SQLAllocStmt           [ODBC32.003]
763  */
764 SQLRETURN WINAPI ODBC32_SQLAllocStmt(SQLHDBC ConnectionHandle, SQLHSTMT *StatementHandle)
765 {
766     SQLRETURN ret;
767 
768     TRACE("(ConnectionHandle %p, StatementHandle %p)\n", ConnectionHandle, StatementHandle);
769 
770     if (!pSQLAllocStmt)
771     {
772         *StatementHandle = SQL_NULL_HSTMT;
773         TRACE("Not ready\n");
774         return SQL_ERROR;
775     }
776 
777     ret = pSQLAllocStmt(ConnectionHandle, StatementHandle);
778     TRACE ("Returning %d, StatementHandle %p\n", ret, *StatementHandle);
779     return ret;
780 }
781 
782 /*************************************************************************
783  *				SQLAllocHandleStd           [ODBC32.077]
784  */
785 SQLRETURN WINAPI ODBC32_SQLAllocHandleStd(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
786 {
787     SQLRETURN ret;
788 
789     TRACE("(HandleType %d, InputHandle %p, OutputHandle %p)\n", HandleType, InputHandle, OutputHandle);
790 
791     if (!pSQLAllocHandleStd)
792     {
793         if (nErrorType == ERROR_LIBRARY_NOT_FOUND)
794             WARN("ProxyODBC: Cannot load ODBC driver manager library.\n");
795 
796         if (HandleType == SQL_HANDLE_ENV)
797             *OutputHandle = SQL_NULL_HENV;
798         else if (HandleType == SQL_HANDLE_DBC)
799             *OutputHandle = SQL_NULL_HDBC;
800         else if (HandleType == SQL_HANDLE_STMT)
801             *OutputHandle = SQL_NULL_HSTMT;
802         else if (HandleType == SQL_HANDLE_DESC)
803             *OutputHandle = SQL_NULL_HDESC;
804 
805         return SQL_ERROR;
806     }
807 
808     ret = pSQLAllocHandleStd(HandleType, InputHandle, OutputHandle);
809     TRACE ("Returning %d, OutputHandle %p\n", ret, *OutputHandle);
810     return ret;
811 }
812 
813 static const char *debugstr_sqllen( SQLLEN len )
814 {
815 #ifdef _WIN64
816     return wine_dbg_sprintf( "%ld", len );
817 #else
818     return wine_dbg_sprintf( "%d", len );
819 #endif
820 }
821 
822 /*************************************************************************
823  *				SQLBindCol           [ODBC32.004]
824  */
825 SQLRETURN WINAPI ODBC32_SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType,
826                                    SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind)
827 {
828     SQLRETURN ret;
829 
830     TRACE("(StatementHandle %p, ColumnNumber %d, TargetType %d, TargetValue %p, BufferLength %s, StrLen_or_Ind %p)\n",
831           StatementHandle, ColumnNumber, TargetType, TargetValue, debugstr_sqllen(BufferLength), StrLen_or_Ind);
832 
833     if (!pSQLBindCol)
834     {
835         TRACE("Not ready\n");
836         return SQL_ERROR;
837     }
838 
839     ret = pSQLBindCol(StatementHandle, ColumnNumber, TargetType, TargetValue, BufferLength, StrLen_or_Ind);
840     TRACE ("Returning %d\n", ret);
841     return ret;
842 }
843 
844 static const char *debugstr_sqlulen( SQLULEN len )
845 {
846 #ifdef _WIN64
847     return wine_dbg_sprintf( "%lu", len );
848 #else
849     return wine_dbg_sprintf( "%u", len );
850 #endif
851 }
852 
853 /*************************************************************************
854  *				SQLBindParam           [ODBC32.025]
855  */
856 SQLRETURN WINAPI ODBC32_SQLBindParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
857                                      SQLSMALLINT ParameterType, SQLULEN LengthPrecision, SQLSMALLINT ParameterScale,
858                                      SQLPOINTER ParameterValue, SQLLEN *StrLen_or_Ind)
859 {
860     SQLRETURN ret;
861 
862     TRACE("(StatementHandle %p, ParameterNumber %d, ValueType %d, ParameterType %d, LengthPrecision %s,"
863           " ParameterScale %d, ParameterValue %p, StrLen_or_Ind %p)\n", StatementHandle, ParameterNumber, ValueType,
864           ParameterType, debugstr_sqlulen(LengthPrecision), ParameterScale, ParameterValue, StrLen_or_Ind);
865 
866     if (!pSQLBindParam) return SQL_ERROR;
867 
868     ret = pSQLBindParam(StatementHandle, ParameterNumber, ValueType, ParameterType, LengthPrecision, ParameterScale,
869                         ParameterValue, StrLen_or_Ind);
870     TRACE ("Returning %d\n", ret);
871     return ret;
872 }
873 
874 /*************************************************************************
875  *				SQLCancel           [ODBC32.005]
876  */
877 SQLRETURN WINAPI ODBC32_SQLCancel(SQLHSTMT StatementHandle)
878 {
879     SQLRETURN ret;
880 
881     TRACE("(StatementHandle %p)\n", StatementHandle);
882 
883     if (!pSQLCancel) return SQL_ERROR;
884 
885     ret = pSQLCancel(StatementHandle);
886     TRACE("Returning %d\n", ret);
887     return ret;
888 }
889 
890 /*************************************************************************
891  *				SQLCloseCursor           [ODBC32.026]
892  */
893 SQLRETURN WINAPI ODBC32_SQLCloseCursor(SQLHSTMT StatementHandle)
894 {
895     SQLRETURN ret;
896 
897     TRACE("(StatementHandle %p)\n", StatementHandle);
898 
899     if (!pSQLCloseCursor) return SQL_ERROR;
900 
901     ret = pSQLCloseCursor(StatementHandle);
902     TRACE("Returning %d\n", ret);
903     return ret;
904 }
905 
906 /*************************************************************************
907  *				SQLColAttribute           [ODBC32.027]
908  */
909 SQLRETURN WINAPI ODBC32_SQLColAttribute(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber,
910                                         SQLUSMALLINT FieldIdentifier, SQLPOINTER CharacterAttribute,
911                                         SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
912                                         SQLLEN *NumericAttribute)
913 {
914     SQLRETURN ret;
915 
916     TRACE("(StatementHandle %p, ColumnNumber %d, FieldIdentifier %d, CharacterAttribute %p, BufferLength %d,"
917           " StringLength %p, NumericAttribute %p)\n", StatementHandle, ColumnNumber, FieldIdentifier,
918           CharacterAttribute, BufferLength, StringLength, NumericAttribute);
919 
920     if (!pSQLColAttribute) return SQL_ERROR;
921 
922     ret = pSQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength,
923                            StringLength, NumericAttribute);
924     TRACE("Returning %d\n", ret);
925     return ret;
926 }
927 
928 /*************************************************************************
929  *				SQLColumns           [ODBC32.040]
930  */
931 SQLRETURN WINAPI ODBC32_SQLColumns(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
932                                    SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName,
933                                    SQLSMALLINT NameLength3, SQLCHAR *ColumnName, SQLSMALLINT NameLength4)
934 {
935     SQLRETURN ret;
936 
937     TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s,"
938           " NameLength3 %d, ColumnName %s, NameLength4 %d)\n", StatementHandle,
939           debugstr_an((const char *)CatalogName, NameLength1), NameLength1,
940           debugstr_an((const char *)SchemaName, NameLength2), NameLength2,
941           debugstr_an((const char *)TableName, NameLength3), NameLength3,
942           debugstr_an((const char *)ColumnName, NameLength4), NameLength4);
943 
944     if (!pSQLColumns) return SQL_ERROR;
945 
946     ret = pSQLColumns(StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2, TableName,
947                       NameLength3, ColumnName, NameLength4);
948     TRACE("Returning %d\n", ret);
949     return ret;
950 }
951 
952 /*************************************************************************
953  *				SQLConnect           [ODBC32.007]
954  */
955 SQLRETURN WINAPI ODBC32_SQLConnect(SQLHDBC ConnectionHandle, SQLCHAR *ServerName, SQLSMALLINT NameLength1,
956                                    SQLCHAR *UserName, SQLSMALLINT NameLength2, SQLCHAR *Authentication,
957                                    SQLSMALLINT NameLength3)
958 {
959     SQLRETURN ret;
960 
961     TRACE("(ConnectionHandle %p, ServerName %s, NameLength1 %d, UserName %s, NameLength2 %d, Authentication %s,"
962           " NameLength3 %d)\n", ConnectionHandle,
963           debugstr_an((const char *)ServerName, NameLength1), NameLength1,
964           debugstr_an((const char *)UserName, NameLength2), NameLength2,
965           debugstr_an((const char *)Authentication, NameLength3), NameLength3);
966 
967     if (!pSQLConnect) return SQL_ERROR;
968 
969     ret = pSQLConnect(ConnectionHandle, ServerName, NameLength1, UserName, NameLength2, Authentication, NameLength3);
970     TRACE("Returning %d\n", ret);
971     return ret;
972 }
973 
974 /*************************************************************************
975  *				SQLCopyDesc           [ODBC32.028]
976  */
977 SQLRETURN WINAPI ODBC32_SQLCopyDesc(SQLHDESC SourceDescHandle, SQLHDESC TargetDescHandle)
978 {
979     SQLRETURN ret;
980 
981     TRACE("(SourceDescHandle %p, TargetDescHandle %p)\n", SourceDescHandle, TargetDescHandle);
982 
983     if (!pSQLCopyDesc) return SQL_ERROR;
984 
985     ret = pSQLCopyDesc(SourceDescHandle, TargetDescHandle);
986     TRACE("Returning %d\n", ret);
987     return ret;
988 }
989 
990 /*************************************************************************
991  *				SQLDataSources           [ODBC32.057]
992  */
993 SQLRETURN WINAPI ODBC32_SQLDataSources(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, SQLCHAR *ServerName,
994                                        SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, SQLCHAR *Description,
995                                        SQLSMALLINT BufferLength2, SQLSMALLINT *NameLength2)
996 {
997     SQLRETURN ret;
998 
999     TRACE("(EnvironmentHandle %p, Direction %d, ServerName %p, BufferLength1 %d, NameLength1 %p, Description %p,"
1000           " BufferLength2 %d, NameLength2 %p)\n", EnvironmentHandle, Direction, ServerName, BufferLength1,
1001           NameLength1, Description, BufferLength2, NameLength2);
1002 
1003     if (!pSQLDataSources) return SQL_ERROR;
1004 
1005     ret = pSQLDataSources(EnvironmentHandle, Direction, ServerName, BufferLength1, NameLength1, Description,
1006                           BufferLength2, NameLength2);
1007     if (ret >= 0 && TRACE_ON(odbc))
1008     {
1009         if (ServerName && NameLength1 && *NameLength1 > 0)
1010             TRACE(" DataSource %s", debugstr_an((const char *)ServerName, *NameLength1));
1011         if (Description && NameLength2 && *NameLength2 > 0)
1012             TRACE(" Description %s", debugstr_an((const char *)Description, *NameLength2));
1013         TRACE("\n");
1014     }
1015 
1016     TRACE("Returning %d\n", ret);
1017     return ret;
1018 }
1019 
1020 SQLRETURN WINAPI ODBC32_SQLDataSourcesA(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, SQLCHAR *ServerName,
1021                                         SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, SQLCHAR *Description,
1022                                         SQLSMALLINT BufferLength2, SQLSMALLINT *NameLength2)
1023 {
1024     SQLRETURN ret;
1025 
1026     TRACE("(EnvironmentHandle %p, Direction %d, ServerName %p, BufferLength1 %d, NameLength1 %p, Description %p,"
1027           " BufferLength2 %d, NameLength2 %p)\n", EnvironmentHandle, Direction, ServerName, BufferLength1,
1028           NameLength1, Description, BufferLength2, NameLength2);
1029 
1030     if (!pSQLDataSourcesA) return SQL_ERROR;
1031 
1032     ret = pSQLDataSourcesA(EnvironmentHandle, Direction, ServerName, BufferLength1, NameLength1, Description,
1033                            BufferLength2, NameLength2);
1034     if (TRACE_ON(odbc))
1035     {
1036        if (ServerName && NameLength1 && *NameLength1 > 0)
1037             TRACE(" DataSource %s", debugstr_an((const char *)ServerName, *NameLength1));
1038        if (Description && NameLength2 && *NameLength2 > 0)
1039             TRACE(" Description %s", debugstr_an((const char *)Description, *NameLength2));
1040        TRACE("\n");
1041     }
1042 
1043     TRACE("Returning %d\n", ret);
1044     return ret;
1045 }
1046 
1047 /*************************************************************************
1048  *				SQLDescribeCol           [ODBC32.008]
1049  */
1050 SQLRETURN WINAPI ODBC32_SQLDescribeCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName,
1051                                        SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, SQLSMALLINT *DataType,
1052                                        SQLULEN *ColumnSize, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable)
1053 {
1054     SQLSMALLINT dummy;
1055     SQLRETURN ret;
1056 
1057     TRACE("(StatementHandle %p, ColumnNumber %d, ColumnName %p, BufferLength %d, NameLength %p, DataType %p,"
1058           " ColumnSize %p, DecimalDigits %p, Nullable %p)\n", StatementHandle, ColumnNumber, ColumnName,
1059           BufferLength, NameLength, DataType, ColumnSize, DecimalDigits, Nullable);
1060 
1061     if (!pSQLDescribeCol) return SQL_ERROR;
1062     if (!NameLength) NameLength = &dummy; /* workaround for drivers that don't accept NULL NameLength */
1063 
1064     ret = pSQLDescribeCol(StatementHandle, ColumnNumber, ColumnName, BufferLength, NameLength, DataType, ColumnSize,
1065                           DecimalDigits, Nullable);
1066     if (ret >= 0)
1067     {
1068         if (ColumnName && NameLength) TRACE(" ColumnName %s\n", debugstr_an((const char *)ColumnName, *NameLength));
1069         if (DataType) TRACE(" DataType %d\n", *DataType);
1070         if (ColumnSize) TRACE(" ColumnSize %s\n", debugstr_sqlulen(*ColumnSize));
1071         if (DecimalDigits) TRACE(" DecimalDigits %d\n", *DecimalDigits);
1072         if (Nullable) TRACE(" Nullable %d\n", *Nullable);
1073     }
1074 
1075     TRACE("Returning %d\n", ret);
1076     return ret;
1077 }
1078 
1079 /*************************************************************************
1080  *				SQLDisconnect           [ODBC32.009]
1081  */
1082 SQLRETURN WINAPI ODBC32_SQLDisconnect(SQLHDBC ConnectionHandle)
1083 {
1084     SQLRETURN ret;
1085 
1086     TRACE("(ConnectionHandle %p)\n", ConnectionHandle);
1087 
1088     if (!pSQLDisconnect) return SQL_ERROR;
1089 
1090     ret = pSQLDisconnect(ConnectionHandle);
1091     TRACE("Returning %d\n", ret);
1092     return ret;
1093 }
1094 
1095 /*************************************************************************
1096  *				SQLEndTran           [ODBC32.029]
1097  */
1098 SQLRETURN WINAPI ODBC32_SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType)
1099 {
1100     SQLRETURN ret;
1101 
1102     TRACE("(HandleType %d, Handle %p, CompletionType %d)\n", HandleType, Handle, CompletionType);
1103 
1104     if (!pSQLEndTran) return SQL_ERROR;
1105 
1106     ret = pSQLEndTran(HandleType, Handle, CompletionType);
1107     TRACE("Returning %d\n", ret);
1108     return ret;
1109 }
1110 
1111 /*************************************************************************
1112  *				SQLError           [ODBC32.010]
1113  */
1114 SQLRETURN WINAPI ODBC32_SQLError(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle,
1115                                  SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText,
1116                                  SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
1117 {
1118     SQLRETURN ret;
1119 
1120     TRACE("(EnvironmentHandle %p, ConnectionHandle %p, StatementHandle %p, Sqlstate %p, NativeError %p,"
1121           " MessageText %p, BufferLength %d, TextLength %p)\n", EnvironmentHandle, ConnectionHandle,
1122           StatementHandle, Sqlstate, NativeError, MessageText, BufferLength, TextLength);
1123 
1124     if (!pSQLError) return SQL_ERROR;
1125 
1126     ret = pSQLError(EnvironmentHandle, ConnectionHandle, StatementHandle, Sqlstate, NativeError, MessageText,
1127                     BufferLength, TextLength);
1128 
1129     if (ret == SQL_SUCCESS)
1130     {
1131         TRACE(" SQLState %s\n", debugstr_an((const char *)Sqlstate, 5));
1132         TRACE(" Error %d\n", *NativeError);
1133         TRACE(" MessageText %s\n", debugstr_an((const char *)MessageText, *TextLength));
1134     }
1135 
1136     TRACE("Returning %d\n", ret);
1137     return ret;
1138 }
1139 
1140 /*************************************************************************
1141  *				SQLExecDirect           [ODBC32.011]
1142  */
1143 SQLRETURN WINAPI ODBC32_SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength)
1144 {
1145     SQLRETURN ret;
1146 
1147     TRACE("(StatementHandle %p, StatementText %s, TextLength %d)\n", StatementHandle,
1148           debugstr_an((const char *)StatementText, TextLength), TextLength);
1149 
1150     if (!pSQLExecDirect) return SQL_ERROR;
1151 
1152     ret = pSQLExecDirect(StatementHandle, StatementText, TextLength);
1153     TRACE("Returning %d\n", ret);
1154     return ret;
1155 }
1156 
1157 /*************************************************************************
1158  *				SQLExecute           [ODBC32.012]
1159  */
1160 SQLRETURN WINAPI ODBC32_SQLExecute(SQLHSTMT StatementHandle)
1161 {
1162     SQLRETURN ret;
1163 
1164     TRACE("(StatementHandle %p)\n", StatementHandle);
1165 
1166     if (!pSQLExecute) return SQL_ERROR;
1167 
1168     ret = pSQLExecute(StatementHandle);
1169     TRACE("Returning %d\n", ret);
1170     return ret;
1171 }
1172 
1173 /*************************************************************************
1174  *				SQLFetch           [ODBC32.013]
1175  */
1176 SQLRETURN WINAPI ODBC32_SQLFetch(SQLHSTMT StatementHandle)
1177 {
1178     SQLRETURN ret;
1179 
1180     TRACE("(StatementHandle %p)\n", StatementHandle);
1181 
1182     if (!pSQLFetch) return SQL_ERROR;
1183 
1184     ret = pSQLFetch(StatementHandle);
1185     TRACE("Returning %d\n", ret);
1186     return ret;
1187 }
1188 
1189 /*************************************************************************
1190  *				SQLFetchScroll          [ODBC32.030]
1191  */
1192 SQLRETURN WINAPI ODBC32_SQLFetchScroll(SQLHSTMT StatementHandle, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
1193 {
1194     SQLRETURN ret;
1195 
1196     TRACE("(StatementHandle %p, FetchOrientation %d, FetchOffset %s)\n", StatementHandle, FetchOrientation,
1197           debugstr_sqllen(FetchOffset));
1198 
1199     if (!pSQLFetchScroll) return SQL_ERROR;
1200 
1201     ret = pSQLFetchScroll(StatementHandle, FetchOrientation, FetchOffset);
1202     TRACE("Returning %d\n", ret);
1203     return ret;
1204 }
1205 
1206 /*************************************************************************
1207  *				SQLFreeConnect           [ODBC32.014]
1208  */
1209 SQLRETURN WINAPI ODBC32_SQLFreeConnect(SQLHDBC ConnectionHandle)
1210 {
1211     SQLRETURN ret;
1212 
1213     TRACE("(ConnectionHandle %p)\n", ConnectionHandle);
1214 
1215     if (!pSQLFreeConnect) return SQL_ERROR;
1216 
1217     ret = pSQLFreeConnect(ConnectionHandle);
1218     TRACE("Returning %d\n", ret);
1219     return ret;
1220 }
1221 
1222 /*************************************************************************
1223  *				SQLFreeEnv           [ODBC32.015]
1224  */
1225 SQLRETURN WINAPI ODBC32_SQLFreeEnv(SQLHENV EnvironmentHandle)
1226 {
1227     SQLRETURN ret;
1228 
1229     TRACE("(EnvironmentHandle %p)\n", EnvironmentHandle);
1230 
1231     if (!pSQLFreeEnv) return SQL_ERROR;
1232 
1233     ret = pSQLFreeEnv(EnvironmentHandle);
1234     TRACE("Returning %d\n", ret);
1235     return ret;
1236 }
1237 
1238 /*************************************************************************
1239  *				SQLFreeHandle           [ODBC32.031]
1240  */
1241 SQLRETURN WINAPI ODBC32_SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
1242 {
1243     SQLRETURN ret;
1244 
1245     TRACE("(HandleType %d, Handle %p)\n", HandleType, Handle);
1246 
1247     if (!pSQLFreeHandle) return SQL_ERROR;
1248 
1249     ret = pSQLFreeHandle(HandleType, Handle);
1250     TRACE ("Returning %d\n", ret);
1251     return ret;
1252 }
1253 
1254 /*************************************************************************
1255  *				SQLFreeStmt           [ODBC32.016]
1256  */
1257 SQLRETURN WINAPI ODBC32_SQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option)
1258 {
1259     SQLRETURN ret;
1260 
1261     TRACE("(StatementHandle %p, Option %d)\n", StatementHandle, Option);
1262 
1263     if (!pSQLFreeStmt) return SQL_ERROR;
1264 
1265     ret = pSQLFreeStmt(StatementHandle, Option);
1266     TRACE("Returning %d\n", ret);
1267     return ret;
1268 }
1269 
1270 /*************************************************************************
1271  *				SQLGetConnectAttr           [ODBC32.032]
1272  */
1273 SQLRETURN WINAPI ODBC32_SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value,
1274                                           SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1275 {
1276     SQLRETURN ret;
1277 
1278     TRACE("(ConnectionHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n", ConnectionHandle,
1279           Attribute, Value, BufferLength, StringLength);
1280 
1281     if (!pSQLGetConnectAttr) return SQL_ERROR;
1282 
1283     ret = pSQLGetConnectAttr(ConnectionHandle, Attribute, Value, BufferLength, StringLength);
1284     TRACE("Returning %d\n", ret);
1285     return ret;
1286 }
1287 
1288 /*************************************************************************
1289  *				SQLGetConnectOption       [ODBC32.042]
1290  */
1291 SQLRETURN WINAPI ODBC32_SQLGetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLPOINTER Value)
1292 {
1293     SQLRETURN ret;
1294 
1295     TRACE("(ConnectionHandle %p, Option %d, Value %p)\n", ConnectionHandle, Option, Value);
1296 
1297     if (!pSQLGetConnectOption) return SQL_ERROR;
1298 
1299     ret = pSQLGetConnectOption(ConnectionHandle, Option, Value);
1300     TRACE("Returning %d\n", ret);
1301     return ret;
1302 }
1303 
1304 /*************************************************************************
1305  *				SQLGetCursorName           [ODBC32.017]
1306  */
1307 SQLRETURN WINAPI ODBC32_SQLGetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLSMALLINT BufferLength,
1308                                          SQLSMALLINT *NameLength)
1309 {
1310     SQLRETURN ret;
1311 
1312     TRACE("(StatementHandle %p, CursorName %p, BufferLength %d, NameLength %p)\n", StatementHandle, CursorName,
1313           BufferLength, NameLength);
1314 
1315     if (!pSQLGetCursorName) return SQL_ERROR;
1316 
1317     ret = pSQLGetCursorName(StatementHandle, CursorName, BufferLength, NameLength);
1318     TRACE("Returning %d\n", ret);
1319     return ret;
1320 }
1321 
1322 /*************************************************************************
1323  *				SQLGetData           [ODBC32.043]
1324  */
1325 SQLRETURN WINAPI ODBC32_SQLGetData(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType,
1326                                    SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind)
1327 {
1328     SQLRETURN ret;
1329 
1330     TRACE("(StatementHandle %p, ColumnNumber %d, TargetType %d, TargetValue %p, BufferLength %s, StrLen_or_Ind %p)\n",
1331           StatementHandle, ColumnNumber, TargetType, TargetValue, debugstr_sqllen(BufferLength), StrLen_or_Ind);
1332 
1333     if (!pSQLGetData) return SQL_ERROR;
1334 
1335     ret = pSQLGetData(StatementHandle, ColumnNumber, TargetType, TargetValue, BufferLength, StrLen_or_Ind);
1336     TRACE("Returning %d\n", ret);
1337     return ret;
1338 }
1339 
1340 /*************************************************************************
1341  *				SQLGetDescField           [ODBC32.033]
1342  */
1343 SQLRETURN WINAPI ODBC32_SQLGetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
1344                                         SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1345 {
1346     SQLRETURN ret;
1347 
1348     TRACE("(DescriptorHandle %p, RecNumber %d, FieldIdentifier %d, Value %p, BufferLength %d, StringLength %p)\n",
1349           DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
1350 
1351     if (!pSQLGetDescField) return SQL_ERROR;
1352 
1353     ret = pSQLGetDescField(DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
1354     TRACE("Returning %d\n", ret);
1355     return ret;
1356 }
1357 
1358 /*************************************************************************
1359  *				SQLGetDescRec           [ODBC32.034]
1360  */
1361 SQLRETURN WINAPI ODBC32_SQLGetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLCHAR *Name,
1362                                       SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLSMALLINT *Type,
1363                                       SQLSMALLINT *SubType, SQLLEN *Length, SQLSMALLINT *Precision,
1364                                       SQLSMALLINT *Scale, SQLSMALLINT *Nullable)
1365 {
1366     SQLRETURN ret;
1367 
1368     TRACE("(DescriptorHandle %p, RecNumber %d, Name %p, BufferLength %d, StringLength %p, Type %p, SubType %p,"
1369           " Length %p, Precision %p, Scale %p, Nullable %p)\n", DescriptorHandle, RecNumber, Name, BufferLength,
1370           StringLength, Type, SubType, Length, Precision, Scale, Nullable);
1371 
1372     if (!pSQLGetDescRec) return SQL_ERROR;
1373 
1374     ret = pSQLGetDescRec(DescriptorHandle, RecNumber, Name, BufferLength, StringLength, Type, SubType, Length,
1375                          Precision, Scale, Nullable);
1376     TRACE("Returning %d\n", ret);
1377     return ret;
1378 }
1379 
1380 /*************************************************************************
1381  *				SQLGetDiagField           [ODBC32.035]
1382  */
1383 SQLRETURN WINAPI ODBC32_SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber,
1384                                         SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength,
1385                                         SQLSMALLINT *StringLength)
1386 {
1387     SQLRETURN ret;
1388 
1389     TRACE("(HandleType %d, Handle %p, RecNumber %d, DiagIdentifier %d, DiagInfo %p, BufferLength %d,"
1390           " StringLength %p)\n", HandleType, Handle, RecNumber, DiagIdentifier, DiagInfo, BufferLength, StringLength);
1391 
1392     if (!pSQLGetDiagField) return SQL_ERROR;
1393 
1394     ret = pSQLGetDiagField(HandleType, Handle, RecNumber, DiagIdentifier, DiagInfo, BufferLength, StringLength);
1395     TRACE("Returning %d\n", ret);
1396     return ret;
1397 }
1398 
1399 /*************************************************************************
1400  *				SQLGetDiagRec           [ODBC32.036]
1401  */
1402 SQLRETURN WINAPI ODBC32_SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber,
1403                                       SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText,
1404                                       SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
1405 {
1406     SQLRETURN ret;
1407 
1408     TRACE("(HandleType %d, Handle %p, RecNumber %d, Sqlstate %p, NativeError %p, MessageText %p, BufferLength %d,"
1409           " TextLength %p)\n", HandleType, Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength,
1410           TextLength);
1411 
1412     if (!pSQLGetDiagRec) return SQL_ERROR;
1413 
1414     ret = pSQLGetDiagRec(HandleType, Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength, TextLength);
1415     TRACE("Returning %d\n", ret);
1416     return ret;
1417 }
1418 
1419 /*************************************************************************
1420  *				SQLGetEnvAttr           [ODBC32.037]
1421  */
1422 SQLRETURN WINAPI ODBC32_SQLGetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value,
1423                                       SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1424 {
1425     SQLRETURN ret;
1426 
1427     TRACE("(EnvironmentHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n",
1428           EnvironmentHandle, Attribute, Value, BufferLength, StringLength);
1429 
1430     if (!pSQLGetEnvAttr) return SQL_ERROR;
1431 
1432     ret = pSQLGetEnvAttr(EnvironmentHandle, Attribute, Value, BufferLength, StringLength);
1433     TRACE("Returning %d\n", ret);
1434     return ret;
1435 }
1436 
1437 /*************************************************************************
1438  *				SQLGetFunctions           [ODBC32.044]
1439  */
1440 SQLRETURN WINAPI ODBC32_SQLGetFunctions(SQLHDBC ConnectionHandle, SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported)
1441 {
1442     SQLRETURN ret;
1443 
1444     TRACE("(ConnectionHandle %p, FunctionId %d, Supported %p)\n", ConnectionHandle, FunctionId, Supported);
1445 
1446     if (!pSQLGetFunctions) return SQL_ERROR;
1447 
1448     ret = pSQLGetFunctions(ConnectionHandle, FunctionId, Supported);
1449     TRACE("Returning %d\n", ret);
1450     return ret;
1451 }
1452 
1453 /*************************************************************************
1454  *				SQLGetInfo           [ODBC32.045]
1455  */
1456 SQLRETURN WINAPI ODBC32_SQLGetInfo(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue,
1457                                    SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
1458 {
1459     SQLRETURN ret;
1460 
1461     TRACE("(ConnectionHandle, %p, InfoType %d, InfoValue %p, BufferLength %d, StringLength %p)\n", ConnectionHandle,
1462           InfoType, InfoValue, BufferLength, StringLength);
1463 
1464     if (!InfoValue)
1465     {
1466         WARN("Unexpected NULL InfoValue address\n");
1467         return SQL_ERROR;
1468     }
1469 
1470     if (!pSQLGetInfo) return SQL_ERROR;
1471 
1472     ret = pSQLGetInfo(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength);
1473     TRACE("Returning %d\n", ret);
1474     return ret;
1475 }
1476 
1477 /*************************************************************************
1478  *				SQLGetStmtAttr           [ODBC32.038]
1479  */
1480 SQLRETURN WINAPI ODBC32_SQLGetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value,
1481                                        SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1482 {
1483     SQLRETURN ret;
1484 
1485     TRACE("(StatementHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n", StatementHandle,
1486           Attribute, Value, BufferLength, StringLength);
1487 
1488     if (!Value)
1489     {
1490         WARN("Unexpected NULL Value return address\n");
1491         return SQL_ERROR;
1492     }
1493 
1494     if (!pSQLGetStmtAttr) return SQL_ERROR;
1495 
1496     ret = pSQLGetStmtAttr(StatementHandle, Attribute, Value, BufferLength, StringLength);
1497     TRACE("Returning %d\n", ret);
1498     return ret;
1499 }
1500 
1501 /*************************************************************************
1502  *				SQLGetStmtOption           [ODBC32.046]
1503  */
1504 SQLRETURN WINAPI ODBC32_SQLGetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLPOINTER Value)
1505 {
1506     SQLRETURN ret;
1507 
1508     TRACE("(StatementHandle %p, Option %d, Value %p)\n", StatementHandle, Option, Value);
1509 
1510     if (!pSQLGetStmtOption) return SQL_ERROR;
1511 
1512     ret = pSQLGetStmtOption(StatementHandle, Option, Value);
1513     TRACE("Returning %d\n", ret);
1514     return ret;
1515 }
1516 
1517 /*************************************************************************
1518  *				SQLGetTypeInfo           [ODBC32.047]
1519  */
1520 SQLRETURN WINAPI ODBC32_SQLGetTypeInfo(SQLHSTMT StatementHandle, SQLSMALLINT DataType)
1521 {
1522     SQLRETURN ret;
1523 
1524     TRACE("(StatementHandle %p, DataType %d)\n", StatementHandle, DataType);
1525 
1526     if (!pSQLGetTypeInfo) return SQL_ERROR;
1527 
1528     ret = pSQLGetTypeInfo(StatementHandle, DataType);
1529     TRACE("Returning %d\n", ret);
1530     return ret;
1531 }
1532 
1533 /*************************************************************************
1534  *				SQLNumResultCols           [ODBC32.018]
1535  */
1536 SQLRETURN WINAPI ODBC32_SQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount)
1537 {
1538     SQLRETURN ret;
1539 
1540     TRACE("(StatementHandle %p, ColumnCount %p)\n", StatementHandle, ColumnCount);
1541 
1542     if (!pSQLNumResultCols) return SQL_ERROR;
1543 
1544     ret = pSQLNumResultCols(StatementHandle, ColumnCount);
1545     TRACE("Returning %d ColumnCount %d\n", ret, *ColumnCount);
1546     return ret;
1547 }
1548 
1549 /*************************************************************************
1550  *				SQLParamData           [ODBC32.048]
1551  */
1552 SQLRETURN WINAPI ODBC32_SQLParamData(SQLHSTMT StatementHandle, SQLPOINTER *Value)
1553 {
1554     SQLRETURN ret;
1555 
1556     TRACE("(StatementHandle %p, Value %p)\n", StatementHandle, Value);
1557 
1558     if (!pSQLParamData) return SQL_ERROR;
1559 
1560     ret = pSQLParamData(StatementHandle, Value);
1561     TRACE("Returning %d\n", ret);
1562     return ret;
1563 }
1564 
1565 /*************************************************************************
1566  *				SQLPrepare           [ODBC32.019]
1567  */
1568 SQLRETURN WINAPI ODBC32_SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength)
1569 {
1570     SQLRETURN ret;
1571 
1572     TRACE("(StatementHandle %p, StatementText %s, TextLength %d)\n", StatementHandle,
1573           debugstr_an((const char *)StatementText, TextLength), TextLength);
1574 
1575     if (!pSQLPrepare) return SQL_ERROR;
1576 
1577     ret = pSQLPrepare(StatementHandle, StatementText, TextLength);
1578     TRACE("Returning %d\n", ret);
1579     return ret;
1580 }
1581 
1582 /*************************************************************************
1583  *				SQLPutData           [ODBC32.049]
1584  */
1585 SQLRETURN WINAPI ODBC32_SQLPutData(SQLHSTMT StatementHandle, SQLPOINTER Data, SQLLEN StrLen_or_Ind)
1586 {
1587     SQLRETURN ret;
1588 
1589     TRACE("(StatementHandle %p, Data %p, StrLen_or_Ind %s)\n", StatementHandle, Data, debugstr_sqllen(StrLen_or_Ind));
1590 
1591     if (!pSQLPutData) return SQL_ERROR;
1592 
1593     ret = pSQLPutData(StatementHandle, Data, StrLen_or_Ind);
1594     TRACE("Returning %d\n", ret);
1595     return ret;
1596 }
1597 
1598 /*************************************************************************
1599  *				SQLRowCount           [ODBC32.020]
1600  */
1601 SQLRETURN WINAPI ODBC32_SQLRowCount(SQLHSTMT StatementHandle, SQLLEN *RowCount)
1602 {
1603     SQLRETURN ret;
1604 
1605     TRACE("(StatementHandle %p, RowCount %p)\n", StatementHandle, RowCount);
1606 
1607     if (!pSQLRowCount) return SQL_ERROR;
1608 
1609     ret = pSQLRowCount(StatementHandle, RowCount);
1610     if (ret == SQL_SUCCESS && RowCount) TRACE(" RowCount %s\n", debugstr_sqllen(*RowCount));
1611     TRACE("Returning %d\n", ret);
1612     return ret;
1613 }
1614 
1615 /*************************************************************************
1616  *				SQLSetConnectAttr           [ODBC32.039]
1617  */
1618 SQLRETURN WINAPI ODBC32_SQLSetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value,
1619                                           SQLINTEGER StringLength)
1620 {
1621     SQLRETURN ret;
1622 
1623     TRACE("(ConnectionHandle %p, Attribute %d, Value %p, StringLength %d)\n", ConnectionHandle, Attribute, Value,
1624           StringLength);
1625 
1626     if (!pSQLSetConnectAttr) return SQL_ERROR;
1627 
1628     ret = pSQLSetConnectAttr(ConnectionHandle, Attribute, Value, StringLength);
1629     TRACE("Returning %d\n", ret);
1630     return ret;
1631 }
1632 
1633 /*************************************************************************
1634  *				SQLSetConnectOption           [ODBC32.050]
1635  */
1636 SQLRETURN WINAPI ODBC32_SQLSetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLULEN Value)
1637 {
1638     SQLRETURN ret;
1639 
1640     TRACE("(ConnectionHandle %p, Option %d, Value %s)\n", ConnectionHandle, Option, debugstr_sqlulen(Value));
1641 
1642     if (!pSQLSetConnectOption) return SQL_ERROR;
1643 
1644     ret = pSQLSetConnectOption(ConnectionHandle, Option, Value);
1645     TRACE("Returning %d\n", ret);
1646     return ret;
1647 }
1648 
1649 /*************************************************************************
1650  *				SQLSetCursorName           [ODBC32.021]
1651  */
1652 SQLRETURN WINAPI ODBC32_SQLSetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLSMALLINT NameLength)
1653 {
1654     SQLRETURN ret;
1655 
1656     TRACE("(StatementHandle %p, CursorName %s, NameLength %d)\n", StatementHandle,
1657           debugstr_an((const char *)CursorName, NameLength), NameLength);
1658 
1659     if (!pSQLSetCursorName) return SQL_ERROR;
1660 
1661     ret = pSQLSetCursorName(StatementHandle, CursorName, NameLength);
1662     TRACE("Returning %d\n", ret);
1663     return ret;
1664 }
1665 
1666 /*************************************************************************
1667  *				SQLSetDescField           [ODBC32.073]
1668  */
1669 SQLRETURN WINAPI ODBC32_SQLSetDescField(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
1670                                         SQLPOINTER Value, SQLINTEGER BufferLength)
1671 {
1672     SQLRETURN ret;
1673 
1674     TRACE("(DescriptorHandle %p, RecNumber %d, FieldIdentifier %d, Value %p, BufferLength %d)\n", DescriptorHandle,
1675           RecNumber, FieldIdentifier, Value, BufferLength);
1676 
1677     if (!pSQLSetDescField) return SQL_ERROR;
1678 
1679     ret = pSQLSetDescField(DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength);
1680     TRACE("Returning %d\n", ret);
1681     return ret;
1682 }
1683 
1684 /*************************************************************************
1685  *				SQLSetDescRec           [ODBC32.074]
1686  */
1687 SQLRETURN WINAPI ODBC32_SQLSetDescRec(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT Type,
1688                                       SQLSMALLINT SubType, SQLLEN Length, SQLSMALLINT Precision, SQLSMALLINT Scale,
1689                                       SQLPOINTER Data, SQLLEN *StringLength, SQLLEN *Indicator)
1690 {
1691     SQLRETURN ret;
1692 
1693     TRACE("(DescriptorHandle %p, RecNumber %d, Type %d, SubType %d, Length %s, Precision %d, Scale %d, Data %p,"
1694           " StringLength %p, Indicator %p)\n", DescriptorHandle, RecNumber, Type, SubType, debugstr_sqllen(Length),
1695           Precision, Scale, Data, StringLength, Indicator);
1696 
1697     if (!pSQLSetDescRec) return SQL_ERROR;
1698 
1699     ret = pSQLSetDescRec(DescriptorHandle, RecNumber, Type, SubType, Length, Precision, Scale, Data,
1700                          StringLength, Indicator);
1701     TRACE("Returning %d\n", ret);
1702     return ret;
1703 }
1704 
1705 /*************************************************************************
1706  *				SQLSetEnvAttr           [ODBC32.075]
1707  */
1708 SQLRETURN WINAPI ODBC32_SQLSetEnvAttr(SQLHENV EnvironmentHandle, SQLINTEGER Attribute, SQLPOINTER Value,
1709                                       SQLINTEGER StringLength)
1710 {
1711     SQLRETURN ret;
1712 
1713     TRACE("(EnvironmentHandle %p, Attribute %d, Value %p, StringLength %d)\n", EnvironmentHandle, Attribute, Value,
1714           StringLength);
1715 
1716     if (!pSQLSetEnvAttr) return SQL_ERROR;
1717 
1718     ret = pSQLSetEnvAttr(EnvironmentHandle, Attribute, Value, StringLength);
1719     TRACE("Returning %d\n", ret);
1720     return ret;
1721 }
1722 
1723 /*************************************************************************
1724  *				SQLSetParam           [ODBC32.022]
1725  */
1726 SQLRETURN WINAPI ODBC32_SQLSetParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
1727                                     SQLSMALLINT ParameterType, SQLULEN LengthPrecision, SQLSMALLINT ParameterScale,
1728                                     SQLPOINTER ParameterValue, SQLLEN *StrLen_or_Ind)
1729 {
1730     SQLRETURN ret;
1731 
1732     TRACE("(StatementHandle %p, ParameterNumber %d, ValueType %d, ParameterType %d, LengthPrecision %s,"
1733           " ParameterScale %d, ParameterValue %p, StrLen_or_Ind %p)\n", StatementHandle, ParameterNumber, ValueType,
1734           ParameterType, debugstr_sqlulen(LengthPrecision), ParameterScale, ParameterValue, StrLen_or_Ind);
1735 
1736     if (!pSQLSetParam) return SQL_ERROR;
1737 
1738     ret = pSQLSetParam(StatementHandle, ParameterNumber, ValueType, ParameterType, LengthPrecision,
1739                        ParameterScale, ParameterValue, StrLen_or_Ind);
1740     TRACE("Returning %d\n", ret);
1741     return ret;
1742 }
1743 
1744 /*************************************************************************
1745  *				SQLSetStmtAttr           [ODBC32.076]
1746  */
1747 SQLRETURN WINAPI ODBC32_SQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value,
1748                                        SQLINTEGER StringLength)
1749 {
1750     SQLRETURN ret;
1751 
1752     TRACE("(StatementHandle %p, Attribute %d, Value %p, StringLength %d)\n", StatementHandle, Attribute, Value,
1753           StringLength);
1754 
1755     if (!pSQLSetStmtAttr) return SQL_ERROR;
1756 
1757     ret = pSQLSetStmtAttr(StatementHandle, Attribute, Value, StringLength);
1758     TRACE("Returning %d\n", ret);
1759     return ret;
1760 }
1761 
1762 /*************************************************************************
1763  *				SQLSetStmtOption           [ODBC32.051]
1764  */
1765 SQLRETURN WINAPI ODBC32_SQLSetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLULEN Value)
1766 {
1767     SQLRETURN ret;
1768 
1769     TRACE("(StatementHandle %p, Option %d, Value %s)\n", StatementHandle, Option, debugstr_sqlulen(Value));
1770 
1771     if (!pSQLSetStmtOption) return SQL_ERROR;
1772 
1773     ret = pSQLSetStmtOption(StatementHandle, Option, Value);
1774     TRACE("Returning %d\n", ret);
1775     return ret;
1776 }
1777 
1778 /*************************************************************************
1779  *				SQLSpecialColumns           [ODBC32.052]
1780  */
1781 SQLRETURN WINAPI ODBC32_SQLSpecialColumns(SQLHSTMT StatementHandle, SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName,
1782                                           SQLSMALLINT NameLength1, SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
1783                                           SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Scope,
1784                                           SQLUSMALLINT Nullable)
1785 {
1786     SQLRETURN ret;
1787 
1788     TRACE("(StatementHandle %p, IdentifierType %d, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d,"
1789           " TableName %s, NameLength3 %d, Scope %d, Nullable %d)\n", StatementHandle, IdentifierType,
1790           debugstr_an((const char *)CatalogName, NameLength1), NameLength1,
1791           debugstr_an((const char *)SchemaName, NameLength2), NameLength2,
1792           debugstr_an((const char *)TableName, NameLength3), NameLength3, Scope, Nullable);
1793 
1794     if (!pSQLSpecialColumns) return SQL_ERROR;
1795 
1796     ret = pSQLSpecialColumns(StatementHandle, IdentifierType, CatalogName, NameLength1, SchemaName,
1797                              NameLength2, TableName, NameLength3, Scope, Nullable);
1798     TRACE("Returning %d\n", ret);
1799     return ret;
1800 }
1801 
1802 /*************************************************************************
1803  *				SQLStatistics           [ODBC32.053]
1804  */
1805 SQLRETURN WINAPI ODBC32_SQLStatistics(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
1806                                       SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName,
1807                                       SQLSMALLINT NameLength3, SQLUSMALLINT Unique, SQLUSMALLINT Reserved)
1808 {
1809     SQLRETURN ret;
1810 
1811     TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d SchemaName %s, NameLength2 %d, TableName %s"
1812           " NameLength3 %d, Unique %d, Reserved %d)\n", StatementHandle,
1813           debugstr_an((const char *)CatalogName, NameLength1), NameLength1,
1814           debugstr_an((const char *)SchemaName, NameLength2), NameLength2,
1815           debugstr_an((const char *)TableName, NameLength3), NameLength3, Unique, Reserved);
1816 
1817     if (!pSQLStatistics) return SQL_ERROR;
1818 
1819     ret = pSQLStatistics(StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2, TableName,
1820                          NameLength3, Unique, Reserved);
1821     TRACE("Returning %d\n", ret);
1822     return ret;
1823 }
1824 
1825 /*************************************************************************
1826  *				SQLTables           [ODBC32.054]
1827  */
1828 SQLRETURN WINAPI ODBC32_SQLTables(SQLHSTMT StatementHandle, SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
1829                                   SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName,
1830                                   SQLSMALLINT NameLength3, SQLCHAR *TableType, SQLSMALLINT NameLength4)
1831 {
1832     SQLRETURN ret;
1833 
1834     TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s,"
1835           " NameLength3 %d, TableType %s, NameLength4 %d)\n", StatementHandle,
1836           debugstr_an((const char *)CatalogName, NameLength1), NameLength1,
1837           debugstr_an((const char *)SchemaName, NameLength2), NameLength2,
1838           debugstr_an((const char *)TableName, NameLength3), NameLength3,
1839           debugstr_an((const char *)TableType, NameLength4), NameLength4);
1840 
1841     if (!pSQLTables) return SQL_ERROR;
1842 
1843     ret = pSQLTables(StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2, TableName, NameLength3,
1844                      TableType, NameLength4);
1845     TRACE("Returning %d\n", ret);
1846     return ret;
1847 }
1848 
1849 /*************************************************************************
1850  *				SQLTransact           [ODBC32.023]
1851  */
1852 SQLRETURN WINAPI ODBC32_SQLTransact(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, SQLUSMALLINT CompletionType)
1853 {
1854     SQLRETURN ret;
1855 
1856     TRACE("(EnvironmentHandle %p, ConnectionHandle %p, CompletionType %d)\n", EnvironmentHandle, ConnectionHandle,
1857           CompletionType);
1858 
1859     if (!pSQLTransact) return SQL_ERROR;
1860 
1861     ret = pSQLTransact(EnvironmentHandle, ConnectionHandle, CompletionType);
1862     TRACE("Returning %d\n", ret);
1863     return ret;
1864 }
1865 
1866 /*************************************************************************
1867  *				SQLBrowseConnect           [ODBC32.055]
1868  */
1869 SQLRETURN WINAPI ODBC32_SQLBrowseConnect(SQLHDBC hdbc, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn,
1870                                          SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax,
1871                                          SQLSMALLINT *pcbConnStrOut)
1872 {
1873     SQLRETURN ret;
1874 
1875     TRACE("(hdbc %p, szConnStrIn %s, cbConnStrIn %d, szConnStrOut %p, cbConnStrOutMax %d, pcbConnStrOut %p)\n",
1876           hdbc, debugstr_an((const char *)szConnStrIn, cbConnStrIn), cbConnStrIn, szConnStrOut, cbConnStrOutMax,
1877           pcbConnStrOut);
1878 
1879     if (!pSQLBrowseConnect) return SQL_ERROR;
1880 
1881     ret = pSQLBrowseConnect(hdbc, szConnStrIn, cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut);
1882     TRACE("Returning %d\n", ret);
1883     return ret;
1884 }
1885 
1886 /*************************************************************************
1887  *				SQLBulkOperations           [ODBC32.078]
1888  */
1889 SQLRETURN WINAPI ODBC32_SQLBulkOperations(SQLHSTMT StatementHandle, SQLSMALLINT Operation)
1890 {
1891     SQLRETURN ret;
1892 
1893     TRACE("(StatementHandle %p, Operation %d)\n", StatementHandle, Operation);
1894 
1895     if (!pSQLBulkOperations) return SQL_ERROR;
1896 
1897     ret = pSQLBulkOperations(StatementHandle, Operation);
1898     TRACE("Returning %d\n", ret);
1899     return ret;
1900 }
1901 
1902 /*************************************************************************
1903  *				SQLColAttributes           [ODBC32.006]
1904  */
1905 SQLRETURN WINAPI ODBC32_SQLColAttributes(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,
1906                                          SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT *pcbDesc,
1907                                          SQLLEN *pfDesc)
1908 {
1909     SQLRETURN ret;
1910 
1911     TRACE("(hstmt %p, icol %d, fDescType %d, rgbDesc %p, cbDescMax %d, pcbDesc %p, pfDesc %p)\n", hstmt, icol,
1912           fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
1913 
1914     if (!pSQLColAttributes) return SQL_ERROR;
1915 
1916     ret = pSQLColAttributes(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
1917     TRACE("Returning %d\n", ret);
1918     return ret;
1919 }
1920 
1921 /*************************************************************************
1922  *				SQLColumnPrivileges           [ODBC32.056]
1923  */
1924 SQLRETURN WINAPI ODBC32_SQLColumnPrivileges(SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
1925                                             SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName,
1926                                             SQLSMALLINT cbTableName, SQLCHAR *szColumnName, SQLSMALLINT cbColumnName)
1927 {
1928     SQLRETURN ret;
1929 
1930     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szTableName %s,"
1931           " cbTableName %d, szColumnName %s, cbColumnName %d)\n", hstmt,
1932           debugstr_an((const char *)szCatalogName, cbCatalogName), cbCatalogName,
1933           debugstr_an((const char *)szSchemaName, cbSchemaName), cbSchemaName,
1934           debugstr_an((const char *)szTableName, cbTableName), cbTableName,
1935           debugstr_an((const char *)szColumnName, cbColumnName), cbColumnName);
1936 
1937     if (!pSQLColumnPrivileges) return SQL_ERROR;
1938 
1939     ret = pSQLColumnPrivileges(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1940                                szTableName, cbTableName, szColumnName, cbColumnName);
1941     TRACE("Returning %d\n", ret);
1942     return ret;
1943 }
1944 
1945 /*************************************************************************
1946  *				SQLDescribeParam          [ODBC32.058]
1947  */
1948 SQLRETURN WINAPI ODBC32_SQLDescribeParam(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT *pfSqlType,
1949                                          SQLULEN *pcbParamDef, SQLSMALLINT *pibScale, SQLSMALLINT *pfNullable)
1950 {
1951     SQLRETURN ret;
1952 
1953     TRACE("(hstmt %p, ipar %d, pfSqlType %p, pcbParamDef %p, pibScale %p, pfNullable %p)\n", hstmt, ipar,
1954           pfSqlType, pcbParamDef, pibScale, pfNullable);
1955 
1956     if (!pSQLDescribeParam) return SQL_ERROR;
1957 
1958     ret = pSQLDescribeParam(hstmt, ipar, pfSqlType, pcbParamDef, pibScale, pfNullable);
1959     TRACE("Returning %d\n", ret);
1960     return ret;
1961 }
1962 
1963 /*************************************************************************
1964  *				SQLExtendedFetch           [ODBC32.059]
1965  */
1966 SQLRETURN WINAPI ODBC32_SQLExtendedFetch(SQLHSTMT hstmt, SQLUSMALLINT fFetchType, SQLLEN irow, SQLULEN *pcrow,
1967                                          SQLUSMALLINT *rgfRowStatus)
1968 {
1969     SQLRETURN ret;
1970 
1971     TRACE("(hstmt %p, fFetchType %d, irow %s, pcrow %p, rgfRowStatus %p)\n", hstmt, fFetchType, debugstr_sqllen(irow),
1972           pcrow, rgfRowStatus);
1973 
1974     if (!pSQLExtendedFetch) return SQL_ERROR;
1975 
1976     ret = pSQLExtendedFetch(hstmt, fFetchType, irow, pcrow, rgfRowStatus);
1977     TRACE("Returning %d\n", ret);
1978     return ret;
1979 }
1980 
1981 /*************************************************************************
1982  *				SQLForeignKeys           [ODBC32.060]
1983  */
1984 SQLRETURN WINAPI ODBC32_SQLForeignKeys(SQLHSTMT hstmt, SQLCHAR *szPkCatalogName, SQLSMALLINT cbPkCatalogName,
1985                                        SQLCHAR *szPkSchemaName, SQLSMALLINT cbPkSchemaName, SQLCHAR *szPkTableName,
1986                                        SQLSMALLINT cbPkTableName, SQLCHAR *szFkCatalogName,
1987                                        SQLSMALLINT cbFkCatalogName, SQLCHAR *szFkSchemaName,
1988                                        SQLSMALLINT cbFkSchemaName, SQLCHAR *szFkTableName, SQLSMALLINT cbFkTableName)
1989 {
1990     SQLRETURN ret;
1991 
1992     TRACE("(hstmt %p, szPkCatalogName %s, cbPkCatalogName %d, szPkSchemaName %s, cbPkSchemaName %d,"
1993           " szPkTableName %s, cbPkTableName %d, szFkCatalogName %s, cbFkCatalogName %d, szFkSchemaName %s,"
1994           " cbFkSchemaName %d, szFkTableName %s, cbFkTableName %d)\n", hstmt,
1995           debugstr_an((const char *)szPkCatalogName, cbPkCatalogName), cbPkCatalogName,
1996           debugstr_an((const char *)szPkSchemaName, cbPkSchemaName), cbPkSchemaName,
1997           debugstr_an((const char *)szPkTableName, cbPkTableName), cbPkTableName,
1998           debugstr_an((const char *)szFkCatalogName, cbFkCatalogName), cbFkCatalogName,
1999           debugstr_an((const char *)szFkSchemaName, cbFkSchemaName), cbFkSchemaName,
2000           debugstr_an((const char *)szFkTableName, cbFkTableName), cbFkTableName);
2001 
2002     if (!pSQLForeignKeys) return SQL_ERROR;
2003 
2004     ret = pSQLForeignKeys(hstmt, szPkCatalogName, cbPkCatalogName, szPkSchemaName, cbPkSchemaName, szPkTableName,
2005                           cbPkTableName, szFkCatalogName, cbFkCatalogName, szFkSchemaName, cbFkSchemaName,
2006                           szFkTableName, cbFkTableName);
2007     TRACE("Returning %d\n", ret);
2008     return ret;
2009 }
2010 
2011 /*************************************************************************
2012  *				SQLMoreResults           [ODBC32.061]
2013  */
2014 SQLRETURN WINAPI ODBC32_SQLMoreResults(SQLHSTMT StatementHandle)
2015 {
2016     SQLRETURN ret;
2017 
2018     TRACE("(%p)\n", StatementHandle);
2019 
2020     if (!pSQLMoreResults) return SQL_ERROR;
2021 
2022     ret = pSQLMoreResults(StatementHandle);
2023     TRACE("Returning %d\n", ret);
2024     return ret;
2025 }
2026 
2027 /*************************************************************************
2028  *				SQLNativeSql           [ODBC32.062]
2029  */
2030 SQLRETURN WINAPI ODBC32_SQLNativeSql(SQLHDBC hdbc, SQLCHAR *szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLCHAR *szSqlStr,
2031                                      SQLINTEGER cbSqlStrMax, SQLINTEGER *pcbSqlStr)
2032 {
2033     SQLRETURN ret;
2034 
2035     TRACE("(hdbc %p, szSqlStrIn %s, cbSqlStrIn %d, szSqlStr %p, cbSqlStrMax %d, pcbSqlStr %p)\n", hdbc,
2036           debugstr_an((const char *)szSqlStrIn, cbSqlStrIn), cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr);
2037 
2038     if (!pSQLNativeSql) return SQL_ERROR;
2039 
2040     ret = pSQLNativeSql(hdbc, szSqlStrIn, cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr);
2041     TRACE("Returning %d\n", ret);
2042     return ret;
2043 }
2044 
2045 /*************************************************************************
2046  *				SQLNumParams           [ODBC32.063]
2047  */
2048 SQLRETURN WINAPI ODBC32_SQLNumParams(SQLHSTMT hstmt, SQLSMALLINT *pcpar)
2049 {
2050     SQLRETURN ret;
2051 
2052     TRACE("(hstmt %p, pcpar %p)\n", hstmt, pcpar);
2053 
2054     if (!pSQLNumParams) return SQL_ERROR;
2055 
2056     ret = pSQLNumParams(hstmt, pcpar);
2057     TRACE("Returning %d\n", ret);
2058     return ret;
2059 }
2060 
2061 /*************************************************************************
2062  *				SQLParamOptions           [ODBC32.064]
2063  */
2064 SQLRETURN WINAPI ODBC32_SQLParamOptions(SQLHSTMT hstmt, SQLULEN crow, SQLULEN *pirow)
2065 {
2066     SQLRETURN ret;
2067 
2068     TRACE("(hstmt %p, crow %s, pirow %p)\n", hstmt, debugstr_sqlulen(crow), pirow);
2069 
2070     if (!pSQLParamOptions) return SQL_ERROR;
2071 
2072     ret = pSQLParamOptions(hstmt, crow, pirow);
2073     TRACE("Returning %d\n", ret);
2074     return ret;
2075 }
2076 
2077 /*************************************************************************
2078  *				SQLPrimaryKeys           [ODBC32.065]
2079  */
2080 SQLRETURN WINAPI ODBC32_SQLPrimaryKeys(SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
2081                                        SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName,
2082                                        SQLSMALLINT cbTableName)
2083 {
2084     SQLRETURN ret;
2085 
2086     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szTableName %s,"
2087           " cbTableName %d)\n", hstmt,
2088           debugstr_an((const char *)szCatalogName, cbCatalogName), cbCatalogName,
2089           debugstr_an((const char *)szSchemaName, cbSchemaName), cbSchemaName,
2090           debugstr_an((const char *)szTableName, cbTableName), cbTableName);
2091 
2092     if (!pSQLPrimaryKeys) return SQL_ERROR;
2093 
2094     ret = pSQLPrimaryKeys(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName);
2095     TRACE("Returning %d\n", ret);
2096     return ret;
2097 }
2098 
2099 /*************************************************************************
2100  *				SQLProcedureColumns           [ODBC32.066]
2101  */
2102 SQLRETURN WINAPI ODBC32_SQLProcedureColumns(SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
2103                                             SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szProcName,
2104                                             SQLSMALLINT cbProcName, SQLCHAR *szColumnName, SQLSMALLINT cbColumnName)
2105 {
2106     SQLRETURN ret;
2107 
2108     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szProcName %s,"
2109           " cbProcName %d, szColumnName %s, cbColumnName %d)\n", hstmt,
2110           debugstr_an((const char *)szCatalogName, cbCatalogName), cbCatalogName,
2111           debugstr_an((const char *)szSchemaName, cbSchemaName), cbSchemaName,
2112           debugstr_an((const char *)szProcName, cbProcName), cbProcName,
2113           debugstr_an((const char *)szColumnName, cbColumnName), cbColumnName);
2114 
2115     if (!pSQLProcedureColumns) return SQL_ERROR;
2116 
2117     ret = pSQLProcedureColumns(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szProcName,
2118                                cbProcName, szColumnName, cbColumnName);
2119     TRACE("Returning %d\n", ret);
2120     return ret;
2121 }
2122 
2123 /*************************************************************************
2124  *				SQLProcedures           [ODBC32.067]
2125  */
2126 SQLRETURN WINAPI ODBC32_SQLProcedures(SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
2127                                       SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szProcName,
2128                                       SQLSMALLINT cbProcName)
2129 {
2130     SQLRETURN ret;
2131 
2132     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szProcName %s,"
2133           " cbProcName %d)\n", hstmt,
2134           debugstr_an((const char *)szCatalogName, cbCatalogName), cbCatalogName,
2135           debugstr_an((const char *)szSchemaName, cbSchemaName), cbSchemaName,
2136           debugstr_an((const char *)szProcName, cbProcName), cbProcName);
2137 
2138     if (!pSQLProcedures) return SQL_ERROR;
2139 
2140     ret = pSQLProcedures(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szProcName, cbProcName);
2141     TRACE("Returning %d\n", ret);
2142     return ret;
2143 }
2144 
2145 /*************************************************************************
2146  *				SQLSetPos           [ODBC32.068]
2147  */
2148 SQLRETURN WINAPI ODBC32_SQLSetPos(SQLHSTMT hstmt, SQLSETPOSIROW irow, SQLUSMALLINT fOption, SQLUSMALLINT fLock)
2149 {
2150     SQLRETURN ret;
2151 
2152     TRACE("(hstmt %p, irow %s, fOption %d, fLock %d)\n", hstmt, debugstr_sqlulen(irow), fOption, fLock);
2153 
2154     if (!pSQLSetPos) return SQL_ERROR;
2155 
2156     ret = pSQLSetPos(hstmt, irow, fOption, fLock);
2157     TRACE("Returning %d\n", ret);
2158     return ret;
2159 }
2160 
2161 /*************************************************************************
2162  *				SQLTablePrivileges           [ODBC32.070]
2163  */
2164 SQLRETURN WINAPI ODBC32_SQLTablePrivileges(SQLHSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
2165                                            SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName,
2166                                            SQLSMALLINT cbTableName)
2167 {
2168     SQLRETURN ret;
2169 
2170     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szTableName %s,"
2171           " cbTableName %d)\n", hstmt,
2172           debugstr_an((const char *)szCatalogName, cbCatalogName), cbCatalogName,
2173           debugstr_an((const char *)szSchemaName, cbSchemaName), cbSchemaName,
2174           debugstr_an((const char *)szTableName, cbTableName), cbTableName);
2175 
2176     if (!pSQLTablePrivileges) return SQL_ERROR;
2177 
2178     ret = pSQLTablePrivileges(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName,
2179                               cbTableName);
2180     TRACE("Returning %d\n", ret);
2181     return ret;
2182 }
2183 
2184 /*************************************************************************
2185  *				SQLDrivers           [ODBC32.071]
2186  */
2187 SQLRETURN WINAPI ODBC32_SQLDrivers(SQLHENV EnvironmentHandle, SQLUSMALLINT fDirection, SQLCHAR *szDriverDesc,
2188                                    SQLSMALLINT cbDriverDescMax, SQLSMALLINT *pcbDriverDesc,
2189                                    SQLCHAR *szDriverAttributes, SQLSMALLINT cbDriverAttrMax,
2190                                    SQLSMALLINT *pcbDriverAttr)
2191 {
2192     SQLRETURN ret;
2193 
2194     TRACE("(EnvironmentHandle %p, Direction %d, szDriverDesc %p, cbDriverDescMax %d, pcbDriverDesc %p,"
2195           " DriverAttributes %p, cbDriverAttrMax %d, pcbDriverAttr %p)\n", EnvironmentHandle, fDirection,
2196           szDriverDesc, cbDriverDescMax, pcbDriverDesc, szDriverAttributes, cbDriverAttrMax, pcbDriverAttr);
2197 
2198     if (!pSQLDrivers) return SQL_ERROR;
2199 
2200     ret = pSQLDrivers(EnvironmentHandle, fDirection, szDriverDesc, cbDriverDescMax, pcbDriverDesc,
2201                       szDriverAttributes, cbDriverAttrMax, pcbDriverAttr);
2202 
2203     if (ret == SQL_NO_DATA && fDirection == SQL_FETCH_FIRST)
2204         ERR_(winediag)("No ODBC drivers could be found. Check the settings for your libodbc provider.\n");
2205 
2206     TRACE("Returning %d\n", ret);
2207     return ret;
2208 }
2209 
2210 /*************************************************************************
2211  *				SQLBindParameter           [ODBC32.072]
2212  */
2213 SQLRETURN WINAPI ODBC32_SQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType,
2214                                          SQLSMALLINT fCType, SQLSMALLINT fSqlType, SQLULEN cbColDef,
2215                                          SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLLEN cbValueMax,
2216                                          SQLLEN *pcbValue)
2217 {
2218     SQLRETURN ret;
2219 
2220     TRACE("(hstmt %p, ipar %d, fParamType %d, fCType %d, fSqlType %d, cbColDef %s, ibScale %d, rgbValue %p,"
2221           " cbValueMax %s, pcbValue %p)\n", hstmt, ipar, fParamType, fCType, fSqlType, debugstr_sqlulen(cbColDef),
2222           ibScale, rgbValue, debugstr_sqllen(cbValueMax), pcbValue);
2223 
2224     if (!pSQLBindParameter) return SQL_ERROR;
2225 
2226     ret = pSQLBindParameter(hstmt, ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, cbValueMax,
2227                             pcbValue);
2228     TRACE("Returning %d\n", ret);
2229     return ret;
2230 }
2231 
2232 /*************************************************************************
2233  *				SQLDriverConnect           [ODBC32.041]
2234  */
2235 SQLRETURN WINAPI ODBC32_SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR *ConnectionString, SQLSMALLINT Length,
2236                                          SQLCHAR *conn_str_out, SQLSMALLINT conn_str_out_max,
2237                                          SQLSMALLINT *ptr_conn_str_out, SQLUSMALLINT driver_completion)
2238 {
2239     SQLRETURN ret;
2240 
2241     TRACE("(hdbc %p, hwnd %p, ConnectionString %s, Length %d, conn_str_out %p, conn_str_out_max %d,"
2242           " ptr_conn_str_out %p, driver_completion %d)\n", hdbc, hwnd,
2243           debugstr_an((const char *)ConnectionString, Length), Length, conn_str_out, conn_str_out_max,
2244           ptr_conn_str_out, driver_completion);
2245 
2246     if (!pSQLDriverConnect) return SQL_ERROR;
2247 
2248     ret = pSQLDriverConnect(hdbc, hwnd, ConnectionString, Length, conn_str_out, conn_str_out_max,
2249                             ptr_conn_str_out, driver_completion);
2250     TRACE("Returning %d\n", ret);
2251     return ret;
2252 }
2253 
2254 /*************************************************************************
2255  *				SQLSetScrollOptions           [ODBC32.069]
2256  */
2257 SQLRETURN WINAPI ODBC32_SQLSetScrollOptions(SQLHSTMT statement_handle, SQLUSMALLINT f_concurrency, SQLLEN crow_keyset,
2258                                             SQLUSMALLINT crow_rowset)
2259 {
2260     SQLRETURN ret;
2261 
2262     TRACE("(statement_handle %p, f_concurrency %d, crow_keyset %s, crow_rowset %d)\n", statement_handle,
2263           f_concurrency, debugstr_sqllen(crow_keyset), crow_rowset);
2264 
2265     if (!pSQLSetScrollOptions) return SQL_ERROR;
2266 
2267     ret = pSQLSetScrollOptions(statement_handle, f_concurrency, crow_keyset, crow_rowset);
2268     TRACE("Returning %d\n", ret);
2269     return ret;
2270 }
2271 
2272 static BOOL SQLColAttributes_KnownStringAttribute(SQLUSMALLINT fDescType)
2273 {
2274     static const SQLUSMALLINT attrList[] =
2275     {
2276         SQL_COLUMN_OWNER_NAME,
2277         SQL_COLUMN_QUALIFIER_NAME,
2278         SQL_COLUMN_LABEL,
2279         SQL_COLUMN_NAME,
2280         SQL_COLUMN_TABLE_NAME,
2281         SQL_COLUMN_TYPE_NAME,
2282         SQL_DESC_BASE_COLUMN_NAME,
2283         SQL_DESC_BASE_TABLE_NAME,
2284         SQL_DESC_CATALOG_NAME,
2285         SQL_DESC_LABEL,
2286         SQL_DESC_LITERAL_PREFIX,
2287         SQL_DESC_LITERAL_SUFFIX,
2288         SQL_DESC_LOCAL_TYPE_NAME,
2289         SQL_DESC_NAME,
2290         SQL_DESC_SCHEMA_NAME,
2291         SQL_DESC_TABLE_NAME,
2292         SQL_DESC_TYPE_NAME,
2293     };
2294     unsigned int i;
2295 
2296     for (i = 0; i < ARRAY_SIZE(attrList); i++) {
2297         if (attrList[i] == fDescType) return TRUE;
2298     }
2299     return FALSE;
2300 }
2301 
2302 /*************************************************************************
2303  *				SQLColAttributesW          [ODBC32.106]
2304  */
2305 SQLRETURN WINAPI ODBC32_SQLColAttributesW(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,
2306                                           SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT *pcbDesc,
2307                                           SQLLEN *pfDesc)
2308 {
2309     SQLRETURN ret;
2310 
2311     TRACE("(hstmt %p, icol %d, fDescType %d, rgbDesc %p, cbDescMax %d, pcbDesc %p, pfDesc %p)\n", hstmt, icol,
2312           fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
2313 
2314     if (!pSQLColAttributesW) return SQL_ERROR;
2315 
2316     ret = pSQLColAttributesW(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
2317 
2318     if (ret == SQL_SUCCESS && SQLColAttributes_KnownStringAttribute(fDescType) && rgbDesc && pcbDesc &&
2319         *pcbDesc != lstrlenW(rgbDesc) * 2)
2320     {
2321         TRACE("CHEAT: resetting name length for ADO\n");
2322         *pcbDesc = lstrlenW(rgbDesc) * 2;
2323     }
2324 
2325     TRACE("Returning %d\n", ret);
2326     return ret;
2327 }
2328 
2329 /*************************************************************************
2330  *				SQLConnectW          [ODBC32.107]
2331  */
2332 SQLRETURN WINAPI ODBC32_SQLConnectW(SQLHDBC ConnectionHandle, WCHAR *ServerName, SQLSMALLINT NameLength1,
2333                                     WCHAR *UserName, SQLSMALLINT NameLength2, WCHAR *Authentication,
2334                                     SQLSMALLINT NameLength3)
2335 {
2336     SQLRETURN ret;
2337 
2338     TRACE("(ConnectionHandle %p, ServerName %s, NameLength1 %d, UserName %s, NameLength2 %d, Authentication %s,"
2339           " NameLength3 %d)\n", ConnectionHandle, debugstr_wn(ServerName, NameLength1), NameLength1,
2340           debugstr_wn(UserName, NameLength2), NameLength2, debugstr_wn(Authentication, NameLength3), NameLength3);
2341 
2342     if (!pSQLConnectW) return SQL_ERROR;
2343 
2344     ret = pSQLConnectW(ConnectionHandle, ServerName, NameLength1, UserName, NameLength2, Authentication, NameLength3);
2345     TRACE("Returning %d\n", ret);
2346     return ret;
2347 }
2348 
2349 /*************************************************************************
2350  *				SQLDescribeColW          [ODBC32.108]
2351  */
2352 SQLRETURN WINAPI ODBC32_SQLDescribeColW(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, WCHAR *ColumnName,
2353                                         SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, SQLSMALLINT *DataType,
2354                                         SQLULEN *ColumnSize, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable)
2355 {
2356     SQLSMALLINT dummy;
2357     SQLRETURN ret;
2358 
2359     TRACE("(StatementHandle %p, ColumnNumber %d, ColumnName %p, BufferLength %d, NameLength %p, DataType %p,"
2360           " ColumnSize %p, DecimalDigits %p, Nullable %p)\n", StatementHandle, ColumnNumber, ColumnName,
2361           BufferLength, NameLength, DataType, ColumnSize, DecimalDigits, Nullable);
2362 
2363     if (!pSQLDescribeColW) return SQL_ERROR;
2364     if (!NameLength) NameLength = &dummy; /* workaround for drivers that don't accept NULL NameLength */
2365 
2366     ret = pSQLDescribeColW(StatementHandle, ColumnNumber, ColumnName, BufferLength, NameLength, DataType, ColumnSize,
2367                            DecimalDigits, Nullable);
2368     if (ret >= 0)
2369     {
2370         if (ColumnName && NameLength) TRACE("ColumnName %s\n", debugstr_wn(ColumnName, *NameLength));
2371         if (DataType) TRACE("DataType %d\n", *DataType);
2372         if (ColumnSize) TRACE("ColumnSize %s\n", debugstr_sqlulen(*ColumnSize));
2373         if (DecimalDigits) TRACE("DecimalDigits %d\n", *DecimalDigits);
2374         if (Nullable) TRACE("Nullable %d\n", *Nullable);
2375     }
2376 
2377     TRACE("Returning %d\n", ret);
2378     return ret;
2379 }
2380 
2381 /*************************************************************************
2382  *				SQLErrorW          [ODBC32.110]
2383  */
2384 SQLRETURN WINAPI ODBC32_SQLErrorW(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle,
2385                                   WCHAR *Sqlstate, SQLINTEGER *NativeError, WCHAR *MessageText,
2386                                   SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
2387 {
2388     SQLRETURN ret;
2389 
2390     TRACE("(EnvironmentHandle %p, ConnectionHandle %p, StatementHandle %p, Sqlstate %p, NativeError %p,"
2391           " MessageText %p, BufferLength %d, TextLength %p)\n", EnvironmentHandle, ConnectionHandle,
2392           StatementHandle, Sqlstate, NativeError, MessageText, BufferLength, TextLength);
2393 
2394     if (!pSQLErrorW) return SQL_ERROR;
2395 
2396     ret = pSQLErrorW(EnvironmentHandle, ConnectionHandle, StatementHandle, Sqlstate, NativeError, MessageText,
2397                      BufferLength, TextLength);
2398 
2399     if (ret == SQL_SUCCESS)
2400     {
2401         TRACE(" SQLState %s\n", debugstr_wn(Sqlstate, 5));
2402         TRACE(" Error %d\n", *NativeError);
2403         TRACE(" MessageText %s\n", debugstr_wn(MessageText, *TextLength));
2404     }
2405 
2406     TRACE("Returning %d\n", ret);
2407     return ret;
2408 }
2409 
2410 /*************************************************************************
2411  *				SQLExecDirectW          [ODBC32.111]
2412  */
2413 SQLRETURN WINAPI ODBC32_SQLExecDirectW(SQLHSTMT StatementHandle, WCHAR *StatementText, SQLINTEGER TextLength)
2414 {
2415     SQLRETURN ret;
2416 
2417     TRACE("(StatementHandle %p, StatementText %s, TextLength %d)\n", StatementHandle,
2418           debugstr_wn(StatementText, TextLength), TextLength);
2419 
2420     if (!pSQLExecDirectW) return SQL_ERROR;
2421 
2422     ret = pSQLExecDirectW(StatementHandle, StatementText, TextLength);
2423     TRACE("Returning %d\n", ret);
2424     return ret;
2425 }
2426 
2427 /*************************************************************************
2428  *				SQLGetCursorNameW          [ODBC32.117]
2429  */
2430 SQLRETURN WINAPI ODBC32_SQLGetCursorNameW(SQLHSTMT StatementHandle, WCHAR *CursorName, SQLSMALLINT BufferLength,
2431                                           SQLSMALLINT *NameLength)
2432 {
2433     SQLRETURN ret;
2434 
2435     TRACE("(StatementHandle %p, CursorName %p, BufferLength %d, NameLength %p)\n", StatementHandle, CursorName,
2436           BufferLength, NameLength);
2437 
2438     if (!pSQLGetCursorNameW) return SQL_ERROR;
2439 
2440     ret = pSQLGetCursorNameW(StatementHandle, CursorName, BufferLength, NameLength);
2441     TRACE("Returning %d\n", ret);
2442     return ret;
2443 }
2444 
2445 /*************************************************************************
2446  *				SQLPrepareW          [ODBC32.119]
2447  */
2448 SQLRETURN WINAPI ODBC32_SQLPrepareW(SQLHSTMT StatementHandle, WCHAR *StatementText, SQLINTEGER TextLength)
2449 {
2450     SQLRETURN ret;
2451 
2452     TRACE("(StatementHandle %p, StatementText %s, TextLength %d)\n", StatementHandle,
2453           debugstr_wn(StatementText, TextLength), TextLength);
2454 
2455     if (!pSQLPrepareW) return SQL_ERROR;
2456 
2457     ret = pSQLPrepareW(StatementHandle, StatementText, TextLength);
2458     TRACE("Returning %d\n", ret);
2459     return ret;
2460 }
2461 
2462 /*************************************************************************
2463  *				SQLSetCursorNameW          [ODBC32.121]
2464  */
2465 SQLRETURN WINAPI ODBC32_SQLSetCursorNameW(SQLHSTMT StatementHandle, WCHAR *CursorName, SQLSMALLINT NameLength)
2466 {
2467     SQLRETURN ret;
2468 
2469     TRACE("(StatementHandle %p, CursorName %s, NameLength %d)\n", StatementHandle,
2470           debugstr_wn(CursorName, NameLength), NameLength);
2471 
2472     if (!pSQLSetCursorNameW) return SQL_ERROR;
2473 
2474     ret = pSQLSetCursorNameW(StatementHandle, CursorName, NameLength);
2475     TRACE("Returning %d\n", ret);
2476     return ret;
2477 }
2478 
2479 /*************************************************************************
2480  *				SQLColAttributeW          [ODBC32.127]
2481  */
2482 SQLRETURN WINAPI ODBC32_SQLColAttributeW(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber,
2483                                          SQLUSMALLINT FieldIdentifier, SQLPOINTER CharacterAttribute,
2484                                          SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
2485                                          SQLLEN *NumericAttribute)
2486 {
2487     SQLRETURN ret;
2488 
2489     TRACE("StatementHandle %p ColumnNumber %d FieldIdentifier %d CharacterAttribute %p BufferLength %d"
2490           " StringLength %p NumericAttribute %p\n", StatementHandle, ColumnNumber, FieldIdentifier,
2491           CharacterAttribute, BufferLength, StringLength, NumericAttribute);
2492 
2493     if (!pSQLColAttributeW) return SQL_ERROR;
2494 
2495     ret = pSQLColAttributeW(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength,
2496                             StringLength, NumericAttribute);
2497 
2498     if (ret == SQL_SUCCESS && CharacterAttribute != NULL && SQLColAttributes_KnownStringAttribute(FieldIdentifier) &&
2499         StringLength && *StringLength != lstrlenW(CharacterAttribute) * 2)
2500     {
2501         TRACE("CHEAT: resetting name length for ADO\n");
2502         *StringLength = lstrlenW(CharacterAttribute) * 2;
2503     }
2504 
2505     TRACE("Returning %d\n", ret);
2506     return ret;
2507 }
2508 
2509 /*************************************************************************
2510  *				SQLGetConnectAttrW          [ODBC32.132]
2511  */
2512 SQLRETURN WINAPI ODBC32_SQLGetConnectAttrW(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value,
2513                                            SQLINTEGER BufferLength, SQLINTEGER *StringLength)
2514 {
2515     SQLRETURN ret;
2516 
2517     TRACE("(ConnectionHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n", ConnectionHandle,
2518           Attribute, Value, BufferLength, StringLength);
2519 
2520     if (!pSQLGetConnectAttrW) return SQL_ERROR;
2521 
2522     ret = pSQLGetConnectAttrW(ConnectionHandle, Attribute, Value, BufferLength, StringLength);
2523     TRACE("Returning %d\n", ret);
2524     return ret;
2525 }
2526 
2527 /*************************************************************************
2528  *				SQLGetDescFieldW          [ODBC32.133]
2529  */
2530 SQLRETURN WINAPI ODBC32_SQLGetDescFieldW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
2531                                          SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength)
2532 {
2533     SQLRETURN ret;
2534 
2535     TRACE("(DescriptorHandle %p, RecNumber %d, FieldIdentifier %d, Value %p, BufferLength %d, StringLength %p)\n",
2536           DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
2537 
2538     if (!pSQLGetDescFieldW) return SQL_ERROR;
2539 
2540     ret = pSQLGetDescFieldW(DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
2541     TRACE("Returning %d\n", ret);
2542     return ret;
2543 }
2544 
2545 /*************************************************************************
2546  *				SQLGetDescRecW          [ODBC32.134]
2547  */
2548 SQLRETURN WINAPI ODBC32_SQLGetDescRecW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, WCHAR *Name,
2549                                        SQLSMALLINT BufferLength, SQLSMALLINT *StringLength, SQLSMALLINT *Type,
2550                                        SQLSMALLINT *SubType, SQLLEN *Length, SQLSMALLINT *Precision,
2551                                        SQLSMALLINT *Scale, SQLSMALLINT *Nullable)
2552 {
2553     SQLRETURN ret;
2554 
2555     TRACE("(DescriptorHandle %p, RecNumber %d, Name %p, BufferLength %d, StringLength %p, Type %p, SubType %p,"
2556           " Length %p, Precision %p, Scale %p, Nullable %p)\n", DescriptorHandle, RecNumber, Name, BufferLength,
2557           StringLength, Type, SubType, Length, Precision, Scale, Nullable);
2558 
2559     if (!pSQLGetDescRecW) return SQL_ERROR;
2560 
2561     ret = pSQLGetDescRecW(DescriptorHandle, RecNumber, Name, BufferLength, StringLength, Type, SubType, Length,
2562                           Precision, Scale, Nullable);
2563     TRACE("Returning %d\n", ret);
2564     return ret;
2565 }
2566 
2567 /*************************************************************************
2568  *				SQLGetDiagFieldW          [ODBC32.135]
2569  */
2570 SQLRETURN WINAPI ODBC32_SQLGetDiagFieldW(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber,
2571                                          SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength,
2572                                          SQLSMALLINT *StringLength)
2573 {
2574     SQLRETURN ret;
2575 
2576     TRACE("(HandleType %d, Handle %p, RecNumber %d, DiagIdentifier %d, DiagInfo %p, BufferLength %d,"
2577           " StringLength %p)\n", HandleType, Handle, RecNumber, DiagIdentifier, DiagInfo, BufferLength, StringLength);
2578 
2579     if (!pSQLGetDiagFieldW) return SQL_ERROR;
2580 
2581     ret = pSQLGetDiagFieldW(HandleType, Handle, RecNumber, DiagIdentifier, DiagInfo, BufferLength, StringLength);
2582     TRACE("Returning %d\n", ret);
2583     return ret;
2584 }
2585 
2586 /*************************************************************************
2587  *				SQLGetDiagRecW           [ODBC32.136]
2588  */
2589 SQLRETURN WINAPI ODBC32_SQLGetDiagRecW(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber,
2590                                        WCHAR *Sqlstate, SQLINTEGER *NativeError, WCHAR *MessageText,
2591                                        SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
2592 {
2593     SQLRETURN ret;
2594 
2595     TRACE("(HandleType %d, Handle %p, RecNumber %d, Sqlstate %p, NativeError %p, MessageText %p, BufferLength %d,"
2596           " TextLength %p)\n", HandleType, Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength,
2597           TextLength);
2598 
2599     if (!pSQLGetDiagRecW) return SQL_ERROR;
2600 
2601     ret = pSQLGetDiagRecW(HandleType, Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength, TextLength);
2602     TRACE("Returning %d\n", ret);
2603     return ret;
2604 }
2605 
2606 /*************************************************************************
2607  *				SQLGetStmtAttrW          [ODBC32.138]
2608  */
2609 SQLRETURN WINAPI ODBC32_SQLGetStmtAttrW(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value,
2610                                         SQLINTEGER BufferLength, SQLINTEGER *StringLength)
2611 {
2612     SQLRETURN ret;
2613 
2614     TRACE("(StatementHandle %p, Attribute %d, Value %p, BufferLength %d, StringLength %p)\n", StatementHandle,
2615           Attribute, Value, BufferLength, StringLength);
2616 
2617     if (!Value)
2618     {
2619         WARN("Unexpected NULL Value return address\n");
2620         return SQL_ERROR;
2621     }
2622 
2623     if (!pSQLGetStmtAttrW) return SQL_ERROR;
2624 
2625     ret = pSQLGetStmtAttrW(StatementHandle, Attribute, Value, BufferLength, StringLength);
2626     TRACE("Returning %d\n", ret);
2627     return ret;
2628 }
2629 
2630 /*************************************************************************
2631  *				SQLSetConnectAttrW          [ODBC32.139]
2632  */
2633 SQLRETURN WINAPI ODBC32_SQLSetConnectAttrW(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value,
2634                                            SQLINTEGER StringLength)
2635 {
2636     SQLRETURN ret;
2637 
2638     TRACE("(ConnectionHandle %p, Attribute %d, Value %p, StringLength %d)\n", ConnectionHandle, Attribute, Value,
2639           StringLength);
2640 
2641     if (!pSQLSetConnectAttrW) return SQL_ERROR;
2642 
2643     ret = pSQLSetConnectAttrW(ConnectionHandle, Attribute, Value, StringLength);
2644     TRACE("Returning %d\n", ret);
2645     return ret;
2646 }
2647 
2648 /*************************************************************************
2649  *				SQLColumnsW          [ODBC32.140]
2650  */
2651 SQLRETURN WINAPI ODBC32_SQLColumnsW(SQLHSTMT StatementHandle, WCHAR *CatalogName, SQLSMALLINT NameLength1,
2652                                     WCHAR *SchemaName, SQLSMALLINT NameLength2, WCHAR *TableName,
2653                                     SQLSMALLINT NameLength3, WCHAR *ColumnName, SQLSMALLINT NameLength4)
2654 {
2655     SQLRETURN ret;
2656 
2657     TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s,"
2658           " NameLength3 %d, ColumnName %s, NameLength4 %d)\n", StatementHandle,
2659           debugstr_wn(CatalogName, NameLength1), NameLength1, debugstr_wn(SchemaName, NameLength2), NameLength2,
2660           debugstr_wn(TableName, NameLength3), NameLength3, debugstr_wn(ColumnName, NameLength4), NameLength4);
2661 
2662     if (!pSQLColumnsW) return SQL_ERROR;
2663 
2664     ret = pSQLColumnsW(StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2, TableName, NameLength3,
2665                        ColumnName, NameLength4);
2666     TRACE("Returning %d\n", ret);
2667     return ret;
2668 }
2669 
2670 /*************************************************************************
2671  *				SQLDriverConnectW          [ODBC32.141]
2672  */
2673 SQLRETURN WINAPI ODBC32_SQLDriverConnectW(SQLHDBC ConnectionHandle, SQLHWND WindowHandle, WCHAR *InConnectionString,
2674                                           SQLSMALLINT Length, WCHAR *OutConnectionString, SQLSMALLINT BufferLength,
2675                                           SQLSMALLINT *Length2, SQLUSMALLINT DriverCompletion)
2676 {
2677     SQLRETURN ret;
2678 
2679     TRACE("(ConnectionHandle %p, WindowHandle %p, InConnectionString %s, Length %d, OutConnectionString %p,"
2680           " BufferLength %d, Length2 %p, DriverCompletion %d)\n", ConnectionHandle, WindowHandle,
2681           debugstr_wn(InConnectionString, Length), Length, OutConnectionString, BufferLength, Length2,
2682           DriverCompletion);
2683 
2684     if (!pSQLDriverConnectW) return SQL_ERROR;
2685 
2686     ret = pSQLDriverConnectW(ConnectionHandle, WindowHandle, InConnectionString, Length, OutConnectionString,
2687                              BufferLength, Length2, DriverCompletion);
2688     TRACE("Returning %d\n", ret);
2689     return ret;
2690 }
2691 
2692 /*************************************************************************
2693  *				SQLGetConnectOptionW      [ODBC32.142]
2694  */
2695 SQLRETURN WINAPI ODBC32_SQLGetConnectOptionW(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLPOINTER Value)
2696 {
2697     SQLRETURN ret;
2698 
2699     TRACE("(ConnectionHandle %p, Option %d, Value %p)\n", ConnectionHandle, Option, Value);
2700 
2701     if (!pSQLGetConnectOptionW) return SQL_ERROR;
2702 
2703     ret = pSQLGetConnectOptionW(ConnectionHandle, Option, Value);
2704     TRACE("Returning %d\n", ret);
2705     return ret;
2706 }
2707 
2708 /*************************************************************************
2709  *				SQLGetInfoW          [ODBC32.145]
2710  */
2711 SQLRETURN WINAPI ODBC32_SQLGetInfoW(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue,
2712                                     SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
2713 {
2714     SQLRETURN ret;
2715 
2716     TRACE("(ConnectionHandle, %p, InfoType %d, InfoValue %p, BufferLength %d, StringLength %p)\n", ConnectionHandle,
2717           InfoType, InfoValue, BufferLength, StringLength);
2718 
2719     if (!InfoValue)
2720     {
2721         WARN("Unexpected NULL InfoValue address\n");
2722         return SQL_ERROR;
2723     }
2724 
2725     if (!pSQLGetInfoW) return SQL_ERROR;
2726 
2727     ret = pSQLGetInfoW(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength);
2728     TRACE("Returning %d\n", ret);
2729     return ret;
2730 }
2731 
2732 /*************************************************************************
2733  *				SQLGetTypeInfoW          [ODBC32.147]
2734  */
2735 SQLRETURN WINAPI ODBC32_SQLGetTypeInfoW(SQLHSTMT StatementHandle, SQLSMALLINT DataType)
2736 {
2737     SQLRETURN ret;
2738 
2739     TRACE("(StatementHandle %p, DataType %d)\n", StatementHandle, DataType);
2740 
2741     if (!pSQLGetTypeInfoW) return SQL_ERROR;
2742 
2743     ret = pSQLGetTypeInfoW(StatementHandle, DataType);
2744     TRACE("Returning %d\n", ret);
2745     return ret;
2746 }
2747 
2748 /*************************************************************************
2749  *				SQLSetConnectOptionW          [ODBC32.150]
2750  */
2751 SQLRETURN WINAPI ODBC32_SQLSetConnectOptionW(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLULEN Value)
2752 {
2753     SQLRETURN ret;
2754 
2755     TRACE("(ConnectionHandle %p, Option %d, Value %s)\n", ConnectionHandle, Option, debugstr_sqllen(Value));
2756 
2757     if (!pSQLSetConnectOptionW) return SQL_ERROR;
2758 
2759     ret = pSQLSetConnectOptionW(ConnectionHandle, Option, Value);
2760     TRACE("Returning %d\n", ret);
2761     return ret;
2762 }
2763 
2764 /*************************************************************************
2765  *				SQLSpecialColumnsW          [ODBC32.152]
2766  */
2767 SQLRETURN WINAPI ODBC32_SQLSpecialColumnsW(SQLHSTMT StatementHandle, SQLUSMALLINT IdentifierType,
2768                                            SQLWCHAR *CatalogName, SQLSMALLINT NameLength1, SQLWCHAR *SchemaName,
2769                                            SQLSMALLINT NameLength2, SQLWCHAR *TableName, SQLSMALLINT NameLength3,
2770                                            SQLUSMALLINT Scope, SQLUSMALLINT Nullable)
2771 {
2772     SQLRETURN ret;
2773 
2774     TRACE("(StatementHandle %p, IdentifierType %d, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d,"
2775           " TableName %s, NameLength3 %d, Scope %d, Nullable %d)\n", StatementHandle, IdentifierType,
2776           debugstr_wn(CatalogName, NameLength1), NameLength1, debugstr_wn(SchemaName, NameLength2), NameLength2,
2777           debugstr_wn(TableName, NameLength3), NameLength3, Scope, Nullable);
2778 
2779     if (!pSQLSpecialColumnsW) return SQL_ERROR;
2780 
2781     ret = pSQLSpecialColumnsW(StatementHandle, IdentifierType, CatalogName, NameLength1, SchemaName,
2782                               NameLength2, TableName, NameLength3, Scope, Nullable);
2783     TRACE("Returning %d\n", ret);
2784     return ret;
2785 }
2786 
2787 /*************************************************************************
2788  *				SQLStatisticsW          [ODBC32.153]
2789  */
2790 SQLRETURN WINAPI ODBC32_SQLStatisticsW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName, SQLSMALLINT NameLength1,
2791                                        SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *TableName,
2792                                        SQLSMALLINT NameLength3, SQLUSMALLINT Unique, SQLUSMALLINT Reserved)
2793 {
2794     SQLRETURN ret;
2795 
2796     TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d SchemaName %s, NameLength2 %d, TableName %s"
2797           " NameLength3 %d, Unique %d, Reserved %d)\n", StatementHandle,
2798           debugstr_wn(CatalogName, NameLength1), NameLength1, debugstr_wn(SchemaName, NameLength2), NameLength2,
2799           debugstr_wn(TableName, NameLength3), NameLength3, Unique, Reserved);
2800 
2801     if (!pSQLStatisticsW) return SQL_ERROR;
2802 
2803     ret = pSQLStatisticsW(StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2, TableName,
2804                           NameLength3, Unique, Reserved);
2805     TRACE("Returning %d\n", ret);
2806     return ret;
2807 }
2808 
2809 /*************************************************************************
2810  *				SQLTablesW          [ODBC32.154]
2811  */
2812 SQLRETURN WINAPI ODBC32_SQLTablesW(SQLHSTMT StatementHandle, SQLWCHAR *CatalogName, SQLSMALLINT NameLength1,
2813                                    SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *TableName,
2814                                    SQLSMALLINT NameLength3, SQLWCHAR *TableType, SQLSMALLINT NameLength4)
2815 {
2816     SQLRETURN ret;
2817 
2818     TRACE("(StatementHandle %p, CatalogName %s, NameLength1 %d, SchemaName %s, NameLength2 %d, TableName %s,"
2819           " NameLength3 %d, TableType %s, NameLength4 %d)\n", StatementHandle,
2820           debugstr_wn(CatalogName, NameLength1), NameLength1, debugstr_wn(SchemaName, NameLength2), NameLength2,
2821           debugstr_wn(TableName, NameLength3), NameLength3, debugstr_wn(TableType, NameLength4), NameLength4);
2822 
2823     if (!pSQLTablesW) return SQL_ERROR;
2824 
2825     ret = pSQLTablesW(StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2, TableName, NameLength3,
2826                       TableType, NameLength4);
2827     TRACE("Returning %d\n", ret);
2828     return ret;
2829 }
2830 
2831 /*************************************************************************
2832  *				SQLBrowseConnectW          [ODBC32.155]
2833  */
2834 SQLRETURN WINAPI ODBC32_SQLBrowseConnectW(SQLHDBC hdbc, SQLWCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn,
2835                                           SQLWCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax,
2836                                           SQLSMALLINT *pcbConnStrOut)
2837 {
2838     SQLRETURN ret;
2839 
2840     TRACE("(hdbc %p, szConnStrIn %s, cbConnStrIn %d, szConnStrOut %p, cbConnStrOutMax %d, pcbConnStrOut %p)\n",
2841           hdbc, debugstr_wn(szConnStrIn, cbConnStrIn), cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut);
2842 
2843     if (!pSQLBrowseConnectW) return SQL_ERROR;
2844 
2845     ret = pSQLBrowseConnectW(hdbc, szConnStrIn, cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut);
2846     TRACE("Returning %d\n", ret);
2847     return ret;
2848 }
2849 
2850 /*************************************************************************
2851  *				SQLColumnPrivilegesW          [ODBC32.156]
2852  */
2853 SQLRETURN WINAPI ODBC32_SQLColumnPrivilegesW(SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
2854                                              SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName,
2855                                              SQLSMALLINT cbTableName, SQLWCHAR *szColumnName, SQLSMALLINT cbColumnName)
2856 {
2857     SQLRETURN ret;
2858 
2859     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szTableName %s,"
2860           " cbTableName %d, szColumnName %s, cbColumnName %d)\n", hstmt,
2861           debugstr_wn(szCatalogName, cbCatalogName), cbCatalogName,
2862           debugstr_wn(szSchemaName, cbSchemaName), cbSchemaName,
2863           debugstr_wn(szTableName, cbTableName), cbTableName,
2864           debugstr_wn(szColumnName, cbColumnName), cbColumnName);
2865 
2866     if (!pSQLColumnPrivilegesW) return SQL_ERROR;
2867 
2868     ret = pSQLColumnPrivilegesW(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName,
2869                                 cbTableName, szColumnName, cbColumnName);
2870     TRACE("Returning %d\n", ret);
2871     return ret;
2872 }
2873 
2874 /*************************************************************************
2875  *				SQLDataSourcesW          [ODBC32.157]
2876  */
2877 SQLRETURN WINAPI ODBC32_SQLDataSourcesW(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, WCHAR *ServerName,
2878                                         SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, WCHAR *Description,
2879                                         SQLSMALLINT BufferLength2, SQLSMALLINT *NameLength2)
2880 {
2881     SQLRETURN ret;
2882 
2883     TRACE("(EnvironmentHandle %p, Direction %d, ServerName %p, BufferLength1 %d, NameLength1 %p, Description %p,"
2884           " BufferLength2 %d, NameLength2 %p)\n", EnvironmentHandle, Direction, ServerName, BufferLength1,
2885           NameLength1, Description, BufferLength2, NameLength2);
2886 
2887     if (!pSQLDataSourcesW) return SQL_ERROR;
2888 
2889     ret = pSQLDataSourcesW(EnvironmentHandle, Direction, ServerName, BufferLength1, NameLength1, Description,
2890                            BufferLength2, NameLength2);
2891 
2892     if (ret >= 0 && TRACE_ON(odbc))
2893     {
2894         if (ServerName && NameLength1 && *NameLength1 > 0)
2895             TRACE(" DataSource %s", debugstr_wn(ServerName, *NameLength1));
2896         if (Description && NameLength2 && *NameLength2 > 0)
2897             TRACE(" Description %s", debugstr_wn(Description, *NameLength2));
2898         TRACE("\n");
2899     }
2900 
2901     TRACE("Returning %d\n", ret);
2902     return ret;
2903 }
2904 
2905 /*************************************************************************
2906  *				SQLForeignKeysW          [ODBC32.160]
2907  */
2908 SQLRETURN WINAPI ODBC32_SQLForeignKeysW(SQLHSTMT hstmt, SQLWCHAR *szPkCatalogName, SQLSMALLINT cbPkCatalogName,
2909                                         SQLWCHAR *szPkSchemaName, SQLSMALLINT cbPkSchemaName, SQLWCHAR *szPkTableName,
2910                                         SQLSMALLINT cbPkTableName, SQLWCHAR *szFkCatalogName,
2911                                         SQLSMALLINT cbFkCatalogName, SQLWCHAR *szFkSchemaName,
2912                                         SQLSMALLINT cbFkSchemaName, SQLWCHAR *szFkTableName, SQLSMALLINT cbFkTableName)
2913 {
2914     SQLRETURN ret;
2915 
2916     TRACE("(hstmt %p, szPkCatalogName %s, cbPkCatalogName %d, szPkSchemaName %s, cbPkSchemaName %d,"
2917           " szPkTableName %s, cbPkTableName %d, szFkCatalogName %s, cbFkCatalogName %d, szFkSchemaName %s,"
2918           " cbFkSchemaName %d, szFkTableName %s, cbFkTableName %d)\n", hstmt,
2919           debugstr_wn(szPkCatalogName, cbPkCatalogName), cbPkCatalogName,
2920           debugstr_wn(szPkSchemaName, cbPkSchemaName), cbPkSchemaName,
2921           debugstr_wn(szPkTableName, cbPkTableName), cbPkTableName,
2922           debugstr_wn(szFkCatalogName, cbFkCatalogName), cbFkCatalogName,
2923           debugstr_wn(szFkSchemaName, cbFkSchemaName), cbFkSchemaName,
2924           debugstr_wn(szFkTableName, cbFkTableName), cbFkTableName);
2925 
2926     if (!pSQLForeignKeysW) return SQL_ERROR;
2927 
2928     ret = pSQLForeignKeysW(hstmt, szPkCatalogName, cbPkCatalogName, szPkSchemaName, cbPkSchemaName, szPkTableName,
2929                            cbPkTableName, szFkCatalogName, cbFkCatalogName, szFkSchemaName, cbFkSchemaName,
2930                            szFkTableName, cbFkTableName);
2931     TRACE("Returning %d\n", ret);
2932     return ret;
2933 }
2934 
2935 /*************************************************************************
2936  *				SQLNativeSqlW          [ODBC32.162]
2937  */
2938 SQLRETURN WINAPI ODBC32_SQLNativeSqlW(SQLHDBC hdbc, SQLWCHAR *szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLWCHAR *szSqlStr,
2939                                       SQLINTEGER cbSqlStrMax, SQLINTEGER *pcbSqlStr)
2940 {
2941     SQLRETURN ret;
2942 
2943     TRACE("(hdbc %p, szSqlStrIn %s, cbSqlStrIn %d, szSqlStr %p, cbSqlStrMax %d, pcbSqlStr %p)\n", hdbc,
2944           debugstr_wn(szSqlStrIn, cbSqlStrIn), cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr);
2945 
2946     if (!pSQLNativeSqlW) return SQL_ERROR;
2947 
2948     ret = pSQLNativeSqlW(hdbc, szSqlStrIn, cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr);
2949     TRACE("Returning %d\n", ret);
2950     return ret;
2951 }
2952 
2953 /*************************************************************************
2954  *				SQLPrimaryKeysW          [ODBC32.165]
2955  */
2956 SQLRETURN WINAPI ODBC32_SQLPrimaryKeysW(SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
2957                                         SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName,
2958                                         SQLSMALLINT cbTableName)
2959 {
2960     SQLRETURN ret;
2961 
2962     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szTableName %s,"
2963           " cbTableName %d)\n", hstmt,
2964           debugstr_wn(szCatalogName, cbCatalogName), cbCatalogName,
2965           debugstr_wn(szSchemaName, cbSchemaName), cbSchemaName,
2966           debugstr_wn(szTableName, cbTableName), cbTableName);
2967 
2968     if (!pSQLPrimaryKeysW) return SQL_ERROR;
2969 
2970     ret = pSQLPrimaryKeysW(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName);
2971     TRACE("Returning %d\n", ret);
2972     return ret;
2973 }
2974 
2975 /*************************************************************************
2976  *				SQLProcedureColumnsW          [ODBC32.166]
2977  */
2978 SQLRETURN WINAPI ODBC32_SQLProcedureColumnsW(SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
2979                                              SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szProcName,
2980                                              SQLSMALLINT cbProcName, SQLWCHAR *szColumnName, SQLSMALLINT cbColumnName)
2981 {
2982     SQLRETURN ret;
2983 
2984     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szProcName %s,"
2985           " cbProcName %d, szColumnName %s, cbColumnName %d)\n", hstmt,
2986           debugstr_wn(szCatalogName, cbCatalogName), cbCatalogName,
2987           debugstr_wn(szSchemaName, cbSchemaName), cbSchemaName,
2988           debugstr_wn(szProcName, cbProcName), cbProcName,
2989           debugstr_wn(szColumnName, cbColumnName), cbColumnName);
2990 
2991     if (!pSQLProcedureColumnsW) return SQL_ERROR;
2992 
2993     ret = pSQLProcedureColumnsW(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szProcName,
2994                                 cbProcName, szColumnName, cbColumnName);
2995     TRACE("Returning %d\n", ret);
2996     return ret;
2997 }
2998 
2999 /*************************************************************************
3000  *				SQLProceduresW          [ODBC32.167]
3001  */
3002 SQLRETURN WINAPI ODBC32_SQLProceduresW(SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
3003                                        SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szProcName,
3004                                        SQLSMALLINT cbProcName)
3005 {
3006     SQLRETURN ret;
3007 
3008     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szProcName %s,"
3009           " cbProcName %d)\n", hstmt, debugstr_wn(szCatalogName, cbCatalogName), cbCatalogName,
3010           debugstr_wn(szSchemaName, cbSchemaName), cbSchemaName, debugstr_wn(szProcName, cbProcName), cbProcName);
3011 
3012     if (!pSQLProceduresW) return SQL_ERROR;
3013 
3014     ret = pSQLProceduresW(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szProcName, cbProcName);
3015     TRACE("Returning %d\n", ret);
3016     return ret;
3017 }
3018 
3019 /*************************************************************************
3020  *				SQLTablePrivilegesW          [ODBC32.170]
3021  */
3022 SQLRETURN WINAPI ODBC32_SQLTablePrivilegesW(SQLHSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName,
3023                                             SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName,
3024                                             SQLSMALLINT cbTableName)
3025 {
3026     SQLRETURN ret;
3027 
3028     TRACE("(hstmt %p, szCatalogName %s, cbCatalogName %d, szSchemaName %s, cbSchemaName %d, szTableName %s,"
3029           " cbTableName %d)\n", hstmt, debugstr_wn(szCatalogName, cbCatalogName), cbCatalogName,
3030           debugstr_wn(szSchemaName, cbSchemaName), cbSchemaName, debugstr_wn(szTableName, cbTableName), cbTableName);
3031 
3032     if (!pSQLTablePrivilegesW) return SQL_ERROR;
3033 
3034     ret = pSQLTablePrivilegesW(hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName,
3035                                cbTableName);
3036     TRACE("Returning %d\n", ret);
3037     return ret;
3038 }
3039 
3040 /*************************************************************************
3041  *				SQLDriversW          [ODBC32.171]
3042  */
3043 SQLRETURN WINAPI ODBC32_SQLDriversW(SQLHENV EnvironmentHandle, SQLUSMALLINT fDirection, SQLWCHAR *szDriverDesc,
3044                                     SQLSMALLINT cbDriverDescMax, SQLSMALLINT *pcbDriverDesc,
3045                                     SQLWCHAR *szDriverAttributes, SQLSMALLINT cbDriverAttrMax,
3046                                     SQLSMALLINT *pcbDriverAttr)
3047 {
3048     SQLRETURN ret;
3049 
3050     TRACE("(EnvironmentHandle %p, Direction %d, szDriverDesc %p, cbDriverDescMax %d, pcbDriverDesc %p,"
3051           " DriverAttributes %p, cbDriverAttrMax %d, pcbDriverAttr %p)\n", EnvironmentHandle, fDirection,
3052           szDriverDesc, cbDriverDescMax, pcbDriverDesc, szDriverAttributes, cbDriverAttrMax, pcbDriverAttr);
3053 
3054     if (!pSQLDriversW) return SQL_ERROR;
3055 
3056     ret = pSQLDriversW(EnvironmentHandle, fDirection, szDriverDesc, cbDriverDescMax, pcbDriverDesc,
3057                        szDriverAttributes, cbDriverAttrMax, pcbDriverAttr);
3058 
3059     if (ret == SQL_NO_DATA && fDirection == SQL_FETCH_FIRST)
3060         ERR_(winediag)("No ODBC drivers could be found. Check the settings for your libodbc provider.\n");
3061 
3062     TRACE("Returning %d\n", ret);
3063     return ret;
3064 }
3065 
3066 /*************************************************************************
3067  *				SQLSetDescFieldW          [ODBC32.173]
3068  */
3069 SQLRETURN WINAPI ODBC32_SQLSetDescFieldW(SQLHDESC DescriptorHandle, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
3070                                          SQLPOINTER Value, SQLINTEGER BufferLength)
3071 {
3072     SQLRETURN ret;
3073 
3074     TRACE("(DescriptorHandle %p, RecNumber %d, FieldIdentifier %d, Value %p, BufferLength %d)\n", DescriptorHandle,
3075           RecNumber, FieldIdentifier, Value, BufferLength);
3076 
3077     if (!pSQLSetDescFieldW) return SQL_ERROR;
3078 
3079     ret = pSQLSetDescFieldW(DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength);
3080     TRACE("Returning %d\n", ret);
3081     return ret;
3082 }
3083 
3084 /*************************************************************************
3085  *				SQLSetStmtAttrW          [ODBC32.176]
3086  */
3087 SQLRETURN WINAPI ODBC32_SQLSetStmtAttrW(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value,
3088                                         SQLINTEGER StringLength)
3089 {
3090     SQLRETURN ret;
3091 
3092     TRACE("(StatementHandle %p, Attribute %d, Value %p, StringLength %d)\n", StatementHandle, Attribute, Value,
3093           StringLength);
3094 
3095     if (!pSQLSetStmtAttrW) return SQL_ERROR;
3096 
3097     ret = pSQLSetStmtAttrW(StatementHandle, Attribute, Value, StringLength);
3098     if (ret == SQL_ERROR && (Attribute == SQL_ROWSET_SIZE || Attribute == SQL_ATTR_ROW_ARRAY_SIZE))
3099     {
3100         TRACE("CHEAT: returning SQL_SUCCESS to ADO\n");
3101         return SQL_SUCCESS;
3102     }
3103 
3104     TRACE("Returning %d\n", ret);
3105     return ret;
3106 }
3107 
3108 /*************************************************************************
3109  *				SQLGetDiagRecA           [ODBC32.236]
3110  */
3111 SQLRETURN WINAPI ODBC32_SQLGetDiagRecA(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber,
3112                                        SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText,
3113                                        SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
3114 {
3115     SQLRETURN ret;
3116 
3117     TRACE("(HandleType %d, Handle %p, RecNumber %d, Sqlstate %p, NativeError %p, MessageText %p, BufferLength %d,"
3118           " TextLength %p)\n", HandleType, Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength,
3119           TextLength);
3120 
3121     if (!pSQLGetDiagRecA) return SQL_ERROR;
3122 
3123     ret = pSQLGetDiagRecA(HandleType, Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength, TextLength);
3124     TRACE("Returning %d\n", ret);
3125     return ret;
3126 }
3127