]> git.saurik.com Git - wxWidgets.git/blobdiff - src/iodbc/connect.c
check that the version of __sync_sub_and_fetch that returns a value is supported...
[wxWidgets.git] / src / iodbc / connect.c
index 88e636aca797981b25cac11b88e15a4639abe3e3..2bd934f6a2464b237672daf20763f8a1c727aac4 100644 (file)
@@ -1,33 +1,42 @@
-/** Connect(load) driver
-
-    Copyright (C) 1995 by Ke Jin <kejin@empress.com> 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-**/
+/*
+ *  connect.c
+ *
+ *  $Id$
+ *
+ *  Connect (load) driver
+ *
+ *  The iODBC driver manager.
+ *  
+ *  Copyright (C) 1995 by Ke Jin <kejin@empress.com> 
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
-#include       <../iodbc/iodbc.h>
+#include       "config.h"
 
-#include       <../iodbc/isql.h>
-#include       <../iodbc/isqlext.h>
+#include       "isql.h"
+#include       "isqlext.h"
 
-#include        <../iodbc/dlproc.h>
+#include       "dlproc.h"
 
-#include       <../iodbc/herr.h>
-#include       <../iodbc/henv.h>
-#include       <../iodbc/hdbc.h>
-#include       <../iodbc/hstmt.h>
+#include       "herr.h"
+#include       "henv.h"
+#include       "hdbc.h"
+#include       "hstmt.h"
 
-#include       <../iodbc/itrace.h>
-#include        <strings.h>
-#include        <stdio.h>
+#include       "itrace.h"
 
 extern char*   _iodbcdm_getkeyvalbydsn();
 extern char*   _iodbcdm_getkeyvalinstr();
@@ -41,11 +50,8 @@ extern       RETCODE _iodbcdm_driverunload();
  *   violation.
  */
 static char sccsid[] 
-       = "@(#)iODBC driver manager " "2.12" ", Copyright(c) 1995 by Ke Jin";
+       = "@(#)iODBC driver manager 2.5, Copyright(c) 1995 by Ke Jin";
 
-static RETCODE _iodbcdm_driverload( 
-                       char FAR*       path,   
-                       HDBC            hdbc )
 /* - Load driver share library( or increase its reference count 
  *   if it has already been loaded by another active connection)
  * - Call driver's SQLAllocEnv() (for the first reference only)
@@ -53,1210 +59,1183 @@ static RETCODE  _iodbcdm_driverload(
  * - Call driver's SQLSetConnectOption() (set login time out)
  * - Increase the bookkeeping reference count
  */
+static RETCODE 
+_iodbcdm_driverload (
+    char FAR * path,
+    HDBC hdbc)
 {
-       DBC_t  FAR*     pdbc = (DBC_t FAR*)hdbc;
-       GENV_t FAR*     genv; 
-       ENV_t  FAR*     penv = NULL;
-       HDLL            hdll;
-       HPROC           hproc;
-       RETCODE         retcode = SQL_SUCCESS;
-       int             sqlstat = en_00000;
-
-       if( path == NULL || path[0] == '\0' )
-       {
-               PUSHSQLERR ( pdbc->herr, en_IM002 );
+  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
+  GENV_t FAR *genv;
+  ENV_t FAR *penv = NULL;
+  HDLL hdll;
+  HPROC hproc;
+  RETCODE retcode = SQL_SUCCESS;
+  int sqlstat = en_00000;
 
-               return SQL_ERROR;
-       }
+  if (path == NULL || path[0] == '\0')
+    {
+      PUSHSQLERR (pdbc->herr, en_IM002);
 
-       if( hdbc == SQL_NULL_HDBC 
-        || pdbc->genv == SQL_NULL_HENV )
-       {
-               return SQL_INVALID_HANDLE;
-       }
+      return SQL_ERROR;
+    }
 
-       genv = (GENV_t FAR*)pdbc->genv;
+  if (hdbc == SQL_NULL_HDBC || pdbc->genv == SQL_NULL_HENV)
+    {
+      return SQL_INVALID_HANDLE;
+    }
 
-       hdll = _iodbcdm_dllopen( (char FAR*) path ); 
-                                /* This will either load the
-                                 * driver dll or increase its
-                                 * reference count */
+  genv = (GENV_t FAR *) pdbc->genv;
 
-       if( hdll == SQL_NULL_HDLL )
-       {
-               PUSHSYSERR ( pdbc->herr, _iodbcdm_dllerror() );
-               PUSHSQLERR ( pdbc->herr, en_IM003 );
-               return SQL_ERROR;
-       }
+  /* This will either load the driver dll or increase its reference count */
+  hdll = _iodbcdm_dllopen ((char FAR *) path);
+
+  if (hdll == SQL_NULL_HDLL)
+    {
+      PUSHSYSERR (pdbc->herr, _iodbcdm_dllerror ());
+      PUSHSQLERR (pdbc->herr, en_IM003);
+      return SQL_ERROR;
+    }
 
-       penv = (ENV_t FAR*)(pdbc->henv);
+  penv = (ENV_t FAR *) (pdbc->henv);
 
-       if( penv != NULL )
+  if (penv != NULL)
+    {
+      if (penv->hdll != hdll)
        {
-               if( penv->hdll != hdll )
-               {
-                       _iodbcdm_driverunload(hdbc);
-               }
-               else
-               {
-                       _iodbcdm_dllclose( hdll );
-                       /* this will not unload the driver
-                        * but only decrease its internal
-                        * reference count 
-                        */
-               }
+         _iodbcdm_driverunload (hdbc);
        }
-
-       if(penv == NULL )
+      else
        {
-               /* find out whether this dll has already 
-                * been loaded on another connection */
-               for( penv  = (ENV_t FAR*)genv->henv;
-                    penv != NULL; 
-                    penv  = (ENV_t FAR*)penv->next )
-               {
-                       if( penv->hdll == hdll )
-                       {
-                               _iodbcdm_dllclose( hdll );
-                               /* this will not unload the driver
-                                * but only decrease its internal
-                                * reference count 
-                                */
-                               break;
-                       }
-               }
-       
-               if( penv == NULL )
-               /* no connection attaching with this dll */
-               {
-                       int     i;
-       
-                       /* create a new dll env instance */
-                       penv = (ENV_t FAR*)MEM_ALLOC ( sizeof(ENV_t) );
-       
-                       if( penv == NULL )
-                       {
-                               _iodbcdm_dllclose(hdll); 
-       
-                               PUSHSQLERR ( pdbc->herr, en_S1001 );
-       
-                               return SQL_ERROR;
-                       }
-       
-                       for( i = 0; i< SQL_EXT_API_LAST + 1; i++)
-                       {
-                               (penv->dllproc_tab)[i] = SQL_NULL_HPROC;
-                       }
-       
-                       pdbc->henv = penv;
-                       penv->hdll = hdll;
-       
-                       /* call driver's SQLAllocHandle() or SQLAllocEnv() */
-#if (ODBCVER >= 0x0300)
-                       hproc = _iodbcdm_getproc( hdbc, en_AllocHandle );
-
-                       if( hproc )
-                       {
-                               CALL_DRIVER ( hdbc, retcode, hproc, en_AllocHandle, 
-                                       ( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(penv->dhenv) )
-                       }
-                       else /* try driver's SQLAllocEnv() */
-#endif
-                       {
-                               hproc = _iodbcdm_getproc( hdbc, en_AllocEnv );
-
-                               if( hproc == SQL_NULL_HPROC)
-                               {
-                                       sqlstat = en_IM004;
-                               }
-                               else
-                               {
-                                       CALL_DRIVER ( hdbc, retcode, hproc, 
-                                       en_AllocEnv, (&(penv->dhenv)) ) 
-                               }
-                       }
-
-                       if( retcode == SQL_ERROR )
-                       {
-                               sqlstat = en_IM004;
-                       }
-
-                       if( sqlstat != en_00000 )
-                       {
-                               _iodbcdm_dllclose ( hdll );
-                               MEM_FREE ( penv );
-                               PUSHSQLERR ( pdbc->herr, en_IM004 );
-       
-                               return SQL_ERROR;
-                       }
-       
-                       /* insert into dll env list */
-                       penv->next = (ENV_t FAR*)genv->henv;
-                       genv->henv = penv;
-       
-                       /* initiate this new env entry */
-                       penv->refcount = 0;     /* we will increase it after
-                                                * driver's SQLAllocConnect()
-                                                * success
-                                                */
-               }
-       
-               pdbc->henv = penv;
-       
-               if( pdbc->dhdbc == SQL_NULL_HDBC )
-               {
-#if (ODBCVER >= 0x0300)
-                       hproc = _iodbcdm_getproc( hdbc, en_AllocHandle );
-
-                       if( hproc )
-                       {
-                               CALL_DRIVER( hdbc, retcode, hproc, en_AllocHandle,
-                               (SQL_HANDLE_DBC, penv->dhenv, &(pdbc->dhdbc)) )
-                       }
-                       else
-#endif
-                       {
-                               hproc = _iodbcdm_getproc( hdbc, en_AllocConnect );
-       
-                               if( hproc == SQL_NULL_HPROC )
-                               {
-                                       sqlstat = en_IM005;
-                               }
-                               else
-                               {
-                                       CALL_DRIVER ( hdbc, retcode, hproc, 
-                                       en_AllocConnect, (penv->dhenv, &(pdbc->dhdbc)) )
-                               }
-                       }
-
-                       if( retcode == SQL_ERROR )
-                       {
-                               sqlstat = en_IM005;
-                       }
-
-                       if( sqlstat != en_00000 )
-                       {
-                               _iodbcdm_driverunload(hdbc);
-       
-                               pdbc->dhdbc = SQL_NULL_HDBC;
-                               PUSHSQLERR ( pdbc->herr, en_IM005 );
-       
-                               return SQL_ERROR;
-                       }
-               }
-       
-               pdbc->henv = penv;
-               penv->refcount ++;  /* bookkeeping reference count on this driver */
+         /* 
+          * this will not unload the driver but only decrease its internal
+          * reference count 
+          */
+         _iodbcdm_dllclose (hdll);
        }
+    }
 
-       /* driver's login timeout option must been set before 
-        * its SQLConnect() call */
-       if( pdbc->login_timeout != 0UL )
+  if (penv == NULL)
+    {
+      /* 
+       * find out whether this dll has already been loaded on another 
+       * connection 
+       */
+      for (penv = (ENV_t FAR *) genv->henv; 
+         penv != NULL;
+         penv = (ENV_t FAR *) penv->next)
        {
-               hproc = _iodbcdm_getproc( hdbc, en_SetConnectOption );
-
-               if( hproc == SQL_NULL_HPROC )
-               {
-                       sqlstat = en_IM004;
-               }
-               else
-               {
-                       CALL_DRIVER ( hdbc, retcode, hproc, 
-                       en_SetConnectOption, ( 
-                               pdbc->dhdbc, 
-                               SQL_LOGIN_TIMEOUT,
-                               pdbc->login_timeout ) )
-               
-                       if( retcode == SQL_ERROR )
-                       {
-                               PUSHSQLERR ( pdbc->herr, en_IM006 );
-
-                               return SQL_SUCCESS_WITH_INFO;
-                       }
-               }
+         if (penv->hdll == hdll)
+           {
+             /* 
+              * this will not unload the driver but only decrease its internal
+              * reference count 
+              */
+             _iodbcdm_dllclose (hdll);
+             break;
+           }
        }
 
-       return SQL_SUCCESS;
-}
-
-RETCODE        _iodbcdm_driverunload( HDBC     hdbc )
-/* - Call driver's SQLFreeConnect()
- * - Call driver's SQLFreeEnv() ( for the last reference only)
- * - Unload the share library( or decrease its reference
- *   count if it is not the last referenct )
- * - decrease bookkeeping reference count
- * - state transition to allocated
- */
-{
-       DBC_t  FAR*     pdbc = (DBC_t FAR*)hdbc;
-       ENV_t  FAR*     penv;
-       ENV_t  FAR*     tpenv;
-       GENV_t FAR*     genv;
-       HPROC           hproc;
-       RETCODE         retcode = SQL_SUCCESS;
-/*     int             sqlstat = en_00000; */
-
-       if( hdbc == SQL_NULL_HDBC )
+      if (penv == NULL)
+       /* no connection attaching with this dll */
        {
-               return SQL_INVALID_HANDLE;
-       }
+         int i;
 
-       /* no pointer check will be performed in this function */
-       penv = (ENV_t  FAR*)pdbc->henv;
-       genv = (GENV_t FAR*)pdbc->genv;
+         /* create a new dll env instance */
+         penv = (ENV_t FAR *) MEM_ALLOC (sizeof (ENV_t));
 
-       if( penv == NULL 
-        || penv->hdll == SQL_NULL_HDLL )
-       {
-               return SQL_SUCCESS;
-       }
+         if (penv == NULL)
+           {
+             _iodbcdm_dllclose (hdll);
 
-#if (ODBCVER >= 0x0300)
-       hproc = _iodbcdm_getproc( hdbc, en_FreeHandle );
+             PUSHSQLERR (pdbc->herr, en_S1001);
 
-       if( hproc )
-       {
-               CALL_DRIVER ( hdbc, retcode, hproc, en_FreeHandle,
-                       ( SQL_HANDLE_DBC, pdbc->dhdbc ) )
-       }
-       else
-#endif
-       {
-               hproc = _iodbcdm_getproc( hdbc, en_FreeConnect );
+             return SQL_ERROR;
+           }
 
-               if( hproc != SQL_NULL_HPROC )
-               {
-                       CALL_DRIVER ( hdbc, retcode, hproc, 
-                       en_FreeConnect, ( pdbc->dhdbc ) )
+         for (i = 0; i < SQL_EXT_API_LAST + 1; i++)
+           {
+             (penv->dllproc_tab)[i] = SQL_NULL_HPROC;
+           }
 
-                       pdbc->dhdbc = SQL_NULL_HDBC;
-               }
-       }
+         pdbc->henv = penv;
+         penv->hdll = hdll;
 
-       penv->refcount --;
+         /* call driver's SQLAllocHandle() or SQLAllocEnv() */
 
-       if( ! penv->refcount )
-       /* no other connections still attaching with this driver */
-       {
 #if (ODBCVER >= 0x0300)
-               hproc = _iodbcdm_getproc( hdbc, en_FreeHandle );
+         hproc = _iodbcdm_getproc (hdbc, en_AllocHandle);
+
+         if (hproc)
+           {
+             CALL_DRIVER (hdbc, retcode, hproc, en_AllocHandle,
+                 (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(penv->dhenv)))
+           }
+         else                  /* try driver's SQLAllocEnv() */
+#endif
+           {
+             hproc = _iodbcdm_getproc (hdbc, en_AllocEnv);
 
-               if( hproc )
+             if (hproc == SQL_NULL_HPROC)
                {
-                       CALL_DRIVER ( hdbc, retcode, hproc, en_FreeHandle,
-                               ( SQL_HANDLE_ENV, penv->dhenv ) )
+                 sqlstat = en_IM004;
                }
-               else
-#endif
+             else
                {
-                       hproc = _iodbcdm_getproc( hdbc, en_FreeEnv );
-
-                       if( hproc != SQL_NULL_HPROC )
-                       {
-                               CALL_DRIVER ( hdbc, retcode, hproc, en_FreeEnv, 
-                                               ( penv->dhenv ) )
-
-                               penv->dhenv = SQL_NULL_HENV;
-                       }
+                 CALL_DRIVER (hdbc, retcode, hproc,
+                     en_AllocEnv, (&(penv->dhenv)))
                }
-
-               _iodbcdm_dllclose ( penv->hdll );
-
-               penv->hdll = SQL_NULL_HDLL; 
-
-               for( tpenv  = (ENV_t FAR*)genv->henv;
-                    tpenv != NULL;
-                    tpenv  = (ENV_t FAR*)penv->next )
-               {
-                       if( tpenv == penv )
-                       {
-                               genv->henv = penv->next;
-                               break;
-                       }
-       
-                       if( tpenv->next == penv )
-                       {
-                               tpenv->next = penv->next;
-                               break;
-                       }
-               }
-
-               MEM_FREE( penv );
-       }
-
-       pdbc->henv = SQL_NULL_HENV;     
-       pdbc->hstmt= SQL_NULL_HSTMT;
-       /* pdbc->herr = SQL_NULL_HERR; 
-               -- delay to DM's SQLFreeConnect() */ 
-       pdbc->dhdbc= SQL_NULL_HDBC;     
-       pdbc->state= en_dbc_allocated;  
-
-       /* set connect options to default values */
-       /**********
-       pdbc->access_mode       = SQL_MODE_DEFAULT;
-       pdbc->autocommit        = SQL_AUTOCOMMIT_DEFAULT;
-       pdbc->login_timeout     = 0UL;
-       **********/
-       pdbc->odbc_cursors      = SQL_CUR_DEFAULT;
-       pdbc->packet_size       = 0UL;
-       pdbc->quiet_mode        = (UDWORD)NULL;
-       pdbc->txn_isolation     = SQL_TXN_READ_UNCOMMITTED;
-
-       if( pdbc->current_qualifier != NULL )
-       {
-               MEM_FREE ( pdbc->current_qualifier );
-               pdbc->current_qualifier = NULL;
+           }
+
+         if (retcode == SQL_ERROR)
+           {
+             sqlstat = en_IM004;
+           }
+
+         if (sqlstat != en_00000)
+           {
+             _iodbcdm_dllclose (hdll);
+             MEM_FREE (penv);
+             PUSHSQLERR (pdbc->herr, en_IM004);
+
+             return SQL_ERROR;
+           }
+
+         /* insert into dll env list */
+         penv->next = (ENV_t FAR *) genv->henv;
+         genv->henv = penv;
+
+         /* initiate this new env entry */
+         penv->refcount = 0;   /* we will increase it after
+                                * driver's SQLAllocConnect()
+                                * success
+                                */
        }
 
-       return SQL_SUCCESS;
-}
-
-static RETCODE _iodbcdm_dbcdelayset( HDBC hdbc )
-{
-       DBC_t FAR*      pdbc    = (DBC_t FAR*)hdbc;
-       ENV_t FAR*      penv;
-       HPROC           hproc;
-       RETCODE         retcode = SQL_SUCCESS;
-       RETCODE         ret;
-
-       penv = pdbc->henv;
-
-       hproc = _iodbcdm_getproc( hdbc, en_SetConnectOption );
+      pdbc->henv = penv;
 
-       if( hproc == SQL_NULL_HPROC )
+      if (pdbc->dhdbc == SQL_NULL_HDBC)
        {
-               PUSHSQLERR ( pdbc->herr, en_IM006 );
-
-               return SQL_SUCCESS_WITH_INFO;
-       }
 
-       if( pdbc->access_mode != SQL_MODE_DEFAULT )
-       {
-               CALL_DRIVER ( hdbc, ret, hproc, 
-                       en_SetConnectOption, ( 
-                               SQL_ACCESS_MODE, 
-                               pdbc->access_mode) )
-
-               retcode |= ret;
-       }
+#if (ODBCVER >= 0x0300)
+         hproc = _iodbcdm_getproc (hdbc, en_AllocHandle);
+
+         if (hproc)
+           {
+             CALL_DRIVER (hdbc, retcode, hproc, en_AllocHandle,
+                 (SQL_HANDLE_DBC, penv->dhenv, &(pdbc->dhdbc)))
+           }
+         else
+#endif
 
-       if( pdbc->autocommit != SQL_AUTOCOMMIT_DEFAULT )
-       {
-               CALL_DRIVER ( hdbc, ret, hproc, 
-                       en_SetConnectOption, (
-                               pdbc->dhdbc,
-                               SQL_AUTOCOMMIT,
-                               pdbc->autocommit ) )
+           {
+             hproc = _iodbcdm_getproc (hdbc, en_AllocConnect);
 
-               retcode |= ret;
-       }
+             if (hproc == SQL_NULL_HPROC)
+               {
+                 sqlstat = en_IM005;
+               }
+             else
+               {
+                 CALL_DRIVER (hdbc, retcode, hproc,
+                     en_AllocConnect, (penv->dhenv, &(pdbc->dhdbc)))
+               }
+           }
 
-       if( pdbc->current_qualifier != NULL )
-       {
-               CALL_DRIVER ( hdbc, ret, hproc, 
-                       en_SetConnectOption, (
-                               pdbc->dhdbc,
-                               SQL_CURRENT_QUALIFIER,
-                               pdbc->current_qualifier ) )
+         if (retcode == SQL_ERROR)
+           {
+             sqlstat = en_IM005;
+           }
 
-               retcode |= ret;
-       }
+         if (sqlstat != en_00000)
+           {
+             _iodbcdm_driverunload (hdbc);
 
-       if( pdbc->packet_size != 0UL )
-       {
-               CALL_DRIVER ( hdbc, ret, hproc,
-                       en_SetConnectOption, (
-                               pdbc->dhdbc,
-                               SQL_PACKET_SIZE,
-                               pdbc->packet_size ) )
+             pdbc->dhdbc = SQL_NULL_HDBC;
+             PUSHSQLERR (pdbc->herr, en_IM005);
 
-               retcode |= ret;
+             return SQL_ERROR;
+           }
        }
 
-       if( pdbc->quiet_mode != (UDWORD)NULL )
-       {
-               CALL_DRIVER ( hdbc, ret, hproc, 
-                       en_SetConnectOption, (
-                               pdbc->dhdbc,
-                               SQL_QUIET_MODE,
-                               pdbc->quiet_mode ) )
+      pdbc->henv = penv;
+      penv->refcount++;                /* bookkeeping reference count on this driver */
+    }
 
-               retcode |= ret;
-       }
+  /* driver's login timeout option must been set before 
+   * its SQLConnect() call */
+  if (pdbc->login_timeout != 0UL)
+    {
+      hproc = _iodbcdm_getproc (hdbc, en_SetConnectOption);
 
-       if( pdbc->txn_isolation != SQL_TXN_READ_UNCOMMITTED )
+      if (hproc == SQL_NULL_HPROC)
        {
-               CALL_DRIVER ( hdbc, ret, hproc,
-                       en_SetConnectOption, (
-                               pdbc->dhdbc,
-                               SQL_TXN_ISOLATION,
-                               pdbc->txn_isolation ) )
+         sqlstat = en_IM004;
        }
-
-       /* check error code for driver's SQLSetConnectOption() call */
-       if( retcode != SQL_SUCCESS 
-        && retcode != SQL_SUCCESS_WITH_INFO )
+      else
        {
-               PUSHSQLERR ( pdbc->herr, en_IM006 );
+         CALL_DRIVER (hdbc, retcode, hproc,
+             en_SetConnectOption, (
+                 pdbc->dhdbc,
+                 SQL_LOGIN_TIMEOUT,
+                 pdbc->login_timeout))
 
-               retcode = SQL_ERROR;
-       }
-
-       /* get cursor behavior on transaction commit or rollback */
-       hproc = _iodbcdm_getproc( hdbc, en_GetInfo );
-
-       if( hproc == SQL_NULL_HPROC )
-       {
-               PUSHSQLERR ( pdbc->herr, en_01000 );
+             if (retcode == SQL_ERROR)
+           {
+             PUSHSQLERR (pdbc->herr, en_IM006);
 
-               return retcode;
+             return SQL_SUCCESS_WITH_INFO;
+           }
        }
+    }
 
-       CALL_DRIVER ( hdbc, ret, hproc,
-               en_GetInfo, (
-                       pdbc->dhdbc, 
-                       SQL_CURSOR_COMMIT_BEHAVIOR,
-                       (PTR)&(pdbc->cb_commit),
-                       sizeof(pdbc->cb_commit),
-                       NULL ) )
-
-       retcode |= ret;
-
-       CALL_DRIVER ( hdbc, ret, hproc,
-               en_GetInfo, (
-                       pdbc->dhdbc,
-                       SQL_CURSOR_ROLLBACK_BEHAVIOR,
-                       (PTR)&(pdbc->cb_rollback),
-                       sizeof(pdbc->cb_rollback),
-                       NULL ) )
-
-       retcode |= ret;
-
-       if( retcode != SQL_SUCCESS
-        && retcode != SQL_SUCCESS_WITH_INFO )
-       {
-               return SQL_ERROR;
-       }
-
-       return retcode;
+  return SQL_SUCCESS;
 }
 
-static RETCODE _iodbcdm_settracing( HDBC hdbc, char* dsn, int dsnlen )
-{
-       char    buf[256];
-       char*   ptr;
-       RETCODE setopterr = SQL_SUCCESS;
-
-       /* Get Driver's DLL path from specificed or default dsn section */
-       ptr = _iodbcdm_getkeyvalbydsn( dsn, dsnlen, "TraceFile",
-                               (char FAR*)buf, sizeof(buf));
-
-       if( ptr == NULL || ptr[0] == '\0' )
-       {
-               ptr = (char FAR*)(SQL_OPT_TRACE_FILE_DEFAULT);
-       }
-
-       setopterr |= SQLSetConnectOption( hdbc, 
-               SQL_OPT_TRACEFILE, (UDWORD)(ptr));
-
-       ptr = _iodbcdm_getkeyvalbydsn( dsn, dsnlen, "Trace",
-                               (char FAR*)buf, sizeof(buf));
-
-       if( ptr != NULL )
-       {
-               UDWORD  opt = (UDWORD)(-1L);
-
-               if( STREQ(ptr, "ON") 
-                || STREQ(ptr, "On") 
-                || STREQ(ptr, "on") 
-                || STREQ(ptr, "1" ) )
-               {
-                       opt = SQL_OPT_TRACE_ON;
-               }
-
-               if( STREQ(ptr, "OFF") 
-                || STREQ(ptr, "Off")
-                || STREQ(ptr, "off") 
-                || STREQ(ptr, "0"  ) )
-               {
-                       opt = SQL_OPT_TRACE_OFF;
-               }
-
-               if( opt != (UDWORD)(-1L) )
-               {
-                       setopterr |= SQLSetConnectOption( hdbc, 
-                               SQL_OPT_TRACE, opt);
-               }
-       }
 
-    return setopterr;
-}
-
-RETCODE SQL_API        SQLConnect (
-                       HDBC            hdbc,
-                       UCHAR FAR*      szDSN,
-                       SWORD           cbDSN,
-                       UCHAR FAR*      szUID,
-                       SWORD           cbUID,
-                       UCHAR FAR*      szAuthStr,
-                       SWORD           cbAuthStr)
+/* - Call driver's SQLFreeConnect()
+ * - Call driver's SQLFreeEnv() ( for the last reference only)
+ * - Unload the share library( or decrease its reference
+ *   count if it is not the last referenct )
+ * - decrease bookkeeping reference count
+ * - state transition to allocated
+ */
+RETCODE 
+_iodbcdm_driverunload (HDBC hdbc)
 {
-       DBC_t  FAR*     pdbc    = (DBC_t FAR*)hdbc;
-       RETCODE         retcode = SQL_SUCCESS;
-       RETCODE         setopterr = SQL_SUCCESS;
-       char            driver[1024] = { '\0' }; /* MS SDK Guide 
-                                                 * specifies driver
-                                                 * path can't longer
-                                                 * than 255. */
-       char            *ptr;
-       HPROC           hproc;
-       
-       if( hdbc == SQL_NULL_HDBC )
-       {
-               return SQL_INVALID_HANDLE;
-       }
-
-       /* check arguments */
-       if( ( cbDSN < 0 && cbDSN != SQL_NTS )
-        || ( cbUID < 0 && cbUID != SQL_NTS )
-        || ( cbAuthStr < 0 && cbAuthStr != SQL_NTS )
-        || ( cbDSN > SQL_MAX_DSN_LENGTH ) )
-       {
-               PUSHSQLERR ( pdbc->herr, en_S1090 );
+  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
+  ENV_t FAR *penv;
+  ENV_t FAR *tpenv;
+  GENV_t FAR *genv;
+  HPROC hproc;
+  RETCODE retcode = SQL_SUCCESS;
+
+  if (hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  /* no pointer check will be performed in this function */
+  penv = (ENV_t FAR *) pdbc->henv;
+  genv = (GENV_t FAR *) pdbc->genv;
+
+  if (penv == NULL || penv->hdll == SQL_NULL_HDLL)
+    {
+      return SQL_SUCCESS;
+    }
 
-               return SQL_ERROR;
-       }
+#if (ODBCVER >= 0x0300)
+  hproc = _iodbcdm_getproc (hdbc, en_FreeHandle);
+
+  if (hproc)
+    {
+      CALL_DRIVER (hdbc, retcode, hproc, en_FreeHandle,
+         (SQL_HANDLE_DBC, pdbc->dhdbc))
+    }
+  else
+#endif
 
-       if( szDSN == NULL || cbDSN == 0 )
-       {
-               PUSHSQLERR ( pdbc->herr, en_IM002 );
-               
-               return SQL_ERROR;
-       }
+    {
+      hproc = _iodbcdm_getproc (hdbc, en_FreeConnect);
 
-       /* check state */
-       if( pdbc->state != en_dbc_allocated )
+      if (hproc != SQL_NULL_HPROC)
        {
-               PUSHSQLERR ( pdbc->herr, en_08002 );
+         CALL_DRIVER (hdbc, retcode, hproc,
+             en_FreeConnect, (pdbc->dhdbc))
 
-               return SQL_ERROR;
+             pdbc->dhdbc = SQL_NULL_HDBC;
        }
+    }
 
-       setopterr |= _iodbcdm_settracing( hdbc, 
-                               (char*)szDSN, cbDSN );
-
-       ptr = _iodbcdm_getkeyvalbydsn( szDSN, cbDSN, "Driver", 
-                               (char FAR*)driver, sizeof(driver));
+  penv->refcount--;
 
-       if( ptr == NULL )
-       /* No specified or default dsn section or
-        * no driver specification in this dsn section */
-       {
-               PUSHSQLERR ( pdbc->herr, en_IM002 );
-
-               return SQL_ERROR;
-       }
+  if (!penv->refcount)
+    /* no other connections still attaching with this driver */
+    {
 
-       retcode = _iodbcdm_driverload( driver, hdbc );
+#if (ODBCVER >= 0x0300)
+      hproc = _iodbcdm_getproc (hdbc, en_FreeHandle);
 
-       switch( retcode )
+      if (hproc)
        {
-               case SQL_SUCCESS:
-                       break;
-
-               case SQL_SUCCESS_WITH_INFO:
-                       setopterr = SQL_ERROR;
-                       /* unsuccessed in calling driver's 
-                        * SQLSetConnectOption() to set login
-                        * timeout.
-                        */
-                       break;
-
-               default:
-                       return retcode;
+         CALL_DRIVER (hdbc, retcode, hproc, en_FreeHandle,
+             (SQL_HANDLE_ENV, penv->dhenv))
        }
+      else
+#endif
 
-       hproc = _iodbcdm_getproc( hdbc, en_Connect );
-
-       if( hproc == SQL_NULL_HPROC )
        {
-               _iodbcdm_driverunload( hdbc );
+         hproc = _iodbcdm_getproc (hdbc, en_FreeEnv);
 
-               PUSHSQLERR ( pdbc->herr, en_IM001 );
+         if (hproc != SQL_NULL_HPROC)
+           {
+             CALL_DRIVER (hdbc, retcode, hproc, en_FreeEnv,
+                 (penv->dhenv))
 
-               return SQL_ERROR;
+                 penv->dhenv = SQL_NULL_HENV;
+           }
        }
 
-       CALL_DRIVER ( hdbc, retcode, hproc, en_Connect, (
-                       pdbc->dhdbc, 
-                       szDSN,     cbDSN,
-                       szUID,     cbUID,
-                       szAuthStr, cbAuthStr ) )
-
-#if 0
-       retcode = hproc(pdbc->dhdbc, 
-                       szDSN,     cbDSN,
-                       szUID,     cbUID,
-                       szAuthStr, cbAuthStr );
-#endif
+      _iodbcdm_dllclose (penv->hdll);
+
+      penv->hdll = SQL_NULL_HDLL;
 
-       if( retcode != SQL_SUCCESS 
-        && retcode != SQL_SUCCESS_WITH_INFO )
+      for (tpenv = (ENV_t FAR *) genv->henv;
+         tpenv != NULL;
+         tpenv = (ENV_t FAR *) penv->next)
        {
-               /* not unload driver for retrive error 
-                * messge from driver */
-               /*********
-               _iodbcdm_driverunload( hdbc );
-               **********/
+         if (tpenv == penv)
+           {
+             genv->henv = penv->next;
+             break;
+           }
 
-               return retcode;
+         if (tpenv->next == penv)
+           {
+             tpenv->next = penv->next;
+             break;
+           }
        }
 
-       /* state transition */
-       pdbc->state = en_dbc_connected;
+      MEM_FREE (penv);
+    }
 
-       /* do delaid option setting */
-       setopterr |= _iodbcdm_dbcdelayset( hdbc );
+  pdbc->henv = SQL_NULL_HENV;
+  pdbc->hstmt = SQL_NULL_HSTMT;
+  /* pdbc->herr = SQL_NULL_HERR; 
+     -- delay to DM's SQLFreeConnect() */
+  pdbc->dhdbc = SQL_NULL_HDBC;
+  pdbc->state = en_dbc_allocated;
 
-       if( setopterr != SQL_SUCCESS )
-       {
-               return SQL_SUCCESS_WITH_INFO;
-       }
-
-       return retcode;
+  /* set connect options to default values */
+       /**********
+       pdbc->access_mode       = SQL_MODE_DEFAULT;
+       pdbc->autocommit        = SQL_AUTOCOMMIT_DEFAULT;
+       pdbc->login_timeout     = 0UL;
+       **********/
+  pdbc->odbc_cursors = SQL_CUR_DEFAULT;
+  pdbc->packet_size = 0UL;
+  pdbc->quiet_mode = (UDWORD) NULL;
+  pdbc->txn_isolation = SQL_TXN_READ_UNCOMMITTED;
+
+  if (pdbc->current_qualifier != NULL)
+    {
+      MEM_FREE (pdbc->current_qualifier);
+      pdbc->current_qualifier = NULL;
+    }
+
+  return SQL_SUCCESS;
 }
-       
-RETCODE SQL_API        SQLDriverConnect (
-                       HDBC            hdbc,
-                       HWND            hwnd,
-                       UCHAR FAR*      szConnStrIn,
-                       SWORD           cbConnStrIn,
-                       UCHAR FAR*      szConnStrOut,
-                       SWORD           cbConnStrOutMax,
-                       SWORD FAR*      pcbConnStrOut,
-                       UWORD           fDriverCompletion )
-{
-       DBC_t FAR*      pdbc    = (DBC_t FAR*)hdbc;
-       HDLL            hdll;
-       char  FAR*      drv;
-       char            drvbuf[1024];
-       char  FAR*      dsn;
-       char            dsnbuf[SQL_MAX_DSN_LENGTH + 1];
-       UCHAR           cnstr2drv[1024];
 
-       HPROC           hproc, dialproc;
 
-       int             sqlstat = en_00000;
-       RETCODE         retcode = SQL_SUCCESS;
-       RETCODE         setopterr = SQL_SUCCESS;
+static RETCODE 
+_iodbcdm_dbcdelayset (HDBC hdbc)
+{
+  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
+  ENV_t FAR *penv;
+  HPROC hproc;
+  RETCODE retcode = SQL_SUCCESS;
+  RETCODE ret;
+
+  penv = pdbc->henv;
+
+  hproc = _iodbcdm_getproc (hdbc, en_SetConnectOption);
+
+  if (hproc == SQL_NULL_HPROC)
+    {
+      PUSHSQLERR (pdbc->herr, en_IM006);
+
+      return SQL_SUCCESS_WITH_INFO;
+    }
+
+  if (pdbc->access_mode != SQL_MODE_DEFAULT)
+    {
+      CALL_DRIVER (hdbc, ret, hproc,
+         en_SetConnectOption, (
+             SQL_ACCESS_MODE,
+             pdbc->access_mode))
+
+         retcode |= ret;
+    }
+
+  if (pdbc->autocommit != SQL_AUTOCOMMIT_DEFAULT)
+    {
+      CALL_DRIVER (hdbc, ret, hproc,
+         en_SetConnectOption, (
+             pdbc->dhdbc,
+             SQL_AUTOCOMMIT,
+             pdbc->autocommit))
+
+         retcode |= ret;
+    }
+
+  if (pdbc->current_qualifier != NULL)
+    {
+      CALL_DRIVER (hdbc, ret, hproc,
+         en_SetConnectOption, (
+             pdbc->dhdbc,
+             SQL_CURRENT_QUALIFIER,
+             pdbc->current_qualifier))
+
+         retcode |= ret;
+    }
+
+  if (pdbc->packet_size != 0UL)
+    {
+      CALL_DRIVER (hdbc, ret, hproc,
+         en_SetConnectOption, (
+             pdbc->dhdbc,
+             SQL_PACKET_SIZE,
+             pdbc->packet_size))
+
+         retcode |= ret;
+    }
+
+  if (pdbc->quiet_mode != (UDWORD) NULL)
+    {
+      CALL_DRIVER (hdbc, ret, hproc,
+         en_SetConnectOption, (
+             pdbc->dhdbc,
+             SQL_QUIET_MODE,
+             pdbc->quiet_mode))
+
+         retcode |= ret;
+    }
+
+  if (pdbc->txn_isolation != SQL_TXN_READ_UNCOMMITTED)
+    {
+      CALL_DRIVER (hdbc, ret, hproc,
+         en_SetConnectOption, (
+             pdbc->dhdbc,
+             SQL_TXN_ISOLATION,
+             pdbc->txn_isolation))
+    }
+
+  /* check error code for driver's SQLSetConnectOption() call */
+  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+    {
+      PUSHSQLERR (pdbc->herr, en_IM006);
+
+      retcode = SQL_ERROR;
+    }
+
+  /* get cursor behavior on transaction commit or rollback */
+  hproc = _iodbcdm_getproc (hdbc, en_GetInfo);
+
+  if (hproc == SQL_NULL_HPROC)
+    {
+      PUSHSQLERR (pdbc->herr, en_01000);
+
+      return retcode;
+    }
+
+  CALL_DRIVER (hdbc, ret, hproc,
+      en_GetInfo, (
+         pdbc->dhdbc,
+         SQL_CURSOR_COMMIT_BEHAVIOR,
+         (PTR) & (pdbc->cb_commit),
+         sizeof (pdbc->cb_commit),
+         NULL))
+
+      retcode |= ret;
+
+  CALL_DRIVER (hdbc, ret, hproc,
+      en_GetInfo, (
+         pdbc->dhdbc,
+         SQL_CURSOR_ROLLBACK_BEHAVIOR,
+         (PTR) & (pdbc->cb_rollback),
+         sizeof (pdbc->cb_rollback),
+         NULL))
+
+      retcode |= ret;
+
+  if (retcode != SQL_SUCCESS
+      && retcode != SQL_SUCCESS_WITH_INFO)
+    {
+      return SQL_ERROR;
+    }
+
+  return retcode;
+}
 
-       if( hdbc == SQL_NULL_HDBC )
-       {
-               return SQL_INVALID_HANDLE;
-       }
 
-       /* check arguments */
-       if( ( cbConnStrIn < 0 && cbConnStrIn != SQL_NTS )
-        || cbConnStrOutMax < 0 )
-       {
-               PUSHSQLERR (pdbc->herr, en_S1090 );
+static RETCODE 
+_iodbcdm_settracing (HDBC hdbc, char *dsn, int dsnlen)
+{
+  char buf[256];
+  char *ptr;
+  RETCODE setopterr = SQL_SUCCESS;
 
-               return SQL_ERROR;
-       }
+  /* Get Driver's DLL path from specificed or default dsn section */
+  ptr = _iodbcdm_getkeyvalbydsn (dsn, dsnlen, "TraceFile",
+      (char FAR *) buf, sizeof (buf));
 
-       /* check state */
-       if( pdbc->state != en_dbc_allocated )
-       {
-               PUSHSQLERR (pdbc->herr, en_08002 );
+  if (ptr == NULL || ptr[0] == '\0')
+    {
+      ptr = (char FAR *) (SQL_OPT_TRACE_FILE_DEFAULT);
+    }
 
-               return SQL_ERROR;
-       }
+  setopterr |= SQLSetConnectOption (hdbc, SQL_OPT_TRACEFILE, (UDWORD) (ptr));
 
-       drv = _iodbcdm_getkeyvalinstr(szConnStrIn, cbConnStrIn, 
-                               "DRIVER", drvbuf, sizeof(drvbuf));
+  ptr = _iodbcdm_getkeyvalbydsn (dsn, dsnlen, "Trace",
+      (char FAR *) buf, sizeof (buf));
 
-       dsn = _iodbcdm_getkeyvalinstr(szConnStrIn, cbConnStrIn,
-                               "DSN",    dsnbuf, sizeof(dsnbuf));
+  if (ptr != NULL)
+    {
+      UDWORD opt = (UDWORD) (-1L);
 
-       switch( fDriverCompletion )
+      if (STREQ (ptr, "ON")
+         || STREQ (ptr, "On")
+         || STREQ (ptr, "on")
+         || STREQ (ptr, "1"))
        {
-               case SQL_DRIVER_NOPROMPT:
-                       break;
-
-               case SQL_DRIVER_COMPLETE:
-               case SQL_DRIVER_COMPLETE_REQUIRED:
-                       if( dsn != NULL )
-                       {
-                               break;
-                       }
-                       /* fall to next case */
-               case SQL_DRIVER_PROMPT:
-                       /* Get data source dialog box function from
-                        * current executable */
-                       hdll = _iodbcdm_dllopen((char FAR*)NULL);
-                       dialproc = _iodbcdm_dllproc( hdll, 
-                                       "_iodbcdm_drvconn_dialbox");
-
-                       if( dialproc == SQL_NULL_HPROC )
-                       {
-                               sqlstat = en_IM008;
-                               break;
-                       }
-
-                       retcode = dialproc( 
-                                       hwnd,   /* window or display handle */
-                                       dsnbuf, /* input/output dsn buf */
-                                       sizeof(dsnbuf), /* buf size */
-                                       &sqlstat);      /* error code */
-
-                       if( retcode != SQL_SUCCESS )
-                       {
-                               break;
-                       }
-                       
-                       if( cbConnStrIn == SQL_NTS )
-                       {
-                               cbConnStrIn = STRLEN(szConnStrIn );
-                       }
-
-                       dsn = dsnbuf;
-
-                       if( dsn[0] == '\0' )
-                       {
-                               dsn = "default";
-                       }
-
-                       if( cbConnStrIn > sizeof(cnstr2drv) 
-                                       - STRLEN(dsn) - STRLEN("DSN=;") -1 )
-                       {
-                               sqlstat = en_S1001; /* a lazy way to avoid
-                                                    * using heap memory */
-                               break;
-                       }
-
-                       sprintf( (char FAR *)cnstr2drv, "DSN=%s;", dsn);
-                       cbConnStrIn += STRLEN(cnstr2drv);
-                       STRNCAT( cnstr2drv, szConnStrIn, cbConnStrIn );
-                       szConnStrIn = cnstr2drv;
-                       break;
-
-               default:
-                       sqlstat = en_S1110;
-                       break;
+         opt = SQL_OPT_TRACE_ON;
        }
 
-       if( sqlstat != en_00000 )
+      if (STREQ (ptr, "OFF")
+         || STREQ (ptr, "Off")
+         || STREQ (ptr, "off")
+         || STREQ (ptr, "0"))
        {
-               PUSHSQLERR( pdbc->herr, sqlstat );
-               
-               return SQL_ERROR;
+         opt = SQL_OPT_TRACE_OFF;
        }
 
-       if( dsn == NULL || dsn[0] == '\0' )
-       {
-               dsn = "default";
-       }
-       else    /* if you want tracing, you must use a DSN */
+      if (opt != (UDWORD) (-1L))
        {
-               setopterr |= _iodbcdm_settracing( hdbc, 
-                                       (char*)dsn, SQL_NTS );
+         setopterr |= SQLSetConnectOption (hdbc,
+             SQL_OPT_TRACE, opt);
        }
+    }
 
-       if( drv == NULL || drv[0] == '\0' )
-       {
-               drv = _iodbcdm_getkeyvalbydsn( dsn, SQL_NTS, "Driver", 
-                                       drvbuf, sizeof(drvbuf));
-       }
+  return setopterr;
+}
 
-       if( drv == NULL )
-       {
-               PUSHSQLERR( pdbc->herr, en_IM002 );
 
-               return SQL_ERROR;
-       }
+RETCODE SQL_API 
+SQLConnect (
+    HDBC hdbc,
+    UCHAR FAR * szDSN,
+    SWORD cbDSN,
+    UCHAR FAR * szUID,
+    SWORD cbUID,
+    UCHAR FAR * szAuthStr,
+    SWORD cbAuthStr)
+{
+  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
+  RETCODE retcode = SQL_SUCCESS;
+  RETCODE setopterr = SQL_SUCCESS;
+  char driver[1024] = {'\0'};  /* MS SDK Guide 
+                                * specifies driver
+                                * path can't longer
+                                * than 255. */
+  char *ptr;
+  HPROC hproc;
+
+  if (hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  /* check arguments */
+  if ((cbDSN < 0 && cbDSN != SQL_NTS)
+      || (cbUID < 0 && cbUID != SQL_NTS)
+      || (cbAuthStr < 0 && cbAuthStr != SQL_NTS)
+      || (cbDSN > SQL_MAX_DSN_LENGTH))
+    {
+      PUSHSQLERR (pdbc->herr, en_S1090);
+
+      return SQL_ERROR;
+    }
+
+  if (szDSN == NULL || cbDSN == 0)
+    {
+      PUSHSQLERR (pdbc->herr, en_IM002);
+
+      return SQL_ERROR;
+    }
+
+  /* check state */
+  if (pdbc->state != en_dbc_allocated)
+    {
+      PUSHSQLERR (pdbc->herr, en_08002);
+
+      return SQL_ERROR;
+    }
+
+  setopterr |= _iodbcdm_settracing (hdbc,
+      (char *) szDSN, cbDSN);
+
+  ptr = _iodbcdm_getkeyvalbydsn (szDSN, cbDSN, "Driver",
+      (char FAR *) driver, sizeof (driver));
+
+  if (ptr == NULL)
+    /* No specified or default dsn section or
+     * no driver specification in this dsn section */
+    {
+      PUSHSQLERR (pdbc->herr, en_IM002);
+
+      return SQL_ERROR;
+    }
+
+  retcode = _iodbcdm_driverload (driver, hdbc);
+
+  switch (retcode)
+     {
+     case SQL_SUCCESS:
+       break;
+
+     case SQL_SUCCESS_WITH_INFO:
+       setopterr = SQL_ERROR;
+       /* unsuccessed in calling driver's 
+        * SQLSetConnectOption() to set login
+        * timeout.
+        */
+       break;
+
+     default:
+       return retcode;
+     }
+
+  hproc = _iodbcdm_getproc (hdbc, en_Connect);
+
+  if (hproc == SQL_NULL_HPROC)
+    {
+      _iodbcdm_driverunload (hdbc);
+
+      PUSHSQLERR (pdbc->herr, en_IM001);
+
+      return SQL_ERROR;
+    }
+
+  CALL_DRIVER (hdbc, retcode, hproc, en_Connect, (
+         pdbc->dhdbc,
+         szDSN, cbDSN,
+         szUID, cbUID,
+         szAuthStr, cbAuthStr))
+
+  if (retcode != SQL_SUCCESS
+      && retcode != SQL_SUCCESS_WITH_INFO)
+    {
+      /* not unload driver for retrive error 
+       * messge from driver */
+               /*********
+               _iodbcdm_driverunload( hdbc );
+               **********/
 
-       retcode = _iodbcdm_driverload( drv, hdbc );
+      return retcode;
+    }
 
-       switch( retcode )
-       {
-               case SQL_SUCCESS:
-                       break;
-
-               case SQL_SUCCESS_WITH_INFO:
-                       setopterr = SQL_ERROR;
-                       /* unsuccessed in calling driver's 
-                        * SQLSetConnectOption() to set login
-                        * timeout.
-                        */
-                       break;
-
-               default:
-                       return retcode;
-       }
+  /* state transition */
+  pdbc->state = en_dbc_connected;
 
-       hproc = _iodbcdm_getproc( hdbc, en_DriverConnect );
+  /* do delaid option setting */
+  setopterr |= _iodbcdm_dbcdelayset (hdbc);
 
-       if( hproc == SQL_NULL_HPROC )
-       {
-               _iodbcdm_driverunload( hdbc );
+  if (setopterr != SQL_SUCCESS)
+    {
+      return SQL_SUCCESS_WITH_INFO;
+    }
 
-               PUSHSQLERR ( pdbc->herr, en_IM001 );
+  return retcode;
+}
 
-               return SQL_ERROR;
-       }
-       
-       CALL_DRIVER ( hdbc, retcode, hproc, en_DriverConnect, (
-                       pdbc->dhdbc, hwnd,
-                       szConnStrIn, cbConnStrIn,
-                       szConnStrOut, cbConnStrOutMax,
-                       pcbConnStrOut, fDriverCompletion ) )
-
-#if 0
-       retcode = hproc(pdbc->dhdbc, hwnd,
-                       szConnStrIn, cbConnStrIn,
-                       szConnStrOut, cbConnStrOutMax,
-                       pcbConnStrOut, fDriverCompletion );
-#endif
 
-       if( retcode != SQL_SUCCESS 
-        && retcode != SQL_SUCCESS_WITH_INFO )
-       {
-               /* don't unload driver here for retrive 
-                * error message from driver */
+RETCODE SQL_API 
+SQLDriverConnect (
+    HDBC hdbc,
+    SQLHWND hwnd,
+    UCHAR FAR * szConnStrIn,
+    SWORD cbConnStrIn,
+    UCHAR FAR * szConnStrOut,
+    SWORD cbConnStrOutMax,
+    SWORD FAR * pcbConnStrOut,
+    UWORD fDriverCompletion)
+{
+  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
+  HDLL hdll;
+  char FAR *drv;
+  char drvbuf[1024];
+  char FAR *dsn;
+  char dsnbuf[SQL_MAX_DSN_LENGTH + 1];
+  UCHAR cnstr2drv[1024];
+
+  HPROC hproc;
+  HPROC dialproc;
+
+  int sqlstat = en_00000;
+  RETCODE retcode = SQL_SUCCESS;
+  RETCODE setopterr = SQL_SUCCESS;
+
+  if (hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  /* check arguments */
+  if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS)
+      || cbConnStrOutMax < 0)
+    {
+      PUSHSQLERR (pdbc->herr, en_S1090);
+
+      return SQL_ERROR;
+    }
+
+  /* check state */
+  if (pdbc->state != en_dbc_allocated)
+    {
+      PUSHSQLERR (pdbc->herr, en_08002);
+
+      return SQL_ERROR;
+    }
+
+  drv = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
+      "DRIVER", drvbuf, sizeof (drvbuf));
+
+  dsn = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
+      "DSN", dsnbuf, sizeof (dsnbuf));
+
+  switch (fDriverCompletion)
+     {
+     case SQL_DRIVER_NOPROMPT:
+       break;
+
+     case SQL_DRIVER_COMPLETE:
+     case SQL_DRIVER_COMPLETE_REQUIRED:
+       if (dsn != NULL || drv != NULL)
+        {
+          break;
+        }
+       /* fall to next case */
+     case SQL_DRIVER_PROMPT:
+       /* Get data source dialog box function from
+        * current executable */
+       hdll = _iodbcdm_dllopen ((char FAR *) NULL);
+       dialproc = _iodbcdm_dllproc (hdll,
+          "_iodbcdm_drvconn_dialbox");
+
+       if (dialproc == SQL_NULL_HPROC)
+        {
+          sqlstat = en_IM008;
+          break;
+        }
+
+       retcode = dialproc (
+          hwnd,                /* window or display handle */
+          dsnbuf,              /* input/output dsn buf */
+          sizeof (dsnbuf),     /* buf size */
+          &sqlstat);           /* error code */
+
+       if (retcode != SQL_SUCCESS)
+        {
+          break;
+        }
+
+       if (cbConnStrIn == SQL_NTS)
+        {
+          cbConnStrIn = STRLEN (szConnStrIn);
+        }
+
+       dsn = dsnbuf;
+
+       if (dsn[0] == '\0')
+        {
+          dsn = "default";
+        }
+
+       if (cbConnStrIn > sizeof (cnstr2drv)
+          - STRLEN (dsn) - STRLEN ("DSN=;") - 1)
+        {
+          sqlstat = en_S1001;  /* a lazy way to avoid
+                                * using heap memory */
+          break;
+        }
+
+       sprintf ((char*)cnstr2drv, "DSN=%s;", dsn);
+       cbConnStrIn += STRLEN (cnstr2drv);
+       STRNCAT (cnstr2drv, szConnStrIn, cbConnStrIn);
+       szConnStrIn = cnstr2drv;
+       break;
+
+     default:
+       sqlstat = en_S1110;
+       break;
+     }
+
+  if (sqlstat != en_00000)
+    {
+      PUSHSQLERR (pdbc->herr, sqlstat);
+
+      return SQL_ERROR;
+    }
+
+  if (dsn == NULL || dsn[0] == '\0')
+    {
+      dsn = "default";
+    }
+  else
+    /* if you want tracing, you must use a DSN */
+    {
+      setopterr |= _iodbcdm_settracing (hdbc,
+         (char *) dsn, SQL_NTS);
+    }
+
+  if (drv == NULL || drv[0] == '\0')
+    {
+      drv = _iodbcdm_getkeyvalbydsn (dsn, SQL_NTS, "Driver",
+         drvbuf, sizeof (drvbuf));
+    }
+
+  if (drv == NULL)
+    {
+      PUSHSQLERR (pdbc->herr, en_IM002);
+
+      return SQL_ERROR;
+    }
+
+  retcode = _iodbcdm_driverload (drv, hdbc);
+
+  switch (retcode)
+     {
+     case SQL_SUCCESS:
+       break;
+
+     case SQL_SUCCESS_WITH_INFO:
+       setopterr = SQL_ERROR;
+       /* unsuccessed in calling driver's 
+        * SQLSetConnectOption() to set login
+        * timeout.
+        */
+       break;
+
+     default:
+       return retcode;
+     }
+
+  hproc = _iodbcdm_getproc (hdbc, en_DriverConnect);
+
+  if (hproc == SQL_NULL_HPROC)
+    {
+      _iodbcdm_driverunload (hdbc);
+
+      PUSHSQLERR (pdbc->herr, en_IM001);
+
+      return SQL_ERROR;
+    }
+
+  CALL_DRIVER (hdbc, retcode, hproc, en_DriverConnect, (
+         pdbc->dhdbc, hwnd,
+         szConnStrIn, cbConnStrIn,
+         szConnStrOut, cbConnStrOutMax,
+         pcbConnStrOut, fDriverCompletion))
+
+  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+    {
+      /* don't unload driver here for retrive 
+       * error message from driver */
                /********
                _iodbcdm_driverunload( hdbc );
                *********/
 
-               return retcode;
-       }
+      return retcode;
+    }
 
-       /* state transition */
-       pdbc->state = en_dbc_connected;
+  /* state transition */
+  pdbc->state = en_dbc_connected;
 
-       /* do delaid option setting */
-       setopterr |= _iodbcdm_dbcdelayset( hdbc );
+  /* do delaid option setting */
+  setopterr |= _iodbcdm_dbcdelayset (hdbc);
 
-       if( setopterr != SQL_SUCCESS )
-       {
-               return SQL_SUCCESS_WITH_INFO;
-       }
+  if (setopterr != SQL_SUCCESS)
+    {
+      return SQL_SUCCESS_WITH_INFO;
+    }
 
-       return retcode;
+  return retcode;
 }
 
-RETCODE SQL_API        SQLBrowseConnect ( 
-                       HDBC            hdbc,
-                       HWND            hwnd,
-                       UCHAR FAR*      szConnStrIn,
-                       SWORD           cbConnStrIn,
-                       UCHAR FAR*      szConnStrOut,
-                       SWORD           cbConnStrOutMax,
-                       SWORD FAR*      pcbConnStrOut )
+
+RETCODE SQL_API 
+SQLBrowseConnect (
+    HDBC hdbc,
+    UCHAR FAR * szConnStrIn,
+    SWORD cbConnStrIn,
+    UCHAR FAR * szConnStrOut,
+    SWORD cbConnStrOutMax,
+    SWORD FAR * pcbConnStrOut)
 {
-       DBC_t FAR*      pdbc    = (DBC_t FAR*)hdbc;
-/*     HDLL            hdll; */
-       char  FAR*      drv;
-       char            drvbuf[1024];
-       char  FAR*      dsn;
-       char            dsnbuf[SQL_MAX_DSN_LENGTH + 1];
-/*     UCHAR           cnstr2drv[1024]; */
+  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
+  char FAR *drv;
+  char drvbuf[1024];
+  char FAR *dsn;
+  char dsnbuf[SQL_MAX_DSN_LENGTH + 1];
 
-       HPROC           hproc /*, dialproc*/ ;
+  HPROC hproc;
 
-/*     int             sqlstat = en_00000; */
-       RETCODE         retcode = SQL_SUCCESS;
-       RETCODE         setopterr = SQL_SUCCESS;
+  RETCODE retcode = SQL_SUCCESS;
+  RETCODE setopterr = SQL_SUCCESS;
 
-       if( hdbc == SQL_NULL_HDBC )
-       {
-               return SQL_INVALID_HANDLE;
-       }
+  if (hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
 
-       /* check arguments */
-       if( ( cbConnStrIn < 0 && cbConnStrIn != SQL_NTS )
-        || cbConnStrOutMax < 0 )
-       {
-               PUSHSQLERR (pdbc->herr, en_S1090 );
+  /* check arguments */
+  if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS) || cbConnStrOutMax < 0)
+    {
+      PUSHSQLERR (pdbc->herr, en_S1090);
 
-               return SQL_ERROR;
-       }
+      return SQL_ERROR;
+    }
 
-       if( pdbc->state == en_dbc_allocated )
-       {
-               drv = _iodbcdm_getkeyvalinstr(szConnStrIn, cbConnStrIn, 
-                               "DRIVER", drvbuf, sizeof(drvbuf));
-       
-               dsn = _iodbcdm_getkeyvalinstr(szConnStrIn, cbConnStrIn,
-                               "DSN",    dsnbuf, sizeof(dsnbuf));
-       
-               if( dsn == NULL || dsn[0] == '\0' )
-               {
-                       dsn = "default";
-               }
-               else    /* if you want tracing, you must use a DSN */
-               {
-                       setopterr |= _iodbcdm_settracing( hdbc, 
-                                               (char*)dsn, SQL_NTS );
-               }
-       
-               if( drv == NULL || drv[0] == '\0' )
-               {
-                       drv = _iodbcdm_getkeyvalbydsn( dsn, SQL_NTS, "Driver", 
-                                               drvbuf, sizeof(drvbuf));
-               }
-       
-               if( drv == NULL )
-               {
-                       PUSHSQLERR( pdbc->herr, en_IM002 );
-       
-                       return SQL_ERROR;
-               }
-       
-               retcode = _iodbcdm_driverload( drv, hdbc );
-       
-               switch( retcode )
-               {
-                       case SQL_SUCCESS:
-                               break;
-       
-                       case SQL_SUCCESS_WITH_INFO:
-                               setopterr = SQL_ERROR;
-                               /* unsuccessed in calling driver's 
-                                * SQLSetConnectOption() to set login
-                                * timeout.
-                                */
-                               break;
-       
-                       default:
-                               return retcode;
-               }
-       }
-       else if( pdbc->state != en_dbc_needdata )
-       {
-               PUSHSQLERR ( pdbc->herr, en_08002 );
-
-               return SQL_ERROR;
-       }
+  if (pdbc->state == en_dbc_allocated)
+    {
+      drv = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
+         "DRIVER", drvbuf, sizeof (drvbuf));
 
-       hproc = _iodbcdm_getproc( hdbc, en_BrowseConnect);
+      dsn = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
+         "DSN", dsnbuf, sizeof (dsnbuf));
 
-       if( hproc == SQL_NULL_HPROC )
+      if (dsn == NULL || dsn[0] == '\0')
        {
-               _iodbcdm_driverunload( hdbc );
-
-               pdbc->state = en_dbc_allocated;
-
-               PUSHSQLERR( pdbc->herr, en_IM001 );
-
-               return SQL_ERROR;
+         dsn = "default";
        }
-
-       CALL_DRIVER ( hdbc, retcode, hproc, en_BrowseConnect, (
-                       pdbc->dhdbc, hwnd,
-                       szConnStrIn, cbConnStrIn,
-                       szConnStrOut, cbConnStrOutMax,
-                       pcbConnStrOut ) )
-
-#if 0 
-       retcode = hproc(pdbc->dhdbc, hwnd,
-                       szConnStrIn, cbConnStrIn,
-                       szConnStrOut, cbConnStrOutMax,
-                       pcbConnStrOut );
-#endif
-
-       switch( retcode )
+      else
+       /* if you want tracing, you must use a DSN */
        {
-               case SQL_SUCCESS: 
-               case SQL_SUCCESS_WITH_INFO:
-                       pdbc->state = en_dbc_connected;
-                       setopterr |= _iodbcdm_dbcdelayset( hdbc );
-                       if( setopterr != SQL_SUCCESS )
-                       {
-                               retcode = SQL_SUCCESS_WITH_INFO;
-                       }
-                       break;
-
-               case SQL_NEED_DATA:
-                       pdbc->state = en_dbc_needdata;
-                       break;
-
-               case SQL_ERROR:
-                       pdbc->state = en_dbc_allocated;
-                       /* but the driver will not unloaded 
-                        * to allow application retrive err
-                        * message from driver 
-                        */
-                       break;
-
-               default:
-                       break;
+         setopterr |= _iodbcdm_settracing (hdbc,
+             (char *) dsn, SQL_NTS);
        }
 
-       return retcode;
-}
-
-RETCODE SQL_API        SQLDisconnect ( HDBC hdbc )
-{
-       DBC_t   FAR*    pdbc    = (DBC_t*)hdbc;
-       STMT_t  FAR*    pstmt;
-       RETCODE         retcode;
-       HPROC           hproc;
-
-       int             sqlstat = en_00000;
-
-       if( hdbc == SQL_NULL_HDBC )
+      if (drv == NULL || drv[0] == '\0')
        {
-               return SQL_INVALID_HANDLE;
+         drv = _iodbcdm_getkeyvalbydsn (dsn, SQL_NTS, "Driver",
+             drvbuf, sizeof (drvbuf));
        }
 
-       /* check hdbc state */
-       if ( pdbc->state == en_dbc_allocated )
+      if (drv == NULL)
        {
-               sqlstat = en_08003;
-       }
+         PUSHSQLERR (pdbc->herr, en_IM002);
 
-       /* check stmt(s) state */
-       for( pstmt  = (STMT_t FAR*)pdbc->hstmt;
-            pstmt != NULL && sqlstat == en_00000;
-            pstmt  = (STMT_t FAR*)pstmt->next )
-       {
-               if( pstmt->state >= en_stmt_needdata 
-                || pstmt->asyn_on != en_NullProc )
-               /* In this case one need to call 
-                * SQLCancel() first */
-               {
-                       sqlstat = en_S1010;
-               }
+         return SQL_ERROR;
        }
 
-       if( sqlstat == en_00000 )
-       {
-               hproc = _iodbcdm_getproc( hdbc, en_Disconnect );
-
-               if( hproc == SQL_NULL_HPROC )
-               {
-                       sqlstat = en_IM001;
-               }
-       }
+      retcode = _iodbcdm_driverload (drv, hdbc);
 
-       if( sqlstat != en_00000 )
-       {
-               PUSHSQLERR ( pdbc->herr, sqlstat );
+      switch (retcode)
+        {
+        case SQL_SUCCESS:
+          break;
 
-               return SQL_ERROR;
-       }
-       
-       CALL_DRIVER ( hdbc, retcode, hproc, en_Disconnect, (
-                       pdbc->dhdbc ) )
+        case SQL_SUCCESS_WITH_INFO:
+          setopterr = SQL_ERROR;
+          /* unsuccessed in calling driver's 
+           * SQLSetConnectOption() to set login
+           * timeout.
+           */
+          break;
 
-#if 0
-       retcode = hproc( pdbc->dhdbc );
-#endif
+        default:
+          return retcode;
+        }
+    }
+  else if (pdbc->state != en_dbc_needdata)
+    {
+      PUSHSQLERR (pdbc->herr, en_08002);
 
-       if( retcode == SQL_SUCCESS
-        || retcode == SQL_SUCCESS_WITH_INFO )
-       {
-               /* diff from MS specs. We disallow
-                * driver SQLDisconnect() return
-                * SQL_SUCCESS_WITH_INFO and post
-                * error message.
-                */
-               retcode = SQL_SUCCESS;
-       }
-       else
-       {
-               return retcode;
-       }
+      return SQL_ERROR;
+    }
 
-       /* free all statement handle(s) on this connection */
-       for(;pdbc->hstmt;)
-       {
-               _iodbcdm_dropstmt( pdbc->hstmt );
-       }
+  hproc = _iodbcdm_getproc (hdbc, en_BrowseConnect);
 
-#if 0
-       retcode = _iodbcdm_driverunload( hdbc );
-#endif
+  if (hproc == SQL_NULL_HPROC)
+    {
+      _iodbcdm_driverunload (hdbc);
 
-       /* state transition */
-       if( retcode == SQL_SUCCESS )
-       {
-               pdbc->state = en_dbc_allocated;
-       }
+      pdbc->state = en_dbc_allocated;
 
-       return retcode;
-}
+      PUSHSQLERR (pdbc->herr, en_IM001);
 
-RETCODE SQL_API        SQLNativeSql(
-                       HDBC            hdbc,
-                       UCHAR  FAR*     szSqlStrIn,
-                       SDWORD          cbSqlStrIn,
-                       UCHAR  FAR*     szSqlStr,
-                       SDWORD          cbSqlStrMax,
-                       SDWORD FAR*     pcbSqlStr )
-{
-       DBC_t FAR*      pdbc    = (DBC_t FAR*)hdbc;
-       HPROC           hproc;
-       int             sqlstat = en_00000;
-       RETCODE         retcode;
-       
-       if( hdbc == SQL_NULL_HDBC )
-       {
-               return SQL_INVALID_HANDLE;
-       }
+      return SQL_ERROR;
+    }
 
-       /* check argument */
-       if( szSqlStrIn == NULL )
-       {
-               sqlstat = en_S1009;
-       }
-       else if( cbSqlStrIn < 0
-             && cbSqlStrIn != SQL_NTS )
-       {
-               sqlstat = en_S1090;
-       }
+  CALL_DRIVER (hdbc, retcode, hproc, en_BrowseConnect, (
+         pdbc->dhdbc, 
+         szConnStrIn, cbConnStrIn, 
+         szConnStrOut, cbConnStrOutMax,
+         pcbConnStrOut))
 
-       if( sqlstat != en_00000 )
-       {
-               PUSHSQLERR ( pdbc->herr, sqlstat );
+  switch (retcode)
+     {
+     case SQL_SUCCESS:
+     case SQL_SUCCESS_WITH_INFO:
+       pdbc->state = en_dbc_connected;
+       setopterr |= _iodbcdm_dbcdelayset (hdbc);
+       if (setopterr != SQL_SUCCESS)
+        {
+          retcode = SQL_SUCCESS_WITH_INFO;
+        }
+       break;
 
-               return SQL_ERROR;
-       }
+     case SQL_NEED_DATA:
+       pdbc->state = en_dbc_needdata;
+       break;
 
-       /* check state */
-       if( pdbc->state <= en_dbc_needdata )
-       {
-               PUSHSQLERR ( pdbc->herr, en_08003 );
+     case SQL_ERROR:
+       pdbc->state = en_dbc_allocated;
+       /* but the driver will not unloaded 
+        * to allow application retrive err
+        * message from driver 
+        */
+       break;
 
-               return SQL_ERROR;
-       }
+     default:
+       break;
+     }
 
-       /* call driver */
-       hproc = _iodbcdm_getproc( hdbc, en_NativeSql );
+  return retcode;
+}
 
-       if( hproc == SQL_NULL_HPROC )
-       {
-               PUSHSQLERR ( pdbc->herr, en_IM001 );
 
-               return SQL_ERROR;
-       }
+RETCODE SQL_API 
+SQLDisconnect (HDBC hdbc)
+{
+  DBC_t FAR *pdbc = (DBC_t *) hdbc;
+  STMT_t FAR *pstmt;
+  RETCODE retcode;
+  HPROC hproc;
+
+  int sqlstat = en_00000;
+
+  if (hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  /* check hdbc state */
+  if (pdbc->state == en_dbc_allocated)
+    {
+      sqlstat = en_08003;
+    }
+
+  /* check stmt(s) state */
+  for (pstmt = (STMT_t FAR *) pdbc->hstmt;
+      pstmt != NULL && sqlstat == en_00000;
+      pstmt = (STMT_t FAR *) pstmt->next)
+    {
+      if (pstmt->state >= en_stmt_needdata
+         || pstmt->asyn_on != en_NullProc)
+       /* In this case one need to call 
+        * SQLCancel() first */
+       {
+         sqlstat = en_S1010;
+       }
+    }
+
+  if (sqlstat == en_00000)
+    {
+      hproc = _iodbcdm_getproc (hdbc, en_Disconnect);
+
+      if (hproc == SQL_NULL_HPROC)
+       {
+         sqlstat = en_IM001;
+       }
+    }
+
+  if (sqlstat != en_00000)
+    {
+      PUSHSQLERR (pdbc->herr, sqlstat);
+
+      return SQL_ERROR;
+    }
+
+  CALL_DRIVER (hdbc, retcode, hproc, en_Disconnect, (
+         pdbc->dhdbc))
+
+  if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
+    {
+      /* diff from MS specs. We disallow
+       * driver SQLDisconnect() return
+       * SQL_SUCCESS_WITH_INFO and post
+       * error message.
+       */
+      retcode = SQL_SUCCESS;
+    }
+  else
+    {
+      return retcode;
+    }
+
+  /* free all statement handle(s) on this connection */
+  for (; pdbc->hstmt;)
+    {
+      _iodbcdm_dropstmt (pdbc->hstmt);
+    }
+
+  /* state transition */
+  if (retcode == SQL_SUCCESS)
+    {
+      pdbc->state = en_dbc_allocated;
+    }
+
+  return retcode;
+}
 
-       CALL_DRIVER ( hdbc, retcode, hproc, en_NativeSql, (
-                       pdbc->dhdbc,
-                       szSqlStrIn,
-                       cbSqlStrIn,
-                       szSqlStr,
-                       cbSqlStrMax,
-                       pcbSqlStr ) )
-
-#if 0
-       retcode = hproc(pdbc->dhdbc,
-                       szSqlStrIn,
-                       cbSqlStrIn,
-                       szSqlStr,
-                       cbSqlStrMax,
-                       pcbSqlStr );
-#endif
 
-       return retcode;
+RETCODE SQL_API 
+SQLNativeSql (
+    HDBC hdbc,
+    UCHAR FAR * szSqlStrIn,
+    SDWORD cbSqlStrIn,
+    UCHAR FAR * szSqlStr,
+    SDWORD cbSqlStrMax,
+    SDWORD FAR * pcbSqlStr)
+{
+  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
+  HPROC hproc;
+  int sqlstat = en_00000;
+  RETCODE retcode;
+
+  if (hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  /* check argument */
+  if (szSqlStrIn == NULL)
+    {
+      sqlstat = en_S1009;
+    }
+  else if (cbSqlStrIn < 0 && cbSqlStrIn != SQL_NTS)
+    {
+      sqlstat = en_S1090;
+    }
+
+  if (sqlstat != en_00000)
+    {
+      PUSHSQLERR (pdbc->herr, sqlstat);
+
+      return SQL_ERROR;
+    }
+
+  /* check state */
+  if (pdbc->state <= en_dbc_needdata)
+    {
+      PUSHSQLERR (pdbc->herr, en_08003);
+
+      return SQL_ERROR;
+    }
+
+  /* call driver */
+  hproc = _iodbcdm_getproc (hdbc, en_NativeSql);
+
+  if (hproc == SQL_NULL_HPROC)
+    {
+      PUSHSQLERR (pdbc->herr, en_IM001);
+
+      return SQL_ERROR;
+    }
+
+  CALL_DRIVER (hdbc, retcode, hproc, en_NativeSql,
+    (pdbc->dhdbc, szSqlStrIn, cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr))
+
+  return retcode;
 }