X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1a6944fd74cfb70ace96d60bde31a7c8e0a5896d..2d19ad25782b1b370cd26d0f17d45856d201fc70:/src/iodbc/connect.c diff --git a/src/iodbc/connect.c b/src/iodbc/connect.c index c2f37e9f28..2bd934f6a2 100644 --- a/src/iodbc/connect.c +++ b/src/iodbc/connect.c @@ -1,31 +1,42 @@ -/** Connect(load) driver - - Copyright (C) 1995 by Ke Jin - - 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 + * + * 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 "itrace.h" extern char* _iodbcdm_getkeyvalbydsn(); extern char* _iodbcdm_getkeyvalinstr(); @@ -39,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) @@ -51,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; }