36 #define DLSYM_DECLARE(symbol) \
37 typeof(symbol)* symbol
38 #define DLSYM_SET_VALUE(symbol) \
39 .symbol = (typeof(symbol)(*))internal_error
42 static LONG internal_error(
void)
47 #pragma GCC diagnostic push
48 #pragma GCC diagnostic ignored "-Wcast-function-type"
52 DLSYM_DECLARE(SCardEstablishContext);
53 DLSYM_DECLARE(SCardReleaseContext);
54 DLSYM_DECLARE(SCardIsValidContext);
55 DLSYM_DECLARE(SCardConnect);
56 DLSYM_DECLARE(SCardReconnect);
57 DLSYM_DECLARE(SCardDisconnect);
58 DLSYM_DECLARE(SCardBeginTransaction);
59 DLSYM_DECLARE(SCardEndTransaction);
60 DLSYM_DECLARE(SCardStatus);
61 DLSYM_DECLARE(SCardGetStatusChange);
62 DLSYM_DECLARE(SCardControl);
63 DLSYM_DECLARE(SCardTransmit);
64 DLSYM_DECLARE(SCardListReaderGroups);
65 DLSYM_DECLARE(SCardListReaders);
66 DLSYM_DECLARE(SCardFreeMemory);
67 DLSYM_DECLARE(SCardCancel);
68 DLSYM_DECLARE(SCardGetAttrib);
69 DLSYM_DECLARE(SCardSetAttrib);
72 DLSYM_SET_VALUE(SCardEstablishContext),
73 DLSYM_SET_VALUE(SCardReleaseContext),
74 DLSYM_SET_VALUE(SCardIsValidContext),
75 DLSYM_SET_VALUE(SCardConnect),
76 DLSYM_SET_VALUE(SCardReconnect),
77 DLSYM_SET_VALUE(SCardDisconnect),
78 DLSYM_SET_VALUE(SCardBeginTransaction),
79 DLSYM_SET_VALUE(SCardEndTransaction),
80 DLSYM_SET_VALUE(SCardStatus),
81 DLSYM_SET_VALUE(SCardGetStatusChange),
82 DLSYM_SET_VALUE(SCardControl),
83 DLSYM_SET_VALUE(SCardTransmit),
84 DLSYM_SET_VALUE(SCardListReaderGroups),
85 DLSYM_SET_VALUE(SCardListReaders),
86 DLSYM_SET_VALUE(SCardFreeMemory),
87 DLSYM_SET_VALUE(SCardCancel),
88 DLSYM_SET_VALUE(SCardGetAttrib),
89 DLSYM_SET_VALUE(SCardSetAttrib)
91 #pragma GCC diagnostic pop
93 #define LOG log_line("%s:%d", __FILE__, __LINE__)
95 static int Log_fd = -1;
96 static void *Lib_handle = NULL;
97 static pthread_mutex_t Log_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
100 static void log_line(
const char *fmt, ...)
110 static void log_line(
const char *fmt, ...)
115 static void spy_line_direct(
char *line)
124 snprintf(threadid,
sizeof threadid,
"%lX@", pthread_self());
125 pthread_mutex_lock(&Log_fd_mutex);
126 r = write(Log_fd, threadid, strlen(threadid));
127 r = write(Log_fd, line, strlen(line));
128 r = write(Log_fd,
"\n", 1);
130 pthread_mutex_unlock(&Log_fd_mutex);
133 static void spy_line(
const char *fmt, ...)
146 size = vsnprintf(line,
sizeof line, fmt, args);
148 if ((
size_t)size >=
sizeof line)
150 printf(
"libpcsc-spy: Buffer is too small!\n");
153 snprintf(threadid,
sizeof threadid,
"%lX@", pthread_self());
154 pthread_mutex_lock(&Log_fd_mutex);
155 r = write(Log_fd, threadid, strlen(threadid));
156 r = write(Log_fd, line, size);
157 r = write(Log_fd,
"\n", 1);
159 pthread_mutex_unlock(&Log_fd_mutex);
162 static void spy_enter(
const char *fname)
164 struct timeval profile_time;
166 gettimeofday(&profile_time, NULL);
167 spy_line(
">|%ld|%ld|%s", profile_time.tv_sec, profile_time.tv_usec, fname);
170 static void spy_quit(
const char *fname, LONG rv)
172 struct timeval profile_time;
174 gettimeofday(&profile_time, NULL);
175 spy_line(
"<|%ld|%ld|%s|0x%08lX", profile_time.tv_sec,
176 profile_time.tv_usec, fname, rv);
179 #define Enter() spy_enter(__FUNCTION__)
180 #define Quit() spy_quit(__FUNCTION__, rv)
182 static void spy_long(
long arg)
184 spy_line(
"0x%08lX", arg);
187 static void spy_ptr_long(LONG *arg)
190 spy_line(
"0x%08lX", *arg);
195 static void spy_ptr_ulong(ULONG *arg)
198 spy_line(
"0x%08lX", *arg);
203 static void spy_pvoid(
const void *ptr)
208 static void spy_buffer(
const unsigned char *buffer,
size_t length)
217 char log_buffer[length * 3 +1], *p;
221 log_buffer[0] =
'\0';
222 for (i=0; i<length; i++)
224 snprintf(p, 4,
"%02X ", buffer[i]);
229 spy_line_direct(log_buffer);
233 static void spy_str(
const char *str)
238 static void spy_n_str(
const char *str, ULONG *len,
int autoallocate)
254 unsigned int length = 0;
262 length += strlen(s)+1;
264 }
while(length < *len);
274 for (i=0; i<cReaders; i++)
276 spy_str(rgReaderStates[i].szReader);
277 spy_long(rgReaderStates[i].dwCurrentState);
278 spy_long(rgReaderStates[i].dwEventState);
280 spy_buffer(rgReaderStates[i].rgbAtr, rgReaderStates[i].cbAtr);
282 spy_buffer(NULL, rgReaderStates[i].cbAtr);
286 static LONG load_lib(
void)
289 #define LIBPCSC "libpcsclite_real.so.1"
298 Lib_handle = dlopen(lib, RTLD_LAZY);
299 if (NULL == Lib_handle)
301 log_line(
"loading \"%s\" failed: %s", lib, dlerror());
305 #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)
307 if (SCardEstablishContext == dlsym(Lib_handle,
"SCardEstablishContext"))
309 log_line(
"Symbols dlsym error");
313 get_symbol(SCardEstablishContext);
314 get_symbol(SCardReleaseContext);
315 get_symbol(SCardIsValidContext);
316 get_symbol(SCardConnect);
317 get_symbol(SCardReconnect);
318 get_symbol(SCardDisconnect);
319 get_symbol(SCardBeginTransaction);
320 get_symbol(SCardEndTransaction);
321 get_symbol(SCardStatus);
322 get_symbol(SCardGetStatusChange);
323 get_symbol(SCardControl);
324 get_symbol(SCardTransmit);
325 get_symbol(SCardListReaderGroups);
326 get_symbol(SCardListReaders);
328 if (dlsym(Lib_handle,
"SCardFreeMemory"))
329 get_symbol(SCardFreeMemory);
330 get_symbol(SCardCancel);
331 get_symbol(SCardGetAttrib);
332 get_symbol(SCardSetAttrib);
339 PCSC_API LONG SCardEstablishContext(DWORD dwScope,
342 LPSCARDCONTEXT phContext)
364 snprintf(log_pipe,
sizeof log_pipe,
"%s/pcsc-spy", home);
365 Log_fd = open(log_pipe, O_WRONLY);
368 log_line(
"open %s failed: %s", log_pipe, strerror(errno));
374 rv = spy.SCardEstablishContext(dwScope, pvReserved1, pvReserved2,
376 spy_ptr_long(phContext);
381 PCSC_API LONG SCardReleaseContext(
SCARDCONTEXT hContext)
387 rv = spy.SCardReleaseContext(hContext);
392 PCSC_API LONG SCardIsValidContext(
SCARDCONTEXT hContext)
398 rv = spy.SCardIsValidContext(hContext);
406 DWORD dwPreferredProtocols,
407 LPSCARDHANDLE phCard,
408 LPDWORD pdwActiveProtocol)
415 spy_long(dwShareMode);
416 spy_long(dwPreferredProtocols);
417 spy_ptr_long(phCard);
418 spy_ptr_ulong(pdwActiveProtocol);
419 rv = spy.SCardConnect(hContext, szReader, dwShareMode,
420 dwPreferredProtocols, phCard, pdwActiveProtocol);
421 spy_ptr_long(phCard);
422 spy_ptr_ulong(pdwActiveProtocol);
429 DWORD dwPreferredProtocols,
430 DWORD dwInitialization,
431 LPDWORD pdwActiveProtocol)
437 spy_long(dwShareMode);
438 spy_long(dwPreferredProtocols);
439 spy_long(dwInitialization);
440 rv = spy.SCardReconnect(hCard, dwShareMode, dwPreferredProtocols,
441 dwInitialization, pdwActiveProtocol);
442 spy_ptr_ulong(pdwActiveProtocol);
454 spy_long(dwDisposition);
455 rv = spy.SCardDisconnect(hCard, dwDisposition);
460 PCSC_API LONG SCardBeginTransaction(
SCARDHANDLE hCard)
466 rv = spy.SCardBeginTransaction(hCard);
471 PCSC_API LONG SCardEndTransaction(
SCARDHANDLE hCard,
478 spy_long(dwDisposition);
479 rv = spy.SCardEndTransaction(hCard, dwDisposition);
486 LPDWORD pcchReaderLen,
493 int autoallocate_ReaderName = 0, autoallocate_Atr = 0;
503 spy_ptr_ulong(pcchReaderLen);
504 spy_ptr_ulong(pcbAtrLen);
505 rv = spy.SCardStatus(hCard, mszReaderName, pcchReaderLen, pdwState,
506 pdwProtocol, pbAtr, pcbAtrLen);
507 spy_n_str(mszReaderName, pcchReaderLen, autoallocate_ReaderName);
508 spy_ptr_ulong(pdwState);
509 spy_ptr_ulong(pdwProtocol);
510 if (NULL == pcbAtrLen)
516 if (autoallocate_Atr)
517 buffer = *(LPBYTE *)pbAtr;
521 spy_buffer(buffer, *pcbAtrLen);
527 PCSC_API LONG SCardGetStatusChange(
SCARDCONTEXT hContext,
538 spy_readerstate(rgReaderStates, cReaders);
539 rv = spy.SCardGetStatusChange(hContext, dwTimeout, rgReaderStates,
541 spy_readerstate(rgReaderStates, cReaders);
548 LPCVOID pbSendBuffer,
552 LPDWORD lpBytesReturned)
558 spy_long(dwControlCode);
559 spy_buffer(pbSendBuffer, cbSendLength);
560 rv = spy.SCardControl(hCard, dwControlCode, pbSendBuffer, cbSendLength,
561 pbRecvBuffer, cbRecvLength, lpBytesReturned);
565 spy_buffer(pbRecvBuffer, *lpBytesReturned);
567 spy_buffer(NULL, *lpBytesReturned);
577 LPCBYTE pbSendBuffer,
581 LPDWORD pcbRecvLength)
597 spy_buffer(pbSendBuffer, cbSendLength);
598 rv = spy.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength,
599 pioRecvPci, pbRecvBuffer, pcbRecvLength);
613 spy_buffer(pbRecvBuffer, *pcbRecvLength);
615 spy_buffer(NULL, *pcbRecvLength);
623 PCSC_API LONG SCardListReaderGroups(
SCARDCONTEXT hContext,
628 int autoallocate = 0;
635 spy_ptr_ulong(pcchGroups);
636 rv = spy.SCardListReaderGroups(hContext, mszGroups, pcchGroups);
638 spy_n_str(mszGroups, pcchGroups, autoallocate);
640 spy_n_str(NULL, pcchGroups, 0);
651 int autoallocate = 0;
659 rv = spy.SCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
661 spy_n_str(mszReaders, pcchReaders, autoallocate);
663 spy_n_str(NULL, pcchReaders, 0);
676 rv = spy.SCardFreeMemory(hContext, pvMem);
687 rv = spy.SCardCancel(hContext);
698 int autoallocate = 0;
706 rv = spy.SCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen);
707 if (NULL == pcbAttrLen)
711 spy_buffer(NULL, *pcbAttrLen);
717 buffer = *(LPBYTE *)pbAttr;
721 spy_buffer(buffer, *pcbAttrLen);
737 spy_buffer(pbAttr, cbAttrLen);
738 rv = spy.SCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen);