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