36 #define SCardControl SCardControl132
38 PCSC_API int32_t SCardControl132(
SCARDHANDLE hCard, uint32_t dwControlCode,
39 const void *pbSendBuffer, uint32_t cbSendLength,
40 void *pbRecvBuffer, uint32_t cbRecvLength, uint32_t *lpBytesReturned);
45 #define p_SCardEstablishContext(fct) LONG(fct)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
47 #define p_SCardReleaseContext(fct) LONG(fct)(SCARDCONTEXT hContext)
49 #define p_SCardIsValidContext(fct) LONG(fct) (SCARDCONTEXT hContext)
51 #define p_SCardConnect(fct) LONG(fct) (SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
53 #define p_SCardReconnect(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol)
55 #define p_SCardDisconnect(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwDisposition)
57 #define p_SCardBeginTransaction(fct) LONG(fct) (SCARDHANDLE hCard)
59 #define p_SCardEndTransaction(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwDisposition)
61 #define p_SCardStatus(fct) LONG(fct) (SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
63 #define p_SCardGetStatusChange(fct) LONG(fct) (SCARDCONTEXT hContext, DWORD dwTimeout, LPSCARD_READERSTATE rgReaderStates, DWORD cReaders)
65 #define p_SCardControl(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
67 #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)
69 #define p_SCardListReaderGroups(fct) LONG(fct) (SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups)
71 #define p_SCardListReaders(fct) LONG(fct) (SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
73 #define p_SCardFreeMemory(fct) LONG(fct) (SCARDCONTEXT hContext, LPCVOID pvMem)
75 #define p_SCardCancel(fct) LONG(fct) (SCARDCONTEXT hContext)
77 #define p_SCardGetAttrib(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
79 #define p_SCardSetAttrib(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
81 #define p_pcsc_stringify_error(fct) const char *(fct)(const LONG pcscError)
84 static LONG internal_error(
void)
89 static const char * internal_stringify_error(
void)
91 return "No spy pcsc_stringify_error() function";
118 .SCardEstablishContext = (p_SCardEstablishContext(*))internal_error,
139 #define LOG log_line("%s:%d", __FILE__, __LINE__)
141 static int Log_fd = -1;
142 static void *Lib_handle = NULL;
143 static pthread_mutex_t Log_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
146 static void log_line(
const char *fmt, ...)
156 static void log_line(
const char *fmt, ...)
161 static void spy_line_direct(
char *line)
170 snprintf(threadid,
sizeof threadid,
"%lX@", pthread_self());
171 pthread_mutex_lock(&Log_fd_mutex);
172 r = write(Log_fd, threadid, strlen(threadid));
173 r = write(Log_fd, line, strlen(line));
174 r = write(Log_fd,
"\n", 1);
176 pthread_mutex_unlock(&Log_fd_mutex);
179 static void spy_line(
const char *fmt, ...)
192 size = vsnprintf(line,
sizeof line, fmt, args);
194 if ((
size_t)size >=
sizeof line)
196 printf(
"libpcsc-spy: Buffer is too small!\n");
199 snprintf(threadid,
sizeof threadid,
"%lX@", pthread_self());
200 pthread_mutex_lock(&Log_fd_mutex);
201 r = write(Log_fd, threadid, strlen(threadid));
202 r = write(Log_fd, line, size);
203 r = write(Log_fd,
"\n", 1);
205 pthread_mutex_unlock(&Log_fd_mutex);
208 static void spy_enter(
const char *fname)
210 struct timeval profile_time;
212 gettimeofday(&profile_time, NULL);
213 spy_line(
">|%ld|%ld|%s", profile_time.tv_sec, profile_time.tv_usec, fname);
216 static void spy_quit(
const char *fname, LONG rv)
218 struct timeval profile_time;
220 gettimeofday(&profile_time, NULL);
221 spy_line(
"<|%ld|%ld|%s|%s|0x%08lX", profile_time.tv_sec,
222 profile_time.tv_usec, fname, spy.pcsc_stringify_error(rv), rv);
225 #define Enter() spy_enter(__FUNCTION__)
226 #define Quit() spy_quit(__FUNCTION__, rv)
228 static void spy_long(
long arg)
230 spy_line(
"0x%08lX", arg);
233 static void spy_ptr_long(LONG *arg)
236 spy_line(
"0x%08lX", *arg);
241 static void spy_ptr_ulong(ULONG *arg)
244 spy_line(
"0x%08lX", *arg);
249 static void spy_pvoid(
const void *ptr)
254 static void spy_buffer(
const unsigned char *buffer,
size_t length)
263 char log_buffer[length * 3 +1], *p;
267 log_buffer[0] =
'\0';
268 for (i=0; i<length; i++)
270 snprintf(p, 4,
"%02X ", buffer[i]);
275 spy_line_direct(log_buffer);
279 static void spy_str(
const char *str)
284 static void spy_n_str(
const char *str, ULONG *len,
int autoallocate)
300 unsigned int length = 0;
308 length += strlen(s)+1;
310 }
while(length < *len);
320 for (i=0; i<cReaders; i++)
322 spy_str(rgReaderStates[i].szReader);
323 spy_long(rgReaderStates[i].dwCurrentState);
324 spy_long(rgReaderStates[i].dwEventState);
326 spy_buffer(rgReaderStates[i].rgbAtr, rgReaderStates[i].cbAtr);
328 spy_buffer(NULL, rgReaderStates[i].cbAtr);
332 static LONG load_lib(
void)
342 #define LIBPCSC_NOSPY "/tmp/PCSC"
343 #define LIBPCSC "/tmp/PCSC"
345 #define LIBPCSC_NOSPY "libpcsclite_nospy.so.1"
346 #define LIBPCSC "libpcsclite.so.1"
352 Lib_handle = dlopen(LIBPCSC_NOSPY, RTLD_LAZY);
353 if (NULL == Lib_handle)
355 log_line(
"%s", dlerror());
358 Lib_handle = dlopen(LIBPCSC, RTLD_LAZY);
359 if (NULL == Lib_handle)
361 log_line(
"%s", dlerror());
366 #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)
370 log_line(
"Symbols dlsym error");
389 if (dlsym(Lib_handle,
"SCardFreeMemory"))
419 home = getenv(
"HOME");
423 snprintf(log_pipe,
sizeof log_pipe,
"%s/pcsc-spy", home);
424 Log_fd = open(log_pipe, O_WRONLY);
427 log_line(
"open %s failed: %s", log_pipe, strerror(errno));
433 rv = spy.SCardEstablishContext(dwScope, pvReserved1, pvReserved2,
435 spy_ptr_long(phContext);
446 rv = spy.SCardReleaseContext(hContext);
457 rv = spy.SCardIsValidContext(hContext);
469 spy_long(dwShareMode);
470 spy_long(dwPreferredProtocols);
471 spy_ptr_long(phCard);
472 spy_ptr_ulong(pdwActiveProtocol);
473 rv = spy.SCardConnect(hContext, szReader, dwShareMode,
474 dwPreferredProtocols, phCard, pdwActiveProtocol);
475 spy_ptr_long(phCard);
476 spy_ptr_ulong(pdwActiveProtocol);
487 spy_long(dwShareMode);
488 spy_long(dwPreferredProtocols);
489 spy_long(dwInitialization);
490 rv = spy.SCardReconnect(hCard, dwShareMode, dwPreferredProtocols,
491 dwInitialization, pdwActiveProtocol);
492 spy_ptr_ulong(pdwActiveProtocol);
503 spy_long(dwDisposition);
504 rv = spy.SCardDisconnect(hCard, dwDisposition);
515 rv = spy.SCardBeginTransaction(hCard);
526 spy_long(dwDisposition);
527 rv = spy.SCardEndTransaction(hCard, dwDisposition);
535 int autoallocate_ReaderName = 0, autoallocate_Atr = 0;
545 spy_ptr_ulong(pcchReaderLen);
546 spy_ptr_ulong(pcbAtrLen);
547 rv = spy.SCardStatus(hCard, mszReaderName, pcchReaderLen, pdwState,
548 pdwProtocol, pbAtr, pcbAtrLen);
549 spy_n_str(mszReaderName, pcchReaderLen, autoallocate_ReaderName);
550 spy_ptr_ulong(pdwState);
551 spy_ptr_ulong(pdwProtocol);
552 if (NULL == pcbAtrLen)
558 if (autoallocate_Atr)
559 buffer = *(LPBYTE *)pbAtr;
563 spy_buffer(buffer, *pcbAtrLen);
577 spy_readerstate(rgReaderStates, cReaders);
578 rv = spy.SCardGetStatusChange(hContext, dwTimeout, rgReaderStates,
580 spy_readerstate(rgReaderStates, cReaders);
591 spy_long(dwControlCode);
592 spy_buffer(pbSendBuffer, cbSendLength);
593 rv = spy.SCardControl(hCard, dwControlCode, pbSendBuffer, cbSendLength,
594 pbRecvBuffer, cbRecvLength, lpBytesReturned);
596 spy_buffer(pbRecvBuffer, *lpBytesReturned);
609 spy_buffer(pbSendBuffer, cbSendLength);
610 rv = spy.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength,
611 pioRecvPci, pbRecvBuffer, pcbRecvLength);
613 spy_buffer(pbRecvBuffer, *pcbRecvLength);
623 int autoallocate = 0;
630 spy_ptr_ulong(pcchGroups);
631 rv = spy.SCardListReaderGroups(hContext, mszGroups, pcchGroups);
633 spy_n_str(mszGroups, pcchGroups, autoallocate);
635 spy_n_str(NULL, pcchGroups, 0);
643 int autoallocate = 0;
651 rv = spy.SCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
653 spy_n_str(mszReaders, pcchReaders, autoallocate);
655 spy_n_str(NULL, pcchReaders, 0);
667 rv = spy.SCardFreeMemory(hContext, pvMem);
678 rv = spy.SCardCancel(hContext);
686 int autoallocate = 0;
694 rv = spy.SCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen);
695 if (NULL == pcbAttrLen)
702 buffer = *(LPBYTE *)pbAttr;
706 spy_buffer(buffer, *pcbAttrLen);
719 spy_buffer(pbAttr, cbAttrLen);
720 rv = spy.SCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen);
727 return spy.pcsc_stringify_error(pcscError);