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: SQLGetConnectOptionW.c,v 1.10 2009/02/18 17:59:08 lurcher Exp $
31 *
32 * $Log: SQLGetConnectOptionW.c,v $
33 * Revision 1.10 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.9 2009/02/17 09:47:44 lurcher
37 * Clear up a number of bugs
38 *
39 * Revision 1.8 2008/08/29 08:01:38 lurcher
40 * Alter the way W functions are passed to the driver
41 *
42 * Revision 1.7 2007/02/28 15:37:48 lurcher
43 * deal with drivers that call internal W functions and end up in the driver manager. controlled by the --enable-handlemap configure arg
44 *
45 * Revision 1.6 2003/10/30 18:20:46 lurcher
46 *
47 * Fix broken thread protection
48 * Remove SQLNumResultCols after execute, lease S4/S% to driver
49 * Fix string overrun in SQLDriverConnect
50 * Add initial support for Interix
51 *
52 * Revision 1.5 2002/12/05 17:44:30 lurcher
53 *
54 * Display unknown return values in return logging
55 *
56 * Revision 1.4 2002/11/11 17:10:12 lurcher
57 *
58 * VMS changes
59 *
60 * Revision 1.3 2002/08/23 09:42:37 lurcher
61 *
62 * Fix some build warnings with casts, and a AIX linker mod, to include
63 * deplib's on the link line, but not the libtool generated ones
64 *
65 * Revision 1.2 2002/07/24 08:49:52 lurcher
66 *
67 * Alter UNICODE support to use iconv for UNICODE-ANSI conversion
68 *
69 * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher
70 *
71 * First upload to SourceForge
72 *
73 * Revision 1.4 2001/08/03 15:19:00 nick
74 *
75 * Add changes to set values before connect
76 *
77 * Revision 1.3 2001/07/03 09:30:41 nick
78 *
79 * Add ability to alter size of displayed message in the log
80 *
81 * Revision 1.2 2001/04/12 17:43:36 nick
82 *
83 * Change logging and added autotest to odbctest
84 *
85 * Revision 1.1 2000/12/31 20:30:54 nick
86 *
87 * Add UNICODE support
88 *
89 *
90 **********************************************************************/
91
92 #include <config.h>
93 #include "drivermanager.h"
94
95 static char const rcsid[]= "$RCSfile: SQLGetConnectOptionW.c,v $";
96
SQLGetConnectOptionW(SQLHDBC connection_handle,SQLUSMALLINT option,SQLPOINTER value)97 SQLRETURN SQLGetConnectOptionW( SQLHDBC connection_handle,
98 SQLUSMALLINT option,
99 SQLPOINTER value )
100 {
101 DMHDBC connection = (DMHDBC)connection_handle;
102 int type = 0;
103 SQLCHAR s1[ 100 + LOG_MESSAGE_LEN ];
104
105 /*
106 * doesn't require a handle
107 */
108
109 if ( option == SQL_ATTR_TRACE )
110 {
111 if ( value )
112 {
113 *((SQLINTEGER*)value) = SQL_OPT_TRACE_ON;
114 }
115
116 return SQL_SUCCESS;
117 }
118 else if ( option == SQL_ATTR_TRACEFILE )
119 {
120 SQLRETURN ret = SQL_SUCCESS;
121
122 if ( log_info.log_file_name )
123 {
124 ansi_to_unicode_copy( value, log_info.log_file_name, SQL_NTS, connection, NULL );
125 }
126 else
127 {
128 ansi_to_unicode_copy( value, "", SQL_NTS, connection, NULL );
129 }
130 return ret;
131 }
132
133
134 /*
135 * check connection
136 */
137
138 if ( !__validate_dbc( connection ))
139 {
140 dm_log_write( __FILE__,
141 __LINE__,
142 LOG_INFO,
143 LOG_INFO,
144 "Error: SQL_INVALID_HANDLE" );
145
146 #ifdef WITH_HANDLE_REDIRECT
147 {
148 DMHDBC parent_connection;
149
150 parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC );
151
152 if ( parent_connection ) {
153 dm_log_write( __FILE__,
154 __LINE__,
155 LOG_INFO,
156 LOG_INFO,
157 "Info: found parent handle" );
158
159 if ( CHECK_SQLGETCONNECTOPTIONW( parent_connection ))
160 {
161 dm_log_write( __FILE__,
162 __LINE__,
163 LOG_INFO,
164 LOG_INFO,
165 "Info: calling redirected driver function" );
166
167 return SQLGETCONNECTOPTIONW( parent_connection,
168 connection,
169 option,
170 value );
171 }
172 }
173 }
174 #endif
175 return SQL_INVALID_HANDLE;
176 }
177
178 function_entry( connection );
179
180 if ( log_info.log_flag )
181 {
182 sprintf( connection -> msg, "\n\t\tEntry:\
183 \n\t\t\tConnection = %p\
184 \n\t\t\tOption = %s\
185 \n\t\t\tValue = %p",
186 connection,
187 __con_attr_as_string( s1, option ),
188 value );
189
190 dm_log_write( __FILE__,
191 __LINE__,
192 LOG_INFO,
193 LOG_INFO,
194 connection -> msg );
195 }
196
197 thread_protect( SQL_HANDLE_DBC, connection );
198
199 if ( connection -> state == STATE_C3 )
200 {
201 dm_log_write( __FILE__,
202 __LINE__,
203 LOG_INFO,
204 LOG_INFO,
205 "Error: HY010" );
206
207 __post_internal_error( &connection -> error,
208 ERROR_HY010, NULL,
209 connection -> environment -> requested_version );
210
211 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
212 }
213
214 if ( connection -> state == STATE_C2 )
215 {
216 switch ( option )
217 {
218 case SQL_ACCESS_MODE:
219 case SQL_AUTOCOMMIT:
220 case SQL_LOGIN_TIMEOUT:
221 case SQL_ODBC_CURSORS:
222 break;
223
224 default:
225 dm_log_write( __FILE__,
226 __LINE__,
227 LOG_INFO,
228 LOG_INFO,
229 "Error: 08003" );
230
231 __post_internal_error( &connection -> error,
232 ERROR_08003, NULL,
233 connection -> environment -> requested_version );
234
235 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
236 }
237 }
238
239 switch ( option )
240 {
241 case SQL_ACCESS_MODE:
242 /*
243 * if connected, call the driver
244 */
245 if ( connection -> state != STATE_C2 )
246 {
247 type = 0;
248 }
249 else
250 {
251 *((SQLINTEGER*)value) = connection -> access_mode;
252 type = 1;
253 }
254 break;
255
256 case SQL_AUTOCOMMIT:
257 /*
258 * if connected, call the driver
259 */
260 if ( connection -> state != STATE_C2 )
261 {
262 type = 0;
263 }
264 else
265 {
266 *((SQLINTEGER*)value) = connection -> auto_commit;
267 type = 1;
268 }
269 break;
270
271 case SQL_ODBC_CURSORS:
272 *((SQLINTEGER*)value) = connection -> cursors;
273 type = 1;
274 break;
275
276 case SQL_ATTR_LOGIN_TIMEOUT:
277 /*
278 * if connected, call the driver
279 */
280 if ( connection -> state != STATE_C2 )
281 {
282 type = 0;
283 }
284 else
285 {
286 *((SQLINTEGER*)value) = connection -> login_timeout;
287 type = 1;
288 }
289 break;
290
291
292 default:
293 break;
294 }
295
296 /*
297 * if type has been set we have already set the value,
298 * so just return
299 */
300 if ( type )
301 {
302 sprintf( connection -> msg,
303 "\n\t\tExit:[%s]",
304 __get_return_status( SQL_SUCCESS, s1 ));
305
306 dm_log_write( __FILE__,
307 __LINE__,
308 LOG_INFO,
309 LOG_INFO,
310 connection -> msg );
311
312 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_SUCCESS );
313 }
314 else
315 {
316 SQLRETURN ret = 0;
317
318 /*
319 * call the driver
320 */
321 if ( connection -> unicode_driver ||
322 CHECK_SQLGETCONNECTOPTIONW( connection ) ||
323 CHECK_SQLGETCONNECTATTRW( connection ))
324 {
325 if ( CHECK_SQLGETCONNECTOPTIONW( connection ))
326 {
327 ret = SQLGETCONNECTOPTIONW( connection,
328 connection -> driver_dbc,
329 option,
330 value );
331 }
332 else if ( CHECK_SQLGETCONNECTATTRW( connection ))
333 {
334 SQLINTEGER length, len;
335 void * ptr;
336 SQLWCHAR txt[ 1024 ];
337
338 switch( option )
339 {
340 case SQL_ATTR_CURRENT_CATALOG:
341 case SQL_ATTR_TRACEFILE:
342 case SQL_ATTR_TRANSLATE_LIB:
343 length = sizeof( txt );
344 ptr = txt;
345 break;
346
347 default:
348 length = sizeof( SQLINTEGER );
349 ptr = value;
350 break;
351
352 }
353
354 ret = SQLGETCONNECTATTRW( connection,
355 connection -> driver_dbc,
356 option,
357 ptr,
358 length,
359 &len );
360
361 /*
362 * not much else we can do here, lets assume that
363 * there is enough space
364 */
365
366 if ( ptr != value )
367 {
368 wide_strcpy( value, ptr );
369
370 /*
371 * are we still here ? good
372 */
373 }
374 }
375 else
376 {
377 __post_internal_error( &connection -> error,
378 ERROR_IM001, NULL,
379 connection -> environment -> requested_version );
380
381 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
382 }
383 }
384 else
385 {
386 if (( ret = CHECK_SQLGETCONNECTOPTION( connection )))
387 {
388 SQLCHAR *as1 = NULL;
389
390 switch( option )
391 {
392 case SQL_ATTR_CURRENT_CATALOG:
393 case SQL_ATTR_TRACEFILE:
394 case SQL_ATTR_TRANSLATE_LIB:
395 if ( SQL_SUCCEEDED( ret ) && value )
396 {
397 /*
398 * we need to chance out arm here, as we dont know
399 */
400
401 as1 = malloc( 1024 );
402 }
403 break;
404 }
405
406 ret = SQLGETCONNECTOPTION( connection,
407 connection -> driver_dbc,
408 option,
409 as1 ? as1 : value );
410
411 switch( option )
412 {
413 case SQL_ATTR_CURRENT_CATALOG:
414 case SQL_ATTR_TRACEFILE:
415 case SQL_ATTR_TRANSLATE_LIB:
416 if ( SQL_SUCCEEDED( ret ) && value && as1 )
417 {
418 ansi_to_unicode_copy( value, (char*) as1, SQL_NTS, connection, NULL );
419 }
420
421 if ( as1 )
422 {
423 free( as1 );
424 }
425 break;
426 }
427 }
428 else if ( CHECK_SQLGETCONNECTATTR( connection ))
429 {
430 SQLINTEGER length, len;
431 void * ptr;
432 char txt[ 1024 ];
433
434 switch( option )
435 {
436 case SQL_ATTR_CURRENT_CATALOG:
437 case SQL_ATTR_TRACEFILE:
438 case SQL_ATTR_TRANSLATE_LIB:
439 length = sizeof( txt );
440 ptr = txt;
441 break;
442
443 default:
444 length = sizeof( SQLINTEGER );
445 ptr = value;
446 break;
447
448 }
449
450 ret = SQLGETCONNECTATTR( connection,
451 connection -> driver_dbc,
452 option,
453 ptr,
454 length,
455 &len );
456
457 /*
458 * not much else we can do here, lets assume that
459 * there is enough space
460 */
461
462 if ( ptr != value )
463 {
464 SQLWCHAR *s1;
465
466 s1 = ansi_to_unicode_alloc( value, SQL_NTS, connection, NULL );
467
468 if ( s1 )
469 {
470 wide_strcpy( value, s1 );
471 free( s1 );
472 }
473
474 /*
475 * are we still here ? good
476 */
477 }
478 }
479 else
480 {
481 __post_internal_error( &connection -> error,
482 ERROR_IM001, NULL,
483 connection -> environment -> requested_version );
484
485 return function_return_nodrv( SQL_HANDLE_DBC, connection, SQL_ERROR );
486 }
487 }
488
489 if ( log_info.log_flag )
490 {
491 sprintf( connection -> msg,
492 "\n\t\tExit:[%s]",
493 __get_return_status( ret, s1 ));
494
495 dm_log_write( __FILE__,
496 __LINE__,
497 LOG_INFO,
498 LOG_INFO,
499 connection -> msg );
500 }
501
502 return function_return( SQL_HANDLE_DBC, connection, ret, DEFER_R3 );
503 }
504 }
505