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>
30 extern char* _iodbcdm_getkeyvalbydsn();
31 extern char* _iodbcdm_getkeyvalinstr();
32 extern RETCODE
_iodbcdm_driverunload();
35 * Following id string is a copyright mark. Removing(i.e. use
36 * souce code of this package without it or make it not appear
37 * in the final object file) or modifing it without permission
38 * from original author(kejin@empress.com) are copyright
42 = "@(#)iODBC driver manager " "2.12" ", Copyright(c) 1995 by Ke Jin";
44 static RETCODE
_iodbcdm_driverload(
47 /* - Load driver share library( or increase its reference count
48 * if it has already been loaded by another active connection)
49 * - Call driver's SQLAllocEnv() (for the first reference only)
50 * - Call driver's SQLAllocConnect()
51 * - Call driver's SQLSetConnectOption() (set login time out)
52 * - Increase the bookkeeping reference count
55 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
57 ENV_t FAR
* penv
= NULL
;
60 RETCODE retcode
= SQL_SUCCESS
;
61 int sqlstat
= en_00000
;
63 if( path
== NULL
|| path
[0] == '\0' )
65 PUSHSQLERR ( pdbc
->herr
, en_IM002
);
70 if( hdbc
== SQL_NULL_HDBC
71 || pdbc
->genv
== SQL_NULL_HENV
)
73 return SQL_INVALID_HANDLE
;
76 genv
= (GENV_t FAR
*)pdbc
->genv
;
78 hdll
= _iodbcdm_dllopen( (char FAR
*) path
);
79 /* This will either load the
80 * driver dll or increase its
83 if( hdll
== SQL_NULL_HDLL
)
85 PUSHSYSERR ( pdbc
->herr
, _iodbcdm_dllerror() );
86 PUSHSQLERR ( pdbc
->herr
, en_IM003
);
90 penv
= (ENV_t FAR
*)(pdbc
->henv
);
94 if( penv
->hdll
!= hdll
)
96 _iodbcdm_driverunload(hdbc
);
100 _iodbcdm_dllclose( hdll
);
101 /* this will not unload the driver
102 * but only decrease its internal
110 /* find out whether this dll has already
111 * been loaded on another connection */
112 for( penv
= (ENV_t FAR
*)genv
->henv
;
114 penv
= (ENV_t FAR
*)penv
->next
)
116 if( penv
->hdll
== hdll
)
118 _iodbcdm_dllclose( hdll
);
119 /* this will not unload the driver
120 * but only decrease its internal
128 /* no connection attaching with this dll */
132 /* create a new dll env instance */
133 penv
= (ENV_t FAR
*)MEM_ALLOC ( sizeof(ENV_t
) );
137 _iodbcdm_dllclose(hdll
);
139 PUSHSQLERR ( pdbc
->herr
, en_S1001
);
144 for( i
= 0; i
< SQL_EXT_API_LAST
+ 1; i
++)
146 (penv
->dllproc_tab
)[i
] = SQL_NULL_HPROC
;
152 /* call driver's SQLAllocHandle() or SQLAllocEnv() */
153 #if (ODBCVER >= 0x0300)
154 hproc
= _iodbcdm_getproc( hdbc
, en_AllocHandle
);
158 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_AllocHandle
,
159 ( SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &(penv
->dhenv
) )
161 else /* try driver's SQLAllocEnv() */
164 hproc
= _iodbcdm_getproc( hdbc
, en_AllocEnv
);
166 if( hproc
== SQL_NULL_HPROC
)
172 CALL_DRIVER ( hdbc
, retcode
, hproc
,
173 en_AllocEnv
, (&(penv
->dhenv
)) )
177 if( retcode
== SQL_ERROR
)
182 if( sqlstat
!= en_00000
)
184 _iodbcdm_dllclose ( hdll
);
186 PUSHSQLERR ( pdbc
->herr
, en_IM004
);
191 /* insert into dll env list */
192 penv
->next
= (ENV_t FAR
*)genv
->henv
;
195 /* initiate this new env entry */
196 penv
->refcount
= 0; /* we will increase it after
197 * driver's SQLAllocConnect()
204 if( pdbc
->dhdbc
== SQL_NULL_HDBC
)
206 #if (ODBCVER >= 0x0300)
207 hproc
= _iodbcdm_getproc( hdbc
, en_AllocHandle
);
211 CALL_DRIVER( hdbc
, retcode
, hproc
, en_AllocHandle
,
212 (SQL_HANDLE_DBC
, penv
->dhenv
, &(pdbc
->dhdbc
)) )
217 hproc
= _iodbcdm_getproc( hdbc
, en_AllocConnect
);
219 if( hproc
== SQL_NULL_HPROC
)
225 CALL_DRIVER ( hdbc
, retcode
, hproc
,
226 en_AllocConnect
, (penv
->dhenv
, &(pdbc
->dhdbc
)) )
230 if( retcode
== SQL_ERROR
)
235 if( sqlstat
!= en_00000
)
237 _iodbcdm_driverunload(hdbc
);
239 pdbc
->dhdbc
= SQL_NULL_HDBC
;
240 PUSHSQLERR ( pdbc
->herr
, en_IM005
);
247 penv
->refcount
++; /* bookkeeping reference count on this driver */
250 /* driver's login timeout option must been set before
251 * its SQLConnect() call */
252 if( pdbc
->login_timeout
!= 0UL )
254 hproc
= _iodbcdm_getproc( hdbc
, en_SetConnectOption
);
256 if( hproc
== SQL_NULL_HPROC
)
262 CALL_DRIVER ( hdbc
, retcode
, hproc
,
263 en_SetConnectOption
, (
266 pdbc
->login_timeout
) )
268 if( retcode
== SQL_ERROR
)
270 PUSHSQLERR ( pdbc
->herr
, en_IM006
);
272 return SQL_SUCCESS_WITH_INFO
;
280 RETCODE
_iodbcdm_driverunload( HDBC hdbc
)
281 /* - Call driver's SQLFreeConnect()
282 * - Call driver's SQLFreeEnv() ( for the last reference only)
283 * - Unload the share library( or decrease its reference
284 * count if it is not the last referenct )
285 * - decrease bookkeeping reference count
286 * - state transition to allocated
289 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
294 RETCODE retcode
= SQL_SUCCESS
;
295 int sqlstat
= en_00000
;
297 if( hdbc
== SQL_NULL_HDBC
)
299 return SQL_INVALID_HANDLE
;
302 /* no pointer check will be performed in this function */
303 penv
= (ENV_t FAR
*)pdbc
->henv
;
304 genv
= (GENV_t FAR
*)pdbc
->genv
;
307 || penv
->hdll
== SQL_NULL_HDLL
)
312 #if (ODBCVER >= 0x0300)
313 hproc
= _iodbcdm_getproc( hdbc
, en_FreeHandle
);
317 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_FreeHandle
,
318 ( SQL_HANDLE_DBC
, pdbc
->dhdbc
) )
323 hproc
= _iodbcdm_getproc( hdbc
, en_FreeConnect
);
325 if( hproc
!= SQL_NULL_HPROC
)
327 CALL_DRIVER ( hdbc
, retcode
, hproc
,
328 en_FreeConnect
, ( pdbc
->dhdbc
) )
330 pdbc
->dhdbc
= SQL_NULL_HDBC
;
336 if( ! penv
->refcount
)
337 /* no other connections still attaching with this driver */
339 #if (ODBCVER >= 0x0300)
340 hproc
= _iodbcdm_getproc( hdbc
, en_FreeHandle
);
344 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_FreeHandle
,
345 ( SQL_HANDLE_ENV
, penv
->dhenv
) )
350 hproc
= _iodbcdm_getproc( hdbc
, en_FreeEnv
);
352 if( hproc
!= SQL_NULL_HPROC
)
354 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_FreeEnv
,
357 penv
->dhenv
= SQL_NULL_HENV
;
361 _iodbcdm_dllclose ( penv
->hdll
);
363 penv
->hdll
= SQL_NULL_HDLL
;
365 for( tpenv
= (ENV_t FAR
*)genv
->henv
;
367 tpenv
= (ENV_t FAR
*)penv
->next
)
371 genv
->henv
= penv
->next
;
375 if( tpenv
->next
== penv
)
377 tpenv
->next
= penv
->next
;
385 pdbc
->henv
= SQL_NULL_HENV
;
386 pdbc
->hstmt
= SQL_NULL_HSTMT
;
387 /* pdbc->herr = SQL_NULL_HERR;
388 -- delay to DM's SQLFreeConnect() */
389 pdbc
->dhdbc
= SQL_NULL_HDBC
;
390 pdbc
->state
= en_dbc_allocated
;
392 /* set connect options to default values */
394 pdbc->access_mode = SQL_MODE_DEFAULT;
395 pdbc->autocommit = SQL_AUTOCOMMIT_DEFAULT;
396 pdbc->login_timeout = 0UL;
398 pdbc
->odbc_cursors
= SQL_CUR_DEFAULT
;
399 pdbc
->packet_size
= 0UL;
400 pdbc
->quiet_mode
= (UDWORD
)NULL
;
401 pdbc
->txn_isolation
= SQL_TXN_READ_UNCOMMITTED
;
403 if( pdbc
->current_qualifier
!= NULL
)
405 MEM_FREE ( pdbc
->current_qualifier
);
406 pdbc
->current_qualifier
= NULL
;
412 static RETCODE
_iodbcdm_dbcdelayset( HDBC hdbc
)
414 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
417 RETCODE retcode
= SQL_SUCCESS
;
422 hproc
= _iodbcdm_getproc( hdbc
, en_SetConnectOption
);
424 if( hproc
== SQL_NULL_HPROC
)
426 PUSHSQLERR ( pdbc
->herr
, en_IM006
);
428 return SQL_SUCCESS_WITH_INFO
;
431 if( pdbc
->access_mode
!= SQL_MODE_DEFAULT
)
433 CALL_DRIVER ( hdbc
, ret
, hproc
,
434 en_SetConnectOption
, (
441 if( pdbc
->autocommit
!= SQL_AUTOCOMMIT_DEFAULT
)
443 CALL_DRIVER ( hdbc
, ret
, hproc
,
444 en_SetConnectOption
, (
452 if( pdbc
->current_qualifier
!= NULL
)
454 CALL_DRIVER ( hdbc
, ret
, hproc
,
455 en_SetConnectOption
, (
457 SQL_CURRENT_QUALIFIER
,
458 pdbc
->current_qualifier
) )
463 if( pdbc
->packet_size
!= 0UL )
465 CALL_DRIVER ( hdbc
, ret
, hproc
,
466 en_SetConnectOption
, (
469 pdbc
->packet_size
) )
474 if( pdbc
->quiet_mode
!= (UDWORD
)NULL
)
476 CALL_DRIVER ( hdbc
, ret
, hproc
,
477 en_SetConnectOption
, (
485 if( pdbc
->txn_isolation
!= SQL_TXN_READ_UNCOMMITTED
)
487 CALL_DRIVER ( hdbc
, ret
, hproc
,
488 en_SetConnectOption
, (
491 pdbc
->txn_isolation
) )
494 /* check error code for driver's SQLSetConnectOption() call */
495 if( retcode
!= SQL_SUCCESS
496 && retcode
!= SQL_SUCCESS_WITH_INFO
)
498 PUSHSQLERR ( pdbc
->herr
, en_IM006
);
503 /* get cursor behavior on transaction commit or rollback */
504 hproc
= _iodbcdm_getproc( hdbc
, en_GetInfo
);
506 if( hproc
== SQL_NULL_HPROC
)
508 PUSHSQLERR ( pdbc
->herr
, en_01000
);
513 CALL_DRIVER ( hdbc
, ret
, hproc
,
516 SQL_CURSOR_COMMIT_BEHAVIOR
,
517 (PTR
)&(pdbc
->cb_commit
),
518 sizeof(pdbc
->cb_commit
),
523 CALL_DRIVER ( hdbc
, ret
, hproc
,
526 SQL_CURSOR_ROLLBACK_BEHAVIOR
,
527 (PTR
)&(pdbc
->cb_rollback
),
528 sizeof(pdbc
->cb_rollback
),
533 if( retcode
!= SQL_SUCCESS
534 && retcode
!= SQL_SUCCESS_WITH_INFO
)
542 static RETCODE
_iodbcdm_settracing( HDBC hdbc
, char* dsn
, int dsnlen
)
546 RETCODE setopterr
= SQL_SUCCESS
;
548 /* Get Driver's DLL path from specificed or default dsn section */
549 ptr
= _iodbcdm_getkeyvalbydsn( dsn
, dsnlen
, "TraceFile",
550 (char FAR
*)buf
, sizeof(buf
));
552 if( ptr
== NULL
|| ptr
[0] == '\0' )
554 ptr
= (char FAR
*)(SQL_OPT_TRACE_FILE_DEFAULT
);
557 setopterr
|= SQLSetConnectOption( hdbc
,
558 SQL_OPT_TRACEFILE
, (UDWORD
)(ptr
));
560 ptr
= _iodbcdm_getkeyvalbydsn( dsn
, dsnlen
, "Trace",
561 (char FAR
*)buf
, sizeof(buf
));
565 UDWORD opt
= (UDWORD
)(-1L);
570 || STREQ(ptr
, "1" ) )
572 opt
= SQL_OPT_TRACE_ON
;
575 if( STREQ(ptr
, "OFF")
578 || STREQ(ptr
, "0" ) )
580 opt
= SQL_OPT_TRACE_OFF
;
583 if( opt
!= (UDWORD
)(-1L) )
585 setopterr
|= SQLSetConnectOption( hdbc
,
593 RETCODE SQL_API
SQLConnect (
599 UCHAR FAR
* szAuthStr
,
602 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
603 RETCODE retcode
= SQL_SUCCESS
;
604 RETCODE setopterr
= SQL_SUCCESS
;
605 char driver
[1024] = { '\0' }; /* MS SDK Guide
612 if( hdbc
== SQL_NULL_HDBC
)
614 return SQL_INVALID_HANDLE
;
617 /* check arguments */
618 if( ( cbDSN
< 0 && cbDSN
!= SQL_NTS
)
619 || ( cbUID
< 0 && cbUID
!= SQL_NTS
)
620 || ( cbAuthStr
< 0 && cbAuthStr
!= SQL_NTS
)
621 || ( cbDSN
> SQL_MAX_DSN_LENGTH
) )
623 PUSHSQLERR ( pdbc
->herr
, en_S1090
);
628 if( szDSN
== NULL
|| cbDSN
== 0 )
630 PUSHSQLERR ( pdbc
->herr
, en_IM002
);
636 if( pdbc
->state
!= en_dbc_allocated
)
638 PUSHSQLERR ( pdbc
->herr
, en_08002
);
643 setopterr
|= _iodbcdm_settracing( hdbc
,
644 (char*)szDSN
, cbDSN
);
646 ptr
= _iodbcdm_getkeyvalbydsn( szDSN
, cbDSN
, "Driver",
647 (char FAR
*)driver
, sizeof(driver
));
650 /* No specified or default dsn section or
651 * no driver specification in this dsn section */
653 PUSHSQLERR ( pdbc
->herr
, en_IM002
);
658 retcode
= _iodbcdm_driverload( driver
, hdbc
);
665 case SQL_SUCCESS_WITH_INFO
:
666 setopterr
= SQL_ERROR
;
667 /* unsuccessed in calling driver's
668 * SQLSetConnectOption() to set login
677 hproc
= _iodbcdm_getproc( hdbc
, en_Connect
);
679 if( hproc
== SQL_NULL_HPROC
)
681 _iodbcdm_driverunload( hdbc
);
683 PUSHSQLERR ( pdbc
->herr
, en_IM001
);
688 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_Connect
, (
692 szAuthStr
, cbAuthStr
) )
695 retcode
= hproc(pdbc
->dhdbc
,
698 szAuthStr
, cbAuthStr
);
701 if( retcode
!= SQL_SUCCESS
702 && retcode
!= SQL_SUCCESS_WITH_INFO
)
704 /* not unload driver for retrive error
705 * messge from driver */
707 _iodbcdm_driverunload( hdbc );
713 /* state transition */
714 pdbc
->state
= en_dbc_connected
;
716 /* do delaid option setting */
717 setopterr
|= _iodbcdm_dbcdelayset( hdbc
);
719 if( setopterr
!= SQL_SUCCESS
)
721 return SQL_SUCCESS_WITH_INFO
;
727 RETCODE SQL_API
SQLDriverConnect (
730 UCHAR FAR
* szConnStrIn
,
732 UCHAR FAR
* szConnStrOut
,
733 SWORD cbConnStrOutMax
,
734 SWORD FAR
* pcbConnStrOut
,
735 UWORD fDriverCompletion
)
737 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
742 char dsnbuf
[SQL_MAX_DSN_LENGTH
+ 1];
743 UCHAR cnstr2drv
[1024];
745 HPROC hproc
, dialproc
;
747 int sqlstat
= en_00000
;
748 RETCODE retcode
= SQL_SUCCESS
;
749 RETCODE setopterr
= SQL_SUCCESS
;
751 if( hdbc
== SQL_NULL_HDBC
)
753 return SQL_INVALID_HANDLE
;
756 /* check arguments */
757 if( ( cbConnStrIn
< 0 && cbConnStrIn
!= SQL_NTS
)
758 || cbConnStrOutMax
< 0 )
760 PUSHSQLERR (pdbc
->herr
, en_S1090
);
766 if( pdbc
->state
!= en_dbc_allocated
)
768 PUSHSQLERR (pdbc
->herr
, en_08002
);
773 drv
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
774 "DRIVER", drvbuf
, sizeof(drvbuf
));
776 dsn
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
777 "DSN", dsnbuf
, sizeof(dsnbuf
));
779 switch( fDriverCompletion
)
781 case SQL_DRIVER_NOPROMPT
:
784 case SQL_DRIVER_COMPLETE
:
785 case SQL_DRIVER_COMPLETE_REQUIRED
:
790 /* fall to next case */
791 case SQL_DRIVER_PROMPT
:
792 /* Get data source dialog box function from
793 * current executable */
794 hdll
= _iodbcdm_dllopen((char FAR
*)NULL
);
795 dialproc
= _iodbcdm_dllproc( hdll
,
796 "_iodbcdm_drvconn_dialbox");
798 if( dialproc
== SQL_NULL_HPROC
)
805 hwnd
, /* window or display handle */
806 dsnbuf
, /* input/output dsn buf */
807 sizeof(dsnbuf
), /* buf size */
808 &sqlstat
); /* error code */
810 if( retcode
!= SQL_SUCCESS
)
815 if( cbConnStrIn
== SQL_NTS
)
817 cbConnStrIn
= STRLEN(szConnStrIn
);
827 if( cbConnStrIn
> sizeof(cnstr2drv
)
828 - STRLEN(dsn
) - STRLEN("DSN=;") -1 )
830 sqlstat
= en_S1001
; /* a lazy way to avoid
831 * using heap memory */
835 sprintf( (char FAR
*)cnstr2drv
, "DSN=%s;", dsn
);
836 cbConnStrIn
+= STRLEN(cnstr2drv
);
837 STRNCAT( cnstr2drv
, szConnStrIn
, cbConnStrIn
);
838 szConnStrIn
= cnstr2drv
;
846 if( sqlstat
!= en_00000
)
848 PUSHSQLERR( pdbc
->herr
, sqlstat
);
853 if( dsn
== NULL
|| dsn
[0] == '\0' )
857 else /* if you want tracing, you must use a DSN */
859 setopterr
|= _iodbcdm_settracing( hdbc
,
860 (char*)dsn
, SQL_NTS
);
863 if( drv
== NULL
|| drv
[0] == '\0' )
865 drv
= _iodbcdm_getkeyvalbydsn( dsn
, SQL_NTS
, "Driver",
866 drvbuf
, sizeof(drvbuf
));
871 PUSHSQLERR( pdbc
->herr
, en_IM002
);
876 retcode
= _iodbcdm_driverload( drv
, hdbc
);
883 case SQL_SUCCESS_WITH_INFO
:
884 setopterr
= SQL_ERROR
;
885 /* unsuccessed in calling driver's
886 * SQLSetConnectOption() to set login
895 hproc
= _iodbcdm_getproc( hdbc
, en_DriverConnect
);
897 if( hproc
== SQL_NULL_HPROC
)
899 _iodbcdm_driverunload( hdbc
);
901 PUSHSQLERR ( pdbc
->herr
, en_IM001
);
906 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_DriverConnect
, (
908 szConnStrIn
, cbConnStrIn
,
909 szConnStrOut
, cbConnStrOutMax
,
910 pcbConnStrOut
, fDriverCompletion
) )
913 retcode
= hproc(pdbc
->dhdbc
, hwnd
,
914 szConnStrIn
, cbConnStrIn
,
915 szConnStrOut
, cbConnStrOutMax
,
916 pcbConnStrOut
, fDriverCompletion
);
919 if( retcode
!= SQL_SUCCESS
920 && retcode
!= SQL_SUCCESS_WITH_INFO
)
922 /* don't unload driver here for retrive
923 * error message from driver */
925 _iodbcdm_driverunload( hdbc );
931 /* state transition */
932 pdbc
->state
= en_dbc_connected
;
934 /* do delaid option setting */
935 setopterr
|= _iodbcdm_dbcdelayset( hdbc
);
937 if( setopterr
!= SQL_SUCCESS
)
939 return SQL_SUCCESS_WITH_INFO
;
945 RETCODE SQL_API
SQLBrowseConnect (
948 UCHAR FAR
* szConnStrIn
,
950 UCHAR FAR
* szConnStrOut
,
951 SWORD cbConnStrOutMax
,
952 SWORD FAR
* pcbConnStrOut
)
954 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
959 char dsnbuf
[SQL_MAX_DSN_LENGTH
+ 1];
960 UCHAR cnstr2drv
[1024];
962 HPROC hproc
, dialproc
;
964 int sqlstat
= en_00000
;
965 RETCODE retcode
= SQL_SUCCESS
;
966 RETCODE setopterr
= SQL_SUCCESS
;
968 if( hdbc
== SQL_NULL_HDBC
)
970 return SQL_INVALID_HANDLE
;
973 /* check arguments */
974 if( ( cbConnStrIn
< 0 && cbConnStrIn
!= SQL_NTS
)
975 || cbConnStrOutMax
< 0 )
977 PUSHSQLERR (pdbc
->herr
, en_S1090
);
982 if( pdbc
->state
== en_dbc_allocated
)
984 drv
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
985 "DRIVER", drvbuf
, sizeof(drvbuf
));
987 dsn
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
988 "DSN", dsnbuf
, sizeof(dsnbuf
));
990 if( dsn
== NULL
|| dsn
[0] == '\0' )
994 else /* if you want tracing, you must use a DSN */
996 setopterr
|= _iodbcdm_settracing( hdbc
,
997 (char*)dsn
, SQL_NTS
);
1000 if( drv
== NULL
|| drv
[0] == '\0' )
1002 drv
= _iodbcdm_getkeyvalbydsn( dsn
, SQL_NTS
, "Driver",
1003 drvbuf
, sizeof(drvbuf
));
1008 PUSHSQLERR( pdbc
->herr
, en_IM002
);
1013 retcode
= _iodbcdm_driverload( drv
, hdbc
);
1020 case SQL_SUCCESS_WITH_INFO
:
1021 setopterr
= SQL_ERROR
;
1022 /* unsuccessed in calling driver's
1023 * SQLSetConnectOption() to set login
1032 else if( pdbc
->state
!= en_dbc_needdata
)
1034 PUSHSQLERR ( pdbc
->herr
, en_08002
);
1039 hproc
= _iodbcdm_getproc( hdbc
, en_BrowseConnect
);
1041 if( hproc
== SQL_NULL_HPROC
)
1043 _iodbcdm_driverunload( hdbc
);
1045 pdbc
->state
= en_dbc_allocated
;
1047 PUSHSQLERR( pdbc
->herr
, en_IM001
);
1052 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_BrowseConnect
, (
1054 szConnStrIn
, cbConnStrIn
,
1055 szConnStrOut
, cbConnStrOutMax
,
1059 retcode
= hproc(pdbc
->dhdbc
, hwnd
,
1060 szConnStrIn
, cbConnStrIn
,
1061 szConnStrOut
, cbConnStrOutMax
,
1068 case SQL_SUCCESS_WITH_INFO
:
1069 pdbc
->state
= en_dbc_connected
;
1070 setopterr
|= _iodbcdm_dbcdelayset( hdbc
);
1071 if( setopterr
!= SQL_SUCCESS
)
1073 retcode
= SQL_SUCCESS_WITH_INFO
;
1078 pdbc
->state
= en_dbc_needdata
;
1082 pdbc
->state
= en_dbc_allocated
;
1083 /* but the driver will not unloaded
1084 * to allow application retrive err
1085 * message from driver
1096 RETCODE SQL_API
SQLDisconnect ( HDBC hdbc
)
1098 DBC_t FAR
* pdbc
= (DBC_t
*)hdbc
;
1103 int sqlstat
= en_00000
;
1105 if( hdbc
== SQL_NULL_HDBC
)
1107 return SQL_INVALID_HANDLE
;
1110 /* check hdbc state */
1111 if ( pdbc
->state
== en_dbc_allocated
)
1116 /* check stmt(s) state */
1117 for( pstmt
= (STMT_t FAR
*)pdbc
->hstmt
;
1118 pstmt
!= NULL
&& sqlstat
== en_00000
;
1119 pstmt
= (STMT_t FAR
*)pstmt
->next
)
1121 if( pstmt
->state
>= en_stmt_needdata
1122 || pstmt
->asyn_on
!= en_NullProc
)
1123 /* In this case one need to call
1124 * SQLCancel() first */
1130 if( sqlstat
== en_00000
)
1132 hproc
= _iodbcdm_getproc( hdbc
, en_Disconnect
);
1134 if( hproc
== SQL_NULL_HPROC
)
1140 if( sqlstat
!= en_00000
)
1142 PUSHSQLERR ( pdbc
->herr
, sqlstat
);
1147 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_Disconnect
, (
1151 retcode
= hproc( pdbc
->dhdbc
);
1154 if( retcode
== SQL_SUCCESS
1155 || retcode
== SQL_SUCCESS_WITH_INFO
)
1157 /* diff from MS specs. We disallow
1158 * driver SQLDisconnect() return
1159 * SQL_SUCCESS_WITH_INFO and post
1162 retcode
= SQL_SUCCESS
;
1169 /* free all statement handle(s) on this connection */
1172 _iodbcdm_dropstmt( pdbc
->hstmt
);
1176 retcode
= _iodbcdm_driverunload( hdbc
);
1179 /* state transition */
1180 if( retcode
== SQL_SUCCESS
)
1182 pdbc
->state
= en_dbc_allocated
;
1188 RETCODE SQL_API
SQLNativeSql(
1190 UCHAR FAR
* szSqlStrIn
,
1192 UCHAR FAR
* szSqlStr
,
1194 SDWORD FAR
* pcbSqlStr
)
1196 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
1198 int sqlstat
= en_00000
;
1201 if( hdbc
== SQL_NULL_HDBC
)
1203 return SQL_INVALID_HANDLE
;
1206 /* check argument */
1207 if( szSqlStrIn
== NULL
)
1211 else if( cbSqlStrIn
< 0
1212 && cbSqlStrIn
!= SQL_NTS
)
1217 if( sqlstat
!= en_00000
)
1219 PUSHSQLERR ( pdbc
->herr
, sqlstat
);
1225 if( pdbc
->state
<= en_dbc_needdata
)
1227 PUSHSQLERR ( pdbc
->herr
, en_08003
);
1233 hproc
= _iodbcdm_getproc( hdbc
, en_NativeSql
);
1235 if( hproc
== SQL_NULL_HPROC
)
1237 PUSHSQLERR ( pdbc
->herr
, en_IM001
);
1242 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_NativeSql
, (
1251 retcode
= hproc(pdbc
->dhdbc
,