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