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: SQLGetDiagRecW.c,v 1.11 2009/02/18 17:59:08 lurcher Exp $ |
31 | * |
32 | * $Log: SQLGetDiagRecW.c,v $ |
33 | * Revision 1.11 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.10 2009/02/04 09:30:02 lurcher |
37 | * Fix some SQLINTEGER/SQLLEN conflicts |
38 | * |
39 | * Revision 1.9 2007/11/26 11:37:23 lurcher |
40 | * Sync up before tag |
41 | * |
42 | * Revision 1.8 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.7 2002/12/05 17:44:31 lurcher |
46 | * |
47 | * Display unknown return values in return logging |
48 | * |
49 | * Revision 1.6 2002/11/11 17:10:17 lurcher |
50 | * |
51 | * VMS changes |
52 | * |
53 | * Revision 1.5 2002/08/23 09:42:37 lurcher |
54 | * |
55 | * Fix some build warnings with casts, and a AIX linker mod, to include |
56 | * deplib's on the link line, but not the libtool generated ones |
57 | * |
58 | * Revision 1.4 2002/07/24 08:49:52 lurcher |
59 | * |
60 | * Alter UNICODE support to use iconv for UNICODE-ANSI conversion |
61 | * |
62 | * Revision 1.3 2002/05/21 14:19:44 lurcher |
63 | * |
64 | * * Update libtool to escape from AIX build problem |
65 | * * Add fix to avoid file handle limitations |
66 | * * Add more UNICODE changes, it looks like it is native 16 representation |
67 | * the old way can be reproduced by defining UCS16BE |
68 | * * Add iusql, its just the same as isql but uses the wide functions |
69 | * |
70 | * Revision 1.2 2001/12/13 13:00:32 lurcher |
71 | * |
72 | * Remove most if not all warnings on 64 bit platforms |
73 | * Add support for new MS 3.52 64 bit changes |
74 | * Add override to disable the stopping of tracing |
75 | * Add MAX_ROWS support in postgres driver |
76 | * |
77 | * Revision 1.1.1.1 2001/10/17 16:40:05 lurcher |
78 | * |
79 | * First upload to SourceForge |
80 | * |
81 | * Revision 1.3 2001/07/03 09:30:41 nick |
82 | * |
83 | * Add ability to alter size of displayed message in the log |
84 | * |
85 | * Revision 1.2 2001/04/12 17:43:36 nick |
86 | * |
87 | * Change logging and added autotest to odbctest |
88 | * |
89 | * Revision 1.1 2000/12/31 20:30:54 nick |
90 | * |
91 | * Add UNICODE support |
92 | * |
93 | * |
94 | **********************************************************************/ |
95 | |
96 | #include <config.h> |
97 | #include "drivermanager.h" |
98 | |
99 | static char const rcsid[]= "$RCSfile: SQLGetDiagRecW.c,v $" ; |
100 | |
101 | extern int __is_env( EHEAD * head ); /* in SQLGetDiagRec.c */ |
102 | |
103 | static SQLRETURN ( EHEAD *head, |
104 | SQLWCHAR *sqlstate, |
105 | SQLINTEGER rec_number, |
106 | SQLINTEGER *native_error, |
107 | SQLWCHAR *message_text, |
108 | SQLSMALLINT buffer_length, |
109 | SQLSMALLINT *text_length ) |
110 | { |
111 | SQLRETURN ret; |
112 | |
113 | if ( sqlstate ) |
114 | { |
115 | SQLWCHAR *tmp; |
116 | |
117 | tmp = ansi_to_unicode_alloc((SQLCHAR*) "00000" , SQL_NTS, __get_connection( head ), NULL ); |
118 | wide_strcpy( sqlstate, tmp ); |
119 | free( tmp ); |
120 | } |
121 | |
122 | if ( rec_number <= head -> sql_diag_head.internal_count ) |
123 | { |
124 | ERROR *ptr; |
125 | |
126 | ptr = head -> sql_diag_head.internal_list_head; |
127 | while( rec_number > 1 ) |
128 | { |
129 | ptr = ptr -> next; |
130 | rec_number --; |
131 | } |
132 | |
133 | if ( !ptr ) |
134 | { |
135 | return SQL_NO_DATA; |
136 | } |
137 | |
138 | if ( sqlstate ) |
139 | { |
140 | wide_strcpy( sqlstate, ptr -> sqlstate ); |
141 | } |
142 | if ( buffer_length < wide_strlen( ptr -> msg ) + 1 ) |
143 | { |
144 | ret = SQL_SUCCESS_WITH_INFO; |
145 | } |
146 | else |
147 | { |
148 | ret = SQL_SUCCESS; |
149 | } |
150 | |
151 | if ( message_text ) |
152 | { |
153 | if ( ret == SQL_SUCCESS ) |
154 | { |
155 | wide_strcpy( message_text, ptr -> msg ); |
156 | } |
157 | else |
158 | { |
159 | memcpy( message_text, ptr -> msg, buffer_length * 2 ); |
160 | message_text[ buffer_length - 1 ] = '\0'; |
161 | } |
162 | } |
163 | |
164 | if ( text_length ) |
165 | { |
166 | *text_length = wide_strlen( ptr -> msg ); |
167 | } |
168 | |
169 | if ( native_error ) |
170 | { |
171 | *native_error = ptr -> native_error; |
172 | } |
173 | |
174 | /* |
175 | * map 3 to 2 if required |
176 | */ |
177 | |
178 | if ( SQL_SUCCEEDED( ret ) && sqlstate ) |
179 | __map_error_state_w(sqlstate, __get_version( head )); |
180 | |
181 | return ret; |
182 | } |
183 | else if ( !__is_env( head ) && __get_connection( head ) -> state != STATE_C2 |
184 | && head->sql_diag_head.error_count ) |
185 | { |
186 | ERROR *ptr; |
187 | rec_number -= head -> sql_diag_head.internal_count; |
188 | |
189 | if ( __get_connection( head ) -> unicode_driver && |
190 | CHECK_SQLGETDIAGRECW( __get_connection( head ))) |
191 | { |
192 | ret = SQLGETDIAGRECW( __get_connection( head ), |
193 | head -> handle_type, |
194 | __get_driver_handle( head ), |
195 | rec_number, |
196 | sqlstate, |
197 | native_error, |
198 | message_text, |
199 | buffer_length, |
200 | text_length ); |
201 | |
202 | /* |
203 | * map 3 to 2 if required |
204 | */ |
205 | |
206 | if ( SQL_SUCCEEDED( ret ) && sqlstate ) |
207 | { |
208 | __map_error_state_w( sqlstate, __get_version( head )); |
209 | } |
210 | |
211 | return ret; |
212 | } |
213 | else if ( !__get_connection( head ) -> unicode_driver && |
214 | CHECK_SQLGETDIAGREC( __get_connection( head ))) |
215 | { |
216 | SQLCHAR *as1 = NULL, *as2 = NULL; |
217 | |
218 | if ( sqlstate ) |
219 | { |
220 | as1 = malloc( 7 ); |
221 | } |
222 | |
223 | if ( message_text && buffer_length > 0 ) |
224 | { |
225 | as2 = malloc( buffer_length + 1 ); |
226 | } |
227 | |
228 | ret = SQLGETDIAGREC( __get_connection( head ), |
229 | head -> handle_type, |
230 | __get_driver_handle( head ), |
231 | rec_number, |
232 | as1 ? as1 : (SQLCHAR *)sqlstate, |
233 | native_error, |
234 | as2 ? as2 : (SQLCHAR *)message_text, |
235 | buffer_length, |
236 | text_length ); |
237 | |
238 | /* |
239 | * map 3 to 2 if required |
240 | */ |
241 | |
242 | if ( SQL_SUCCEEDED( ret ) && sqlstate ) |
243 | { |
244 | if ( sqlstate ) |
245 | { |
246 | if ( as1 ) |
247 | { |
248 | ansi_to_unicode_copy( sqlstate,(char*) as1, SQL_NTS, __get_connection( head ), NULL ); |
249 | __map_error_state_w( sqlstate, __get_version( head )); |
250 | } |
251 | } |
252 | if ( message_text ) |
253 | { |
254 | if ( as2 ) |
255 | { |
256 | ansi_to_unicode_copy( message_text,(char*) as2, SQL_NTS, __get_connection( head ), NULL ); |
257 | } |
258 | } |
259 | } |
260 | |
261 | if ( as1 ) free( as1 ); |
262 | if ( as2 ) free( as2 ); |
263 | |
264 | return ret; |
265 | } |
266 | else |
267 | { |
268 | ptr = head -> sql_diag_head.error_list_head; |
269 | while( rec_number > 1 ) |
270 | { |
271 | ptr = ptr -> next; |
272 | rec_number --; |
273 | } |
274 | |
275 | if ( !ptr ) |
276 | { |
277 | return SQL_NO_DATA; |
278 | } |
279 | |
280 | if ( sqlstate ) |
281 | { |
282 | wide_strcpy( sqlstate, ptr -> sqlstate ); |
283 | } |
284 | if ( buffer_length < wide_strlen( ptr -> msg ) + 1 ) |
285 | { |
286 | ret = SQL_SUCCESS_WITH_INFO; |
287 | } |
288 | else |
289 | { |
290 | ret = SQL_SUCCESS; |
291 | } |
292 | |
293 | if ( message_text ) |
294 | { |
295 | if ( ret == SQL_SUCCESS ) |
296 | { |
297 | wide_strcpy( message_text, ptr -> msg ); |
298 | } |
299 | else |
300 | { |
301 | memcpy( message_text, ptr -> msg, buffer_length * 2 ); |
302 | message_text[ buffer_length - 1 ] = '\0'; |
303 | } |
304 | } |
305 | |
306 | if ( text_length ) |
307 | { |
308 | *text_length = wide_strlen( ptr -> msg ); |
309 | } |
310 | |
311 | if ( native_error ) |
312 | { |
313 | *native_error = ptr -> native_error; |
314 | } |
315 | |
316 | /* |
317 | * map 3 to 2 if required |
318 | */ |
319 | |
320 | if ( SQL_SUCCEEDED( ret ) && sqlstate ) |
321 | __map_error_state_w( sqlstate, __get_version( head )); |
322 | |
323 | return ret; |
324 | } |
325 | } |
326 | else |
327 | { |
328 | return SQL_NO_DATA; |
329 | } |
330 | } |
331 | |
332 | SQLRETURN SQLGetDiagRecW( SQLSMALLINT handle_type, |
333 | SQLHANDLE handle, |
334 | SQLSMALLINT rec_number, |
335 | SQLWCHAR *sqlstate, |
336 | SQLINTEGER *native, |
337 | SQLWCHAR *message_text, |
338 | SQLSMALLINT buffer_length, |
339 | SQLSMALLINT *text_length_ptr ) |
340 | { |
341 | SQLRETURN ret; |
342 | SQLCHAR s0[ 32 ], s1[ 100 + LOG_MESSAGE_LEN ]; |
343 | SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ]; |
344 | SQLCHAR s3[ 100 + LOG_MESSAGE_LEN ]; |
345 | |
346 | if ( rec_number < 1 ) |
347 | { |
348 | return SQL_ERROR; |
349 | } |
350 | |
351 | if ( handle_type == SQL_HANDLE_ENV ) |
352 | { |
353 | DMHENV environment = ( DMHENV ) handle; |
354 | |
355 | if ( !__validate_env( environment )) |
356 | { |
357 | dm_log_write( __FILE__, |
358 | __LINE__, |
359 | LOG_INFO, |
360 | LOG_INFO, |
361 | "Error: SQL_INVALID_HANDLE" ); |
362 | |
363 | return SQL_INVALID_HANDLE; |
364 | } |
365 | |
366 | thread_protect( SQL_HANDLE_ENV, environment ); |
367 | |
368 | if ( log_info.log_flag ) |
369 | { |
370 | sprintf( environment -> msg, |
371 | "\n\t\tEntry:\ |
372 | \n\t\t\tEnvironment = %p\ |
373 | \n\t\t\tRec Number = %d\ |
374 | \n\t\t\tSQLState = %p\ |
375 | \n\t\t\tNative = %p\ |
376 | \n\t\t\tMessage Text = %p\ |
377 | \n\t\t\tBuffer Length = %d\ |
378 | \n\t\t\tText Len Ptr = %p" , |
379 | environment, |
380 | rec_number, |
381 | sqlstate, |
382 | native, |
383 | message_text, |
384 | buffer_length, |
385 | text_length_ptr ); |
386 | |
387 | dm_log_write( __FILE__, |
388 | __LINE__, |
389 | LOG_INFO, |
390 | LOG_INFO, |
391 | environment -> msg ); |
392 | } |
393 | |
394 | ret = extract_sql_error_rec_w( &environment -> error, |
395 | sqlstate, |
396 | rec_number, |
397 | native, |
398 | message_text, |
399 | buffer_length, |
400 | text_length_ptr ); |
401 | |
402 | if ( log_info.log_flag ) |
403 | { |
404 | if ( SQL_SUCCEEDED( ret )) |
405 | { |
406 | char *ts1, *ts2; |
407 | |
408 | sprintf( environment -> msg, |
409 | "\n\t\tExit:[%s]\ |
410 | \n\t\t\tSQLState = %s\ |
411 | \n\t\t\tNative = %s\ |
412 | \n\t\t\tMessage Text = %s" , |
413 | __get_return_status( ret, s2 ), |
414 | __sdata_as_string( s3, SQL_CHAR, |
415 | NULL, ts1 = unicode_to_ansi_alloc( sqlstate, SQL_NTS, NULL, NULL )), |
416 | __iptr_as_string( s0, native ), |
417 | __sdata_as_string( s1, SQL_CHAR, |
418 | text_length_ptr, ts2 = unicode_to_ansi_alloc( message_text, SQL_NTS, NULL, NULL ))); |
419 | |
420 | if ( ts1 ) { |
421 | free( ts1 ); |
422 | } |
423 | if ( ts2 ) { |
424 | free( ts2 ); |
425 | } |
426 | } |
427 | else |
428 | { |
429 | sprintf( environment -> msg, |
430 | "\n\t\tExit:[%s]" , |
431 | __get_return_status( ret, s2 )); |
432 | } |
433 | |
434 | dm_log_write( __FILE__, |
435 | __LINE__, |
436 | LOG_INFO, |
437 | LOG_INFO, |
438 | environment -> msg ); |
439 | } |
440 | |
441 | thread_release( SQL_HANDLE_ENV, environment ); |
442 | |
443 | return ret; |
444 | } |
445 | else if ( handle_type == SQL_HANDLE_DBC ) |
446 | { |
447 | DMHDBC connection = ( DMHDBC ) handle; |
448 | |
449 | if ( !__validate_dbc( connection )) |
450 | { |
451 | dm_log_write( __FILE__, |
452 | __LINE__, |
453 | LOG_INFO, |
454 | LOG_INFO, |
455 | "Error: SQL_INVALID_HANDLE" ); |
456 | |
457 | #ifdef WITH_HANDLE_REDIRECT |
458 | { |
459 | DMHDBC parent_connection; |
460 | |
461 | parent_connection = find_parent_handle( connection, SQL_HANDLE_DBC ); |
462 | |
463 | if ( parent_connection ) { |
464 | dm_log_write( __FILE__, |
465 | __LINE__, |
466 | LOG_INFO, |
467 | LOG_INFO, |
468 | "Info: found parent handle" ); |
469 | |
470 | if ( CHECK_SQLGETDIAGRECW( parent_connection )) |
471 | { |
472 | dm_log_write( __FILE__, |
473 | __LINE__, |
474 | LOG_INFO, |
475 | LOG_INFO, |
476 | "Info: calling redirected driver function" ); |
477 | |
478 | return SQLGETDIAGRECW( parent_connection, |
479 | handle_type, |
480 | connection, |
481 | rec_number, |
482 | sqlstate, |
483 | native, |
484 | message_text, |
485 | buffer_length, |
486 | text_length_ptr ); |
487 | } |
488 | } |
489 | } |
490 | #endif |
491 | return SQL_INVALID_HANDLE; |
492 | } |
493 | |
494 | thread_protect( SQL_HANDLE_DBC, connection ); |
495 | |
496 | if ( log_info.log_flag ) |
497 | { |
498 | sprintf( connection -> msg, |
499 | "\n\t\tEntry:\ |
500 | \n\t\t\tConnection = %p\ |
501 | \n\t\t\tRec Number = %d\ |
502 | \n\t\t\tSQLState = %p\ |
503 | \n\t\t\tNative = %p\ |
504 | \n\t\t\tMessage Text = %p\ |
505 | \n\t\t\tBuffer Length = %d\ |
506 | \n\t\t\tText Len Ptr = %p" , |
507 | connection, |
508 | rec_number, |
509 | sqlstate, |
510 | native, |
511 | message_text, |
512 | buffer_length, |
513 | text_length_ptr ); |
514 | |
515 | dm_log_write( __FILE__, |
516 | __LINE__, |
517 | LOG_INFO, |
518 | LOG_INFO, |
519 | connection -> msg ); |
520 | } |
521 | |
522 | ret = extract_sql_error_rec_w( &connection -> error, |
523 | sqlstate, |
524 | rec_number, |
525 | native, |
526 | message_text, |
527 | buffer_length, |
528 | text_length_ptr ); |
529 | |
530 | if ( log_info.log_flag ) |
531 | { |
532 | if ( SQL_SUCCEEDED( ret )) |
533 | { |
534 | char *ts1, *ts2; |
535 | |
536 | sprintf( connection -> msg, |
537 | "\n\t\tExit:[%s]\ |
538 | \n\t\t\tSQLState = %s\ |
539 | \n\t\t\tNative = %s\ |
540 | \n\t\t\tMessage Text = %s" , |
541 | __get_return_status( ret, s2 ), |
542 | __sdata_as_string( s3, SQL_CHAR, |
543 | NULL, ts1 = unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL )), |
544 | __iptr_as_string( s0, native ), |
545 | __sdata_as_string( s1, SQL_CHAR, |
546 | text_length_ptr, ts2 = unicode_to_ansi_alloc( message_text, SQL_NTS, connection, NULL ))); |
547 | |
548 | if ( ts1 ) { |
549 | free( ts1 ); |
550 | } |
551 | if ( ts2 ) { |
552 | free( ts2 ); |
553 | } |
554 | } |
555 | else |
556 | { |
557 | sprintf( connection -> msg, |
558 | "\n\t\tExit:[%s]" , |
559 | __get_return_status( ret, s2 )); |
560 | } |
561 | |
562 | dm_log_write( __FILE__, |
563 | __LINE__, |
564 | LOG_INFO, |
565 | LOG_INFO, |
566 | connection -> msg ); |
567 | } |
568 | |
569 | thread_release( SQL_HANDLE_DBC, connection ); |
570 | |
571 | return ret; |
572 | } |
573 | else if ( handle_type == SQL_HANDLE_STMT ) |
574 | { |
575 | DMHSTMT statement = ( DMHSTMT ) handle; |
576 | |
577 | if ( !__validate_stmt( statement )) |
578 | { |
579 | dm_log_write( __FILE__, |
580 | __LINE__, |
581 | LOG_INFO, |
582 | LOG_INFO, |
583 | "Error: SQL_INVALID_HANDLE" ); |
584 | |
585 | #ifdef WITH_HANDLE_REDIRECT |
586 | { |
587 | DMHSTMT parent_statement; |
588 | |
589 | parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT ); |
590 | |
591 | if ( parent_statement ) { |
592 | dm_log_write( __FILE__, |
593 | __LINE__, |
594 | LOG_INFO, |
595 | LOG_INFO, |
596 | "Info: found parent handle" ); |
597 | |
598 | if ( CHECK_SQLGETDIAGRECW( parent_statement -> connection )) |
599 | { |
600 | dm_log_write( __FILE__, |
601 | __LINE__, |
602 | LOG_INFO, |
603 | LOG_INFO, |
604 | "Info: calling redirected driver function" ); |
605 | |
606 | return SQLGETDIAGRECW( parent_statement -> connection, |
607 | handle_type, |
608 | statement, |
609 | rec_number, |
610 | sqlstate, |
611 | native, |
612 | message_text, |
613 | buffer_length, |
614 | text_length_ptr ); |
615 | } |
616 | } |
617 | } |
618 | #endif |
619 | return SQL_INVALID_HANDLE; |
620 | } |
621 | |
622 | thread_protect( SQL_HANDLE_STMT, statement ); |
623 | |
624 | if ( log_info.log_flag ) |
625 | { |
626 | sprintf( statement -> msg, |
627 | "\n\t\tEntry:\ |
628 | \n\t\t\tStatement = %p\ |
629 | \n\t\t\tRec Number = %d\ |
630 | \n\t\t\tSQLState = %p\ |
631 | \n\t\t\tNative = %p\ |
632 | \n\t\t\tMessage Text = %p\ |
633 | \n\t\t\tBuffer Length = %d\ |
634 | \n\t\t\tText Len Ptr = %p" , |
635 | statement, |
636 | rec_number, |
637 | sqlstate, |
638 | native, |
639 | message_text, |
640 | buffer_length, |
641 | text_length_ptr ); |
642 | |
643 | dm_log_write( __FILE__, |
644 | __LINE__, |
645 | LOG_INFO, |
646 | LOG_INFO, |
647 | statement -> msg ); |
648 | } |
649 | |
650 | ret = extract_sql_error_rec_w( &statement -> error, |
651 | sqlstate, |
652 | rec_number, |
653 | native, |
654 | message_text, |
655 | buffer_length, |
656 | text_length_ptr ); |
657 | |
658 | if ( log_info.log_flag ) |
659 | { |
660 | if ( SQL_SUCCEEDED( ret )) |
661 | { |
662 | char *ts1, *ts2; |
663 | |
664 | sprintf( statement -> msg, |
665 | "\n\t\tExit:[%s]\ |
666 | \n\t\t\tSQLState = %s\ |
667 | \n\t\t\tNative = %s\ |
668 | \n\t\t\tMessage Text = %s" , |
669 | __get_return_status( ret, s2 ), |
670 | __sdata_as_string( s3, SQL_CHAR, |
671 | NULL, ts1 = unicode_to_ansi_alloc( sqlstate, SQL_NTS, statement -> connection, NULL )), |
672 | __iptr_as_string( s0, native ), |
673 | __sdata_as_string( s1, SQL_CHAR, |
674 | text_length_ptr, ts2 = unicode_to_ansi_alloc( message_text, SQL_NTS, statement -> connection, NULL ))); |
675 | |
676 | if ( ts1 ) { |
677 | free( ts1 ); |
678 | } |
679 | if ( ts2 ) { |
680 | free( ts2 ); |
681 | } |
682 | } |
683 | else |
684 | { |
685 | sprintf( statement -> msg, |
686 | "\n\t\tExit:[%s]" , |
687 | __get_return_status( ret, s2 )); |
688 | } |
689 | |
690 | dm_log_write( __FILE__, |
691 | __LINE__, |
692 | LOG_INFO, |
693 | LOG_INFO, |
694 | statement -> msg ); |
695 | } |
696 | |
697 | thread_release( SQL_HANDLE_STMT, statement ); |
698 | |
699 | return ret; |
700 | } |
701 | else if ( handle_type == SQL_HANDLE_DESC ) |
702 | { |
703 | DMHDESC descriptor = ( DMHDESC ) handle; |
704 | |
705 | if ( !__validate_desc( descriptor )) |
706 | { |
707 | dm_log_write( __FILE__, |
708 | __LINE__, |
709 | LOG_INFO, |
710 | LOG_INFO, |
711 | "Error: SQL_INVALID_HANDLE" ); |
712 | |
713 | #ifdef WITH_HANDLE_REDIRECT |
714 | { |
715 | DMHDESC parent_desc; |
716 | |
717 | parent_desc = find_parent_handle( descriptor, SQL_HANDLE_DESC ); |
718 | |
719 | if ( parent_desc ) { |
720 | dm_log_write( __FILE__, |
721 | __LINE__, |
722 | LOG_INFO, |
723 | LOG_INFO, |
724 | "Info: found parent handle" ); |
725 | |
726 | if ( CHECK_SQLGETDIAGRECW( parent_desc -> connection )) |
727 | { |
728 | dm_log_write( __FILE__, |
729 | __LINE__, |
730 | LOG_INFO, |
731 | LOG_INFO, |
732 | "Info: calling redirected driver function" ); |
733 | |
734 | return SQLGETDIAGRECW( parent_desc -> connection, |
735 | handle_type, |
736 | descriptor, |
737 | rec_number, |
738 | sqlstate, |
739 | native, |
740 | message_text, |
741 | buffer_length, |
742 | text_length_ptr ); |
743 | } |
744 | } |
745 | } |
746 | #endif |
747 | return SQL_INVALID_HANDLE; |
748 | } |
749 | |
750 | thread_protect( SQL_HANDLE_DESC, descriptor ); |
751 | |
752 | if ( log_info.log_flag ) |
753 | { |
754 | sprintf( descriptor -> msg, |
755 | "\n\t\tEntry:\ |
756 | \n\t\t\tDescriptor = %p\ |
757 | \n\t\t\tRec Number = %d\ |
758 | \n\t\t\tSQLState = %p\ |
759 | \n\t\t\tNative = %p\ |
760 | \n\t\t\tMessage Text = %p\ |
761 | \n\t\t\tBuffer Length = %d\ |
762 | \n\t\t\tText Len Ptr = %p" , |
763 | descriptor, |
764 | rec_number, |
765 | sqlstate, |
766 | native, |
767 | message_text, |
768 | buffer_length, |
769 | text_length_ptr ); |
770 | |
771 | dm_log_write( __FILE__, |
772 | __LINE__, |
773 | LOG_INFO, |
774 | LOG_INFO, |
775 | descriptor -> msg ); |
776 | } |
777 | |
778 | ret = extract_sql_error_rec_w( &descriptor -> error, |
779 | sqlstate, |
780 | rec_number, |
781 | native, |
782 | message_text, |
783 | buffer_length, |
784 | text_length_ptr ); |
785 | |
786 | if ( log_info.log_flag ) |
787 | { |
788 | if ( SQL_SUCCEEDED( ret )) |
789 | { |
790 | char *ts1, *ts2; |
791 | |
792 | sprintf( descriptor -> msg, |
793 | "\n\t\tExit:[%s]\ |
794 | \n\t\t\tSQLState = %s\ |
795 | \n\t\t\tNative = %s\ |
796 | \n\t\t\tMessage Text = %s" , |
797 | __get_return_status( ret, s2 ), |
798 | __sdata_as_string( s3, SQL_CHAR, |
799 | NULL, ts1 = unicode_to_ansi_alloc( sqlstate, SQL_NTS, descriptor -> connection, NULL )), |
800 | __iptr_as_string( s0, native ), |
801 | __sdata_as_string( s1, SQL_CHAR, |
802 | text_length_ptr, ts2 = unicode_to_ansi_alloc( message_text, SQL_NTS, descriptor -> connection, NULL ))); |
803 | |
804 | if ( ts1 ) { |
805 | free( ts1 ); |
806 | } |
807 | if ( ts2 ) { |
808 | free( ts2 ); |
809 | } |
810 | } |
811 | else |
812 | { |
813 | sprintf( descriptor -> msg, |
814 | "\n\t\tExit:[%s]" , |
815 | __get_return_status( ret, s2 )); |
816 | } |
817 | |
818 | dm_log_write( __FILE__, |
819 | __LINE__, |
820 | LOG_INFO, |
821 | LOG_INFO, |
822 | descriptor -> msg ); |
823 | } |
824 | |
825 | thread_release( SQL_HANDLE_DESC, descriptor ); |
826 | |
827 | return ret; |
828 | } |
829 | return SQL_NO_DATA; |
830 | } |
831 | |
832 | |