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