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, ...)
105 vfprintf(stderr, fmt, args);
106 fprintf(stderr,
"\n");
110 static void log_line(
const char *fmt, ...)
115 static void spy_line_direct(
char *line)
124 snprintf(threadid,
sizeof threadid,
"%lX@", (
unsigned long)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@", (
unsigned long)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);
337 static void init(
void)
351 snprintf(log_pipe,
sizeof log_pipe,
"%s/pcsc-spy", home);
352 Log_fd = open(log_pipe, O_WRONLY);
355 log_line(
"open %s failed: %s", log_pipe, strerror(errno));
360 PCSC_API LONG SCardEstablishContext(DWORD dwScope,
363 LPSCARDCONTEXT phContext)
366 static pthread_once_t once_control = PTHREAD_ONCE_INIT;
368 pthread_once(&once_control, init);
372 rv = spy.SCardEstablishContext(dwScope, pvReserved1, pvReserved2,
374 spy_ptr_long(phContext);
379 PCSC_API LONG SCardReleaseContext(
SCARDCONTEXT hContext)
385 rv = spy.SCardReleaseContext(hContext);
390 PCSC_API LONG SCardIsValidContext(
SCARDCONTEXT hContext)
396 rv = spy.SCardIsValidContext(hContext);
404 DWORD dwPreferredProtocols,
405 LPSCARDHANDLE phCard,
406 LPDWORD pdwActiveProtocol)
413 spy_long(dwShareMode);
414 spy_long(dwPreferredProtocols);
415 spy_ptr_long(phCard);
416 spy_ptr_ulong(pdwActiveProtocol);
417 rv = spy.SCardConnect(hContext, szReader, dwShareMode,
418 dwPreferredProtocols, phCard, pdwActiveProtocol);
419 spy_ptr_long(phCard);
420 spy_ptr_ulong(pdwActiveProtocol);
427 DWORD dwPreferredProtocols,
428 DWORD dwInitialization,
429 LPDWORD pdwActiveProtocol)
435 spy_long(dwShareMode);
436 spy_long(dwPreferredProtocols);
437 spy_long(dwInitialization);
438 rv = spy.SCardReconnect(hCard, dwShareMode, dwPreferredProtocols,
439 dwInitialization, pdwActiveProtocol);
440 spy_ptr_ulong(pdwActiveProtocol);
452 spy_long(dwDisposition);
453 rv = spy.SCardDisconnect(hCard, dwDisposition);
458 PCSC_API LONG SCardBeginTransaction(
SCARDHANDLE hCard)
464 rv = spy.SCardBeginTransaction(hCard);
469 PCSC_API LONG SCardEndTransaction(
SCARDHANDLE hCard,
476 spy_long(dwDisposition);
477 rv = spy.SCardEndTransaction(hCard, dwDisposition);
484 LPDWORD pcchReaderLen,
491 int autoallocate_ReaderName = 0, autoallocate_Atr = 0;
501 spy_ptr_ulong(pcchReaderLen);
502 spy_ptr_ulong(pcbAtrLen);
503 rv = spy.SCardStatus(hCard, mszReaderName, pcchReaderLen, pdwState,
504 pdwProtocol, pbAtr, pcbAtrLen);
505 spy_n_str(mszReaderName, pcchReaderLen, autoallocate_ReaderName);
506 spy_ptr_ulong(pdwState);
507 spy_ptr_ulong(pdwProtocol);
508 if (NULL == pcbAtrLen)
514 if (autoallocate_Atr)
515 buffer = *(LPBYTE *)pbAtr;
519 spy_buffer(buffer, *pcbAtrLen);
525 PCSC_API LONG SCardGetStatusChange(
SCARDCONTEXT hContext,
536 spy_readerstate(rgReaderStates, cReaders);
537 rv = spy.SCardGetStatusChange(hContext, dwTimeout, rgReaderStates,
539 spy_readerstate(rgReaderStates, cReaders);
546 LPCVOID pbSendBuffer,
550 LPDWORD lpBytesReturned)
556 spy_long(dwControlCode);
557 spy_buffer(pbSendBuffer, cbSendLength);
558 rv = spy.SCardControl(hCard, dwControlCode, pbSendBuffer, cbSendLength,
559 pbRecvBuffer, cbRecvLength, lpBytesReturned);
563 spy_buffer(pbRecvBuffer, *lpBytesReturned);
565 spy_buffer(NULL, *lpBytesReturned);
575 LPCBYTE pbSendBuffer,
579 LPDWORD pcbRecvLength)
595 spy_buffer(pbSendBuffer, cbSendLength);
596 rv = spy.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength,
597 pioRecvPci, pbRecvBuffer, pcbRecvLength);
611 spy_buffer(pbRecvBuffer, *pcbRecvLength);
613 spy_buffer(NULL, *pcbRecvLength);
621 PCSC_API LONG SCardListReaderGroups(
SCARDCONTEXT hContext,
626 int autoallocate = 0;
633 spy_ptr_ulong(pcchGroups);
634 rv = spy.SCardListReaderGroups(hContext, mszGroups, pcchGroups);
636 spy_n_str(mszGroups, pcchGroups, autoallocate);
638 spy_n_str(NULL, pcchGroups, 0);
649 int autoallocate = 0;
657 rv = spy.SCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
659 spy_n_str(mszReaders, pcchReaders, autoallocate);
661 spy_n_str(NULL, pcchReaders, 0);
674 rv = spy.SCardFreeMemory(hContext, pvMem);
685 rv = spy.SCardCancel(hContext);
696 int autoallocate = 0;
704 rv = spy.SCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen);
705 if (NULL == pcbAttrLen)
709 spy_buffer(NULL, *pcbAttrLen);
715 buffer = *(LPBYTE *)pbAttr;
719 spy_buffer(buffer, *pcbAttrLen);
735 spy_buffer(pbAttr, cbAttrLen);
736 rv = spy.SCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen);
#define SCARD_S_SUCCESS
No error was encountered.
unsigned long cbPciLength
Protocol Control Inf Length.
This handles abstract system level calls.
const char * SYS_GetEnv(const char *name)
(More) secure version of getenv(3)
#define SCARD_AUTOALLOCATE
see SCardFreeMemory()
LONG SCARDCONTEXT
hContext returned by SCardEstablishContext()
unsigned long dwProtocol
Protocol identifier.
LONG SCARDHANDLE
hCard returned by SCardConnect()
Protocol Control Information (PCI)
#define MAX_ATR_SIZE
Maximum ATR size.
#define SCARD_F_INTERNAL_ERROR
An internal consistency check failed.
This handles smart card reader communications.