odbc32: Sign-compare warnings fix.
[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 == lstrlenA(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 == lstrlenA(dsn) && sizedesc == lstrlenA(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
522 #ifdef SONAME_LIBODBC
523    if (!s || !s[0]) s = SONAME_LIBODBC;
524 #endif
525    if (!s || !s[0]) goto failed;
526
527    gProxyHandle.dmHandle = wine_dlopen(s, RTLD_LAZY | RTLD_GLOBAL, error, sizeof(error));
528
529    if (gProxyHandle.dmHandle != NULL)
530    {
531       gProxyHandle.nErrorType = ERROR_FREE;
532       return TRUE;
533    }
534 failed:
535    WARN("failed to open library %s: %s\n", debugstr_a(s), error);
536    gProxyHandle.nErrorType = ERROR_LIBRARY_NOT_FOUND;
537    return FALSE;
538 }
539
540
541 /***********************************************************************
542  * ODBC_LoadDMFunctions [Internal] Populate function table.
543  *
544  * PARAMS
545  *
546  * RETURNS
547  *     Success: TRUE
548  *     Failure: FALSE
549  */
550
551 static BOOL ODBC_LoadDMFunctions(void)
552 {
553     int i;
554     char error[256];
555
556     if (gProxyHandle.dmHandle == NULL)
557         return FALSE;
558
559     for ( i = 0; i < NUM_SQLFUNC; i ++ )
560     {
561         char * pFuncNameW;
562
563         gProxyHandle.functions[i] = template_func[i];
564         gProxyHandle.functions[i].func = wine_dlsym(gProxyHandle.dmHandle,
565                 gProxyHandle.functions[i].name, error, sizeof(error));
566
567         if (error[0])
568         {
569             ERR("Failed to load function %s\n",gProxyHandle.functions[i].name);
570             gProxyHandle.functions[i].func = SQLDummyFunc;
571         }
572         else
573         {
574             /* Build Unicode function name for this function */
575             pFuncNameW = HeapAlloc(GetProcessHeap(), 0, strlen(gProxyHandle.functions[i].name) + 2);
576             strcpy(pFuncNameW, gProxyHandle.functions[i].name);
577             pFuncNameW[strlen(gProxyHandle.functions[i].name) + 1] = '\0';
578             pFuncNameW[strlen(gProxyHandle.functions[i].name)] = 'W';
579
580             gProxyHandle.functions[i].funcW = wine_dlsym(gProxyHandle.dmHandle,
581                 pFuncNameW, error, sizeof(error));
582             if (error[0])
583             {
584 /*                TRACE("Failed to load function %s, possibly no Unicode version is required\n", pFuncNameW); */
585                 gProxyHandle.functions[i].funcW = NULL;
586             }
587             HeapFree(GetProcessHeap(), 0, pFuncNameW);
588         }
589     }
590
591     gProxyHandle.bFunctionReady = TRUE;
592
593     return TRUE;
594 }
595
596
597 /*************************************************************************
598  *                              SQLAllocConnect           [ODBC32.001]
599  */
600 SQLRETURN WINAPI SQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC *ConnectionHandle)
601 {
602         SQLRETURN ret;
603         TRACE("Env=%lx\n",EnvironmentHandle);
604
605         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
606         {
607            *ConnectionHandle = SQL_NULL_HDBC;
608            TRACE("Not ready\n");
609            return SQL_ERROR;
610         }
611
612         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCCONNECT].func);
613         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCCONNECT].func)
614             (EnvironmentHandle, ConnectionHandle);
615         TRACE("Returns ret=%d, Handle %lx\n",ret, *ConnectionHandle);
616         return ret;
617 }
618
619
620 /*************************************************************************
621  *                              SQLAllocEnv           [ODBC32.002]
622  */
623 SQLRETURN WINAPI  SQLAllocEnv(SQLHENV *EnvironmentHandle)
624 {
625         SQLRETURN ret;
626         TRACE("\n");
627
628         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
629         {
630            *EnvironmentHandle = SQL_NULL_HENV;
631            TRACE("Not ready\n");
632            return SQL_ERROR;
633         }
634
635         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCENV].func);
636         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCENV].func) (EnvironmentHandle);
637         TRACE("Returns ret=%d, Env=%lx\n",ret, *EnvironmentHandle);
638         return ret;
639 }
640
641
642 /*************************************************************************
643  *                              SQLAllocHandle           [ODBC32.024]
644  */
645 SQLRETURN WINAPI SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
646 {
647         SQLRETURN ret;
648         TRACE("(Type=%d, Handle=%lx)\n",HandleType,InputHandle);
649
650         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
651         {
652             if (gProxyHandle.nErrorType == ERROR_LIBRARY_NOT_FOUND)
653                 WARN("ProxyODBC: Cannot load ODBC driver manager library.\n");
654
655             if (HandleType == SQL_HANDLE_ENV)
656                 *OutputHandle = SQL_NULL_HENV;
657             else if (HandleType == SQL_HANDLE_DBC)
658                 *OutputHandle = SQL_NULL_HDBC;
659             else if (HandleType == SQL_HANDLE_STMT)
660                 *OutputHandle = SQL_NULL_HSTMT;
661             else if (HandleType == SQL_HANDLE_DESC)
662                 *OutputHandle = SQL_NULL_HDESC;
663
664             TRACE ("Not ready\n");
665             return SQL_ERROR;
666         }
667
668         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCHANDLE].func);
669         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCHANDLE].func)
670                    (HandleType, InputHandle, OutputHandle);
671         TRACE("Returns ret=%d, Handle=%lx\n",ret, *OutputHandle);
672         return ret;
673 }
674
675
676 /*************************************************************************
677  *                              SQLAllocStmt           [ODBC32.003]
678  */
679 SQLRETURN WINAPI SQLAllocStmt(SQLHDBC ConnectionHandle, SQLHSTMT *StatementHandle)
680 {
681         SQLRETURN ret;
682
683         TRACE("(Connection=%lx)\n",ConnectionHandle);
684
685         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
686         {
687            *StatementHandle = SQL_NULL_HSTMT;
688            TRACE ("Not ready\n");
689            return SQL_ERROR;
690         }
691
692         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCSTMT].func);
693         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCSTMT].func)
694             (ConnectionHandle, StatementHandle);
695         TRACE ("Returns ret=%d, Handle=%lx\n", ret, *StatementHandle);
696         return ret;
697 }
698
699
700 /*************************************************************************
701  *                              SQLAllocHandleStd           [ODBC32.077]
702  */
703 SQLRETURN WINAPI SQLAllocHandleStd( SQLSMALLINT HandleType,
704                                                          SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
705 {
706         TRACE("ProxyODBC: SQLAllocHandleStd.\n");
707
708         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
709         {
710             if (gProxyHandle.nErrorType == ERROR_LIBRARY_NOT_FOUND)
711                 WARN("ProxyODBC: Cannot load ODBC driver manager library.\n");
712
713             if (HandleType == SQL_HANDLE_ENV)
714                 *OutputHandle = SQL_NULL_HENV;
715             else if (HandleType == SQL_HANDLE_DBC)
716                 *OutputHandle = SQL_NULL_HDBC;
717             else if (HandleType == SQL_HANDLE_STMT)
718                 *OutputHandle = SQL_NULL_HSTMT;
719             else if (HandleType == SQL_HANDLE_DESC)
720                 *OutputHandle = SQL_NULL_HDESC;
721
722             return SQL_ERROR;
723         }
724
725         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCHANDLESTD].func);
726         return (gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCHANDLESTD].func)
727                    (HandleType, InputHandle, OutputHandle);
728 }
729
730
731 /*************************************************************************
732  *                              SQLBindCol           [ODBC32.004]
733  */
734 SQLRETURN WINAPI SQLBindCol(SQLHSTMT StatementHandle,
735                      SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType,
736                      SQLPOINTER TargetValue, SQLINTEGER BufferLength,
737                      SQLINTEGER *StrLen_or_Ind)
738 {
739         TRACE("\n");
740
741         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
742         {
743                 TRACE ("Not ready\n");
744                 return SQL_ERROR;
745         }
746
747         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDCOL].func);
748         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDCOL].func)
749             (StatementHandle, ColumnNumber, TargetType,
750             TargetValue, BufferLength, StrLen_or_Ind);
751 }
752
753
754 /*************************************************************************
755  *                              SQLBindParam           [ODBC32.025]
756  */
757 SQLRETURN WINAPI SQLBindParam(SQLHSTMT StatementHandle,
758              SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
759              SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision,
760              SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue,
761              SQLINTEGER *StrLen_or_Ind)
762 {
763         TRACE("\n");
764
765         CHECK_READY_AND_dmHandle();
766
767         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDPARAM].func);
768         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDPARAM].func)
769                    (StatementHandle, ParameterNumber, ValueType,
770                     ParameterScale, ParameterValue, StrLen_or_Ind);
771 }
772
773
774 /*************************************************************************
775  *                              SQLCancel           [ODBC32.005]
776  */
777 SQLRETURN WINAPI SQLCancel(SQLHSTMT StatementHandle)
778 {
779         TRACE("\n");
780
781         CHECK_READY_AND_dmHandle();
782
783         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCANCEL].func);
784         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCANCEL].func) (StatementHandle);
785 }
786
787
788 /*************************************************************************
789  *                              SQLCloseCursor           [ODBC32.026]
790  */
791 SQLRETURN WINAPI  SQLCloseCursor(SQLHSTMT StatementHandle)
792 {
793         SQLRETURN ret;
794         TRACE("(Handle=%lx)\n",StatementHandle);
795
796         CHECK_READY_AND_dmHandle();
797
798         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLCLOSECURSOR].func);
799         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLCLOSECURSOR].func) (StatementHandle);
800         TRACE("returns %d\n",ret);
801         return ret;
802 }
803
804
805 /*************************************************************************
806  *                              SQLColAttribute           [ODBC32.027]
807  */
808 SQLRETURN WINAPI SQLColAttribute (SQLHSTMT StatementHandle,
809              SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier,
810              SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength,
811              SQLSMALLINT *StringLength, SQLPOINTER NumericAttribute)
812 {
813         TRACE("\n");
814
815         CHECK_READY_AND_dmHandle();
816
817         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTE].func);
818         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTE].func)
819             (StatementHandle, ColumnNumber, FieldIdentifier,
820             CharacterAttribute, BufferLength, StringLength, NumericAttribute);
821 }
822
823
824 /*************************************************************************
825  *                              SQLColumns           [ODBC32.040]
826  */
827 SQLRETURN WINAPI SQLColumns(SQLHSTMT StatementHandle,
828              SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
829              SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
830              SQLCHAR *TableName, SQLSMALLINT NameLength3,
831              SQLCHAR *ColumnName, SQLSMALLINT NameLength4)
832 {
833         TRACE("\n");
834
835         CHECK_READY_AND_dmHandle();
836
837         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNS].func);
838         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNS].func)
839             (StatementHandle, CatalogName, NameLength1,
840             SchemaName, NameLength2, TableName, NameLength3, ColumnName, NameLength4);
841 }
842
843
844 /*************************************************************************
845  *                              SQLConnect           [ODBC32.007]
846  */
847 SQLRETURN WINAPI SQLConnect(SQLHDBC ConnectionHandle,
848              SQLCHAR *ServerName, SQLSMALLINT NameLength1,
849              SQLCHAR *UserName, SQLSMALLINT NameLength2,
850              SQLCHAR *Authentication, SQLSMALLINT NameLength3)
851 {
852         SQLRETURN ret;
853         TRACE("(Server=%.*s)\n",NameLength1, ServerName);
854
855         CHECK_READY_AND_dmHandle();
856
857         strcpy( (LPSTR)gProxyHandle.ServerName, (LPSTR)ServerName );
858         strcpy( (LPSTR)gProxyHandle.UserName, (LPSTR)UserName );
859
860         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLCONNECT].func);
861         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLCONNECT].func)
862             (ConnectionHandle, ServerName, NameLength1,
863             UserName, NameLength2, Authentication, NameLength3);
864
865         TRACE("returns %d\n",ret);
866         return ret;
867 }
868
869
870 /*************************************************************************
871  *                              SQLCopyDesc           [ODBC32.028]
872  */
873 SQLRETURN WINAPI SQLCopyDesc(SQLHDESC SourceDescHandle, SQLHDESC TargetDescHandle)
874 {
875         TRACE("\n");
876
877         CHECK_READY_AND_dmHandle();
878
879         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOPYDESC].func);
880         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOPYDESC].func)
881             (SourceDescHandle, TargetDescHandle);
882 }
883
884
885 /*************************************************************************
886  *                              SQLDataSources           [ODBC32.057]
887  */
888 SQLRETURN WINAPI SQLDataSources(SQLHENV EnvironmentHandle,
889              SQLUSMALLINT Direction, SQLCHAR *ServerName,
890              SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1,
891              SQLCHAR *Description, SQLSMALLINT BufferLength2,
892              SQLSMALLINT *NameLength2)
893 {
894         SQLRETURN ret;
895
896         TRACE("EnvironmentHandle = %p\n", (LPVOID)EnvironmentHandle);
897
898         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
899         {
900             ERR("Error: empty dm handle (gProxyHandle.dmHandle == NULL)\n");
901             return SQL_ERROR;
902         }
903
904         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLDATASOURCES].func);
905         ret = (gProxyHandle.functions[SQLAPI_INDEX_SQLDATASOURCES].func)
906             (EnvironmentHandle, Direction, ServerName,
907             BufferLength1, NameLength1, Description, BufferLength2, NameLength2);
908
909         if (TRACE_ON(odbc))
910         {
911            TRACE("returns: %d \t", ret);
912            if (*NameLength1 > 0)
913              TRACE("DataSource = %s,", ServerName);
914            if (*NameLength2 > 0)
915              TRACE(" Description = %s", Description);
916            TRACE("\n");
917         }
918
919         return ret;
920 }
921
922
923 /*************************************************************************
924  *                              SQLDescribeCol           [ODBC32.008]
925  */
926 SQLRETURN WINAPI SQLDescribeCol(SQLHSTMT StatementHandle,
927              SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName,
928              SQLSMALLINT BufferLength, SQLSMALLINT *NameLength,
929              SQLSMALLINT *DataType, SQLUINTEGER *ColumnSize,
930              SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable)
931 {
932         TRACE("\n");
933
934         CHECK_READY_AND_dmHandle();
935
936         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBECOL].func);
937         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBECOL].func)
938             (StatementHandle, ColumnNumber, ColumnName,
939             BufferLength, NameLength, DataType, ColumnSize, DecimalDigits, Nullable);
940 }
941
942
943 /*************************************************************************
944  *                              SQLDisconnect           [ODBC32.009]
945  */
946 SQLRETURN WINAPI SQLDisconnect(SQLHDBC ConnectionHandle)
947 {
948         SQLRETURN ret;
949         TRACE("(Handle=%lx)\n", ConnectionHandle);
950
951         CHECK_READY_AND_dmHandle();
952
953         gProxyHandle.ServerName[0] = '\0';
954         gProxyHandle.UserName[0]   = '\0';
955
956         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLDISCONNECT].func);
957         ret = (gProxyHandle.functions[SQLAPI_INDEX_SQLDISCONNECT].func) (ConnectionHandle);
958         TRACE("returns %d\n",ret);
959         return ret;
960 }
961
962
963 /*************************************************************************
964  *                              SQLEndTran           [ODBC32.029]
965  */
966 SQLRETURN WINAPI SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType)
967 {
968         TRACE("\n");
969
970         CHECK_READY_AND_dmHandle();
971
972         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLENDTRAN].func);
973         return (gProxyHandle.functions[SQLAPI_INDEX_SQLENDTRAN].func) (HandleType, Handle, CompletionType);
974 }
975
976
977 /*************************************************************************
978  *                              SQLError           [ODBC32.010]
979  */
980 SQLRETURN WINAPI SQLError(SQLHENV EnvironmentHandle,
981              SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle,
982              SQLCHAR *Sqlstate, SQLINTEGER *NativeError,
983              SQLCHAR *MessageText, SQLSMALLINT BufferLength,
984              SQLSMALLINT *TextLength)
985 {
986         TRACE("\n");
987
988         CHECK_READY_AND_dmHandle();
989
990         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLERROR].func);
991         return (gProxyHandle.functions[SQLAPI_INDEX_SQLERROR].func)
992             (EnvironmentHandle, ConnectionHandle, StatementHandle,
993             Sqlstate, NativeError, MessageText, BufferLength, TextLength);
994 }
995
996
997 /*************************************************************************
998  *                              SQLExecDirect           [ODBC32.011]
999  */
1000 SQLRETURN WINAPI SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength)
1001 {
1002         TRACE("\n");
1003
1004         CHECK_READY_AND_dmHandle();
1005
1006         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECDIRECT].func);
1007         return (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECDIRECT].func)
1008             (StatementHandle, StatementText, TextLength);
1009 }
1010
1011
1012 /*************************************************************************
1013  *                              SQLExecute           [ODBC32.012]
1014  */
1015 SQLRETURN WINAPI SQLExecute(SQLHSTMT StatementHandle)
1016 {
1017         TRACE("\n");
1018
1019         CHECK_READY_AND_dmHandle();
1020
1021         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECUTE].func);
1022         return (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECUTE].func) (StatementHandle);
1023 }
1024
1025
1026 /*************************************************************************
1027  *                              SQLFetch           [ODBC32.013]
1028  */
1029 SQLRETURN WINAPI SQLFetch(SQLHSTMT StatementHandle)
1030 {
1031         TRACE("\n");
1032
1033         CHECK_READY_AND_dmHandle();
1034
1035         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFETCH].func);
1036         return (gProxyHandle.functions[SQLAPI_INDEX_SQLFETCH].func) (StatementHandle);
1037 }
1038
1039
1040 /*************************************************************************
1041  *                              SQLFetchScroll          [ODBC32.030]
1042  */
1043 SQLRETURN WINAPI SQLFetchScroll(SQLHSTMT StatementHandle, SQLSMALLINT FetchOrientation, SQLINTEGER FetchOffset)
1044 {
1045         TRACE("\n");
1046
1047         CHECK_dmHandle();
1048
1049         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFETCHSCROLL].func);
1050         return (gProxyHandle.functions[SQLAPI_INDEX_SQLFETCHSCROLL].func)
1051             (StatementHandle, FetchOrientation, FetchOffset);
1052 }
1053
1054
1055 /*************************************************************************
1056  *                              SQLFreeConnect           [ODBC32.014]
1057  */
1058 SQLRETURN WINAPI SQLFreeConnect(SQLHDBC ConnectionHandle)
1059 {
1060         SQLRETURN ret;
1061         TRACE("(Handle=%lx)\n",ConnectionHandle);
1062
1063         CHECK_dmHandle();
1064
1065         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFREECONNECT].func);
1066         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLFREECONNECT].func) (ConnectionHandle);
1067         TRACE("Returns %d\n",ret);
1068         return ret;
1069 }
1070
1071
1072 /*************************************************************************
1073  *                              SQLFreeEnv           [ODBC32.015]
1074  */
1075 SQLRETURN WINAPI SQLFreeEnv(SQLHENV EnvironmentHandle)
1076 {
1077         SQLRETURN ret;
1078         TRACE("(Env=%lx)\n",EnvironmentHandle);
1079
1080         CHECK_dmHandle();
1081
1082         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFREEENV].func);
1083         ret = (gProxyHandle.functions[SQLAPI_INDEX_SQLFREEENV].func) (EnvironmentHandle);
1084         TRACE("Returns %d\n",ret);
1085         return ret;
1086 }
1087
1088
1089 /*************************************************************************
1090  *                              SQLFreeHandle           [ODBC32.031]
1091  */
1092 SQLRETURN WINAPI SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
1093 {
1094         SQLRETURN ret;
1095         TRACE("(Type=%d, Handle=%lx)\n",HandleType,Handle);
1096
1097         CHECK_dmHandle();
1098
1099         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFREEHANDLE].func);
1100         ret = (gProxyHandle.functions[SQLAPI_INDEX_SQLFREEHANDLE].func)
1101             (HandleType, Handle);
1102         TRACE ("Returns %d\n",ret);
1103         return ret;
1104 }
1105
1106
1107 /*************************************************************************
1108  *                              SQLFreeStmt           [ODBC32.016]
1109  */
1110 SQLRETURN WINAPI SQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option)
1111 {
1112         SQLRETURN ret;
1113         TRACE("(Handle %lx, Option=%d)\n",StatementHandle, Option);
1114
1115         CHECK_dmHandle();
1116
1117         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFREESTMT].func);
1118         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLFREESTMT].func)
1119             (StatementHandle, Option);
1120         TRACE("Returns %d\n",ret);
1121         return ret;
1122 }
1123
1124
1125 /*************************************************************************
1126  *                              SQLGetConnectAttr           [ODBC32.032]
1127  */
1128 SQLRETURN WINAPI SQLGetConnectAttr(SQLHDBC ConnectionHandle,
1129              SQLINTEGER Attribute, SQLPOINTER Value,
1130              SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1131 {
1132         TRACE("\n");
1133
1134         CHECK_dmHandle();
1135
1136         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTATTR].func);
1137         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTATTR].func)
1138             (ConnectionHandle, Attribute, Value,
1139             BufferLength, StringLength);
1140 }
1141
1142
1143 /*************************************************************************
1144  *                              SQLGetConnectOption       [ODBC32.042]
1145  */
1146 SQLRETURN WINAPI SQLGetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLPOINTER Value)
1147 {
1148         TRACE("\n");
1149
1150         CHECK_dmHandle();
1151
1152         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTOPTION].func);
1153         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTOPTION].func)
1154             (ConnectionHandle, Option, Value);
1155 }
1156
1157
1158 /*************************************************************************
1159  *                              SQLGetCursorName           [ODBC32.017]
1160  */
1161 SQLRETURN WINAPI SQLGetCursorName(SQLHSTMT StatementHandle,
1162              SQLCHAR *CursorName, SQLSMALLINT BufferLength,
1163              SQLSMALLINT *NameLength)
1164 {
1165         TRACE("\n");
1166
1167         CHECK_dmHandle();
1168
1169         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCURSORNAME].func);
1170         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCURSORNAME].func)
1171             (StatementHandle, CursorName, BufferLength, NameLength);
1172 }
1173
1174
1175 /*************************************************************************
1176  *                              SQLGetData           [ODBC32.043]
1177  */
1178 SQLRETURN WINAPI SQLGetData(SQLHSTMT StatementHandle,
1179              SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType,
1180              SQLPOINTER TargetValue, SQLINTEGER BufferLength,
1181              SQLINTEGER *StrLen_or_Ind)
1182 {
1183         TRACE("\n");
1184
1185         CHECK_dmHandle();
1186
1187         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDATA].func);
1188         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDATA].func)
1189             (StatementHandle, ColumnNumber, TargetType,
1190             TargetValue, BufferLength, StrLen_or_Ind);
1191 }
1192
1193
1194 /*************************************************************************
1195  *                              SQLGetDescField           [ODBC32.033]
1196  */
1197 SQLRETURN WINAPI SQLGetDescField(SQLHDESC DescriptorHandle,
1198              SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
1199              SQLPOINTER Value, SQLINTEGER BufferLength,
1200              SQLINTEGER *StringLength)
1201 {
1202         TRACE("\n");
1203
1204         CHECK_dmHandle();
1205
1206         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCFIELD].func);
1207         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCFIELD].func)
1208             (DescriptorHandle, RecNumber, FieldIdentifier,
1209             Value, BufferLength, StringLength);
1210 }
1211
1212
1213 /*************************************************************************
1214  *                              SQLGetDescRec           [ODBC32.034]
1215  */
1216 SQLRETURN WINAPI SQLGetDescRec(SQLHDESC DescriptorHandle,
1217              SQLSMALLINT RecNumber, SQLCHAR *Name,
1218              SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
1219              SQLSMALLINT *Type, SQLSMALLINT *SubType,
1220              SQLINTEGER *Length, SQLSMALLINT *Precision,
1221              SQLSMALLINT *Scale, SQLSMALLINT *Nullable)
1222 {
1223         TRACE("\n");
1224
1225         CHECK_dmHandle();
1226
1227         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCREC].func);
1228         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCREC].func)
1229             (DescriptorHandle, RecNumber, Name, BufferLength,
1230             StringLength, Type, SubType, Length, Precision, Scale, Nullable);
1231 }
1232
1233
1234 /*************************************************************************
1235  *                              SQLGetDiagField           [ODBC32.035]
1236  */
1237 SQLRETURN WINAPI SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
1238              SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
1239              SQLPOINTER DiagInfo, SQLSMALLINT BufferLength,
1240              SQLSMALLINT *StringLength)
1241 {
1242         TRACE("\n");
1243
1244         CHECK_dmHandle();
1245
1246         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGFIELD].func);
1247         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGFIELD].func)
1248             (HandleType, Handle, RecNumber, DiagIdentifier,
1249             DiagInfo, BufferLength, StringLength);
1250 }
1251
1252
1253 /*************************************************************************
1254  *                              SQLGetDiagRec           [ODBC32.036]
1255  */
1256 SQLRETURN WINAPI SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
1257              SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
1258              SQLINTEGER *NativeError, SQLCHAR *MessageText,
1259              SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
1260 {
1261         TRACE("\n");
1262
1263         CHECK_dmHandle();
1264
1265         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGREC].func);
1266         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGREC].func)
1267             (HandleType, Handle, RecNumber, Sqlstate, NativeError,
1268             MessageText, BufferLength, TextLength);
1269 }
1270
1271
1272 /*************************************************************************
1273  *                              SQLGetEnvAttr           [ODBC32.037]
1274  */
1275 SQLRETURN WINAPI SQLGetEnvAttr(SQLHENV EnvironmentHandle,
1276              SQLINTEGER Attribute, SQLPOINTER Value,
1277              SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1278 {
1279         TRACE("\n");
1280
1281         CHECK_dmHandle();
1282
1283         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETENVATTR].func);
1284         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETENVATTR].func)
1285             (EnvironmentHandle, Attribute, Value, BufferLength, StringLength);
1286 }
1287
1288
1289 /*************************************************************************
1290  *                              SQLGetFunctions           [ODBC32.044]
1291  */
1292 SQLRETURN WINAPI SQLGetFunctions(SQLHDBC ConnectionHandle, SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported)
1293 {
1294         TRACE("\n");
1295
1296         CHECK_dmHandle();
1297
1298         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETFUNCTIONS].func);
1299         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETFUNCTIONS].func)
1300             (ConnectionHandle, FunctionId, Supported);
1301 }
1302
1303
1304 /*************************************************************************
1305  *                              SQLGetInfo           [ODBC32.045]
1306  */
1307 SQLRETURN WINAPI SQLGetInfo(SQLHDBC ConnectionHandle,
1308              SQLUSMALLINT InfoType, SQLPOINTER InfoValue,
1309              SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
1310 {
1311         TRACE("\n");
1312
1313         CHECK_dmHandle();
1314
1315         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETINFO].func);
1316         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETINFO].func)
1317             (ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength);
1318 }
1319
1320
1321 /*************************************************************************
1322  *                              SQLGetStmtAttr           [ODBC32.038]
1323  */
1324 SQLRETURN WINAPI SQLGetStmtAttr(SQLHSTMT StatementHandle,
1325              SQLINTEGER Attribute, SQLPOINTER Value,
1326              SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1327 {
1328         TRACE("\n");
1329
1330         CHECK_dmHandle();
1331
1332         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTATTR].func);
1333         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTATTR].func)
1334             (StatementHandle, Attribute, Value, BufferLength, StringLength);
1335 }
1336
1337
1338 /*************************************************************************
1339  *                              SQLGetStmtOption           [ODBC32.046]
1340  */
1341 SQLRETURN WINAPI SQLGetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLPOINTER Value)
1342 {
1343         TRACE("\n");
1344
1345         CHECK_dmHandle();
1346
1347         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTOPTION].func);
1348         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTOPTION].func)
1349                 (StatementHandle, Option, Value);
1350 }
1351
1352
1353 /*************************************************************************
1354  *                              SQLGetTypeInfo           [ODBC32.047]
1355  */
1356 SQLRETURN WINAPI SQLGetTypeInfo(SQLHSTMT StatementHandle, SQLSMALLINT DataType)
1357 {
1358         TRACE("\n");
1359
1360         CHECK_dmHandle();
1361
1362         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETTYPEINFO].func);
1363         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETTYPEINFO].func)
1364             (StatementHandle, DataType);
1365 }
1366
1367
1368 /*************************************************************************
1369  *                              SQLNumResultCols           [ODBC32.018]
1370  */
1371 SQLRETURN WINAPI SQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount)
1372 {
1373         TRACE("\n");
1374
1375         CHECK_dmHandle();
1376
1377         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLNUMRESULTCOLS].func);
1378         return (gProxyHandle.functions[SQLAPI_INDEX_SQLNUMRESULTCOLS].func)
1379             (StatementHandle, ColumnCount);
1380 }
1381
1382
1383 /*************************************************************************
1384  *                              SQLParamData           [ODBC32.048]
1385  */
1386 SQLRETURN WINAPI SQLParamData(SQLHSTMT StatementHandle, SQLPOINTER *Value)
1387 {
1388         TRACE("\n");
1389
1390         CHECK_dmHandle();
1391
1392         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPARAMDATA].func);
1393         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPARAMDATA].func)
1394             (StatementHandle, Value);
1395 }
1396
1397
1398 /*************************************************************************
1399  *                              SQLPrepare           [ODBC32.019]
1400  */
1401 SQLRETURN WINAPI SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength)
1402 {
1403         TRACE("\n");
1404
1405         CHECK_dmHandle();
1406
1407         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPREPARE].func);
1408         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPREPARE].func)
1409             (StatementHandle, StatementText, TextLength);
1410 }
1411
1412
1413 /*************************************************************************
1414  *                              SQLPutData           [ODBC32.049]
1415  */
1416 SQLRETURN WINAPI SQLPutData(SQLHSTMT StatementHandle, SQLPOINTER Data, SQLINTEGER StrLen_or_Ind)
1417 {
1418         TRACE("\n");
1419
1420         CHECK_dmHandle();
1421
1422         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPUTDATA].func);
1423         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPUTDATA].func)
1424             (StatementHandle, Data, StrLen_or_Ind);
1425 }
1426
1427
1428 /*************************************************************************
1429  *                              SQLRowCount           [ODBC32.020]
1430  */
1431 SQLRETURN WINAPI SQLRowCount(SQLHSTMT StatementHandle, SQLINTEGER *RowCount)
1432 {
1433         TRACE("\n");
1434
1435         CHECK_dmHandle();
1436
1437         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLROWCOUNT].func);
1438         return (gProxyHandle.functions[SQLAPI_INDEX_SQLROWCOUNT].func)
1439             (StatementHandle, RowCount);
1440 }
1441
1442
1443 /*************************************************************************
1444  *                              SQLSetConnectAttr           [ODBC32.039]
1445  */
1446 SQLRETURN WINAPI SQLSetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute,
1447         SQLPOINTER Value, SQLINTEGER StringLength)
1448 {
1449         TRACE("\n");
1450
1451         CHECK_dmHandle();
1452
1453         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTATTR].func);
1454         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTATTR].func)
1455             (ConnectionHandle, Attribute, Value, StringLength);
1456 }
1457
1458
1459 /*************************************************************************
1460  *                              SQLSetConnectOption           [ODBC32.050]
1461  */
1462 SQLRETURN WINAPI SQLSetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLUINTEGER Value)
1463 {
1464         TRACE("\n");
1465
1466         CHECK_dmHandle();
1467
1468         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTOPTION].func);
1469         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTOPTION].func)
1470             (ConnectionHandle, Option, Value);
1471 }
1472
1473
1474 /*************************************************************************
1475  *                              SQLSetCursorName           [ODBC32.021]
1476  */
1477 SQLRETURN WINAPI SQLSetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLSMALLINT NameLength)
1478 {
1479         TRACE("\n");
1480
1481         CHECK_dmHandle();
1482
1483         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCURSORNAME].func);
1484         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCURSORNAME].func)
1485             (StatementHandle, CursorName, NameLength);
1486 }
1487
1488
1489 /*************************************************************************
1490  *                              SQLSetDescField           [ODBC32.073]
1491  */
1492 SQLRETURN WINAPI SQLSetDescField(SQLHDESC DescriptorHandle,
1493              SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
1494              SQLPOINTER Value, SQLINTEGER BufferLength)
1495 {
1496         TRACE("\n");
1497
1498         CHECK_dmHandle();
1499
1500         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCFIELD].func);
1501         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCFIELD].func)
1502             (DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength);
1503 }
1504
1505
1506 /*************************************************************************
1507  *                              SQLSetDescRec           [ODBC32.074]
1508  */
1509 SQLRETURN WINAPI SQLSetDescRec(SQLHDESC DescriptorHandle,
1510              SQLSMALLINT RecNumber, SQLSMALLINT Type,
1511              SQLSMALLINT SubType, SQLINTEGER Length,
1512              SQLSMALLINT Precision, SQLSMALLINT Scale,
1513              SQLPOINTER Data, SQLINTEGER *StringLength,
1514              SQLINTEGER *Indicator)
1515 {
1516         TRACE("\n");
1517
1518         CHECK_dmHandle();
1519
1520         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCREC].func);
1521         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCREC].func)
1522             (DescriptorHandle, RecNumber, Type, SubType, Length,
1523             Precision, Scale, Data, StringLength, Indicator);
1524 }
1525
1526
1527 /*************************************************************************
1528  *                              SQLSetEnvAttr           [ODBC32.075]
1529  */
1530 SQLRETURN WINAPI SQLSetEnvAttr(SQLHENV EnvironmentHandle,
1531              SQLINTEGER Attribute, SQLPOINTER Value,
1532              SQLINTEGER StringLength)
1533 {
1534         TRACE("\n");
1535
1536         CHECK_dmHandle();
1537
1538         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETENVATTR].func);
1539         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETENVATTR].func)
1540             (EnvironmentHandle, Attribute, Value, StringLength);
1541 }
1542
1543
1544 /*************************************************************************
1545  *                              SQLSetParam           [ODBC32.022]
1546  */
1547 SQLRETURN WINAPI SQLSetParam(SQLHSTMT StatementHandle,
1548              SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
1549              SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision,
1550              SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue,
1551              SQLINTEGER *StrLen_or_Ind)
1552 {
1553         TRACE("\n");
1554
1555         CHECK_dmHandle();
1556
1557         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETPARAM].func);
1558         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETPARAM].func)
1559             (StatementHandle, ParameterNumber, ValueType, ParameterType, LengthPrecision,
1560              ParameterScale, ParameterValue, StrLen_or_Ind);
1561 }
1562
1563
1564 /*************************************************************************
1565  *                              SQLSetStmtAttr           [ODBC32.076]
1566  */
1567 SQLRETURN WINAPI SQLSetStmtAttr(SQLHSTMT StatementHandle,
1568                  SQLINTEGER Attribute, SQLPOINTER Value,
1569                  SQLINTEGER StringLength)
1570 {
1571         TRACE("\n");
1572
1573         CHECK_dmHandle();
1574
1575         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTATTR].func);
1576         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTATTR].func)
1577             (StatementHandle, Attribute, Value, StringLength);
1578 }
1579
1580
1581 /*************************************************************************
1582  *                              SQLSetStmtOption           [ODBC32.051]
1583  */
1584 SQLRETURN WINAPI SQLSetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLUINTEGER Value)
1585 {
1586         TRACE("\n");
1587
1588         CHECK_dmHandle();
1589
1590         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTOPTION].func);
1591         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTOPTION].func)
1592             (StatementHandle, Option, Value);
1593 }
1594
1595
1596 /*************************************************************************
1597  *                              SQLSpecialColumns           [ODBC32.052]
1598  */
1599 SQLRETURN WINAPI SQLSpecialColumns(SQLHSTMT StatementHandle,
1600              SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName,
1601              SQLSMALLINT NameLength1, SQLCHAR *SchemaName,
1602              SQLSMALLINT NameLength2, SQLCHAR *TableName,
1603              SQLSMALLINT NameLength3, SQLUSMALLINT Scope,
1604              SQLUSMALLINT Nullable)
1605 {
1606
1607         CHECK_dmHandle();
1608
1609         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSPECIALCOLUMNS].func);
1610         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSPECIALCOLUMNS].func)
1611             (StatementHandle, IdentifierType, CatalogName, NameLength1, SchemaName,
1612              NameLength2, TableName, NameLength3, Scope, Nullable);
1613 }
1614
1615
1616 /*************************************************************************
1617  *                              SQLStatistics           [ODBC32.053]
1618  */
1619 SQLRETURN WINAPI SQLStatistics(SQLHSTMT StatementHandle,
1620              SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
1621              SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
1622              SQLCHAR *TableName, SQLSMALLINT NameLength3,
1623              SQLUSMALLINT Unique, SQLUSMALLINT Reserved)
1624 {
1625         TRACE("\n");
1626
1627         CHECK_dmHandle();
1628
1629         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSTATISTICS].func);
1630         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSTATISTICS].func)
1631             (StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2,
1632              TableName, NameLength3, Unique, Reserved);
1633 }
1634
1635
1636 /*************************************************************************
1637  *                              SQLTables           [ODBC32.054]
1638  */
1639 SQLRETURN WINAPI SQLTables(SQLHSTMT StatementHandle,
1640              SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
1641              SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
1642              SQLCHAR *TableName, SQLSMALLINT NameLength3,
1643              SQLCHAR *TableType, SQLSMALLINT NameLength4)
1644 {
1645         TRACE("\n");
1646
1647         CHECK_dmHandle();
1648
1649         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLES].func);
1650         return (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLES].func)
1651                 (StatementHandle, CatalogName, NameLength1,
1652                 SchemaName, NameLength2, TableName, NameLength3, TableType, NameLength4);
1653 }
1654
1655
1656 /*************************************************************************
1657  *                              SQLTransact           [ODBC32.023]
1658  */
1659 SQLRETURN WINAPI SQLTransact(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle,
1660         SQLUSMALLINT CompletionType)
1661 {
1662         TRACE("\n");
1663
1664         CHECK_dmHandle();
1665
1666         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLTRANSACT].func);
1667         return (gProxyHandle.functions[SQLAPI_INDEX_SQLTRANSACT].func)
1668             (EnvironmentHandle, ConnectionHandle, CompletionType);
1669 }
1670
1671
1672 /*************************************************************************
1673  *                              SQLBrowseConnect           [ODBC32.055]
1674  */
1675 SQLRETURN WINAPI SQLBrowseConnect(
1676     SQLHDBC            hdbc,
1677     SQLCHAR               *szConnStrIn,
1678     SQLSMALLINT        cbConnStrIn,
1679     SQLCHAR               *szConnStrOut,
1680     SQLSMALLINT        cbConnStrOutMax,
1681     SQLSMALLINT       *pcbConnStrOut)
1682 {
1683         TRACE("\n");
1684
1685         CHECK_dmHandle();
1686
1687         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBROWSECONNECT].func);
1688         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBROWSECONNECT].func)
1689                 (hdbc, szConnStrIn, cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut);
1690 }
1691
1692
1693 /*************************************************************************
1694  *                              SQLBulkOperations           [ODBC32.078]
1695  */
1696 SQLRETURN WINAPI  SQLBulkOperations(
1697         SQLHSTMT                        StatementHandle,
1698         SQLSMALLINT                     Operation)
1699 {
1700         TRACE("\n");
1701
1702         CHECK_dmHandle();
1703
1704         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBULKOPERATIONS].func);
1705         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBULKOPERATIONS].func)
1706                    (StatementHandle, Operation);
1707 }
1708
1709
1710 /*************************************************************************
1711  *                              SQLColAttributes           [ODBC32.006]
1712  */
1713 SQLRETURN WINAPI SQLColAttributes(
1714     SQLHSTMT           hstmt,
1715     SQLUSMALLINT       icol,
1716     SQLUSMALLINT       fDescType,
1717     SQLPOINTER         rgbDesc,
1718     SQLSMALLINT        cbDescMax,
1719     SQLSMALLINT           *pcbDesc,
1720     SQLINTEGER            *pfDesc)
1721 {
1722         TRACE("\n");
1723
1724         CHECK_dmHandle();
1725
1726         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTES].func);
1727         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTES].func)
1728                    (hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
1729 }
1730
1731
1732 /*************************************************************************
1733  *                              SQLColumnPrivileges           [ODBC32.056]
1734  */
1735 SQLRETURN WINAPI SQLColumnPrivileges(
1736     SQLHSTMT           hstmt,
1737     SQLCHAR               *szCatalogName,
1738     SQLSMALLINT        cbCatalogName,
1739     SQLCHAR               *szSchemaName,
1740     SQLSMALLINT        cbSchemaName,
1741     SQLCHAR               *szTableName,
1742     SQLSMALLINT        cbTableName,
1743     SQLCHAR               *szColumnName,
1744     SQLSMALLINT        cbColumnName)
1745 {
1746         TRACE("\n");
1747
1748         CHECK_dmHandle();
1749
1750         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNPRIVILEGES].func);
1751         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNPRIVILEGES].func)
1752                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1753                     szTableName, cbTableName, szColumnName, cbColumnName);
1754 }
1755
1756
1757 /*************************************************************************
1758  *                              SQLDescribeParam          [ODBC32.058]
1759  */
1760 SQLRETURN WINAPI SQLDescribeParam(
1761     SQLHSTMT           hstmt,
1762     SQLUSMALLINT       ipar,
1763     SQLSMALLINT           *pfSqlType,
1764     SQLUINTEGER           *pcbParamDef,
1765     SQLSMALLINT           *pibScale,
1766     SQLSMALLINT           *pfNullable)
1767 {
1768         TRACE("\n");
1769
1770         CHECK_dmHandle();
1771
1772         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBEPARAM].func);
1773         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBEPARAM].func)
1774                    (hstmt, ipar, pfSqlType, pcbParamDef, pibScale, pfNullable);
1775 }
1776
1777
1778 /*************************************************************************
1779  *                              SQLExtendedFetch           [ODBC32.059]
1780  */
1781 SQLRETURN WINAPI SQLExtendedFetch(
1782     SQLHSTMT           hstmt,
1783     SQLUSMALLINT       fFetchType,
1784     SQLINTEGER         irow,
1785     SQLUINTEGER           *pcrow,
1786     SQLUSMALLINT          *rgfRowStatus)
1787 {
1788         TRACE("\n");
1789
1790         CHECK_dmHandle();
1791
1792         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLEXTENDEDFETCH].func);
1793         return (gProxyHandle.functions[SQLAPI_INDEX_SQLEXTENDEDFETCH].func)
1794                    (hstmt, fFetchType, irow, pcrow, rgfRowStatus);
1795 }
1796
1797
1798 /*************************************************************************
1799  *                              SQLForeignKeys           [ODBC32.060]
1800  */
1801 SQLRETURN WINAPI SQLForeignKeys(
1802     SQLHSTMT           hstmt,
1803     SQLCHAR               *szPkCatalogName,
1804     SQLSMALLINT        cbPkCatalogName,
1805     SQLCHAR               *szPkSchemaName,
1806     SQLSMALLINT        cbPkSchemaName,
1807     SQLCHAR               *szPkTableName,
1808     SQLSMALLINT        cbPkTableName,
1809     SQLCHAR               *szFkCatalogName,
1810     SQLSMALLINT        cbFkCatalogName,
1811     SQLCHAR               *szFkSchemaName,
1812     SQLSMALLINT        cbFkSchemaName,
1813     SQLCHAR               *szFkTableName,
1814     SQLSMALLINT        cbFkTableName)
1815 {
1816         TRACE("\n");
1817
1818         CHECK_dmHandle();
1819
1820         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFOREIGNKEYS].func);
1821         return (gProxyHandle.functions[SQLAPI_INDEX_SQLFOREIGNKEYS].func)
1822                    (hstmt, szPkCatalogName, cbPkCatalogName, szPkSchemaName, cbPkSchemaName,
1823                     szPkTableName, cbPkTableName, szFkCatalogName, cbFkCatalogName, szFkSchemaName,
1824                         cbFkSchemaName, szFkTableName, cbFkTableName);
1825 }
1826
1827
1828 /*************************************************************************
1829  *                              SQLMoreResults           [ODBC32.061]
1830  */
1831 SQLRETURN WINAPI SQLMoreResults(SQLHSTMT hstmt)
1832 {
1833         TRACE("\n");
1834
1835         CHECK_dmHandle();
1836
1837         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLMORERESULTS].func);
1838         return (gProxyHandle.functions[SQLAPI_INDEX_SQLMORERESULTS].func) (hstmt);
1839 }
1840
1841
1842 /*************************************************************************
1843  *                              SQLNativeSql           [ODBC32.062]
1844  */
1845 SQLRETURN WINAPI SQLNativeSql(
1846     SQLHDBC            hdbc,
1847     SQLCHAR               *szSqlStrIn,
1848     SQLINTEGER         cbSqlStrIn,
1849     SQLCHAR               *szSqlStr,
1850     SQLINTEGER         cbSqlStrMax,
1851     SQLINTEGER            *pcbSqlStr)
1852 {
1853         TRACE("\n");
1854
1855         CHECK_dmHandle();
1856
1857         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLNATIVESQL].func);
1858         return (gProxyHandle.functions[SQLAPI_INDEX_SQLNATIVESQL].func)
1859                    (hdbc, szSqlStrIn, cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr);
1860 }
1861
1862
1863 /*************************************************************************
1864  *                              SQLNumParams           [ODBC32.063]
1865  */
1866 SQLRETURN WINAPI SQLNumParams(
1867     SQLHSTMT           hstmt,
1868     SQLSMALLINT           *pcpar)
1869 {
1870         TRACE("\n");
1871
1872         CHECK_dmHandle();
1873
1874         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLNUMPARAMS].func);
1875         return (gProxyHandle.functions[SQLAPI_INDEX_SQLNUMPARAMS].func) (hstmt, pcpar);
1876 }
1877
1878
1879 /*************************************************************************
1880  *                              SQLParamOptions           [ODBC32.064]
1881  */
1882 SQLRETURN WINAPI SQLParamOptions(
1883     SQLHSTMT           hstmt,
1884     SQLUINTEGER        crow,
1885     SQLUINTEGER           *pirow)
1886 {
1887         TRACE("\n");
1888
1889         CHECK_dmHandle();
1890
1891         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPARAMOPTIONS].func);
1892         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPARAMOPTIONS].func) (hstmt, crow, pirow);
1893 }
1894
1895
1896 /*************************************************************************
1897  *                              SQLPrimaryKeys           [ODBC32.065]
1898  */
1899 SQLRETURN WINAPI SQLPrimaryKeys(
1900     SQLHSTMT           hstmt,
1901     SQLCHAR               *szCatalogName,
1902     SQLSMALLINT        cbCatalogName,
1903     SQLCHAR               *szSchemaName,
1904     SQLSMALLINT        cbSchemaName,
1905     SQLCHAR               *szTableName,
1906     SQLSMALLINT        cbTableName)
1907 {
1908         TRACE("\n");
1909
1910         CHECK_dmHandle();
1911
1912         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPRIMARYKEYS].func);
1913         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPRIMARYKEYS].func)
1914                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1915                     szTableName, cbTableName);
1916 }
1917
1918
1919 /*************************************************************************
1920  *                              SQLProcedureColumns           [ODBC32.066]
1921  */
1922 SQLRETURN WINAPI SQLProcedureColumns(
1923     SQLHSTMT           hstmt,
1924     SQLCHAR               *szCatalogName,
1925     SQLSMALLINT        cbCatalogName,
1926     SQLCHAR               *szSchemaName,
1927     SQLSMALLINT        cbSchemaName,
1928     SQLCHAR               *szProcName,
1929     SQLSMALLINT        cbProcName,
1930     SQLCHAR               *szColumnName,
1931     SQLSMALLINT        cbColumnName)
1932 {
1933         TRACE("\n");
1934
1935         CHECK_dmHandle();
1936
1937         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURECOLUMNS].func);
1938         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURECOLUMNS].func)
1939                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1940                     szProcName, cbProcName, szColumnName, cbColumnName);
1941 }
1942
1943
1944 /*************************************************************************
1945  *                              SQLProcedures           [ODBC32.067]
1946  */
1947 SQLRETURN WINAPI SQLProcedures(
1948     SQLHSTMT           hstmt,
1949     SQLCHAR               *szCatalogName,
1950     SQLSMALLINT        cbCatalogName,
1951     SQLCHAR               *szSchemaName,
1952     SQLSMALLINT        cbSchemaName,
1953     SQLCHAR               *szProcName,
1954     SQLSMALLINT        cbProcName)
1955 {
1956         TRACE("\n");
1957
1958         CHECK_dmHandle();
1959
1960         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURES].func);
1961         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURES].func)
1962                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1963                     szProcName, cbProcName);
1964 }
1965
1966
1967 /*************************************************************************
1968  *                              SQLSetPos           [ODBC32.068]
1969  */
1970 SQLRETURN WINAPI SQLSetPos(
1971     SQLHSTMT           hstmt,
1972     SQLUSMALLINT       irow,
1973     SQLUSMALLINT       fOption,
1974     SQLUSMALLINT       fLock)
1975 {
1976         TRACE("\n");
1977
1978         CHECK_dmHandle();
1979
1980         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETPOS].func);
1981         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETPOS].func)
1982                    (hstmt, irow, fOption, fLock);
1983 }
1984
1985
1986 /*************************************************************************
1987  *                              SQLTablePrivileges           [ODBC32.070]
1988  */
1989 SQLRETURN WINAPI SQLTablePrivileges(
1990     SQLHSTMT           hstmt,
1991     SQLCHAR               *szCatalogName,
1992     SQLSMALLINT        cbCatalogName,
1993     SQLCHAR               *szSchemaName,
1994     SQLSMALLINT        cbSchemaName,
1995     SQLCHAR               *szTableName,
1996     SQLSMALLINT        cbTableName)
1997 {
1998         TRACE("\n");
1999
2000         CHECK_dmHandle();
2001
2002         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLEPRIVILEGES].func);
2003         return (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLEPRIVILEGES].func)
2004                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
2005                     szTableName, cbTableName);
2006 }
2007
2008
2009 /*************************************************************************
2010  *                              SQLDrivers           [ODBC32.071]
2011  */
2012 SQLRETURN WINAPI SQLDrivers(
2013     SQLHENV            henv,
2014     SQLUSMALLINT       fDirection,
2015     SQLCHAR               *szDriverDesc,
2016     SQLSMALLINT        cbDriverDescMax,
2017     SQLSMALLINT           *pcbDriverDesc,
2018     SQLCHAR               *szDriverAttributes,
2019     SQLSMALLINT        cbDriverAttrMax,
2020     SQLSMALLINT           *pcbDriverAttr)
2021 {
2022         TRACE("\n");
2023
2024         CHECK_dmHandle();
2025
2026         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERS].func);
2027         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERS].func)
2028                 (henv, fDirection, szDriverDesc, cbDriverDescMax, pcbDriverDesc,
2029                  szDriverAttributes, cbDriverAttrMax, pcbDriverAttr);
2030 }
2031
2032
2033 /*************************************************************************
2034  *                              SQLBindParameter           [ODBC32.072]
2035  */
2036 SQLRETURN WINAPI SQLBindParameter(
2037     SQLHSTMT           hstmt,
2038     SQLUSMALLINT       ipar,
2039     SQLSMALLINT        fParamType,
2040     SQLSMALLINT        fCType,
2041     SQLSMALLINT        fSqlType,
2042     SQLUINTEGER        cbColDef,
2043     SQLSMALLINT        ibScale,
2044     SQLPOINTER         rgbValue,
2045     SQLINTEGER         cbValueMax,
2046     SQLINTEGER            *pcbValue)
2047 {
2048         TRACE("\n");
2049
2050         CHECK_dmHandle();
2051
2052         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDPARAMETER].func);
2053         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDPARAMETER].func)
2054                 (hstmt, ipar, fParamType, fCType, fSqlType, cbColDef, ibScale,
2055                  rgbValue, cbValueMax, pcbValue);
2056 }
2057
2058
2059 /*************************************************************************
2060  *                              SQLDriverConnect           [ODBC32.041]
2061  */
2062 SQLRETURN WINAPI SQLDriverConnect(
2063     SQLHDBC            hdbc,
2064     SQLHWND            hwnd,
2065     SQLCHAR            *conn_str_in,
2066     SQLSMALLINT        len_conn_str_in,
2067     SQLCHAR            *conn_str_out,
2068     SQLSMALLINT        conn_str_out_max,
2069     SQLSMALLINT        *ptr_conn_str_out,
2070     SQLUSMALLINT       driver_completion )
2071 {
2072         TRACE("\n");
2073
2074         CHECK_dmHandle();
2075
2076         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERCONNECT].func);
2077         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERCONNECT].func)
2078                  (hdbc, hwnd, conn_str_in, len_conn_str_in, conn_str_out,
2079                   conn_str_out_max, ptr_conn_str_out, driver_completion);
2080 }
2081
2082
2083 /*************************************************************************
2084  *                              SQLSetScrollOptions           [ODBC32.069]
2085  */
2086 SQLRETURN WINAPI SQLSetScrollOptions(
2087     SQLHSTMT           statement_handle,
2088     SQLUSMALLINT       f_concurrency,
2089     SQLINTEGER         crow_keyset,
2090     SQLUSMALLINT       crow_rowset )
2091 {
2092         TRACE("\n");
2093
2094         CHECK_dmHandle();
2095
2096         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSCROLLOPTIONS].func);
2097         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSCROLLOPTIONS].func)
2098                    (statement_handle, f_concurrency, crow_keyset, crow_rowset);
2099 }
2100
2101 static int SQLColAttributes_KnownStringAttribute(SQLUSMALLINT fDescType)
2102 {
2103     static const SQLUSMALLINT attrList[] =
2104     {
2105         SQL_COLUMN_OWNER_NAME,
2106         SQL_COLUMN_QUALIFIER_NAME,
2107         SQL_COLUMN_LABEL,
2108         SQL_COLUMN_NAME,
2109         SQL_COLUMN_TABLE_NAME,
2110         SQL_COLUMN_TYPE_NAME,
2111         SQL_DESC_BASE_COLUMN_NAME,
2112         SQL_DESC_BASE_TABLE_NAME,
2113         SQL_DESC_CATALOG_NAME,
2114         SQL_DESC_LABEL,
2115         SQL_DESC_LITERAL_PREFIX,
2116         SQL_DESC_LITERAL_SUFFIX,
2117         SQL_DESC_LOCAL_TYPE_NAME,
2118         SQL_DESC_NAME,
2119         SQL_DESC_SCHEMA_NAME,
2120         SQL_DESC_TABLE_NAME,
2121         SQL_DESC_TYPE_NAME,
2122     };
2123     unsigned int i;
2124
2125     for (i = 0; i < sizeof(attrList) / sizeof(SQLUSMALLINT); i++) {
2126         if (attrList[i] == fDescType) return 1;
2127     }
2128     return 0;
2129 }
2130
2131 /*************************************************************************
2132  *                              SQLColAttributesW          [ODBC32.106]
2133  */
2134 SQLRETURN WINAPI SQLColAttributesW(
2135     SQLHSTMT           hstmt,
2136     SQLUSMALLINT       icol,
2137     SQLUSMALLINT       fDescType,
2138     SQLPOINTER         rgbDesc,
2139     SQLSMALLINT        cbDescMax,
2140     SQLSMALLINT           *pcbDesc,
2141     SQLINTEGER            *pfDesc)
2142 {
2143         SQLRETURN iResult;
2144
2145         TRACE("hstmt=0x%08lx icol=%d fDescType=%d rgbDesc=%p cbDescMax=%d pcbDesc=%p pfDesc=%p\n",
2146             hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
2147
2148         CHECK_dmHandle();
2149         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTES].funcW);
2150         iResult = (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTES].funcW)
2151                    (hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
2152         if (iResult == SQL_SUCCESS && rgbDesc != NULL && SQLColAttributes_KnownStringAttribute(fDescType)) {
2153         /*
2154             TRACE("Dumping values fetched via SQLColAttributesW:\n");
2155             TRACE("    Attribute name : %s\n", debugstr_w(rgbDesc));
2156             TRACE("    Declared length: %d\n", *pcbDesc);
2157         */
2158             if (*pcbDesc != lstrlenW(rgbDesc) * 2) {
2159                 TRACE("CHEAT: resetting name length for ADO\n");
2160                 *pcbDesc = lstrlenW(rgbDesc) * 2;
2161             }
2162         }
2163         return iResult;
2164 }
2165
2166 /*************************************************************************
2167  *                              SQLConnectW          [ODBC32.107]
2168  */
2169 SQLRETURN WINAPI SQLConnectW(SQLHDBC ConnectionHandle,
2170              WCHAR *ServerName, SQLSMALLINT NameLength1,
2171              WCHAR *UserName, SQLSMALLINT NameLength2,
2172              WCHAR *Authentication, SQLSMALLINT NameLength3)
2173 {
2174         SQLRETURN ret;
2175         TRACE("(Server=%.*s)\n",NameLength1+3, debugstr_w(ServerName));
2176
2177         CHECK_READY_AND_dmHandle();
2178
2179         WideCharToMultiByte(
2180             CP_UTF8, 0,
2181             ServerName, NameLength1,
2182             gProxyHandle.ServerName, sizeof(gProxyHandle.ServerName),
2183             NULL, NULL);
2184         WideCharToMultiByte(
2185             CP_UTF8, 0,
2186             UserName, NameLength2,
2187             gProxyHandle.UserName, sizeof(gProxyHandle.UserName),
2188             NULL, NULL);
2189
2190         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLCONNECT].funcW);
2191         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLCONNECT].funcW)
2192             (ConnectionHandle, ServerName, NameLength1,
2193             UserName, NameLength2, Authentication, NameLength3);
2194
2195         TRACE("returns %d\n",ret);
2196         return ret;
2197 }
2198
2199 /*************************************************************************
2200  *                              SQLDescribeColW          [ODBC32.108]
2201  */
2202 SQLRETURN WINAPI SQLDescribeColW(SQLHSTMT StatementHandle,
2203              SQLUSMALLINT ColumnNumber, WCHAR *ColumnName,
2204              SQLSMALLINT BufferLength, SQLSMALLINT *NameLength,
2205              SQLSMALLINT *DataType, SQLUINTEGER *ColumnSize,
2206              SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable)
2207 {
2208         SQLRETURN iResult;
2209         TRACE("\n");
2210
2211         CHECK_READY_AND_dmHandle();
2212
2213         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBECOL].funcW);
2214         iResult = (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBECOL].funcW)
2215             (StatementHandle, ColumnNumber, ColumnName,
2216             BufferLength, NameLength, DataType, ColumnSize, DecimalDigits, Nullable);
2217         if (iResult >= 0) {
2218             TRACE("Successfully recovered the following column information:\n");
2219             TRACE("\tRequested column index: %d\n", ColumnNumber);
2220             TRACE("\tAvailable length for column name: %d\n", BufferLength);
2221             if (NameLength != NULL)
2222                 TRACE("\tActual length for column name: %d\n", *NameLength);
2223             else TRACE("\tActual length for column name: (null)\n");
2224             TRACE("\tReturned column name: %s\n", debugstr_w(ColumnName));
2225         }
2226         return iResult;
2227 }
2228
2229 /*************************************************************************
2230  *                              SQLErrorW          [ODBC32.110]
2231  */
2232 SQLRETURN WINAPI SQLErrorW(SQLHENV EnvironmentHandle,
2233              SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle,
2234              WCHAR *Sqlstate, SQLINTEGER *NativeError,
2235              WCHAR *MessageText, SQLSMALLINT BufferLength,
2236              SQLSMALLINT *TextLength)
2237 {
2238         TRACE("\n");
2239
2240         CHECK_READY_AND_dmHandle();
2241
2242         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLERROR].funcW);
2243         return (gProxyHandle.functions[SQLAPI_INDEX_SQLERROR].funcW)
2244             (EnvironmentHandle, ConnectionHandle, StatementHandle,
2245             Sqlstate, NativeError, MessageText, BufferLength, TextLength);
2246 }
2247
2248 /*************************************************************************
2249  *                              SQLExecDirectW          [ODBC32.111]
2250  */
2251 SQLRETURN WINAPI SQLExecDirectW(SQLHSTMT StatementHandle,
2252     WCHAR *StatementText, SQLINTEGER TextLength)
2253 {
2254         TRACE("\n");
2255
2256         CHECK_READY_AND_dmHandle();
2257
2258         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECDIRECT].funcW);
2259         return (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECDIRECT].funcW)
2260             (StatementHandle, StatementText, TextLength);
2261 }
2262
2263 /*************************************************************************
2264  *                              SQLGetCursorNameW          [ODBC32.117]
2265  */
2266 SQLRETURN WINAPI SQLGetCursorNameW(SQLHSTMT StatementHandle,
2267              WCHAR *CursorName, SQLSMALLINT BufferLength,
2268              SQLSMALLINT *NameLength)
2269 {
2270         TRACE("\n");
2271
2272         CHECK_dmHandle();
2273
2274         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCURSORNAME].funcW);
2275         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCURSORNAME].funcW)
2276             (StatementHandle, CursorName, BufferLength, NameLength);
2277 }
2278
2279 /*************************************************************************
2280  *                              SQLPrepareW          [ODBC32.119]
2281  */
2282 SQLRETURN WINAPI SQLPrepareW(SQLHSTMT StatementHandle,
2283     WCHAR *StatementText, SQLINTEGER TextLength)
2284 {
2285         TRACE("\n");
2286
2287         CHECK_dmHandle();
2288
2289         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPREPARE].funcW);
2290         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPREPARE].funcW)
2291             (StatementHandle, StatementText, TextLength);
2292 }
2293
2294 /*************************************************************************
2295  *                              SQLSetCursorNameW          [ODBC32.121]
2296  */
2297 SQLRETURN WINAPI SQLSetCursorNameW(SQLHSTMT StatementHandle, WCHAR *CursorName, SQLSMALLINT NameLength)
2298 {
2299         TRACE("\n");
2300
2301         CHECK_dmHandle();
2302
2303         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCURSORNAME].funcW);
2304         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCURSORNAME].funcW)
2305             (StatementHandle, CursorName, NameLength);
2306 }
2307
2308 /*************************************************************************
2309  *                              SQLColAttributeW          [ODBC32.127]
2310  */
2311 SQLRETURN WINAPI SQLColAttributeW (SQLHSTMT StatementHandle,
2312              SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier,
2313              SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength,
2314              SQLSMALLINT *StringLength, SQLPOINTER NumericAttribute)
2315 {
2316         SQLRETURN iResult;
2317
2318         TRACE("StatementHandle=0x%08lx ColumnNumber=%d FieldIdentifier=%d CharacterAttribute=%p BufferLength=%d StringLength=%p NumericAttribute=%p\n",
2319             StatementHandle, ColumnNumber, FieldIdentifier,
2320             CharacterAttribute, BufferLength, StringLength, NumericAttribute);
2321
2322         CHECK_READY_AND_dmHandle();
2323
2324         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTE].funcW);
2325         iResult = (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTE].funcW)
2326             (StatementHandle, ColumnNumber, FieldIdentifier,
2327             CharacterAttribute, BufferLength, StringLength, NumericAttribute);
2328         if (iResult == SQL_SUCCESS && CharacterAttribute != NULL && SQLColAttributes_KnownStringAttribute(FieldIdentifier)) {
2329         /*
2330             TRACE("Dumping values fetched via SQLColAttributeW:\n");
2331             TRACE("    Attribute name : %s\n", debugstr_w(rgbDesc));
2332             TRACE("    Declared length: %d\n", *pcbDesc);
2333         */
2334             if (*StringLength != lstrlenW(CharacterAttribute) * 2) {
2335                 TRACE("CHEAT: resetting name length for ADO\n");
2336                 *StringLength = lstrlenW(CharacterAttribute) * 2;
2337             }
2338         }
2339         return iResult;
2340 }
2341
2342 /*************************************************************************
2343  *                              SQLGetConnectAttrW          [ODBC32.132]
2344  */
2345 SQLRETURN WINAPI SQLGetConnectAttrW(SQLHDBC ConnectionHandle,
2346              SQLINTEGER Attribute, SQLPOINTER Value,
2347              SQLINTEGER BufferLength, SQLINTEGER *StringLength)
2348 {
2349         TRACE("\n");
2350
2351         CHECK_dmHandle();
2352
2353         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTATTR].funcW);
2354         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTATTR].funcW)
2355             (ConnectionHandle, Attribute, Value,
2356             BufferLength, StringLength);
2357 }
2358
2359 /*************************************************************************
2360  *                              SQLGetDescFieldW          [ODBC32.133]
2361  */
2362 SQLRETURN WINAPI SQLGetDescFieldW(SQLHDESC DescriptorHandle,
2363              SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
2364              SQLPOINTER Value, SQLINTEGER BufferLength,
2365              SQLINTEGER *StringLength)
2366 {
2367         TRACE("\n");
2368
2369         CHECK_dmHandle();
2370
2371         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCFIELD].funcW);
2372         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCFIELD].funcW)
2373             (DescriptorHandle, RecNumber, FieldIdentifier,
2374             Value, BufferLength, StringLength);
2375 }
2376
2377 /*************************************************************************
2378  *                              SQLGetDescRecW          [ODBC32.134]
2379  */
2380 SQLRETURN WINAPI SQLGetDescRecW(SQLHDESC DescriptorHandle,
2381              SQLSMALLINT RecNumber, WCHAR *Name,
2382              SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
2383              SQLSMALLINT *Type, SQLSMALLINT *SubType,
2384              SQLINTEGER *Length, SQLSMALLINT *Precision,
2385              SQLSMALLINT *Scale, SQLSMALLINT *Nullable)
2386 {
2387         TRACE("\n");
2388
2389         CHECK_dmHandle();
2390
2391         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCREC].funcW);
2392         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCREC].funcW)
2393             (DescriptorHandle, RecNumber, Name, BufferLength,
2394             StringLength, Type, SubType, Length, Precision, Scale, Nullable);
2395 }
2396
2397 /*************************************************************************
2398  *                              SQLGetDiagFieldW          [ODBC32.135]
2399  */
2400 SQLRETURN WINAPI SQLGetDiagFieldW(SQLSMALLINT HandleType, SQLHANDLE Handle,
2401              SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
2402              SQLPOINTER DiagInfo, SQLSMALLINT BufferLength,
2403              SQLSMALLINT *StringLength)
2404 {
2405         TRACE("\n");
2406
2407         CHECK_dmHandle();
2408
2409         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGFIELD].funcW);
2410         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGFIELD].funcW)
2411             (HandleType, Handle, RecNumber, DiagIdentifier,
2412             DiagInfo, BufferLength, StringLength);
2413 }
2414
2415 /*************************************************************************
2416  *                              SQLGetDiagRecW           [ODBC32.136]
2417  */
2418 SQLRETURN WINAPI SQLGetDiagRecW(SQLSMALLINT HandleType, SQLHANDLE Handle,
2419              SQLSMALLINT RecNumber, WCHAR *Sqlstate,
2420              SQLINTEGER *NativeError, WCHAR *MessageText,
2421              SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
2422 {
2423         TRACE("\n");
2424
2425         CHECK_dmHandle();
2426
2427         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGREC].funcW);
2428         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGREC].funcW)
2429             (HandleType, Handle, RecNumber, Sqlstate, NativeError,
2430             MessageText, BufferLength, TextLength);
2431 }
2432
2433 /*************************************************************************
2434  *                              SQLGetStmtAttrW          [ODBC32.138]
2435  */
2436 SQLRETURN WINAPI SQLGetStmtAttrW(SQLHSTMT StatementHandle,
2437              SQLINTEGER Attribute, SQLPOINTER Value,
2438              SQLINTEGER BufferLength, SQLINTEGER *StringLength)
2439 {
2440         SQLRETURN iResult;
2441
2442         TRACE("Attribute = (%02ld) Value = %p BufferLength = (%ld) StringLength = %p\n",
2443             Attribute, Value, BufferLength, StringLength);
2444
2445         if (Value == NULL) {
2446             WARN("Unexpected NULL in Value return address\n");
2447             iResult = SQL_ERROR;
2448 /*
2449         } else if (StringLength == NULL) {
2450             WARN("Unexpected NULL in StringLength return address\n");
2451             iResult = SQL_ERROR;
2452 */
2453         } else {
2454             CHECK_dmHandle();
2455
2456             assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTATTR].funcW);
2457             iResult = (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTATTR].funcW)
2458                 (StatementHandle, Attribute, Value, BufferLength, StringLength);
2459             TRACE("returning %d...\n", iResult);
2460         }
2461         return iResult;
2462 }
2463
2464 /*************************************************************************
2465  *                              SQLSetConnectAttrW          [ODBC32.139]
2466  */
2467 SQLRETURN WINAPI SQLSetConnectAttrW(SQLHDBC ConnectionHandle, SQLINTEGER Attribute,
2468         SQLPOINTER Value, SQLINTEGER StringLength)
2469 {
2470         TRACE("\n");
2471
2472         CHECK_dmHandle();
2473
2474         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTATTR].funcW);
2475         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTATTR].funcW)
2476             (ConnectionHandle, Attribute, Value, StringLength);
2477 }
2478
2479 /*************************************************************************
2480  *                              SQLColumnsW          [ODBC32.140]
2481  */
2482 SQLRETURN WINAPI SQLColumnsW(SQLHSTMT StatementHandle,
2483              WCHAR *CatalogName, SQLSMALLINT NameLength1,
2484              WCHAR *SchemaName, SQLSMALLINT NameLength2,
2485              WCHAR *TableName, SQLSMALLINT NameLength3,
2486              WCHAR *ColumnName, SQLSMALLINT NameLength4)
2487 {
2488         TRACE("\n");
2489
2490         CHECK_READY_AND_dmHandle();
2491
2492         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNS].funcW);
2493         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNS].funcW)
2494             (StatementHandle, CatalogName, NameLength1,
2495             SchemaName, NameLength2, TableName, NameLength3, ColumnName, NameLength4);
2496 }
2497
2498 /*************************************************************************
2499  *                              SQLDriverConnectW          [ODBC32.141]
2500  */
2501 SQLRETURN WINAPI SQLDriverConnectW(
2502     SQLHDBC            hdbc,
2503     SQLHWND            hwnd,
2504     WCHAR              *conn_str_in,
2505     SQLSMALLINT        len_conn_str_in,
2506     WCHAR              *conn_str_out,
2507     SQLSMALLINT        conn_str_out_max,
2508     SQLSMALLINT        *ptr_conn_str_out,
2509     SQLUSMALLINT       driver_completion )
2510 {
2511         TRACE("ConnStrIn (%d bytes) --> %s\n", len_conn_str_in, debugstr_w(conn_str_in));
2512
2513         CHECK_dmHandle();
2514
2515         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERCONNECT].funcW);
2516         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERCONNECT].funcW)
2517                  (hdbc, hwnd, conn_str_in, len_conn_str_in, conn_str_out,
2518                   conn_str_out_max, ptr_conn_str_out, driver_completion);
2519 }
2520
2521 /*************************************************************************
2522  *                              SQLGetConnectOptionW      [ODBC32.142]
2523  */
2524 SQLRETURN WINAPI SQLGetConnectOptionW(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLPOINTER Value)
2525 {
2526         TRACE("\n");
2527
2528         CHECK_dmHandle();
2529
2530         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTOPTION].funcW);
2531         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTOPTION].funcW)
2532             (ConnectionHandle, Option, Value);
2533 }
2534
2535 /*************************************************************************
2536  *                              SQLGetInfoW          [ODBC32.145]
2537  */
2538 SQLRETURN WINAPI SQLGetInfoW(SQLHDBC ConnectionHandle,
2539              SQLUSMALLINT InfoType, SQLPOINTER InfoValue,
2540              SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
2541 {
2542         SQLRETURN iResult;
2543
2544         TRACE("InfoType = (%02u), InfoValue = %p, BufferLength = %d bytes\n", InfoType, InfoValue, BufferLength);
2545         if (InfoValue == NULL) {
2546                 WARN("Unexpected NULL in InfoValue address\n");
2547                 iResult = SQL_ERROR;
2548         } else {
2549                 CHECK_dmHandle();
2550
2551                 assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETINFO].funcW);
2552                 iResult = (gProxyHandle.functions[SQLAPI_INDEX_SQLGETINFO].funcW)
2553                     (ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength);
2554                 TRACE("returning %d...\n", iResult);
2555         }
2556         return iResult;
2557 }
2558
2559 /*************************************************************************
2560  *                              SQLGetTypeInfoW          [ODBC32.147]
2561  */
2562 SQLRETURN WINAPI SQLGetTypeInfoW(SQLHSTMT StatementHandle, SQLSMALLINT DataType)
2563 {
2564         TRACE("\n");
2565
2566         CHECK_dmHandle();
2567
2568         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETTYPEINFO].funcW);
2569         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETTYPEINFO].funcW)
2570             (StatementHandle, DataType);
2571 }
2572
2573 /*************************************************************************
2574  *                              SQLSetConnectOptionW          [ODBC32.150]
2575  */
2576 SQLRETURN WINAPI SQLSetConnectOptionW(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLUINTEGER Value)
2577 {
2578         TRACE("\n");
2579
2580         CHECK_dmHandle();
2581
2582         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTOPTION].funcW);
2583         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTOPTION].funcW)
2584             (ConnectionHandle, Option, Value);
2585 }
2586
2587 /*************************************************************************
2588  *                              SQLSpecialColumnsW          [ODBC32.152]
2589  */
2590 SQLRETURN WINAPI SQLSpecialColumnsW(SQLHSTMT StatementHandle,
2591              SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName,
2592              SQLSMALLINT NameLength1, SQLCHAR *SchemaName,
2593              SQLSMALLINT NameLength2, SQLCHAR *TableName,
2594              SQLSMALLINT NameLength3, SQLUSMALLINT Scope,
2595              SQLUSMALLINT Nullable)
2596 {
2597
2598         CHECK_dmHandle();
2599
2600         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSPECIALCOLUMNS].funcW);
2601         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSPECIALCOLUMNS].funcW)
2602             (StatementHandle, IdentifierType, CatalogName, NameLength1, SchemaName,
2603              NameLength2, TableName, NameLength3, Scope, Nullable);
2604 }
2605
2606 /*************************************************************************
2607  *                              SQLStatisticsW          [ODBC32.153]
2608  */
2609 SQLRETURN WINAPI SQLStatisticsW(SQLHSTMT StatementHandle,
2610              SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
2611              SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
2612              SQLCHAR *TableName, SQLSMALLINT NameLength3,
2613              SQLUSMALLINT Unique, SQLUSMALLINT Reserved)
2614 {
2615         TRACE("\n");
2616
2617         CHECK_dmHandle();
2618
2619         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSTATISTICS].funcW);
2620         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSTATISTICS].funcW)
2621             (StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2,
2622              TableName, NameLength3, Unique, Reserved);
2623 }
2624
2625 /*************************************************************************
2626  *                              SQLTablesW          [ODBC32.154]
2627  */
2628 SQLRETURN WINAPI SQLTablesW(SQLHSTMT StatementHandle,
2629              SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
2630              SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
2631              SQLCHAR *TableName, SQLSMALLINT NameLength3,
2632              SQLCHAR *TableType, SQLSMALLINT NameLength4)
2633 {
2634         TRACE("\n");
2635
2636         CHECK_dmHandle();
2637
2638         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLES].funcW);
2639         return (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLES].funcW)
2640                 (StatementHandle, CatalogName, NameLength1,
2641                 SchemaName, NameLength2, TableName, NameLength3, TableType, NameLength4);
2642 }
2643
2644 /*************************************************************************
2645  *                              SQLBrowseConnectW          [ODBC32.155]
2646  */
2647 SQLRETURN WINAPI SQLBrowseConnectW(
2648     SQLHDBC            hdbc,
2649     SQLCHAR               *szConnStrIn,
2650     SQLSMALLINT        cbConnStrIn,
2651     SQLCHAR               *szConnStrOut,
2652     SQLSMALLINT        cbConnStrOutMax,
2653     SQLSMALLINT       *pcbConnStrOut)
2654 {
2655         TRACE("\n");
2656
2657         CHECK_dmHandle();
2658
2659         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBROWSECONNECT].funcW);
2660         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBROWSECONNECT].funcW)
2661                 (hdbc, szConnStrIn, cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut);
2662 }
2663
2664 /*************************************************************************
2665  *                              SQLColumnPrivilegesW          [ODBC32.156]
2666  */
2667 SQLRETURN WINAPI SQLColumnPrivilegesW(
2668     SQLHSTMT           hstmt,
2669     SQLCHAR               *szCatalogName,
2670     SQLSMALLINT        cbCatalogName,
2671     SQLCHAR               *szSchemaName,
2672     SQLSMALLINT        cbSchemaName,
2673     SQLCHAR               *szTableName,
2674     SQLSMALLINT        cbTableName,
2675     SQLCHAR               *szColumnName,
2676     SQLSMALLINT        cbColumnName)
2677 {
2678         TRACE("\n");
2679
2680         CHECK_dmHandle();
2681
2682         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNPRIVILEGES].funcW);
2683         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNPRIVILEGES].funcW)
2684                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
2685                     szTableName, cbTableName, szColumnName, cbColumnName);
2686 }
2687
2688 /*************************************************************************
2689  *                              SQLDataSourcesW          [ODBC32.157]
2690  */
2691 SQLRETURN WINAPI SQLDataSourcesW(SQLHENV EnvironmentHandle,
2692              SQLUSMALLINT Direction, WCHAR *ServerName,
2693              SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1,
2694              WCHAR *Description, SQLSMALLINT BufferLength2,
2695              SQLSMALLINT *NameLength2)
2696 {
2697         SQLRETURN ret;
2698
2699         TRACE("EnvironmentHandle = %p\n", (LPVOID)EnvironmentHandle);
2700
2701         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
2702         {
2703             ERR("Error: empty dm handle (gProxyHandle.dmHandle == NULL)\n");
2704             return SQL_ERROR;
2705         }
2706
2707         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLDATASOURCES].funcW);
2708         ret = (gProxyHandle.functions[SQLAPI_INDEX_SQLDATASOURCES].funcW)
2709             (EnvironmentHandle, Direction, ServerName,
2710             BufferLength1, NameLength1, Description, BufferLength2, NameLength2);
2711
2712         if (TRACE_ON(odbc))
2713         {
2714            TRACE("returns: %d \t", ret);
2715            if (*NameLength1 > 0)
2716              TRACE("DataSource = %s,", debugstr_w(ServerName));
2717            if (*NameLength2 > 0)
2718              TRACE(" Description = %s", debugstr_w(Description));
2719            TRACE("\n");
2720         }
2721
2722         return ret;
2723 }
2724
2725 /*************************************************************************
2726  *                              SQLForeignKeysW          [ODBC32.160]
2727  */
2728 SQLRETURN WINAPI SQLForeignKeysW(
2729     SQLHSTMT           hstmt,
2730     SQLCHAR               *szPkCatalogName,
2731     SQLSMALLINT        cbPkCatalogName,
2732     SQLCHAR               *szPkSchemaName,
2733     SQLSMALLINT        cbPkSchemaName,
2734     SQLCHAR               *szPkTableName,
2735     SQLSMALLINT        cbPkTableName,
2736     SQLCHAR               *szFkCatalogName,
2737     SQLSMALLINT        cbFkCatalogName,
2738     SQLCHAR               *szFkSchemaName,
2739     SQLSMALLINT        cbFkSchemaName,
2740     SQLCHAR               *szFkTableName,
2741     SQLSMALLINT        cbFkTableName)
2742 {
2743         TRACE("\n");
2744
2745         CHECK_dmHandle();
2746
2747         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFOREIGNKEYS].funcW);
2748         return (gProxyHandle.functions[SQLAPI_INDEX_SQLFOREIGNKEYS].funcW)
2749                    (hstmt, szPkCatalogName, cbPkCatalogName, szPkSchemaName, cbPkSchemaName,
2750                     szPkTableName, cbPkTableName, szFkCatalogName, cbFkCatalogName, szFkSchemaName,
2751                         cbFkSchemaName, szFkTableName, cbFkTableName);
2752 }
2753
2754 /*************************************************************************
2755  *                              SQLNativeSqlW          [ODBC32.162]
2756  */
2757 SQLRETURN WINAPI SQLNativeSqlW(
2758     SQLHDBC            hdbc,
2759     SQLCHAR               *szSqlStrIn,
2760     SQLINTEGER         cbSqlStrIn,
2761     SQLCHAR               *szSqlStr,
2762     SQLINTEGER         cbSqlStrMax,
2763     SQLINTEGER            *pcbSqlStr)
2764 {
2765         TRACE("\n");
2766
2767         CHECK_dmHandle();
2768
2769         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLNATIVESQL].funcW);
2770         return (gProxyHandle.functions[SQLAPI_INDEX_SQLNATIVESQL].funcW)
2771                    (hdbc, szSqlStrIn, cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr);
2772 }
2773
2774 /*************************************************************************
2775  *                              SQLPrimaryKeysW          [ODBC32.165]
2776  */
2777 SQLRETURN WINAPI SQLPrimaryKeysW(
2778     SQLHSTMT           hstmt,
2779     SQLCHAR               *szCatalogName,
2780     SQLSMALLINT        cbCatalogName,
2781     SQLCHAR               *szSchemaName,
2782     SQLSMALLINT        cbSchemaName,
2783     SQLCHAR               *szTableName,
2784     SQLSMALLINT        cbTableName)
2785 {
2786         TRACE("\n");
2787
2788         CHECK_dmHandle();
2789
2790         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPRIMARYKEYS].funcW);
2791         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPRIMARYKEYS].funcW)
2792                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
2793                     szTableName, cbTableName);
2794 }
2795
2796 /*************************************************************************
2797  *                              SQLProcedureColumnsW          [ODBC32.166]
2798  */
2799 SQLRETURN WINAPI SQLProcedureColumnsW(
2800     SQLHSTMT           hstmt,
2801     SQLCHAR               *szCatalogName,
2802     SQLSMALLINT        cbCatalogName,
2803     SQLCHAR               *szSchemaName,
2804     SQLSMALLINT        cbSchemaName,
2805     SQLCHAR               *szProcName,
2806     SQLSMALLINT        cbProcName,
2807     SQLCHAR               *szColumnName,
2808     SQLSMALLINT        cbColumnName)
2809 {
2810         TRACE("\n");
2811
2812         CHECK_dmHandle();
2813
2814         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURECOLUMNS].funcW);
2815         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURECOLUMNS].funcW)
2816                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
2817                     szProcName, cbProcName, szColumnName, cbColumnName);
2818 }
2819
2820 /*************************************************************************
2821  *                              SQLProceduresW          [ODBC32.167]
2822  */
2823 SQLRETURN WINAPI SQLProceduresW(
2824     SQLHSTMT           hstmt,
2825     SQLCHAR               *szCatalogName,
2826     SQLSMALLINT        cbCatalogName,
2827     SQLCHAR               *szSchemaName,
2828     SQLSMALLINT        cbSchemaName,
2829     SQLCHAR               *szProcName,
2830     SQLSMALLINT        cbProcName)
2831 {
2832         TRACE("\n");
2833
2834         CHECK_dmHandle();
2835
2836         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURES].funcW);
2837         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURES].funcW)
2838                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
2839                     szProcName, cbProcName);
2840 }
2841
2842 /*************************************************************************
2843  *                              SQLTablePrivilegesW          [ODBC32.170]
2844  */
2845 SQLRETURN WINAPI SQLTablePrivilegesW(
2846     SQLHSTMT           hstmt,
2847     SQLCHAR               *szCatalogName,
2848     SQLSMALLINT        cbCatalogName,
2849     SQLCHAR               *szSchemaName,
2850     SQLSMALLINT        cbSchemaName,
2851     SQLCHAR               *szTableName,
2852     SQLSMALLINT        cbTableName)
2853 {
2854         TRACE("\n");
2855
2856         CHECK_dmHandle();
2857
2858         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLEPRIVILEGES].funcW);
2859         return (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLEPRIVILEGES].funcW)
2860                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
2861                     szTableName, cbTableName);
2862 }
2863
2864 /*************************************************************************
2865  *                              SQLDriversW          [ODBC32.171]
2866  */
2867 SQLRETURN WINAPI SQLDriversW(
2868     SQLHENV            henv,
2869     SQLUSMALLINT       fDirection,
2870     SQLCHAR               *szDriverDesc,
2871     SQLSMALLINT        cbDriverDescMax,
2872     SQLSMALLINT           *pcbDriverDesc,
2873     SQLCHAR               *szDriverAttributes,
2874     SQLSMALLINT        cbDriverAttrMax,
2875     SQLSMALLINT           *pcbDriverAttr)
2876 {
2877         TRACE("\n");
2878
2879         CHECK_dmHandle();
2880
2881         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERS].funcW);
2882         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERS].funcW)
2883                 (henv, fDirection, szDriverDesc, cbDriverDescMax, pcbDriverDesc,
2884                  szDriverAttributes, cbDriverAttrMax, pcbDriverAttr);
2885 }
2886
2887 /*************************************************************************
2888  *                              SQLSetDescFieldW          [ODBC32.173]
2889  */
2890 SQLRETURN WINAPI SQLSetDescFieldW(SQLHDESC DescriptorHandle,
2891              SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
2892              SQLPOINTER Value, SQLINTEGER BufferLength)
2893 {
2894         TRACE("\n");
2895
2896         CHECK_dmHandle();
2897
2898         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCFIELD].funcW);
2899         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCFIELD].funcW)
2900             (DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength);
2901 }
2902
2903 /*************************************************************************
2904  *                              SQLSetStmtAttrW          [ODBC32.176]
2905  */
2906 SQLRETURN WINAPI SQLSetStmtAttrW(SQLHSTMT StatementHandle,
2907                  SQLINTEGER Attribute, SQLPOINTER Value,
2908                  SQLINTEGER StringLength)
2909 {
2910         SQLRETURN iResult;
2911         TRACE("Attribute = (%02ld) Value = %p StringLength = (%ld)\n",
2912             Attribute, Value, StringLength);
2913
2914         CHECK_dmHandle();
2915
2916         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTATTR].funcW);
2917         iResult = (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTATTR].funcW)
2918             (StatementHandle, Attribute, Value, StringLength);
2919         if (iResult == SQL_ERROR && (Attribute == SQL_ROWSET_SIZE || Attribute == SQL_ATTR_ROW_ARRAY_SIZE)) {
2920             TRACE("CHEAT: returning SQL_SUCCESS to ADO...\n");
2921             iResult = SQL_SUCCESS;
2922         } else {
2923             TRACE("returning %d...\n", iResult);
2924         }
2925         return iResult;
2926 }
2927
2928
2929 /* End of file */