During startup of the connection to an external ODBC provider
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
43 #include "sql.h"
44 #include "sqltypes.h"
45 #include "sqlext.h"
46
47 #include "proxyodbc.h"
48
49 static BOOL ODBC_LoadDriverManager(void);
50 static BOOL ODBC_LoadDMFunctions(void);
51
52 WINE_DEFAULT_DEBUG_CHANNEL(odbc);
53
54 static const DM_FUNC template_func[] =
55 {
56     /* 00 */ { SQL_API_SQLALLOCCONNECT,      "SQLAllocConnect", SQLAllocConnect, NULL },
57     /* 01 */ { SQL_API_SQLALLOCENV,          "SQLAllocEnv", SQLAllocEnv, NULL  },
58     /* 02 */ { SQL_API_SQLALLOCHANDLE,       "SQLAllocHandle", SQLAllocHandle, NULL },
59     /* 03 */ { SQL_API_SQLALLOCSTMT,         "SQLAllocStmt", SQLAllocStmt, NULL },
60     /* 04 */ { SQL_API_SQLALLOCHANDLESTD,    "SQLAllocHandleStd", SQLAllocHandleStd, NULL },
61     /* 05 */ { SQL_API_SQLBINDCOL,           "SQLBindCol", SQLBindCol, NULL },
62     /* 06 */ { SQL_API_SQLBINDPARAM,         "SQLBindParam", SQLBindParam, NULL },
63     /* 07 */ { SQL_API_SQLBINDPARAMETER,     "SQLBindParameter", SQLBindParameter, NULL },
64     /* 08 */ { SQL_API_SQLBROWSECONNECT,     "SQLBrowseConnect", SQLBrowseConnect, NULL },
65     /* 09 */ { SQL_API_SQLBULKOPERATIONS,    "SQLBulkOperations", SQLBulkOperations, NULL },
66     /* 10 */ { SQL_API_SQLCANCEL,            "SQLCancel", SQLCancel, NULL },
67     /* 11 */ { SQL_API_SQLCLOSECURSOR,       "SQLCloseCursor", SQLCloseCursor, NULL },
68     /* 12 */ { SQL_API_SQLCOLATTRIBUTE,      "SQLColAttribute", SQLColAttribute, NULL },
69     /* 13 */ { SQL_API_SQLCOLATTRIBUTES,     "SQLColAttributes", SQLColAttributes, NULL },
70     /* 14 */ { SQL_API_SQLCOLUMNPRIVILEGES,  "SQLColumnPrivileges", SQLColumnPrivileges, NULL },
71     /* 15 */ { SQL_API_SQLCOLUMNS,           "SQLColumns", SQLColumns, NULL },
72     /* 16 */ { SQL_API_SQLCONNECT,           "SQLConnect", SQLConnect, NULL },
73     /* 17 */ { SQL_API_SQLCOPYDESC,          "SQLCopyDesc", SQLCopyDesc, NULL },
74     /* 18 */ { SQL_API_SQLDATASOURCES,       "SQLDataSources", SQLDataSources, NULL },
75     /* 19 */ { SQL_API_SQLDESCRIBECOL,       "SQLDescribeCol", SQLDescribeCol, NULL },
76     /* 20 */ { SQL_API_SQLDESCRIBEPARAM,     "SQLDescribeParam", SQLDescribeParam, NULL },
77     /* 21 */ { SQL_API_SQLDISCONNECT,        "SQLDisconnect", SQLDisconnect, NULL },
78     /* 22 */ { SQL_API_SQLDRIVERCONNECT,     "SQLDriverConnect", SQLDriverConnect, NULL },
79     /* 23 */ { SQL_API_SQLDRIVERS,           "SQLDrivers", SQLDrivers, NULL },
80     /* 24 */ { SQL_API_SQLENDTRAN,           "SQLEndTran", SQLEndTran, NULL },
81     /* 25 */ { SQL_API_SQLERROR,             "SQLError", SQLError, NULL },
82     /* 26 */ { SQL_API_SQLEXECDIRECT,        "SQLExecDirect", SQLExecDirect, NULL },
83     /* 27 */ { SQL_API_SQLEXECUTE,           "SQLExecute", SQLExecute, NULL },
84     /* 28 */ { SQL_API_SQLEXTENDEDFETCH,     "SQLExtendedFetch", SQLExtendedFetch, NULL },
85     /* 29 */ { SQL_API_SQLFETCH,             "SQLFetch", SQLFetch, NULL },
86     /* 30 */ { SQL_API_SQLFETCHSCROLL,       "SQLFetchScroll", SQLFetchScroll, NULL },
87     /* 31 */ { SQL_API_SQLFOREIGNKEYS,       "SQLForeignKeys", SQLForeignKeys, NULL },
88     /* 32 */ { SQL_API_SQLFREEENV,           "SQLFreeEnv", SQLFreeEnv, NULL },
89     /* 33 */ { SQL_API_SQLFREEHANDLE,        "SQLFreeHandle", SQLFreeHandle, NULL },
90     /* 34 */ { SQL_API_SQLFREESTMT,          "SQLFreeStmt", SQLFreeStmt, NULL },
91     /* 35 */ { SQL_API_SQLFREECONNECT,       "SQLFreeConnect", SQLFreeConnect, NULL },
92     /* 36 */ { SQL_API_SQLGETCONNECTATTR,    "SQLGetConnectAttr", SQLGetConnectAttr, NULL },
93     /* 37 */ { SQL_API_SQLGETCONNECTOPTION,  "SQLGetConnectOption", SQLGetConnectOption, NULL },
94     /* 38 */ { SQL_API_SQLGETCURSORNAME,     "SQLGetCursorName", SQLGetCursorName, NULL },
95     /* 39 */ { SQL_API_SQLGETDATA,           "SQLGetData", SQLGetData, NULL },
96     /* 40 */ { SQL_API_SQLGETDESCFIELD,      "SQLGetDescField", SQLGetDescField, NULL },
97     /* 41 */ { SQL_API_SQLGETDESCREC,        "SQLGetDescRec", SQLGetDescRec, NULL },
98     /* 42 */ { SQL_API_SQLGETDIAGFIELD,      "SQLGetDiagField", SQLGetDiagField, NULL },
99     /* 43 */ { SQL_API_SQLGETENVATTR,        "SQLGetEnvAttr", SQLGetEnvAttr, NULL },
100     /* 44 */ { SQL_API_SQLGETFUNCTIONS,      "SQLGetFunctions", SQLGetFunctions, NULL },
101     /* 45 */ { SQL_API_SQLGETINFO,           "SQLGetInfo", SQLGetInfo, NULL },
102     /* 46 */ { SQL_API_SQLGETSTMTATTR,       "SQLGetStmtAttr", SQLGetStmtAttr, NULL },
103     /* 47 */ { SQL_API_SQLGETSTMTOPTION,     "SQLGetStmtOption", SQLGetStmtOption, NULL },
104     /* 48 */ { SQL_API_SQLGETTYPEINFO,       "SQLGetTypeInfo", SQLGetTypeInfo, NULL },
105     /* 49 */ { SQL_API_SQLMORERESULTS,       "SQLMoreResults", SQLMoreResults, NULL },
106     /* 50 */ { SQL_API_SQLNATIVESQL,         "SQLNativeSql", SQLNativeSql, NULL },
107     /* 51 */ { SQL_API_SQLNUMPARAMS,         "SQLNumParams", SQLNumParams, NULL },
108     /* 52 */ { SQL_API_SQLNUMRESULTCOLS,     "SQLNumResultCols", SQLNumResultCols, NULL },
109     /* 53 */ { SQL_API_SQLPARAMDATA,         "SQLParamData", SQLParamData, NULL },
110     /* 54 */ { SQL_API_SQLPARAMOPTIONS,      "SQLParamOptions", SQLParamOptions, NULL },
111     /* 55 */ { SQL_API_SQLPREPARE,           "SQLPrepare", SQLPrepare, NULL },
112     /* 56 */ { SQL_API_SQLPRIMARYKEYS,       "SQLPrimaryKeys", SQLPrimaryKeys, NULL },
113     /* 57 */ { SQL_API_SQLPROCEDURECOLUMNS,  "SQLProcedureColumns", SQLProcedureColumns, NULL },
114     /* 58 */ { SQL_API_SQLPROCEDURES,        "SQLProcedures", SQLProcedures, NULL },
115     /* 59 */ { SQL_API_SQLPUTDATA,           "SQLPutData", SQLPutData, NULL },
116     /* 60 */ { SQL_API_SQLROWCOUNT,          "SQLRowCount", SQLRowCount, NULL },
117     /* 61 */ { SQL_API_SQLSETCONNECTATTR,    "SQLSetConnectAttr", SQLSetConnectAttr, NULL },
118     /* 62 */ { SQL_API_SQLSETCONNECTOPTION,  "SQLSetConnectOption", SQLSetConnectOption, NULL },
119     /* 63 */ { SQL_API_SQLSETCURSORNAME,     "SQLSetCursorName", SQLSetCursorName, NULL },
120     /* 64 */ { SQL_API_SQLSETDESCFIELD,      "SQLSetDescField", SQLSetDescField, NULL },
121     /* 65 */ { SQL_API_SQLSETDESCREC,        "SQLSetDescRec", SQLSetDescRec, NULL },
122     /* 66 */ { SQL_API_SQLSETENVATTR,        "SQLSetEnvAttr", SQLSetEnvAttr, NULL },
123     /* 67 */ { SQL_API_SQLSETPARAM,          "SQLSetParam", SQLSetParam, NULL },
124     /* 68 */ { SQL_API_SQLSETPOS,            "SQLSetPos", SQLSetPos, NULL },
125     /* 69 */ { SQL_API_SQLSETSCROLLOPTIONS,  "SQLSetScrollOptions", SQLSetScrollOptions, NULL },
126     /* 70 */ { SQL_API_SQLSETSTMTATTR,       "SQLSetStmtAttr", SQLSetStmtAttr, NULL },
127     /* 71 */ { SQL_API_SQLSETSTMTOPTION,     "SQLSetStmtOption", SQLSetStmtOption, NULL },
128     /* 72 */ { SQL_API_SQLSPECIALCOLUMNS,    "SQLSpecialColumns", SQLSpecialColumns, NULL },
129     /* 73 */ { SQL_API_SQLSTATISTICS,        "SQLStatistics", SQLStatistics, NULL },
130     /* 74 */ { SQL_API_SQLTABLEPRIVILEGES,   "SQLTablePrivileges", SQLTablePrivileges, NULL },
131     /* 75 */ { SQL_API_SQLTABLES,            "SQLTables", SQLTables, NULL },
132     /* 76 */ { SQL_API_SQLTRANSACT,          "SQLTransact", SQLTransact, NULL },
133     /* 77 */ { SQL_API_SQLGETDIAGREC,        "SQLGetDiagRec", SQLGetDiagRec, NULL },
134 };
135
136 static PROXYHANDLE gProxyHandle;
137
138 /* What is the difference between these two (dmHandle cf READY_AND_dmHandle)? When does one use one and when the other? */
139
140 #define CHECK_dmHandle() \
141 { \
142         if (gProxyHandle.dmHandle == NULL) \
143         { \
144                 TRACE ("Not ready\n"); \
145                 return SQL_ERROR; \
146         } \
147 }
148
149 #define CHECK_READY_AND_dmHandle() \
150 { \
151         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL) \
152         { \
153                 TRACE ("Not ready\n"); \
154                 return SQL_ERROR; \
155         } \
156 }
157
158 SQLRETURN SQLDummyFunc()
159 {
160     TRACE("SQLDummyFunc: \n");
161     return SQL_SUCCESS;
162 }
163
164 /***********************************************************************
165  * ODBC_ReplicateODBCInstToRegistry
166  *
167  * PARAMS
168  *
169  * RETURNS
170  *
171  * Utility to ODBC_ReplicateToRegistry to replicate the drivers of the
172  * ODBCINST.INI settings
173  *
174  * The driver settings are not replicated to the registry.  If we were to 
175  * replicate them we would need to decide whether to replicate all settings
176  * or to do some translation; whether to remove any entries present only in
177  * the windows registry, etc.
178  */
179
180 static void ODBC_ReplicateODBCInstToRegistry (SQLHENV hEnv)
181 {
182     HKEY hODBCInst;
183     LONG reg_ret;
184     int success;
185
186     success = 0;
187     TRACE ("Driver settings are not currently replicated to the registry\n");
188     if ((reg_ret = RegCreateKeyExA (HKEY_LOCAL_MACHINE,
189             "Software\\ODBC\\ODBCINST.INI", 0, NULL,
190             REG_OPTION_NON_VOLATILE,
191             KEY_ALL_ACCESS /* a couple more than we need */, NULL,
192             &hODBCInst, NULL)) == ERROR_SUCCESS)
193     {
194         HKEY hDrivers;
195         if ((reg_ret = RegCreateKeyExA (hODBCInst, "ODBC Drivers", 0,
196                 NULL, REG_OPTION_NON_VOLATILE,
197                 KEY_ALL_ACCESS /* overkill */, NULL, &hDrivers, NULL))
198                 == ERROR_SUCCESS)
199         {
200             SQLRETURN sql_ret;
201             SQLUSMALLINT dirn;
202             SQLCHAR desc [256];
203             SQLSMALLINT sizedesc;
204
205             success = 1;
206             dirn = SQL_FETCH_FIRST;
207             while ((sql_ret = SQLDrivers (hEnv, dirn, desc, sizeof(desc),
208                     &sizedesc, NULL, 0, NULL)) == SQL_SUCCESS ||
209                     sql_ret == SQL_SUCCESS_WITH_INFO)
210             {
211                 /* FIXME Do some proper handling of the SUCCESS_WITH_INFO */
212                 dirn = SQL_FETCH_NEXT;
213                 if (sizedesc == strlen(desc))
214                 {
215                     HKEY hThis;
216                     if ((reg_ret = RegQueryValueExA (hDrivers, desc, NULL,
217                             NULL, NULL, NULL)) == ERROR_FILE_NOT_FOUND)
218                     {
219                         if ((reg_ret = RegSetValueExA (hDrivers, desc, 0,
220                                 REG_SZ, "Installed", 10)) != ERROR_SUCCESS)
221                         {
222                             TRACE ("Error %ld replicating driver %s\n",
223                                     reg_ret, desc);
224                             success = 0;
225                         }
226                     }
227                     else if (reg_ret != ERROR_SUCCESS)
228                     {
229                         TRACE ("Error %ld checking for %s in drivers\n",
230                                 reg_ret, desc);
231                         success = 0;
232                     }
233                     if ((reg_ret = RegCreateKeyExA (hODBCInst, desc, 0,
234                             NULL, REG_OPTION_NON_VOLATILE,
235                             KEY_ALL_ACCESS, NULL, &hThis, NULL))
236                             == ERROR_SUCCESS)
237                     {
238                         /* FIXME This is where the settings go.
239                          * I suggest that if the disposition says it 
240                          * exists then we leave it alone.  Alternatively
241                          * include an extra value to flag that it is 
242                          * a replication of the unixODBC/iODBC/...
243                          */
244                         if ((reg_ret = RegCloseKey (hThis)) !=
245                                 ERROR_SUCCESS)
246                             TRACE ("Error %ld closing %s key\n", reg_ret,
247                                     desc);
248                     }
249                     else
250                     {
251                         TRACE ("Error %ld ensuring driver key %s\n",
252                                 reg_ret, desc);
253                         success = 0;
254                     }
255                 }
256                 else
257                 {
258                     WARN ("Unusually long driver name %s not replicated\n",
259                             desc);
260                     success = 0;
261                 }
262             }
263             if (sql_ret != SQL_NO_DATA)
264             {
265                 TRACE ("Error %d enumerating drivers\n", (int)sql_ret);
266                 success = 0;
267             }
268             if ((reg_ret = RegCloseKey (hDrivers)) != ERROR_SUCCESS)
269             {
270                 TRACE ("Error %ld closing hDrivers\n", reg_ret);
271             }
272         }
273         else
274         {
275             TRACE ("Error %ld opening HKLM\\S\\O\\OI\\Drivers\n", reg_ret);
276         }
277         if ((reg_ret = RegCloseKey (hODBCInst)) != ERROR_SUCCESS)
278         {
279             TRACE ("Error %ld closing HKLM\\S\\O\\ODBCINST.INI\n", reg_ret);
280         }
281     }
282     else
283     {
284         TRACE ("Error %ld opening HKLM\\S\\O\\ODBCINST.INI\n", reg_ret);
285     }
286     if (!success)
287     {
288         WARN ("May not have replicated all ODBC drivers to the registry\n");
289     }
290 }
291
292 /***********************************************************************
293  * ODBC_ReplicateODBCToRegistry
294  *
295  * PARAMS
296  *
297  * RETURNS
298  *
299  * Utility to ODBC_ReplicateToRegistry to replicate either the USER or 
300  * SYSTEM dsns
301  *
302  * For now simply place the "Driver description" (as returned by SQLDataSources)
303  * into the registry as the driver.  This is enough to satisfy Crystal's 
304  * requirement that there be a driver entry.  (It doesn't seem to care what
305  * the setting is).
306  * A slightly more accurate setting would be to access the registry to find
307  * the actual driver library for the given description (which appears to map
308  * to one of the HKLM/Software/ODBC/ODBCINST.INI keys).  (If you do this note
309  * that this will add a requirement that this function be called after
310  * ODBC_ReplicateODBCInstToRegistry)
311  */
312 static void ODBC_ReplicateODBCToRegistry (int is_user, SQLHENV hEnv)
313 {
314     HKEY hODBC;
315     LONG reg_ret;
316     SQLRETURN sql_ret;
317     SQLUSMALLINT dirn;
318     SQLCHAR dsn [SQL_MAX_DSN_LENGTH + 1];
319     SQLSMALLINT sizedsn;
320     SQLCHAR desc [256];
321     SQLSMALLINT sizedesc;
322     int success;
323     const char *which = is_user ? "user" : "system";
324
325     success = 0;
326     if ((reg_ret = RegCreateKeyExA (
327             is_user ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
328             "Software\\ODBC\\ODBC.INI", 0, NULL, REG_OPTION_NON_VOLATILE,
329             KEY_ALL_ACCESS /* a couple more than we need */, NULL, &hODBC,
330             NULL)) == ERROR_SUCCESS)
331     {
332         success = 1;
333         dirn = is_user ? SQL_FETCH_FIRST_USER : SQL_FETCH_FIRST_SYSTEM;
334         while ((sql_ret = SQLDataSources (hEnv, dirn,
335                 dsn, sizeof(dsn), &sizedsn,
336                 desc, sizeof(desc), &sizedesc)) == SQL_SUCCESS
337                 || sql_ret == SQL_SUCCESS_WITH_INFO)
338         {
339             /* FIXME Do some proper handling of the SUCCESS_WITH_INFO */
340             dirn = SQL_FETCH_NEXT;
341             if (sizedsn == strlen(dsn) && sizedesc == strlen(desc))
342             {
343                 HKEY hDSN;
344                 if ((reg_ret = RegCreateKeyExA (hODBC, dsn, 0,
345                         NULL, REG_OPTION_NON_VOLATILE,
346                         KEY_ALL_ACCESS, NULL, &hDSN, NULL))
347                         == ERROR_SUCCESS)
348                 {
349                     static const char *DRIVERKEY = "Driver";
350                     if ((reg_ret = RegQueryValueExA (hDSN, DRIVERKEY,
351                             NULL, NULL, NULL, NULL))
352                             == ERROR_FILE_NOT_FOUND)
353                     {
354                         if ((reg_ret = RegSetValueExA (hDSN, DRIVERKEY, 0,
355                                 REG_SZ, desc, sizedesc)) != ERROR_SUCCESS)
356                         {
357                             TRACE ("Error %ld replicating description of "
358                                     "%s(%s)\n", reg_ret, dsn, desc);
359                             success = 0;
360                         }
361                     }
362                     else if (reg_ret != ERROR_SUCCESS)
363                     {
364                         TRACE ("Error %ld checking for description of %s\n",
365                                 reg_ret, dsn);
366                         success = 0;
367                     }
368                     if ((reg_ret = RegCloseKey (hDSN)) != ERROR_SUCCESS)
369                     {
370                         TRACE ("Error %ld closing %s DSN key %s\n",
371                                 reg_ret, which, dsn);
372                     }
373                 }
374                 else
375                 {
376                     TRACE ("Error %ld opening %s DSN key %s\n",
377                             reg_ret, which, dsn);
378                     success = 0;
379                 }
380             }
381             else
382             {
383                 WARN ("Unusually long %s data source name %s (%s) not "
384                         "replicated\n", which, dsn, desc);
385                 success = 0;
386             }
387         }
388         if (sql_ret != SQL_NO_DATA)
389         {
390             TRACE ("Error %d enumerating %s datasources\n",
391                     (int)sql_ret, which);
392             success = 0;
393         }
394         if ((reg_ret = RegCloseKey (hODBC)) != ERROR_SUCCESS)
395         {
396             TRACE ("Error %ld closing %s ODBC.INI registry key\n", reg_ret,
397                     which);
398         }
399     }
400     else
401     {
402         TRACE ("Error %ld creating/opening %s ODBC.INI registry key\n",
403                 reg_ret, which);
404     }
405     if (!success)
406     {
407         WARN ("May not have replicated all %s ODBC DSNs to the registry\n",
408                 which);
409     }
410 }
411
412 /***********************************************************************
413  * ODBC_ReplicateToRegistry
414  *
415  * PARAMS
416  *
417  * RETURNS
418  *
419  * Unfortunately some of the functions that Windows documents as being part
420  * of the ODBC API it implements directly during compilation or something
421  * in terms of registry access functions.
422  * e.g. SQLGetInstalledDrivers queries the list at
423  * HKEY_LOCAL_MACHINE\Software\ODBC\ODBCINST.INI\ODBC Drivers
424  *
425  * This function is called when the driver manager is loaded and is used
426  * to replicate the appropriate details into the Wine registry
427  */
428
429 static void ODBC_ReplicateToRegistry (void)
430 {
431     SQLRETURN sql_ret;
432     SQLHENV hEnv;
433
434     if ((sql_ret = SQLAllocEnv (&hEnv)) == SQL_SUCCESS)
435     {
436         ODBC_ReplicateODBCInstToRegistry (hEnv);
437         ODBC_ReplicateODBCToRegistry (0 /* system dsns */, hEnv);
438         ODBC_ReplicateODBCToRegistry (1 /* user dsns */, hEnv);
439
440         if ((sql_ret = SQLFreeEnv (hEnv)) != SQL_SUCCESS)
441         {
442             TRACE ("Error %d freeing the SQL environment.\n", (int)sql_ret);
443         }
444     }
445     else
446     {
447         TRACE ("Error %d opening an SQL environment.\n", (int)sql_ret);
448         WARN ("The external ODBC settings have not been replicated to the"
449                 " Wine registry\n");
450     }
451 }
452
453 /***********************************************************************
454  * DllMain [Internal] Initializes the internal 'ODBC32.DLL'.
455  *
456  * PARAMS
457  *     hinstDLL    [I] handle to the DLL's instance
458  *     fdwReason   [I]
459  *     lpvReserved [I] reserved, must be NULL
460  *
461  * RETURNS
462  *     Success: TRUE
463  *     Failure: FALSE
464  */
465
466 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
467 {
468     int i;
469     TRACE("Initializing or Finalizing proxy ODBC: %p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
470
471     if (fdwReason == DLL_PROCESS_ATTACH)
472     {
473        TRACE("Loading ODBC...\n");
474        DisableThreadLibraryCalls(hinstDLL);
475        if (ODBC_LoadDriverManager())
476        {
477           ODBC_LoadDMFunctions();
478           ODBC_ReplicateToRegistry();
479        }
480     }
481     else if (fdwReason == DLL_PROCESS_DETACH)
482     {
483       TRACE("Unloading ODBC...\n");
484       if (gProxyHandle.bFunctionReady)
485       {
486          for ( i = 0; i < NUM_SQLFUNC; i ++ )
487          {
488             gProxyHandle.functions[i].func = SQLDummyFunc;
489          }
490       }
491
492       if (gProxyHandle.dmHandle)
493       {
494          wine_dlclose(gProxyHandle.dmHandle,NULL,0);
495          gProxyHandle.dmHandle = NULL;
496       }
497     }
498
499     return TRUE;
500 }
501
502 /***********************************************************************
503  * ODBC_LoadDriverManager [Internal] Load ODBC library.
504  *
505  * PARAMS
506  *
507  * RETURNS
508  *     Success: TRUE
509  *     Failure: FALSE
510  */
511
512 static BOOL ODBC_LoadDriverManager(void)
513 {
514    const char *s = getenv("LIB_ODBC_DRIVER_MANAGER");
515    char error[256];
516
517    TRACE("\n");
518
519    gProxyHandle.bFunctionReady = FALSE;
520    gProxyHandle.nErrorType = ERROR_LIBRARY_NOT_FOUND;
521
522    if (s!= NULL && strlen (s) >= sizeof(gProxyHandle.dmLibName))
523    {
524           ERR("Driver name too long (%s)\n",s);
525           return FALSE;
526    }
527    if (s == NULL || strlen(s) == 0)
528           s = "libodbc.so";
529    strcpy(gProxyHandle.dmLibName, s);
530
531    gProxyHandle.dmHandle = wine_dlopen(gProxyHandle.dmLibName, RTLD_LAZY | RTLD_GLOBAL, error, sizeof(error));
532
533    if (gProxyHandle.dmHandle == NULL)           /* fail to load unixODBC driver manager */
534    {
535            WARN("failed to open library %s: %s\n", gProxyHandle.dmLibName, error);
536            gProxyHandle.dmLibName[0] = '\0';
537            gProxyHandle.nErrorType = ERROR_LIBRARY_NOT_FOUND;
538            return FALSE;
539    }
540    else
541    {
542       gProxyHandle.nErrorType = ERROR_FREE;
543       return TRUE;
544    }
545 }
546
547
548 /***********************************************************************
549  * ODBC_LoadDMFunctions [Internal] Populate function table.
550  *
551  * PARAMS
552  *
553  * RETURNS
554  *     Success: TRUE
555  *     Failure: FALSE
556  */
557
558 static BOOL ODBC_LoadDMFunctions(void)
559 {
560     int i;
561     char error[256];
562
563     if (gProxyHandle.dmHandle == NULL)
564         return FALSE;
565
566     for ( i = 0; i < NUM_SQLFUNC; i ++ )
567     {
568         gProxyHandle.functions[i] = template_func[i];
569         gProxyHandle.functions[i].func = wine_dlsym(gProxyHandle.dmHandle,
570                 gProxyHandle.functions[i].name, error, sizeof(error));
571
572         if (error[0])
573         {
574             ERR("Failed to load function %s\n",gProxyHandle.functions[i].name);
575             gProxyHandle.functions[i].func = SQLDummyFunc;
576         }
577     }
578
579     gProxyHandle.bFunctionReady = TRUE;
580
581     return TRUE;
582 }
583
584
585 /*************************************************************************
586  *                              SQLAllocConnect           [ODBC32.001]
587  */
588 SQLRETURN WINAPI SQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC *ConnectionHandle)
589 {
590         SQLRETURN ret;
591         TRACE("Env=%lx\n",EnvironmentHandle);
592
593         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
594         {
595            *ConnectionHandle = SQL_NULL_HDBC;
596            TRACE("Not ready\n");
597            return SQL_ERROR;
598         }
599
600         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCCONNECT].func);
601         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCCONNECT].func)
602             (EnvironmentHandle, ConnectionHandle);
603         TRACE("Returns ret=%d, Handle %lx\n",ret, *ConnectionHandle);
604         return ret;
605 }
606
607
608 /*************************************************************************
609  *                              SQLAllocEnv           [ODBC32.002]
610  */
611 SQLRETURN WINAPI  SQLAllocEnv(SQLHENV *EnvironmentHandle)
612 {
613         SQLRETURN ret;
614         TRACE("\n");
615
616         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
617         {
618            *EnvironmentHandle = SQL_NULL_HENV;
619            TRACE("Not ready\n");
620            return SQL_ERROR;
621         }
622
623         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCENV].func);
624         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCENV].func) (EnvironmentHandle);
625         TRACE("Returns ret=%d, Env=%lx\n",ret, *EnvironmentHandle);
626         return ret;
627 }
628
629
630 /*************************************************************************
631  *                              SQLAllocHandle           [ODBC32.024]
632  */
633 SQLRETURN WINAPI SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
634 {
635         SQLRETURN ret;
636         TRACE("(Type=%d, Handle=%lx)\n",HandleType,InputHandle);
637
638         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
639         {
640             if (gProxyHandle.nErrorType == ERROR_LIBRARY_NOT_FOUND)
641                 WARN("ProxyODBC: Can not load ODBC driver manager library.\n");
642
643             if (HandleType == SQL_HANDLE_ENV)
644                 *OutputHandle = SQL_NULL_HENV;
645             else if (HandleType == SQL_HANDLE_DBC)
646                 *OutputHandle = SQL_NULL_HDBC;
647             else if (HandleType == SQL_HANDLE_STMT)
648                 *OutputHandle = SQL_NULL_HSTMT;
649             else if (HandleType == SQL_HANDLE_DESC)
650                 *OutputHandle = SQL_NULL_HDESC;
651
652             TRACE ("Not ready\n");
653             return SQL_ERROR;
654         }
655
656         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCHANDLE].func);
657         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCHANDLE].func)
658                    (HandleType, InputHandle, OutputHandle);
659         TRACE("Returns ret=%d, Handle=%lx\n",ret, *OutputHandle);
660         return ret;
661 }
662
663
664 /*************************************************************************
665  *                              SQLAllocStmt           [ODBC32.003]
666  */
667 SQLRETURN WINAPI SQLAllocStmt(SQLHDBC ConnectionHandle, SQLHSTMT *StatementHandle)
668 {
669         SQLRETURN ret;
670
671         TRACE("(Connection=%lx)\n",ConnectionHandle);
672
673         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
674         {
675            *StatementHandle = SQL_NULL_HSTMT;
676            TRACE ("Not ready\n");
677            return SQL_ERROR;
678         }
679
680         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCSTMT].func);
681         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCSTMT].func)
682             (ConnectionHandle, StatementHandle);
683         TRACE ("Returns ret=%d, Handle=%lx\n", ret, *StatementHandle);
684         return ret;
685 }
686
687
688 /*************************************************************************
689  *                              SQLAllocHandleStd           [ODBC32.077]
690  */
691 SQLRETURN WINAPI SQLAllocHandleStd( SQLSMALLINT HandleType,
692                                                          SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
693 {
694         TRACE("ProxyODBC: SQLAllocHandelStd.\n");
695
696         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
697         {
698             if (gProxyHandle.nErrorType == ERROR_LIBRARY_NOT_FOUND)
699                 WARN("ProxyODBC: Can not load ODBC driver manager library.\n");
700
701             if (HandleType == SQL_HANDLE_ENV)
702                 *OutputHandle = SQL_NULL_HENV;
703             else if (HandleType == SQL_HANDLE_DBC)
704                 *OutputHandle = SQL_NULL_HDBC;
705             else if (HandleType == SQL_HANDLE_STMT)
706                 *OutputHandle = SQL_NULL_HSTMT;
707             else if (HandleType == SQL_HANDLE_DESC)
708                 *OutputHandle = SQL_NULL_HDESC;
709
710             return SQL_ERROR;
711         }
712
713         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCHANDLESTD].func);
714         return (gProxyHandle.functions[SQLAPI_INDEX_SQLALLOCHANDLESTD].func)
715                    (HandleType, InputHandle, OutputHandle);
716 }
717
718
719 /*************************************************************************
720  *                              SQLBindCol           [ODBC32.004]
721  */
722 SQLRETURN WINAPI SQLBindCol(SQLHSTMT StatementHandle,
723                      SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType,
724                      SQLPOINTER TargetValue, SQLINTEGER BufferLength,
725                      SQLINTEGER *StrLen_or_Ind)
726 {
727         TRACE("\n");
728
729         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
730         {
731                 TRACE ("Not ready\n");
732                 return SQL_ERROR;
733         }
734
735         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDCOL].func);
736         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDCOL].func)
737             (StatementHandle, ColumnNumber, TargetType,
738             TargetValue, BufferLength, StrLen_or_Ind);
739 }
740
741
742 /*************************************************************************
743  *                              SQLBindParam           [ODBC32.025]
744  */
745 SQLRETURN WINAPI SQLBindParam(SQLHSTMT StatementHandle,
746              SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
747              SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision,
748              SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue,
749              SQLINTEGER *StrLen_or_Ind)
750 {
751         TRACE("\n");
752
753         CHECK_READY_AND_dmHandle();
754
755         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDPARAM].func);
756         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDPARAM].func)
757                    (StatementHandle, ParameterNumber, ValueType,
758                     ParameterScale, ParameterValue, StrLen_or_Ind);
759 }
760
761
762 /*************************************************************************
763  *                              SQLCancel           [ODBC32.005]
764  */
765 SQLRETURN WINAPI SQLCancel(SQLHSTMT StatementHandle)
766 {
767         TRACE("\n");
768
769         CHECK_READY_AND_dmHandle();
770
771         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCANCEL].func);
772         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCANCEL].func) (StatementHandle);
773 }
774
775
776 /*************************************************************************
777  *                              SQLCloseCursor           [ODBC32.026]
778  */
779 SQLRETURN WINAPI  SQLCloseCursor(SQLHSTMT StatementHandle)
780 {
781         SQLRETURN ret;
782         TRACE("(Handle=%lx)\n",StatementHandle);
783
784         CHECK_READY_AND_dmHandle();
785
786         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLCLOSECURSOR].func);
787         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLCLOSECURSOR].func) (StatementHandle);
788         TRACE("returns %d\n",ret);
789         return ret;
790 }
791
792
793 /*************************************************************************
794  *                              SQLColAttribute           [ODBC32.027]
795  */
796 SQLRETURN WINAPI SQLColAttribute (SQLHSTMT StatementHandle,
797              SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier,
798              SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength,
799              SQLSMALLINT *StringLength, SQLPOINTER NumericAttribute)
800 {
801         TRACE("\n");
802
803         CHECK_READY_AND_dmHandle();
804
805         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTE].func);
806         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTE].func)
807             (StatementHandle, ColumnNumber, FieldIdentifier,
808             CharacterAttribute, BufferLength, StringLength, NumericAttribute);
809 }
810
811
812 /*************************************************************************
813  *                              SQLColumns           [ODBC32.040]
814  */
815 SQLRETURN WINAPI SQLColumns(SQLHSTMT StatementHandle,
816              SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
817              SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
818              SQLCHAR *TableName, SQLSMALLINT NameLength3,
819              SQLCHAR *ColumnName, SQLSMALLINT NameLength4)
820 {
821         TRACE("\n");
822
823         CHECK_READY_AND_dmHandle();
824
825         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNS].func);
826         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNS].func)
827             (StatementHandle, CatalogName, NameLength1,
828             SchemaName, NameLength2, TableName, NameLength3, ColumnName, NameLength4);
829 }
830
831
832 /*************************************************************************
833  *                              SQLConnect           [ODBC32.007]
834  */
835 SQLRETURN WINAPI SQLConnect(SQLHDBC ConnectionHandle,
836              SQLCHAR *ServerName, SQLSMALLINT NameLength1,
837              SQLCHAR *UserName, SQLSMALLINT NameLength2,
838              SQLCHAR *Authentication, SQLSMALLINT NameLength3)
839 {
840         SQLRETURN ret;
841         TRACE("(Server=%.*s)\n",NameLength1, ServerName);
842
843         CHECK_READY_AND_dmHandle();
844
845         strcpy(gProxyHandle.ServerName, ServerName);
846         strcpy(gProxyHandle.UserName, UserName);
847
848         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLCONNECT].func);
849         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLCONNECT].func)
850             (ConnectionHandle, ServerName, NameLength1,
851             UserName, NameLength2, Authentication, NameLength3);
852
853         TRACE("returns %d\n",ret);
854         return ret;
855 }
856
857
858 /*************************************************************************
859  *                              SQLCopyDesc           [ODBC32.028]
860  */
861 SQLRETURN WINAPI SQLCopyDesc(SQLHDESC SourceDescHandle, SQLHDESC TargetDescHandle)
862 {
863         TRACE("\n");
864
865         CHECK_READY_AND_dmHandle();
866
867         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOPYDESC].func);
868         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOPYDESC].func)
869             (SourceDescHandle, TargetDescHandle);
870 }
871
872
873 /*************************************************************************
874  *                              SQLDataSources           [ODBC32.057]
875  */
876 SQLRETURN WINAPI SQLDataSources(SQLHENV EnvironmentHandle,
877              SQLUSMALLINT Direction, SQLCHAR *ServerName,
878              SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1,
879              SQLCHAR *Description, SQLSMALLINT BufferLength2,
880              SQLSMALLINT *NameLength2)
881 {
882         SQLRETURN ret;
883
884         TRACE("EnvironmentHandle = %p\n", (LPVOID)EnvironmentHandle);
885
886         if (!gProxyHandle.bFunctionReady || gProxyHandle.dmHandle == NULL)
887         {
888             ERR("Error: empty dm handle (gProxyHandle.dmHandle == NULL)\n");
889             return SQL_ERROR;
890         }
891
892         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLDATASOURCES].func);
893         ret = (gProxyHandle.functions[SQLAPI_INDEX_SQLDATASOURCES].func)
894             (EnvironmentHandle, Direction, ServerName,
895             BufferLength1, NameLength1, Description, BufferLength2, NameLength2);
896
897         if (TRACE_ON(odbc))
898         {
899            TRACE("returns: %d \t", ret);
900            if (*NameLength1 > 0)
901              TRACE("DataSource = %s,", ServerName);
902            if (*NameLength2 > 0)
903              TRACE(" Description = %s", Description);
904            TRACE("\n");
905         }
906
907         return ret;
908 }
909
910
911 /*************************************************************************
912  *                              SQLDescribeCol           [ODBC32.008]
913  */
914 SQLRETURN WINAPI SQLDescribeCol(SQLHSTMT StatementHandle,
915              SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName,
916              SQLSMALLINT BufferLength, SQLSMALLINT *NameLength,
917              SQLSMALLINT *DataType, SQLUINTEGER *ColumnSize,
918              SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable)
919 {
920         TRACE("\n");
921
922         CHECK_READY_AND_dmHandle();
923
924         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBECOL].func);
925         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBECOL].func)
926             (StatementHandle, ColumnNumber, ColumnName,
927             BufferLength, NameLength, DataType, ColumnSize, DecimalDigits, Nullable);
928 }
929
930
931 /*************************************************************************
932  *                              SQLDisconnect           [ODBC32.009]
933  */
934 SQLRETURN WINAPI SQLDisconnect(SQLHDBC ConnectionHandle)
935 {
936         SQLRETURN ret;
937         TRACE("(Handle=%lx)\n", ConnectionHandle);
938
939         CHECK_READY_AND_dmHandle();
940
941         gProxyHandle.ServerName[0] = '\0';
942         gProxyHandle.UserName[0]   = '\0';
943
944         assert(gProxyHandle.functions[SQLAPI_INDEX_SQLDISCONNECT].func);
945         ret = (gProxyHandle.functions[SQLAPI_INDEX_SQLDISCONNECT].func) (ConnectionHandle);
946         TRACE("returns %d\n",ret);
947         return ret;
948 }
949
950
951 /*************************************************************************
952  *                              SQLEndTran           [ODBC32.029]
953  */
954 SQLRETURN WINAPI SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType)
955 {
956         TRACE("\n");
957
958         CHECK_READY_AND_dmHandle();
959
960         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLENDTRAN].func);
961         return (gProxyHandle.functions[SQLAPI_INDEX_SQLENDTRAN].func) (HandleType, Handle, CompletionType);
962 }
963
964
965 /*************************************************************************
966  *                              SQLError           [ODBC32.010]
967  */
968 SQLRETURN WINAPI SQLError(SQLHENV EnvironmentHandle,
969              SQLHDBC ConnectionHandle, SQLHSTMT StatementHandle,
970              SQLCHAR *Sqlstate, SQLINTEGER *NativeError,
971              SQLCHAR *MessageText, SQLSMALLINT BufferLength,
972              SQLSMALLINT *TextLength)
973 {
974         TRACE("\n");
975
976         CHECK_READY_AND_dmHandle();
977
978         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLERROR].func);
979         return (gProxyHandle.functions[SQLAPI_INDEX_SQLERROR].func)
980             (EnvironmentHandle, ConnectionHandle, StatementHandle,
981             Sqlstate, NativeError, MessageText, BufferLength, TextLength);
982 }
983
984
985 /*************************************************************************
986  *                              SQLExecDirect           [ODBC32.011]
987  */
988 SQLRETURN WINAPI SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength)
989 {
990         TRACE("\n");
991
992         CHECK_READY_AND_dmHandle();
993
994         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECDIRECT].func);
995         return (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECDIRECT].func)
996             (StatementHandle, StatementText, TextLength);
997 }
998
999
1000 /*************************************************************************
1001  *                              SQLExecute           [ODBC32.012]
1002  */
1003 SQLRETURN WINAPI SQLExecute(SQLHSTMT StatementHandle)
1004 {
1005         TRACE("\n");
1006
1007         CHECK_READY_AND_dmHandle();
1008
1009         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECUTE].func);
1010         return (gProxyHandle.functions[SQLAPI_INDEX_SQLEXECUTE].func) (StatementHandle);
1011 }
1012
1013
1014 /*************************************************************************
1015  *                              SQLFetch           [ODBC32.013]
1016  */
1017 SQLRETURN WINAPI SQLFetch(SQLHSTMT StatementHandle)
1018 {
1019         TRACE("\n");
1020
1021         CHECK_READY_AND_dmHandle();
1022
1023         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFETCH].func);
1024         return (gProxyHandle.functions[SQLAPI_INDEX_SQLFETCH].func) (StatementHandle);
1025 }
1026
1027
1028 /*************************************************************************
1029  *                              SQLFetchScroll          [ODBC32.030]
1030  */
1031 SQLRETURN WINAPI SQLFetchScroll(SQLHSTMT StatementHandle, SQLSMALLINT FetchOrientation, SQLINTEGER FetchOffset)
1032 {
1033         TRACE("\n");
1034
1035         CHECK_dmHandle();
1036
1037         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFETCHSCROLL].func);
1038         return (gProxyHandle.functions[SQLAPI_INDEX_SQLFETCHSCROLL].func)
1039             (StatementHandle, FetchOrientation, FetchOffset);
1040 }
1041
1042
1043 /*************************************************************************
1044  *                              SQLFreeConnect           [ODBC32.014]
1045  */
1046 SQLRETURN WINAPI SQLFreeConnect(SQLHDBC ConnectionHandle)
1047 {
1048         SQLRETURN ret;
1049         TRACE("(Handle=%lx)\n",ConnectionHandle);
1050
1051         CHECK_dmHandle();
1052
1053         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFREECONNECT].func);
1054         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLFREECONNECT].func) (ConnectionHandle);
1055         TRACE("Returns %d\n",ret);
1056         return ret;
1057 }
1058
1059
1060 /*************************************************************************
1061  *                              SQLFreeEnv           [ODBC32.015]
1062  */
1063 SQLRETURN WINAPI SQLFreeEnv(SQLHENV EnvironmentHandle)
1064 {
1065         SQLRETURN ret;
1066         TRACE("(Env=%lx)\n",EnvironmentHandle);
1067
1068         CHECK_dmHandle();
1069
1070         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFREEENV].func);
1071         ret = (gProxyHandle.functions[SQLAPI_INDEX_SQLFREEENV].func) (EnvironmentHandle);
1072         TRACE("Returns %d\n",ret);
1073         return ret;
1074 }
1075
1076
1077 /*************************************************************************
1078  *                              SQLFreeHandle           [ODBC32.031]
1079  */
1080 SQLRETURN WINAPI SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
1081 {
1082         SQLRETURN ret;
1083         TRACE("(Type=%d, Handle=%lx)\n",HandleType,Handle);
1084
1085         CHECK_dmHandle();
1086
1087         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFREEHANDLE].func);
1088         ret = (gProxyHandle.functions[SQLAPI_INDEX_SQLFREEHANDLE].func)
1089             (HandleType, Handle);
1090         TRACE ("Returns %d\n",ret);
1091         return ret;
1092 }
1093
1094
1095 /*************************************************************************
1096  *                              SQLFreeStmt           [ODBC32.016]
1097  */
1098 SQLRETURN WINAPI SQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option)
1099 {
1100         SQLRETURN ret;
1101         TRACE("(Handle %lx, Option=%d)\n",StatementHandle, Option);
1102
1103         CHECK_dmHandle();
1104
1105         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFREESTMT].func);
1106         ret=(gProxyHandle.functions[SQLAPI_INDEX_SQLFREESTMT].func)
1107             (StatementHandle, Option);
1108         TRACE("Returns %d\n",ret);
1109         return ret;
1110 }
1111
1112
1113 /*************************************************************************
1114  *                              SQLGetConnectAttr           [ODBC32.032]
1115  */
1116 SQLRETURN WINAPI SQLGetConnectAttr(SQLHDBC ConnectionHandle,
1117              SQLINTEGER Attribute, SQLPOINTER Value,
1118              SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1119 {
1120         TRACE("\n");
1121
1122         CHECK_dmHandle();
1123
1124         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTATTR].func);
1125         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTATTR].func)
1126             (ConnectionHandle, Attribute, Value,
1127             BufferLength, StringLength);
1128 }
1129
1130
1131 /*************************************************************************
1132  *                              SQLGetConnectOption       [ODBC32.042]
1133  */
1134 SQLRETURN WINAPI SQLGetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLPOINTER Value)
1135 {
1136         TRACE("\n");
1137
1138         CHECK_dmHandle();
1139
1140         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTOPTION].func);
1141         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCONNECTOPTION].func)
1142             (ConnectionHandle, Option, Value);
1143 }
1144
1145
1146 /*************************************************************************
1147  *                              SQLGetCursorName           [ODBC32.017]
1148  */
1149 SQLRETURN WINAPI SQLGetCursorName(SQLHSTMT StatementHandle,
1150              SQLCHAR *CursorName, SQLSMALLINT BufferLength,
1151              SQLSMALLINT *NameLength)
1152 {
1153         TRACE("\n");
1154
1155         CHECK_dmHandle();
1156
1157         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCURSORNAME].func);
1158         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETCURSORNAME].func)
1159             (StatementHandle, CursorName, BufferLength, NameLength);
1160 }
1161
1162
1163 /*************************************************************************
1164  *                              SQLGetData           [ODBC32.043]
1165  */
1166 SQLRETURN WINAPI SQLGetData(SQLHSTMT StatementHandle,
1167              SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType,
1168              SQLPOINTER TargetValue, SQLINTEGER BufferLength,
1169              SQLINTEGER *StrLen_or_Ind)
1170 {
1171         TRACE("\n");
1172
1173         CHECK_dmHandle();
1174
1175         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDATA].func);
1176         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDATA].func)
1177             (StatementHandle, ColumnNumber, TargetType,
1178             TargetValue, BufferLength, StrLen_or_Ind);
1179 }
1180
1181
1182 /*************************************************************************
1183  *                              SQLGetDescField           [ODBC32.033]
1184  */
1185 SQLRETURN WINAPI SQLGetDescField(SQLHDESC DescriptorHandle,
1186              SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
1187              SQLPOINTER Value, SQLINTEGER BufferLength,
1188              SQLINTEGER *StringLength)
1189 {
1190         TRACE("\n");
1191
1192         CHECK_dmHandle();
1193
1194         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCFIELD].func);
1195         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCFIELD].func)
1196             (DescriptorHandle, RecNumber, FieldIdentifier,
1197             Value, BufferLength, StringLength);
1198 }
1199
1200
1201 /*************************************************************************
1202  *                              SQLGetDescRec           [ODBC32.034]
1203  */
1204 SQLRETURN WINAPI SQLGetDescRec(SQLHDESC DescriptorHandle,
1205              SQLSMALLINT RecNumber, SQLCHAR *Name,
1206              SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
1207              SQLSMALLINT *Type, SQLSMALLINT *SubType,
1208              SQLINTEGER *Length, SQLSMALLINT *Precision,
1209              SQLSMALLINT *Scale, SQLSMALLINT *Nullable)
1210 {
1211         TRACE("\n");
1212
1213         CHECK_dmHandle();
1214
1215         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCREC].func);
1216         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDESCREC].func)
1217             (DescriptorHandle, RecNumber, Name, BufferLength,
1218             StringLength, Type, SubType, Length, Precision, Scale, Nullable);
1219 }
1220
1221
1222 /*************************************************************************
1223  *                              SQLGetDiagField           [ODBC32.035]
1224  */
1225 SQLRETURN WINAPI SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
1226              SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
1227              SQLPOINTER DiagInfo, SQLSMALLINT BufferLength,
1228              SQLSMALLINT *StringLength)
1229 {
1230         TRACE("\n");
1231
1232         CHECK_dmHandle();
1233
1234         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGFIELD].func);
1235         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGFIELD].func)
1236             (HandleType, Handle, RecNumber, DiagIdentifier,
1237             DiagInfo, BufferLength, StringLength);
1238 }
1239
1240
1241 /*************************************************************************
1242  *                              SQLGetDiagRec           [ODBC32.036]
1243  */
1244 SQLRETURN WINAPI SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
1245              SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
1246              SQLINTEGER *NativeError, SQLCHAR *MessageText,
1247              SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
1248 {
1249         TRACE("\n");
1250
1251         CHECK_dmHandle();
1252
1253         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGREC].func);
1254         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETDIAGREC].func)
1255             (HandleType, Handle, RecNumber, Sqlstate, NativeError,
1256             MessageText, BufferLength, TextLength);
1257 }
1258
1259
1260 /*************************************************************************
1261  *                              SQLGetEnvAttr           [ODBC32.037]
1262  */
1263 SQLRETURN WINAPI SQLGetEnvAttr(SQLHENV EnvironmentHandle,
1264              SQLINTEGER Attribute, SQLPOINTER Value,
1265              SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1266 {
1267         TRACE("\n");
1268
1269         CHECK_dmHandle();
1270
1271         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETENVATTR].func);
1272         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETENVATTR].func)
1273             (EnvironmentHandle, Attribute, Value, BufferLength, StringLength);
1274 }
1275
1276
1277 /*************************************************************************
1278  *                              SQLGetFunctions           [ODBC32.044]
1279  */
1280 SQLRETURN WINAPI SQLGetFunctions(SQLHDBC ConnectionHandle, SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported)
1281 {
1282         TRACE("\n");
1283
1284         CHECK_dmHandle();
1285
1286         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETFUNCTIONS].func);
1287         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETFUNCTIONS].func)
1288             (ConnectionHandle, FunctionId, Supported);
1289 }
1290
1291
1292 /*************************************************************************
1293  *                              SQLGetInfo           [ODBC32.045]
1294  */
1295 SQLRETURN WINAPI SQLGetInfo(SQLHDBC ConnectionHandle,
1296              SQLUSMALLINT InfoType, SQLPOINTER InfoValue,
1297              SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
1298 {
1299         TRACE("\n");
1300
1301         CHECK_dmHandle();
1302
1303         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETINFO].func);
1304         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETINFO].func)
1305             (ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength);
1306 }
1307
1308
1309 /*************************************************************************
1310  *                              SQLGetStmtAttr           [ODBC32.038]
1311  */
1312 SQLRETURN WINAPI SQLGetStmtAttr(SQLHSTMT StatementHandle,
1313              SQLINTEGER Attribute, SQLPOINTER Value,
1314              SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1315 {
1316         TRACE("\n");
1317
1318         CHECK_dmHandle();
1319
1320         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTATTR].func);
1321         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTATTR].func)
1322             (StatementHandle, Attribute, Value, BufferLength, StringLength);
1323 }
1324
1325
1326 /*************************************************************************
1327  *                              SQLGetStmtOption           [ODBC32.046]
1328  */
1329 SQLRETURN WINAPI SQLGetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLPOINTER Value)
1330 {
1331         TRACE("\n");
1332
1333         CHECK_dmHandle();
1334
1335         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTOPTION].func);
1336         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETSTMTOPTION].func)
1337                 (StatementHandle, Option, Value);
1338 }
1339
1340
1341 /*************************************************************************
1342  *                              SQLGetTypeInfo           [ODBC32.047]
1343  */
1344 SQLRETURN WINAPI SQLGetTypeInfo(SQLHSTMT StatementHandle, SQLSMALLINT DataType)
1345 {
1346         TRACE("\n");
1347
1348         CHECK_dmHandle();
1349
1350         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLGETTYPEINFO].func);
1351         return (gProxyHandle.functions[SQLAPI_INDEX_SQLGETTYPEINFO].func)
1352             (StatementHandle, DataType);
1353 }
1354
1355
1356 /*************************************************************************
1357  *                              SQLNumResultCols           [ODBC32.018]
1358  */
1359 SQLRETURN WINAPI SQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount)
1360 {
1361         TRACE("\n");
1362
1363         CHECK_dmHandle();
1364
1365         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLNUMRESULTCOLS].func);
1366         return (gProxyHandle.functions[SQLAPI_INDEX_SQLNUMRESULTCOLS].func)
1367             (StatementHandle, ColumnCount);
1368 }
1369
1370
1371 /*************************************************************************
1372  *                              SQLParamData           [ODBC32.048]
1373  */
1374 SQLRETURN WINAPI SQLParamData(SQLHSTMT StatementHandle, SQLPOINTER *Value)
1375 {
1376         TRACE("\n");
1377
1378         CHECK_dmHandle();
1379
1380         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPARAMDATA].func);
1381         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPARAMDATA].func)
1382             (StatementHandle, Value);
1383 }
1384
1385
1386 /*************************************************************************
1387  *                              SQLPrepare           [ODBC32.019]
1388  */
1389 SQLRETURN WINAPI SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength)
1390 {
1391         TRACE("\n");
1392
1393         CHECK_dmHandle();
1394
1395         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPREPARE].func);
1396         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPREPARE].func)
1397             (StatementHandle, StatementText, TextLength);
1398 }
1399
1400
1401 /*************************************************************************
1402  *                              SQLPutData           [ODBC32.049]
1403  */
1404 SQLRETURN WINAPI SQLPutData(SQLHSTMT StatementHandle, SQLPOINTER Data, SQLINTEGER StrLen_or_Ind)
1405 {
1406         TRACE("\n");
1407
1408         CHECK_dmHandle();
1409
1410         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPUTDATA].func);
1411         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPUTDATA].func)
1412             (StatementHandle, Data, StrLen_or_Ind);
1413 }
1414
1415
1416 /*************************************************************************
1417  *                              SQLRowCount           [ODBC32.020]
1418  */
1419 SQLRETURN WINAPI SQLRowCount(SQLHSTMT StatementHandle, SQLINTEGER *RowCount)
1420 {
1421         TRACE("\n");
1422
1423         CHECK_dmHandle();
1424
1425         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLROWCOUNT].func);
1426         return (gProxyHandle.functions[SQLAPI_INDEX_SQLROWCOUNT].func)
1427             (StatementHandle, RowCount);
1428 }
1429
1430
1431 /*************************************************************************
1432  *                              SQLSetConnectAttr           [ODBC32.039]
1433  */
1434 SQLRETURN WINAPI SQLSetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute,
1435         SQLPOINTER Value, SQLINTEGER StringLength)
1436 {
1437         TRACE("\n");
1438
1439         CHECK_dmHandle();
1440
1441         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTATTR].func);
1442         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTATTR].func)
1443             (ConnectionHandle, Attribute, Value, StringLength);
1444 }
1445
1446
1447 /*************************************************************************
1448  *                              SQLSetConnectOption           [ODBC32.050]
1449  */
1450 SQLRETURN WINAPI SQLSetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLUINTEGER Value)
1451 {
1452         TRACE("\n");
1453
1454         CHECK_dmHandle();
1455
1456         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTOPTION].func);
1457         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCONNECTOPTION].func)
1458             (ConnectionHandle, Option, Value);
1459 }
1460
1461
1462 /*************************************************************************
1463  *                              SQLSetCursorName           [ODBC32.021]
1464  */
1465 SQLRETURN WINAPI SQLSetCursorName(SQLHSTMT StatementHandle, SQLCHAR *CursorName, SQLSMALLINT NameLength)
1466 {
1467         TRACE("\n");
1468
1469         CHECK_dmHandle();
1470
1471         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCURSORNAME].func);
1472         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETCURSORNAME].func)
1473             (StatementHandle, CursorName, NameLength);
1474 }
1475
1476
1477 /*************************************************************************
1478  *                              SQLSetDescField           [ODBC32.073]
1479  */
1480 SQLRETURN WINAPI SQLSetDescField(SQLHDESC DescriptorHandle,
1481              SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
1482              SQLPOINTER Value, SQLINTEGER BufferLength)
1483 {
1484         TRACE("\n");
1485
1486         CHECK_dmHandle();
1487
1488         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCFIELD].func);
1489         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCFIELD].func)
1490             (DescriptorHandle, RecNumber, FieldIdentifier, Value, BufferLength);
1491 }
1492
1493
1494 /*************************************************************************
1495  *                              SQLSetDescRec           [ODBC32.074]
1496  */
1497 SQLRETURN WINAPI SQLSetDescRec(SQLHDESC DescriptorHandle,
1498              SQLSMALLINT RecNumber, SQLSMALLINT Type,
1499              SQLSMALLINT SubType, SQLINTEGER Length,
1500              SQLSMALLINT Precision, SQLSMALLINT Scale,
1501              SQLPOINTER Data, SQLINTEGER *StringLength,
1502              SQLINTEGER *Indicator)
1503 {
1504         TRACE("\n");
1505
1506         CHECK_dmHandle();
1507
1508         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCREC].func);
1509         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETDESCREC].func)
1510             (DescriptorHandle, RecNumber, Type, SubType, Length,
1511             Precision, Scale, Data, StringLength, Indicator);
1512 }
1513
1514
1515 /*************************************************************************
1516  *                              SQLSetEnvAttr           [ODBC32.075]
1517  */
1518 SQLRETURN WINAPI SQLSetEnvAttr(SQLHENV EnvironmentHandle,
1519              SQLINTEGER Attribute, SQLPOINTER Value,
1520              SQLINTEGER StringLength)
1521 {
1522         TRACE("\n");
1523
1524         CHECK_dmHandle();
1525
1526         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETENVATTR].func);
1527         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETENVATTR].func)
1528             (EnvironmentHandle, Attribute, Value, StringLength);
1529 }
1530
1531
1532 /*************************************************************************
1533  *                              SQLSetParam           [ODBC32.022]
1534  */
1535 SQLRETURN WINAPI SQLSetParam(SQLHSTMT StatementHandle,
1536              SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
1537              SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision,
1538              SQLSMALLINT ParameterScale, SQLPOINTER ParameterValue,
1539              SQLINTEGER *StrLen_or_Ind)
1540 {
1541         TRACE("\n");
1542
1543         CHECK_dmHandle();
1544
1545         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETPARAM].func);
1546         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETPARAM].func)
1547             (StatementHandle, ParameterNumber, ValueType, ParameterType, LengthPrecision,
1548              ParameterScale, ParameterValue, StrLen_or_Ind);
1549 }
1550
1551
1552 /*************************************************************************
1553  *                              SQLSetStmtAttr           [ODBC32.076]
1554  */
1555 SQLRETURN WINAPI SQLSetStmtAttr(SQLHSTMT StatementHandle,
1556                  SQLINTEGER Attribute, SQLPOINTER Value,
1557                  SQLINTEGER StringLength)
1558 {
1559         TRACE("\n");
1560
1561         CHECK_dmHandle();
1562
1563         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTATTR].func);
1564         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTATTR].func)
1565             (StatementHandle, Attribute, Value, StringLength);
1566 }
1567
1568
1569 /*************************************************************************
1570  *                              SQLSetStmtOption           [ODBC32.051]
1571  */
1572 SQLRETURN WINAPI SQLSetStmtOption(SQLHSTMT StatementHandle, SQLUSMALLINT Option, SQLUINTEGER Value)
1573 {
1574         TRACE("\n");
1575
1576         CHECK_dmHandle();
1577
1578         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTOPTION].func);
1579         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSTMTOPTION].func)
1580             (StatementHandle, Option, Value);
1581 }
1582
1583
1584 /*************************************************************************
1585  *                              SQLSpecialColumns           [ODBC32.052]
1586  */
1587 SQLRETURN WINAPI SQLSpecialColumns(SQLHSTMT StatementHandle,
1588              SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName,
1589              SQLSMALLINT NameLength1, SQLCHAR *SchemaName,
1590              SQLSMALLINT NameLength2, SQLCHAR *TableName,
1591              SQLSMALLINT NameLength3, SQLUSMALLINT Scope,
1592              SQLUSMALLINT Nullable)
1593 {
1594
1595         CHECK_dmHandle();
1596
1597         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSPECIALCOLUMNS].func);
1598         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSPECIALCOLUMNS].func)
1599             (StatementHandle, IdentifierType, CatalogName, NameLength1, SchemaName,
1600              NameLength2, TableName, NameLength3, Scope, Nullable);
1601 }
1602
1603
1604 /*************************************************************************
1605  *                              SQLStatistics           [ODBC32.053]
1606  */
1607 SQLRETURN WINAPI SQLStatistics(SQLHSTMT StatementHandle,
1608              SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
1609              SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
1610              SQLCHAR *TableName, SQLSMALLINT NameLength3,
1611              SQLUSMALLINT Unique, SQLUSMALLINT Reserved)
1612 {
1613         TRACE("\n");
1614
1615         CHECK_dmHandle();
1616
1617         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSTATISTICS].func);
1618         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSTATISTICS].func)
1619             (StatementHandle, CatalogName, NameLength1, SchemaName, NameLength2,
1620              TableName, NameLength3, Unique, Reserved);
1621 }
1622
1623
1624 /*************************************************************************
1625  *                              SQLTables           [ODBC32.054]
1626  */
1627 SQLRETURN WINAPI SQLTables(SQLHSTMT StatementHandle,
1628              SQLCHAR *CatalogName, SQLSMALLINT NameLength1,
1629              SQLCHAR *SchemaName, SQLSMALLINT NameLength2,
1630              SQLCHAR *TableName, SQLSMALLINT NameLength3,
1631              SQLCHAR *TableType, SQLSMALLINT NameLength4)
1632 {
1633         TRACE("\n");
1634
1635         CHECK_dmHandle();
1636
1637         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLES].func);
1638         return (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLES].func)
1639                 (StatementHandle, CatalogName, NameLength1,
1640                 SchemaName, NameLength2, TableName, NameLength3, TableType, NameLength4);
1641 }
1642
1643
1644 /*************************************************************************
1645  *                              SQLTransact           [ODBC32.023]
1646  */
1647 SQLRETURN WINAPI SQLTransact(SQLHENV EnvironmentHandle, SQLHDBC ConnectionHandle,
1648         SQLUSMALLINT CompletionType)
1649 {
1650         TRACE("\n");
1651
1652         CHECK_dmHandle();
1653
1654         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLTRANSACT].func);
1655         return (gProxyHandle.functions[SQLAPI_INDEX_SQLTRANSACT].func)
1656             (EnvironmentHandle, ConnectionHandle, CompletionType);
1657 }
1658
1659
1660 /*************************************************************************
1661  *                              SQLBrowseConnect           [ODBC32.055]
1662  */
1663 SQLRETURN WINAPI SQLBrowseConnect(
1664     SQLHDBC            hdbc,
1665     SQLCHAR               *szConnStrIn,
1666     SQLSMALLINT        cbConnStrIn,
1667     SQLCHAR               *szConnStrOut,
1668     SQLSMALLINT        cbConnStrOutMax,
1669     SQLSMALLINT       *pcbConnStrOut)
1670 {
1671         TRACE("\n");
1672
1673         CHECK_dmHandle();
1674
1675         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBROWSECONNECT].func);
1676         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBROWSECONNECT].func)
1677                 (hdbc, szConnStrIn, cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut);
1678 }
1679
1680
1681 /*************************************************************************
1682  *                              SQLBulkOperations           [ODBC32.078]
1683  */
1684 SQLRETURN WINAPI  SQLBulkOperations(
1685         SQLHSTMT                        StatementHandle,
1686         SQLSMALLINT                     Operation)
1687 {
1688         TRACE("\n");
1689
1690         CHECK_dmHandle();
1691
1692         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBULKOPERATIONS].func);
1693         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBULKOPERATIONS].func)
1694                    (StatementHandle, Operation);
1695 }
1696
1697
1698 /*************************************************************************
1699  *                              SQLColAttributes           [ODBC32.006]
1700  */
1701 SQLRETURN WINAPI SQLColAttributes(
1702     SQLHSTMT           hstmt,
1703     SQLUSMALLINT       icol,
1704     SQLUSMALLINT       fDescType,
1705     SQLPOINTER         rgbDesc,
1706     SQLSMALLINT        cbDescMax,
1707     SQLSMALLINT           *pcbDesc,
1708     SQLINTEGER            *pfDesc)
1709 {
1710         TRACE("\n");
1711
1712         CHECK_dmHandle();
1713
1714         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTES].func);
1715         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLATTRIBUTES].func)
1716                    (hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
1717 }
1718
1719
1720 /*************************************************************************
1721  *                              SQLColumnPrivileges           [ODBC32.056]
1722  */
1723 SQLRETURN WINAPI SQLColumnPrivileges(
1724     SQLHSTMT           hstmt,
1725     SQLCHAR               *szCatalogName,
1726     SQLSMALLINT        cbCatalogName,
1727     SQLCHAR               *szSchemaName,
1728     SQLSMALLINT        cbSchemaName,
1729     SQLCHAR               *szTableName,
1730     SQLSMALLINT        cbTableName,
1731     SQLCHAR               *szColumnName,
1732     SQLSMALLINT        cbColumnName)
1733 {
1734         TRACE("\n");
1735
1736         CHECK_dmHandle();
1737
1738         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNPRIVILEGES].func);
1739         return (gProxyHandle.functions[SQLAPI_INDEX_SQLCOLUMNPRIVILEGES].func)
1740                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1741                     szTableName, cbTableName, szColumnName, cbColumnName);
1742 }
1743
1744
1745 /*************************************************************************
1746  *                              SQLDescribeParam          [ODBC32.058]
1747  */
1748 SQLRETURN WINAPI SQLDescribeParam(
1749     SQLHSTMT           hstmt,
1750     SQLUSMALLINT       ipar,
1751     SQLSMALLINT           *pfSqlType,
1752     SQLUINTEGER           *pcbParamDef,
1753     SQLSMALLINT           *pibScale,
1754     SQLSMALLINT           *pfNullable)
1755 {
1756         TRACE("\n");
1757
1758         CHECK_dmHandle();
1759
1760         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBEPARAM].func);
1761         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDESCRIBEPARAM].func)
1762                    (hstmt, ipar, pfSqlType, pcbParamDef, pibScale, pfNullable);
1763 }
1764
1765
1766 /*************************************************************************
1767  *                              SQLExtendedFetch           [ODBC32.059]
1768  */
1769 SQLRETURN WINAPI SQLExtendedFetch(
1770     SQLHSTMT           hstmt,
1771     SQLUSMALLINT       fFetchType,
1772     SQLINTEGER         irow,
1773     SQLUINTEGER           *pcrow,
1774     SQLUSMALLINT          *rgfRowStatus)
1775 {
1776         TRACE("\n");
1777
1778         CHECK_dmHandle();
1779
1780         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLEXTENDEDFETCH].func);
1781         return (gProxyHandle.functions[SQLAPI_INDEX_SQLEXTENDEDFETCH].func)
1782                    (hstmt, fFetchType, irow, pcrow, rgfRowStatus);
1783 }
1784
1785
1786 /*************************************************************************
1787  *                              SQLForeignKeys           [ODBC32.060]
1788  */
1789 SQLRETURN WINAPI SQLForeignKeys(
1790     SQLHSTMT           hstmt,
1791     SQLCHAR               *szPkCatalogName,
1792     SQLSMALLINT        cbPkCatalogName,
1793     SQLCHAR               *szPkSchemaName,
1794     SQLSMALLINT        cbPkSchemaName,
1795     SQLCHAR               *szPkTableName,
1796     SQLSMALLINT        cbPkTableName,
1797     SQLCHAR               *szFkCatalogName,
1798     SQLSMALLINT        cbFkCatalogName,
1799     SQLCHAR               *szFkSchemaName,
1800     SQLSMALLINT        cbFkSchemaName,
1801     SQLCHAR               *szFkTableName,
1802     SQLSMALLINT        cbFkTableName)
1803 {
1804         TRACE("\n");
1805
1806         CHECK_dmHandle();
1807
1808         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLFOREIGNKEYS].func);
1809         return (gProxyHandle.functions[SQLAPI_INDEX_SQLFOREIGNKEYS].func)
1810                    (hstmt, szPkCatalogName, cbPkCatalogName, szPkSchemaName, cbPkSchemaName,
1811                     szPkTableName, cbPkTableName, szFkCatalogName, cbFkCatalogName, szFkSchemaName,
1812                         cbFkSchemaName, szFkTableName, cbFkTableName);
1813 }
1814
1815
1816 /*************************************************************************
1817  *                              SQLMoreResults           [ODBC32.061]
1818  */
1819 SQLRETURN WINAPI SQLMoreResults(SQLHSTMT hstmt)
1820 {
1821         TRACE("\n");
1822
1823         CHECK_dmHandle();
1824
1825         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLMORERESULTS].func);
1826         return (gProxyHandle.functions[SQLAPI_INDEX_SQLMORERESULTS].func) (hstmt);
1827 }
1828
1829
1830 /*************************************************************************
1831  *                              SQLNativeSql           [ODBC32.062]
1832  */
1833 SQLRETURN WINAPI SQLNativeSql(
1834     SQLHDBC            hdbc,
1835     SQLCHAR               *szSqlStrIn,
1836     SQLINTEGER         cbSqlStrIn,
1837     SQLCHAR               *szSqlStr,
1838     SQLINTEGER         cbSqlStrMax,
1839     SQLINTEGER            *pcbSqlStr)
1840 {
1841         TRACE("\n");
1842
1843         CHECK_dmHandle();
1844
1845         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLNATIVESQL].func);
1846         return (gProxyHandle.functions[SQLAPI_INDEX_SQLNATIVESQL].func)
1847                    (hdbc, szSqlStrIn, cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr);
1848 }
1849
1850
1851 /*************************************************************************
1852  *                              SQLNumParams           [ODBC32.063]
1853  */
1854 SQLRETURN WINAPI SQLNumParams(
1855     SQLHSTMT           hstmt,
1856     SQLSMALLINT           *pcpar)
1857 {
1858         TRACE("\n");
1859
1860         CHECK_dmHandle();
1861
1862         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLNUMPARAMS].func);
1863         return (gProxyHandle.functions[SQLAPI_INDEX_SQLNUMPARAMS].func) (hstmt, pcpar);
1864 }
1865
1866
1867 /*************************************************************************
1868  *                              SQLParamOptions           [ODBC32.064]
1869  */
1870 SQLRETURN WINAPI SQLParamOptions(
1871     SQLHSTMT           hstmt,
1872     SQLUINTEGER        crow,
1873     SQLUINTEGER           *pirow)
1874 {
1875         TRACE("\n");
1876
1877         CHECK_dmHandle();
1878
1879         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPARAMOPTIONS].func);
1880         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPARAMOPTIONS].func) (hstmt, crow, pirow);
1881 }
1882
1883
1884 /*************************************************************************
1885  *                              SQLPrimaryKeys           [ODBC32.065]
1886  */
1887 SQLRETURN WINAPI SQLPrimaryKeys(
1888     SQLHSTMT           hstmt,
1889     SQLCHAR               *szCatalogName,
1890     SQLSMALLINT        cbCatalogName,
1891     SQLCHAR               *szSchemaName,
1892     SQLSMALLINT        cbSchemaName,
1893     SQLCHAR               *szTableName,
1894     SQLSMALLINT        cbTableName)
1895 {
1896         TRACE("\n");
1897
1898         CHECK_dmHandle();
1899
1900         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPRIMARYKEYS].func);
1901         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPRIMARYKEYS].func)
1902                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1903                     szTableName, cbTableName);
1904 }
1905
1906
1907 /*************************************************************************
1908  *                              SQLProcedureColumns           [ODBC32.066]
1909  */
1910 SQLRETURN WINAPI SQLProcedureColumns(
1911     SQLHSTMT           hstmt,
1912     SQLCHAR               *szCatalogName,
1913     SQLSMALLINT        cbCatalogName,
1914     SQLCHAR               *szSchemaName,
1915     SQLSMALLINT        cbSchemaName,
1916     SQLCHAR               *szProcName,
1917     SQLSMALLINT        cbProcName,
1918     SQLCHAR               *szColumnName,
1919     SQLSMALLINT        cbColumnName)
1920 {
1921         TRACE("\n");
1922
1923         CHECK_dmHandle();
1924
1925         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURECOLUMNS].func);
1926         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURECOLUMNS].func)
1927                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1928                     szProcName, cbProcName, szColumnName, cbColumnName);
1929 }
1930
1931
1932 /*************************************************************************
1933  *                              SQLProcedures           [ODBC32.067]
1934  */
1935 SQLRETURN WINAPI SQLProcedures(
1936     SQLHSTMT           hstmt,
1937     SQLCHAR               *szCatalogName,
1938     SQLSMALLINT        cbCatalogName,
1939     SQLCHAR               *szSchemaName,
1940     SQLSMALLINT        cbSchemaName,
1941     SQLCHAR               *szProcName,
1942     SQLSMALLINT        cbProcName)
1943 {
1944         TRACE("\n");
1945
1946         CHECK_dmHandle();
1947
1948         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURES].func);
1949         return (gProxyHandle.functions[SQLAPI_INDEX_SQLPROCEDURES].func)
1950                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1951                     szProcName, cbProcName);
1952 }
1953
1954
1955 /*************************************************************************
1956  *                              SQLSetPos           [ODBC32.068]
1957  */
1958 SQLRETURN WINAPI SQLSetPos(
1959     SQLHSTMT           hstmt,
1960     SQLUSMALLINT       irow,
1961     SQLUSMALLINT       fOption,
1962     SQLUSMALLINT       fLock)
1963 {
1964         TRACE("\n");
1965
1966         CHECK_dmHandle();
1967
1968         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETPOS].func);
1969         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETPOS].func)
1970                    (hstmt, irow, fOption, fLock);
1971 }
1972
1973
1974 /*************************************************************************
1975  *                              SQLTablePrivileges           [ODBC32.070]
1976  */
1977 SQLRETURN WINAPI SQLTablePrivileges(
1978     SQLHSTMT           hstmt,
1979     SQLCHAR               *szCatalogName,
1980     SQLSMALLINT        cbCatalogName,
1981     SQLCHAR               *szSchemaName,
1982     SQLSMALLINT        cbSchemaName,
1983     SQLCHAR               *szTableName,
1984     SQLSMALLINT        cbTableName)
1985 {
1986         TRACE("\n");
1987
1988         CHECK_dmHandle();
1989
1990         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLEPRIVILEGES].func);
1991         return (gProxyHandle.functions[SQLAPI_INDEX_SQLTABLEPRIVILEGES].func)
1992                    (hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName,
1993                     szTableName, cbTableName);
1994 }
1995
1996
1997 /*************************************************************************
1998  *                              SQLDrivers           [ODBC32.071]
1999  */
2000 SQLRETURN WINAPI SQLDrivers(
2001     SQLHENV            henv,
2002     SQLUSMALLINT       fDirection,
2003     SQLCHAR               *szDriverDesc,
2004     SQLSMALLINT        cbDriverDescMax,
2005     SQLSMALLINT           *pcbDriverDesc,
2006     SQLCHAR               *szDriverAttributes,
2007     SQLSMALLINT        cbDriverAttrMax,
2008     SQLSMALLINT           *pcbDriverAttr)
2009 {
2010         TRACE("\n");
2011
2012         CHECK_dmHandle();
2013
2014         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERS].func);
2015         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERS].func)
2016                 (henv, fDirection, szDriverDesc, cbDriverDescMax, pcbDriverDesc,
2017                  szDriverAttributes, cbDriverAttrMax, pcbDriverAttr);
2018 }
2019
2020
2021 /*************************************************************************
2022  *                              SQLBindParameter           [ODBC32.072]
2023  */
2024 SQLRETURN WINAPI SQLBindParameter(
2025     SQLHSTMT           hstmt,
2026     SQLUSMALLINT       ipar,
2027     SQLSMALLINT        fParamType,
2028     SQLSMALLINT        fCType,
2029     SQLSMALLINT        fSqlType,
2030     SQLUINTEGER        cbColDef,
2031     SQLSMALLINT        ibScale,
2032     SQLPOINTER         rgbValue,
2033     SQLINTEGER         cbValueMax,
2034     SQLINTEGER            *pcbValue)
2035 {
2036         TRACE("\n");
2037
2038         CHECK_dmHandle();
2039
2040         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDPARAMETER].func);
2041         return (gProxyHandle.functions[SQLAPI_INDEX_SQLBINDPARAMETER].func)
2042                 (hstmt, ipar, fParamType, fCType, fSqlType, cbColDef, ibScale,
2043                  rgbValue, cbValueMax, pcbValue);
2044 }
2045
2046
2047 /*************************************************************************
2048  *                              SQLDriverConnect           [ODBC32.041]
2049  */
2050 SQLRETURN WINAPI SQLDriverConnect(
2051     SQLHDBC            hdbc,
2052     SQLHWND            hwnd,
2053     SQLCHAR            *conn_str_in,
2054     SQLSMALLINT        len_conn_str_in,
2055     SQLCHAR            *conn_str_out,
2056     SQLSMALLINT        conn_str_out_max,
2057     SQLSMALLINT        *ptr_conn_str_out,
2058     SQLUSMALLINT       driver_completion )
2059 {
2060         TRACE("\n");
2061
2062         CHECK_dmHandle();
2063
2064         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERCONNECT].func);
2065         return (gProxyHandle.functions[SQLAPI_INDEX_SQLDRIVERCONNECT].func)
2066                  (hdbc, hwnd, conn_str_in, len_conn_str_in, conn_str_out,
2067                   conn_str_out_max, ptr_conn_str_out, driver_completion);
2068 }
2069
2070
2071 /*************************************************************************
2072  *                              SQLSetScrollOptions           [ODBC32.069]
2073  */
2074 SQLRETURN WINAPI SQLSetScrollOptions(
2075     SQLHSTMT           statement_handle,
2076     SQLUSMALLINT       f_concurrency,
2077     SQLINTEGER         crow_keyset,
2078     SQLUSMALLINT       crow_rowset )
2079 {
2080         TRACE("\n");
2081
2082         CHECK_dmHandle();
2083
2084         assert (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSCROLLOPTIONS].func);
2085         return (gProxyHandle.functions[SQLAPI_INDEX_SQLSETSCROLLOPTIONS].func)
2086                    (statement_handle, f_concurrency, crow_keyset, crow_rowset);
2087 }
2088
2089 /* End of file */