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