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