pcsc-lite
1.8.2
|
00001 /* 00002 Log PC/SC arguments 00003 Copyright (C) 2001 Ludovic Rousseau 00004 00005 This program is free software: you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation, either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 /* $Id: libpcscspy.c 6177 2012-01-15 17:20:00Z rousseau $ */ 00020 00021 #include <dlfcn.h> 00022 #include <stdio.h> 00023 #include <stdarg.h> 00024 #include <fcntl.h> 00025 #include <stdlib.h> 00026 #include <errno.h> 00027 #include <string.h> 00028 #include <unistd.h> 00029 #include <sys/time.h> 00030 #include <pthread.h> 00031 00032 #include "misc.h" 00033 #include <winscard.h> 00034 00035 #define DEBUG 00036 00037 /* function prototypes */ 00038 00039 #define p_SCardEstablishContext(fct) LONG(fct)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) 00040 00041 #define p_SCardReleaseContext(fct) LONG(fct)(SCARDCONTEXT hContext) 00042 00043 #define p_SCardIsValidContext(fct) LONG(fct) (SCARDCONTEXT hContext) 00044 00045 #define p_SCardConnect(fct) LONG(fct) (SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) 00046 00047 #define p_SCardReconnect(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol) 00048 00049 #define p_SCardDisconnect(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwDisposition) 00050 00051 #define p_SCardBeginTransaction(fct) LONG(fct) (SCARDHANDLE hCard) 00052 00053 #define p_SCardEndTransaction(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwDisposition) 00054 00055 #define p_SCardStatus(fct) LONG(fct) (SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) 00056 00057 #define p_SCardGetStatusChange(fct) LONG(fct) (SCARDCONTEXT hContext, DWORD dwTimeout, LPSCARD_READERSTATE rgReaderStates, DWORD cReaders) 00058 00059 #define p_SCardControl(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned) 00060 00061 #define p_SCardTransmit(fct) LONG(fct) (SCARDHANDLE hCard, const SCARD_IO_REQUEST * pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST * pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) 00062 00063 #define p_SCardListReaderGroups(fct) LONG(fct) (SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups) 00064 00065 #define p_SCardListReaders(fct) LONG(fct) (SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) 00066 00067 #define p_SCardFreeMemory(fct) LONG(fct) (SCARDCONTEXT hContext, LPCVOID pvMem) 00068 00069 #define p_SCardCancel(fct) LONG(fct) (SCARDCONTEXT hContext) 00070 00071 #define p_SCardGetAttrib(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen) 00072 00073 #define p_SCardSetAttrib(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen) 00074 00075 #define p_pcsc_stringify_error(fct) char *(fct)(const LONG pcscError) 00076 00077 /* fake function to just return en error code */ 00078 static LONG internal_error(void) 00079 { 00080 return SCARD_F_INTERNAL_ERROR; 00081 } 00082 00083 /* contains pointers to real functions */ 00084 static struct 00085 { 00086 p_SCardEstablishContext(*SCardEstablishContext); 00087 p_SCardReleaseContext(*SCardReleaseContext); 00088 p_SCardIsValidContext(*SCardIsValidContext); 00089 p_SCardConnect(*SCardConnect); 00090 p_SCardReconnect(*SCardReconnect); 00091 p_SCardDisconnect(*SCardDisconnect); 00092 p_SCardBeginTransaction(*SCardBeginTransaction); 00093 p_SCardEndTransaction(*SCardEndTransaction); 00094 p_SCardStatus(*SCardStatus); 00095 p_SCardGetStatusChange(*SCardGetStatusChange); 00096 p_SCardControl(*SCardControl); 00097 p_SCardTransmit(*SCardTransmit); 00098 p_SCardListReaderGroups(*SCardListReaderGroups); 00099 p_SCardListReaders(*SCardListReaders); 00100 p_SCardFreeMemory(*SCardFreeMemory); 00101 p_SCardCancel(*SCardCancel); 00102 p_SCardGetAttrib(*SCardGetAttrib); 00103 p_SCardSetAttrib(*SCardSetAttrib); 00104 p_pcsc_stringify_error(*pcsc_stringify_error); 00105 } spy = { 00106 /* initialized with the fake internal_error() function */ 00107 .SCardEstablishContext = (p_SCardEstablishContext(*))internal_error, 00108 .SCardReleaseContext = (p_SCardReleaseContext(*))internal_error, 00109 .SCardIsValidContext = (p_SCardIsValidContext(*))internal_error, 00110 .SCardConnect = (p_SCardConnect(*))internal_error, 00111 .SCardReconnect = (p_SCardReconnect(*))internal_error, 00112 .SCardDisconnect = (p_SCardDisconnect(*))internal_error, 00113 .SCardBeginTransaction = (p_SCardBeginTransaction(*))internal_error, 00114 .SCardEndTransaction = (p_SCardEndTransaction(*))internal_error, 00115 .SCardStatus = (p_SCardStatus(*))internal_error, 00116 .SCardGetStatusChange = (p_SCardGetStatusChange(*))internal_error, 00117 .SCardControl = (p_SCardControl(*))internal_error, 00118 .SCardTransmit = (p_SCardTransmit(*))internal_error, 00119 .SCardListReaderGroups = (p_SCardListReaderGroups(*))internal_error, 00120 .SCardListReaders = (p_SCardListReaders(*))internal_error, 00121 .SCardFreeMemory = (p_SCardFreeMemory(*))internal_error, 00122 .SCardCancel = (p_SCardCancel(*))internal_error, 00123 .SCardGetAttrib = (p_SCardGetAttrib(*))internal_error, 00124 .SCardSetAttrib = (p_SCardSetAttrib(*))internal_error, 00125 .pcsc_stringify_error = (p_pcsc_stringify_error(*))internal_error 00126 }; 00127 00128 #define LOG log_line("%s:%d", __FILE__, __LINE__) 00129 00130 static int Log_fd = -1; 00131 static void *Lib_handle = NULL; 00132 static pthread_mutex_t Log_fd_mutex = PTHREAD_MUTEX_INITIALIZER; 00133 00134 #ifdef DEBUG 00135 static void log_line(const char *fmt, ...) 00136 { 00137 va_list args; 00138 00139 va_start(args, fmt); 00140 vprintf(fmt, args); 00141 printf("\n"); 00142 va_end(args); 00143 } 00144 #else 00145 static void log_line(const char *fmt, ...) 00146 { 00147 } 00148 #endif 00149 00150 static void spy_line_direct(char *line) 00151 { 00152 char threadid[30]; 00153 00154 /* spying disabled */ 00155 if (Log_fd < 0) 00156 return; 00157 00158 snprintf(threadid, sizeof threadid, "%lX@", pthread_self()); 00159 pthread_mutex_lock(&Log_fd_mutex); 00160 write(Log_fd, threadid, strlen(threadid)); 00161 write(Log_fd, line, strlen(line)); 00162 write(Log_fd, "\n", 1); 00163 pthread_mutex_unlock(&Log_fd_mutex); 00164 } 00165 00166 static void spy_line(const char *fmt, ...) 00167 { 00168 va_list args; 00169 char line[256]; 00170 int size; 00171 char threadid[30]; 00172 00173 /* spying disabled */ 00174 if (Log_fd < 0) 00175 return; 00176 00177 va_start(args, fmt); 00178 size = vsnprintf(line, sizeof line, fmt, args); 00179 if ((size_t)size >= sizeof line) 00180 { 00181 printf("libpcsc-spy: Buffer is too small!\n"); 00182 return; 00183 } 00184 snprintf(threadid, sizeof threadid, "%lX@", pthread_self()); 00185 pthread_mutex_lock(&Log_fd_mutex); 00186 write(Log_fd, threadid, strlen(threadid)); 00187 write(Log_fd, line, size); 00188 write(Log_fd, "\n", 1); 00189 pthread_mutex_unlock(&Log_fd_mutex); 00190 va_end(args); 00191 } 00192 00193 static void spy_enter(const char *fname) 00194 { 00195 struct timeval profile_time; 00196 00197 gettimeofday(&profile_time, NULL); 00198 spy_line(">|%d|%d|%s", profile_time.tv_sec, profile_time.tv_usec, fname); 00199 } 00200 00201 static void spy_quit(const char *fname, LONG rv) 00202 { 00203 struct timeval profile_time; 00204 00205 gettimeofday(&profile_time, NULL); 00206 spy_line("<|%d|%d|%s|%s|0x%08X", profile_time.tv_sec, 00207 profile_time.tv_usec, fname, spy.pcsc_stringify_error(rv), rv); 00208 } 00209 00210 #define Enter() spy_enter(__FUNCTION__) 00211 #define Quit() spy_quit(__FUNCTION__, rv) 00212 00213 static void spy_long(long arg) 00214 { 00215 spy_line("0x%08lX", arg); 00216 } 00217 00218 static void spy_ptr_long(long *arg) 00219 { 00220 if (arg) 00221 spy_line("0x%08lX", *arg); 00222 else 00223 spy_line("NULL"); 00224 } 00225 00226 static void spy_ptr_ulong(unsigned long *arg) 00227 { 00228 if (arg) 00229 spy_line("0x%08lX", *arg); 00230 else 00231 spy_line("NULL"); 00232 } 00233 00234 static void spy_pvoid(const void *ptr) 00235 { 00236 spy_line("%p", ptr); 00237 } 00238 00239 static void spy_buffer(const unsigned char *buffer, size_t length) 00240 { 00241 spy_long(length); 00242 00243 if (NULL == buffer) 00244 spy_line("NULL"); 00245 else 00246 { 00247 /* "78 79 7A" */ 00248 char log_buffer[length * 3 +1], *p; 00249 size_t i; 00250 00251 p = log_buffer; 00252 log_buffer[0] = '\0'; 00253 for (i=0; i<length; i++) 00254 { 00255 snprintf(p, 4, "%02X ", buffer[i]); 00256 p += 3; 00257 } 00258 *p = '\0'; 00259 00260 spy_line_direct(log_buffer); 00261 } 00262 } 00263 00264 static void spy_str(const char *str) 00265 { 00266 spy_line("%s", str); 00267 } 00268 00269 static void spy_n_str(const char *str, unsigned long *len, int autoallocate) 00270 { 00271 spy_ptr_ulong(len); 00272 if (NULL == len) 00273 { 00274 spy_line("\"\""); 00275 } 00276 else 00277 { 00278 if (NULL == str) 00279 { 00280 spy_line("NULL"); 00281 } 00282 else 00283 { 00284 const char *s = str; 00285 unsigned int length = 0; 00286 00287 if (autoallocate) 00288 s = *(char **)str; 00289 00290 do 00291 { 00292 spy_line("%s", s); 00293 length += strlen(s)+1; 00294 s += strlen(s)+1; 00295 } while(length < *len); 00296 } 00297 } 00298 } 00299 00300 00301 static void spy_readerstate(SCARD_READERSTATE * rgReaderStates, int cReaders) 00302 { 00303 int i; 00304 00305 for (i=0; i<cReaders; i++) 00306 { 00307 spy_str(rgReaderStates[i].szReader); 00308 spy_long(rgReaderStates[i].dwCurrentState); 00309 spy_long(rgReaderStates[i].dwEventState); 00310 if (rgReaderStates[i].cbAtr <= MAX_ATR_SIZE) 00311 spy_buffer(rgReaderStates[i].rgbAtr, rgReaderStates[i].cbAtr); 00312 else 00313 spy_buffer(NULL, rgReaderStates[i].cbAtr); 00314 } 00315 } 00316 00317 static LONG load_lib(void) 00318 { 00319 00320 #define LIBPCSC_NOSPY "libpcsclite_nospy.so.1" 00321 #define LIBPCSC "libpcsclite.so.1" 00322 00323 /* first try to load the NOSPY library 00324 * this is used for programs doing an explicit dlopen like 00325 * Perl and Python wrappers */ 00326 Lib_handle = dlopen(LIBPCSC_NOSPY, RTLD_LAZY); 00327 if (NULL == Lib_handle) 00328 { 00329 log_line("%s", dlerror()); 00330 00331 /* load the normal library */ 00332 Lib_handle = dlopen(LIBPCSC, RTLD_LAZY); 00333 if (NULL == Lib_handle) 00334 { 00335 log_line("%s", dlerror()); 00336 return SCARD_F_INTERNAL_ERROR; 00337 } 00338 } 00339 00340 #define get_symbol(s) do { spy.s = dlsym(Lib_handle, #s); if (NULL == spy.s) { log_line("%s", dlerror()); return SCARD_F_INTERNAL_ERROR; } } while (0) 00341 00342 get_symbol(SCardEstablishContext); 00343 get_symbol(SCardReleaseContext); 00344 get_symbol(SCardIsValidContext); 00345 get_symbol(SCardConnect); 00346 get_symbol(SCardReconnect); 00347 get_symbol(SCardDisconnect); 00348 get_symbol(SCardBeginTransaction); 00349 get_symbol(SCardEndTransaction); 00350 get_symbol(SCardStatus); 00351 get_symbol(SCardGetStatusChange); 00352 get_symbol(SCardControl); 00353 get_symbol(SCardTransmit); 00354 get_symbol(SCardListReaderGroups); 00355 get_symbol(SCardListReaders); 00356 get_symbol(SCardFreeMemory); 00357 get_symbol(SCardCancel); 00358 get_symbol(SCardGetAttrib); 00359 get_symbol(SCardSetAttrib); 00360 get_symbol(pcsc_stringify_error); 00361 00362 return SCARD_S_SUCCESS; 00363 } 00364 00365 00366 /* exported functions */ 00367 PCSC_API p_SCardEstablishContext(SCardEstablishContext) 00368 { 00369 LONG rv; 00370 static int init = 0; 00371 00372 if (!init) 00373 { 00374 const char *home; 00375 char log_pipe[128]; 00376 00377 init = 1; 00378 00379 /* load the real library */ 00380 rv = load_lib(); 00381 if (rv != SCARD_S_SUCCESS) 00382 return rv; 00383 00384 /* check if we can log */ 00385 home = getenv("HOME"); 00386 if (NULL == home) 00387 home = "/tmp"; 00388 00389 snprintf(log_pipe, sizeof log_pipe, "%s/pcsc-spy", home); 00390 Log_fd = open(log_pipe, O_WRONLY); 00391 if (Log_fd < 0) 00392 { 00393 log_line("open %s failed: %s", log_pipe, strerror(errno)); 00394 } 00395 } 00396 00397 Enter(); 00398 spy_long(dwScope); 00399 rv = spy.SCardEstablishContext(dwScope, pvReserved1, pvReserved2, 00400 phContext); 00401 spy_ptr_long(phContext); 00402 Quit(); 00403 return rv; 00404 } 00405 00406 PCSC_API p_SCardReleaseContext(SCardReleaseContext) 00407 { 00408 LONG rv; 00409 00410 Enter(); 00411 spy_long(hContext); 00412 rv = spy.SCardReleaseContext(hContext); 00413 Quit(); 00414 return rv; 00415 } 00416 00417 PCSC_API p_SCardIsValidContext(SCardIsValidContext) 00418 { 00419 LONG rv; 00420 00421 Enter(); 00422 spy_long(hContext); 00423 rv = spy.SCardIsValidContext(hContext); 00424 Quit(); 00425 return rv; 00426 } 00427 00428 PCSC_API p_SCardConnect(SCardConnect) 00429 { 00430 LONG rv; 00431 00432 Enter(); 00433 spy_long(hContext); 00434 spy_str(szReader); 00435 spy_long(dwShareMode); 00436 spy_long(dwPreferredProtocols); 00437 spy_ptr_long(phCard); 00438 spy_ptr_ulong(pdwActiveProtocol); 00439 rv = spy.SCardConnect(hContext, szReader, dwShareMode, 00440 dwPreferredProtocols, phCard, pdwActiveProtocol); 00441 spy_ptr_long(phCard); 00442 spy_ptr_ulong(pdwActiveProtocol); 00443 Quit(); 00444 return rv; 00445 } 00446 00447 PCSC_API p_SCardReconnect(SCardReconnect) 00448 { 00449 LONG rv; 00450 00451 Enter(); 00452 spy_long(hCard); 00453 spy_long(dwShareMode); 00454 spy_long(dwPreferredProtocols); 00455 spy_long(dwInitialization); 00456 rv = spy.SCardReconnect(hCard, dwShareMode, dwPreferredProtocols, 00457 dwInitialization, pdwActiveProtocol); 00458 spy_ptr_ulong(pdwActiveProtocol); 00459 Quit(); 00460 return rv; 00461 } 00462 00463 PCSC_API p_SCardDisconnect(SCardDisconnect) 00464 { 00465 LONG rv; 00466 00467 Enter(); 00468 spy_long(hCard); 00469 spy_long(dwDisposition); 00470 rv = spy.SCardDisconnect(hCard, dwDisposition); 00471 Quit(); 00472 return rv; 00473 } 00474 00475 PCSC_API p_SCardBeginTransaction(SCardBeginTransaction) 00476 { 00477 LONG rv; 00478 00479 Enter(); 00480 spy_long(hCard); 00481 rv = spy.SCardBeginTransaction(hCard); 00482 Quit(); 00483 return rv; 00484 } 00485 00486 PCSC_API p_SCardEndTransaction(SCardEndTransaction) 00487 { 00488 LONG rv; 00489 00490 Enter(); 00491 spy_long(hCard); 00492 spy_long(dwDisposition); 00493 rv = spy.SCardEndTransaction(hCard, dwDisposition); 00494 Quit(); 00495 return rv; 00496 } 00497 00498 PCSC_API p_SCardStatus(SCardStatus) 00499 { 00500 LONG rv; 00501 int autoallocate_ReaderName = 0, autoallocate_Atr = 0; 00502 00503 if (pcchReaderLen) 00504 autoallocate_ReaderName = *pcchReaderLen == SCARD_AUTOALLOCATE; 00505 00506 if (pcbAtrLen) 00507 autoallocate_Atr = *pcbAtrLen == SCARD_AUTOALLOCATE; 00508 00509 Enter(); 00510 spy_long(hCard); 00511 spy_ptr_ulong(pcchReaderLen); 00512 spy_ptr_ulong(pcbAtrLen); 00513 rv = spy.SCardStatus(hCard, mszReaderName, pcchReaderLen, pdwState, 00514 pdwProtocol, pbAtr, pcbAtrLen); 00515 spy_n_str(mszReaderName, pcchReaderLen, autoallocate_ReaderName); 00516 spy_ptr_ulong(pdwState); 00517 spy_ptr_ulong(pdwProtocol); 00518 if (NULL == pcbAtrLen) 00519 spy_line("NULL"); 00520 else 00521 { 00522 if (autoallocate_Atr) 00523 { 00524 const unsigned char *b = *(unsigned char **)pbAtr; 00525 00526 spy_buffer(b, *pcbAtrLen); 00527 } 00528 else 00529 spy_buffer(pbAtr, *pcbAtrLen); 00530 } 00531 Quit(); 00532 return rv; 00533 } 00534 00535 PCSC_API p_SCardGetStatusChange(SCardGetStatusChange) 00536 { 00537 LONG rv; 00538 00539 Enter(); 00540 spy_long(hContext); 00541 spy_long(dwTimeout); 00542 spy_long(cReaders); 00543 spy_readerstate(rgReaderStates, cReaders); 00544 rv = spy.SCardGetStatusChange(hContext, dwTimeout, rgReaderStates, 00545 cReaders); 00546 spy_readerstate(rgReaderStates, cReaders); 00547 Quit(); 00548 return rv; 00549 } 00550 00551 PCSC_API p_SCardControl(SCardControl) 00552 { 00553 LONG rv; 00554 00555 Enter(); 00556 spy_long(hCard); 00557 spy_long(dwControlCode); 00558 spy_buffer(pbSendBuffer, cbSendLength); 00559 rv = spy.SCardControl(hCard, dwControlCode, pbSendBuffer, cbSendLength, 00560 pbRecvBuffer, cbRecvLength, lpBytesReturned); 00561 if (lpBytesReturned) 00562 spy_buffer(pbRecvBuffer, *lpBytesReturned); 00563 else 00564 spy_buffer(NULL, 0); 00565 Quit(); 00566 return rv; 00567 } 00568 00569 PCSC_API p_SCardTransmit(SCardTransmit) 00570 { 00571 LONG rv; 00572 00573 Enter(); 00574 spy_long(hCard); 00575 spy_buffer(pbSendBuffer, cbSendLength); 00576 rv = spy.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength, 00577 pioRecvPci, pbRecvBuffer, pcbRecvLength); 00578 if (pcbRecvLength) 00579 spy_buffer(pbRecvBuffer, *pcbRecvLength); 00580 else 00581 spy_buffer(NULL, 0); 00582 Quit(); 00583 return rv; 00584 } 00585 00586 PCSC_API p_SCardListReaderGroups(SCardListReaderGroups) 00587 { 00588 LONG rv; 00589 int autoallocate = 0; 00590 00591 if (pcchGroups) 00592 autoallocate = *pcchGroups == SCARD_AUTOALLOCATE; 00593 00594 Enter(); 00595 spy_long(hContext); 00596 spy_ptr_ulong(pcchGroups); 00597 rv = spy.SCardListReaderGroups(hContext, mszGroups, pcchGroups); 00598 spy_n_str(mszGroups, pcchGroups, autoallocate); 00599 Quit(); 00600 return rv; 00601 } 00602 00603 PCSC_API p_SCardListReaders(SCardListReaders) 00604 { 00605 LONG rv; 00606 int autoallocate = 0; 00607 00608 if (pcchReaders) 00609 autoallocate = *pcchReaders == SCARD_AUTOALLOCATE; 00610 00611 Enter(); 00612 spy_long(hContext); 00613 spy_str(mszGroups); 00614 rv = spy.SCardListReaders(hContext, mszGroups, mszReaders, pcchReaders); 00615 spy_n_str(mszReaders, pcchReaders, autoallocate); 00616 Quit(); 00617 return rv; 00618 } 00619 00620 PCSC_API p_SCardFreeMemory(SCardFreeMemory) 00621 { 00622 LONG rv; 00623 00624 Enter(); 00625 spy_long(hContext); 00626 spy_pvoid(pvMem); 00627 rv = spy.SCardFreeMemory(hContext, pvMem); 00628 Quit(); 00629 return rv; 00630 } 00631 00632 PCSC_API p_SCardCancel(SCardCancel) 00633 { 00634 LONG rv; 00635 00636 Enter(); 00637 spy_long(hContext); 00638 rv = spy.SCardCancel(hContext); 00639 Quit(); 00640 return rv; 00641 } 00642 00643 PCSC_API p_SCardGetAttrib(SCardGetAttrib) 00644 { 00645 LONG rv; 00646 int autoallocate = 0; 00647 00648 if (pcbAttrLen) 00649 autoallocate = *pcbAttrLen == SCARD_AUTOALLOCATE; 00650 00651 Enter(); 00652 spy_long(hCard); 00653 spy_long(dwAttrId); 00654 rv = spy.SCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen); 00655 if (NULL == pcbAttrLen) 00656 spy_buffer(NULL, 0); 00657 else 00658 { 00659 const unsigned char *s = pbAttr; 00660 00661 if (autoallocate) 00662 s = *(unsigned char **)pbAttr; 00663 00664 spy_buffer(s, *pcbAttrLen); 00665 } 00666 Quit(); 00667 return rv; 00668 } 00669 00670 PCSC_API p_SCardSetAttrib(SCardSetAttrib) 00671 { 00672 LONG rv; 00673 00674 Enter(); 00675 spy_long(hCard); 00676 spy_long(dwAttrId); 00677 spy_buffer(pbAttr, cbAttrLen); 00678 rv = spy.SCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen); 00679 Quit(); 00680 return rv; 00681 } 00682 00683 PCSC_API p_pcsc_stringify_error(pcsc_stringify_error) 00684 { 00685 return spy.pcsc_stringify_error(pcscError); 00686 } 00687 00688 PCSC_API const SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, sizeof(SCARD_IO_REQUEST) }; 00689 PCSC_API const SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(SCARD_IO_REQUEST) }; 00690 PCSC_API const SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, sizeof(SCARD_IO_REQUEST) };