1/* 2 * connect.c 3 * 4 * $Id: connect.c,v 1.53 2007/09/10 07:27:13 source Exp $ 5 * 6 * Connect (load) driver 7 * 8 * The iODBC driver manager. 9 * 10 * Copyright (C) 1995 by Ke Jin <kejin@empress.com> 11 * Copyright (C) 1996-2006 by OpenLink Software <iodbc@openlinksw.com> 12 * All Rights Reserved. 13 * 14 * This software is released under the terms of either of the following 15 * licenses: 16 * 17 * - GNU Library General Public License (see LICENSE.LGPL) 18 * - The BSD License (see LICENSE.BSD). 19 * 20 * Note that the only valid version of the LGPL license as far as this 21 * project is concerned is the original GNU Library General Public License 22 * Version 2, dated June 1991. 23 * 24 * While not mandated by the BSD license, any patches you make to the 25 * iODBC source code may be contributed back into the iODBC project 26 * at your discretion. Contributions will benefit the Open Source and 27 * Data Access community as a whole. Submissions may be made at: 28 * 29 * http://www.iodbc.org 30 * 31 * 32 * GNU Library Generic Public License Version 2 33 * ============================================ 34 * This library is free software; you can redistribute it and/or 35 * modify it under the terms of the GNU Library General Public 36 * License as published by the Free Software Foundation; only 37 * Version 2 of the License dated June 1991. 38 * 39 * This library is distributed in the hope that it will be useful, 40 * but WITHOUT ANY WARRANTY; without even the implied warranty of 41 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 42 * Library General Public License for more details. 43 * 44 * You should have received a copy of the GNU Library General Public 45 * License along with this library; if not, write to the Free 46 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 47 * 48 * 49 * The BSD License 50 * =============== 51 * Redistribution and use in source and binary forms, with or without 52 * modification, are permitted provided that the following conditions 53 * are met: 54 * 55 * 1. Redistributions of source code must retain the above copyright 56 * notice, this list of conditions and the following disclaimer. 57 * 2. Redistributions in binary form must reproduce the above copyright 58 * notice, this list of conditions and the following disclaimer in 59 * the documentation and/or other materials provided with the 60 * distribution. 61 * 3. Neither the name of OpenLink Software Inc. nor the names of its 62 * contributors may be used to endorse or promote products derived 63 * from this software without specific prior written permission. 64 * 65 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 66 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 67 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 68 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 69 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 70 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 71 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 72 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 73 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 74 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 75 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 76 */ 77 78#include <iodbc.h> 79 80#include <assert.h> 81#include <sql.h> 82#include <sqlext.h> 83#include <sqlucode.h> 84#include <iodbcext.h> 85#include <odbcinst.h> 86 87#include <dlproc.h> 88 89#include <herr.h> 90#include <henv.h> 91#include <hdbc.h> 92#include <hstmt.h> 93 94#include <itrace.h> 95 96#include <unicode.h> 97 98#if defined (__APPLE__) && !(defined (NO_FRAMEWORKS) || defined (_LP64)) 99#include <Carbon/Carbon.h> 100#endif 101 102#include "misc.h" 103#include "iodbc_misc.h" 104 105/* 106 * Identification strings 107 */ 108static char sccsid[] = "@(#)iODBC driver manager " VERSION "\n"; 109char *iodbc_version = VERSION; 110 111 112/* 113 * Prototypes 114 */ 115extern SQLRETURN _iodbcdm_driverunload (HDBC hdbc, int ver); 116extern SQLRETURN SQL_API _iodbcdm_SetConnectOption (SQLHDBC hdbc, 117 SQLUSMALLINT fOption, SQLULEN vParam, SQLCHAR waMode); 118 119 120#define CHECK_DRVCONN_DIALBOX(path) \ 121 { \ 122 if ((handle = DLL_OPEN(path)) != NULL) \ 123 { \ 124 if (DLL_PROC(handle, "_iodbcdm_drvconn_dialboxw") != NULL) \ 125 { \ 126 DLL_CLOSE(handle); \ 127 retVal = TRUE; \ 128 goto quit; \ 129 } \ 130 else \ 131 { \ 132 if (DLL_PROC(handle, "_iodbcdm_drvconn_dialbox") != NULL) \ 133 { \ 134 DLL_CLOSE(handle); \ 135 retVal = TRUE; \ 136 goto quit; \ 137 } \ 138 } \ 139 DLL_CLOSE(handle); \ 140 } \ 141 } 142 143 144 145static BOOL 146_iodbcdm_CheckDriverLoginDlg ( 147 LPSTR drv, 148 LPSTR dsn 149) 150{ 151 char tokenstr[4096]; 152 char drvbuf[4096] = { L'\0'}; 153 HDLL handle; 154 BOOL retVal = FALSE; 155 156 /* Check if the driver is provided */ 157 if (drv == NULL) 158 { 159 SQLSetConfigMode (ODBC_BOTH_DSN); 160 SQLGetPrivateProfileString ("ODBC Data Sources", 161 dsn && dsn[0] != '\0' ? dsn : "Default", 162 "", tokenstr, sizeof (tokenstr), NULL); 163 drv = tokenstr; 164 } 165 166 /* Call the iodbcdm_drvconn_dialbox */ 167 168 SQLSetConfigMode (ODBC_USER_DSN); 169 if (!access (drv, X_OK)) 170 { CHECK_DRVCONN_DIALBOX (drv); } 171 if (SQLGetPrivateProfileString (drv, "Driver", "", drvbuf, 172 sizeof (drvbuf), "odbcinst.ini")) 173 { CHECK_DRVCONN_DIALBOX (drvbuf); } 174 if (SQLGetPrivateProfileString (drv, "Setup", "", drvbuf, 175 sizeof (drvbuf), "odbcinst.ini")) 176 { CHECK_DRVCONN_DIALBOX (drvbuf); } 177 if (SQLGetPrivateProfileString ("Default", "Driver", "", drvbuf, 178 sizeof (drvbuf), "odbcinst.ini")) 179 { CHECK_DRVCONN_DIALBOX (drvbuf); } 180 if (SQLGetPrivateProfileString ("Default", "Setup", "", drvbuf, 181 sizeof (drvbuf), "odbcinst.ini")) 182 { CHECK_DRVCONN_DIALBOX (drvbuf); } 183 184 185 SQLSetConfigMode (ODBC_SYSTEM_DSN); 186 if (!access (drv, X_OK)) 187 { CHECK_DRVCONN_DIALBOX (drv); } 188 if (SQLGetPrivateProfileString (drv, "Driver", "", drvbuf, 189 sizeof (drvbuf), "odbcinst.ini")) 190 { CHECK_DRVCONN_DIALBOX (drvbuf); } 191 if (SQLGetPrivateProfileString (drv, "Setup", "", drvbuf, 192 sizeof (drvbuf), "odbcinst.ini")) 193 { CHECK_DRVCONN_DIALBOX (drvbuf); } 194 if (SQLGetPrivateProfileString ("Default", "Driver", "", drvbuf, 195 sizeof (drvbuf), "odbcinst.ini")) 196 { CHECK_DRVCONN_DIALBOX (drvbuf); } 197 if (SQLGetPrivateProfileString ("Default", "Setup", "", drvbuf, 198 sizeof (drvbuf), "odbcinst.ini")) 199 { CHECK_DRVCONN_DIALBOX (drvbuf); } 200 201quit: 202 203 return retVal; 204} 205 206 207#define RETURN(_ret) \ 208 do { \ 209 retcode = _ret; \ 210 goto end; \ 211 } while (0) 212 213#if 0 214#define DPRINTF(a) fprintf a 215#else 216#define DPRINTF(a) 217#endif 218 219 220static SQLRETURN 221_iodbcdm_SetConnectOption_init ( 222 SQLHDBC hdbc, 223 SQLUSMALLINT fOption, 224 SQLULEN vParam, 225 UCHAR waMode) 226{ 227 CONN (pdbc, hdbc); 228 ENVR (penv, pdbc->henv); 229 HPROC hproc = SQL_NULL_HPROC; 230 SQLRETURN retcode = SQL_SUCCESS; 231 int retinfo = 0; 232 233 SQLINTEGER strLength = 0; 234 void *ptr = (void *) vParam; 235 void *_vParam = NULL; 236 237 if (fOption >= 1000) 238 { 239 retinfo = 1; /* Change SQL_ERROR -> SQL_SUCCESS_WITH_INFO */ 240 } 241 242 if ((penv->unicode_driver && waMode != 'W') 243 || (!penv->unicode_driver && waMode == 'W')) 244 { 245 switch (fOption) 246 { 247 case SQL_ATTR_TRACEFILE: 248 case SQL_CURRENT_QUALIFIER: 249 case SQL_TRANSLATE_DLL: 250 case SQL_APPLICATION_NAME: 251 case SQL_COPT_SS_ENLIST_IN_DTC: 252 case SQL_COPT_SS_PERF_QUERY_LOG: 253 case SQL_COPT_SS_PERF_DATA_LOG: 254 case SQL_CURRENT_SCHEMA: 255 if (waMode != 'W') 256 { 257 /* ansi=>unicode*/ 258 _vParam = dm_SQL_A2W((SQLCHAR *)vParam, SQL_NTS); 259 } 260 else 261 { 262 /* unicode=>ansi*/ 263 _vParam = dm_SQL_W2A((SQLWCHAR *)vParam, SQL_NTS); 264 } 265 ptr = _vParam; 266 strLength = SQL_NTS; 267 break; 268 } 269 } 270 271 if (penv->unicode_driver) 272 { 273 /* SQL_XXX_W */ 274 if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectOptionW)) 275 != SQL_NULL_HPROC) 276 { 277 CALL_DRIVER (hdbc, pdbc, retcode, hproc, 278 (pdbc->dhdbc, fOption, ptr)); 279 } 280#if (ODBCVER >= 0x300) 281 else if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectAttrW)) 282 != SQL_NULL_HPROC) 283 { 284 CALL_DRIVER (hdbc, pdbc, retcode, hproc, 285 (pdbc->dhdbc, fOption, ptr, strLength)); 286 } 287#endif 288 } 289 else 290 { 291 /* SQL_XXX */ 292 /* SQL_XXX_A */ 293 if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectOption)) 294 != SQL_NULL_HPROC) 295 { 296 CALL_DRIVER (hdbc, pdbc, retcode, hproc, 297 (pdbc->dhdbc, fOption, vParam)); 298 } 299 else if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectOptionA)) 300 != SQL_NULL_HPROC) 301 { 302 CALL_DRIVER (hdbc, pdbc, retcode, hproc, 303 (pdbc->dhdbc, fOption, vParam)); 304 } 305#if (ODBCVER >= 0x300) 306 else if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectAttr)) 307 != SQL_NULL_HPROC) 308 { 309 CALL_DRIVER (hdbc, pdbc, retcode, hproc, 310 (pdbc->dhdbc, fOption, vParam, strLength)); 311 } 312 else if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectAttrA)) 313 != SQL_NULL_HPROC) 314 { 315 CALL_DRIVER (hdbc, pdbc, retcode, hproc, 316 (pdbc->dhdbc, fOption, vParam, strLength)); 317 } 318#endif 319 } 320 MEM_FREE(_vParam); 321 322 if (hproc == SQL_NULL_HPROC) 323 { 324 PUSHSQLERR (pdbc->herr, en_IM004); 325 return SQL_SUCCESS_WITH_INFO; 326 } 327 328 if (retcode != SQL_SUCCESS && retinfo) 329 return SQL_SUCCESS_WITH_INFO; 330 331 return retcode; 332} 333 334 335static SQLRETURN 336_iodbcdm_getInfo_init (SQLHDBC hdbc, 337 SQLUSMALLINT fInfoType, 338 SQLPOINTER rgbInfoValue, 339 SQLSMALLINT cbInfoValueMax, 340 SQLSMALLINT * pcbInfoValue, 341 SQLCHAR waMode) 342{ 343 CONN (pdbc, hdbc); 344 ENVR (penv, pdbc->henv); 345 HPROC hproc = SQL_NULL_HPROC; 346 SQLRETURN retcode = SQL_SUCCESS; 347 348 waMode = waMode; /*UNUSED*/ 349 350 switch(fInfoType) 351 { 352 case SQL_CURSOR_COMMIT_BEHAVIOR: 353 case SQL_CURSOR_ROLLBACK_BEHAVIOR: 354 break; 355 default: 356 return SQL_ERROR; 357 } 358 359 CALL_UDRIVER(hdbc, pdbc, retcode, hproc, penv->unicode_driver, 360 en_GetInfo, ( 361 pdbc->dhdbc, 362 fInfoType, 363 rgbInfoValue, 364 cbInfoValueMax, 365 pcbInfoValue)); 366 367 if (hproc == SQL_NULL_HPROC) 368 { 369 PUSHSQLERR (pdbc->herr, en_IM004); 370 return SQL_SUCCESS_WITH_INFO; 371 } 372 373 return retcode; 374} 375 376 377static SQLRETURN 378_iodbcdm_finish_disconnect (HDBC hdbc, BOOL driver_disconnect) 379{ 380 CONN (pdbc, hdbc); 381 HPROC hproc = SQL_NULL_HPROC; 382 383 DPRINTF ((stderr, 384 "DEBUG: _iodbcdm_finish_disconnect (conn %p, driver_disconnect %d)\n", 385 hdbc, driver_disconnect)); 386 387 if (driver_disconnect) 388 { 389 SQLRETURN retcode; 390 391 hproc = _iodbcdm_getproc (pdbc, en_Disconnect); 392 if (hproc == SQL_NULL_HPROC) 393 { 394 PUSHSQLERR (pdbc->herr, en_IM001); 395 return SQL_ERROR; 396 } 397 398 ODBC_UNLOCK (); 399 CALL_DRIVER (hdbc, pdbc, retcode, hproc, (pdbc->dhdbc)); 400 ODBC_LOCK (); 401 402 if (!SQL_SUCCEEDED (retcode)) 403 { 404 /* diff from MS specs. We disallow 405 * driver SQLDisconnect() return 406 * SQL_SUCCESS_WITH_INFO and post 407 * error message. 408 */ 409 return retcode; 410 } 411 } 412 413 /* free all statement handle(s) on this connection */ 414 while (pdbc->hstmt != NULL) 415 _iodbcdm_dropstmt (pdbc->hstmt); 416 417 /* state transition */ 418 pdbc->state = en_dbc_allocated; 419 420 return SQL_SUCCESS; 421} 422 423 424#if (ODBCVER >= 0x300) 425/* 426 * Set Retry Wait timeout 427 */ 428static void 429_iodbcdm_pool_set_retry_wait (HDBC hdbc) 430{ 431 CONN (pdbc, hdbc); 432 int retry_wait = 0; 433 char buf[1024]; 434 435 /* Get the "Retry Wait" keyword value from the Pooling section */ 436 SQLSetConfigMode (ODBC_BOTH_DSN); 437 if (SQLGetPrivateProfileString ("ODBC Connection Pooling", "Retry Wait", "", 438 buf, sizeof (buf), "odbcinst.ini") != 0 && 439 buf[0] != '\0') 440 retry_wait = atoi(buf); 441 442 DPRINTF ((stderr, "DEBUG: setting RetryWait %d (conn %p)\n", 443 retry_wait, hdbc)); 444 pdbc->cp_retry_wait = time(NULL) + retry_wait; 445} 446 447 448extern SQLRETURN SQLFreeConnect_Internal (SQLHDBC hdbc); 449 450/* 451 * Drop connection from the pool 452 */ 453void 454_iodbcdm_pool_drop_conn (HDBC hdbc, HDBC hdbc_prev) 455{ 456 CONN (pdbc, hdbc); 457 CONN (pdbc_prev, hdbc_prev); 458 459 assert (!pdbc->cp_in_use); 460 461 DPRINTF ((stderr, "DEBUG: dropping connection %p (prev %p) from the pool\n", 462 hdbc, hdbc_prev)); 463 464 /* remove from pool */ 465 if (pdbc_prev != NULL) 466 pdbc_prev->next = pdbc->next; 467 else 468 { 469 GENV (genv, pdbc->genv); 470 471 genv->pdbc_pool = pdbc->next; 472 } 473 474 /* finish disconnect and free connection */ 475 _iodbcdm_finish_disconnect (hdbc, TRUE); 476 SQLFreeConnect_Internal (hdbc); 477 MEM_FREE (hdbc); 478} 479 480 481/* 482 * Copy connection parameters from src to dst and reset src parameters 483 * so that src can be correctly freed by SQLDisconnect. 484 */ 485static void 486_iodbcdm_pool_copy_conn (HDBC hdbc_dst, HDBC hdbc_src) 487{ 488 CONN (pdbc_dst, hdbc_dst); 489 CONN (pdbc_src, hdbc_src); 490 HDBC next; 491 time_t cp_timeout, cp_expiry_time; 492 493 /* Preserve `next', `cp_timeout' and `cp_expiry_time' */ 494 next = pdbc_dst->next; 495 cp_timeout = pdbc_dst->cp_timeout; 496 cp_expiry_time = pdbc_dst->cp_expiry_time; 497 *pdbc_dst = *pdbc_src; 498 pdbc_dst->next = next; 499 pdbc_dst->cp_timeout = cp_timeout; 500 pdbc_dst->cp_expiry_time = cp_expiry_time; 501 502 /* Reset parameters of source connection */ 503 pdbc_src->herr = SQL_NULL_HERR; 504 pdbc_src->dhdbc = SQL_NULL_HDBC; 505 pdbc_src->henv = SQL_NULL_HENV; 506 pdbc_src->hstmt = SQL_NULL_HSTMT; 507 pdbc_src->hdesc = SQL_NULL_HDESC; 508 pdbc_src->current_qualifier = NULL; 509 pdbc_src->drvopt = NULL; 510 511 pdbc_src->cp_probe = NULL; 512 pdbc_src->cp_dsn = NULL; 513 pdbc_src->cp_uid = NULL; 514 pdbc_src->cp_pwd = NULL; 515 pdbc_src->cp_connstr = NULL; 516} 517 518 519/* 520 * Check if attributes of two connections match 521 */ 522static BOOL 523_iodbcdm_pool_check_attr_match (HDBC hdbc, HDBC cp_hdbc) 524{ 525 CONN (pdbc, hdbc); 526 GENV (genv, pdbc->genv); 527 CONN (cp_pdbc, cp_hdbc); 528 BOOL strict_match = (genv->cp_match == SQL_CP_STRICT_MATCH); 529 530 DPRINTF ((stderr, "DEBUG: check attr match (conn %p, cp_conn %p)\n", 531 hdbc, cp_hdbc)); 532 533 /* 534 * Check attrs that must be set before connection has been made: 535 * - SQL_ATTR_PACKET_SIZE (packet_size) 536 * - SQL_ATTR_ODBC_CURSORS (odbc_cursors) 537 * 538 * SQL_ATTR_PACKET_SIZE can be different if !strict_match. 539 * The value of SQL_ATTR_LOGIN_TIMEOUT is not examined. 540 */ 541 if (strict_match && pdbc->packet_size != cp_pdbc->packet_size) 542 { 543 DPRINTF ((stderr, "DEBUG: packet_size does not match (conn %p, cp_conn %p, strict_match %d)", 544 hdbc, cp_hdbc, strict_match)); 545 return FALSE; 546 } 547 548 if (pdbc->odbc_cursors != cp_pdbc->odbc_cursors) 549 { 550 DPRINTF ((stderr, "DEBUG: odbc_cursors does not match (conn %p, cp_conn %p, strict_match %d)", 551 hdbc, cp_hdbc, strict_match)); 552 return FALSE; 553 } 554 555 /* 556 * Check attrs that must be set either before or after the connection 557 * has been made: 558 * - SQL_ATTR_ACCESS_MODE (access_mode, default SQL_MODE_DEFAULT) 559 * - SQL_ATTR_AUTOCOMMIT (autocommit, default SQL_AUTOCOMMIT_DEFAULT) 560 * - SQL_ATTR_CURRENT_CATALOG (current_qualifier) 561 * - SQL_ATTR_QUIET_MODE (quiet_mode) 562 * - SQL_ATTR_TXN_ISOLATION (txn_isolation, default SQL_TXN_READ_UNCOMMITTED) 563 * 564 * If an attr is not set by the application but set in the pool: 565 * - if there is a default, an attr is reset to the default value 566 * (see _iodbcdm_pool_reset_conn_attrs()). 567 * - if there is no default value, pooled connection is not considered 568 * a match 569 * 570 * If an attr is set by the application, this value overrides the 571 * value from the pool. 572 */ 573 if (pdbc->current_qualifier == NULL && cp_pdbc->current_qualifier != NULL) 574 { 575 /* has not been set by application, but set in the pool */ 576 DPRINTF ((stderr, "DEBUG: current_qualifier has not been set by application, but is set in the pool (conn %p, cp_conn %p)", 577 hdbc, cp_hdbc)); 578 return FALSE; 579 } 580 581 if (pdbc->quiet_mode == 0 && cp_pdbc->quiet_mode != 0) 582 { 583 /* has not been set by application, but set in the pool */ 584 DPRINTF ((stderr, "DEBUG: quiet_mode has not been set by application, but is set in the pool (conn %p, cp_conn %p)", 585 hdbc, cp_hdbc)); 586 return FALSE; 587 } 588 589 return TRUE; 590} 591 592 593/* 594 * Reset connection attributes to the default values (if an attr is not set 595 * by application and there is a default) or to the value set by application. 596 */ 597SQLRETURN 598_iodbcdm_pool_reset_conn_attrs (SQLHDBC hdbc, SQLHDBC cp_hdbc) 599{ 600 CONN (pdbc, hdbc); 601 CONN (cp_pdbc, cp_hdbc); 602 SQLRETURN retcode = SQL_SUCCESS; 603 SQLRETURN ret; 604 605 if (pdbc->access_mode != cp_pdbc->access_mode) 606 { 607 cp_pdbc->access_mode = pdbc->access_mode; 608 609 ret = _iodbcdm_SetConnectOption_init ( 610 cp_pdbc, SQL_ACCESS_MODE, cp_pdbc->access_mode, 'A'); 611 retcode |= ret; 612 } 613 614 if (pdbc->autocommit != cp_pdbc->autocommit) 615 { 616 cp_pdbc->autocommit = pdbc->autocommit; 617 618 ret = _iodbcdm_SetConnectOption_init ( 619 cp_pdbc, SQL_AUTOCOMMIT, cp_pdbc->autocommit, 'A'); 620 retcode |= ret; 621 } 622 623 if (pdbc->current_qualifier != NULL) 624 { 625 if (cp_pdbc->current_qualifier != NULL) 626 MEM_FREE (cp_pdbc->current_qualifier); 627 cp_pdbc->current_qualifier = pdbc->current_qualifier; 628 pdbc->current_qualifier = NULL; 629 cp_pdbc->current_qualifier_WA = pdbc->current_qualifier_WA; 630 631 ret = _iodbcdm_SetConnectOption_init ( 632 cp_pdbc, SQL_CURRENT_QUALIFIER, 633 (SQLULEN) cp_pdbc->current_qualifier, cp_pdbc->current_qualifier_WA); 634 retcode |= ret; 635 } 636 637 if (cp_pdbc->quiet_mode != pdbc->quiet_mode) 638 { 639 cp_pdbc->quiet_mode = pdbc->quiet_mode; 640 641 ret = _iodbcdm_SetConnectOption_init ( 642 cp_pdbc, SQL_QUIET_MODE, cp_pdbc->quiet_mode, 'A'); 643 retcode |= ret; 644 } 645 646 if (pdbc->txn_isolation != cp_pdbc->txn_isolation) 647 { 648 cp_pdbc->txn_isolation = pdbc->txn_isolation; 649 650 ret = _iodbcdm_SetConnectOption_init ( 651 cp_pdbc, SQL_TXN_ISOLATION, cp_pdbc->txn_isolation, 'A'); 652 retcode |= ret; 653 } 654 655 return retcode; 656} 657 658 659extern SQLRETURN 660SQLAllocStmt_Internal (SQLHDBC hdbc, SQLHSTMT *phstmt); 661extern SQLRETURN 662SQLFreeStmt_Internal (SQLHSTMT hstmt, SQLUSMALLINT fOption); 663extern SQLRETURN SQL_API 664SQLExecDirect_Internal (SQLHSTMT hstmt, 665 SQLPOINTER szSqlStr, SQLINTEGER cbSqlStr, SQLCHAR waMode); 666extern SQLRETURN SQLFetch_Internal (SQLHSTMT hstmt); 667 668/* 669 * Execute CPProbe statement to check if connection is dead 670 */ 671static SQLRETURN 672_iodbcdm_pool_exec_cpprobe (HDBC hdbc, char *cp_probe) 673{ 674 HSTMT hstmt = SQL_NULL_HSTMT; 675 SQLRETURN retcode; 676 SQLSMALLINT num_cols; 677 678 DPRINTF ((stderr, "DEBUG: executing CPProbe (conn %p, stmt [%s])\n", 679 hdbc, cp_probe)); 680 681 /* allocate statement handle */ 682 retcode = SQLAllocStmt_Internal (hdbc, &hstmt); 683 if (!SQL_SUCCEEDED (retcode)) 684 RETURN (retcode); 685 686 /* execute statement */ 687 retcode = SQLExecDirect_Internal (hstmt, cp_probe, SQL_NTS, 'A'); 688 if (!SQL_SUCCEEDED (retcode)) 689 RETURN (retcode); 690 691 /* check that there is a result set */ 692 retcode = _iodbcdm_NumResultCols (hstmt, &num_cols); 693 if (!SQL_SUCCEEDED (retcode)) 694 RETURN (retcode); 695 696 /* if there was no result set -- success */ 697 if (num_cols == 0) 698 RETURN (SQL_SUCCESS); 699 700 /* fetch results */ 701 do 702 { 703 retcode = SQLFetch_Internal (hstmt); 704 if (!SQL_SUCCEEDED (retcode)) 705 RETURN (retcode); 706 } 707 while (retcode != SQL_NO_DATA); 708 709 /* success */ 710 RETURN (SQL_SUCCESS); 711 712end: 713 if (hstmt != SQL_NULL_HSTMT) 714 SQLFreeStmt_Internal (hstmt, SQL_DROP); 715 return retcode; 716} 717 718 719/* 720 * Check if connection is dead 721 */ 722static BOOL 723_iodbcdm_pool_conn_dead (HDBC hdbc) 724{ 725 CONN (pdbc, hdbc); 726 HPROC hproc = SQL_NULL_HPROC; 727 SQLRETURN retcode; 728 SQLINTEGER attr_dead; 729 730 DPRINTF ((stderr, "DEBUG: checking if connection is dead (conn %p)\n", 731 hdbc)); 732 733 /* first try SQLGetConnectAttr */ 734 CALL_UDRIVER(pdbc, pdbc, retcode, hproc, 'A', en_GetConnectAttr, 735 (pdbc->dhdbc, SQL_ATTR_CONNECTION_DEAD, &attr_dead, 0, NULL)); 736 if (hproc != SQL_NULL_HPROC && SQL_SUCCEEDED (retcode)) 737 { 738 DPRINTF ((stderr, "DEBUG: GetConnectAttr: attr_dead = %ld (conn %p)\n", 739 attr_dead, hdbc)); 740 return attr_dead == SQL_CD_TRUE; 741 } 742 743 /* try SQLGetConnectOption */ 744 CALL_UDRIVER(pdbc, pdbc, retcode, hproc, 'A', en_GetConnectOption, 745 (pdbc->dhdbc, SQL_ATTR_CONNECTION_DEAD, &attr_dead)); 746 if (hproc != SQL_NULL_HPROC && SQL_SUCCEEDED (retcode)) 747 { 748 DPRINTF ((stderr, "DEBUG: GetConnectOption: attr_dead = %ld (conn %p)\n", 749 attr_dead, hdbc)); 750 return attr_dead == SQL_CD_TRUE; 751 } 752 753 /* try CPProbe statement */ 754 if (pdbc->cp_probe != NULL && STRLEN(pdbc->cp_probe) > 0) 755 { 756 retcode = _iodbcdm_pool_exec_cpprobe (pdbc, pdbc->cp_probe); 757 return SQL_SUCCEEDED (retcode); 758 } 759 760 /* don't know, assume it is alive */ 761 return FALSE; 762} 763 764 765/* 766 * Get the connection from to the pool 767 * 768 * Returns 0 if the connection was put successfully 769 * Returns -1 otherwise 770 */ 771static SQLRETURN 772_iodbcdm_pool_get_conn ( 773 HDBC hdbc, char *dsn, char *uid, char *pwd, char *connstr) 774{ 775 CONN (pdbc, hdbc); 776 GENV (genv, pdbc->genv); 777 DBC_t *cp_pdbc, *cp_pdbc_next, *cp_pdbc_prev = NULL; 778 time_t current_time; 779 780 DPRINTF ((stderr, "DEBUG: getting connection %p from the pool (dsn [%s], uid [%s], pwd [%s], connstr [%s])\n", 781 hdbc, dsn, uid, pwd, connstr)); 782 783 current_time = time(NULL); 784 785 for (cp_pdbc = genv->pdbc_pool; cp_pdbc != NULL; 786 cp_pdbc_prev = cp_pdbc, cp_pdbc = cp_pdbc_next) 787 { 788 SQLRETURN retcode; 789 790 cp_pdbc_next = cp_pdbc->next; 791 792 /* skip connections in use */ 793 if (cp_pdbc->cp_in_use) 794 { 795 DPRINTF ((stderr, "DEBUG: skipping connection %p (in use)\n", 796 cp_pdbc)); 797 continue; 798 } 799 800 /* 801 * Check that pooled connection timeout has not expired 802 */ 803 if (current_time >= cp_pdbc->cp_expiry_time) 804 { 805 DPRINTF ((stderr, "DEBUG: connection %p expired (cp_expiry_time %d, current_time %d)\n", 806 cp_pdbc, cp_pdbc->cp_expiry_time, current_time)); 807 _iodbcdm_pool_drop_conn (cp_pdbc, cp_pdbc_prev); 808 continue; 809 } 810 811 /* 812 * Check that requested dsn, uid, pwd and connstr match 813 * pooled connection 814 */ 815 if (dsn != NULL) 816 { 817 if (cp_pdbc->cp_dsn == NULL || 818 strcmp (dsn, cp_pdbc->cp_dsn) != 0) 819 continue; 820 } 821 else if (cp_pdbc->cp_dsn != NULL) 822 continue; 823 if (uid != NULL) 824 { 825 if (cp_pdbc->cp_uid == NULL || 826 strcmp (uid, cp_pdbc->cp_uid) != 0) 827 continue; 828 } 829 else if (cp_pdbc->cp_uid != NULL) 830 continue; 831 if (pwd != NULL) 832 { 833 if (cp_pdbc->cp_pwd == NULL || 834 strcmp (pwd, cp_pdbc->cp_pwd) != 0) 835 continue; 836 } 837 else if (cp_pdbc->cp_pwd != NULL) 838 continue; 839 if (connstr != NULL) 840 { 841 if (cp_pdbc->cp_connstr == NULL || 842 strcmp (connstr, cp_pdbc->cp_connstr) != 0) 843 continue; 844 } 845 else if (cp_pdbc->cp_connstr != NULL) 846 continue; 847 848 DPRINTF ((stderr, "DEBUG: found matching pooled connection %p\n", 849 cp_pdbc)); 850 851 /* check that connection attributes match */ 852 if (!_iodbcdm_pool_check_attr_match (pdbc, cp_pdbc)) 853 continue; 854 855 /* 856 * Match found! 857 */ 858 859 /* 860 * Check Retry Wait timeout 861 */ 862 if (cp_pdbc->cp_retry_wait != 0) 863 { 864 if (current_time < cp_pdbc->cp_retry_wait) 865 { 866 /* Retry Wait timeout has not expired yet */ 867 DPRINTF ((stderr, 868 "DEBUG: RetryWait timeout has not expired yet (cp_pdbc %p, cp_retry_wait %d, current_time %d)\n", 869 cp_pdbc, cp_pdbc->cp_retry_wait, current_time)); 870 871 /* remember matching pooled connection */ 872 pdbc->cp_pdbc = cp_pdbc; 873 874 return SQL_ERROR; 875 } 876 877 DPRINTF ((stderr, "DEBUG: RetryWait timeout reset (cp_pdbc %p)\n", 878 cp_pdbc)); 879 /* reset Retry Wait timeout */ 880 cp_pdbc->cp_retry_wait = 0; 881 } 882 883 /* 884 * Check if connection is dead 885 */ 886 if (_iodbcdm_pool_conn_dead (cp_pdbc)) 887 { 888 /* Connection is dead -- try to reconnect */ 889 DPRINTF ((stderr, "DEBUG: pooled connection is dead (cp_pdbc %p)\n", 890 cp_pdbc)); 891 892 /* remember matching pooled connection */ 893 pdbc->cp_pdbc = cp_pdbc; 894 cp_pdbc->cp_in_use = TRUE; 895 896 return SQL_ERROR; 897 } 898 899 /* reset connection attrs */ 900 retcode = _iodbcdm_pool_reset_conn_attrs (pdbc, cp_pdbc); 901 if (retcode != SQL_SUCCESS) 902 retcode = SQL_SUCCESS_WITH_INFO; 903 904 /* copy parameters */ 905 _iodbcdm_pool_copy_conn (pdbc, cp_pdbc); 906 907 /* remember matching pooled connection */ 908 pdbc->cp_pdbc = cp_pdbc; 909 cp_pdbc->cp_in_use = TRUE; 910 911 DPRINTF ((stderr, "DEBUG: got connection from the pool (cp_pdbc %p)\n", 912 cp_pdbc)); 913 /* found a connection in a pool */ 914 return retcode; 915 } 916 917 DPRINTF ((stderr, "DEBUG: no matching connection in the pool\n")); 918 /* can't find a connection in a pool */ 919 return SQL_ERROR; 920} 921 922 923/* 924 * Put the conneciton back to the pool 925 * 926 * Return 0 if the connection was put successfully 927 * Return -1 otherwise 928 */ 929static int 930_iodbcdm_pool_put_conn (HDBC hdbc) 931{ 932 CONN (pdbc, hdbc); 933 GENV (genv, NULL); 934 DBC_t *cp_pdbc = pdbc->cp_pdbc; 935 936 DPRINTF ((stderr, "DEBUG: putting connection back to the pool (conn %p, dsn [%s], uid [%s], pwd [%s], connstr [%s])\n", 937 hdbc, pdbc->cp_dsn, pdbc->cp_uid, pdbc->cp_pwd, pdbc->cp_connstr)); 938 939 if (cp_pdbc == NULL) 940 { 941 cp_pdbc = (DBC_t *) MEM_ALLOC (sizeof (DBC_t)); 942 if (cp_pdbc == NULL) 943 { 944 return -1; 945 } 946 947 /* put to the pool */ 948 genv = (GENV_t *) pdbc->genv; 949 cp_pdbc->next = genv->pdbc_pool; 950 genv->pdbc_pool = cp_pdbc; 951 952 cp_pdbc->cp_timeout = pdbc->cp_timeout; 953 DPRINTF ((stderr, "DEBUG: new pooled connection %p\n", cp_pdbc)); 954 } 955 956 /* copy out parameters */ 957 _iodbcdm_pool_copy_conn(cp_pdbc, pdbc); 958 pdbc->cp_pdbc = NULL; 959 960 /* free all statement handle(s) on connection in pool */ 961 while (cp_pdbc->hstmt != NULL) 962 _iodbcdm_dropstmt (cp_pdbc->hstmt); 963 964 /* set expiration time and other parameters for connection in pool */ 965 cp_pdbc->cp_pdbc = NULL; 966 if (cp_pdbc->cp_retry_wait == 0) 967 { 968 /* set new expiry time only if we are not returning the connection 969 to the pool after unsuccessfull reconnect attempt */ 970 cp_pdbc->cp_expiry_time = time(NULL) + cp_pdbc->cp_timeout; 971 } 972 cp_pdbc->cp_in_use = FALSE; 973 974 DPRINTF ((stderr, "DEBUG: connection %p put back to the pool (cp_pdbc %p, cp_timeout %d)\n", 975 hdbc, cp_pdbc, cp_pdbc->cp_timeout)); 976 return 0; 977} 978#endif /* (ODBCVER >= 0x300) */ 979 980 981/* - Load driver share library( or increase its reference count 982 * if it has already been loaded by another active connection) 983 * - Call driver's SQLAllocEnv() (for the first reference only) 984 * - Call driver's SQLAllocConnect() 985 * - Call driver's SQLSetConnectOption() (set login time out) 986 * - Increase the bookkeeping reference count 987 */ 988SQLRETURN 989_iodbcdm_driverload ( 990 char * dsn, 991 char * drv, 992 HDBC hdbc, 993 SWORD thread_safe, 994 SWORD unload_safe, 995 UCHAR waMode) 996{ 997 CONN (pdbc, hdbc); 998 ENVR (penv, NULL); 999 GENV (genv, NULL); 1000 HDLL hdll = SQL_NULL_HDLL; 1001 HPROC hproc; 1002 SQLRETURN retcode = SQL_SUCCESS; 1003 sqlstcode_t sqlstat = en_00000; 1004 char buf[1024]; 1005 char path_tmp[1024]; 1006 char *path = drv; 1007 char cp_probe[1024] = {""}; 1008 int cp_timeout = 0; 1009 1010 if (drv == NULL || ((char*)drv)[0] == '\0') 1011 { 1012 PUSHSQLERR (pdbc->herr, en_IM002); 1013 return SQL_ERROR; 1014 } 1015 1016 if (!IS_VALID_HDBC (pdbc) || pdbc->genv == SQL_NULL_HENV) 1017 { 1018 return SQL_INVALID_HANDLE; 1019 } 1020 1021 /* 1022 * If drv does not start with / or ., we may have a symbolic driver name 1023 */ 1024 if (!(drv[0] == '/' || drv[0] == '.')) 1025 { 1026 char *tmp_drv = NULL; 1027 1028 /* 1029 * Remove curly braces 1030 */ 1031 if (drv[0] == '{') 1032 { 1033 tmp_drv = strdup (drv); 1034 if (tmp_drv[strlen (drv) - 1] == '}') 1035 tmp_drv[strlen (drv) - 1] = '\0'; 1036 drv = &tmp_drv[1]; 1037 } 1038 1039 /* 1040 * Hopefully the driver was registered under that name in the 1041 * odbcinst.ini file 1042 */ 1043 if (SQLGetPrivateProfileString ((char *) drv, "Driver", "", 1044 path_tmp, sizeof (path_tmp), "odbcinst.ini") && path_tmp[0]) 1045 path = path_tmp; 1046 1047 if (tmp_drv) 1048 free (tmp_drv); 1049 1050 /* 1051 * Get CPTimeout value 1052 */ 1053 SQLSetConfigMode (ODBC_BOTH_DSN); 1054 if (SQLGetPrivateProfileString (drv, "CPTimeout", "", 1055 buf, sizeof(buf), "odbcinst.ini") && buf[0]) 1056 cp_timeout = atoi(buf); 1057 1058 /* 1059 * Get CPProbe value 1060 */ 1061 SQLGetPrivateProfileString (drv, "CPProbe", "", 1062 cp_probe, sizeof(cp_probe), "odbcinst.ini"); 1063 } 1064 else if (dsn != NULL && *dsn != '\0') 1065 { 1066 char tmp_drv[1024] = {""}; 1067 1068 SQLSetConfigMode (ODBC_BOTH_DSN); 1069 if (SQLGetPrivateProfileString ("ODBC Data Sources", dsn, "", 1070 tmp_drv, sizeof(tmp_drv), NULL) && tmp_drv[0]) 1071 { 1072 /* 1073 * Get CPTimeout value 1074 */ 1075 if (SQLGetPrivateProfileString (tmp_drv, "CPTimeout", "", 1076 buf, sizeof(buf), "odbcinst.ini") && buf[0]) 1077 cp_timeout = atoi(buf); 1078 1079 /* 1080 * Get CPProbe value 1081 */ 1082 SQLGetPrivateProfileString (tmp_drv, "CPProbe", "", 1083 cp_probe, sizeof(cp_probe), "odbcinst.ini"); 1084 } 1085 } 1086 1087 genv = (GENV_t *) pdbc->genv; 1088 1089 /* This will either load the driver dll or increase its reference count */ 1090 hdll = _iodbcdm_dllopen ((char *) path); 1091 1092 /* Set flag if it is safe to unload the driver after use */ 1093 if (unload_safe) 1094 _iodbcdm_safe_unload (hdll); 1095 1096 if (hdll == SQL_NULL_HDLL) 1097 { 1098 PUSHSYSERR (pdbc->herr, _iodbcdm_dllerror ()); 1099 PUSHSQLERR (pdbc->herr, en_IM003); 1100 return SQL_ERROR; 1101 } 1102 1103 penv = (ENV_t *) (pdbc->henv); 1104 1105 if (penv != NULL) 1106 { 1107 if (penv->hdll != hdll) 1108 { 1109 _iodbcdm_driverunload (hdbc, 3); 1110 penv->hdll = hdll; 1111 } 1112 else 1113 { 1114 /* 1115 * this will not unload the driver but only decrease its internal 1116 * reference count 1117 */ 1118 _iodbcdm_dllclose (hdll); 1119 } 1120 } 1121 1122 if (penv == NULL) 1123 { 1124 /* 1125 * find out whether this dll has already been loaded on another 1126 * connection 1127 */ 1128 for (penv = (ENV_t *) genv->henv; 1129 penv != NULL; 1130 penv = (ENV_t *) penv->next) 1131 { 1132 if (penv->hdll == hdll) 1133 { 1134 /* 1135 * this will not unload the driver but only decrease its internal 1136 * reference count 1137 */ 1138 _iodbcdm_dllclose (hdll); 1139 break; 1140 } 1141 } 1142 1143 if (penv == NULL) 1144 /* no connection attaching with this dll */ 1145 { 1146 int i; 1147 1148 /* create a new dll env instance */ 1149 penv = (ENV_t *) MEM_ALLOC (sizeof (ENV_t)); 1150 1151 if (penv == NULL) 1152 { 1153 _iodbcdm_dllclose (hdll); 1154 1155 PUSHSQLERR (pdbc->herr, en_S1001); 1156 1157 return SQL_ERROR; 1158 } 1159 1160 /* 1161 * Initialize array of ODBC functions 1162 */ 1163 for (i = 0; i < __LAST_API_FUNCTION__; i++) 1164 { 1165#if 1 1166 (penv->dllproc_tab)[i] = SQL_NULL_HPROC; 1167#else 1168 (penv->dllproc_tab)[i] = _iodbcdm_getproc(pdbc, i); 1169#endif 1170 } 1171 1172 pdbc->henv = penv; 1173 penv->hdll = hdll; 1174 1175 /* 1176 * If the driver appears not to be thread safe, use a 1177 * driver mutex to serialize all calls to this driver 1178 */ 1179 penv->thread_safe = thread_safe; 1180 if (!penv->thread_safe) 1181 MUTEX_INIT (penv->drv_lock); 1182 1183 penv->unicode_driver = 0; 1184 /* 1185 * If the driver is Unicode 1186 */ 1187 if ( _iodbcdm_getproc (pdbc, en_ConnectW)) 1188 penv->unicode_driver = 1; 1189 1190 /* call driver's SQLAllocHandle() or SQLAllocEnv() */ 1191 1192#if (ODBCVER >= 0x0300) 1193 hproc = _iodbcdm_getproc (pdbc, en_AllocHandle); 1194 1195 if (hproc) 1196 { 1197 CALL_DRIVER (hdbc, genv, retcode, hproc, 1198 (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(penv->dhenv))); 1199 if (SQL_SUCCEEDED (retcode)) 1200 { 1201 /* 1202 * This appears to be an ODBC3 driver 1203 * 1204 * Try to set the app's requested version 1205 */ 1206 SQLRETURN save_retcode = retcode; 1207 1208 penv->dodbc_ver = SQL_OV_ODBC2; 1209 hproc = _iodbcdm_getproc (pdbc, en_SetEnvAttr); 1210 if (hproc != SQL_NULL_HPROC) 1211 { 1212 CALL_DRIVER (hdbc, genv, retcode, hproc, 1213 (penv->dhenv, SQL_ATTR_ODBC_VERSION, genv->odbc_ver, 1214 0)); 1215 if (retcode == SQL_SUCCESS) 1216 penv->dodbc_ver = SQL_OV_ODBC3; 1217 } 1218 retcode = save_retcode; 1219 } 1220 } 1221 else /* try driver's SQLAllocEnv() */ 1222#endif 1223 { 1224 hproc = _iodbcdm_getproc (pdbc, en_AllocEnv); 1225 1226 if (hproc == SQL_NULL_HPROC) 1227 { 1228 sqlstat = en_IM004; 1229 } 1230 else 1231 { 1232#if (ODBCVER >= 0x0300) 1233 penv->dodbc_ver = SQL_OV_ODBC2; 1234#endif 1235 CALL_DRIVER (hdbc, genv, retcode, hproc, (&(penv->dhenv))); 1236 } 1237 } 1238 1239 if (retcode == SQL_ERROR) 1240 { 1241 sqlstat = en_IM004; 1242 } 1243 1244 if (sqlstat != en_00000) 1245 { 1246 _iodbcdm_dllclose (hdll); 1247 MEM_FREE (penv); 1248 PUSHSQLERR (pdbc->herr, en_IM004); 1249 1250 return SQL_ERROR; 1251 } 1252 1253 /* insert into dll env list */ 1254 penv->next = (ENV_t *) genv->henv; 1255 genv->henv = penv; 1256 1257 /* initiate this new env entry */ 1258 penv->refcount = 0; /* we will increase it after 1259 * driver's SQLAllocConnect() 1260 * success 1261 */ 1262 } 1263 1264 pdbc->henv = penv; 1265 1266 if (pdbc->dhdbc == SQL_NULL_HDBC) 1267 { 1268 1269#if (ODBCVER >= 0x0300) 1270 hproc = _iodbcdm_getproc (pdbc, en_AllocHandle); 1271 1272 if (hproc) 1273 { 1274 CALL_DRIVER (hdbc, genv, retcode, hproc, 1275 (SQL_HANDLE_DBC, penv->dhenv, &(pdbc->dhdbc))); 1276 } 1277 else 1278#endif 1279 1280 { 1281 hproc = _iodbcdm_getproc (pdbc, en_AllocConnect); 1282 1283 if (hproc == SQL_NULL_HPROC) 1284 { 1285 sqlstat = en_IM005; 1286 } 1287 else 1288 { 1289 CALL_DRIVER (hdbc, genv, retcode, hproc, 1290 (penv->dhenv, &(pdbc->dhdbc))); 1291 } 1292 } 1293 1294 if (retcode == SQL_ERROR) 1295 { 1296 sqlstat = en_IM005; 1297 } 1298 1299 if (sqlstat != en_00000) 1300 { 1301 _iodbcdm_driverunload (hdbc, 3); 1302 1303 pdbc->dhdbc = SQL_NULL_HDBC; 1304 PUSHSQLERR (pdbc->herr, en_IM005); 1305 1306 return SQL_ERROR; 1307 } 1308 } 1309 1310 pdbc->henv = penv; 1311 penv->refcount++; /* bookkeeping reference count on this driver */ 1312 } 1313 1314 /* driver's login timeout option must been set before 1315 * its SQLConnect() call */ 1316 if (pdbc->login_timeout != 0UL) 1317 { 1318 retcode = _iodbcdm_SetConnectOption_init (hdbc, SQL_LOGIN_TIMEOUT, 1319 pdbc->login_timeout, waMode); 1320 1321 if (retcode == SQL_ERROR) 1322 { 1323 PUSHSQLERR (pdbc->herr, en_IM006); 1324 return SQL_SUCCESS_WITH_INFO; 1325 } 1326 } 1327 1328 /* 1329 * Now set the driver specific options we saved earlier 1330 */ 1331 if (pdbc->drvopt != NULL) 1332 { 1333 DRVOPT *popt; 1334 1335 for (popt = pdbc->drvopt; popt != NULL; popt = popt->next) 1336 { 1337 retcode = _iodbcdm_SetConnectOption_init (hdbc, popt->Option, 1338 popt->Param, popt->waMode); 1339 1340 if (retcode == SQL_ERROR) 1341 { 1342 PUSHSQLERR (pdbc->herr, en_IM006); 1343 return SQL_SUCCESS_WITH_INFO; 1344 } 1345 } 1346 } 1347 1348 pdbc->cp_timeout = cp_timeout; 1349 pdbc->cp_probe = strdup (cp_probe); 1350 1351 return SQL_SUCCESS; 1352} 1353 1354 1355/* - Call driver's SQLFreeConnect() 1356 * - Call driver's SQLFreeEnv() ( for the last reference only) 1357 * - Unload the share library( or decrease its reference 1358 * count if it is not the last reference ) 1359 * - decrease bookkeeping reference count 1360 * - state transition to allocated 1361 */ 1362SQLRETURN 1363_iodbcdm_driverunload (HDBC hdbc, int ver) 1364{ 1365 CONN (pdbc, hdbc); 1366 ENVR (penv, pdbc->henv); 1367 GENV (genv, pdbc->genv); 1368 ENV_t *tpenv; 1369 HPROC hproc2, hproc3; 1370 SQLRETURN retcode = SQL_SUCCESS; 1371 1372 if (!IS_VALID_HDBC (pdbc)) 1373 { 1374 return SQL_INVALID_HANDLE; 1375 } 1376 1377 if (penv == NULL || penv->hdll == SQL_NULL_HDLL || 1378 pdbc->dhdbc == SQL_NULL_HDBC) 1379 { 1380 return SQL_SUCCESS; 1381 } 1382 1383 /* 1384 * When calling from an ODBC 2.x application, we favor the ODBC 2.x call 1385 * in the driver if the driver implements both 1386 */ 1387 hproc2 = _iodbcdm_getproc (pdbc, en_FreeConnect); 1388#if (ODBCVER >= 0x0300) 1389 hproc3 = _iodbcdm_getproc (pdbc, en_FreeHandle); 1390 1391 if (ver == 3 && hproc2 != SQL_NULL_HPROC && hproc3 != SQL_NULL_HPROC) 1392 hproc2 = SQL_NULL_HPROC; 1393#else 1394 hproc3 = SQL_NULL_HPROC; 1395#endif 1396 1397 if (hproc2 != SQL_NULL_HPROC) 1398 { 1399 CALL_DRIVER (hdbc, pdbc, retcode, hproc2, (pdbc->dhdbc)); 1400 1401 pdbc->dhdbc = SQL_NULL_HDBC; 1402 } 1403#if (ODBCVER >= 0x0300) 1404 else if (hproc3 != SQL_NULL_HPROC) 1405 { 1406 CALL_DRIVER (hdbc, pdbc, retcode, hproc3, 1407 (SQL_HANDLE_DBC, pdbc->dhdbc)); 1408 } 1409#endif 1410 1411 penv->refcount--; 1412 1413 if (!penv->refcount) 1414 /* no other connections still attaching with this driver */ 1415 { 1416 /* 1417 * When calling from an ODBC 2.x application, we favor the ODBC 2.x call 1418 * in the driver if the driver implements both 1419 */ 1420 hproc2 = _iodbcdm_getproc (pdbc, en_FreeEnv); 1421#if (ODBCVER >= 0x0300) 1422 hproc3 = _iodbcdm_getproc (pdbc, en_FreeHandle); 1423 1424 if (ver == 3 && hproc2 != SQL_NULL_HPROC && hproc3 != SQL_NULL_HPROC) 1425 hproc2 = SQL_NULL_HPROC; 1426#else 1427 hproc3 = SQL_NULL_HPROC; 1428#endif 1429 1430 if (hproc2 != SQL_NULL_HPROC) 1431 { 1432 CALL_DRIVER (hdbc, genv, retcode, hproc2, (penv->dhenv)); 1433 1434 penv->dhenv = SQL_NULL_HENV; 1435 } 1436#if (ODBCVER >= 0x0300) 1437 else if (hproc3 != SQL_NULL_HPROC) 1438 { 1439 CALL_DRIVER (hdbc, genv, retcode, hproc3, 1440 (SQL_HANDLE_ENV, penv->dhenv)); 1441 } 1442#endif 1443 1444 _iodbcdm_dllclose (penv->hdll); 1445 1446 penv->hdll = SQL_NULL_HDLL; 1447 1448 for (tpenv = (ENV_t *) genv->henv; 1449 tpenv != NULL; tpenv = (ENV_t *) penv->next) 1450 { 1451 if (tpenv == penv) 1452 { 1453 genv->henv = penv->next; 1454 break; 1455 } 1456 1457 if (tpenv->next == penv) 1458 { 1459 tpenv->next = penv->next; 1460 break; 1461 } 1462 } 1463 1464 MEM_FREE (penv); 1465 } 1466 1467 /* pdbc->henv = SQL_NULL_HENV; */ 1468 pdbc->hstmt = SQL_NULL_HSTMT; 1469 /* pdbc->herr = SQL_NULL_HERR; 1470 -- delay to DM's SQLFreeConnect() */ 1471 pdbc->dhdbc = SQL_NULL_HDBC; 1472 pdbc->state = en_dbc_allocated; 1473 1474 /* set connect options to default values */ 1475 /********** 1476 pdbc->access_mode = SQL_MODE_DEFAULT; 1477 pdbc->autocommit = SQL_AUTOCOMMIT_DEFAULT; 1478 pdbc->login_timeout = 0UL; 1479 **********/ 1480 pdbc->odbc_cursors = SQL_CUR_DEFAULT; 1481 pdbc->packet_size = 0UL; 1482 pdbc->quiet_mode = (UDWORD) NULL; 1483 pdbc->txn_isolation = SQL_TXN_READ_UNCOMMITTED; 1484 1485#if (ODBCVER >= 0x0300) 1486 if (pdbc->cp_probe != NULL) 1487 { 1488 MEM_FREE (pdbc->cp_probe); 1489 pdbc->cp_probe = NULL; 1490 } 1491 if (pdbc->cp_dsn != NULL) 1492 { 1493 MEM_FREE (pdbc->cp_dsn); 1494 pdbc->cp_dsn = NULL; 1495 } 1496 if (pdbc->cp_uid != NULL) 1497 { 1498 MEM_FREE (pdbc->cp_uid); 1499 pdbc->cp_uid = NULL; 1500 } 1501 if (pdbc->cp_pwd != NULL) 1502 { 1503 MEM_FREE (pdbc->cp_pwd); 1504 pdbc->cp_pwd = NULL; 1505 } 1506 if (pdbc->cp_connstr != NULL) 1507 { 1508 MEM_FREE (pdbc->cp_connstr); 1509 pdbc->cp_connstr = NULL; 1510 } 1511#endif 1512 1513 if (pdbc->current_qualifier != NULL) 1514 { 1515 MEM_FREE (pdbc->current_qualifier); 1516 pdbc->current_qualifier = NULL; 1517 } 1518 1519 return SQL_SUCCESS; 1520} 1521 1522 1523static SQLRETURN 1524_iodbcdm_dbcdelayset (HDBC hdbc, UCHAR waMode) 1525{ 1526 CONN (pdbc, hdbc); 1527 SQLRETURN retcode = SQL_SUCCESS; 1528 SQLRETURN ret; 1529 1530 if (pdbc->access_mode != SQL_MODE_DEFAULT) 1531 { 1532 ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_ACCESS_MODE, 1533 pdbc->access_mode, waMode); 1534 1535 retcode |= ret; 1536 } 1537 1538 if (pdbc->autocommit != SQL_AUTOCOMMIT_DEFAULT) 1539 { 1540 ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_AUTOCOMMIT, 1541 pdbc->autocommit, waMode); 1542 1543 retcode |= ret; 1544 } 1545 1546 if (pdbc->current_qualifier != NULL) 1547 { 1548 ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_CURRENT_QUALIFIER, 1549 (SQLULEN) pdbc->current_qualifier, 1550 pdbc->current_qualifier_WA); 1551 1552 retcode |= ret; 1553 } 1554 1555 if (pdbc->packet_size != 0UL) 1556 { 1557 ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_PACKET_SIZE, 1558 pdbc->packet_size, waMode); 1559 1560 retcode |= ret; 1561 } 1562 1563 if (pdbc->quiet_mode != (UDWORD) NULL) 1564 { 1565 ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_QUIET_MODE, 1566 pdbc->quiet_mode, waMode); 1567 1568 retcode |= ret; 1569 } 1570 1571 if (pdbc->txn_isolation != SQL_TXN_READ_UNCOMMITTED) 1572 { 1573 ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_TXN_ISOLATION, 1574 pdbc->txn_isolation, waMode); 1575 1576 retcode |= ret; 1577 } 1578 1579 /* check error code for driver's SQLSetConnectOption() call */ 1580 if (!SQL_SUCCEEDED (retcode)) 1581 { 1582 PUSHSQLERR (pdbc->herr, en_IM006); 1583 retcode = SQL_ERROR; 1584 } 1585 1586 1587 /* get cursor behavior on transaction commit or rollback */ 1588 ret = _iodbcdm_getInfo_init (hdbc, SQL_CURSOR_COMMIT_BEHAVIOR, 1589 (PTR) & (pdbc->cb_commit), 1590 sizeof (pdbc->cb_commit), 1591 NULL, waMode); 1592 retcode |= ret; 1593 1594 ret = _iodbcdm_getInfo_init (hdbc, SQL_CURSOR_ROLLBACK_BEHAVIOR, 1595 (PTR) & (pdbc->cb_rollback), 1596 sizeof (pdbc->cb_rollback), 1597 NULL, waMode); 1598 retcode |= ret; 1599 1600 if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) 1601 { 1602 return SQL_ERROR; 1603 } 1604 1605 return retcode; 1606} 1607 1608 1609static SQLRETURN 1610_iodbcdm_con_settracing (HDBC hdbc, SQLCHAR *dsn, int dsnlen, UCHAR waMode) 1611{ 1612 SQLUINTEGER trace = SQL_OPT_TRACE_OFF; 1613 char buf[1024]; 1614 1615 /* Unused */ 1616 hdbc=hdbc; 1617 dsnlen=dsnlen; 1618 waMode = waMode; 1619 1620 /* Get the TraceFile keyword value from the ODBC section */ 1621 SQLSetConfigMode (ODBC_BOTH_DSN); 1622 if ((SQLGetPrivateProfileString ((char *) dsn, "TraceFile", "", 1623 buf, sizeof (buf), "odbc.ini") == 0 || !buf[0])) 1624 STRCPY (buf, SQL_OPT_TRACE_FILE_DEFAULT); 1625 1626 trace_set_filename (buf); /* UTF-8 */ 1627 1628 /* Get the Trace keyword value from the ODBC section */ 1629 SQLSetConfigMode (ODBC_BOTH_DSN); 1630 if (SQLGetPrivateProfileString ((char *) dsn, "Trace", "", 1631 buf, sizeof (buf), "odbc.ini") 1632 && (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "yes") 1633 || STRCASEEQ (buf, "1"))) 1634 { 1635 trace = SQL_OPT_TRACE_ON; 1636 } 1637 1638 /* Set the trace flag now */ 1639 if (trace == SQL_OPT_TRACE_ON) 1640 trace_start (); 1641 1642 return SQL_SUCCESS; 1643} 1644 1645 1646#define CATBUF(buf, str, buf_sz) \ 1647 do { \ 1648 if (_iodbcdm_strlcat (buf, str, buf_sz) >= buf_sz) \ 1649 return -1; \ 1650 } while (0) 1651 1652 1653/* 1654 * Merge the contents of .dsn file into config 1655 */ 1656static int 1657_iodbcdm_cfg_merge_filedsn (PCONFIG pconfig, const char *filedsn, 1658 char *buf, size_t buf_sz, int wide) 1659{ 1660 BOOL override; /* TRUE if params from conn str 1661 override params from .dsn file */ 1662 WORD len; 1663 char *p, *p_next; 1664 char entries[1024]; 1665 char value[1024]; 1666 char drv_value[1024] = {"\0"}; 1667 char *tmp = NULL; 1668 int rc = 0; 1669 1670 /* identify params precedence */ 1671 if (SQLReadFileDSN (filedsn, "ODBC", "DRIVER", value, sizeof (value), &len) && 1672 len > 0) 1673 { 1674 /* if DRIVER is the same, then conn str params have precedence */ 1675 if (_iodbcdm_cfg_find (pconfig, "ODBC", "DRIVER") == 0 && 1676 !strcasecmp (value, pconfig->value)) 1677 override = TRUE; 1678 else 1679 override = FALSE; 1680 } 1681 else 1682 override = TRUE; 1683 1684 /* get list of entries in .dsn file */ 1685 if (!SQLReadFileDSN (filedsn, "ODBC", NULL, 1686 entries, sizeof (entries), &len)) 1687 return -1; 1688 1689 /* ignore DSN from connection string */ 1690 _iodbcdm_cfg_write (pconfig, "ODBC", "DSN", NULL); 1691 1692 /* add params from the .dsn file */ 1693 for (p = entries; *p != '\0'; p = p_next) 1694 { 1695 /* get next entry */ 1696 p_next = strchr (p, ';'); 1697 if (p_next) 1698 *p_next++ = '\0'; 1699 1700 if ((override || !strcasecmp (p, "DRIVER")) && 1701 _iodbcdm_cfg_find (pconfig, "ODBC", p) == 0) 1702 { 1703 /* skip param because it is specified in connection string */ 1704 continue; 1705 } 1706 1707 if (!SQLReadFileDSN (filedsn, "ODBC", p, value, sizeof(value), &len)) 1708 return -1; 1709 _iodbcdm_cfg_write (pconfig, "ODBC", p, value); 1710 } 1711 1712 /* remove FILEDSN from new config */ 1713 _iodbcdm_cfg_write (pconfig, "ODBC", "FILEDSN", NULL); 1714 1715 if (_iodbcdm_cfg_find (pconfig, "ODBC", "DRIVER") == 0) 1716 strncpy(drv_value, pconfig->value, sizeof(drv_value)); 1717 1718 /* remove DRIVER from new config */ 1719 _iodbcdm_cfg_write (pconfig, "ODBC", "DRIVER", NULL); 1720 1721 /* construct new connection string */ 1722 if ((rc =_iodbcdm_cfg_to_string (pconfig, "ODBC", buf, buf_sz)) == -1) 1723 goto done; 1724 1725 tmp = strdup(buf); 1726 strncpy(buf, "DRIVER=", buf_sz); 1727 CATBUF(buf, drv_value, buf_sz); 1728 CATBUF(buf, ";", buf_sz); 1729 CATBUF(buf, tmp, buf_sz); 1730 MEM_FREE(tmp); 1731 1732 if (wide) 1733 { 1734 SQLWCHAR *_in = dm_SQL_U8toW (buf, SQL_NTS); 1735 if (_in == NULL) 1736 { 1737 rc = -1; 1738 goto done; 1739 } 1740 WCSNCPY (buf, _in, buf_sz / sizeof (SQLWCHAR)); 1741 MEM_FREE (_in); 1742 } 1743 1744 rc = 0; 1745 1746done: 1747 if (drv_value[0]) 1748 _iodbcdm_cfg_write (pconfig, "ODBC", "DRIVER", drv_value); 1749 1750 return rc; 1751} 1752 1753 1754/* 1755 * Save connection string into the file 1756 */ 1757static int 1758_iodbcdm_cfg_savefile (const char *savefile, void *conn_str, int wide) 1759{ 1760 int ret = 0; 1761 PCONFIG pconfig; 1762 BOOL atsection = FALSE; 1763 1764 /* parse connection string into pconfig */ 1765 if (_iodbcdm_cfg_init_str (&pconfig, conn_str, SQL_NTS, wide) == -1) 1766 return -1; 1767 1768 /* don't save PWD, FILEDSN and SAVEFILE */ 1769 _iodbcdm_cfg_write (pconfig, "ODBC", "PWD", NULL); 1770 _iodbcdm_cfg_write (pconfig, "ODBC", "FILEDSN", NULL); 1771 _iodbcdm_cfg_write (pconfig, "ODBC", "SAVEFILE", NULL); 1772 _iodbcdm_cfg_write (pconfig, "ODBC", "DSN", NULL); 1773 1774 /* save the file */ 1775 SQLWriteFileDSN (savefile, "ODBC", "DSN", NULL); 1776 _iodbcdm_cfg_rewind (pconfig); 1777 while (_iodbcdm_cfg_nextentry (pconfig) == 0) 1778 { 1779 if (atsection) 1780 { 1781 if (_iodbcdm_cfg_section (pconfig)) 1782 { 1783 /* found next section -- we're done */ 1784 break; 1785 } 1786 else if (_iodbcdm_cfg_define (pconfig)) 1787 { 1788 if (!SQLWriteFileDSN (savefile, "ODBC", 1789 pconfig->id, pconfig->value)) 1790 { 1791 ret = -1; 1792 break; 1793 } 1794 } 1795 } 1796 else if (_iodbcdm_cfg_section (pconfig) 1797 && !strcasecmp (pconfig->section, "ODBC")) 1798 atsection = TRUE; 1799 } 1800 1801 _iodbcdm_cfg_done (pconfig); 1802 return ret; 1803} 1804 1805 1806static 1807SQLRETURN SQL_API 1808SQLConnect_Internal (SQLHDBC hdbc, 1809 SQLPOINTER szDSN, 1810 SQLSMALLINT cbDSN, 1811 SQLPOINTER szUID, 1812 SQLSMALLINT cbUID, 1813 SQLPOINTER szAuthStr, 1814 SQLSMALLINT cbAuthStr, 1815 SQLCHAR waMode) 1816{ 1817 CONN (pdbc, hdbc); 1818 ENVR (penv, NULL); 1819#if (ODBCVER >= 0x300) 1820 GENV (genv, NULL); 1821#endif 1822 SQLRETURN retcode = SQL_SUCCESS; 1823 SQLRETURN setopterr = SQL_SUCCESS; 1824 /* MS SDK Guide specifies driver path can't longer than 255. */ 1825 char driver[1024] = { '\0' }; 1826 char buf[256]; 1827 HPROC hproc = SQL_NULL_HPROC; 1828 SWORD thread_safe; 1829 SWORD unload_safe; 1830 void * _szDSN = NULL; 1831 void * _szUID = NULL; 1832 void * _szAuthStr = NULL; 1833 SQLCHAR *_dsn = (SQLCHAR *) szDSN; 1834 SQLSMALLINT _dsn_len = cbDSN; 1835 1836 /* check arguments */ 1837 if ((cbDSN < 0 && cbDSN != SQL_NTS) 1838 || (cbUID < 0 && cbUID != SQL_NTS) 1839 || (cbAuthStr < 0 && cbAuthStr != SQL_NTS) 1840 || (cbDSN > SQL_MAX_DSN_LENGTH)) 1841 { 1842 PUSHSQLERR (pdbc->herr, en_S1090); 1843 RETURN (SQL_ERROR); 1844 } 1845 1846 if (szDSN == NULL || cbDSN == 0) 1847 { 1848 PUSHSQLERR (pdbc->herr, en_IM002); 1849 RETURN (SQL_ERROR); 1850 } 1851 1852 /* check state */ 1853 if (pdbc->state != en_dbc_allocated) 1854 { 1855 PUSHSQLERR (pdbc->herr, en_08002); 1856 RETURN (SQL_ERROR); 1857 } 1858 1859 1860 if (waMode == 'W') 1861 { 1862 _szDSN = (void *) dm_SQL_WtoU8((SQLWCHAR *)szDSN, cbDSN); 1863 _dsn = (SQLCHAR *) _szDSN; 1864 _dsn_len = SQL_NTS; 1865 if (_dsn == NULL) 1866 { 1867 PUSHSQLERR (pdbc->herr, en_S1001); 1868 RETURN (SQL_ERROR); 1869 } 1870 } 1871 1872 /* Get the config mode */ 1873 if (_iodbcdm_con_settracing (pdbc, _dsn, _dsn_len, waMode) == SQL_ERROR) 1874 RETURN (SQL_ERROR); 1875 1876#if (ODBCVER >= 0x300) 1877 genv = (GENV_t *) pdbc->genv; 1878 1879 if (genv->connection_pooling != SQL_CP_OFF) 1880 { 1881 char *_uid = szUID; 1882 char *_pwd = szAuthStr; 1883 1884 /* 1885 * _dsn is already an UTF8 string so 1886 * need to convert to UTF8 only szUID and szAuthStr 1887 */ 1888 if (waMode == 'W') 1889 { 1890 if (szUID != NULL) 1891 { 1892 _szUID = (void *) dm_SQL_WtoU8((SQLWCHAR *) szUID, cbUID); 1893 if (_szUID == NULL) 1894 { 1895 PUSHSQLERR (pdbc->herr, en_S1001); 1896 RETURN (SQL_ERROR); 1897 } 1898 } 1899 if (szAuthStr != NULL) 1900 { 1901 _szAuthStr = (void *) dm_SQL_WtoU8( 1902 (SQLWCHAR *) szAuthStr, cbAuthStr); 1903 if (_szAuthStr == NULL) 1904 { 1905 PUSHSQLERR (pdbc->herr, en_S1001); 1906 RETURN (SQL_ERROR); 1907 } 1908 } 1909 _uid = _szUID; 1910 _pwd = _szAuthStr; 1911 } 1912 1913 retcode = _iodbcdm_pool_get_conn (pdbc, _dsn, _uid, _pwd, NULL); 1914 if (SQL_SUCCEEDED (retcode)) 1915 { 1916 /* 1917 * Got connection from the pool 1918 */ 1919 1920 /* state transition */ 1921 pdbc->state = en_dbc_connected; 1922 1923 RETURN (retcode); 1924 } 1925 1926 if (pdbc->cp_pdbc != NULL) 1927 { 1928 /* 1929 * Dead connection was taken from pool 1930 */ 1931 1932 if (pdbc->cp_pdbc->cp_retry_wait != 0) 1933 { 1934 /* 1935 * Retry Wait timeout has not expired yet 1936 */ 1937 PUSHSQLERR (pdbc->herr, en_08004); 1938 RETURN (SQL_ERROR); 1939 } 1940 1941 /* 1942 * Free connection parameters. 1943 */ 1944 if (waMode == 'W') 1945 { 1946 if (_szUID != NULL) 1947 { 1948 MEM_FREE (_szUID); 1949 _szUID = NULL; 1950 } 1951 if (_szAuthStr != NULL) 1952 { 1953 MEM_FREE (_szAuthStr); 1954 _szAuthStr = NULL; 1955 } 1956 } 1957 } 1958 else 1959 { 1960 /* 1961 * Connection was not found in the pool -- 1962 * save connection parameters 1963 */ 1964 if (pdbc->cp_dsn != NULL) 1965 MEM_FREE (pdbc->cp_dsn); 1966 if (pdbc->cp_uid != NULL) 1967 MEM_FREE (pdbc->cp_uid); 1968 if (pdbc->cp_pwd != NULL) 1969 MEM_FREE (pdbc->cp_pwd); 1970 1971 if (waMode == 'W') 1972 { 1973 pdbc->cp_dsn = _szDSN; 1974 _szDSN = NULL; 1975 pdbc->cp_uid = _szUID; 1976 _szUID = NULL; 1977 pdbc->cp_pwd = _szAuthStr; 1978 _szAuthStr = NULL; 1979 } 1980 else 1981 { 1982 pdbc->cp_dsn = strdup (_dsn); 1983 if (pdbc->cp_dsn == NULL) 1984 { 1985 PUSHSQLERR (pdbc->herr, en_S1001); 1986 RETURN (SQL_ERROR); 1987 } 1988 if (_uid != NULL) 1989 { 1990 pdbc->cp_uid = strdup (_uid); 1991 if (pdbc->cp_uid == NULL) 1992 { 1993 PUSHSQLERR (pdbc->herr, en_S1001); 1994 RETURN (SQL_ERROR); 1995 } 1996 } 1997 if (_pwd != NULL) 1998 { 1999 pdbc->cp_pwd = strdup (_pwd); 2000 if (pdbc->cp_pwd == NULL) 2001 { 2002 PUSHSQLERR (pdbc->herr, en_S1001); 2003 RETURN (SQL_ERROR); 2004 } 2005 } 2006 } 2007 } 2008 } 2009#endif /* (ODBCVER >= 0x300) */ 2010 2011 /* 2012 * Check whether driver is thread safe 2013 */ 2014 thread_safe = 1; /* Assume driver is thread safe */ 2015 2016 SQLSetConfigMode (ODBC_BOTH_DSN); 2017 if ( SQLGetPrivateProfileString ((char *) _dsn, "ThreadManager", "", 2018 buf, sizeof(buf), "odbc.ini") && 2019 (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1"))) 2020 { 2021 thread_safe = 0; /* Driver needs a thread manager */ 2022 } 2023 2024 /* 2025 * Check if it is safe to unload the driver 2026 */ 2027 unload_safe = 0; /* Assume driver is not unload safe */ 2028 2029 SQLSetConfigMode (ODBC_BOTH_DSN); 2030 if ( SQLGetPrivateProfileString ((char *) _dsn, "UnloadSafe", "", 2031 buf, sizeof(buf), "odbc.ini") && 2032 (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1"))) 2033 { 2034 unload_safe = 1; 2035 } 2036 2037 2038 /* 2039 * Get the name of the driver module and load it 2040 */ 2041 SQLSetConfigMode (ODBC_BOTH_DSN); 2042 if ( SQLGetPrivateProfileString ((char *) _dsn, "Driver", "", 2043 (char *) driver, sizeof(driver), "odbc.ini") == 0) 2044 /* No specified or default dsn section or 2045 * no driver specification in this dsn section */ 2046 { 2047 PUSHSQLERR (pdbc->herr, en_IM002); 2048 RETURN (SQL_ERROR); 2049 } 2050 2051 MEM_FREE(_szDSN); 2052 _szDSN = NULL; 2053 2054 retcode = _iodbcdm_driverload (_dsn, (char *)driver, pdbc, thread_safe, unload_safe, waMode); 2055 2056 switch (retcode) 2057 { 2058 case SQL_SUCCESS: 2059 break; 2060 2061 case SQL_SUCCESS_WITH_INFO: 2062#if 0 2063 /* 2064 * Unsuccessful in calling driver's SQLSetConnectOption() to set 2065 * login timeout. 2066 */ 2067 setopterr = SQL_ERROR; 2068#endif 2069 break; 2070 2071 default: 2072 return retcode; 2073 } 2074 2075 penv = (ENV_t *) pdbc->henv; 2076 2077 if ((penv->unicode_driver && waMode != 'W') 2078 || (!penv->unicode_driver && waMode == 'W')) 2079 { 2080 if (waMode != 'W') 2081 { 2082 /* ansi=>unicode*/ 2083 _szDSN = dm_SQL_A2W((SQLCHAR *)szDSN, cbDSN); 2084 _szUID = dm_SQL_A2W((SQLCHAR *)szUID, cbUID); 2085 _szAuthStr = dm_SQL_A2W((SQLCHAR *)szAuthStr, cbAuthStr); 2086 } 2087 else 2088 { 2089 /* unicode=>ansi*/ 2090 _szDSN = dm_SQL_W2A((SQLWCHAR *)szDSN, cbDSN); 2091 _szUID = dm_SQL_W2A((SQLWCHAR *)szUID, cbUID); 2092 _szAuthStr = dm_SQL_W2A((SQLWCHAR *)szAuthStr, cbAuthStr); 2093 } 2094 cbDSN = SQL_NTS; 2095 cbUID = SQL_NTS; 2096 cbAuthStr = SQL_NTS; 2097 szDSN = _szDSN; 2098 szUID = _szUID; 2099 szAuthStr = _szAuthStr; 2100 } 2101 2102 ODBC_UNLOCK (); 2103 CALL_UDRIVER(hdbc, pdbc, retcode, hproc, penv->unicode_driver, 2104 en_Connect, ( 2105 pdbc->dhdbc, 2106 szDSN, 2107 cbDSN, 2108 szUID, 2109 cbUID, 2110 szAuthStr, 2111 cbAuthStr)); 2112 ODBC_LOCK (); 2113 2114 if (hproc == SQL_NULL_HPROC) 2115 { 2116 _iodbcdm_driverunload (pdbc, 3); 2117 PUSHSQLERR (pdbc->herr, en_IM001); 2118 RETURN (SQL_ERROR); 2119 } 2120 2121 if (!SQL_SUCCEEDED (retcode)) 2122 { 2123 /* not unload driver for retrieve error 2124 * message from driver */ 2125 /********* 2126 _iodbcdm_driverunload( hdbc , 3); 2127 **********/ 2128 2129 RETURN (retcode); 2130 } 2131 2132 /* state transition */ 2133 pdbc->state = en_dbc_connected; 2134 2135 /* do delayed option setting */ 2136 setopterr |= _iodbcdm_dbcdelayset (pdbc, waMode); 2137 2138 if (setopterr != SQL_SUCCESS) 2139 retcode = SQL_SUCCESS_WITH_INFO; 2140 2141end: 2142#if (ODBCVER >= 0x300) 2143 if (!SQL_SUCCEEDED (retcode) && 2144 pdbc->cp_pdbc != NULL) 2145 { 2146 int rc; 2147 2148 /* 2149 * Dead connection was taken from the pool 2150 * but reconnection attempt has failed: 2151 * set cp_retry_wait time and return connection to the pool. 2152 */ 2153 _iodbcdm_pool_set_retry_wait (pdbc); 2154 rc = _iodbcdm_pool_put_conn (pdbc); 2155 assert (rc == 0); 2156 } 2157#endif 2158 if (_szDSN != NULL) 2159 MEM_FREE(_szDSN); 2160 if (_szUID != NULL) 2161 MEM_FREE (_szUID); 2162 if (_szAuthStr != NULL) 2163 MEM_FREE (_szAuthStr); 2164 2165 return retcode; 2166} 2167 2168 2169SQLRETURN SQL_API 2170SQLConnect ( 2171 SQLHDBC hdbc, 2172 SQLCHAR * szDSN, 2173 SQLSMALLINT cbDSN, 2174 SQLCHAR * szUID, 2175 SQLSMALLINT cbUID, 2176 SQLCHAR * szAuthStr, 2177 SQLSMALLINT cbAuthStr) 2178{ 2179 ENTER_HDBC (hdbc, 1, 2180 trace_SQLConnect (TRACE_ENTER, 2181 hdbc, 2182 szDSN, cbDSN, 2183 szUID, cbUID, 2184 szAuthStr, cbAuthStr)); 2185 2186 retcode = SQLConnect_Internal ( 2187 hdbc, 2188 szDSN, cbDSN, 2189 szUID, cbUID, 2190 szAuthStr, cbAuthStr, 'A'); 2191 2192 LEAVE_HDBC (hdbc, 1, 2193 trace_SQLConnect (TRACE_LEAVE, 2194 hdbc, 2195 szDSN, cbDSN, 2196 szUID, cbUID, 2197 szAuthStr, cbAuthStr)); 2198} 2199 2200 2201SQLRETURN SQL_API 2202SQLConnectA ( 2203 SQLHDBC hdbc, 2204 SQLCHAR * szDSN, 2205 SQLSMALLINT cbDSN, 2206 SQLCHAR * szUID, 2207 SQLSMALLINT cbUID, 2208 SQLCHAR * szAuthStr, 2209 SQLSMALLINT cbAuthStr) 2210{ 2211 ENTER_HDBC (hdbc, 1, 2212 trace_SQLConnect (TRACE_ENTER, 2213 hdbc, 2214 szDSN, cbDSN, 2215 szUID, cbUID, 2216 szAuthStr, cbAuthStr)); 2217 2218 retcode = SQLConnect_Internal ( 2219 hdbc, 2220 szDSN, cbDSN, 2221 szUID, cbUID, 2222 szAuthStr, cbAuthStr, 'A'); 2223 2224 LEAVE_HDBC (hdbc, 1, 2225 trace_SQLConnect (TRACE_LEAVE, 2226 hdbc, 2227 szDSN, cbDSN, 2228 szUID, cbUID, 2229 szAuthStr, cbAuthStr)); 2230} 2231 2232 2233SQLRETURN SQL_API 2234SQLConnectW (SQLHDBC hdbc, 2235 SQLWCHAR * szDSN, 2236 SQLSMALLINT cbDSN, 2237 SQLWCHAR * szUID, 2238 SQLSMALLINT cbUID, 2239 SQLWCHAR * szAuthStr, 2240 SQLSMALLINT cbAuthStr) 2241{ 2242 ENTER_HDBC (hdbc, 1, 2243 trace_SQLConnectW (TRACE_ENTER, 2244 hdbc, 2245 szDSN, cbDSN, 2246 szUID, cbUID, 2247 szAuthStr, cbAuthStr)); 2248 2249 retcode = SQLConnect_Internal ( 2250 hdbc, 2251 szDSN, cbDSN, 2252 szUID, cbUID, 2253 szAuthStr, cbAuthStr, 2254 'W'); 2255 2256 LEAVE_HDBC (hdbc, 1, 2257 trace_SQLConnectW (TRACE_LEAVE, 2258 hdbc, 2259 szDSN, cbDSN, 2260 szUID, cbUID, 2261 szAuthStr, cbAuthStr)); 2262} 2263 2264 2265SQLRETURN SQL_API 2266SQLDriverConnect_Internal ( 2267 SQLHDBC hdbc, 2268 SQLHWND hwnd, 2269 SQLPOINTER szConnStrIn, 2270 SQLSMALLINT cbConnStrIn, 2271 SQLPOINTER szConnStrOut, 2272 SQLSMALLINT cbConnStrOutMax, 2273 SQLPOINTER pcbConnStrOut, 2274 SQLUSMALLINT fDriverCompletion, 2275 SQLCHAR waMode) 2276{ 2277 CONN (pdbc, hdbc); 2278 ENVR (penv, NULL); 2279#if (ODBCVER >= 0x300) 2280 GENV (genv, NULL); 2281#endif 2282 HDLL hdll; 2283 SQLCHAR *drv = NULL; 2284 SQLCHAR drvbuf[1024]; 2285 SQLCHAR *dsn = NULL; 2286 SQLCHAR dsnbuf[SQL_MAX_DSN_LENGTH + 1]; 2287 SQLWCHAR prov[2048]; 2288 SWORD thread_safe; 2289 SWORD unload_safe; 2290 SQLCHAR buf[1024]; 2291 HPROC hproc = SQL_NULL_HPROC; 2292 void *_ConnStrIn = NULL; 2293 void *_ConnStrOut = NULL; 2294 void *connStrOut = szConnStrOut; 2295 void *connStrIn = szConnStrIn; 2296 SQLSMALLINT connStrOutMax = cbConnStrOutMax; 2297 SQLWCHAR connStrOut_buf[2048]; 2298 SQLWCHAR connStrIn_buf[2048]; 2299 UWORD config; 2300 PCONFIG pconfig = NULL; 2301 BOOL bCallDmDlg = FALSE; 2302#if defined (__APPLE__) && !(defined (NO_FRAMEWORKS) || defined (_LP64)) 2303 CFStringRef libname = NULL; 2304 CFBundleRef bundle = NULL; 2305 CFURLRef liburl = NULL; 2306 char name[1024] = { 0 }; 2307#endif 2308 SQLCHAR *filedsn = NULL; 2309 SQLCHAR *savefile = NULL; 2310 2311 HPROC dialproc = SQL_NULL_HPROC; 2312 2313 sqlstcode_t sqlstat = en_00000; 2314 SQLRETURN retcode = SQL_SUCCESS; 2315 SQLRETURN setopterr = SQL_SUCCESS; 2316 2317 /* check arguments */ 2318 if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS) || 2319 (cbConnStrOutMax < 0 && cbConnStrOutMax != SQL_NTS)) 2320 { 2321 PUSHSQLERR (pdbc->herr, en_S1090); 2322 RETURN (SQL_ERROR); 2323 } 2324 2325 /* check state */ 2326 if (pdbc->state != en_dbc_allocated) 2327 { 2328 PUSHSQLERR (pdbc->herr, en_08002); 2329 RETURN (SQL_ERROR); 2330 } 2331 2332 /* Save config mode */ 2333 SQLGetConfigMode (&config); 2334 2335 if (_iodbcdm_cfg_init_str (&pconfig, connStrIn, cbConnStrIn, 2336 waMode == 'W') == -1) 2337 { 2338 PUSHSQLERR (pdbc->herr, en_HY001); 2339 RETURN (SQL_ERROR); 2340 } 2341 assert (_iodbcdm_cfg_valid(pconfig)); 2342 2343 /* lookup and save original SAVEFILE value */ 2344 if (_iodbcdm_cfg_find (pconfig, "ODBC", "SAVEFILE") == 0) 2345 { 2346 savefile = strdup (pconfig->value); 2347 if (savefile == NULL) 2348 { 2349 PUSHSQLERR (pdbc->herr, en_HY001); 2350 RETURN (SQL_ERROR); 2351 } 2352 } 2353 2354 2355#if (ODBCVER >= 0x300) 2356 genv = (GENV_t *) pdbc->genv; 2357 2358 /* 2359 * Try to find pooled connection. 2360 * Pooling is disabled if SAVEFILE is present. 2361 */ 2362 if (genv->connection_pooling != SQL_CP_OFF && savefile == NULL) 2363 { 2364 char *_connstr = connStrIn; 2365 2366 if (fDriverCompletion != SQL_DRIVER_NOPROMPT) 2367 { 2368 PUSHSQLERR (pdbc->herr, en_HY110); 2369 RETURN (SQL_ERROR); 2370 } 2371 2372 if (waMode == 'W') 2373 { 2374 _ConnStrIn = dm_SQL_WtoU8((SQLWCHAR *) connStrIn, cbConnStrIn); 2375 if (_ConnStrIn == NULL) 2376 { 2377 PUSHSQLERR (pdbc->herr, en_HY001); 2378 RETURN (SQL_ERROR); 2379 } 2380 _connstr = _ConnStrIn; 2381 } 2382 2383 retcode = _iodbcdm_pool_get_conn (pdbc, NULL, NULL, NULL, _connstr); 2384 if (SQL_SUCCEEDED (retcode)) 2385 { 2386 /* 2387 * Got connection from the pool 2388 */ 2389 2390 /* copy out connection string */ 2391 if (szConnStrOut != NULL) 2392 { 2393 if (waMode == 'W') 2394 { 2395 WCSNCPY (szConnStrOut, szConnStrIn, cbConnStrOutMax); 2396 *(SQLSMALLINT *) pcbConnStrOut = 2397 WCSLEN (szConnStrOut) * sizeof (SQLWCHAR); 2398 } 2399 else 2400 { 2401 _iodbcdm_strlcpy (szConnStrOut, szConnStrIn, cbConnStrOutMax); 2402 *(SQLSMALLINT *) pcbConnStrOut = strlen (szConnStrOut); 2403 } 2404 } 2405 2406 /* state transition */ 2407 pdbc->state = en_dbc_connected; 2408 2409 RETURN (retcode); 2410 } 2411 2412 if (pdbc->cp_pdbc != NULL) 2413 { 2414 /* 2415 * Dead connection was taken from pool 2416 */ 2417 2418 if (pdbc->cp_pdbc->cp_retry_wait != 0) 2419 { 2420 /* 2421 * Retry Wait timeout has not expired yet 2422 */ 2423 PUSHSQLERR (pdbc->herr, en_08004); 2424 RETURN (SQL_ERROR); 2425 } 2426 2427 /* 2428 * Free connection parameters. 2429 */ 2430 if (waMode == 'W') 2431 { 2432 if (_ConnStrIn != NULL) 2433 { 2434 MEM_FREE (_ConnStrIn); 2435 _ConnStrIn = NULL; 2436 } 2437 } 2438 } 2439 else 2440 { 2441 /* 2442 * Connection was not found in the pool -- 2443 * save connection parameters 2444 */ 2445 if (pdbc->cp_connstr != NULL) 2446 MEM_FREE (pdbc->cp_connstr); 2447 2448 if (waMode == 'W') 2449 { 2450 pdbc->cp_connstr = _ConnStrIn; 2451 _ConnStrIn = NULL; 2452 } 2453 else 2454 { 2455 pdbc->cp_connstr = strdup (_connstr); 2456 if (pdbc->cp_connstr == NULL) 2457 { 2458 PUSHSQLERR (pdbc->herr, en_HY001); 2459 RETURN (SQL_ERROR); 2460 } 2461 } 2462 } 2463 } 2464#endif /* (ODBCVER >= 0x300) */ 2465 2466 /* always get (even if not requested) out connection string for SAVEFILE */ 2467 if (!connStrOut) 2468 { 2469 connStrOut = connStrOut_buf; 2470 connStrOutMax = sizeof(connStrOut_buf); 2471 } 2472 2473 /* now look for DSN or FILEDSN, whichever comes first */ 2474 _iodbcdm_cfg_rewind (pconfig); 2475 while (_iodbcdm_cfg_nextentry (pconfig) == 0) 2476 { 2477 if (!_iodbcdm_cfg_define (pconfig)) 2478 continue; 2479 2480 if (!strcasecmp(pconfig->id, "DSN")) 2481 { 2482 /* not a file dsn */ 2483 break; 2484 } 2485 else if (!strcasecmp(pconfig->id, "FILEDSN")) 2486 { 2487 /* file dsn */ 2488 filedsn = strdup (pconfig->value); 2489 if (filedsn == NULL) 2490 { 2491 PUSHSQLERR (pdbc->herr, en_HY001); 2492 RETURN (SQL_ERROR); 2493 } 2494 break; 2495 } 2496 } 2497 2498 2499 /* get connect parameters from .dsn file if requested */ 2500 if (filedsn != NULL) 2501 { 2502 /* merge params from .dsn file */ 2503 if (_iodbcdm_cfg_merge_filedsn (pconfig, filedsn, 2504 (char *) connStrIn_buf, sizeof (connStrIn_buf), 2505 waMode == 'W') == -1) 2506 { 2507 PUSHSQLERR (pdbc->herr, en_IM015); 2508 RETURN (SQL_ERROR); 2509 } 2510 2511 /* update connection string and its length */ 2512 connStrIn = connStrIn_buf; 2513 if (cbConnStrIn != SQL_NTS) 2514 { 2515 if (waMode != 'W') 2516 cbConnStrIn = STRLEN (connStrIn); 2517 else 2518 cbConnStrIn = WCSLEN (connStrIn); 2519 } 2520 } 2521 2522 if (_iodbcdm_cfg_find (pconfig, "ODBC", "DRIVER") == 0) 2523 { 2524 /* copy because pconfig can be reinitialized later */ 2525 _iodbcdm_strlcpy ((char *) drvbuf, pconfig->value, sizeof (drvbuf)); 2526 drv = drvbuf; 2527 } 2528 if (_iodbcdm_cfg_find (pconfig, "ODBC", "DSN") == 0) 2529 { 2530 /* copy because pconfig can be reinitialized later */ 2531 _iodbcdm_strlcpy ((char *) dsnbuf, pconfig->value, sizeof (dsnbuf)); 2532 dsn = dsnbuf; 2533 } 2534 2535 switch (fDriverCompletion) 2536 { 2537 case SQL_DRIVER_NOPROMPT: 2538 /* Check if there's a DSN or DRIVER */ 2539 if (!dsn && !drv) 2540 { 2541 PUSHSQLERR (pdbc->herr, en_IM007); 2542 RETURN (SQL_ERROR); 2543 } 2544 break; 2545 2546 case SQL_DRIVER_COMPLETE: 2547 case SQL_DRIVER_COMPLETE_REQUIRED: 2548 if (dsn != NULL || drv != NULL) 2549 { 2550 break; 2551 } 2552 /* fall to next case */ 2553 case SQL_DRIVER_PROMPT: 2554 /* Get data source dialog box function from 2555 * current executable */ 2556 /* Not really sure here, but should load that from the iodbcadm */ 2557 if (waMode == 'A') 2558 _iodbcdm_strlcpy ((char *) prov, connStrIn, sizeof (prov)); 2559 else 2560 wcsncpy (prov, connStrIn, sizeof (prov) / sizeof (wchar_t)); 2561 2562#if 0 2563 if (!dsn && !drv) 2564 bCallDmDlg = TRUE; 2565 else if ( _iodbcdm_CheckDriverLoginDlg(drv, dsn) == FALSE) 2566 bCallDmDlg = TRUE; 2567 2568 /* not call iODBC function "iodbcdm_drvconn_dialbox", if there is 2569 * the function "_iodbcdm_drvconn_dialbox" in the odbc driver, 2570 * odbc driver must call its function itself 2571 */ 2572 if (!bCallDmDlg) 2573 break; 2574#endif 2575 2576 ODBC_UNLOCK (); 2577#if defined (__APPLE__) && !(defined (NO_FRAMEWORKS) || defined (_LP64)) 2578 bundle = CFBundleGetBundleWithIdentifier (CFSTR ("org.iodbc.core")); 2579 if (bundle) 2580 { 2581 /* Search for the drvproxy library */ 2582 liburl = 2583 CFBundleCopyResourceURL (bundle, CFSTR ("iODBCadm.bundle"), 2584 NULL, NULL); 2585 if (liburl 2586 && (libname = 2587 CFURLCopyFileSystemPath (liburl, kCFURLPOSIXPathStyle))) 2588 { 2589 CFStringGetCString (libname, name, sizeof (name), 2590 kCFStringEncodingASCII); 2591 _iodbcdm_strlcat (name, "/Contents/MacOS/iODBCadm", 2592 sizeof (name)); 2593 hdll = _iodbcdm_dllopen (name); 2594 } 2595 if (liburl) 2596 CFRelease (liburl); 2597 if (libname) 2598 CFRelease (libname); 2599 } 2600#else 2601 hdll = _iodbcdm_dllopen ("libiodbcadm.so"); 2602#endif 2603 2604 if (!hdll) 2605 break; 2606 2607 if (waMode != 'W') 2608 dialproc = _iodbcdm_dllproc (hdll, "iodbcdm_drvconn_dialbox"); 2609 else 2610 dialproc = _iodbcdm_dllproc (hdll, "iodbcdm_drvconn_dialboxw"); 2611 2612 if (dialproc == SQL_NULL_HPROC) 2613 { 2614 sqlstat = en_IM008; 2615 break; 2616 } 2617 2618 retcode = dialproc (hwnd, /* window or display handle */ 2619 prov, /* input/output dsn buf */ 2620 sizeof (prov) / (waMode == 'A' ? 1 : sizeof (SQLWCHAR)), /* buf size */ 2621 &sqlstat, /* error code */ 2622 fDriverCompletion, /* type of completion */ 2623 &config); /* config mode */ 2624 2625 ODBC_LOCK (); 2626 fDriverCompletion = SQL_DRIVER_NOPROMPT; 2627 2628 if (retcode != SQL_SUCCESS) 2629 { 2630 if (retcode != SQL_NO_DATA_FOUND) 2631 PUSHSQLERR (pdbc->herr, sqlstat); 2632 goto end; 2633 } 2634 2635 connStrIn = prov; 2636 2637 /* 2638 * Recalculate length of connStrIn if needed, as it may have been 2639 * changed by iodbcdm_drvconn_dialbox 2640 */ 2641 if (cbConnStrIn != SQL_NTS) 2642 { 2643 if (waMode != 'W') 2644 cbConnStrIn = STRLEN (connStrIn); 2645 else 2646 cbConnStrIn = WCSLEN (connStrIn); 2647 } 2648 2649 if (_iodbcdm_cfg_parse_str (pconfig, connStrIn, cbConnStrIn, 2650 waMode == 'W') == -1) 2651 { 2652 PUSHSQLERR (pdbc->herr, en_HY001); 2653 RETURN (SQL_ERROR); 2654 } 2655 if (_iodbcdm_cfg_find (pconfig, "ODBC", "DSN") == 0) 2656 dsn = pconfig->value; 2657 if (_iodbcdm_cfg_find (pconfig, "ODBC", "DRIVER") == 0) 2658 { 2659 /* copy because pconfig can be reinitialized later */ 2660 _iodbcdm_strlcpy ((char *) drvbuf, pconfig->value, sizeof (drvbuf)); 2661 drv = drvbuf; 2662 } 2663 break; 2664 2665 default: 2666 sqlstat = en_S1110; 2667 break; 2668 } 2669 2670 if (sqlstat != en_00000) 2671 { 2672 PUSHSQLERR (pdbc->herr, sqlstat); 2673 RETURN (SQL_ERROR); 2674 } 2675 2676 if (dsn == NULL || *(char *) dsn == '\0') 2677 { 2678 dsn = (void *) "default"; 2679 } 2680 else 2681 /* if you want tracing, you must use a DSN */ 2682 { 2683 setopterr |= 2684 _iodbcdm_con_settracing (pdbc, (SQLCHAR *) dsn, SQL_NTS, waMode); 2685 } 2686 2687 /* 2688 * Check whether driver is thread safe 2689 */ 2690 thread_safe = 1; /* Assume driver is thread safe */ 2691 2692 SQLSetConfigMode (ODBC_BOTH_DSN); 2693 if (SQLGetPrivateProfileString ((char *) dsn, "ThreadManager", "", 2694 buf, sizeof (buf), "odbc.ini") 2695 && (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1"))) 2696 { 2697 thread_safe = 0; /* Driver needs a thread manager */ 2698 } 2699 2700 /* 2701 * Check whether driver is unload safe 2702 */ 2703 unload_safe = 0; /* Assume driver is not unload safe */ 2704 2705 SQLSetConfigMode (ODBC_BOTH_DSN); 2706 if (SQLGetPrivateProfileString ((char *) dsn, "UnloadSafe", "", 2707 buf, sizeof (buf), "odbc.ini") 2708 && (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1"))) 2709 { 2710 unload_safe = 1; 2711 } 2712 2713 /* 2714 * Get the name of the driver module 2715 */ 2716 if (drv == NULL || *(char *) drv == '\0') 2717 { 2718 SQLSetConfigMode (ODBC_BOTH_DSN); 2719 if (SQLGetPrivateProfileString ((char *) dsn, "Driver", "", 2720 (char *) drvbuf, sizeof (drvbuf), "odbc.ini") != 0) 2721 { 2722 drv = drvbuf; 2723 } 2724 } 2725 2726 if (drv == NULL) 2727 { 2728 PUSHSQLERR (pdbc->herr, en_IM002); 2729 RETURN (SQL_ERROR); 2730 } 2731 2732 retcode = 2733 _iodbcdm_driverload (dsn, (char *) drv, pdbc, thread_safe, unload_safe, 2734 waMode); 2735 2736 switch (retcode) 2737 { 2738 case SQL_SUCCESS: 2739 break; 2740 2741 case SQL_SUCCESS_WITH_INFO: 2742#if 0 2743 /* 2744 * Unsuccessful in calling driver's SQLSetConnectOption() to set 2745 * login timeout. 2746 */ 2747 setopterr = SQL_ERROR; 2748#endif 2749 break; 2750 2751 default: 2752 RETURN (retcode); 2753 } 2754 2755#if (ODBCVER >= 0x300) 2756 /* 2757 * Pooling is disabled if SAVEFILE is present. 2758 */ 2759 if (savefile != NULL) 2760 pdbc->cp_timeout = 0; 2761#endif 2762 2763 penv = (ENV_t *) pdbc->henv; 2764 2765 if ((penv->unicode_driver && waMode != 'W') 2766 || (!penv->unicode_driver && waMode == 'W')) 2767 { 2768 if (waMode != 'W') 2769 { 2770 /* ansi=>unicode */ 2771 if ((_ConnStrOut = 2772 malloc (connStrOutMax * sizeof (SQLWCHAR) + 1)) == NULL) 2773 { 2774 PUSHSQLERR (pdbc->herr, en_HY001); 2775 RETURN (SQL_ERROR); 2776 } 2777 _ConnStrIn = dm_SQL_A2W ((SQLCHAR *) connStrIn, cbConnStrIn); 2778 } 2779 else 2780 { 2781 /* unicode=>ansi */ 2782 if ((_ConnStrOut = malloc (connStrOutMax + 1)) == NULL) 2783 { 2784 PUSHSQLERR (pdbc->herr, en_HY001); 2785 RETURN (SQL_ERROR); 2786 } 2787 _ConnStrIn = dm_SQL_W2A ((SQLWCHAR *) connStrIn, cbConnStrIn); 2788 } 2789 connStrOut = _ConnStrOut; 2790 connStrIn = _ConnStrIn; 2791 cbConnStrIn = SQL_NTS; 2792 } 2793 2794 2795 /* Restore config mode */ 2796 SQLSetConfigMode (config); 2797 2798 ODBC_UNLOCK (); 2799 CALL_UDRIVER (hdbc, pdbc, retcode, hproc, penv->unicode_driver, 2800 en_DriverConnect, (pdbc->dhdbc, 2801 hwnd, 2802 connStrIn, 2803 cbConnStrIn, 2804 connStrOut, connStrOutMax, pcbConnStrOut, fDriverCompletion)); 2805 ODBC_LOCK (); 2806 2807 if (hproc == SQL_NULL_HPROC) 2808 { 2809 _iodbcdm_driverunload (pdbc, 3); 2810 PUSHSQLERR (pdbc->herr, en_IM001); 2811 RETURN (SQL_ERROR); 2812 } 2813 2814 if (szConnStrOut 2815 && SQL_SUCCEEDED (retcode) 2816 && ((penv->unicode_driver && waMode != 'W') 2817 || (!penv->unicode_driver && waMode == 'W'))) 2818 { 2819 if (waMode != 'W') 2820 { 2821 /* ansi<=unicode */ 2822 dm_StrCopyOut2_W2A ((SQLWCHAR *) connStrOut, 2823 (SQLCHAR *) szConnStrOut, cbConnStrOutMax, NULL); 2824 } 2825 else 2826 { 2827 /* unicode<=ansi */ 2828 dm_StrCopyOut2_A2W ((SQLCHAR *) connStrOut, 2829 (SQLWCHAR *) szConnStrOut, cbConnStrOutMax, NULL); 2830 } 2831 } 2832 2833 if (szConnStrOut != NULL) 2834 { 2835 if (filedsn != NULL) 2836 { 2837 /* append FILEDSN to the out connection string */ 2838 if (waMode == 'W') 2839 { 2840 SQLWCHAR *_tmp = dm_SQL_U8toW (filedsn, SQL_NTS); 2841 if (_tmp == NULL) 2842 { 2843 PUSHSQLERR (pdbc->herr, en_HY001); 2844 RETURN (SQL_ERROR); 2845 } 2846 WCSNCAT (szConnStrOut, L";FILEDSN=", cbConnStrOutMax); 2847 WCSNCAT (szConnStrOut, _tmp, cbConnStrOutMax); 2848 MEM_FREE (_tmp); 2849 } 2850 else 2851 { 2852 _iodbcdm_strlcat (szConnStrOut, ";FILEDSN=", cbConnStrOutMax); 2853 _iodbcdm_strlcat (szConnStrOut, filedsn, cbConnStrOutMax); 2854 } 2855 } 2856 if (savefile != NULL) 2857 { 2858 /* append SAVEFILE to the out connection string */ 2859 if (waMode == 'W') 2860 { 2861 SQLWCHAR *_tmp = dm_SQL_U8toW (savefile, SQL_NTS); 2862 if (_tmp == NULL) 2863 { 2864 PUSHSQLERR (pdbc->herr, en_HY001); 2865 RETURN (SQL_ERROR); 2866 } 2867 WCSNCAT (szConnStrOut, L";SAVEFILE=", cbConnStrOutMax); 2868 WCSNCAT (szConnStrOut, _tmp, cbConnStrOutMax); 2869 MEM_FREE (_tmp); 2870 } 2871 else 2872 { 2873 _iodbcdm_strlcat (szConnStrOut, ";SAVEFILE=", cbConnStrOutMax); 2874 _iodbcdm_strlcat (szConnStrOut, savefile, cbConnStrOutMax); 2875 } 2876 } 2877 2878 /* fixup pcbConnStrOut */ 2879 if (waMode == 'W') 2880 { 2881 *(SQLSMALLINT *) pcbConnStrOut = 2882 WCSLEN (szConnStrOut) * sizeof (SQLWCHAR); 2883 } 2884 else 2885 *(SQLSMALLINT *) pcbConnStrOut = strlen (szConnStrOut); 2886 } 2887 2888 if (!SQL_SUCCEEDED (retcode)) 2889 { 2890 /* don't unload driver here for retrieve 2891 * error message from driver */ 2892 /******** 2893 _iodbcdm_driverunload( hdbc , 3); 2894 *********/ 2895 2896 RETURN (retcode); 2897 } 2898 2899 /* state transition */ 2900 pdbc->state = en_dbc_connected; 2901 2902 /* do delayed option setting */ 2903 setopterr |= _iodbcdm_dbcdelayset (pdbc, waMode); 2904 2905 if (setopterr != SQL_SUCCESS) 2906 retcode = SQL_SUCCESS_WITH_INFO; 2907 2908 /* save .dsn file if requested */ 2909 if (savefile != NULL) 2910 { 2911 assert (connStrOut != NULL); 2912 2913 if (_iodbcdm_cfg_savefile (savefile, connStrOut, 2914 penv->unicode_driver) == -1) 2915 { 2916 PUSHSQLERR (pdbc->herr, en_01S08); 2917 retcode = SQL_SUCCESS_WITH_INFO; 2918 } 2919 } 2920 2921end: 2922#if (ODBCVER >= 0x300) 2923 if (!SQL_SUCCEEDED (retcode) && 2924 pdbc->cp_pdbc != NULL) 2925 { 2926 int rc; 2927 2928 /* 2929 * Dead connection was taken from the pool 2930 * but reconnection attempt has failed: 2931 * set cp_retry_wait time and return connection to the pool. 2932 */ 2933 _iodbcdm_pool_set_retry_wait (pdbc); 2934 rc = _iodbcdm_pool_put_conn (pdbc); 2935 assert (rc == 0); 2936 } 2937#endif 2938 _iodbcdm_cfg_done (pconfig); 2939 if (_ConnStrIn != NULL) 2940 MEM_FREE (_ConnStrIn); 2941 if (_ConnStrOut != NULL) 2942 MEM_FREE (_ConnStrOut); 2943 if (savefile != NULL) 2944 MEM_FREE (savefile); 2945 if (filedsn != NULL) 2946 MEM_FREE (filedsn); 2947 2948 return retcode; 2949} 2950 2951 2952SQLRETURN SQL_API 2953SQLDriverConnect (SQLHDBC hdbc, 2954 SQLHWND hwnd, 2955 SQLCHAR * szConnStrIn, 2956 SQLSMALLINT cbConnStrIn, 2957 SQLCHAR * szConnStrOut, 2958 SQLSMALLINT cbConnStrOutMax, 2959 SQLSMALLINT * pcbConnStrOut, 2960 SQLUSMALLINT fDriverCompletion) 2961{ 2962 ENTER_HDBC (hdbc, 1, 2963 trace_SQLDriverConnect (TRACE_ENTER, 2964 hdbc, 2965 hwnd, 2966 szConnStrIn, cbConnStrIn, 2967 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 2968 fDriverCompletion)); 2969 2970 retcode = SQLDriverConnect_Internal( 2971 hdbc, 2972 hwnd, 2973 szConnStrIn, cbConnStrIn, 2974 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 2975 fDriverCompletion, 2976 'A'); 2977 2978 LEAVE_HDBC (hdbc, 1, 2979 trace_SQLDriverConnect (TRACE_LEAVE, 2980 hdbc, 2981 hwnd, 2982 szConnStrIn, cbConnStrIn, 2983 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 2984 fDriverCompletion)); 2985} 2986 2987 2988SQLRETURN SQL_API 2989SQLDriverConnectA (SQLHDBC hdbc, 2990 SQLHWND hwnd, 2991 SQLCHAR * szConnStrIn, 2992 SQLSMALLINT cbConnStrIn, 2993 SQLCHAR * szConnStrOut, 2994 SQLSMALLINT cbConnStrOutMax, 2995 SQLSMALLINT * pcbConnStrOut, 2996 SQLUSMALLINT fDriverCompletion) 2997{ 2998 ENTER_HDBC (hdbc, 1, 2999 trace_SQLDriverConnect (TRACE_ENTER, 3000 hdbc, 3001 hwnd, 3002 szConnStrIn, cbConnStrIn, 3003 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 3004 fDriverCompletion)); 3005 3006 retcode = SQLDriverConnect_Internal( 3007 hdbc, 3008 hwnd, 3009 szConnStrIn, cbConnStrIn, 3010 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 3011 fDriverCompletion, 3012 'A'); 3013 3014 LEAVE_HDBC (hdbc, 1, 3015 trace_SQLDriverConnect (TRACE_LEAVE, 3016 hdbc, 3017 hwnd, 3018 szConnStrIn, cbConnStrIn, 3019 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 3020 fDriverCompletion)); 3021} 3022 3023 3024SQLRETURN SQL_API 3025SQLDriverConnectW (SQLHDBC hdbc, 3026 SQLHWND hwnd, 3027 SQLWCHAR * szConnStrIn, 3028 SQLSMALLINT cbConnStrIn, 3029 SQLWCHAR * szConnStrOut, 3030 SQLSMALLINT cbConnStrOutMax, 3031 SQLSMALLINT * pcbConnStrOut, 3032 SQLUSMALLINT fDriverCompletion) 3033{ 3034 ENTER_HDBC (hdbc, 1, 3035 trace_SQLDriverConnectW (TRACE_ENTER, 3036 hdbc, 3037 hwnd, 3038 szConnStrIn, cbConnStrIn, 3039 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 3040 fDriverCompletion)); 3041 3042 retcode = SQLDriverConnect_Internal( 3043 hdbc, 3044 hwnd, 3045 szConnStrIn, cbConnStrIn, 3046 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 3047 fDriverCompletion, 3048 'W'); 3049 3050 LEAVE_HDBC (hdbc, 1, 3051 trace_SQLDriverConnectW (TRACE_LEAVE, 3052 hdbc, 3053 hwnd, 3054 szConnStrIn, cbConnStrIn, 3055 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 3056 fDriverCompletion)); 3057} 3058 3059 3060SQLRETURN SQL_API 3061SQLBrowseConnect_Internal (SQLHDBC hdbc, 3062 SQLPOINTER szConnStrIn, 3063 SQLSMALLINT cbConnStrIn, 3064 SQLPOINTER szConnStrOut, 3065 SQLSMALLINT cbConnStrOutMax, SQLSMALLINT * pcbConnStrOut, 3066 SQLCHAR waMode) 3067{ 3068 CONN (pdbc, hdbc); 3069 ENVR (penv, NULL); 3070 char buf[1024]; 3071 SWORD thread_safe; 3072 SWORD unload_safe; 3073 HPROC hproc = SQL_NULL_HPROC; 3074 void * _ConnStrIn = NULL; 3075 void * _ConnStrOut = NULL; 3076 void * connStrOut = szConnStrOut; 3077 void * connStrIn = szConnStrIn; 3078 3079 SQLRETURN retcode = SQL_SUCCESS; 3080 SQLRETURN setopterr = SQL_SUCCESS; 3081 3082 /* check arguments */ 3083 if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS) || cbConnStrOutMax < 0) 3084 { 3085 PUSHSQLERR (pdbc->herr, en_S1090); 3086 return SQL_ERROR; 3087 } 3088 3089 if (pdbc->state == en_dbc_allocated) 3090 { 3091 PCONFIG pconfig; 3092 void *drv = NULL, *dsn = NULL; 3093 3094 if (_iodbcdm_cfg_init_str (&pconfig, szConnStrIn, cbConnStrIn, 3095 waMode == 'W') == -1) 3096 { 3097 PUSHSQLERR (pdbc->herr, en_HY001); 3098 return SQL_ERROR; 3099 } 3100 if (_iodbcdm_cfg_find (pconfig, "ODBC", "DRIVER") == 0) 3101 drv = pconfig->value; 3102 if (_iodbcdm_cfg_find (pconfig, "ODBC", "DSN") == 0) 3103 dsn = pconfig->value; 3104 3105 if (dsn == NULL || ((char*)dsn)[0] == '\0') 3106 dsn = (void *) "default"; 3107 else 3108 /* if you want tracing, you must use a DSN */ 3109 { 3110 if (_iodbcdm_con_settracing (pdbc, (SQLCHAR *) dsn, SQL_NTS, waMode) == SQL_ERROR) 3111 { 3112 _iodbcdm_cfg_done (pconfig); 3113 return SQL_ERROR; 3114 } 3115 } 3116 3117 /* 3118 * Check whether driver is thread safe 3119 */ 3120 thread_safe = 1; /* Assume driver is thread safe */ 3121 3122 SQLSetConfigMode (ODBC_BOTH_DSN); 3123 if ( SQLGetPrivateProfileString ((char *) dsn, "ThreadManager", "", 3124 buf, sizeof(buf), "odbc.ini") && 3125 (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1"))) 3126 { 3127 thread_safe = 0; /* Driver needs a thread manager */ 3128 } 3129 3130 /* 3131 * Check whether driver is unload safe 3132 */ 3133 unload_safe = 0; /* Assume driver is not unload safe */ 3134 3135 SQLSetConfigMode (ODBC_BOTH_DSN); 3136 if ( SQLGetPrivateProfileString ((char *) dsn, "ThreadManager", "", 3137 buf, sizeof(buf), "odbc.ini") && 3138 (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1"))) 3139 { 3140 unload_safe = 1; 3141 } 3142 3143 /* 3144 * Get the name of the driver module and load it 3145 */ 3146 if (drv == NULL || *(char*)drv == '\0') 3147 { 3148 SQLSetConfigMode (ODBC_BOTH_DSN); 3149 if ( SQLGetPrivateProfileString ((char *) dsn, "Driver", "", 3150 buf, sizeof(buf), "odbc.ini") != 0) 3151 { 3152 drv = buf; 3153 } 3154 } 3155 3156 if (drv == NULL) 3157 { 3158 PUSHSQLERR (pdbc->herr, en_IM002); 3159 _iodbcdm_cfg_done (pconfig); 3160 return SQL_ERROR; 3161 } 3162 3163 retcode = _iodbcdm_driverload (dsn, (char *) drv, pdbc, thread_safe, unload_safe, waMode); 3164 _iodbcdm_cfg_done (pconfig); 3165 3166 switch (retcode) 3167 { 3168 case SQL_SUCCESS: 3169 break; 3170 3171 case SQL_SUCCESS_WITH_INFO: 3172#if 0 3173 /* 3174 * Unsuccessful in calling driver's SQLSetConnectOption() to set 3175 * login timeout. 3176 */ 3177 setopterr = SQL_ERROR; 3178#endif 3179 break; 3180 3181 default: 3182 return retcode; 3183 } 3184 } 3185 else if (pdbc->state != en_dbc_needdata) 3186 { 3187 PUSHSQLERR (pdbc->herr, en_08002); 3188 return SQL_ERROR; 3189 } 3190 3191 penv = (ENV_t *) pdbc->henv; 3192 3193 if ((penv->unicode_driver && waMode != 'W') 3194 || (!penv->unicode_driver && waMode == 'W')) 3195 { 3196 if (waMode != 'W') 3197 { 3198 /* ansi=>unicode*/ 3199 if ((_ConnStrOut = malloc((cbConnStrOutMax + 1) * sizeof(SQLWCHAR))) == NULL) 3200 { 3201 PUSHSQLERR (pdbc->herr, en_HY001); 3202 return SQL_ERROR; 3203 } 3204 _ConnStrIn = dm_SQL_A2W((SQLCHAR *)szConnStrIn, SQL_NTS); 3205 } 3206 else 3207 { 3208 /* unicode=>ansi*/ 3209 if ((_ConnStrOut = malloc(cbConnStrOutMax + 1)) == NULL) 3210 { 3211 PUSHSQLERR (pdbc->herr, en_HY001); 3212 return SQL_ERROR; 3213 } 3214 _ConnStrIn = dm_SQL_W2A((SQLWCHAR *)szConnStrIn, SQL_NTS); 3215 } 3216 connStrIn = _ConnStrIn; 3217 cbConnStrIn = SQL_NTS; 3218 connStrOut = _ConnStrOut; 3219 } 3220 3221 ODBC_UNLOCK (); 3222 CALL_UDRIVER(hdbc, pdbc, retcode, hproc, penv->unicode_driver, 3223 en_BrowseConnect, ( 3224 pdbc->dhdbc, 3225 connStrIn, 3226 cbConnStrIn, 3227 connStrOut, 3228 cbConnStrOutMax, 3229 pcbConnStrOut)); 3230 ODBC_LOCK (); 3231 3232 MEM_FREE(_ConnStrIn); 3233 3234 if (hproc == SQL_NULL_HPROC) 3235 { 3236 MEM_FREE(_ConnStrOut); 3237 _iodbcdm_driverunload (pdbc, 3); 3238 pdbc->state = en_dbc_allocated; 3239 PUSHSQLERR (pdbc->herr, en_IM001); 3240 return SQL_ERROR; 3241 } 3242 3243 if (szConnStrOut 3244 && SQL_SUCCEEDED (retcode) 3245 && ((penv->unicode_driver && waMode != 'W') 3246 || (!penv->unicode_driver && waMode == 'W'))) 3247 { 3248 if (waMode != 'W') 3249 { 3250 /* ansi<=unicode*/ 3251 dm_StrCopyOut2_W2A ((SQLWCHAR *) connStrOut, (SQLCHAR *) szConnStrOut, cbConnStrOutMax, NULL); 3252 } 3253 else 3254 { 3255 /* unicode<=ansi*/ 3256 dm_StrCopyOut2_A2W ((SQLCHAR *) connStrOut, (SQLWCHAR *) szConnStrOut, cbConnStrOutMax, NULL); 3257 } 3258 } 3259 3260 MEM_FREE(_ConnStrOut); 3261 3262 switch (retcode) 3263 { 3264 case SQL_SUCCESS: 3265 case SQL_SUCCESS_WITH_INFO: 3266 pdbc->state = en_dbc_connected; 3267 setopterr |= _iodbcdm_dbcdelayset (pdbc, waMode); 3268 if (setopterr != SQL_SUCCESS) 3269 { 3270 retcode = SQL_SUCCESS_WITH_INFO; 3271 } 3272 break; 3273 3274 case SQL_NEED_DATA: 3275 pdbc->state = en_dbc_needdata; 3276 break; 3277 3278 case SQL_ERROR: 3279 pdbc->state = en_dbc_allocated; 3280 /* but the driver will not unloaded 3281 * to allow application retrieve err 3282 * message from driver 3283 */ 3284 break; 3285 3286 default: 3287 break; 3288 } 3289 3290 return retcode; 3291} 3292 3293 3294SQLRETURN SQL_API 3295SQLBrowseConnect (SQLHDBC hdbc, 3296 SQLCHAR * szConnStrIn, 3297 SQLSMALLINT cbConnStrIn, 3298 SQLCHAR * szConnStrOut, 3299 SQLSMALLINT cbConnStrOutMax, 3300 SQLSMALLINT * pcbConnStrOut) 3301{ 3302 ENTER_HDBC (hdbc, 1, 3303 trace_SQLBrowseConnect (TRACE_ENTER, 3304 hdbc, 3305 szConnStrIn, cbConnStrIn, 3306 szConnStrOut, cbConnStrOutMax, pcbConnStrOut)); 3307 3308 retcode = SQLBrowseConnect_Internal ( 3309 hdbc, 3310 szConnStrIn, cbConnStrIn, 3311 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 3312 'A'); 3313 3314 LEAVE_HDBC (hdbc, 1, 3315 trace_SQLBrowseConnect (TRACE_LEAVE, 3316 hdbc, 3317 szConnStrIn, cbConnStrIn, 3318 szConnStrOut, cbConnStrOutMax, pcbConnStrOut)); 3319} 3320 3321 3322SQLRETURN SQL_API 3323SQLBrowseConnectA (SQLHDBC hdbc, 3324 SQLCHAR * szConnStrIn, 3325 SQLSMALLINT cbConnStrIn, 3326 SQLCHAR * szConnStrOut, 3327 SQLSMALLINT cbConnStrOutMax, 3328 SQLSMALLINT * pcbConnStrOut) 3329{ 3330 ENTER_HDBC (hdbc, 1, 3331 trace_SQLBrowseConnect (TRACE_ENTER, 3332 hdbc, 3333 szConnStrIn, cbConnStrIn, 3334 szConnStrOut, cbConnStrOutMax, pcbConnStrOut)); 3335 3336 retcode = SQLBrowseConnect_Internal ( 3337 hdbc, 3338 szConnStrIn, cbConnStrIn, 3339 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 3340 'A'); 3341 3342 LEAVE_HDBC (hdbc, 1, 3343 trace_SQLBrowseConnect (TRACE_LEAVE, 3344 hdbc, 3345 szConnStrIn, cbConnStrIn, 3346 szConnStrOut, cbConnStrOutMax, pcbConnStrOut)); 3347} 3348 3349 3350SQLRETURN SQL_API 3351SQLBrowseConnectW (SQLHDBC hdbc, 3352 SQLWCHAR * szConnStrIn, 3353 SQLSMALLINT cbConnStrIn, 3354 SQLWCHAR * szConnStrOut, 3355 SQLSMALLINT cbConnStrOutMax, 3356 SQLSMALLINT * pcbConnStrOut) 3357{ 3358 ENTER_HDBC (hdbc, 1, 3359 trace_SQLBrowseConnectW (TRACE_ENTER, 3360 hdbc, 3361 szConnStrIn, cbConnStrIn, 3362 szConnStrOut, cbConnStrOutMax, pcbConnStrOut)); 3363 3364 retcode = SQLBrowseConnect_Internal ( 3365 hdbc, 3366 szConnStrIn, cbConnStrIn, 3367 szConnStrOut, cbConnStrOutMax, pcbConnStrOut, 3368 'W'); 3369 3370 LEAVE_HDBC (hdbc, 1, 3371 trace_SQLBrowseConnectW (TRACE_LEAVE, 3372 hdbc, 3373 szConnStrIn, cbConnStrIn, 3374 szConnStrOut, cbConnStrOutMax, pcbConnStrOut)); 3375} 3376 3377 3378static SQLRETURN 3379SQLDisconnect_Internal (SQLHDBC hdbc) 3380{ 3381 CONN (pdbc, hdbc); 3382#if (ODBCVER >= 0x300) 3383 GENV (genv, pdbc->genv); 3384#endif 3385 STMT (pstmt, NULL); 3386 3387 /* check hdbc state */ 3388 if (pdbc->state == en_dbc_allocated) 3389 { 3390 PUSHSQLERR (pdbc->herr, en_08003); 3391 return SQL_ERROR; 3392 } 3393 3394 /* check stmt(s) state */ 3395 for (pstmt = (STMT_t *) pdbc->hstmt; 3396 pstmt != NULL; 3397 pstmt = (STMT_t *) pstmt->next) 3398 { 3399 if (pstmt->state >= en_stmt_needdata 3400 || pstmt->asyn_on != en_NullProc) 3401 /* In this case one need to call 3402 * SQLCancel() first */ 3403 { 3404 PUSHSQLERR (pdbc->herr, en_S1010); 3405 return SQL_ERROR; 3406 } 3407 } 3408 3409#if (ODBCVER >= 0x300) 3410 /* 3411 * Try to return the connected connection to the pool if 3412 * - connection was taken from the pool 3413 * - pooling is enabled and CPTimeout > 0 3414 */ 3415 if ((pdbc->state == en_dbc_connected || pdbc->state == en_dbc_hstmt) 3416 && (pdbc->cp_pdbc != NULL || 3417 (genv->connection_pooling != SQL_CP_OFF && pdbc->cp_timeout > 0))) 3418 { 3419 if (_iodbcdm_pool_put_conn (pdbc) == 0) 3420 { 3421 _iodbcdm_finish_disconnect (pdbc, FALSE); 3422 return SQL_SUCCESS; 3423 } 3424 } 3425#endif /* (ODBCVER >= 0x300) */ 3426 3427 return _iodbcdm_finish_disconnect (pdbc, TRUE); 3428} 3429 3430 3431SQLRETURN SQL_API 3432SQLDisconnect (SQLHDBC hdbc) 3433{ 3434 ENTER_HDBC (hdbc, 1, 3435 trace_SQLDisconnect (TRACE_ENTER, hdbc)); 3436 3437 retcode = SQLDisconnect_Internal (hdbc); 3438 3439 LEAVE_HDBC (hdbc, 1, 3440 trace_SQLDisconnect (TRACE_LEAVE, hdbc)); 3441} 3442 3443 3444SQLRETURN SQL_API 3445SQLNativeSql_Internal (SQLHDBC hdbc, 3446 SQLPOINTER szSqlStrIn, 3447 SQLINTEGER cbSqlStrIn, 3448 SQLPOINTER szSqlStr, 3449 SQLINTEGER cbSqlStrMax, 3450 SQLINTEGER * pcbSqlStr, 3451 SQLCHAR waMode) 3452{ 3453 CONN (pdbc, hdbc); 3454 ENVR (penv, pdbc->henv); 3455 sqlstcode_t sqlstat = en_00000; 3456 SQLRETURN retcode = SQL_SUCCESS; 3457 HPROC hproc = SQL_NULL_HPROC; 3458 void * _SqlStrIn = NULL; 3459 void * _SqlStr = NULL; 3460 void * sqlStr = szSqlStr; 3461 3462 /* check argument */ 3463 if (szSqlStrIn == NULL) 3464 { 3465 sqlstat = en_S1009; 3466 } 3467 else if (cbSqlStrIn < 0 && cbSqlStrIn != SQL_NTS) 3468 { 3469 sqlstat = en_S1090; 3470 } 3471 3472 if (sqlstat != en_00000) 3473 { 3474 PUSHSQLERR (pdbc->herr, sqlstat); 3475 return SQL_ERROR; 3476 } 3477 3478 /* check state */ 3479 if (pdbc->state <= en_dbc_needdata) 3480 { 3481 PUSHSQLERR (pdbc->herr, en_08003); 3482 return SQL_ERROR; 3483 } 3484 3485 if ((penv->unicode_driver && waMode != 'W') 3486 || (!penv->unicode_driver && waMode == 'W')) 3487 { 3488 if (waMode != 'W') 3489 { 3490 /* ansi=>unicode*/ 3491 if ((_SqlStr = malloc(cbSqlStrMax * sizeof(SQLWCHAR) + 1)) == NULL) 3492 { 3493 PUSHSQLERR (pdbc->herr, en_HY001); 3494 3495 return SQL_ERROR; 3496 } 3497 _SqlStrIn = dm_SQL_A2W((SQLCHAR *)szSqlStrIn, SQL_NTS); 3498 } 3499 else 3500 { 3501 /* unicode=>ansi*/ 3502 if ((_SqlStr = malloc(cbSqlStrMax + 1)) == NULL) 3503 { 3504 PUSHSQLERR (pdbc->herr, en_HY001); 3505 3506 return SQL_ERROR; 3507 } 3508 _SqlStrIn = dm_SQL_W2A((SQLWCHAR *)szSqlStrIn, SQL_NTS); 3509 } 3510 szSqlStrIn = _SqlStrIn; 3511 cbSqlStrIn = SQL_NTS; 3512 sqlStr = _SqlStr; 3513 } 3514 3515 /* call driver */ 3516 CALL_UDRIVER(hdbc, pdbc, retcode, hproc, penv->unicode_driver, 3517 en_NativeSql, ( 3518 pdbc->dhdbc, 3519 szSqlStrIn, 3520 cbSqlStrIn, 3521 sqlStr, 3522 cbSqlStrMax, 3523 pcbSqlStr)); 3524 3525 MEM_FREE(_SqlStrIn); 3526 3527 if (hproc == SQL_NULL_HPROC) 3528 { 3529 MEM_FREE(_SqlStr); 3530 PUSHSQLERR (pdbc->herr, en_IM001); 3531 3532 return SQL_ERROR; 3533 } 3534 3535 if (szSqlStr 3536 && SQL_SUCCEEDED (retcode) 3537 && ((penv->unicode_driver && waMode != 'W') 3538 || (!penv->unicode_driver && waMode == 'W'))) 3539 { 3540 if (waMode != 'W') 3541 { 3542 /* ansi<=unicode*/ 3543 dm_StrCopyOut2_W2A ((SQLWCHAR *) sqlStr, (SQLCHAR *) szSqlStr, cbSqlStrMax, NULL); 3544 } 3545 else 3546 { 3547 /* unicode<=ansi*/ 3548 dm_StrCopyOut2_A2W ((SQLCHAR *) sqlStr, (SQLWCHAR *) szSqlStr, cbSqlStrMax, NULL); 3549 } 3550 } 3551 3552 MEM_FREE(_SqlStr); 3553 3554 return retcode; 3555} 3556 3557 3558SQLRETURN SQL_API 3559SQLNativeSql ( 3560 SQLHDBC hdbc, 3561 SQLCHAR * szSqlStrIn, 3562 SQLINTEGER cbSqlStrIn, 3563 SQLCHAR * szSqlStr, 3564 SQLINTEGER cbSqlStrMax, 3565 SQLINTEGER * pcbSqlStr) 3566{ 3567 ENTER_HDBC (hdbc, 0, 3568 trace_SQLNativeSql (TRACE_ENTER, 3569 hdbc, 3570 szSqlStrIn, cbSqlStrIn, 3571 szSqlStr, cbSqlStrMax, pcbSqlStr)); 3572 3573 retcode = SQLNativeSql_Internal ( 3574 hdbc, 3575 szSqlStrIn, cbSqlStrIn, 3576 szSqlStr, cbSqlStrMax, pcbSqlStr, 3577 'A'); 3578 3579 LEAVE_HDBC (hdbc, 0, 3580 trace_SQLNativeSql (TRACE_LEAVE, 3581 hdbc, 3582 szSqlStrIn, cbSqlStrIn, 3583 szSqlStr, cbSqlStrMax, pcbSqlStr)); 3584} 3585 3586 3587SQLRETURN SQL_API 3588SQLNativeSqlA ( 3589 SQLHDBC hdbc, 3590 SQLCHAR * szSqlStrIn, 3591 SQLINTEGER cbSqlStrIn, 3592 SQLCHAR * szSqlStr, 3593 SQLINTEGER cbSqlStrMax, 3594 SQLINTEGER * pcbSqlStr) 3595{ 3596 ENTER_HDBC (hdbc, 0, 3597 trace_SQLNativeSql (TRACE_ENTER, 3598 hdbc, 3599 szSqlStrIn, cbSqlStrIn, 3600 szSqlStr, cbSqlStrMax, pcbSqlStr)); 3601 3602 retcode = SQLNativeSql_Internal( 3603 hdbc, 3604 szSqlStrIn, cbSqlStrIn, 3605 szSqlStr, cbSqlStrMax, pcbSqlStr, 3606 'A'); 3607 3608 LEAVE_HDBC (hdbc, 0, 3609 trace_SQLNativeSql (TRACE_LEAVE, 3610 hdbc, 3611 szSqlStrIn, cbSqlStrIn, 3612 szSqlStr, cbSqlStrMax, pcbSqlStr)); 3613} 3614 3615 3616SQLRETURN SQL_API 3617SQLNativeSqlW ( 3618 SQLHDBC hdbc, 3619 SQLWCHAR * szSqlStrIn, 3620 SQLINTEGER cbSqlStrIn, 3621 SQLWCHAR * szSqlStr, 3622 SQLINTEGER cbSqlStrMax, 3623 SQLINTEGER * pcbSqlStr) 3624{ 3625 ENTER_HDBC (hdbc, 0, 3626 trace_SQLNativeSqlW (TRACE_ENTER, 3627 hdbc, 3628 szSqlStrIn, cbSqlStrIn, 3629 szSqlStr, cbSqlStrMax, pcbSqlStr)); 3630 3631 retcode = SQLNativeSql_Internal( 3632 hdbc, 3633 szSqlStrIn, cbSqlStrIn, 3634 szSqlStr, cbSqlStrMax, pcbSqlStr, 3635 'W'); 3636 3637 LEAVE_HDBC (hdbc, 0, 3638 trace_SQLNativeSqlW (TRACE_LEAVE, 3639 hdbc, 3640 szSqlStrIn, cbSqlStrIn, 3641 szSqlStr, cbSqlStrMax, pcbSqlStr)); 3642} 3643