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