pcsc-lite  2.2.3
libpcscspy.c
1 /*
2  Log PC/SC arguments
3  Copyright (C) 2011-2024 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 #include "sys_generic.h"
33 
34 #define DEBUG
35 
36 #define DLSYM_DECLARE(symbol) \
37  typeof(symbol)* symbol
38 #define DLSYM_SET_VALUE(symbol) \
39  .symbol = (typeof(symbol)(*))internal_error
40 
41 /* fake function to just return en error code */
42 static LONG internal_error(void)
43 {
45 }
46 
47 #pragma GCC diagnostic push
48 #pragma GCC diagnostic ignored "-Wcast-function-type"
49 /* contains pointers to real functions */
50 static struct
51 {
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);
70 } spy = {
71  /* initialized with the fake internal_error() function */
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)
90 };
91 #pragma GCC diagnostic pop
92 
93 #define LOG log_line("%s:%d", __FILE__, __LINE__)
94 
95 static int Log_fd = -1;
96 static void *Lib_handle = NULL;
97 static pthread_mutex_t Log_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
98 
99 #ifdef DEBUG
100 static void log_line(const char *fmt, ...)
101 {
102  va_list args;
103 
104  va_start(args, fmt);
105  vprintf(fmt, args);
106  printf("\n");
107  va_end(args);
108 }
109 #else
110 static void log_line(const char *fmt, ...)
111 {
112 }
113 #endif
114 
115 static void spy_line_direct(char *line)
116 {
117  char threadid[30];
118  ssize_t r;
119 
120  /* spying disabled */
121  if (Log_fd < 0)
122  return;
123 
124  snprintf(threadid, sizeof threadid, "%lX@", 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);
129  (void)r;
130  pthread_mutex_unlock(&Log_fd_mutex);
131 }
132 
133 static void spy_line(const char *fmt, ...)
134 {
135  va_list args;
136  char line[256];
137  int size;
138  char threadid[30];
139  ssize_t r;
140 
141  /* spying disabled */
142  if (Log_fd < 0)
143  return;
144 
145  va_start(args, fmt);
146  size = vsnprintf(line, sizeof line, fmt, args);
147  va_end(args);
148  if ((size_t)size >= sizeof line)
149  {
150  printf("libpcsc-spy: Buffer is too small!\n");
151  return;
152  }
153  snprintf(threadid, sizeof threadid, "%lX@", 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);
158  (void)r;
159  pthread_mutex_unlock(&Log_fd_mutex);
160 }
161 
162 static void spy_enter(const char *fname)
163 {
164  struct timeval profile_time;
165 
166  gettimeofday(&profile_time, NULL);
167  spy_line(">|%ld|%ld|%s", profile_time.tv_sec, profile_time.tv_usec, fname);
168 }
169 
170 static void spy_quit(const char *fname, LONG rv)
171 {
172  struct timeval profile_time;
173 
174  gettimeofday(&profile_time, NULL);
175  spy_line("<|%ld|%ld|%s|0x%08lX", profile_time.tv_sec,
176  profile_time.tv_usec, fname, rv);
177 }
178 
179 #define Enter() spy_enter(__FUNCTION__)
180 #define Quit() spy_quit(__FUNCTION__, rv)
181 
182 static void spy_long(long arg)
183 {
184  spy_line("0x%08lX", arg);
185 }
186 
187 static void spy_ptr_long(LONG *arg)
188 {
189  if (arg)
190  spy_line("0x%08lX", *arg);
191  else
192  spy_line("NULL");
193 }
194 
195 static void spy_ptr_ulong(ULONG *arg)
196 {
197  if (arg)
198  spy_line("0x%08lX", *arg);
199  else
200  spy_line("NULL");
201 }
202 
203 static void spy_pvoid(const void *ptr)
204 {
205  spy_line("%p", ptr);
206 }
207 
208 static void spy_buffer(const unsigned char *buffer, size_t length)
209 {
210  spy_long(length);
211 
212  if (NULL == buffer)
213  spy_line("NULL");
214  else
215  {
216  /* "78 79 7A" */
217  char log_buffer[length * 3 +1], *p;
218  size_t i;
219 
220  p = log_buffer;
221  log_buffer[0] = '\0';
222  for (i=0; i<length; i++)
223  {
224  snprintf(p, 4, "%02X ", buffer[i]);
225  p += 3;
226  }
227  *p = '\0';
228 
229  spy_line_direct(log_buffer);
230  }
231 }
232 
233 static void spy_str(const char *str)
234 {
235  spy_line("%s", str);
236 }
237 
238 static void spy_n_str(const char *str, ULONG *len, int autoallocate)
239 {
240  spy_ptr_ulong(len);
241  if (NULL == len)
242  {
243  spy_line("\"\"");
244  }
245  else
246  {
247  if (NULL == str)
248  {
249  spy_line("NULL");
250  }
251  else
252  {
253  const char *s = str;
254  unsigned int length = 0;
255 
256  if (autoallocate)
257  s = *(char **)str;
258 
259  do
260  {
261  spy_line("%s", s);
262  length += strlen(s)+1;
263  s += strlen(s)+1;
264  } while(length < *len);
265  }
266  }
267 }
268 
269 
270 static void spy_readerstate(SCARD_READERSTATE * rgReaderStates, int cReaders)
271 {
272  int i;
273 
274  for (i=0; i<cReaders; i++)
275  {
276  spy_str(rgReaderStates[i].szReader);
277  spy_long(rgReaderStates[i].dwCurrentState);
278  spy_long(rgReaderStates[i].dwEventState);
279  if (rgReaderStates[i].cbAtr <= MAX_ATR_SIZE)
280  spy_buffer(rgReaderStates[i].rgbAtr, rgReaderStates[i].cbAtr);
281  else
282  spy_buffer(NULL, rgReaderStates[i].cbAtr);
283  }
284 }
285 
286 static LONG load_lib(void)
287 {
288 
289 #define LIBPCSC "libpcsclite_real.so.1"
290 
291  const char *lib;
292 
293  lib = SYS_GetEnv("LIBPCSCLITE_SPY_DELEGATE");
294  if (NULL == lib)
295  lib = LIBPCSC;
296 
297  /* load the normal library */
298  Lib_handle = dlopen(lib, RTLD_LAZY);
299  if (NULL == Lib_handle)
300  {
301  log_line("loading \"%s\" failed: %s", lib, dlerror());
302  return SCARD_F_INTERNAL_ERROR;
303  }
304 
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)
306 
307  if (SCardEstablishContext == dlsym(Lib_handle, "SCardEstablishContext"))
308  {
309  log_line("Symbols dlsym error");
310  return SCARD_F_INTERNAL_ERROR;
311  }
312 
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);
327  /* Mac OS X do not have SCardFreeMemory() */
328  if (dlsym(Lib_handle, "SCardFreeMemory"))
329  get_symbol(SCardFreeMemory);
330  get_symbol(SCardCancel);
331  get_symbol(SCardGetAttrib);
332  get_symbol(SCardSetAttrib);
333 
334  return SCARD_S_SUCCESS;
335 }
336 
337 
338 /* exported functions */
339 PCSC_API LONG SCardEstablishContext(DWORD dwScope,
340  LPCVOID pvReserved1,
341  LPCVOID pvReserved2,
342  LPSCARDCONTEXT phContext)
343 {
344  LONG rv;
345  static int init = 0;
346 
347  if (!init)
348  {
349  const char *home;
350  char log_pipe[128];
351 
352  init = 1;
353 
354  /* load the real library */
355  rv = load_lib();
356  if (rv != SCARD_S_SUCCESS)
357  return rv;
358 
359  /* check if we can log */
360  home = SYS_GetEnv("HOME");
361  if (NULL == home)
362  home = "/tmp";
363 
364  snprintf(log_pipe, sizeof log_pipe, "%s/pcsc-spy", home);
365  Log_fd = open(log_pipe, O_WRONLY);
366  if (Log_fd < 0)
367  {
368  log_line("open %s failed: %s", log_pipe, strerror(errno));
369  }
370  }
371 
372  Enter();
373  spy_long(dwScope);
374  rv = spy.SCardEstablishContext(dwScope, pvReserved1, pvReserved2,
375  phContext);
376  spy_ptr_long(phContext);
377  Quit();
378  return rv;
379 }
380 
381 PCSC_API LONG SCardReleaseContext(SCARDCONTEXT hContext)
382 {
383  LONG rv;
384 
385  Enter();
386  spy_long(hContext);
387  rv = spy.SCardReleaseContext(hContext);
388  Quit();
389  return rv;
390 }
391 
392 PCSC_API LONG SCardIsValidContext(SCARDCONTEXT hContext)
393 {
394  LONG rv;
395 
396  Enter();
397  spy_long(hContext);
398  rv = spy.SCardIsValidContext(hContext);
399  Quit();
400  return rv;
401 }
402 
403 PCSC_API LONG SCardConnect(SCARDCONTEXT hContext,
404  LPCSTR szReader,
405  DWORD dwShareMode,
406  DWORD dwPreferredProtocols,
407  LPSCARDHANDLE phCard,
408  LPDWORD pdwActiveProtocol)
409 {
410  LONG rv;
411 
412  Enter();
413  spy_long(hContext);
414  spy_str(szReader);
415  spy_long(dwShareMode);
416  spy_long(dwPreferredProtocols);
417  spy_ptr_long(phCard);
418  spy_ptr_ulong(pdwActiveProtocol);
419  rv = spy.SCardConnect(hContext, szReader, dwShareMode,
420  dwPreferredProtocols, phCard, pdwActiveProtocol);
421  spy_ptr_long(phCard);
422  spy_ptr_ulong(pdwActiveProtocol);
423  Quit();
424  return rv;
425 }
426 
427 PCSC_API LONG SCardReconnect(SCARDHANDLE hCard,
428  DWORD dwShareMode,
429  DWORD dwPreferredProtocols,
430  DWORD dwInitialization,
431  LPDWORD pdwActiveProtocol)
432 {
433  LONG rv;
434 
435  Enter();
436  spy_long(hCard);
437  spy_long(dwShareMode);
438  spy_long(dwPreferredProtocols);
439  spy_long(dwInitialization);
440  rv = spy.SCardReconnect(hCard, dwShareMode, dwPreferredProtocols,
441  dwInitialization, pdwActiveProtocol);
442  spy_ptr_ulong(pdwActiveProtocol);
443  Quit();
444  return rv;
445 }
446 
447 PCSC_API LONG SCardDisconnect(SCARDHANDLE hCard,
448  DWORD dwDisposition)
449 {
450  LONG rv;
451 
452  Enter();
453  spy_long(hCard);
454  spy_long(dwDisposition);
455  rv = spy.SCardDisconnect(hCard, dwDisposition);
456  Quit();
457  return rv;
458 }
459 
460 PCSC_API LONG SCardBeginTransaction(SCARDHANDLE hCard)
461 {
462  LONG rv;
463 
464  Enter();
465  spy_long(hCard);
466  rv = spy.SCardBeginTransaction(hCard);
467  Quit();
468  return rv;
469 }
470 
471 PCSC_API LONG SCardEndTransaction(SCARDHANDLE hCard,
472  DWORD dwDisposition)
473 {
474  LONG rv;
475 
476  Enter();
477  spy_long(hCard);
478  spy_long(dwDisposition);
479  rv = spy.SCardEndTransaction(hCard, dwDisposition);
480  Quit();
481  return rv;
482 }
483 
484 PCSC_API LONG SCardStatus(SCARDHANDLE hCard,
485  LPSTR mszReaderName,
486  LPDWORD pcchReaderLen,
487  LPDWORD pdwState,
488  LPDWORD pdwProtocol,
489  LPBYTE pbAtr,
490  LPDWORD pcbAtrLen)
491 {
492  LONG rv;
493  int autoallocate_ReaderName = 0, autoallocate_Atr = 0;
494 
495  if (pcchReaderLen)
496  autoallocate_ReaderName = *pcchReaderLen == SCARD_AUTOALLOCATE;
497 
498  if (pcbAtrLen)
499  autoallocate_Atr = *pcbAtrLen == SCARD_AUTOALLOCATE;
500 
501  Enter();
502  spy_long(hCard);
503  spy_ptr_ulong(pcchReaderLen);
504  spy_ptr_ulong(pcbAtrLen);
505  rv = spy.SCardStatus(hCard, mszReaderName, pcchReaderLen, pdwState,
506  pdwProtocol, pbAtr, pcbAtrLen);
507  spy_n_str(mszReaderName, pcchReaderLen, autoallocate_ReaderName);
508  spy_ptr_ulong(pdwState);
509  spy_ptr_ulong(pdwProtocol);
510  if (NULL == pcbAtrLen)
511  spy_line("NULL");
512  else
513  {
514  LPBYTE buffer;
515 
516  if (autoallocate_Atr)
517  buffer = *(LPBYTE *)pbAtr;
518  else
519  buffer = pbAtr;
520 
521  spy_buffer(buffer, *pcbAtrLen);
522  }
523  Quit();
524  return rv;
525 }
526 
527 PCSC_API LONG SCardGetStatusChange(SCARDCONTEXT hContext,
528  DWORD dwTimeout,
529  SCARD_READERSTATE *rgReaderStates,
530  DWORD cReaders)
531 {
532  LONG rv;
533 
534  Enter();
535  spy_long(hContext);
536  spy_long(dwTimeout);
537  spy_long(cReaders);
538  spy_readerstate(rgReaderStates, cReaders);
539  rv = spy.SCardGetStatusChange(hContext, dwTimeout, rgReaderStates,
540  cReaders);
541  spy_readerstate(rgReaderStates, cReaders);
542  Quit();
543  return rv;
544 }
545 
546 PCSC_API LONG SCardControl(SCARDHANDLE hCard,
547  DWORD dwControlCode,
548  LPCVOID pbSendBuffer,
549  DWORD cbSendLength,
550  LPVOID pbRecvBuffer,
551  DWORD cbRecvLength,
552  LPDWORD lpBytesReturned)
553 {
554  LONG rv;
555 
556  Enter();
557  spy_long(hCard);
558  spy_long(dwControlCode);
559  spy_buffer(pbSendBuffer, cbSendLength);
560  rv = spy.SCardControl(hCard, dwControlCode, pbSendBuffer, cbSendLength,
561  pbRecvBuffer, cbRecvLength, lpBytesReturned);
562  if (lpBytesReturned)
563  {
564  if (SCARD_S_SUCCESS == rv)
565  spy_buffer(pbRecvBuffer, *lpBytesReturned);
566  else
567  spy_buffer(NULL, *lpBytesReturned);
568  }
569  else
570  spy_buffer(NULL, 0);
571  Quit();
572  return rv;
573 }
574 
575 PCSC_API LONG SCardTransmit(SCARDHANDLE hCard,
576  const SCARD_IO_REQUEST *pioSendPci,
577  LPCBYTE pbSendBuffer,
578  DWORD cbSendLength,
579  SCARD_IO_REQUEST *pioRecvPci,
580  LPBYTE pbRecvBuffer,
581  LPDWORD pcbRecvLength)
582 {
583  LONG rv;
584 
585  Enter();
586  spy_long(hCard);
587  if (pioSendPci)
588  {
589  spy_long(pioSendPci->dwProtocol);
590  spy_long(pioSendPci->cbPciLength);
591  }
592  else
593  {
594  spy_long(-1);
595  spy_long(-1);
596  }
597  spy_buffer(pbSendBuffer, cbSendLength);
598  rv = spy.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength,
599  pioRecvPci, pbRecvBuffer, pcbRecvLength);
600  if (pioRecvPci)
601  {
602  spy_long(pioRecvPci->dwProtocol);
603  spy_long(pioRecvPci->cbPciLength);
604  }
605  else
606  {
607  spy_long(-1);
608  spy_long(-1);
609  }
610  if (pcbRecvLength)
611  {
612  if (SCARD_S_SUCCESS == rv)
613  spy_buffer(pbRecvBuffer, *pcbRecvLength);
614  else
615  spy_buffer(NULL, *pcbRecvLength);
616  }
617  else
618  spy_buffer(NULL, 0);
619  Quit();
620  return rv;
621 }
622 
623 PCSC_API LONG SCardListReaderGroups(SCARDCONTEXT hContext,
624  LPSTR mszGroups,
625  LPDWORD pcchGroups)
626 {
627  LONG rv;
628  int autoallocate = 0;
629 
630  if (pcchGroups)
631  autoallocate = *pcchGroups == SCARD_AUTOALLOCATE;
632 
633  Enter();
634  spy_long(hContext);
635  spy_ptr_ulong(pcchGroups);
636  rv = spy.SCardListReaderGroups(hContext, mszGroups, pcchGroups);
637  if (SCARD_S_SUCCESS == rv)
638  spy_n_str(mszGroups, pcchGroups, autoallocate);
639  else
640  spy_n_str(NULL, pcchGroups, 0);
641  Quit();
642  return rv;
643 }
644 
645 PCSC_API LONG SCardListReaders(SCARDCONTEXT hContext,
646  LPCSTR mszGroups,
647  LPSTR mszReaders,
648  LPDWORD pcchReaders)
649 {
650  LONG rv;
651  int autoallocate = 0;
652 
653  if (pcchReaders)
654  autoallocate = *pcchReaders == SCARD_AUTOALLOCATE;
655 
656  Enter();
657  spy_long(hContext);
658  spy_str(mszGroups);
659  rv = spy.SCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
660  if (SCARD_S_SUCCESS == rv)
661  spy_n_str(mszReaders, pcchReaders, autoallocate);
662  else
663  spy_n_str(NULL, pcchReaders, 0);
664  Quit();
665  return rv;
666 }
667 
668 PCSC_API LONG SCardFreeMemory(SCARDCONTEXT hContext,
669  LPCVOID pvMem)
670 {
671  LONG rv;
672 
673  Enter();
674  spy_long(hContext);
675  spy_pvoid(pvMem);
676  rv = spy.SCardFreeMemory(hContext, pvMem);
677  Quit();
678  return rv;
679 }
680 
681 PCSC_API LONG SCardCancel(SCARDCONTEXT hContext)
682 {
683  LONG rv;
684 
685  Enter();
686  spy_long(hContext);
687  rv = spy.SCardCancel(hContext);
688  Quit();
689  return rv;
690 }
691 
692 PCSC_API LONG SCardGetAttrib(SCARDHANDLE hCard,
693  DWORD dwAttrId,
694  LPBYTE pbAttr,
695  LPDWORD pcbAttrLen)
696 {
697  LONG rv;
698  int autoallocate = 0;
699 
700  if (pcbAttrLen)
701  autoallocate = *pcbAttrLen == SCARD_AUTOALLOCATE;
702 
703  Enter();
704  spy_long(hCard);
705  spy_long(dwAttrId);
706  rv = spy.SCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen);
707  if (NULL == pcbAttrLen)
708  spy_buffer(NULL, 0);
709  else
710  if (rv != SCARD_S_SUCCESS)
711  spy_buffer(NULL, *pcbAttrLen);
712  else
713  {
714  LPBYTE buffer;
715 
716  if (autoallocate)
717  buffer = *(LPBYTE *)pbAttr;
718  else
719  buffer = pbAttr;
720 
721  spy_buffer(buffer, *pcbAttrLen);
722  }
723  Quit();
724  return rv;
725 }
726 
727 PCSC_API LONG SCardSetAttrib(SCARDHANDLE hCard,
728  DWORD dwAttrId,
729  LPCBYTE pbAttr,
730  DWORD cbAttrLen)
731 {
732  LONG rv;
733 
734  Enter();
735  spy_long(hCard);
736  spy_long(dwAttrId);
737  spy_buffer(pbAttr, cbAttrLen);
738  rv = spy.SCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen);
739  Quit();
740  return rv;
741 }
742 
SCARD_S_SUCCESS
#define SCARD_S_SUCCESS
No error was encountered.
Definition: pcsclite.h:107
SYS_GetEnv
const char * SYS_GetEnv(const char *name)
(More) secure version of getenv(3)
Definition: sys_unix.c:168
SCARD_IO_REQUEST::cbPciLength
unsigned long cbPciLength
Protocol Control Inf Length.
Definition: pcsclite.h:82
sys_generic.h
This handles abstract system level calls.
SCARD_READERSTATE
Definition: pcsclite.h:68
SCARD_AUTOALLOCATE
#define SCARD_AUTOALLOCATE
see SCardFreeMemory()
Definition: pcsclite.h:234
SCARDHANDLE
LONG SCARDHANDLE
hCard returned by SCardConnect()
Definition: pcsclite.h:55
MAX_ATR_SIZE
#define MAX_ATR_SIZE
Maximum ATR size.
Definition: pcsclite.h:59
SCARD_IO_REQUEST::dwProtocol
unsigned long dwProtocol
Protocol identifier.
Definition: pcsclite.h:81
winscard.h
This handles smart card reader communications.
SCARDCONTEXT
LONG SCARDCONTEXT
hContext returned by SCardEstablishContext()
Definition: pcsclite.h:52
SCARD_IO_REQUEST
Protocol Control Information (PCI)
Definition: pcsclite.h:80
SCARD_F_INTERNAL_ERROR
#define SCARD_F_INTERNAL_ERROR
An internal consistency check failed.
Definition: pcsclite.h:109