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