pcsc-lite  1.9.5
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(0, -1);
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  Log3(PCSC_LOG_ERROR, "Error powering up card: %ld 0x%04lX",
339  rv, 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  if (rv != SCARD_S_SUCCESS)
844  return rv;
845 
846  /*
847  * wait until a possible transaction is finished
848  */
849  if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->hLockId != 0)
850  && (rContext->hLockId != hCard))
851  {
852  Log1(PCSC_LOG_INFO, "Waiting for release of lock");
853  while (rContext->hLockId != 0)
855  Log1(PCSC_LOG_INFO, "Lock released");
856  }
857 
858  /*
859  * Try to unlock any blocks on this context
860  *
861  * This may fail with SCARD_E_SHARING_VIOLATION if a transaction is
862  * on going on another card context and dwDisposition == SCARD_LEAVE_CARD.
863  * We should not stop.
864  */
865  rv = RFUnlockAllSharing(hCard, rContext);
866  if (rv != SCARD_S_SUCCESS)
867  {
868  if (rv != SCARD_E_SHARING_VIOLATION)
869  {
870  goto exit;
871  }
872  else
873  {
874  if (SCARD_LEAVE_CARD != dwDisposition)
875  goto exit;
876  }
877  }
878 
879  Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->contexts);
880  Log2(PCSC_LOG_DEBUG, "dwDisposition: %ld", dwDisposition);
881 
882  if (dwDisposition == SCARD_RESET_CARD ||
883  dwDisposition == SCARD_UNPOWER_CARD)
884  {
885  DWORD dwAtrLen;
886 
887  /*
888  * Notify the card has been reset
889  */
890  RFSetReaderEventState(rContext, SCARD_RESET);
891 
892  dwAtrLen = sizeof(rContext->readerState->cardAtr);
893  if (SCARD_RESET_CARD == dwDisposition)
894  rv = IFDPowerICC(rContext, IFD_RESET,
895  rContext->readerState->cardAtr, &dwAtrLen);
896  else
897  {
898  /* SCARD_UNPOWER_CARD */
899  rv = IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
900 
901  RFSetPowerState(rContext, POWER_STATE_UNPOWERED);
902  Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED");
903  }
904 
905  /* the protocol is unset after a power on */
907 
908  if (rv == IFD_SUCCESS)
909  {
910  if (SCARD_UNPOWER_CARD == dwDisposition)
912  else
913  {
914  rContext->readerState->cardAtrLength = dwAtrLen;
915  rContext->readerState->readerState =
917 
918  Log1(PCSC_LOG_DEBUG, "Reset complete.");
919  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
920  rContext->readerState->cardAtr,
921  rContext->readerState->cardAtrLength);
922  }
923  }
924  else
925  {
926  if (SCARD_UNPOWER_CARD == dwDisposition)
927  Log3(PCSC_LOG_ERROR, "Error powering down card: %ld 0x%04lX",
928  rv, rv);
929  else
930  {
931  rContext->readerState->cardAtrLength = 0;
932  Log1(PCSC_LOG_ERROR, "Error resetting card.");
933  }
934 
935  if (rv == SCARD_W_REMOVED_CARD)
936  rContext->readerState->readerState = SCARD_ABSENT;
937  else
938  rContext->readerState->readerState =
940  }
941  }
942  else if (dwDisposition == SCARD_EJECT_CARD)
943  {
944  UCHAR controlBuffer[5];
945  UCHAR receiveBuffer[MAX_BUFFER_SIZE];
946  DWORD receiveLength;
947 
948  /*
949  * Set up the CTBCS command for Eject ICC
950  */
951  controlBuffer[0] = 0x20;
952  controlBuffer[1] = 0x15;
953  controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1;
954  controlBuffer[3] = 0x00;
955  controlBuffer[4] = 0x00;
956  receiveLength = 2;
957  rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
958  &receiveLength);
959 
960  if (rv == SCARD_S_SUCCESS)
961  {
962  if (receiveLength == 2 && receiveBuffer[0] == 0x90)
963  {
964  Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
965  /*
966  * Successful
967  */
968  }
969  else
970  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
971  }
972  else
973  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
974 
975  }
976  else if (dwDisposition == SCARD_LEAVE_CARD)
977  {
978  /*
979  * Do nothing
980  */
981  }
982 
983  /*
984  * Remove and destroy this handle
985  */
986  (void)RFRemoveReaderHandle(rContext, hCard);
987 
988  /*
989  * For exclusive connection reset it to no connections
990  */
993  else
994  {
995  /*
996  * Remove a connection from the context stack
997  */
998  rContext->contexts -= 1;
999 
1000  if (rContext->contexts < 0)
1001  rContext->contexts = 0;
1002  }
1003 
1004  if (PCSCLITE_SHARING_NO_CONTEXT == rContext->contexts)
1005  {
1006  RESPONSECODE (*fct)(DWORD) = NULL;
1007  DWORD dwGetSize;
1008 
1009  (void)pthread_mutex_lock(&rContext->powerState_lock);
1010  /* Switch to POWER_STATE_GRACE_PERIOD unless the card was not
1011  * powered */
1012  if (POWER_STATE_POWERED <= rContext->powerState)
1013  {
1015  Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_GRACE_PERIOD");
1016  }
1017 
1018  (void)pthread_mutex_unlock(&rContext->powerState_lock);
1019 
1020  /* ask to stop the "polling" thread so it can be restarted using
1021  * the correct timeout */
1022  dwGetSize = sizeof(fct);
1024  &dwGetSize, (PUCHAR)&fct);
1025 
1026  if ((IFD_SUCCESS == rv) && (dwGetSize == sizeof(fct)))
1027  {
1028  Log1(PCSC_LOG_INFO, "Stopping polling thread");
1029  fct(rContext->slot);
1030  }
1031  }
1032 
1033  /*
1034  * Propagate new state to reader state
1035  */
1036  rContext->readerState->readerSharing = rContext->contexts;
1037 
1038  rv = SCARD_S_SUCCESS;
1039 
1040 exit:
1041  UNREF_READER(rContext)
1042 
1043  return rv;
1044 }
1045 
1046 LONG SCardBeginTransaction(SCARDHANDLE hCard)
1047 {
1048  LONG rv;
1049  READER_CONTEXT * rContext;
1050 
1051  if (hCard == 0)
1052  return SCARD_E_INVALID_HANDLE;
1053 
1054  /* get rContext corresponding to hCard */
1055  rv = RFReaderInfoById(hCard, &rContext);
1056  if (rv != SCARD_S_SUCCESS)
1057  return rv;
1058 
1059  /*
1060  * Make sure the reader is working properly
1061  */
1062  rv = RFCheckReaderStatus(rContext);
1063  if (rv != SCARD_S_SUCCESS)
1064  goto exit;
1065 
1066  /*
1067  * Make sure some event has not occurred
1068  */
1069  rv = RFCheckReaderEventState(rContext, hCard);
1070  if (rv != SCARD_S_SUCCESS)
1071  goto exit;
1072 
1073  rv = RFLockSharing(hCard, rContext);
1074 
1075  /* if the transaction is not yet ready we sleep a bit so the client
1076  * do not retry immediately */
1077  if (SCARD_E_SHARING_VIOLATION == rv)
1079 
1080  Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv);
1081 
1082 exit:
1083  UNREF_READER(rContext)
1084 
1085  return rv;
1086 }
1087 
1088 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
1089 {
1090  LONG rv;
1091  LONG rv2;
1092  READER_CONTEXT * rContext = NULL;
1093 
1094  /*
1095  * Ignoring dwDisposition for now
1096  */
1097  if (hCard == 0)
1098  return SCARD_E_INVALID_HANDLE;
1099 
1100  if ((dwDisposition != SCARD_LEAVE_CARD)
1101  && (dwDisposition != SCARD_UNPOWER_CARD)
1102  && (dwDisposition != SCARD_RESET_CARD)
1103  && (dwDisposition != SCARD_EJECT_CARD))
1104  return SCARD_E_INVALID_VALUE;
1105 
1106  /* get rContext corresponding to hCard */
1107  rv = RFReaderInfoById(hCard, &rContext);
1108  if (rv != SCARD_S_SUCCESS)
1109  return rv;
1110 
1111  /*
1112  * Make sure some event has not occurred
1113  */
1114  rv = RFCheckReaderEventState(rContext, hCard);
1115  if (rv != SCARD_S_SUCCESS)
1116  goto exit;
1117 
1118  /*
1119  * Error if another transaction is ongoing and a card action is
1120  * requested
1121  */
1122  if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->hLockId != 0)
1123  && (rContext->hLockId != hCard))
1124  {
1125  Log1(PCSC_LOG_INFO, "No card reset within a transaction");
1127  goto exit;
1128  }
1129 
1130  if (dwDisposition == SCARD_RESET_CARD ||
1131  dwDisposition == SCARD_UNPOWER_CARD)
1132  {
1133  DWORD dwAtrLen;
1134 
1135  dwAtrLen = sizeof(rContext->readerState->cardAtr);
1136  if (SCARD_RESET_CARD == dwDisposition)
1137  rv = IFDPowerICC(rContext, IFD_RESET,
1138  rContext->readerState->cardAtr, &dwAtrLen);
1139  else
1140  {
1141  IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
1142  rv = IFDPowerICC(rContext, IFD_POWER_UP,
1143  rContext->readerState->cardAtr, &dwAtrLen);
1144  }
1145 
1146  /* the protocol is unset after a power on */
1148 
1149  /*
1150  * Notify the card has been reset
1151  */
1152  RFSetReaderEventState(rContext, SCARD_RESET);
1153 
1154  /*
1155  * Set up the status bit masks on readerState
1156  */
1157  if (rv == IFD_SUCCESS)
1158  {
1159  rContext->readerState->cardAtrLength = dwAtrLen;
1160  rContext->readerState->readerState =
1162 
1163  Log1(PCSC_LOG_DEBUG, "Reset complete.");
1164  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
1165  rContext->readerState->cardAtr,
1166  rContext->readerState->cardAtrLength);
1167  }
1168  else
1169  {
1170  rContext->readerState->cardAtrLength = 0;
1171  Log1(PCSC_LOG_ERROR, "Error resetting card.");
1172 
1173  if (rv == SCARD_W_REMOVED_CARD)
1174  rContext->readerState->readerState = SCARD_ABSENT;
1175  else
1176  rContext->readerState->readerState =
1178  }
1179  }
1180  else if (dwDisposition == SCARD_EJECT_CARD)
1181  {
1182  UCHAR controlBuffer[5];
1183  UCHAR receiveBuffer[MAX_BUFFER_SIZE];
1184  DWORD receiveLength;
1185 
1186  /*
1187  * Set up the CTBCS command for Eject ICC
1188  */
1189  controlBuffer[0] = 0x20;
1190  controlBuffer[1] = 0x15;
1191  controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1;
1192  controlBuffer[3] = 0x00;
1193  controlBuffer[4] = 0x00;
1194  receiveLength = 2;
1195  rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
1196  &receiveLength);
1197 
1198  if (rv == SCARD_S_SUCCESS)
1199  {
1200  if (receiveLength == 2 && receiveBuffer[0] == 0x90)
1201  {
1202  Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
1203  /*
1204  * Successful
1205  */
1206  }
1207  else
1208  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1209  }
1210  else
1211  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1212 
1213  }
1214  else if (dwDisposition == SCARD_LEAVE_CARD)
1215  {
1216  /*
1217  * Do nothing
1218  */
1219  }
1220 
1221  /*
1222  * Unlock any blocks on this context
1223  */
1224  /* we do not want to lose the previous rv value
1225  * So we use another variable */
1226  rv2 = RFUnlockSharing(hCard, rContext);
1227  if (rv2 != SCARD_S_SUCCESS)
1228  /* if rv is already in error then do not change its value */
1229  if (rv == SCARD_S_SUCCESS)
1230  rv = rv2;
1231 
1232  Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv);
1233 
1234 exit:
1235  UNREF_READER(rContext)
1236 
1237  return rv;
1238 }
1239 
1240 LONG SCardStatus(SCARDHANDLE hCard, LPSTR szReaderNames,
1241  LPDWORD pcchReaderLen, LPDWORD pdwState,
1242  LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1243 {
1244  LONG rv;
1245  READER_CONTEXT * rContext = NULL;
1246 
1247  /* These parameters are not used by the client
1248  * Client side code uses readerStates[] instead */
1249  (void)szReaderNames;
1250  (void)pcchReaderLen;
1251  (void)pdwState;
1252  (void)pdwProtocol;
1253  (void)pbAtr;
1254  (void)pcbAtrLen;
1255 
1256  if (hCard == 0)
1257  return SCARD_E_INVALID_HANDLE;
1258 
1259  /* get rContext corresponding to hCard */
1260  rv = RFReaderInfoById(hCard, &rContext);
1261  if (rv != SCARD_S_SUCCESS)
1262  return rv;
1263 
1264  /*
1265  * Make sure no one has a lock on this reader
1266  */
1267  rv = RFCheckSharing(hCard, rContext);
1268  if (rv != SCARD_S_SUCCESS)
1269  goto exit;
1270 
1271  if (rContext->readerState->cardAtrLength > MAX_ATR_SIZE)
1272  {
1274  goto exit;
1275  }
1276 
1277  /*
1278  * This is a client side function however the server maintains the
1279  * list of events between applications so it must be passed through to
1280  * obtain this event if it has occurred
1281  */
1282 
1283  /*
1284  * Make sure some event has not occurred
1285  */
1286  rv = RFCheckReaderEventState(rContext, hCard);
1287  if (rv != SCARD_S_SUCCESS)
1288  goto exit;
1289 
1290  /*
1291  * Make sure the reader is working properly
1292  */
1293  rv = RFCheckReaderStatus(rContext);
1294  if (rv != SCARD_S_SUCCESS)
1295  goto exit;
1296 
1297 exit:
1298  UNREF_READER(rContext)
1299 
1300  return rv;
1301 }
1302 
1303 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
1304  LPCVOID pbSendBuffer, DWORD cbSendLength,
1305  LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
1306 {
1307  LONG rv;
1308  READER_CONTEXT * rContext = NULL;
1309 
1310  /* 0 bytes returned by default */
1311  *lpBytesReturned = 0;
1312 
1313  if (0 == hCard)
1314  return SCARD_E_INVALID_HANDLE;
1315 
1316  /* get rContext corresponding to hCard */
1317  rv = RFReaderInfoById(hCard, &rContext);
1318  if (rv != SCARD_S_SUCCESS)
1319  return rv;
1320 
1321  /*
1322  * Make sure no one has a lock on this reader
1323  */
1324  rv = RFCheckSharing(hCard, rContext);
1325  if (rv != SCARD_S_SUCCESS)
1326  goto exit;
1327 
1328  if (IFD_HVERSION_2_0 == rContext->version)
1329  if (NULL == pbSendBuffer || 0 == cbSendLength)
1330  {
1332  goto exit;
1333  }
1334 
1335  /*
1336  * Make sure the reader is working properly
1337  */
1338  rv = RFCheckReaderStatus(rContext);
1339  if (rv != SCARD_S_SUCCESS)
1340  goto exit;
1341 
1342  if (IFD_HVERSION_2_0 == rContext->version)
1343  {
1344  /* we must wrap a API 3.0 client in an API 2.0 driver */
1345  *lpBytesReturned = cbRecvLength;
1346  rv = IFDControl_v2(rContext, (PUCHAR)pbSendBuffer,
1347  cbSendLength, pbRecvBuffer, lpBytesReturned);
1348  }
1349  else
1350  if (IFD_HVERSION_3_0 == rContext->version)
1351  rv = IFDControl(rContext, dwControlCode, pbSendBuffer,
1352  cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned);
1353  else
1355 
1356 exit:
1357  UNREF_READER(rContext)
1358 
1359  return rv;
1360 }
1361 
1362 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1363  LPBYTE pbAttr, LPDWORD pcbAttrLen)
1364 {
1365  LONG rv;
1366  READER_CONTEXT * rContext = NULL;
1367 
1368  if (0 == hCard)
1369  return SCARD_E_INVALID_HANDLE;
1370 
1371  /* get rContext corresponding to hCard */
1372  rv = RFReaderInfoById(hCard, &rContext);
1373  if (rv != SCARD_S_SUCCESS)
1374  return rv;
1375 
1376  /*
1377  * Make sure no one has a lock on this reader
1378  */
1379  rv = RFCheckSharing(hCard, rContext);
1380  if (rv != SCARD_S_SUCCESS)
1381  goto exit;
1382 
1383  /*
1384  * Make sure the reader is working properly
1385  */
1386  rv = RFCheckReaderStatus(rContext);
1387  if (rv != SCARD_S_SUCCESS)
1388  goto exit;
1389 
1390  /*
1391  * Make sure some event has not occurred
1392  */
1393  rv = RFCheckReaderEventState(rContext, hCard);
1394  if (rv != SCARD_S_SUCCESS)
1395  goto exit;
1396 
1397  rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr);
1398  switch(rv)
1399  {
1400  case IFD_SUCCESS:
1401  rv = SCARD_S_SUCCESS;
1402  break;
1403  case IFD_ERROR_TAG:
1404  /* Special case SCARD_ATTR_DEVICE_FRIENDLY_NAME as it is better
1405  * implemented in pcscd (it knows the friendly name)
1406  */
1407  if ((SCARD_ATTR_DEVICE_FRIENDLY_NAME == dwAttrId)
1408  || (SCARD_ATTR_DEVICE_SYSTEM_NAME == dwAttrId))
1409  {
1410  unsigned int len = strlen(rContext->readerState->readerName)+1;
1411 
1412  if (len > *pcbAttrLen)
1414  else
1415  {
1416  strcpy((char *)pbAttr, rContext->readerState->readerName);
1417  rv = SCARD_S_SUCCESS;
1418  }
1419  *pcbAttrLen = len;
1420  }
1421  else
1423  break;
1426  break;
1427  default:
1429  }
1430 
1431 exit:
1432  UNREF_READER(rContext)
1433 
1434  return rv;
1435 }
1436 
1437 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1438  LPCBYTE pbAttr, DWORD cbAttrLen)
1439 {
1440  LONG rv;
1441  READER_CONTEXT * rContext = NULL;
1442 
1443  if (0 == hCard)
1444  return SCARD_E_INVALID_HANDLE;
1445 
1446  /* get rContext corresponding to hCard */
1447  rv = RFReaderInfoById(hCard, &rContext);
1448  if (rv != SCARD_S_SUCCESS)
1449  return rv;
1450 
1451  /*
1452  * Make sure no one has a lock on this reader
1453  */
1454  rv = RFCheckSharing(hCard, rContext);
1455  if (rv != SCARD_S_SUCCESS)
1456  goto exit;
1457 
1458  /*
1459  * Make sure the reader is working properly
1460  */
1461  rv = RFCheckReaderStatus(rContext);
1462  if (rv != SCARD_S_SUCCESS)
1463  goto exit;
1464 
1465  /*
1466  * Make sure some event has not occurred
1467  */
1468  rv = RFCheckReaderEventState(rContext, hCard);
1469  if (rv != SCARD_S_SUCCESS)
1470  goto exit;
1471 
1472  rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr);
1473  if (rv == IFD_SUCCESS)
1474  rv = SCARD_S_SUCCESS;
1475  else
1476  if (rv == IFD_ERROR_TAG)
1478  else
1480 
1481 exit:
1482  UNREF_READER(rContext)
1483 
1484  return rv;
1485 }
1486 
1487 LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
1488  LPCBYTE pbSendBuffer, DWORD cbSendLength,
1489  SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer,
1490  LPDWORD pcbRecvLength)
1491 {
1492  LONG rv;
1493  READER_CONTEXT * rContext = NULL;
1494  SCARD_IO_HEADER sSendPci, sRecvPci;
1495  DWORD dwRxLength, tempRxLength;
1496 
1497  dwRxLength = *pcbRecvLength;
1498  *pcbRecvLength = 0;
1499 
1500  if (hCard == 0)
1501  return SCARD_E_INVALID_HANDLE;
1502 
1503  /*
1504  * Must at least have 2 status words even for SCardControl
1505  */
1506  if (dwRxLength < 2)
1508 
1509  /* get rContext corresponding to hCard */
1510  rv = RFReaderInfoById(hCard, &rContext);
1511  if (rv != SCARD_S_SUCCESS)
1512  return rv;
1513 
1514  /*
1515  * Make sure no one has a lock on this reader
1516  */
1517  rv = RFCheckSharing(hCard, rContext);
1518  if (rv != SCARD_S_SUCCESS)
1519  goto exit;
1520 
1521  /*
1522  * Make sure the reader is working properly
1523  */
1524  rv = RFCheckReaderStatus(rContext);
1525  if (rv != SCARD_S_SUCCESS)
1526  goto exit;
1527 
1528  /*
1529  * Make sure some event has not occurred
1530  */
1531  rv = RFCheckReaderEventState(rContext, hCard);
1532  if (rv != SCARD_S_SUCCESS)
1533  goto exit;
1534 
1535  /*
1536  * Check for some common errors
1537  */
1538  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1539  {
1540  if (rContext->readerState->readerState & SCARD_ABSENT)
1541  {
1542  rv = SCARD_E_NO_SMARTCARD;
1543  goto exit;
1544  }
1545  }
1546 
1547  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1548  {
1549  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD)
1550  {
1551  if (pioSendPci->dwProtocol != rContext->readerState->cardProtocol)
1552  {
1554  goto exit;
1555  }
1556  }
1557  }
1558 
1559  /*
1560  * Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler
1561  * just wants 0 or 1
1562  */
1563 
1564  sSendPci.Protocol = 0; /* protocol T=0 by default */
1565 
1566  if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1)
1567  {
1568  sSendPci.Protocol = 1;
1569  } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1570  {
1571  /*
1572  * This is temporary ......
1573  */
1574  sSendPci.Protocol = SCARD_PROTOCOL_RAW;
1575  } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD)
1576  {
1577  /* Fix by Amira (Athena) */
1578  unsigned long i;
1579  unsigned long prot = rContext->readerState->cardProtocol;
1580 
1581  for (i = 0 ; prot != 1 && i < 16; i++)
1582  prot >>= 1;
1583 
1584  sSendPci.Protocol = i;
1585  }
1586 
1587  sSendPci.Length = pioSendPci->cbPciLength;
1588 
1589  sRecvPci.Protocol = pioRecvPci->dwProtocol;
1590  sRecvPci.Length = pioRecvPci->cbPciLength;
1591 
1592  /* the protocol number is decoded a few lines above */
1593  Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%ld", sSendPci.Protocol);
1594 
1595  tempRxLength = dwRxLength;
1596 
1597  if ((pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1598  && (rContext->version == IFD_HVERSION_2_0))
1599  {
1600  rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength,
1601  pbRecvBuffer, &dwRxLength);
1602  } else
1603  {
1604  rv = IFDTransmit(rContext, sSendPci, (PUCHAR) pbSendBuffer,
1605  cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci);
1606  }
1607 
1608  pioRecvPci->dwProtocol = sRecvPci.Protocol;
1609  pioRecvPci->cbPciLength = sRecvPci.Length;
1610 
1611  /*
1612  * Check for any errors that might have occurred
1613  */
1614 
1615  if (rv != SCARD_S_SUCCESS)
1616  {
1617  *pcbRecvLength = 0;
1618  Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv);
1619 
1620  if (SCARD_E_NO_SMARTCARD == rv)
1621  {
1622  rContext->readerState->cardAtrLength = 0;
1624  rContext->readerState->readerState = SCARD_ABSENT;
1625  }
1626 
1627  goto exit;
1628  }
1629 
1630  /*
1631  * Available is less than received
1632  */
1633  if (tempRxLength < dwRxLength)
1634  {
1635  *pcbRecvLength = 0;
1637  goto exit;
1638  }
1639 
1640  /*
1641  * Successful return
1642  */
1643  *pcbRecvLength = dwRxLength;
1644 
1645 exit:
1646  UNREF_READER(rContext)
1647 
1648  return rv;
1649 }
1650 
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_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:69
@ POWER_STATE_UNPOWERED
auto power off
Definition: pcscd.h:66
@ POWER_STATE_GRACE_PERIOD
card was in use
Definition: pcscd.h:68
#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.
volatile SCARDHANDLE hLockId
Lock Id.
pthread_mutex_t * mMutex
Mutex for this connection.
pthread_mutex_t powerState_lock
powerState mutex
int slot
Current Reader Slot.
int version
IFD Handler version number.
int32_t contexts
Number of open contexts.
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(int, int)
Generate a pseudo random number.
Definition: sys_unix.c:95
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
Definition: sys_unix.c:71
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.