1 /** Connect(load) driver
3 Copyright (C) 1995 by Ke Jin <kejin@empress.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
16 #include <../iodbc/iodbc.h>
18 #include <../iodbc/isql.h>
19 #include <../iodbc/isqlext.h>
21 #include <../iodbc/dlproc.h>
23 #include <../iodbc/herr.h>
24 #include <../iodbc/henv.h>
25 #include <../iodbc/hdbc.h>
26 #include <../iodbc/hstmt.h>
28 #include <../iodbc/itrace.h>
33 extern char* _iodbcdm_getkeyvalbydsn();
34 extern char* _iodbcdm_getkeyvalinstr();
35 extern RETCODE
_iodbcdm_driverunload();
38 * Following id string is a copyright mark. Removing(i.e. use
39 * souce code of this package without it or make it not appear
40 * in the final object file) or modifing it without permission
41 * from original author(kejin@empress.com) are copyright
45 = "@(#)iODBC driver manager " "2.12" ", Copyright(c) 1995 by Ke Jin";
47 static RETCODE
_iodbcdm_driverload(
50 /* - Load driver share library( or increase its reference count
51 * if it has already been loaded by another active connection)
52 * - Call driver's SQLAllocEnv() (for the first reference only)
53 * - Call driver's SQLAllocConnect()
54 * - Call driver's SQLSetConnectOption() (set login time out)
55 * - Increase the bookkeeping reference count
58 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
60 ENV_t FAR
* penv
= NULL
;
63 RETCODE retcode
= SQL_SUCCESS
;
64 int sqlstat
= en_00000
;
68 fprintf(pdbc
->tstm
, "_iodbcdm_driverload(%s, 0x%x)\n", path
, (int)hdbc
);
71 if( path
== NULL
|| path
[0] == '\0' )
73 PUSHSQLERR ( pdbc
->herr
, en_IM002
);
78 if( hdbc
== SQL_NULL_HDBC
79 || pdbc
->genv
== SQL_NULL_HENV
)
81 return SQL_INVALID_HANDLE
;
84 genv
= (GENV_t FAR
*)pdbc
->genv
;
86 hdll
= _iodbcdm_dllopen( (char FAR
*) path
);
87 /* This will either load the
88 * driver dll or increase its
91 if( hdll
== SQL_NULL_HDLL
)
95 fprintf(pdbc
->tstm
, "ERROR: _iodbcdm_driverload cannot load driver - '%s'\n", _iodbcdm_dllerror());
98 PUSHSYSERR ( pdbc
->herr
, _iodbcdm_dllerror() );
99 PUSHSQLERR ( pdbc
->herr
, en_IM003
);
103 penv
= (ENV_t FAR
*)(pdbc
->henv
);
107 if( penv
->hdll
!= hdll
)
109 _iodbcdm_driverunload(hdbc
);
113 _iodbcdm_dllclose( hdll
);
114 /* this will not unload the driver
115 * but only decrease its internal
123 /* find out whether this dll has already
124 * been loaded on another connection */
125 for( penv
= (ENV_t FAR
*)genv
->henv
;
127 penv
= (ENV_t FAR
*)penv
->next
)
129 if( penv
->hdll
== hdll
)
131 _iodbcdm_dllclose( hdll
);
132 /* this will not unload the driver
133 * but only decrease its internal
141 /* no connection attaching with this dll */
145 /* create a new dll env instance */
146 penv
= (ENV_t FAR
*)MEM_ALLOC ( sizeof(ENV_t
) );
150 _iodbcdm_dllclose(hdll
);
152 PUSHSQLERR ( pdbc
->herr
, en_S1001
);
157 for( i
= 0; i
< SQL_EXT_API_LAST
+ 1; i
++)
159 (penv
->dllproc_tab
)[i
] = SQL_NULL_HPROC
;
165 /* call driver's SQLAllocHandle() or SQLAllocEnv() */
166 #if (ODBCVER >= 0x0300)
167 hproc
= _iodbcdm_getproc( hdbc
, en_AllocHandle
);
171 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_AllocHandle
,
172 ( SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &(penv
->dhenv
) )
174 else /* try driver's SQLAllocEnv() */
177 hproc
= _iodbcdm_getproc( hdbc
, en_AllocEnv
);
179 if( hproc
== SQL_NULL_HPROC
)
185 CALL_DRIVER ( hdbc
, retcode
, hproc
,
186 en_AllocEnv
, (&(penv
->dhenv
)) )
190 if( retcode
== SQL_ERROR
)
195 if( sqlstat
!= en_00000
)
197 _iodbcdm_dllclose ( hdll
);
199 PUSHSQLERR ( pdbc
->herr
, en_IM004
);
204 /* insert into dll env list */
205 penv
->next
= (ENV_t FAR
*)genv
->henv
;
208 /* initiate this new env entry */
209 penv
->refcount
= 0; /* we will increase it after
210 * driver's SQLAllocConnect()
217 if( pdbc
->dhdbc
== SQL_NULL_HDBC
)
219 #if (ODBCVER >= 0x0300)
220 hproc
= _iodbcdm_getproc( hdbc
, en_AllocHandle
);
224 CALL_DRIVER( hdbc
, retcode
, hproc
, en_AllocHandle
,
225 (SQL_HANDLE_DBC
, penv
->dhenv
, &(pdbc
->dhdbc
)) )
230 hproc
= _iodbcdm_getproc( hdbc
, en_AllocConnect
);
232 if( hproc
== SQL_NULL_HPROC
)
238 CALL_DRIVER ( hdbc
, retcode
, hproc
,
239 en_AllocConnect
, (penv
->dhenv
, &(pdbc
->dhdbc
)) )
243 if( retcode
== SQL_ERROR
)
248 if( sqlstat
!= en_00000
)
250 _iodbcdm_driverunload(hdbc
);
252 pdbc
->dhdbc
= SQL_NULL_HDBC
;
253 PUSHSQLERR ( pdbc
->herr
, en_IM005
);
260 penv
->refcount
++; /* bookkeeping reference count on this driver */
263 /* driver's login timeout option must been set before
264 * its SQLConnect() call */
265 if( pdbc
->login_timeout
!= 0UL )
267 hproc
= _iodbcdm_getproc( hdbc
, en_SetConnectOption
);
269 if( hproc
== SQL_NULL_HPROC
)
275 CALL_DRIVER ( hdbc
, retcode
, hproc
,
276 en_SetConnectOption
, (
279 pdbc
->login_timeout
) )
281 if( retcode
== SQL_ERROR
)
283 PUSHSQLERR ( pdbc
->herr
, en_IM006
);
285 return SQL_SUCCESS_WITH_INFO
;
293 RETCODE
_iodbcdm_driverunload( HDBC hdbc
)
294 /* - Call driver's SQLFreeConnect()
295 * - Call driver's SQLFreeEnv() ( for the last reference only)
296 * - Unload the share library( or decrease its reference
297 * count if it is not the last referenct )
298 * - decrease bookkeeping reference count
299 * - state transition to allocated
302 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
307 RETCODE retcode
= SQL_SUCCESS
;
308 int sqlstat
= en_00000
;
310 if( hdbc
== SQL_NULL_HDBC
)
312 return SQL_INVALID_HANDLE
;
315 /* no pointer check will be performed in this function */
316 penv
= (ENV_t FAR
*)pdbc
->henv
;
317 genv
= (GENV_t FAR
*)pdbc
->genv
;
320 || penv
->hdll
== SQL_NULL_HDLL
)
325 #if (ODBCVER >= 0x0300)
326 hproc
= _iodbcdm_getproc( hdbc
, en_FreeHandle
);
330 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_FreeHandle
,
331 ( SQL_HANDLE_DBC
, pdbc
->dhdbc
) )
336 hproc
= _iodbcdm_getproc( hdbc
, en_FreeConnect
);
338 if( hproc
!= SQL_NULL_HPROC
)
340 CALL_DRIVER ( hdbc
, retcode
, hproc
,
341 en_FreeConnect
, ( pdbc
->dhdbc
) )
343 pdbc
->dhdbc
= SQL_NULL_HDBC
;
349 if( ! penv
->refcount
)
350 /* no other connections still attaching with this driver */
352 #if (ODBCVER >= 0x0300)
353 hproc
= _iodbcdm_getproc( hdbc
, en_FreeHandle
);
357 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_FreeHandle
,
358 ( SQL_HANDLE_ENV
, penv
->dhenv
) )
363 hproc
= _iodbcdm_getproc( hdbc
, en_FreeEnv
);
365 if( hproc
!= SQL_NULL_HPROC
)
367 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_FreeEnv
,
370 penv
->dhenv
= SQL_NULL_HENV
;
374 _iodbcdm_dllclose ( penv
->hdll
);
376 penv
->hdll
== SQL_NULL_HDLL
;
378 for( tpenv
= (ENV_t FAR
*)genv
->henv
;
380 tpenv
= (ENV_t FAR
*)penv
->next
)
384 genv
->henv
= penv
->next
;
388 if( tpenv
->next
== penv
)
390 tpenv
->next
= penv
->next
;
398 pdbc
->henv
= SQL_NULL_HENV
;
399 pdbc
->hstmt
= SQL_NULL_HSTMT
;
400 /* pdbc->herr = SQL_NULL_HERR;
401 -- delay to DM's SQLFreeConnect() */
402 pdbc
->dhdbc
= SQL_NULL_HDBC
;
403 pdbc
->state
= en_dbc_allocated
;
405 /* set connect options to default values */
407 pdbc->access_mode = SQL_MODE_DEFAULT;
408 pdbc->autocommit = SQL_AUTOCOMMIT_DEFAULT;
409 pdbc->login_timeout = 0UL;
411 pdbc
->odbc_cursors
= SQL_CUR_DEFAULT
;
412 pdbc
->packet_size
= 0UL;
413 pdbc
->quiet_mode
= (UDWORD
)NULL
;
414 pdbc
->txn_isolation
= SQL_TXN_READ_UNCOMMITTED
;
416 if( pdbc
->current_qualifier
!= NULL
)
418 MEM_FREE ( pdbc
->current_qualifier
);
419 pdbc
->current_qualifier
= NULL
;
425 static RETCODE
_iodbcdm_dbcdelayset( HDBC hdbc
)
427 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
430 RETCODE retcode
= SQL_SUCCESS
;
435 hproc
= _iodbcdm_getproc( hdbc
, en_SetConnectOption
);
437 if( hproc
== SQL_NULL_HPROC
)
439 PUSHSQLERR ( pdbc
->herr
, en_IM006
);
441 return SQL_SUCCESS_WITH_INFO
;
444 if( pdbc
->access_mode
!= SQL_MODE_DEFAULT
)
446 CALL_DRIVER ( hdbc
, ret
, hproc
,
447 en_SetConnectOption
, (
454 if( pdbc
->autocommit
!= SQL_AUTOCOMMIT_DEFAULT
)
456 CALL_DRIVER ( hdbc
, ret
, hproc
,
457 en_SetConnectOption
, (
465 if( pdbc
->current_qualifier
!= NULL
)
467 CALL_DRIVER ( hdbc
, ret
, hproc
,
468 en_SetConnectOption
, (
470 SQL_CURRENT_QUALIFIER
,
471 pdbc
->current_qualifier
) )
476 if( pdbc
->packet_size
!= 0UL )
478 CALL_DRIVER ( hdbc
, ret
, hproc
,
479 en_SetConnectOption
, (
482 pdbc
->packet_size
) )
487 if( pdbc
->quiet_mode
!= (UDWORD
)NULL
)
489 CALL_DRIVER ( hdbc
, ret
, hproc
,
490 en_SetConnectOption
, (
498 if( pdbc
->txn_isolation
!= SQL_TXN_READ_UNCOMMITTED
)
500 CALL_DRIVER ( hdbc
, ret
, hproc
,
501 en_SetConnectOption
, (
504 pdbc
->txn_isolation
) )
507 /* check error code for driver's SQLSetConnectOption() call */
508 if( retcode
!= SQL_SUCCESS
509 && retcode
!= SQL_SUCCESS_WITH_INFO
)
511 PUSHSQLERR ( pdbc
->herr
, en_IM006
);
516 /* get cursor behavior on transaction commit or rollback */
517 hproc
= _iodbcdm_getproc( hdbc
, en_GetInfo
);
519 if( hproc
== SQL_NULL_HPROC
)
521 PUSHSQLERR ( pdbc
->herr
, en_01000
);
526 CALL_DRIVER ( hdbc
, ret
, hproc
,
529 SQL_CURSOR_COMMIT_BEHAVIOR
,
530 (PTR
)&(pdbc
->cb_commit
),
531 sizeof(pdbc
->cb_commit
),
536 CALL_DRIVER ( hdbc
, ret
, hproc
,
539 SQL_CURSOR_ROLLBACK_BEHAVIOR
,
540 (PTR
)&(pdbc
->cb_rollback
),
541 sizeof(pdbc
->cb_rollback
),
546 if( retcode
!= SQL_SUCCESS
547 && retcode
!= SQL_SUCCESS_WITH_INFO
)
555 static RETCODE
_iodbcdm_settracing( HDBC hdbc
, char* dsn
, int dsnlen
)
559 RETCODE setopterr
= SQL_SUCCESS
;
561 /* Get Driver's DLL path from specificed or default dsn section */
562 ptr
= _iodbcdm_getkeyvalbydsn( dsn
, dsnlen
, "TraceFile",
563 (char FAR
*)buf
, sizeof(buf
));
565 if( ptr
== NULL
|| ptr
[0] == '\0' )
567 ptr
= (char FAR
*)(SQL_OPT_TRACE_FILE_DEFAULT
);
570 setopterr
|= SQLSetConnectOption( hdbc
,
571 SQL_OPT_TRACEFILE
, (UDWORD
)(ptr
));
573 ptr
= _iodbcdm_getkeyvalbydsn( dsn
, dsnlen
, "Trace",
574 (char FAR
*)buf
, sizeof(buf
));
578 UDWORD opt
= (UDWORD
)(-1L);
583 || STREQ(ptr
, "1" ) )
585 opt
= SQL_OPT_TRACE_ON
;
588 if( STREQ(ptr
, "OFF")
591 || STREQ(ptr
, "0" ) )
593 opt
= SQL_OPT_TRACE_OFF
;
596 if( opt
!= (UDWORD
)(-1L) )
598 setopterr
|= SQLSetConnectOption( hdbc
,
605 RETCODE SQL_API
SQLConnect (
611 UCHAR FAR
* szAuthStr
,
614 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
615 RETCODE retcode
= SQL_SUCCESS
;
616 RETCODE setopterr
= SQL_SUCCESS
;
617 char driver
[1024] = { '\0' }; /* MS SDK Guide
621 char szNewDSN
[256]; /* OS/2 !!! */
625 if( hdbc
== SQL_NULL_HDBC
)
627 return SQL_INVALID_HANDLE
;
630 /* check arguments */
631 if( ( cbDSN
< 0 && cbDSN
!= SQL_NTS
)
632 || ( cbUID
< 0 && cbUID
!= SQL_NTS
)
633 || ( cbAuthStr
< 0 && cbAuthStr
!= SQL_NTS
)
634 || ( cbDSN
> SQL_MAX_DSN_LENGTH
) )
636 PUSHSQLERR ( pdbc
->herr
, en_S1090
);
641 if( szDSN
== NULL
|| cbDSN
== 0 )
643 PUSHSQLERR ( pdbc
->herr
, en_IM002
);
649 if( pdbc
->state
!= en_dbc_allocated
)
651 PUSHSQLERR ( pdbc
->herr
, en_08002
);
656 setopterr
|= _iodbcdm_settracing( hdbc
,
657 (char*)szDSN
, cbDSN
);
659 ptr
= _iodbcdm_getkeyvalbydsn( szDSN
, cbDSN
, "Driver",
660 (char FAR
*)driver
, sizeof(driver
));
663 /* No specified or default dsn section or
664 * no driver specification in this dsn section */
666 PUSHSQLERR ( pdbc
->herr
, en_IM002
);
674 ** get new szDSN from INI file, if existing
676 if( NULL
!= _iodbcdm_getkeyvalbydsn( szDSN
, cbDSN
, "DSN",
677 (char FAR
*) &szNewDSN
,
680 szDSN
= &szNewDSN
[0];
684 retcode
= _iodbcdm_driverload( driver
, hdbc
);
691 case SQL_SUCCESS_WITH_INFO
:
692 setopterr
= SQL_ERROR
;
693 /* unsuccessed in calling driver's
694 * SQLSetConnectOption() to set login
703 hproc
= _iodbcdm_getproc( hdbc
, en_Connect
);
705 if( hproc
== SQL_NULL_HPROC
)
707 _iodbcdm_driverunload( hdbc
);
709 PUSHSQLERR ( pdbc
->herr
, en_IM001
);
714 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_Connect
, (
718 szAuthStr
, cbAuthStr
) )
721 retcode
= hproc(pdbc
->dhdbc
,
724 szAuthStr
, cbAuthStr
);
727 if( retcode
!= SQL_SUCCESS
728 && retcode
!= SQL_SUCCESS_WITH_INFO
)
730 /* not unload driver for retrive error
731 * messge from driver */
733 _iodbcdm_driverunload( hdbc );
739 /* state transition */
740 pdbc
->state
= en_dbc_connected
;
742 /* do delaid option setting */
743 setopterr
|= _iodbcdm_dbcdelayset( hdbc
);
745 if( setopterr
!= SQL_SUCCESS
)
747 return SQL_SUCCESS_WITH_INFO
;
753 RETCODE SQL_API
SQLDriverConnect (
756 UCHAR FAR
* szConnStrIn
,
758 UCHAR FAR
* szConnStrOut
,
759 SWORD cbConnStrOutMax
,
760 SWORD FAR
* pcbConnStrOut
,
761 UWORD fDriverCompletion
)
763 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
768 char dsnbuf
[SQL_MAX_DSN_LENGTH
+ 1];
769 char szNewDSN
[256]; /* OS/2 !!! */
770 UCHAR cnstr2drv
[1024];
772 HPROC hproc
, dialproc
;
774 int sqlstat
= en_00000
;
775 RETCODE retcode
= SQL_SUCCESS
;
776 RETCODE setopterr
= SQL_SUCCESS
;
778 if( hdbc
== SQL_NULL_HDBC
)
780 return SQL_INVALID_HANDLE
;
783 /* check arguments */
784 if( ( cbConnStrIn
< 0 && cbConnStrIn
!= SQL_NTS
)
785 || cbConnStrOutMax
< 0 )
787 PUSHSQLERR (pdbc
->herr
, en_S1090
);
793 if( pdbc
->state
!= en_dbc_allocated
)
795 PUSHSQLERR (pdbc
->herr
, en_08002
);
800 drv
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
801 "DRIVER", drvbuf
, sizeof(drvbuf
));
803 dsn
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
804 "DSN", dsnbuf
, sizeof(dsnbuf
));
806 switch( fDriverCompletion
)
808 case SQL_DRIVER_NOPROMPT
:
811 case SQL_DRIVER_COMPLETE
:
812 case SQL_DRIVER_COMPLETE_REQUIRED
:
817 /* fall to next case */
818 case SQL_DRIVER_PROMPT
:
819 /* Get data source dialog box function from
820 * current executable */
821 hdll
= _iodbcdm_dllopen((char FAR
*)NULL
);
822 dialproc
= _iodbcdm_dllproc( hdll
,
823 "_iodbcdm_drvconn_dialbox");
825 if( dialproc
== SQL_NULL_HPROC
)
832 hwnd
, /* window or display handle */
833 dsnbuf
, /* input/output dsn buf */
834 sizeof(dsnbuf
), /* buf size */
835 &sqlstat
); /* error code */
837 if( retcode
!= SQL_SUCCESS
)
842 if( cbConnStrIn
== SQL_NTS
)
844 cbConnStrIn
= STRLEN(szConnStrIn
);
854 if( cbConnStrIn
> sizeof(cnstr2drv
)
855 - STRLEN(dsn
) - STRLEN("DSN=;") -1 )
857 sqlstat
= en_S1001
; /* a lazy way to avoid
858 * using heap memory */
862 sprintf(cnstr2drv
, "DSN=%s;", dsn
);
863 cbConnStrIn
+= STRLEN(cnstr2drv
);
864 STRNCAT( cnstr2drv
, szConnStrIn
, cbConnStrIn
);
865 szConnStrIn
= cnstr2drv
;
873 if( sqlstat
!= en_00000
)
875 PUSHSQLERR( pdbc
->herr
, sqlstat
);
880 if( dsn
== NULL
|| dsn
[0] == '\0' )
884 else /* if you want tracing, you must use a DSN */
886 setopterr
|= _iodbcdm_settracing( hdbc
,
887 (char*)dsn
, SQL_NTS
);
890 if( drv
== NULL
|| drv
[0] == '\0' )
892 drv
= _iodbcdm_getkeyvalbydsn( dsn
, SQL_NTS
, "Driver",
893 drvbuf
, sizeof(drvbuf
));
898 PUSHSQLERR( pdbc
->herr
, en_IM002
);
903 retcode
= _iodbcdm_driverload( drv
, hdbc
);
910 case SQL_SUCCESS_WITH_INFO
:
911 setopterr
= SQL_ERROR
;
912 /* unsuccessed in calling driver's
913 * SQLSetConnectOption() to set login
922 hproc
= _iodbcdm_getproc( hdbc
, en_DriverConnect
);
924 if( hproc
== SQL_NULL_HPROC
)
926 _iodbcdm_driverunload( hdbc
);
928 PUSHSQLERR ( pdbc
->herr
, en_IM001
);
936 ** get new szDSN from INI file, if existing
938 strcpy( szNewDSN
, "DSN=" );
939 if( NULL
!= _iodbcdm_getkeyvalbydsn( dsn
, SQL_NTS
, "DSN",
940 (char FAR
*) &szNewDSN
[4],
941 sizeof(szNewDSN
) - 4 ) )
945 strcat( szNewDSN
, ";UID=" );
946 psz
= strtok( szNewDSN
, "\0" );
951 if(NULL
== _iodbcdm_getkeyvalinstr( szConnStrIn
, cbConnStrIn
,
953 "UID", psz, sizeof(szNewDSN) ))
955 "UID", (char FAR
*) &szNewDSN
[strlen(psz
)],
956 (sizeof(szNewDSN
) - strlen(psz
)) ) )
958 _iodbcdm_getkeyvalbydsn( dsn
, SQL_NTS
,
959 "UID", (char FAR
*) &szNewDSN
[strlen(psz
)],
960 (sizeof(szNewDSN
) - strlen(psz
)) );
962 strcat( szNewDSN
, ";PWD=" );
963 psz
= strtok( szNewDSN
, "\0" );
964 if(NULL
== _iodbcdm_getkeyvalinstr( szConnStrIn
, cbConnStrIn
,
966 "PWD", psz, sizeof(szNewDSN) ))
968 "PWD", (char FAR
*) &szNewDSN
[strlen(psz
)],
969 (sizeof(szNewDSN
) - strlen(psz
)) ) )
972 _iodbcdm_getkeyvalbydsn( dsn
, SQL_NTS
,
973 "PWD", (char FAR
*) &szNewDSN
[strlen(psz
)],
974 (sizeof(szNewDSN
) - strlen(psz
)) );
981 strcat( szNewDSN, ";UID=" );
982 psz = strtok( szNewDSN, "\0" );
983 _iodbcdm_getkeyvalinstr( szConnStrIn, cbConnStrIn,
984 "UID", psz, sizeof(szNewDSN) );
985 strcat( szNewDSN, ";PWD=" );
986 psz = strtok( szNewDSN, "\0" );
987 _iodbcdm_getkeyvalinstr( szConnStrIn, cbConnStrIn,
988 "PWD", psz, sizeof(szNewDSN) );
989 szConnStrIn = &szNewDSN[0];
990 cbConnStrIn = SQL_NTS;
995 /******** giovanni & monty ********/
996 /* Add a lot of optional keywords */
998 static char *keywords
[]= { "SERVER","PORT","SOCKET","OPTION","DB",0 };
999 char buff
[80],**key
,*end
;
1001 psz
= szNewDSN
+strlen(szNewDSN
);
1002 end
= szNewDSN
+sizeof(szNewDSN
);
1003 for (key
=keywords
; *key
; key
++)
1005 if (_iodbcdm_getkeyvalbydsn(dsn
, SQL_NTS
,
1006 *key
, (char FAR
*) buff
,
1008 strlen(*key
)+strlen(buff
)+2 < (int) (end
- psz
))
1011 strcpy(psz
,*key
); psz
+=strlen(*key
);
1013 strcpy(psz
,buff
); psz
+=strlen(buff
);
1018 /******** giovanni */
1019 szConnStrIn
= szNewDSN
; /*giovanni, era &szNewDSN */
1020 cbConnStrIn
= SQL_NTS
;
1023 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_DriverConnect
, (
1025 szConnStrIn
, cbConnStrIn
,
1026 szConnStrOut
, cbConnStrOutMax
,
1027 pcbConnStrOut
, fDriverCompletion
) )
1029 retcode
= hproc(pdbc
->dhdbc
, hwnd
,
1030 szConnStrIn
, cbConnStrIn
,
1031 szConnStrOut
, cbConnStrOutMax
,
1032 pcbConnStrOut
, fDriverCompletion
);
1035 if( retcode
!= SQL_SUCCESS
1036 && retcode
!= SQL_SUCCESS_WITH_INFO
)
1038 /* don't unload driver here for retrive
1039 * error message from driver */
1041 _iodbcdm_driverunload( hdbc );
1047 /* state transition */
1048 pdbc
->state
= en_dbc_connected
;
1050 /* do delaid option setting */
1051 setopterr
|= _iodbcdm_dbcdelayset( hdbc
);
1053 if( setopterr
!= SQL_SUCCESS
)
1055 return SQL_SUCCESS_WITH_INFO
;
1061 RETCODE SQL_API
SQLBrowseConnect (
1064 UCHAR FAR
* szConnStrIn
,
1066 UCHAR FAR
* szConnStrOut
,
1067 SWORD cbConnStrOutMax
,
1068 SWORD FAR
* pcbConnStrOut
)
1070 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
1075 char dsnbuf
[SQL_MAX_DSN_LENGTH
+ 1];
1076 UCHAR cnstr2drv
[1024];
1078 HPROC hproc
, dialproc
;
1080 int sqlstat
= en_00000
;
1081 RETCODE retcode
= SQL_SUCCESS
;
1082 RETCODE setopterr
= SQL_SUCCESS
;
1084 if( hdbc
== SQL_NULL_HDBC
)
1086 return SQL_INVALID_HANDLE
;
1089 /* check arguments */
1090 if( ( cbConnStrIn
< 0 && cbConnStrIn
!= SQL_NTS
)
1091 || cbConnStrOutMax
< 0 )
1093 PUSHSQLERR (pdbc
->herr
, en_S1090
);
1098 if( pdbc
->state
== en_dbc_allocated
)
1100 drv
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
1101 "DRIVER", drvbuf
, sizeof(drvbuf
));
1103 dsn
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
1104 "DSN", dsnbuf
, sizeof(dsnbuf
));
1106 if( dsn
== NULL
|| dsn
[0] == '\0' )
1110 else /* if you want tracing, you must use a DSN */
1112 setopterr
|= _iodbcdm_settracing( hdbc
,
1113 (char*)dsn
, SQL_NTS
);
1116 if( drv
== NULL
|| drv
[0] == '\0' )
1118 drv
= _iodbcdm_getkeyvalbydsn( dsn
, SQL_NTS
, "Driver",
1119 drvbuf
, sizeof(drvbuf
));
1124 PUSHSQLERR( pdbc
->herr
, en_IM002
);
1129 retcode
= _iodbcdm_driverload( drv
, hdbc
);
1136 case SQL_SUCCESS_WITH_INFO
:
1137 setopterr
= SQL_ERROR
;
1138 /* unsuccessed in calling driver's
1139 * SQLSetConnectOption() to set login
1148 else if( pdbc
->state
!= en_dbc_needdata
)
1150 PUSHSQLERR ( pdbc
->herr
, en_08002
);
1155 hproc
= _iodbcdm_getproc( hdbc
, en_BrowseConnect
);
1157 if( hproc
== SQL_NULL_HPROC
)
1159 _iodbcdm_driverunload( hdbc
);
1161 pdbc
->state
= en_dbc_allocated
;
1163 PUSHSQLERR( pdbc
->herr
, en_IM001
);
1168 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_BrowseConnect
, (
1170 szConnStrIn
, cbConnStrIn
,
1171 szConnStrOut
, cbConnStrOutMax
,
1175 retcode
= hproc(pdbc
->dhdbc
, hwnd
,
1176 szConnStrIn
, cbConnStrIn
,
1177 szConnStrOut
, cbConnStrOutMax
,
1184 case SQL_SUCCESS_WITH_INFO
:
1185 pdbc
->state
= en_dbc_connected
;
1186 setopterr
|= _iodbcdm_dbcdelayset( hdbc
);
1187 if( setopterr
!= SQL_SUCCESS
)
1189 retcode
= SQL_SUCCESS_WITH_INFO
;
1194 pdbc
->state
= en_dbc_needdata
;
1198 pdbc
->state
= en_dbc_allocated
;
1199 /* but the driver will not unloaded
1200 * to allow application retrive err
1201 * message from driver
1212 RETCODE SQL_API
SQLDisconnect ( HDBC hdbc
)
1214 DBC_t FAR
* pdbc
= (DBC_t
*)hdbc
;
1219 int sqlstat
= en_00000
;
1221 if( hdbc
== SQL_NULL_HDBC
)
1223 return SQL_INVALID_HANDLE
;
1226 /* check hdbc state */
1227 if ( pdbc
->state
== en_dbc_allocated
)
1232 /* check stmt(s) state */
1233 for( pstmt
= (STMT_t FAR
*)pdbc
->hstmt
;
1234 pstmt
!= NULL
&& sqlstat
== en_00000
;
1235 pstmt
= (STMT_t FAR
*)pstmt
->next
)
1237 if( pstmt
->state
>= en_stmt_needdata
1238 || pstmt
->asyn_on
!= en_NullProc
)
1239 /* In this case one need to call
1240 * SQLCancel() first */
1246 if( sqlstat
== en_00000
)
1248 hproc
= _iodbcdm_getproc( hdbc
, en_Disconnect
);
1250 if( hproc
== SQL_NULL_HPROC
)
1256 if( sqlstat
!= en_00000
)
1258 PUSHSQLERR ( pdbc
->herr
, sqlstat
);
1263 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_Disconnect
, (
1267 retcode
= hproc( pdbc
->dhdbc
);
1270 if( retcode
== SQL_SUCCESS
1271 || retcode
== SQL_SUCCESS_WITH_INFO
)
1273 /* diff from MS specs. We disallow
1274 * driver SQLDisconnect() return
1275 * SQL_SUCCESS_WITH_INFO and post
1278 retcode
= SQL_SUCCESS
;
1285 /* free all statement handle(s) on this connection */
1288 _iodbcdm_dropstmt( pdbc
->hstmt
);
1292 retcode
= _iodbcdm_driverunload( hdbc
);
1295 /* state transition */
1296 if( retcode
== SQL_SUCCESS
)
1298 pdbc
->state
= en_dbc_allocated
;
1304 RETCODE SQL_API
SQLNativeSql(
1306 UCHAR FAR
* szSqlStrIn
,
1308 UCHAR FAR
* szSqlStr
,
1310 SDWORD FAR
* pcbSqlStr
)
1312 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
1314 int sqlstat
= en_00000
;
1317 if( hdbc
== SQL_NULL_HDBC
)
1319 return SQL_INVALID_HANDLE
;
1322 /* check argument */
1323 if( szSqlStrIn
== NULL
)
1327 else if( cbSqlStrIn
< 0
1328 && cbSqlStrIn
!= SQL_NTS
)
1333 if( sqlstat
!= en_00000
)
1335 PUSHSQLERR ( pdbc
->herr
, sqlstat
);
1341 if( pdbc
->state
<= en_dbc_needdata
)
1343 PUSHSQLERR ( pdbc
->herr
, en_08003
);
1349 hproc
= _iodbcdm_getproc( hdbc
, en_NativeSql
);
1351 if( hproc
== SQL_NULL_HPROC
)
1353 PUSHSQLERR ( pdbc
->herr
, en_IM001
);
1358 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_NativeSql
, (
1367 retcode
= hproc(pdbc
->dhdbc
,