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