pcsc-lite  1.9.9
libpcscspy.c
1 /*
2  Log PC/SC arguments
3  Copyright (C) 2011-2013 Ludovic Rousseau
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <dlfcn.h>
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <fcntl.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <sys/time.h>
28 #include <pthread.h>
29 
30 #include "misc.h"
31 #include <winscard.h>
32 
33 #define DEBUG
34 
35 /* function prototypes */
36 
37 #define p_SCardEstablishContext(fct) LONG(fct)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
38 
39 #define p_SCardReleaseContext(fct) LONG(fct)(SCARDCONTEXT hContext)
40 
41 #define p_SCardIsValidContext(fct) LONG(fct) (SCARDCONTEXT hContext)
42 
43 #define p_SCardConnect(fct) LONG(fct) (SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
44 
45 #define p_SCardReconnect(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol)
46 
47 #define p_SCardDisconnect(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwDisposition)
48 
49 #define p_SCardBeginTransaction(fct) LONG(fct) (SCARDHANDLE hCard)
50 
51 #define p_SCardEndTransaction(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwDisposition)
52 
53 #define p_SCardStatus(fct) LONG(fct) (SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
54 
55 #define p_SCardGetStatusChange(fct) LONG(fct) (SCARDCONTEXT hContext, DWORD dwTimeout, LPSCARD_READERSTATE rgReaderStates, DWORD cReaders)
56 
57 #define p_SCardControl(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
58 
59 #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)
60 
61 #define p_SCardListReaderGroups(fct) LONG(fct) (SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups)
62 
63 #define p_SCardListReaders(fct) LONG(fct) (SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
64 
65 #define p_SCardFreeMemory(fct) LONG(fct) (SCARDCONTEXT hContext, LPCVOID pvMem)
66 
67 #define p_SCardCancel(fct) LONG(fct) (SCARDCONTEXT hContext)
68 
69 #define p_SCardGetAttrib(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
70 
71 #define p_SCardSetAttrib(fct) LONG(fct) (SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
72 
73 #define p_pcsc_stringify_error(fct) const char *(fct)(const LONG pcscError)
74 
75 /* fake function to just return en error code */
76 static LONG internal_error(void)
77 {
79 }
80 
81 static const char * internal_stringify_error(void)
82 {
83  return "No spy pcsc_stringify_error() function";
84 }
85 
86 #pragma GCC diagnostic push
87 #pragma GCC diagnostic ignored "-Wcast-function-type"
88 /* contains pointers to real functions */
89 static struct
90 {
91  p_SCardEstablishContext(*SCardEstablishContext);
92  p_SCardReleaseContext(*SCardReleaseContext);
93  p_SCardIsValidContext(*SCardIsValidContext);
94  p_SCardConnect(*SCardConnect);
95  p_SCardReconnect(*SCardReconnect);
96  p_SCardDisconnect(*SCardDisconnect);
97  p_SCardBeginTransaction(*SCardBeginTransaction);
98  p_SCardEndTransaction(*SCardEndTransaction);
99  p_SCardStatus(*SCardStatus);
100  p_SCardGetStatusChange(*SCardGetStatusChange);
101  p_SCardControl(*SCardControl);
102  p_SCardTransmit(*SCardTransmit);
103  p_SCardListReaderGroups(*SCardListReaderGroups);
104  p_SCardListReaders(*SCardListReaders);
105  p_SCardFreeMemory(*SCardFreeMemory);
106  p_SCardCancel(*SCardCancel);
107  p_SCardGetAttrib(*SCardGetAttrib);
108  p_SCardSetAttrib(*SCardSetAttrib);
109  p_pcsc_stringify_error(*pcsc_stringify_error);
110 } spy = {
111  /* initialized with the fake internal_error() function */
112  .SCardEstablishContext = (p_SCardEstablishContext(*))internal_error,
113  .SCardReleaseContext = (p_SCardReleaseContext(*))internal_error,
114  .SCardIsValidContext = (p_SCardIsValidContext(*))internal_error,
115  .SCardConnect = (p_SCardConnect(*))internal_error,
116  .SCardReconnect = (p_SCardReconnect(*))internal_error,
117  .SCardDisconnect = (p_SCardDisconnect(*))internal_error,
118  .SCardBeginTransaction = (p_SCardBeginTransaction(*))internal_error,
119  .SCardEndTransaction = (p_SCardEndTransaction(*))internal_error,
120  .SCardStatus = (p_SCardStatus(*))internal_error,
121  .SCardGetStatusChange = (p_SCardGetStatusChange(*))internal_error,
122  .SCardControl = (p_SCardControl(*))internal_error,
123  .SCardTransmit = (p_SCardTransmit(*))internal_error,
124  .SCardListReaderGroups = (p_SCardListReaderGroups(*))internal_error,
125  .SCardListReaders = (p_SCardListReaders(*))internal_error,
126  .SCardFreeMemory = (p_SCardFreeMemory(*))internal_error,
127  .SCardCancel = (p_SCardCancel(*))internal_error,
128  .SCardGetAttrib = (p_SCardGetAttrib(*))internal_error,
129  .SCardSetAttrib = (p_SCardSetAttrib(*))internal_error,
130  .pcsc_stringify_error = (p_pcsc_stringify_error(*))internal_stringify_error
131 };
132 #pragma GCC diagnostic pop
133 
134 #define LOG log_line("%s:%d", __FILE__, __LINE__)
135 
136 static int Log_fd = -1;
137 static void *Lib_handle = NULL;
138 static pthread_mutex_t Log_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
139 
140 #ifdef DEBUG
141 static void log_line(const char *fmt, ...)
142 {
143  va_list args;
144 
145  va_start(args, fmt);
146  vprintf(fmt, args);
147  printf("\n");
148  va_end(args);
149 }
150 #else
151 static void log_line(const char *fmt, ...)
152 {
153 }
154 #endif
155 
156 static void spy_line_direct(char *line)
157 {
158  char threadid[30];
159  ssize_t r;
160 
161  /* spying disabled */
162  if (Log_fd < 0)
163  return;
164 
165  snprintf(threadid, sizeof threadid, "%lX@", pthread_self());
166  pthread_mutex_lock(&Log_fd_mutex);
167  r = write(Log_fd, threadid, strlen(threadid));
168  r = write(Log_fd, line, strlen(line));
169  r = write(Log_fd, "\n", 1);
170  (void)r;
171  pthread_mutex_unlock(&Log_fd_mutex);
172 }
173 
174 static void spy_line(const char *fmt, ...)
175 {
176  va_list args;
177  char line[256];
178  int size;
179  char threadid[30];
180  ssize_t r;
181 
182  /* spying disabled */
183  if (Log_fd < 0)
184  return;
185 
186  va_start(args, fmt);
187  size = vsnprintf(line, sizeof line, fmt, args);
188  va_end(args);
189  if ((size_t)size >= sizeof line)
190  {
191  printf("libpcsc-spy: Buffer is too small!\n");
192  return;
193  }
194  snprintf(threadid, sizeof threadid, "%lX@", pthread_self());
195  pthread_mutex_lock(&Log_fd_mutex);
196  r = write(Log_fd, threadid, strlen(threadid));
197  r = write(Log_fd, line, size);
198  r = write(Log_fd, "\n", 1);
199  (void)r;
200  pthread_mutex_unlock(&Log_fd_mutex);
201 }
202 
203 static void spy_enter(const char *fname)
204 {
205  struct timeval profile_time;
206 
207  gettimeofday(&profile_time, NULL);
208  spy_line(">|%ld|%ld|%s", profile_time.tv_sec, profile_time.tv_usec, fname);
209 }
210 
211 static void spy_quit(const char *fname, LONG rv)
212 {
213  struct timeval profile_time;
214 
215  gettimeofday(&profile_time, NULL);
216  spy_line("<|%ld|%ld|%s|%s|0x%08lX", profile_time.tv_sec,
217  profile_time.tv_usec, fname, spy.pcsc_stringify_error(rv), rv);
218 }
219 
220 #define Enter() spy_enter(__FUNCTION__)
221 #define Quit() spy_quit(__FUNCTION__, rv)
222 
223 static void spy_long(long arg)
224 {
225  spy_line("0x%08lX", arg);
226 }
227 
228 static void spy_ptr_long(LONG *arg)
229 {
230  if (arg)
231  spy_line("0x%08lX", *arg);
232  else
233  spy_line("NULL");
234 }
235 
236 static void spy_ptr_ulong(ULONG *arg)
237 {
238  if (arg)
239  spy_line("0x%08lX", *arg);
240  else
241  spy_line("NULL");
242 }
243 
244 static void spy_pvoid(const void *ptr)
245 {
246  spy_line("%p", ptr);
247 }
248 
249 static void spy_buffer(const unsigned char *buffer, size_t length)
250 {
251  spy_long(length);
252 
253  if (NULL == buffer)
254  spy_line("NULL");
255  else
256  {
257  /* "78 79 7A" */
258  char log_buffer[length * 3 +1], *p;
259  size_t i;
260 
261  p = log_buffer;
262  log_buffer[0] = '\0';
263  for (i=0; i<length; i++)
264  {
265  snprintf(p, 4, "%02X ", buffer[i]);
266  p += 3;
267  }
268  *p = '\0';
269 
270  spy_line_direct(log_buffer);
271  }
272 }
273 
274 static void spy_str(const char *str)
275 {
276  spy_line("%s", str);
277 }
278 
279 static void spy_n_str(const char *str, ULONG *len, int autoallocate)
280 {
281  spy_ptr_ulong(len);
282  if (NULL == len)
283  {
284  spy_line("\"\"");
285  }
286  else
287  {
288  if (NULL == str)
289  {
290  spy_line("NULL");
291  }
292  else
293  {
294  const char *s = str;
295  unsigned int length = 0;
296 
297  if (autoallocate)
298  s = *(char **)str;
299 
300  do
301  {
302  spy_line("%s", s);
303  length += strlen(s)+1;
304  s += strlen(s)+1;
305  } while(length < *len);
306  }
307  }
308 }
309 
310 
311 static void spy_readerstate(SCARD_READERSTATE * rgReaderStates, int cReaders)
312 {
313  int i;
314 
315  for (i=0; i<cReaders; i++)
316  {
317  spy_str(rgReaderStates[i].szReader);
318  spy_long(rgReaderStates[i].dwCurrentState);
319  spy_long(rgReaderStates[i].dwEventState);
320  if (rgReaderStates[i].cbAtr <= MAX_ATR_SIZE)
321  spy_buffer(rgReaderStates[i].rgbAtr, rgReaderStates[i].cbAtr);
322  else
323  spy_buffer(NULL, rgReaderStates[i].cbAtr);
324  }
325 }
326 
327 static LONG load_lib(void)
328 {
329 
330 #define LIBPCSC_NOSPY "libpcsclite_nospy.so.1"
331 #define LIBPCSC "libpcsclite.so.1"
332 
333  /* first try to load the NOSPY library
334  * this is used for programs doing an explicit dlopen like
335  * Perl and Python wrappers */
336  Lib_handle = dlopen(LIBPCSC_NOSPY, RTLD_LAZY);
337  if (NULL == Lib_handle)
338  {
339  log_line("%s", dlerror());
340 
341  /* load the normal library */
342  Lib_handle = dlopen(LIBPCSC, RTLD_LAZY);
343  if (NULL == Lib_handle)
344  {
345  log_line("%s", dlerror());
346  return SCARD_F_INTERNAL_ERROR;
347  }
348  }
349 
350 #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)
351 
352  if (SCardEstablishContext == dlsym(Lib_handle, "SCardEstablishContext"))
353  {
354  log_line("Symbols dlsym error");
355  return SCARD_F_INTERNAL_ERROR;
356  }
357 
358  get_symbol(SCardEstablishContext);
359  get_symbol(SCardReleaseContext);
360  get_symbol(SCardIsValidContext);
361  get_symbol(SCardConnect);
362  get_symbol(SCardReconnect);
363  get_symbol(SCardDisconnect);
364  get_symbol(SCardBeginTransaction);
365  get_symbol(SCardEndTransaction);
366  get_symbol(SCardStatus);
367  get_symbol(SCardGetStatusChange);
368  get_symbol(SCardControl);
369  get_symbol(SCardTransmit);
370  get_symbol(SCardListReaderGroups);
371  get_symbol(SCardListReaders);
372  /* Mac OS X do not have SCardFreeMemory() */
373  if (dlsym(Lib_handle, "SCardFreeMemory"))
374  get_symbol(SCardFreeMemory);
375  get_symbol(SCardCancel);
376  get_symbol(SCardGetAttrib);
377  get_symbol(SCardSetAttrib);
378  get_symbol(pcsc_stringify_error);
379 
380  return SCARD_S_SUCCESS;
381 }
382 
383 
384 /* exported functions */
385 PCSC_API p_SCardEstablishContext(SCardEstablishContext)
386 {
387  LONG rv;
388  static int init = 0;
389 
390  if (!init)
391  {
392  const char *home;
393  char log_pipe[128];
394 
395  init = 1;
396 
397  /* load the real library */
398  rv = load_lib();
399  if (rv != SCARD_S_SUCCESS)
400  return rv;
401 
402  /* check if we can log */
403  home = getenv("HOME");
404  if (NULL == home)
405  home = "/tmp";
406 
407  snprintf(log_pipe, sizeof log_pipe, "%s/pcsc-spy", home);
408  Log_fd = open(log_pipe, O_WRONLY);
409  if (Log_fd < 0)
410  {
411  log_line("open %s failed: %s", log_pipe, strerror(errno));
412  }
413  }
414 
415  Enter();
416  spy_long(dwScope);
417  rv = spy.SCardEstablishContext(dwScope, pvReserved1, pvReserved2,
418  phContext);
419  spy_ptr_long(phContext);
420  Quit();
421  return rv;
422 }
423 
424 PCSC_API p_SCardReleaseContext(SCardReleaseContext)
425 {
426  LONG rv;
427 
428  Enter();
429  spy_long(hContext);
430  rv = spy.SCardReleaseContext(hContext);
431  Quit();
432  return rv;
433 }
434 
435 PCSC_API p_SCardIsValidContext(SCardIsValidContext)
436 {
437  LONG rv;
438 
439  Enter();
440  spy_long(hContext);
441  rv = spy.SCardIsValidContext(hContext);
442  Quit();
443  return rv;
444 }
445 
446 PCSC_API p_SCardConnect(SCardConnect)
447 {
448  LONG rv;
449 
450  Enter();
451  spy_long(hContext);
452  spy_str(szReader);
453  spy_long(dwShareMode);
454  spy_long(dwPreferredProtocols);
455  spy_ptr_long(phCard);
456  spy_ptr_ulong(pdwActiveProtocol);
457  rv = spy.SCardConnect(hContext, szReader, dwShareMode,
458  dwPreferredProtocols, phCard, pdwActiveProtocol);
459  spy_ptr_long(phCard);
460  spy_ptr_ulong(pdwActiveProtocol);
461  Quit();
462  return rv;
463 }
464 
465 PCSC_API p_SCardReconnect(SCardReconnect)
466 {
467  LONG rv;
468 
469  Enter();
470  spy_long(hCard);
471  spy_long(dwShareMode);
472  spy_long(dwPreferredProtocols);
473  spy_long(dwInitialization);
474  rv = spy.SCardReconnect(hCard, dwShareMode, dwPreferredProtocols,
475  dwInitialization, pdwActiveProtocol);
476  spy_ptr_ulong(pdwActiveProtocol);
477  Quit();
478  return rv;
479 }
480 
481 PCSC_API p_SCardDisconnect(SCardDisconnect)
482 {
483  LONG rv;
484 
485  Enter();
486  spy_long(hCard);
487  spy_long(dwDisposition);
488  rv = spy.SCardDisconnect(hCard, dwDisposition);
489  Quit();
490  return rv;
491 }
492 
493 PCSC_API p_SCardBeginTransaction(SCardBeginTransaction)
494 {
495  LONG rv;
496 
497  Enter();
498  spy_long(hCard);
499  rv = spy.SCardBeginTransaction(hCard);
500  Quit();
501  return rv;
502 }
503 
504 PCSC_API p_SCardEndTransaction(SCardEndTransaction)
505 {
506  LONG rv;
507 
508  Enter();
509  spy_long(hCard);
510  spy_long(dwDisposition);
511  rv = spy.SCardEndTransaction(hCard, dwDisposition);
512  Quit();
513  return rv;
514 }
515 
516 PCSC_API p_SCardStatus(SCardStatus)
517 {
518  LONG rv;
519  int autoallocate_ReaderName = 0, autoallocate_Atr = 0;
520 
521  if (pcchReaderLen)
522  autoallocate_ReaderName = *pcchReaderLen == SCARD_AUTOALLOCATE;
523 
524  if (pcbAtrLen)
525  autoallocate_Atr = *pcbAtrLen == SCARD_AUTOALLOCATE;
526 
527  Enter();
528  spy_long(hCard);
529  spy_ptr_ulong(pcchReaderLen);
530  spy_ptr_ulong(pcbAtrLen);
531  rv = spy.SCardStatus(hCard, mszReaderName, pcchReaderLen, pdwState,
532  pdwProtocol, pbAtr, pcbAtrLen);
533  spy_n_str(mszReaderName, pcchReaderLen, autoallocate_ReaderName);
534  spy_ptr_ulong(pdwState);
535  spy_ptr_ulong(pdwProtocol);
536  if (NULL == pcbAtrLen)
537  spy_line("NULL");
538  else
539  {
540  LPBYTE buffer;
541 
542  if (autoallocate_Atr)
543  buffer = *(LPBYTE *)pbAtr;
544  else
545  buffer = pbAtr;
546 
547  spy_buffer(buffer, *pcbAtrLen);
548  }
549  Quit();
550  return rv;
551 }
552 
553 PCSC_API p_SCardGetStatusChange(SCardGetStatusChange)
554 {
555  LONG rv;
556 
557  Enter();
558  spy_long(hContext);
559  spy_long(dwTimeout);
560  spy_long(cReaders);
561  spy_readerstate(rgReaderStates, cReaders);
562  rv = spy.SCardGetStatusChange(hContext, dwTimeout, rgReaderStates,
563  cReaders);
564  spy_readerstate(rgReaderStates, cReaders);
565  Quit();
566  return rv;
567 }
568 
569 PCSC_API p_SCardControl(SCardControl)
570 {
571  LONG rv;
572 
573  Enter();
574  spy_long(hCard);
575  spy_long(dwControlCode);
576  spy_buffer(pbSendBuffer, cbSendLength);
577  rv = spy.SCardControl(hCard, dwControlCode, pbSendBuffer, cbSendLength,
578  pbRecvBuffer, cbRecvLength, lpBytesReturned);
579  if (lpBytesReturned)
580  spy_buffer(pbRecvBuffer, *lpBytesReturned);
581  else
582  spy_buffer(NULL, 0);
583  Quit();
584  return rv;
585 }
586 
587 PCSC_API p_SCardTransmit(SCardTransmit)
588 {
589  LONG rv;
590 
591  Enter();
592  spy_long(hCard);
593  spy_long(pioSendPci->dwProtocol);
594  spy_long(pioSendPci->cbPciLength);
595  spy_buffer(pbSendBuffer, cbSendLength);
596  rv = spy.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength,
597  pioRecvPci, pbRecvBuffer, pcbRecvLength);
598  spy_long(pioRecvPci->dwProtocol);
599  spy_long(pioRecvPci->cbPciLength);
600  if (pcbRecvLength)
601  spy_buffer(pbRecvBuffer, *pcbRecvLength);
602  else
603  spy_buffer(NULL, 0);
604  Quit();
605  return rv;
606 }
607 
608 PCSC_API p_SCardListReaderGroups(SCardListReaderGroups)
609 {
610  LONG rv;
611  int autoallocate = 0;
612 
613  if (pcchGroups)
614  autoallocate = *pcchGroups == SCARD_AUTOALLOCATE;
615 
616  Enter();
617  spy_long(hContext);
618  spy_ptr_ulong(pcchGroups);
619  rv = spy.SCardListReaderGroups(hContext, mszGroups, pcchGroups);
620  if (SCARD_S_SUCCESS == rv)
621  spy_n_str(mszGroups, pcchGroups, autoallocate);
622  else
623  spy_n_str(NULL, pcchGroups, 0);
624  Quit();
625  return rv;
626 }
627 
628 PCSC_API p_SCardListReaders(SCardListReaders)
629 {
630  LONG rv;
631  int autoallocate = 0;
632 
633  if (pcchReaders)
634  autoallocate = *pcchReaders == SCARD_AUTOALLOCATE;
635 
636  Enter();
637  spy_long(hContext);
638  spy_str(mszGroups);
639  rv = spy.SCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
640  if (SCARD_S_SUCCESS == rv)
641  spy_n_str(mszReaders, pcchReaders, autoallocate);
642  else
643  spy_n_str(NULL, pcchReaders, 0);
644  Quit();
645  return rv;
646 }
647 
648 PCSC_API p_SCardFreeMemory(SCardFreeMemory)
649 {
650  LONG rv;
651 
652  Enter();
653  spy_long(hContext);
654  spy_pvoid(pvMem);
655  rv = spy.SCardFreeMemory(hContext, pvMem);
656  Quit();
657  return rv;
658 }
659 
660 PCSC_API p_SCardCancel(SCardCancel)
661 {
662  LONG rv;
663 
664  Enter();
665  spy_long(hContext);
666  rv = spy.SCardCancel(hContext);
667  Quit();
668  return rv;
669 }
670 
671 PCSC_API p_SCardGetAttrib(SCardGetAttrib)
672 {
673  LONG rv;
674  int autoallocate = 0;
675 
676  if (pcbAttrLen)
677  autoallocate = *pcbAttrLen == SCARD_AUTOALLOCATE;
678 
679  Enter();
680  spy_long(hCard);
681  spy_long(dwAttrId);
682  rv = spy.SCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen);
683  if (NULL == pcbAttrLen)
684  spy_buffer(NULL, 0);
685  else
686  {
687  LPBYTE buffer;
688 
689  if (autoallocate)
690  buffer = *(LPBYTE *)pbAttr;
691  else
692  buffer = pbAttr;
693 
694  spy_buffer(buffer, *pcbAttrLen);
695  }
696  Quit();
697  return rv;
698 }
699 
700 PCSC_API p_SCardSetAttrib(SCardSetAttrib)
701 {
702  LONG rv;
703 
704  Enter();
705  spy_long(hCard);
706  spy_long(dwAttrId);
707  spy_buffer(pbAttr, cbAttrLen);
708  rv = spy.SCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen);
709  Quit();
710  return rv;
711 }
712 
713 PCSC_API p_pcsc_stringify_error(pcsc_stringify_error)
714 {
715  return spy.pcsc_stringify_error(pcscError);
716 }
717 
PCSC_API LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
Releases memory that has been returned from the resource manager using the SCARD_AUTOALLOCATE length ...
PCSC_API LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
Set an attribute of the IFD Handler.
Definition: winscard.c:1440
PCSC_API 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 SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
Terminates a connection made through SCardConnect().
Definition: winscard.c:827
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.
Definition: winscard.c:234
PCSC_API LONG SCardReleaseContext(SCARDCONTEXT hContext)
Destroys a communication context to the PC/SC Resource Manager.
Definition: winscard.c:220
PCSC_API LONG SCardIsValidContext(SCARDCONTEXT hContext)
Check if a SCARDCONTEXT is valid.
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 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().
Definition: winscard.c:1490
PCSC_API LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups)
Returns a list of currently available reader groups on the system.
PCSC_API LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
Creates an Application Context to the PC/SC Resource Manager.
Definition: winscard.c:195
PCSC_API LONG SCardCancel(SCARDCONTEXT hContext)
Cancels a specific blocking SCardGetStatusChange() function.
PCSC_API const char * pcsc_stringify_error(const LONG pcscError)
Returns a human readable text for the given PC/SC error code.
Definition: error.c:82
PCSC_API LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
Get an attribute from the IFD Handler (reader driver).
Definition: winscard.c:1365
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.
Definition: winscard.c:1306
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().
Definition: winscard.c:525
PCSC_API LONG SCardBeginTransaction(SCARDHANDLE hCard)
Establishes a temporary exclusive access mode for doing a serie of commands in a transaction.
Definition: winscard.c:1049
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.
Definition: winscard.c:1243
PCSC_API LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
Ends a previously begun transaction.
Definition: winscard.c:1091
#define SCARD_F_INTERNAL_ERROR
An internal consistency check failed.
Definition: pcsclite.h:109
#define SCARD_S_SUCCESS
No error was encountered.
Definition: pcsclite.h:107
#define SCARD_PROTOCOL_T1
T=1 active protocol.
Definition: pcsclite.h:242
#define SCARD_PROTOCOL_T0
T=0 active protocol.
Definition: pcsclite.h:241
#define SCARD_AUTOALLOCATE
see SCardFreeMemory()
Definition: pcsclite.h:233
#define MAX_ATR_SIZE
Maximum ATR size.
Definition: pcsclite.h:59
#define SCARD_PROTOCOL_RAW
Raw active protocol.
Definition: pcsclite.h:243
const SCARD_IO_REQUEST g_rgSCardT0Pci
Protocol Control Information for T=0.
Definition: libpcscspy.c:718
Protocol Control Information (PCI)
Definition: pcsclite.h:80
This handles smart card reader communications.
PCSC_API const SCARD_IO_REQUEST g_rgSCardRawPci
Protocol Control Information for raw access.
PCSC_API const SCARD_IO_REQUEST g_rgSCardT1Pci
Protocol Control Information for T=1.