| 1 | /********************************************************************* | 
| 2 |  * | 
| 3 |  * This is based on code created by Peter Harvey, | 
| 4 |  * (pharvey@codebydesign.com). | 
| 5 |  * | 
| 6 |  * Modified and extended by Nick Gorham | 
| 7 |  * (nick@lurcher.org). | 
| 8 |  * | 
| 9 |  * Any bugs or problems should be considered the fault of Nick and not | 
| 10 |  * Peter. | 
| 11 |  * | 
| 12 |  * copyright (c) 1999 Nick Gorham | 
| 13 |  * | 
| 14 |  * This library is free software; you can redistribute it and/or | 
| 15 |  * modify it under the terms of the GNU Lesser General Public | 
| 16 |  * License as published by the Free Software Foundation; either | 
| 17 |  * version 2 of the License, or (at your option) any later version. | 
| 18 |  * | 
| 19 |  * This library is distributed in the hope that it will be useful, | 
| 20 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 21 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
| 22 |  * Lesser General Public License for more details. | 
| 23 |  * | 
| 24 |  * You should have received a copy of the GNU Lesser General Public | 
| 25 |  * License along with this library; if not, write to the Free Software | 
| 26 |  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
| 27 |  * | 
| 28 |  ********************************************************************** | 
| 29 |  * | 
| 30 |  * $Id: SQLGetInfo.c,v 1.14 2009/02/18 17:59:08 lurcher Exp $ | 
| 31 |  * | 
| 32 |  * $Log: SQLGetInfo.c,v $ | 
| 33 |  * Revision 1.14  2009/02/18 17:59:08  lurcher | 
| 34 |  * Shift to using config.h, the compile lines were making it hard to spot warnings | 
| 35 |  * | 
| 36 |  * Revision 1.13  2009/02/17 09:47:44  lurcher | 
| 37 |  * Clear up a number of bugs | 
| 38 |  * | 
| 39 |  * Revision 1.12  2008/09/29 14:02:45  lurcher | 
| 40 |  * Fix missing dlfcn group option | 
| 41 |  * | 
| 42 |  * Revision 1.11  2007/01/02 10:29:18  lurcher | 
| 43 |  * Fix descriptor leak with unicode only driver | 
| 44 |  * | 
| 45 |  * Revision 1.10  2006/08/31 12:44:52  lurcher | 
| 46 |  * Check in for 2.2.12 release | 
| 47 |  * | 
| 48 |  * Revision 1.9  2006/01/06 18:44:35  lurcher | 
| 49 |  * Couple of unicode fixes | 
| 50 |  * | 
| 51 |  * Revision 1.8  2005/10/06 08:50:58  lurcher | 
| 52 |  * Fix problem with SQLDrivers not returning first entry | 
| 53 |  * | 
| 54 |  * Revision 1.7  2004/11/22 17:02:49  lurcher | 
| 55 |  * Fix unicode/ansi conversion in the SQLGet functions | 
| 56 |  * | 
| 57 |  * Revision 1.6  2003/10/30 18:20:46  lurcher | 
| 58 |  * | 
| 59 |  * Fix broken thread protection | 
| 60 |  * Remove SQLNumResultCols after execute, lease S4/S% to driver | 
| 61 |  * Fix string overrun in SQLDriverConnect | 
| 62 |  * Add initial support for Interix | 
| 63 |  * | 
| 64 |  * Revision 1.5  2003/03/05 09:48:44  lurcher | 
| 65 |  * | 
| 66 |  * Add some 64 bit fixes | 
| 67 |  * | 
| 68 |  * Revision 1.4  2003/02/27 12:19:39  lurcher | 
| 69 |  * | 
| 70 |  * Add the A functions as well as the W | 
| 71 |  * | 
| 72 |  * Revision 1.3  2002/12/05 17:44:31  lurcher | 
| 73 |  * | 
| 74 |  * Display unknown return values in return logging | 
| 75 |  * | 
| 76 |  * Revision 1.2  2002/07/24 08:49:52  lurcher | 
| 77 |  * | 
| 78 |  * Alter UNICODE support to use iconv for UNICODE-ANSI conversion | 
| 79 |  * | 
| 80 |  * Revision 1.1.1.1  2001/10/17 16:40:05  lurcher | 
| 81 |  * | 
| 82 |  * First upload to SourceForge | 
| 83 |  * | 
| 84 |  * Revision 1.9  2001/07/31 12:03:46  nick | 
| 85 |  * | 
| 86 |  * Fix how the DM gets the CLI year for SQLGetInfo | 
| 87 |  * Fix small bug in strncasecmp | 
| 88 |  * | 
| 89 |  * Revision 1.8  2001/07/03 09:30:41  nick | 
| 90 |  * | 
| 91 |  * Add ability to alter size of displayed message in the log | 
| 92 |  * | 
| 93 |  * Revision 1.7  2001/04/23 13:58:43  nick | 
| 94 |  * | 
| 95 |  * Assorted tweeks to text driver to get it to work with StarOffice | 
| 96 |  * | 
| 97 |  * Revision 1.6  2001/04/18 15:03:37  nick | 
| 98 |  * | 
| 99 |  * Fix problem when going to DB2 unicode driver | 
| 100 |  * | 
| 101 |  * Revision 1.5  2001/04/12 17:43:36  nick | 
| 102 |  * | 
| 103 |  * Change logging and added autotest to odbctest | 
| 104 |  * | 
| 105 |  * Revision 1.4  2001/01/12 19:43:12  nick | 
| 106 |  * | 
| 107 |  * Fixed UNICODE conversion bug in SQLGetInfo | 
| 108 |  * | 
| 109 |  * Revision 1.3  2000/12/31 20:30:54  nick | 
| 110 |  * | 
| 111 |  * Add UNICODE support | 
| 112 |  * | 
| 113 |  * Revision 1.2  2000/09/08 08:58:17  nick | 
| 114 |  * | 
| 115 |  * Add SQL_DRIVER_HDESC to SQLGetinfo | 
| 116 |  * | 
| 117 |  * Revision 1.1.1.1  2000/09/04 16:42:52  nick | 
| 118 |  * Imported Sources | 
| 119 |  * | 
| 120 |  * Revision 1.9  1999/11/13 23:40:59  ngorham | 
| 121 |  * | 
| 122 |  * Alter the way DM logging works | 
| 123 |  * Upgrade the Postgres driver to 6.4.6 | 
| 124 |  * | 
| 125 |  * Revision 1.8  1999/11/10 03:51:34  ngorham | 
| 126 |  * | 
| 127 |  * Update the error reporting in the DM to enable ODBC 3 and 2 calls to | 
| 128 |  * work at the same time | 
| 129 |  * | 
| 130 |  * Revision 1.7  1999/10/29 21:07:40  ngorham | 
| 131 |  * | 
| 132 |  * Fix some stupid bugs in the DM | 
| 133 |  * Make the postgres driver work via unix sockets | 
| 134 |  * | 
| 135 |  * Revision 1.6  1999/10/24 23:54:18  ngorham | 
| 136 |  * | 
| 137 |  * First part of the changes to the error reporting | 
| 138 |  * | 
| 139 |  * Revision 1.5  1999/09/21 22:34:25  ngorham | 
| 140 |  * | 
| 141 |  * Improve performance by removing unneeded logging calls when logging is | 
| 142 |  * disabled | 
| 143 |  * | 
| 144 |  * Revision 1.4  1999/07/10 21:10:16  ngorham | 
| 145 |  * | 
| 146 |  * Adjust error sqlstate from driver manager, depending on requested | 
| 147 |  * version (ODBC2/3) | 
| 148 |  * | 
| 149 |  * Revision 1.3  1999/07/04 21:05:07  ngorham | 
| 150 |  * | 
| 151 |  * Add LGPL Headers to code | 
| 152 |  * | 
| 153 |  * Revision 1.2  1999/06/30 23:56:55  ngorham | 
| 154 |  * | 
| 155 |  * Add initial thread safety code | 
| 156 |  * | 
| 157 |  * Revision 1.1.1.1  1999/05/29 13:41:07  sShandyb | 
| 158 |  * first go at it | 
| 159 |  * | 
| 160 |  * Revision 1.1.1.1  1999/05/27 18:23:18  pharvey | 
| 161 |  * Imported sources | 
| 162 |  * | 
| 163 |  * Revision 1.2  1999/04/30 16:22:47  nick | 
| 164 |  * Another checkpoint | 
| 165 |  * | 
| 166 |  * Revision 1.1  1999/04/25 23:06:11  nick | 
| 167 |  * Initial revision | 
| 168 |  * | 
| 169 |  * | 
| 170 |  **********************************************************************/ | 
| 171 |  | 
| 172 | #include <config.h> | 
| 173 | #include "drivermanager.h" | 
| 174 |  | 
| 175 | static char const rcsid[]= "$RCSfile: SQLGetInfo.c,v $ $Revision: 1.14 $" ; | 
| 176 |  | 
| 177 | SQLRETURN SQLGetInfoA( SQLHDBC connection_handle, | 
| 178 |            SQLUSMALLINT info_type, | 
| 179 |            SQLPOINTER info_value, | 
| 180 |            SQLSMALLINT buffer_length, | 
| 181 |            SQLSMALLINT *string_length ) | 
| 182 | { | 
| 183 |     return SQLGetInfo( connection_handle, | 
| 184 |                 info_type, | 
| 185 |                 info_value, | 
| 186 |                 buffer_length, | 
| 187 |                 string_length ); | 
| 188 | } | 
| 189 |  | 
| 190 | SQLRETURN SQLGetInfoInternal( SQLHDBC connection_handle, | 
| 191 |            SQLUSMALLINT info_type, | 
| 192 |            SQLPOINTER info_value, | 
| 193 |            SQLSMALLINT buffer_length, | 
| 194 |            SQLSMALLINT *string_length, | 
| 195 |            int do_checks ) | 
| 196 | { | 
| 197 |     DMHDBC connection = (DMHDBC)connection_handle; | 
| 198 |     SQLRETURN ret = SQL_SUCCESS; | 
| 199 |     SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ]; | 
| 200 |     int type; | 
| 201 | 	SQLUSMALLINT sval; | 
| 202 |     char txt[ 30 ], *cptr; | 
| 203 |     SQLPOINTER *ptr; | 
| 204 |  | 
| 205 |     if ( do_checks ) | 
| 206 |     { | 
| 207 |         if ( !__validate_dbc( connection )) | 
| 208 |         { | 
| 209 |             dm_log_write( __FILE__,  | 
| 210 |                         __LINE__,  | 
| 211 |                         LOG_INFO,  | 
| 212 |                         LOG_INFO,  | 
| 213 |                         "Error: SQL_INVALID_HANDLE"  ); | 
| 214 |  | 
| 215 |             return SQL_INVALID_HANDLE; | 
| 216 |         } | 
| 217 |  | 
| 218 |         function_entry( connection ); | 
| 219 |  | 
| 220 |         if ( log_info.log_flag ) | 
| 221 |         { | 
| 222 |             sprintf( connection -> msg, "\n\t\tEntry:\  | 
| 223 | \n\t\t\tConnection = %p\  | 
| 224 | \n\t\t\tInfo Type = %s (%d)\  | 
| 225 | \n\t\t\tInfo Value = %p\  | 
| 226 | \n\t\t\tBuffer Length = %d\  | 
| 227 | \n\t\t\tStrLen = %p" , | 
| 228 |                     connection, | 
| 229 |                     __info_as_string( s1, info_type ), | 
| 230 |                     info_type, | 
| 231 |                     info_value,  | 
| 232 |                     (int)buffer_length, | 
| 233 |                     (void*)string_length ); | 
| 234 |  | 
| 235 |             dm_log_write( __FILE__,  | 
| 236 |                     __LINE__,  | 
| 237 |                     LOG_INFO,  | 
| 238 |                     LOG_INFO,  | 
| 239 |                     connection -> msg ); | 
| 240 |         } | 
| 241 |  | 
| 242 |         thread_protect( SQL_HANDLE_DBC, connection ); | 
| 243 |  | 
| 244 |         if ( info_type != SQL_ODBC_VER &&  | 
| 245 |                 info_type != SQL_DM_VER && | 
| 246 |                 connection -> state == STATE_C2 ) | 
| 247 |         { | 
| 248 |             dm_log_write( __FILE__,  | 
| 249 |                     __LINE__,  | 
| 250 |                     LOG_INFO,  | 
| 251 |                     LOG_INFO,  | 
| 252 |                     "Error: 08003"  ); | 
| 253 |  | 
| 254 |             __post_internal_error( &connection -> error, | 
| 255 |                     ERROR_08003, NULL, | 
| 256 |                     connection -> environment -> requested_version ); | 
| 257 |  | 
| 258 |             return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); | 
| 259 |         } | 
| 260 |         else if ( connection -> state == STATE_C3 ) | 
| 261 |         { | 
| 262 |             dm_log_write( __FILE__,  | 
| 263 |                     __LINE__,  | 
| 264 |                     LOG_INFO,  | 
| 265 |                     LOG_INFO,  | 
| 266 |                     "Error: 08003"  ); | 
| 267 |  | 
| 268 |             __post_internal_error( &connection -> error, | 
| 269 |                     ERROR_08003, NULL, | 
| 270 |                     connection -> environment -> requested_version ); | 
| 271 |  | 
| 272 |             return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); | 
| 273 |         } | 
| 274 |  | 
| 275 |         if ( buffer_length < 0 ) | 
| 276 |         { | 
| 277 |             dm_log_write( __FILE__,  | 
| 278 |                     __LINE__,  | 
| 279 |                     LOG_INFO,  | 
| 280 |                     LOG_INFO,  | 
| 281 |                     "Error: HY090"  ); | 
| 282 |  | 
| 283 |             __post_internal_error( &connection -> error, | 
| 284 |                     ERROR_HY090, NULL, | 
| 285 |                     connection -> environment -> requested_version ); | 
| 286 |  | 
| 287 |             return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ); | 
| 288 |         } | 
| 289 |     } | 
| 290 |      | 
| 291 |     switch ( info_type ) | 
| 292 |     { | 
| 293 |       case SQL_DATA_SOURCE_NAME: | 
| 294 |         type = 1; | 
| 295 |         cptr = connection -> dsn; | 
| 296 |         break; | 
| 297 |  | 
| 298 |       case SQL_DM_VER: | 
| 299 |         type = 1; | 
| 300 |         sprintf( txt, "%02d.%02d.%04d.%04d" , | 
| 301 |                 SQL_SPEC_MAJOR, SQL_SPEC_MINOR,  | 
| 302 |                 atoi( VERSION ), atoi( VERSION + 2 )); | 
| 303 |         cptr = txt; | 
| 304 |         break; | 
| 305 |  | 
| 306 |       case SQL_ODBC_VER: | 
| 307 |         type = 1; | 
| 308 |         sprintf( txt, "%02d.%02d" , | 
| 309 |                 SQL_SPEC_MAJOR, SQL_SPEC_MINOR ); | 
| 310 |         cptr = txt; | 
| 311 |         break; | 
| 312 |  | 
| 313 |       case SQL_DRIVER_HDBC: | 
| 314 |         type = 2; | 
| 315 |         ptr = (SQLPOINTER) connection -> driver_dbc; | 
| 316 |         break; | 
| 317 |  | 
| 318 |       case SQL_DRIVER_HENV: | 
| 319 |         type = 2; | 
| 320 |         ptr = (SQLPOINTER) connection -> driver_env; | 
| 321 |         break; | 
| 322 |  | 
| 323 |       case SQL_DRIVER_HDESC: | 
| 324 |         { | 
| 325 |             DMHDESC hdesc; | 
| 326 |             if ( info_value && __validate_desc ( hdesc = *(DMHDESC*) info_value ) ) | 
| 327 |             { | 
| 328 |                 type = 2; | 
| 329 |  | 
| 330 |                 ptr = (SQLPOINTER) hdesc -> driver_desc; | 
| 331 |             } | 
| 332 |             else | 
| 333 |             { | 
| 334 |                 dm_log_write( __FILE__,  | 
| 335 |                         __LINE__,  | 
| 336 |                         LOG_INFO,  | 
| 337 |                         LOG_INFO,  | 
| 338 |                         "Error: HY024"  ); | 
| 339 |  | 
| 340 |                 __post_internal_error( &connection -> error, | 
| 341 |                         ERROR_HY024, NULL, | 
| 342 |                         connection -> environment -> requested_version ); | 
| 343 |  | 
| 344 |                 return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ) : SQL_ERROR; | 
| 345 |             } | 
| 346 |         } | 
| 347 |         break; | 
| 348 |  | 
| 349 |       case SQL_DRIVER_HLIB: | 
| 350 |         type = 2; | 
| 351 |         ptr = connection -> dl_handle; | 
| 352 |         break; | 
| 353 |  | 
| 354 |       case SQL_DRIVER_HSTMT: | 
| 355 |         { | 
| 356 |             DMHSTMT hstmt; | 
| 357 |             if ( info_value && __validate_stmt( hstmt = *(DMHSTMT*)info_value ) ) | 
| 358 |             { | 
| 359 |                 type = 2; | 
| 360 |  | 
| 361 |                 ptr = (SQLPOINTER) hstmt -> driver_stmt; | 
| 362 |             } | 
| 363 |             else | 
| 364 |             { | 
| 365 |                 dm_log_write( __FILE__,  | 
| 366 |                     __LINE__,  | 
| 367 |                     LOG_INFO,  | 
| 368 |                     LOG_INFO,  | 
| 369 |                     "Error: HY024"  ); | 
| 370 |  | 
| 371 |                 __post_internal_error( &connection -> error, | 
| 372 |                     ERROR_HY024, NULL, | 
| 373 |                     connection -> environment -> requested_version ); | 
| 374 |  | 
| 375 |                 return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ) : SQL_ERROR; | 
| 376 |             } | 
| 377 |         } | 
| 378 |         break; | 
| 379 |  | 
| 380 |       case SQL_XOPEN_CLI_YEAR: | 
| 381 |         type = 1; | 
| 382 |         cptr = connection -> cli_year; | 
| 383 |         break; | 
| 384 |  | 
| 385 | 	  case SQL_ATTR_DRIVER_THREADING: | 
| 386 | 		type = 3; | 
| 387 | 		sval = connection -> threading_level; | 
| 388 | 		break; | 
| 389 |  | 
| 390 |       default: | 
| 391 |         /* | 
| 392 |          * pass all the others on | 
| 393 |          */ | 
| 394 |  | 
| 395 |         if ( connection -> unicode_driver ) | 
| 396 |         { | 
| 397 |             SQLWCHAR *s1 = NULL; | 
| 398 |  | 
| 399 |             if ( !CHECK_SQLGETINFOW( connection )) | 
| 400 |             { | 
| 401 |                 dm_log_write( __FILE__,  | 
| 402 |                         __LINE__,  | 
| 403 |                         LOG_INFO,  | 
| 404 |                         LOG_INFO,  | 
| 405 |                         "Error: IM001"  ); | 
| 406 |  | 
| 407 |                 __post_internal_error( &connection -> error, | 
| 408 |                         ERROR_IM001, NULL, | 
| 409 |                         connection -> environment -> requested_version ); | 
| 410 |  | 
| 411 |                 return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ) : SQL_ERROR; | 
| 412 |             } | 
| 413 |  | 
| 414 |             switch( info_type ) | 
| 415 |             { | 
| 416 |               case SQL_ACCESSIBLE_PROCEDURES: | 
| 417 |               case SQL_ACCESSIBLE_TABLES: | 
| 418 |               case SQL_CATALOG_NAME: | 
| 419 |               case SQL_CATALOG_NAME_SEPARATOR: | 
| 420 |               case SQL_CATALOG_TERM: | 
| 421 |               case SQL_COLLATION_SEQ: | 
| 422 |               case SQL_COLUMN_ALIAS: | 
| 423 |               case SQL_DATA_SOURCE_NAME: | 
| 424 |               case SQL_DATA_SOURCE_READ_ONLY: | 
| 425 |               case SQL_DATABASE_NAME: | 
| 426 |               case SQL_DBMS_NAME: | 
| 427 |               case SQL_DBMS_VER: | 
| 428 |               case SQL_DESCRIBE_PARAMETER: | 
| 429 |               case SQL_DRIVER_NAME: | 
| 430 |               case SQL_DRIVER_ODBC_VER: | 
| 431 |               case SQL_DRIVER_VER: | 
| 432 |               case SQL_ODBC_VER: | 
| 433 |               case SQL_EXPRESSIONS_IN_ORDERBY: | 
| 434 |               case SQL_IDENTIFIER_QUOTE_CHAR: | 
| 435 |               case SQL_INTEGRITY: | 
| 436 |               case SQL_KEYWORDS: | 
| 437 |               case SQL_LIKE_ESCAPE_CLAUSE: | 
| 438 |               case SQL_MAX_ROW_SIZE_INCLUDES_LONG: | 
| 439 |               case SQL_MULT_RESULT_SETS: | 
| 440 |               case SQL_MULTIPLE_ACTIVE_TXN: | 
| 441 |               case SQL_NEED_LONG_DATA_LEN: | 
| 442 |               case SQL_ORDER_BY_COLUMNS_IN_SELECT: | 
| 443 |               case SQL_PROCEDURE_TERM: | 
| 444 |               case SQL_PROCEDURES: | 
| 445 |               case SQL_ROW_UPDATES: | 
| 446 |               case SQL_SCHEMA_TERM: | 
| 447 |               case SQL_SEARCH_PATTERN_ESCAPE: | 
| 448 |               case SQL_SERVER_NAME: | 
| 449 |               case SQL_SPECIAL_CHARACTERS: | 
| 450 |               case SQL_TABLE_TERM: | 
| 451 |               case SQL_USER_NAME: | 
| 452 |               case SQL_XOPEN_CLI_YEAR: | 
| 453 |               case SQL_OUTER_JOINS: | 
| 454 |                 if ( info_value && buffer_length > 0 ) | 
| 455 |                 { | 
| 456 | 					buffer_length = sizeof( SQLWCHAR ) * ( buffer_length + 1 ); | 
| 457 |                     s1 = malloc( buffer_length ); | 
| 458 |                 } | 
| 459 |                 break; | 
| 460 |             } | 
| 461 |  | 
| 462 |             ret = SQLGETINFOW( connection, | 
| 463 |                     connection -> driver_dbc, | 
| 464 |                     info_type, | 
| 465 |                     s1 ? s1 : info_value, | 
| 466 |                     buffer_length, | 
| 467 |                     string_length ); | 
| 468 |  | 
| 469 |             switch( info_type ) | 
| 470 |             { | 
| 471 |               case SQL_ACCESSIBLE_PROCEDURES: | 
| 472 |               case SQL_ACCESSIBLE_TABLES: | 
| 473 |               case SQL_CATALOG_NAME: | 
| 474 |               case SQL_CATALOG_NAME_SEPARATOR: | 
| 475 |               case SQL_CATALOG_TERM: | 
| 476 |               case SQL_COLLATION_SEQ: | 
| 477 |               case SQL_COLUMN_ALIAS: | 
| 478 |               case SQL_DATA_SOURCE_NAME: | 
| 479 |               case SQL_DATA_SOURCE_READ_ONLY: | 
| 480 |               case SQL_DATABASE_NAME: | 
| 481 |               case SQL_DBMS_NAME: | 
| 482 |               case SQL_DBMS_VER: | 
| 483 |               case SQL_DESCRIBE_PARAMETER: | 
| 484 |               case SQL_DRIVER_NAME: | 
| 485 |               case SQL_DRIVER_ODBC_VER: | 
| 486 |               case SQL_DRIVER_VER: | 
| 487 |               case SQL_ODBC_VER: | 
| 488 |               case SQL_EXPRESSIONS_IN_ORDERBY: | 
| 489 |               case SQL_IDENTIFIER_QUOTE_CHAR: | 
| 490 |               case SQL_INTEGRITY: | 
| 491 |               case SQL_KEYWORDS: | 
| 492 |               case SQL_LIKE_ESCAPE_CLAUSE: | 
| 493 |               case SQL_MAX_ROW_SIZE_INCLUDES_LONG: | 
| 494 |               case SQL_MULT_RESULT_SETS: | 
| 495 |               case SQL_MULTIPLE_ACTIVE_TXN: | 
| 496 |               case SQL_NEED_LONG_DATA_LEN: | 
| 497 |               case SQL_ORDER_BY_COLUMNS_IN_SELECT: | 
| 498 |               case SQL_PROCEDURE_TERM: | 
| 499 |               case SQL_PROCEDURES: | 
| 500 |               case SQL_ROW_UPDATES: | 
| 501 |               case SQL_SCHEMA_TERM: | 
| 502 |               case SQL_SEARCH_PATTERN_ESCAPE: | 
| 503 |               case SQL_SERVER_NAME: | 
| 504 |               case SQL_SPECIAL_CHARACTERS: | 
| 505 |               case SQL_TABLE_TERM: | 
| 506 |               case SQL_USER_NAME: | 
| 507 |               case SQL_XOPEN_CLI_YEAR: | 
| 508 |               case SQL_OUTER_JOINS: | 
| 509 |                 if ( SQL_SUCCEEDED( ret ) && info_value && s1 ) | 
| 510 |                 { | 
| 511 |                     unicode_to_ansi_copy( info_value, buffer_length, s1, SQL_NTS, connection, NULL  ); | 
| 512 |                 } | 
| 513 | 				if ( SQL_SUCCEEDED( ret ) && string_length && info_value )  | 
| 514 | 				{ | 
| 515 | 					*string_length = strlen(info_value); | 
| 516 | 				} | 
| 517 |                 break; | 
| 518 |             } | 
| 519 |             if ( s1 ) | 
| 520 |             { | 
| 521 |                 free( s1 ); | 
| 522 |             } | 
| 523 |         } | 
| 524 |         else | 
| 525 |         { | 
| 526 |             if ( !CHECK_SQLGETINFO( connection )) | 
| 527 |             { | 
| 528 |                 dm_log_write( __FILE__,  | 
| 529 |                         __LINE__,  | 
| 530 |                         LOG_INFO,  | 
| 531 |                         LOG_INFO,  | 
| 532 |                         "Error: IM001"  ); | 
| 533 |  | 
| 534 |                 __post_internal_error( &connection -> error, | 
| 535 |                         ERROR_IM001, NULL, | 
| 536 |                         connection -> environment -> requested_version ); | 
| 537 |  | 
| 538 |                 return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR ) : SQL_ERROR; | 
| 539 |             } | 
| 540 |  | 
| 541 |             ret = SQLGETINFO( connection, | 
| 542 |                     connection -> driver_dbc, | 
| 543 |                     info_type, | 
| 544 |                     info_value, | 
| 545 |                     buffer_length, | 
| 546 |                     string_length ); | 
| 547 |         } | 
| 548 |  | 
| 549 |         return do_checks ? function_return( SQL_HANDLE_DBC, connection, ret ) : ret; | 
| 550 |     } | 
| 551 |  | 
| 552 |     if ( type == 1 ) | 
| 553 |     { | 
| 554 |         if ( string_length ) | 
| 555 |             *string_length = strlen( cptr ); | 
| 556 |  | 
| 557 |         if ( info_value ) | 
| 558 |         { | 
| 559 |             if ( buffer_length > strlen( cptr ) + 1 ) | 
| 560 |             { | 
| 561 |                 strcpy( info_value, cptr ); | 
| 562 |             } | 
| 563 |             else | 
| 564 |             { | 
| 565 |                 memcpy( info_value, cptr, buffer_length - 1 ); | 
| 566 |                 ((char*)info_value)[ buffer_length - 1 ] = '\0'; | 
| 567 |                 ret = SQL_SUCCESS_WITH_INFO; | 
| 568 |             } | 
| 569 |         } | 
| 570 |     } | 
| 571 |     else if ( type == 2 ) | 
| 572 |     { | 
| 573 |         if ( info_value ) | 
| 574 |             *((void **)info_value) = ptr; | 
| 575 |  | 
| 576 |         if ( string_length ) | 
| 577 |             *string_length = sizeof( SQLPOINTER ); | 
| 578 |     } | 
| 579 | 	else if ( type == 3 )  | 
| 580 | 	{ | 
| 581 |         if ( info_value ) | 
| 582 |             *((SQLUSMALLINT *)info_value) = sval; | 
| 583 |  | 
| 584 |         if ( string_length ) | 
| 585 |             *string_length = sizeof( SQLUSMALLINT ); | 
| 586 | 	} | 
| 587 |  | 
| 588 |     return do_checks ? function_return_nodrv( SQL_HANDLE_DBC, connection, ret ) : ret; | 
| 589 | } | 
| 590 |  | 
| 591 | SQLRETURN __SQLGetInfo( SQLHDBC connection_handle, | 
| 592 |            SQLUSMALLINT info_type, | 
| 593 |            SQLPOINTER info_value, | 
| 594 |            SQLSMALLINT buffer_length, | 
| 595 |            SQLSMALLINT *string_length ) | 
| 596 | { | 
| 597 |     return SQLGetInfoInternal( connection_handle, info_type, info_value, | 
| 598 |         buffer_length, string_length, 0); | 
| 599 | } | 
| 600 |  | 
| 601 | SQLRETURN SQLGetInfo( SQLHDBC connection_handle, | 
| 602 |            SQLUSMALLINT info_type, | 
| 603 |            SQLPOINTER info_value, | 
| 604 |            SQLSMALLINT buffer_length, | 
| 605 |            SQLSMALLINT *string_length ) | 
| 606 | { | 
| 607 |     return SQLGetInfoInternal( connection_handle, info_type, info_value, | 
| 608 |         buffer_length, string_length, 1); | 
| 609 | } | 
| 610 |  |