38 #define SCardControl SCardControl132
40 PCSC_API int32_t SCardControl132(
SCARDHANDLE hCard, uint32_t dwControlCode,
41 const void *pbSendBuffer, uint32_t cbSendLength,
42 void *pbRecvBuffer, uint32_t cbRecvLength, uint32_t *lpBytesReturned);
47 #define p_SCardEstablishContext(fct) LONG(fct)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
49 #define p_SCardReleaseContext(fct) LONG(fct)(SCARDCONTEXT hContext)
51 #define p_SCardIsValidContext(fct) LONG(fct) (SCARDCONTEXT hContext)
53 #define p_SCardConnect(fct) LONG(fct) (SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
55 #define p_SCardReconnect(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol)
57 #define p_SCardDisconnect(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwDisposition)
59 #define p_SCardBeginTransaction(fct) LONG(fct) (SCARDHANDLE hCard)
61 #define p_SCardEndTransaction(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwDisposition)
63 #define p_SCardStatus(fct) LONG(fct) (SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
65 #define p_SCardGetStatusChange(fct) LONG(fct) (SCARDCONTEXT hContext, DWORD dwTimeout, LPSCARD_READERSTATE rgReaderStates, DWORD cReaders)
67 #define p_SCardControl(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
69 #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)
71 #define p_SCardListReaderGroups(fct) LONG(fct) (SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups)
73 #define p_SCardListReaders(fct) LONG(fct) (SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
75 #define p_SCardFreeMemory(fct) LONG(fct) (SCARDCONTEXT hContext, LPCVOID pvMem)
77 #define p_SCardCancel(fct) LONG(fct) (SCARDCONTEXT hContext)
79 #define p_SCardGetAttrib(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
81 #define p_SCardSetAttrib(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
83 #define p_pcsc_stringify_error(fct) char *(fct)(const LONG pcscError)
86 static LONG internal_error(
void)
91 static const char * internal_stringify_error(
void)
93 return "No spy pcsc_stringify_error() function";
120 .SCardEstablishContext = (p_SCardEstablishContext(*))internal_error,
141 #define LOG log_line("%s:%d", __FILE__, __LINE__)
143 static int Log_fd = -1;
144 static void *Lib_handle = NULL;
145 static pthread_mutex_t Log_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
148 static void log_line(
const char *fmt, ...)
158 static void log_line(
const char *fmt, ...)
163 static void spy_line_direct(
char *line)
172 snprintf(threadid,
sizeof threadid,
"%lX@", pthread_self());
173 pthread_mutex_lock(&Log_fd_mutex);
174 r = write(Log_fd, threadid, strlen(threadid));
175 r = write(Log_fd, line, strlen(line));
176 r = write(Log_fd,
"\n", 1);
178 pthread_mutex_unlock(&Log_fd_mutex);
181 static void spy_line(
const char *fmt, ...)
194 size = vsnprintf(line,
sizeof line, fmt, args);
196 if ((
size_t)size >=
sizeof line)
198 printf(
"libpcsc-spy: Buffer is too small!\n");
201 snprintf(threadid,
sizeof threadid,
"%lX@", pthread_self());
202 pthread_mutex_lock(&Log_fd_mutex);
203 r = write(Log_fd, threadid, strlen(threadid));
204 r = write(Log_fd, line, size);
205 r = write(Log_fd,
"\n", 1);
207 pthread_mutex_unlock(&Log_fd_mutex);
210 static void spy_enter(
const char *fname)
212 struct timeval profile_time;
214 gettimeofday(&profile_time, NULL);
215 spy_line(
">|%d|%d|%s", profile_time.tv_sec, profile_time.tv_usec, fname);
218 static void spy_quit(
const char *fname, LONG rv)
220 struct timeval profile_time;
222 gettimeofday(&profile_time, NULL);
223 spy_line(
"<|%d|%d|%s|%s|0x%08X", profile_time.tv_sec,
224 profile_time.tv_usec, fname, spy.pcsc_stringify_error(rv), rv);
227 #define Enter() spy_enter(__FUNCTION__)
228 #define Quit() spy_quit(__FUNCTION__, rv)
230 static void spy_long(
long arg)
232 spy_line(
"0x%08lX", arg);
235 static void spy_ptr_long(LONG *arg)
238 spy_line(
"0x%08lX", *arg);
243 static void spy_ptr_ulong(ULONG *arg)
246 spy_line(
"0x%08lX", *arg);
251 static void spy_pvoid(
const void *ptr)
256 static void spy_buffer(
const unsigned char *buffer,
size_t length)
265 char log_buffer[length * 3 +1], *p;
269 log_buffer[0] =
'\0';
270 for (i=0; i<length; i++)
272 snprintf(p, 4,
"%02X ", buffer[i]);
277 spy_line_direct(log_buffer);
281 static void spy_str(
const char *str)
286 static void spy_n_str(
const char *str, ULONG *len,
int autoallocate)
302 unsigned int length = 0;
310 length += strlen(s)+1;
312 }
while(length < *len);
322 for (i=0; i<cReaders; i++)
324 spy_str(rgReaderStates[i].szReader);
325 spy_long(rgReaderStates[i].dwCurrentState);
326 spy_long(rgReaderStates[i].dwEventState);
328 spy_buffer(rgReaderStates[i].rgbAtr, rgReaderStates[i].cbAtr);
330 spy_buffer(NULL, rgReaderStates[i].cbAtr);
334 static LONG load_lib(
void)
344 #define LIBPCSC_NOSPY "/tmp/PCSC"
345 #define LIBPCSC "/tmp/PCSC"
347 #define LIBPCSC_NOSPY "libpcsclite_nospy.so.1"
348 #define LIBPCSC "libpcsclite.so.1"
354 Lib_handle = dlopen(LIBPCSC_NOSPY, RTLD_LAZY);
355 if (NULL == Lib_handle)
357 log_line(
"%s", dlerror());
360 Lib_handle = dlopen(LIBPCSC, RTLD_LAZY);
361 if (NULL == Lib_handle)
363 log_line(
"%s", dlerror());
368 #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)
372 log_line(
"Symbols dlsym error");
391 if (dlsym(Lib_handle,
"SCardFreeMemory"))
421 home = getenv(
"HOME");
425 snprintf(log_pipe,
sizeof log_pipe,
"%s/pcsc-spy", home);
426 Log_fd = open(log_pipe, O_WRONLY);
429 log_line(
"open %s failed: %s", log_pipe, strerror(errno));
435 rv = spy.SCardEstablishContext(dwScope, pvReserved1, pvReserved2,
437 spy_ptr_long(phContext);
448 rv = spy.SCardReleaseContext(hContext);
459 rv = spy.SCardIsValidContext(hContext);
471 spy_long(dwShareMode);
472 spy_long(dwPreferredProtocols);
473 spy_ptr_long(phCard);
474 spy_ptr_ulong(pdwActiveProtocol);
475 rv = spy.SCardConnect(hContext, szReader, dwShareMode,
476 dwPreferredProtocols, phCard, pdwActiveProtocol);
477 spy_ptr_long(phCard);
478 spy_ptr_ulong(pdwActiveProtocol);
489 spy_long(dwShareMode);
490 spy_long(dwPreferredProtocols);
491 spy_long(dwInitialization);
492 rv = spy.SCardReconnect(hCard, dwShareMode, dwPreferredProtocols,
493 dwInitialization, pdwActiveProtocol);
494 spy_ptr_ulong(pdwActiveProtocol);
505 spy_long(dwDisposition);
506 rv = spy.SCardDisconnect(hCard, dwDisposition);
517 rv = spy.SCardBeginTransaction(hCard);
528 spy_long(dwDisposition);
529 rv = spy.SCardEndTransaction(hCard, dwDisposition);
537 int autoallocate_ReaderName = 0, autoallocate_Atr = 0;
547 spy_ptr_ulong(pcchReaderLen);
548 spy_ptr_ulong(pcbAtrLen);
549 rv = spy.SCardStatus(hCard, mszReaderName, pcchReaderLen, pdwState,
550 pdwProtocol, pbAtr, pcbAtrLen);
551 spy_n_str(mszReaderName, pcchReaderLen, autoallocate_ReaderName);
552 spy_ptr_ulong(pdwState);
553 spy_ptr_ulong(pdwProtocol);
554 if (NULL == pcbAtrLen)
558 if (autoallocate_Atr)
560 const unsigned char *b = *(
unsigned char **)pbAtr;
562 spy_buffer(b, *pcbAtrLen);
565 spy_buffer(pbAtr, *pcbAtrLen);
579 spy_readerstate(rgReaderStates, cReaders);
580 rv = spy.SCardGetStatusChange(hContext, dwTimeout, rgReaderStates,
582 spy_readerstate(rgReaderStates, cReaders);
593 spy_long(dwControlCode);
594 spy_buffer(pbSendBuffer, cbSendLength);
595 rv = spy.SCardControl(hCard, dwControlCode, pbSendBuffer, cbSendLength,
596 pbRecvBuffer, cbRecvLength, lpBytesReturned);
598 spy_buffer(pbRecvBuffer, *lpBytesReturned);
611 spy_buffer(pbSendBuffer, cbSendLength);
612 rv = spy.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength,
613 pioRecvPci, pbRecvBuffer, pcbRecvLength);
615 spy_buffer(pbRecvBuffer, *pcbRecvLength);
625 int autoallocate = 0;
632 spy_ptr_ulong(pcchGroups);
633 rv = spy.SCardListReaderGroups(hContext, mszGroups, pcchGroups);
634 spy_n_str(mszGroups, pcchGroups, autoallocate);
642 int autoallocate = 0;
650 rv = spy.SCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
651 spy_n_str(mszReaders, pcchReaders, autoallocate);
663 rv = spy.SCardFreeMemory(hContext, pvMem);
674 rv = spy.SCardCancel(hContext);
682 int autoallocate = 0;
690 rv = spy.SCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen);
691 if (NULL == pcbAttrLen)
695 const unsigned char *s = pbAttr;
698 s = *(
unsigned char **)pbAttr;
700 spy_buffer(s, *pcbAttrLen);
713 spy_buffer(pbAttr, cbAttrLen);
714 rv = spy.SCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen);
721 return spy.pcsc_stringify_error(pcscError);
PCSC_API LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
Returns a list of currently available readers on the system.
PCSC_API LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups)
Returns a list of currently available reader groups on the system.
PCSC_API char * pcsc_stringify_error(const LONG pcscError)
Returns a human readable text for the given PC/SC error code.
PCSC_API LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
Creates an Application Context to the PC/SC Resource Manager.
#define SCARD_PROTOCOL_T1
T=1 active protocol.
PCSC_API LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
Releases memory that has been returned from the resource manager using the SCARD_AUTOALLOCATE length ...
LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout, SCARD_READERSTATE *rgReaderStates, DWORD cReaders)
Blocks execution until the current availability of the cards in a specific set of readers changes...
PCSC_API LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
Get an attribute from the IFD Handler (reader driver).
PCSC_API LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
Terminates a connection made through SCardConnect().
PCSC_API LONG SCardCancel(SCARDCONTEXT hContext)
Cancels all pending blocking requests on the SCardGetStatusChange() function.
const SCARD_IO_REQUEST g_rgSCardRawPci
Protocol Control Information for raw access.
PCSC_API LONG SCardIsValidContext(SCARDCONTEXT hContext)
Check if a SCARDCONTEXT is valid.
#define SCARD_AUTOALLOCATE
see SCardFreeMemory()
#define SCARD_PROTOCOL_T0
T=0 active protocol.
PCSC_API LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol)
Reestablishes a connection to a reader that was previously connected to using SCardConnect().
PCSC_API LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
Establishes a connection to the reader specified in * szReader.
PCSC_API LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
Returns the current status of the reader connected to by hCard.
PCSC_API LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
Set an attribute of the IFD Handler.
LONG SCARDHANDLE
hCard returned by SCardConnect()
PCSC_API LONG SCardBeginTransaction(SCARDHANDLE hCard)
Establishes a temporary exclusive access mode for doing a serie of commands in a transaction.
#define SCARD_PROTOCOL_RAW
Raw active protocol.
Protocol Control Information (PCI)
PCSC_API LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
Sends a command directly to the IFD Handler (reader driver) to be processed by the reader...
#define MAX_ATR_SIZE
Maximum ATR size.
PCSC_API LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
Ends a previously begun transaction.
PCSC_API LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
Sends an APDU to the smart card contained in the reader connected to by SCardConnect().
const SCARD_IO_REQUEST g_rgSCardT1Pci
Protocol Control Information for T=1.
#define SCARD_S_SUCCESS
error codes from http://msdn.microsoft.com/en-us/library/aa924526.aspx
const SCARD_IO_REQUEST g_rgSCardT0Pci
Protocol Control Information for T=0.
This handles smart card reader communications.
PCSC_API LONG SCardReleaseContext(SCARDCONTEXT hContext)
Destroys a communication context to the PC/SC Resource Manager.
#define SCARD_F_INTERNAL_ERROR
An internal consistency check failed.