pcsc-lite  1.8.10
winscard.c
Go to the documentation of this file.
1 /*
2  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
3  *
4  * Copyright (C) 1999-2004
5  * David Corcoran <corcoran@linuxnet.com>
6  * Copyright (C) 2002-2011
7  * Ludovic Rousseau <ludovic.rousseau@free.fr>
8  *
9  * $Id: winscard.c 6748 2013-09-10 18:28:44Z rousseau $
10  */
11 
82 #include "config.h"
83 #include <stdlib.h>
84 #include <sys/time.h>
85 #include <string.h>
86 #include <pthread.h>
87 
88 #include "pcscd.h"
89 #include "winscard.h"
90 #include "ifdhandler.h"
91 #include "debuglog.h"
92 #include "readerfactory.h"
93 #include "prothandler.h"
94 #include "ifdwrapper.h"
95 #include "atrhandler.h"
96 #include "sys_generic.h"
97 #include "eventhandler.h"
98 #include "utils.h"
99 #include "reader.h"
100 #include "strlcpycat.h"
101 
102 #undef DO_PROFILE
103 #ifdef DO_PROFILE
104 
105 #ifndef FALSE
106 #define FALSE 0
107 #define TRUE 1
108 #endif
109 
110 #define PROFILE_FILE "/tmp/pcscd_profile"
111 #include <stdio.h>
112 #include <sys/time.h>
113 #include <errno.h>
114 #include <unistd.h>
115 
116 struct timeval profile_time_start;
117 FILE *fd;
118 char profile_tty;
119 
120 #define PROFILE_START profile_start(__FUNCTION__);
121 #define PROFILE_END profile_end(__FUNCTION__, __LINE__);
122 
123 static void profile_start(const char *f)
124 {
125  static char initialized = FALSE;
126 
127  if (!initialized)
128  {
129  initialized = TRUE;
130  fd = fopen(PROFILE_FILE, "a+");
131  if (NULL == fd)
132  {
133  fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n",
134  PROFILE_FILE, strerror(errno));
135  exit(-1);
136  }
137  fprintf(fd, "\nStart a new profile\n");
138  fflush(fd);
139 
140  if (isatty(fileno(stderr)))
141  profile_tty = TRUE;
142  else
143  profile_tty = FALSE;
144  }
145 
146  gettimeofday(&profile_time_start, NULL);
147 } /* profile_start */
148 
149 
150 static void profile_end(const char *f, int line)
151 {
152  struct timeval profile_time_end;
153  long d;
154 
155  gettimeofday(&profile_time_end, NULL);
156  d = time_sub(&profile_time_end, &profile_time_start);
157 
158  if (profile_tty)
159  fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m (%d)\n", f, d,
160  line);
161  fprintf(fd, "%s %ld\n", f, d);
162  fflush(fd);
163 } /* profile_end */
164 
165 #else
166 #define PROFILE_START
167 #define PROFILE_END
168 #endif
169 
171 #define SCARD_PROTOCOL_ANY_OLD 0x1000
172 
173 LONG SCardEstablishContext(DWORD dwScope, /*@unused@*/ LPCVOID pvReserved1,
174  /*@unused@*/ LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
175 {
176  (void)pvReserved1;
177  (void)pvReserved2;
178 
179  if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
180  dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
181  {
182  *phContext = 0;
183  return SCARD_E_INVALID_VALUE;
184  }
185 
186  /*
187  * Unique identifier for this server so that it can uniquely be
188  * identified by clients and distinguished from others
189  */
190 
191  *phContext = SYS_RandomInt(0, -1);
192 
193  Log2(PCSC_LOG_DEBUG, "Establishing Context: 0x%lX", *phContext);
194 
195  return SCARD_S_SUCCESS;
196 }
197 
198 LONG SCardReleaseContext(SCARDCONTEXT hContext)
199 {
200  /*
201  * Nothing to do here RPC layer will handle this
202  */
203 
204  Log2(PCSC_LOG_DEBUG, "Releasing Context: 0x%lX", hContext);
205 
206  return SCARD_S_SUCCESS;
207 }
208 
209 LONG SCardConnect(/*@unused@*/ SCARDCONTEXT hContext, LPCSTR szReader,
210  DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
211  LPDWORD pdwActiveProtocol)
212 {
213  LONG rv;
214  READER_CONTEXT * rContext = NULL;
215  uint32_t readerState;
216 
217  (void)hContext;
218  PROFILE_START
219 
220  *phCard = 0;
221 
222  if ((dwShareMode != SCARD_SHARE_DIRECT) &&
223  !(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
224  !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
225  !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
226  !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
227  return SCARD_E_PROTO_MISMATCH;
228 
229  if (dwShareMode != SCARD_SHARE_EXCLUSIVE &&
230  dwShareMode != SCARD_SHARE_SHARED &&
231  dwShareMode != SCARD_SHARE_DIRECT)
232  return SCARD_E_INVALID_VALUE;
233 
234  Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %ld",
235  szReader, dwPreferredProtocols);
236 
237  rv = RFReaderInfo((LPSTR) szReader, &rContext);
238  if (rv != SCARD_S_SUCCESS)
239  {
240  Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader);
241  return rv;
242  }
243 
244  /*
245  * Make sure the reader is working properly
246  */
247  rv = RFCheckReaderStatus(rContext);
248  if (rv != SCARD_S_SUCCESS)
249  goto exit;
250 
251  /*******************************************
252  *
253  * This section checks for simple errors
254  *
255  *******************************************/
256 
257  /*
258  * Connect if not exclusive mode
259  */
261  {
262  Log1(PCSC_LOG_ERROR, "Error Reader Exclusive");
264  goto exit;
265  }
266 
267  /*
268  * wait until a possible transaction is finished
269  */
270  if (rContext->hLockId != 0)
271  {
272  Log1(PCSC_LOG_INFO, "Waiting for release of lock");
273  while (rContext->hLockId != 0)
275  Log1(PCSC_LOG_INFO, "Lock released");
276  }
277 
278  /*******************************************
279  *
280  * This section tries to determine the
281  * presence of a card or not
282  *
283  *******************************************/
284  readerState = rContext->readerState->readerState;
285 
286  if (dwShareMode != SCARD_SHARE_DIRECT)
287  {
288  if (!(readerState & SCARD_PRESENT))
289  {
290  Log1(PCSC_LOG_DEBUG, "Card Not Inserted");
292  goto exit;
293  }
294 
295  /* Power on (again) the card if needed */
296  (void)pthread_mutex_lock(&rContext->powerState_lock);
297  if (POWER_STATE_UNPOWERED == rContext->powerState)
298  {
299  DWORD dwAtrLen;
300 
301  dwAtrLen = sizeof(rContext->readerState->cardAtr);
302  rv = IFDPowerICC(rContext, IFD_POWER_UP,
303  rContext->readerState->cardAtr, &dwAtrLen);
304  rContext->readerState->cardAtrLength = dwAtrLen;
305 
306  if (rv == IFD_SUCCESS)
307  {
308  readerState = SCARD_PRESENT | SCARD_POWERED | SCARD_NEGOTIABLE;
309 
310  Log1(PCSC_LOG_DEBUG, "power up complete.");
311  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
312  rContext->readerState->cardAtr,
313  rContext->readerState->cardAtrLength);
314  }
315  else
316  Log3(PCSC_LOG_ERROR, "Error powering up card: %ld 0x%04lX",
317  rv, rv);
318  }
319 
320  if (! (readerState & SCARD_POWERED))
321  {
322  Log1(PCSC_LOG_ERROR, "Card Not Powered");
323  (void)pthread_mutex_unlock(&rContext->powerState_lock);
325  goto exit;
326  }
327 
328  /* the card is now in use */
329  rContext->powerState = POWER_STATE_INUSE;
330  Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_INUSE");
331  (void)pthread_mutex_unlock(&rContext->powerState_lock);
332  }
333 
334  /*******************************************
335  *
336  * This section tries to decode the ATR
337  * and set up which protocol to use
338  *
339  *******************************************/
340  if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
342  else
343  {
344  if (dwShareMode != SCARD_SHARE_DIRECT)
345  {
346  /* lock here instead in IFDSetPTS() to lock up to
347  * setting rContext->readerState->cardProtocol */
348  (void)pthread_mutex_lock(rContext->mMutex);
349 
350  /* the protocol is not yet set (no PPS yet) */
352  {
353  int availableProtocols, defaultProtocol;
354  int ret;
355 
356  ATRDecodeAtr(&availableProtocols, &defaultProtocol,
357  rContext->readerState->cardAtr,
358  rContext->readerState->cardAtrLength);
359 
360  /* If it is set to ANY let it do any of the protocols */
361  if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
362  dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
363 
364  ret = PHSetProtocol(rContext, dwPreferredProtocols,
365  availableProtocols, defaultProtocol);
366 
367  /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error */
368  if (SET_PROTOCOL_PPS_FAILED == ret)
369  {
370  (void)pthread_mutex_unlock(rContext->mMutex);
372  goto exit;
373  }
374 
375  if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
376  {
377  (void)pthread_mutex_unlock(rContext->mMutex);
379  goto exit;
380  }
381 
382  /* use negotiated protocol */
383  rContext->readerState->cardProtocol = ret;
384 
385  (void)pthread_mutex_unlock(rContext->mMutex);
386  }
387  else
388  {
389  (void)pthread_mutex_unlock(rContext->mMutex);
390 
391  if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
392  {
394  goto exit;
395  }
396  }
397  }
398  }
399 
400  *pdwActiveProtocol = rContext->readerState->cardProtocol;
401 
402  if (dwShareMode != SCARD_SHARE_DIRECT)
403  {
404  switch (*pdwActiveProtocol)
405  {
406  case SCARD_PROTOCOL_T0:
407  case SCARD_PROTOCOL_T1:
408  Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
409  (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
410  break;
411 
412  case SCARD_PROTOCOL_RAW:
413  Log1(PCSC_LOG_DEBUG, "Active Protocol: RAW");
414  break;
415 
416  default:
417  Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %ld",
418  *pdwActiveProtocol);
419  }
420  }
421  else
422  Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected");
423 
424  /*
425  * Prepare the SCARDHANDLE identity
426  */
427  *phCard = RFCreateReaderHandle(rContext);
428 
429  Log2(PCSC_LOG_DEBUG, "hCard Identity: %lx", *phCard);
430 
431  /*******************************************
432  *
433  * This section tries to set up the
434  * exclusivity modes. -1 is exclusive
435  *
436  *******************************************/
437 
438  if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
439  {
440  if (rContext->contexts == PCSCLITE_SHARING_NO_CONTEXT)
441  {
443  (void)RFLockSharing(*phCard, rContext);
444  }
445  else
446  {
447  (void)RFDestroyReaderHandle(*phCard);
448  *phCard = 0;
450  goto exit;
451  }
452  }
453  else
454  {
455  /*
456  * Add a connection to the context stack
457  */
458  rContext->contexts += 1;
459  }
460 
461  /*
462  * Add this handle to the handle list
463  */
464  rv = RFAddReaderHandle(rContext, *phCard);
465 
466  if (rv != SCARD_S_SUCCESS)
467  {
468  /*
469  * Clean up - there is no more room
470  */
471  (void)RFDestroyReaderHandle(*phCard);
474  else
475  if (rContext->contexts > PCSCLITE_SHARING_NO_CONTEXT)
476  rContext->contexts -= 1;
477 
478  *phCard = 0;
479 
481  goto exit;
482  }
483 
484  /*
485  * Propagate new state to reader state
486  */
487  rContext->readerState->readerSharing = rContext->contexts;
488 
489 exit:
490  UNREF_READER(rContext)
491 
492  PROFILE_END
493 
494  return rv;
495 }
496 
497 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
498  DWORD dwPreferredProtocols, DWORD dwInitialization,
499  LPDWORD pdwActiveProtocol)
500 {
501  LONG rv;
502  READER_CONTEXT * rContext = NULL;
503 
504  Log1(PCSC_LOG_DEBUG, "Attempting reconnect to token.");
505 
506  if (hCard == 0)
507  return SCARD_E_INVALID_HANDLE;
508 
509  /*
510  * Handle the dwInitialization
511  */
512  if (dwInitialization != SCARD_LEAVE_CARD &&
513  dwInitialization != SCARD_RESET_CARD &&
514  dwInitialization != SCARD_UNPOWER_CARD)
515  return SCARD_E_INVALID_VALUE;
516 
517  if (dwShareMode != SCARD_SHARE_SHARED &&
518  dwShareMode != SCARD_SHARE_EXCLUSIVE &&
519  dwShareMode != SCARD_SHARE_DIRECT)
520  return SCARD_E_INVALID_VALUE;
521 
522  if ((dwShareMode != SCARD_SHARE_DIRECT) &&
523  !(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
524  !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
525  !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
526  !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
527  return SCARD_E_PROTO_MISMATCH;
528 
529  /* get rContext corresponding to hCard */
530  rv = RFReaderInfoById(hCard, &rContext);
531  if (rv != SCARD_S_SUCCESS)
532  return rv;
533 
534  /*
535  * Make sure the reader is working properly
536  */
537  rv = RFCheckReaderStatus(rContext);
538  if (rv != SCARD_S_SUCCESS)
539  goto exit;
540 
541  /*
542  * Make sure no one has a lock on this reader
543  */
544  rv = RFCheckSharing(hCard, rContext);
545  if (rv != SCARD_S_SUCCESS)
546  goto exit;
547 
548  if (dwInitialization == SCARD_RESET_CARD ||
549  dwInitialization == SCARD_UNPOWER_CARD)
550  {
551  DWORD dwAtrLen;
552 
553  /*
554  * Notify the card has been reset
555  */
556  (void)RFSetReaderEventState(rContext, SCARD_RESET);
557 
558  /*
559  * Currently pcsc-lite keeps the card powered constantly
560  */
561  dwAtrLen = sizeof(rContext->readerState->cardAtr);
562  if (SCARD_RESET_CARD == dwInitialization)
563  rv = IFDPowerICC(rContext, IFD_RESET,
564  rContext->readerState->cardAtr, &dwAtrLen);
565  else
566  {
567  IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
568  rv = IFDPowerICC(rContext, IFD_POWER_UP,
569  rContext->readerState->cardAtr, &dwAtrLen);
570  }
571 
572  /* the protocol is unset after a power on */
574 
575  /*
576  * Set up the status bit masks on readerState
577  */
578  if (rv == SCARD_S_SUCCESS)
579  {
580  rContext->readerState->cardAtrLength = dwAtrLen;
581  rContext->readerState->readerState =
583 
584  Log1(PCSC_LOG_DEBUG, "Reset complete.");
585  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
586  rContext->readerState->cardAtr,
587  rContext->readerState->cardAtrLength);
588  }
589  else
590  {
591  rContext->readerState->cardAtrLength = 0;
592  Log1(PCSC_LOG_ERROR, "Error resetting card.");
593 
594  if (rv == SCARD_W_REMOVED_CARD)
595  {
596  rContext->readerState->readerState = SCARD_ABSENT;
598  goto exit;
599  }
600  else
601  {
602  rContext->readerState->readerState =
605  goto exit;
606  }
607  }
608  }
609  else
610  if (dwInitialization == SCARD_LEAVE_CARD)
611  {
612  uint32_t readerState = rContext->readerState->readerState;
613 
614  if (readerState & SCARD_ABSENT)
615  {
617  goto exit;
618  }
619 
620  if ((readerState & SCARD_PRESENT)
621  && (readerState & SCARD_SWALLOWED))
622  {
624  goto exit;
625  }
626  }
627 
628  /*******************************************
629  *
630  * This section tries to decode the ATR
631  * and set up which protocol to use
632  *
633  *******************************************/
634  if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
636  else
637  {
638  if (dwShareMode != SCARD_SHARE_DIRECT)
639  {
640  /* lock here instead in IFDSetPTS() to lock up to
641  * setting rContext->readerState->cardProtocol */
642  (void)pthread_mutex_lock(rContext->mMutex);
643 
644  /* the protocol is not yet set (no PPS yet) */
646  {
647  int availableProtocols, defaultProtocol;
648  int ret;
649 
650  ATRDecodeAtr(&availableProtocols, &defaultProtocol,
651  rContext->readerState->cardAtr,
652  rContext->readerState->cardAtrLength);
653 
654  /* If it is set to ANY let it do any of the protocols */
655  if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
656  dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
657 
658  ret = PHSetProtocol(rContext, dwPreferredProtocols,
659  availableProtocols, defaultProtocol);
660 
661  /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error */
662  if (SET_PROTOCOL_PPS_FAILED == ret)
663  {
664  (void)pthread_mutex_unlock(rContext->mMutex);
666  goto exit;
667  }
668 
669  if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
670  {
671  (void)pthread_mutex_unlock(rContext->mMutex);
673  goto exit;
674  }
675 
676  /* use negotiated protocol */
677  rContext->readerState->cardProtocol = ret;
678 
679  (void)pthread_mutex_unlock(rContext->mMutex);
680  }
681  else
682  {
683  (void)pthread_mutex_unlock(rContext->mMutex);
684 
685  if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
686  {
688  goto exit;
689  }
690  }
691  }
692  }
693 
694  *pdwActiveProtocol = rContext->readerState->cardProtocol;
695 
696  if (dwShareMode != SCARD_SHARE_DIRECT)
697  {
698  switch (*pdwActiveProtocol)
699  {
700  case SCARD_PROTOCOL_T0:
701  case SCARD_PROTOCOL_T1:
702  Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
703  (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
704  break;
705 
706  case SCARD_PROTOCOL_RAW:
707  Log1(PCSC_LOG_DEBUG, "Active Protocol: RAW");
708  break;
709 
710  default:
711  Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %ld",
712  *pdwActiveProtocol);
713  }
714  }
715  else
716  Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected");
717 
718  if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
719  {
721  {
722  /*
723  * Do nothing - we are already exclusive
724  */
725  }
726  else
727  {
728  if (rContext->contexts == PCSCLITE_SHARING_LAST_CONTEXT)
729  {
731  (void)RFLockSharing(hCard, rContext);
732  }
733  else
734  {
736  goto exit;
737  }
738  }
739  }
740  else if (dwShareMode == SCARD_SHARE_SHARED)
741  {
743  {
744  /*
745  * Do nothing - in sharing mode already
746  */
747  }
748  else
749  {
750  /*
751  * We are in exclusive mode but want to share now
752  */
753  (void)RFUnlockSharing(hCard, rContext);
755  }
756  }
757  else if (dwShareMode == SCARD_SHARE_DIRECT)
758  {
760  {
761  /*
762  * Do nothing - in sharing mode already
763  */
764  }
765  else
766  {
767  /*
768  * We are in exclusive mode but want to share now
769  */
770  (void)RFUnlockSharing(hCard, rContext);
772  }
773  }
774  else
775  {
777  goto exit;
778  }
779 
780  /*
781  * Clear a previous event to the application
782  */
783  (void)RFClearReaderEventState(rContext, hCard);
784 
785  /*
786  * Propagate new state to reader state
787  */
788  rContext->readerState->readerSharing = rContext->contexts;
789 
790  rv = SCARD_S_SUCCESS;
791 
792 exit:
793  UNREF_READER(rContext)
794 
795  return rv;
796 }
797 
798 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
799 {
800  LONG rv;
801  READER_CONTEXT * rContext = NULL;
802 
803  if (hCard == 0)
804  return SCARD_E_INVALID_HANDLE;
805 
806  if ((dwDisposition != SCARD_LEAVE_CARD)
807  && (dwDisposition != SCARD_UNPOWER_CARD)
808  && (dwDisposition != SCARD_RESET_CARD)
809  && (dwDisposition != SCARD_EJECT_CARD))
810  return SCARD_E_INVALID_VALUE;
811 
812  /* get rContext corresponding to hCard */
813  rv = RFReaderInfoById(hCard, &rContext);
814  if (rv != SCARD_S_SUCCESS)
815  return rv;
816 
817  /*
818  * wait until a possible transaction is finished
819  */
820  if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->hLockId != 0)
821  && (rContext->hLockId != hCard))
822  {
823  Log1(PCSC_LOG_INFO, "Waiting for release of lock");
824  while (rContext->hLockId != 0)
826  Log1(PCSC_LOG_INFO, "Lock released");
827  }
828 
829  /*
830  * Try to unlock any blocks on this context
831  *
832  * This may fail with SCARD_E_SHARING_VIOLATION if a transaction is
833  * on going on another card context and dwDisposition == SCARD_LEAVE_CARD.
834  * We should not stop.
835  */
836  rv = RFUnlockAllSharing(hCard, rContext);
837  if (rv != SCARD_S_SUCCESS)
838  {
839  if (rv != SCARD_E_SHARING_VIOLATION)
840  {
841  goto exit;
842  }
843  else
844  {
845  if (SCARD_LEAVE_CARD != dwDisposition)
846  goto exit;
847  }
848  }
849 
850  Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->contexts);
851  Log2(PCSC_LOG_DEBUG, "dwDisposition: %ld", dwDisposition);
852 
853  if (dwDisposition == SCARD_RESET_CARD ||
854  dwDisposition == SCARD_UNPOWER_CARD)
855  {
856  DWORD dwAtrLen;
857 
858  /*
859  * Notify the card has been reset
860  */
861  (void)RFSetReaderEventState(rContext, SCARD_RESET);
862 
863  /*
864  * Currently pcsc-lite keeps the card powered constantly
865  * unless DISABLE_AUTO_POWER_ON is defined
866  */
867  dwAtrLen = sizeof(rContext->readerState->cardAtr);
868  if (SCARD_RESET_CARD == dwDisposition)
869  rv = IFDPowerICC(rContext, IFD_RESET,
870  rContext->readerState->cardAtr, &dwAtrLen);
871  else
872  {
873  IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
874 
875 #ifdef DISABLE_AUTO_POWER_ON
876  rContext->powerState = POWER_STATE_UNPOWERED;
877  Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED");
878 #else
879  rv = IFDPowerICC(rContext, IFD_POWER_UP,
880  rContext->readerState->cardAtr, &dwAtrLen);
881 #endif
882  }
883 
884  /* the protocol is unset after a power on */
886 
887 #ifdef DISABLE_AUTO_POWER_ON
888  if (SCARD_UNPOWER_CARD == dwDisposition)
889  {
890  rContext->readerState->cardAtrLength = 0;
891  if (rv == SCARD_S_SUCCESS)
893  else
894  {
895  Log3(PCSC_LOG_ERROR, "Error powering down card: %d 0x%04X",
896  rv, rv);
897  if (rv == SCARD_W_REMOVED_CARD)
898  rContext->readerState->readerState = SCARD_ABSENT;
899  else
900  rContext->readerState->readerState =
902  }
903  Log1(PCSC_LOG_INFO, "Skip card power on");
904  }
905  else
906 #endif
907  {
908  /*
909  * Set up the status bit masks on readerState
910  */
911  if (rv == SCARD_S_SUCCESS)
912  {
913  rContext->readerState->cardAtrLength = dwAtrLen;
914  rContext->readerState->readerState =
916 
917  Log1(PCSC_LOG_DEBUG, "Reset complete.");
918  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
919  rContext->readerState->cardAtr,
920  rContext->readerState->cardAtrLength);
921  }
922  else
923  {
924  rContext->readerState->cardAtrLength = 0;
925  Log1(PCSC_LOG_ERROR, "Error resetting card.");
926 
927  if (rv == SCARD_W_REMOVED_CARD)
928  rContext->readerState->readerState = SCARD_ABSENT;
929  else
930  rContext->readerState->readerState =
932  }
933  }
934  }
935  else if (dwDisposition == SCARD_EJECT_CARD)
936  {
937  UCHAR controlBuffer[5];
938  UCHAR receiveBuffer[MAX_BUFFER_SIZE];
939  DWORD receiveLength;
940 
941  /*
942  * Set up the CTBCS command for Eject ICC
943  */
944  controlBuffer[0] = 0x20;
945  controlBuffer[1] = 0x15;
946  controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1;
947  controlBuffer[3] = 0x00;
948  controlBuffer[4] = 0x00;
949  receiveLength = 2;
950  rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
951  &receiveLength);
952 
953  if (rv == SCARD_S_SUCCESS)
954  {
955  if (receiveLength == 2 && receiveBuffer[0] == 0x90)
956  {
957  Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
958  /*
959  * Successful
960  */
961  }
962  else
963  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
964  }
965  else
966  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
967 
968  }
969  else if (dwDisposition == SCARD_LEAVE_CARD)
970  {
971  /*
972  * Do nothing
973  */
974  }
975 
976  /*
977  * Remove and destroy this handle
978  */
979  (void)RFRemoveReaderHandle(rContext, hCard);
980  (void)RFDestroyReaderHandle(hCard);
981 
982  /*
983  * For exclusive connection reset it to no connections
984  */
987  else
988  {
989  /*
990  * Remove a connection from the context stack
991  */
992  rContext->contexts -= 1;
993 
994  if (rContext->contexts < 0)
995  rContext->contexts = 0;
996  }
997 
998  if (PCSCLITE_SHARING_NO_CONTEXT == rContext->contexts)
999  {
1000  RESPONSECODE (*fct)(DWORD) = NULL;
1001  DWORD dwGetSize;
1002 
1003  (void)pthread_mutex_lock(&rContext->powerState_lock);
1004  /* Switch to POWER_STATE_GRACE_PERIOD unless the card was not
1005  * powered */
1006  if (POWER_STATE_POWERED <= rContext->powerState)
1007  {
1008 #ifdef DISABLE_AUTO_POWER_ON
1009  if (SCARD_RESET_CARD == dwDisposition)
1010  {
1012  Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_GRACE_PERIOD");
1013  }
1014 #else
1016  Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_GRACE_PERIOD");
1017 #endif
1018  }
1019 
1020  (void)pthread_mutex_unlock(&rContext->powerState_lock);
1021 
1022  /* ask to stop the "polling" thread so it can be restarted using
1023  * the correct timeout */
1024  dwGetSize = sizeof(fct);
1026  &dwGetSize, (PUCHAR)&fct);
1027 
1028  if ((IFD_SUCCESS == rv) && (dwGetSize == sizeof(fct)))
1029  {
1030  Log1(PCSC_LOG_INFO, "Stopping polling thread");
1031  fct(rContext->slot);
1032  }
1033  }
1034 
1035  /*
1036  * Propagate new state to reader state
1037  */
1038  rContext->readerState->readerSharing = rContext->contexts;
1039 
1040  rv = SCARD_S_SUCCESS;
1041 
1042 exit:
1043  UNREF_READER(rContext)
1044 
1045  return rv;
1046 }
1047 
1048 LONG SCardBeginTransaction(SCARDHANDLE hCard)
1049 {
1050  LONG rv;
1051  READER_CONTEXT * rContext;
1052 
1053  if (hCard == 0)
1054  return SCARD_E_INVALID_HANDLE;
1055 
1056  /* get rContext corresponding to hCard */
1057  rv = RFReaderInfoById(hCard, &rContext);
1058  if (rv != SCARD_S_SUCCESS)
1059  return rv;
1060 
1061  /*
1062  * Make sure the reader is working properly
1063  */
1064  rv = RFCheckReaderStatus(rContext);
1065  if (rv != SCARD_S_SUCCESS)
1066  goto exit;
1067 
1068  /*
1069  * Make sure some event has not occurred
1070  */
1071  rv = RFCheckReaderEventState(rContext, hCard);
1072  if (rv != SCARD_S_SUCCESS)
1073  goto exit;
1074 
1075  rv = RFLockSharing(hCard, rContext);
1076 
1077  /* if the transaction is not yet ready we sleep a bit so the client
1078  * do not retry immediately */
1079  if (SCARD_E_SHARING_VIOLATION == rv)
1081 
1082  Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv);
1083 
1084 exit:
1085  UNREF_READER(rContext)
1086 
1087  return rv;
1088 }
1089 
1090 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
1091 {
1092  LONG rv;
1093  LONG rv2;
1094  READER_CONTEXT * rContext = NULL;
1095 
1096  /*
1097  * Ignoring dwDisposition for now
1098  */
1099  if (hCard == 0)
1100  return SCARD_E_INVALID_HANDLE;
1101 
1102  if ((dwDisposition != SCARD_LEAVE_CARD)
1103  && (dwDisposition != SCARD_UNPOWER_CARD)
1104  && (dwDisposition != SCARD_RESET_CARD)
1105  && (dwDisposition != SCARD_EJECT_CARD))
1106  return SCARD_E_INVALID_VALUE;
1107 
1108  /* get rContext corresponding to hCard */
1109  rv = RFReaderInfoById(hCard, &rContext);
1110  if (rv != SCARD_S_SUCCESS)
1111  return rv;
1112 
1113  /*
1114  * Make sure some event has not occurred
1115  */
1116  rv = RFCheckReaderEventState(rContext, hCard);
1117  if (rv != SCARD_S_SUCCESS)
1118  goto exit;
1119 
1120  if (dwDisposition == SCARD_RESET_CARD ||
1121  dwDisposition == SCARD_UNPOWER_CARD)
1122  {
1123  DWORD dwAtrLen;
1124 
1125  /*
1126  * Currently pcsc-lite keeps the card always powered
1127  */
1128  dwAtrLen = sizeof(rContext->readerState->cardAtr);
1129  if (SCARD_RESET_CARD == dwDisposition)
1130  rv = IFDPowerICC(rContext, IFD_RESET,
1131  rContext->readerState->cardAtr, &dwAtrLen);
1132  else
1133  {
1134  IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
1135  rv = IFDPowerICC(rContext, IFD_POWER_UP,
1136  rContext->readerState->cardAtr, &dwAtrLen);
1137  }
1138 
1139  /* the protocol is unset after a power on */
1141 
1142  /*
1143  * Notify the card has been reset
1144  */
1145  (void)RFSetReaderEventState(rContext, SCARD_RESET);
1146 
1147  /*
1148  * Set up the status bit masks on readerState
1149  */
1150  if (rv == SCARD_S_SUCCESS)
1151  {
1152  rContext->readerState->cardAtrLength = dwAtrLen;
1153  rContext->readerState->readerState =
1155 
1156  Log1(PCSC_LOG_DEBUG, "Reset complete.");
1157  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
1158  rContext->readerState->cardAtr,
1159  rContext->readerState->cardAtrLength);
1160  }
1161  else
1162  {
1163  rContext->readerState->cardAtrLength = 0;
1164  Log1(PCSC_LOG_ERROR, "Error resetting card.");
1165 
1166  if (rv == SCARD_W_REMOVED_CARD)
1167  rContext->readerState->readerState = SCARD_ABSENT;
1168  else
1169  rContext->readerState->readerState =
1171  }
1172  }
1173  else if (dwDisposition == SCARD_EJECT_CARD)
1174  {
1175  UCHAR controlBuffer[5];
1176  UCHAR receiveBuffer[MAX_BUFFER_SIZE];
1177  DWORD receiveLength;
1178 
1179  /*
1180  * Set up the CTBCS command for Eject ICC
1181  */
1182  controlBuffer[0] = 0x20;
1183  controlBuffer[1] = 0x15;
1184  controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1;
1185  controlBuffer[3] = 0x00;
1186  controlBuffer[4] = 0x00;
1187  receiveLength = 2;
1188  rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
1189  &receiveLength);
1190 
1191  if (rv == SCARD_S_SUCCESS)
1192  {
1193  if (receiveLength == 2 && receiveBuffer[0] == 0x90)
1194  {
1195  Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
1196  /*
1197  * Successful
1198  */
1199  }
1200  else
1201  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1202  }
1203  else
1204  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1205 
1206  }
1207  else if (dwDisposition == SCARD_LEAVE_CARD)
1208  {
1209  /*
1210  * Do nothing
1211  */
1212  }
1213 
1214  /*
1215  * Unlock any blocks on this context
1216  */
1217  /* we do not want to lose the previous rv value
1218  * So we use another variable */
1219  rv2 = RFUnlockSharing(hCard, rContext);
1220  if (rv2 != SCARD_S_SUCCESS)
1221  /* if rv is already in error then do not change its value */
1222  if (rv == SCARD_S_SUCCESS)
1223  rv = rv2;
1224 
1225  Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv);
1226 
1227 exit:
1228  UNREF_READER(rContext)
1229 
1230  return rv;
1231 }
1232 
1233 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames,
1234  LPDWORD pcchReaderLen, LPDWORD pdwState,
1235  LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1236 {
1237  LONG rv;
1238  READER_CONTEXT * rContext = NULL;
1239 
1240  /* These parameters are not used by the client
1241  * Client side code uses readerStates[] instead */
1242  (void)mszReaderNames;
1243  (void)pcchReaderLen;
1244  (void)pdwState;
1245  (void)pdwProtocol;
1246  (void)pbAtr;
1247  (void)pcbAtrLen;
1248 
1249  if (hCard == 0)
1250  return SCARD_E_INVALID_HANDLE;
1251 
1252  /* get rContext corresponding to hCard */
1253  rv = RFReaderInfoById(hCard, &rContext);
1254  if (rv != SCARD_S_SUCCESS)
1255  return rv;
1256 
1257  /*
1258  * Make sure no one has a lock on this reader
1259  */
1260  rv = RFCheckSharing(hCard, rContext);
1261  if (rv != SCARD_S_SUCCESS)
1262  goto exit;
1263 
1264  if (rContext->readerState->cardAtrLength > MAX_ATR_SIZE)
1265  {
1267  goto exit;
1268  }
1269 
1270  /*
1271  * This is a client side function however the server maintains the
1272  * list of events between applications so it must be passed through to
1273  * obtain this event if it has occurred
1274  */
1275 
1276  /*
1277  * Make sure some event has not occurred
1278  */
1279  rv = RFCheckReaderEventState(rContext, hCard);
1280  if (rv != SCARD_S_SUCCESS)
1281  goto exit;
1282 
1283  /*
1284  * Make sure the reader is working properly
1285  */
1286  rv = RFCheckReaderStatus(rContext);
1287  if (rv != SCARD_S_SUCCESS)
1288  goto exit;
1289 
1290 exit:
1291  UNREF_READER(rContext)
1292 
1293  return rv;
1294 }
1295 
1296 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
1297  LPCVOID pbSendBuffer, DWORD cbSendLength,
1298  LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
1299 {
1300  LONG rv;
1301  READER_CONTEXT * rContext = NULL;
1302 
1303  /* 0 bytes returned by default */
1304  *lpBytesReturned = 0;
1305 
1306  if (0 == hCard)
1307  return SCARD_E_INVALID_HANDLE;
1308 
1309  /* get rContext corresponding to hCard */
1310  rv = RFReaderInfoById(hCard, &rContext);
1311  if (rv != SCARD_S_SUCCESS)
1312  return rv;
1313 
1314  /*
1315  * Make sure no one has a lock on this reader
1316  */
1317  rv = RFCheckSharing(hCard, rContext);
1318  if (rv != SCARD_S_SUCCESS)
1319  goto exit;
1320 
1321  if (IFD_HVERSION_2_0 == rContext->version)
1322  if (NULL == pbSendBuffer || 0 == cbSendLength)
1323  {
1325  goto exit;
1326  }
1327 
1328  /*
1329  * Make sure the reader is working properly
1330  */
1331  rv = RFCheckReaderStatus(rContext);
1332  if (rv != SCARD_S_SUCCESS)
1333  goto exit;
1334 
1335  if (IFD_HVERSION_2_0 == rContext->version)
1336  {
1337  /* we must wrap a API 3.0 client in an API 2.0 driver */
1338  *lpBytesReturned = cbRecvLength;
1339  rv = IFDControl_v2(rContext, (PUCHAR)pbSendBuffer,
1340  cbSendLength, pbRecvBuffer, lpBytesReturned);
1341  }
1342  else
1343  if (IFD_HVERSION_3_0 == rContext->version)
1344  rv = IFDControl(rContext, dwControlCode, pbSendBuffer,
1345  cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned);
1346  else
1348 
1349 exit:
1350  UNREF_READER(rContext)
1351 
1352  return rv;
1353 }
1354 
1355 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1356  LPBYTE pbAttr, LPDWORD pcbAttrLen)
1357 {
1358  LONG rv;
1359  READER_CONTEXT * rContext = NULL;
1360 
1361  if (0 == hCard)
1362  return SCARD_E_INVALID_HANDLE;
1363 
1364  /* get rContext corresponding to hCard */
1365  rv = RFReaderInfoById(hCard, &rContext);
1366  if (rv != SCARD_S_SUCCESS)
1367  return rv;
1368 
1369  /*
1370  * Make sure no one has a lock on this reader
1371  */
1372  rv = RFCheckSharing(hCard, rContext);
1373  if (rv != SCARD_S_SUCCESS)
1374  goto exit;
1375 
1376  /*
1377  * Make sure the reader is working properly
1378  */
1379  rv = RFCheckReaderStatus(rContext);
1380  if (rv != SCARD_S_SUCCESS)
1381  goto exit;
1382 
1383  /*
1384  * Make sure some event has not occurred
1385  */
1386  rv = RFCheckReaderEventState(rContext, hCard);
1387  if (rv != SCARD_S_SUCCESS)
1388  goto exit;
1389 
1390  rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr);
1391  switch(rv)
1392  {
1393  case IFD_SUCCESS:
1394  rv = SCARD_S_SUCCESS;
1395  break;
1396  case IFD_ERROR_TAG:
1397  /* Special case SCARD_ATTR_DEVICE_FRIENDLY_NAME as it is better
1398  * implemented in pcscd (it knows the friendly name)
1399  */
1400  if ((SCARD_ATTR_DEVICE_FRIENDLY_NAME == dwAttrId)
1401  || (SCARD_ATTR_DEVICE_SYSTEM_NAME == dwAttrId))
1402  {
1403  unsigned int len = strlen(rContext->readerState->readerName)+1;
1404 
1405  if (len > *pcbAttrLen)
1407  else
1408  {
1409  (void)strlcpy((char *)pbAttr,
1410  rContext->readerState->readerName, len);
1411  rv = SCARD_S_SUCCESS;
1412  }
1413  *pcbAttrLen = len;
1414  }
1415  else
1417  break;
1420  break;
1421  default:
1423  }
1424 
1425 exit:
1426  UNREF_READER(rContext)
1427 
1428  return rv;
1429 }
1430 
1431 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1432  LPCBYTE pbAttr, DWORD cbAttrLen)
1433 {
1434  LONG rv;
1435  READER_CONTEXT * rContext = NULL;
1436 
1437  if (0 == hCard)
1438  return SCARD_E_INVALID_HANDLE;
1439 
1440  /* get rContext corresponding to hCard */
1441  rv = RFReaderInfoById(hCard, &rContext);
1442  if (rv != SCARD_S_SUCCESS)
1443  return rv;
1444 
1445  /*
1446  * Make sure no one has a lock on this reader
1447  */
1448  rv = RFCheckSharing(hCard, rContext);
1449  if (rv != SCARD_S_SUCCESS)
1450  goto exit;
1451 
1452  /*
1453  * Make sure the reader is working properly
1454  */
1455  rv = RFCheckReaderStatus(rContext);
1456  if (rv != SCARD_S_SUCCESS)
1457  goto exit;
1458 
1459  /*
1460  * Make sure some event has not occurred
1461  */
1462  rv = RFCheckReaderEventState(rContext, hCard);
1463  if (rv != SCARD_S_SUCCESS)
1464  goto exit;
1465 
1466  rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr);
1467  if (rv == IFD_SUCCESS)
1468  rv = SCARD_S_SUCCESS;
1469  else
1470  if (rv == IFD_ERROR_TAG)
1472  else
1474 
1475 exit:
1476  UNREF_READER(rContext)
1477 
1478  return rv;
1479 }
1480 
1481 LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
1482  LPCBYTE pbSendBuffer, DWORD cbSendLength,
1483  SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer,
1484  LPDWORD pcbRecvLength)
1485 {
1486  LONG rv;
1487  READER_CONTEXT * rContext = NULL;
1488  SCARD_IO_HEADER sSendPci, sRecvPci;
1489  DWORD dwRxLength, tempRxLength;
1490 
1491  dwRxLength = *pcbRecvLength;
1492  *pcbRecvLength = 0;
1493 
1494  if (hCard == 0)
1495  return SCARD_E_INVALID_HANDLE;
1496 
1497  /*
1498  * Must at least have 2 status words even for SCardControl
1499  */
1500  if (dwRxLength < 2)
1502 
1503  /* get rContext corresponding to hCard */
1504  rv = RFReaderInfoById(hCard, &rContext);
1505  if (rv != SCARD_S_SUCCESS)
1506  return rv;
1507 
1508  /*
1509  * Make sure no one has a lock on this reader
1510  */
1511  rv = RFCheckSharing(hCard, rContext);
1512  if (rv != SCARD_S_SUCCESS)
1513  goto exit;
1514 
1515  /*
1516  * Make sure the reader is working properly
1517  */
1518  rv = RFCheckReaderStatus(rContext);
1519  if (rv != SCARD_S_SUCCESS)
1520  goto exit;
1521 
1522  /*
1523  * Make sure some event has not occurred
1524  */
1525  rv = RFCheckReaderEventState(rContext, hCard);
1526  if (rv != SCARD_S_SUCCESS)
1527  goto exit;
1528 
1529  /*
1530  * Check for some common errors
1531  */
1532  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1533  {
1534  if (rContext->readerState->readerState & SCARD_ABSENT)
1535  {
1536  rv = SCARD_E_NO_SMARTCARD;
1537  goto exit;
1538  }
1539  }
1540 
1541  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1542  {
1543  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD)
1544  {
1545  if (pioSendPci->dwProtocol != rContext->readerState->cardProtocol)
1546  {
1548  goto exit;
1549  }
1550  }
1551  }
1552 
1553  /*
1554  * Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler
1555  * just wants 0 or 1
1556  */
1557 
1558  sSendPci.Protocol = 0; /* protocol T=0 by default */
1559 
1560  if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1)
1561  {
1562  sSendPci.Protocol = 1;
1563  } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1564  {
1565  /*
1566  * This is temporary ......
1567  */
1568  sSendPci.Protocol = SCARD_PROTOCOL_RAW;
1569  } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD)
1570  {
1571  /* Fix by Amira (Athena) */
1572  unsigned long i;
1573  unsigned long prot = rContext->readerState->cardProtocol;
1574 
1575  for (i = 0 ; prot != 1 ; i++)
1576  prot >>= 1;
1577 
1578  sSendPci.Protocol = i;
1579  }
1580 
1581  sSendPci.Length = pioSendPci->cbPciLength;
1582 
1583  sRecvPci.Protocol = pioRecvPci->dwProtocol;
1584  sRecvPci.Length = pioRecvPci->cbPciLength;
1585 
1586  /* the protocol number is decoded a few lines above */
1587  Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%ld", sSendPci.Protocol);
1588 
1589  tempRxLength = dwRxLength;
1590 
1591  if ((pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1592  && (rContext->version == IFD_HVERSION_2_0))
1593  {
1594  rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength,
1595  pbRecvBuffer, &dwRxLength);
1596  } else
1597  {
1598  rv = IFDTransmit(rContext, sSendPci, (PUCHAR) pbSendBuffer,
1599  cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci);
1600  }
1601 
1602  pioRecvPci->dwProtocol = sRecvPci.Protocol;
1603  pioRecvPci->cbPciLength = sRecvPci.Length;
1604 
1605  /*
1606  * Check for any errors that might have occurred
1607  */
1608 
1609  if (rv != SCARD_S_SUCCESS)
1610  {
1611  *pcbRecvLength = 0;
1612  Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv);
1613  goto exit;
1614  }
1615 
1616  /*
1617  * Available is less than received
1618  */
1619  if (tempRxLength < dwRxLength)
1620  {
1621  *pcbRecvLength = 0;
1623  goto exit;
1624  }
1625 
1626  /*
1627  * Successful return
1628  */
1629  *pcbRecvLength = dwRxLength;
1630 
1631 exit:
1632  UNREF_READER(rContext)
1633 
1634  return rv;
1635 }
1636 
struct pubReaderStatesList * readerState
link to the reader state
uint32_t cardAtrLength
ATR length.
Definition: eventhandler.h:35
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME
Reader's display name.
Definition: reader.h:90
int32_t contexts
Number of open contexts.
#define IFD_ERROR_TAG
tag unknown
Definition: ifdhandler.h:329
#define SCARD_E_PROTO_MISMATCH
The requested protocols are incompatible with the protocol currently in use with the smart card...
Definition: pcsclite.h:95
volatile SCARDHANDLE hLockId
Lock Id.
#define SCARD_SCOPE_USER
Scope in user space.
Definition: pcsclite.h:146
#define TAG_IFD_STOP_POLLING_THREAD
method used to stop the polling thread (instead of just pthread_kill())
Definition: ifdhandler.h:307
#define SCARD_ATTR_DEVICE_SYSTEM_NAME
Reader's system name.
Definition: reader.h:91
#define PCSCLITE_SHARING_NO_CONTEXT
No application is using the reader.
Definition: eventhandler.h:52
#define MAX_BUFFER_SIZE
Maximum Tx/Rx Buffer for short APDU.
Definition: pcsclite.h:208
LONG IFDGetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, PDWORD pdwLength, PUCHAR pucValue)
Get's capabilities in the reader.
Definition: ifdwrapper.c:214
This keeps a list of defines shared between the driver and the application.
char readerName[MAX_READERNAME]
reader name
Definition: eventhandler.h:29
unsigned long cbPciLength
Protocol Control Inf Length.
Definition: pcsclite.h:61
int32_t readerSharing
PCSCLITE_SHARING_* sharing status.
Definition: eventhandler.h:32
#define SCARD_E_INVALID_PARAMETER
One or more of the supplied parameters could not be properly interpreted.
Definition: pcsclite.h:84
#define SCARD_E_NOT_TRANSACTED
An attempt was made to end a non-existent transaction.
Definition: pcsclite.h:102
#define SCARD_LEAVE_CARD
Do nothing on close.
Definition: pcsclite.h:163
This handles protocol defaults, PTS, etc.
This handles abstract system level calls.
int slot
Current Reader Slot.
This wraps the dynamic ifdhandler functions.
#define SCARD_PROTOCOL_T1
T=1 active protocol.
Definition: pcsclite.h:153
#define SCARD_E_INVALID_HANDLE
The supplied handle was invalid.
Definition: pcsclite.h:83
#define SCARD_SCOPE_TERMINAL
Scope in terminal.
Definition: pcsclite.h:147
#define SCARD_W_UNRESPONSIVE_CARD
The smart card is not responding to a reset.
Definition: pcsclite.h:133
#define SCARD_PROTOCOL_ANY_OLD
used for backward compatibility
Definition: winscard.c:171
#define SCARD_PRESENT
Card is present.
Definition: pcsclite.h:170
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
Definition: sys_unix.c:62
#define SCARD_NEGOTIABLE
Ready for PTS.
Definition: pcsclite.h:173
#define PCSCLITE_SHARING_EXCLUSIVE_CONTEXT
Reader used in exclusive mode.
Definition: eventhandler.h:54
#define PCSCLITE_LOCK_POLL_RATE
Lock polling rate.
Definition: pcscd.h:35
LONG SCARDCONTEXT
hContext returned by SCardEstablishContext()
Definition: pcsclite.h:31
This keeps track of smart card protocols, timing issues and Answer to Reset ATR handling.
#define SCARD_E_INVALID_VALUE
One or more of the supplied parameters values could not be properly interpreted.
Definition: pcsclite.h:97
#define SCARD_RESET
Card was reset.
Definition: pcscd.h:22
#define SCARD_SHARE_SHARED
Shared mode only.
Definition: pcsclite.h:160
LONG IFDTransmit(READER_CONTEXT *rContext, SCARD_IO_HEADER pioTxPci, PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer, PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
Transmit an APDU to the ICC.
Definition: ifdwrapper.c:486
unsigned long dwProtocol
Protocol identifier.
Definition: pcsclite.h:60
prototypes of strlcpy()/strlcat() imported from OpenBSD
#define IFD_POWER_DOWN
power down the card
Definition: ifdhandler.h:321
card is used
Definition: pcscd.h:50
int version
IFD Handler version number.
#define SCARD_PROTOCOL_T0
T=0 active protocol.
Definition: pcsclite.h:152
pthread_mutex_t * mMutex
Mutex for this connection.
Definition: readerfactory.h:91
long int time_sub(struct timeval *a, struct timeval *b)
return the difference (as long int) in µs between 2 struct timeval r = a - b
Definition: utils.c:114
short ATRDecodeAtr(int *availableProtocols, int *currentProtocol, PUCHAR pucAtr, DWORD dwLength)
parse an ATR
Definition: atrhandler.c:45
This handles card insertion/removal events, updates ATR, protocol, and status information.
#define SCARD_UNPOWER_CARD
Power down on close.
Definition: pcsclite.h:165
LONG IFDSetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, DWORD dwLength, PUCHAR pucValue)
Set capabilities in the reader.
Definition: ifdwrapper.c:183
#define SCARD_W_REMOVED_CARD
The smart card has been removed, so further communication is not possible.
Definition: pcsclite.h:136
#define SCARD_SWALLOWED
Card not powered.
Definition: pcsclite.h:171
#define SCARD_E_UNSUPPORTED_FEATURE
This smart card does not support the requested feature.
Definition: pcsclite.h:112
int powerState
auto power off state
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
Definition: pcsclite.h:150
#define SCARD_RESET_CARD
Reset on close.
Definition: pcsclite.h:164
UCHAR cardAtr[MAX_ATR_SIZE]
ATR.
Definition: eventhandler.h:34
LONG SCARDHANDLE
hCard returned by SCardConnect()
Definition: pcsclite.h:34
LONG IFDPowerICC(READER_CONTEXT *rContext, DWORD dwAction, PUCHAR pucAtr, PDWORD pdwAtrLen)
Power up/down or reset's an ICC located in the IFD.
Definition: ifdwrapper.c:244
#define SCARD_SHARE_EXCLUSIVE
Exclusive mode only.
Definition: pcsclite.h:159
#define SCARD_POWERED
Card is powered.
Definition: pcsclite.h:172
card was in use
Definition: pcscd.h:49
DWORD PHSetProtocol(struct ReaderContext *rContext, DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault)
Determine which protocol to use.
Definition: prothandler.c:39
This keeps a list of defines for pcsc-lite.
#define SCARD_PROTOCOL_RAW
Raw active protocol.
Definition: pcsclite.h:154
#define SCARD_EJECT_CARD
Eject on close.
Definition: pcsclite.h:166
Protocol Control Information (PCI)
Definition: pcsclite.h:58
#define SCARD_E_SHARING_VIOLATION
The smart card cannot be accessed because of other connections outstanding.
Definition: pcsclite.h:91
#define SCARD_SCOPE_GLOBAL
Scope is global.
Definition: pcscd.h:20
#define SCARD_W_UNPOWERED_CARD
Power has been removed from the smart card, so that further communication is not possible.
Definition: pcsclite.h:134
#define SCARD_ABSENT
Card is absent.
Definition: pcsclite.h:169
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
Definition: eventhandler.h:36
auto power off
Definition: pcscd.h:47
#define SCARD_E_NO_SMARTCARD
The operation requires a Smart Card, but no Smart Card is currently in the device.
Definition: pcsclite.h:92
This keeps track of a list of currently available reader structures.
#define MAX_ATR_SIZE
Maximum ATR size.
Definition: pcsclite.h:38
#define IFD_ERROR_INSUFFICIENT_BUFFER
buffer is too small
Definition: ifdhandler.h:350
uint32_t readerState
SCARD_* bit field.
Definition: eventhandler.h:31
#define SCARD_E_INSUFFICIENT_BUFFER
The data buffer to receive returned data is too small for the returned data.
Definition: pcsclite.h:88
#define SCARD_SHARE_DIRECT
Raw mode only.
Definition: pcsclite.h:161
#define PCSCLITE_SHARING_LAST_CONTEXT
One application is using the reader.
Definition: eventhandler.h:50
pthread_mutex_t powerState_lock
powerState mutex
Use by SCardTransmit()
Definition: ifdhandler.h:288
#define IFD_RESET
warm reset
Definition: ifdhandler.h:322
#define SCARD_S_SUCCESS
error codes from http://msdn.microsoft.com/en-us/library/aa924526.aspx
Definition: pcsclite.h:80
#define SCARD_SCOPE_SYSTEM
Scope in system.
Definition: pcsclite.h:148
This handles smart card reader communications.
#define IFD_POWER_UP
power up the card
Definition: ifdhandler.h:320
This handles debugging.
#define IFD_SUCCESS
no error
Definition: ifdhandler.h:328
LONG IFDControl(READER_CONTEXT *rContext, DWORD ControlCode, LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength, LPDWORD BytesReturned)
Provide a means for toggling a specific action on the reader such as swallow, eject, biometric.
Definition: ifdwrapper.c:426
#define SCARD_F_INTERNAL_ERROR
An internal consistency check failed.
Definition: pcsclite.h:81