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