pcsc-lite  1.8.20
winscard.c
Go to the documentation of this file.
1 /*
2  * MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
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_INUSE;
352  Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_INUSE");
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  /*
587  * Currently pcsc-lite keeps the card powered constantly
588  */
589  dwAtrLen = sizeof(rContext->readerState->cardAtr);
590  if (SCARD_RESET_CARD == dwInitialization)
591  rv = IFDPowerICC(rContext, IFD_RESET,
592  rContext->readerState->cardAtr, &dwAtrLen);
593  else
594  {
595  IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
596  rv = IFDPowerICC(rContext, IFD_POWER_UP,
597  rContext->readerState->cardAtr, &dwAtrLen);
598  }
599 
600  /* the protocol is unset after a power on */
602 
603  /*
604  * Set up the status bit masks on readerState
605  */
606  if (rv == SCARD_S_SUCCESS)
607  {
608  rContext->readerState->cardAtrLength = dwAtrLen;
609  rContext->readerState->readerState =
611 
612  Log1(PCSC_LOG_DEBUG, "Reset complete.");
613  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
614  rContext->readerState->cardAtr,
615  rContext->readerState->cardAtrLength);
616  }
617  else
618  {
619  rContext->readerState->cardAtrLength = 0;
620  Log1(PCSC_LOG_ERROR, "Error resetting card.");
621 
622  if (rv == SCARD_W_REMOVED_CARD)
623  {
624  rContext->readerState->readerState = SCARD_ABSENT;
626  goto exit;
627  }
628  else
629  {
630  rContext->readerState->readerState =
633  goto exit;
634  }
635  }
636  }
637  else
638  if (dwInitialization == SCARD_LEAVE_CARD)
639  {
640  uint32_t readerState = rContext->readerState->readerState;
641 
642  if (readerState & SCARD_ABSENT)
643  {
645  goto exit;
646  }
647 
648  if ((readerState & SCARD_PRESENT)
649  && (readerState & SCARD_SWALLOWED))
650  {
652  goto exit;
653  }
654  }
655 
656  /*******************************************
657  *
658  * This section tries to decode the ATR
659  * and set up which protocol to use
660  *
661  *******************************************/
662  if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
664  else
665  {
666  if (dwShareMode != SCARD_SHARE_DIRECT)
667  {
668  /* lock here instead in IFDSetPTS() to lock up to
669  * setting rContext->readerState->cardProtocol */
670  (void)pthread_mutex_lock(rContext->mMutex);
671 
672  /* the protocol is not yet set (no PPS yet) */
674  {
675  int availableProtocols, defaultProtocol;
676  int ret;
677 
678  ATRDecodeAtr(&availableProtocols, &defaultProtocol,
679  rContext->readerState->cardAtr,
680  rContext->readerState->cardAtrLength);
681 
682  /* If it is set to ANY let it do any of the protocols */
683  if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
684  dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
685 
686  ret = PHSetProtocol(rContext, dwPreferredProtocols,
687  availableProtocols, defaultProtocol);
688 
689  /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error */
690  if (SET_PROTOCOL_PPS_FAILED == ret)
691  {
692  (void)pthread_mutex_unlock(rContext->mMutex);
694  goto exit;
695  }
696 
697  if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
698  {
699  (void)pthread_mutex_unlock(rContext->mMutex);
701  goto exit;
702  }
703 
704  /* use negotiated protocol */
705  rContext->readerState->cardProtocol = ret;
706 
707  (void)pthread_mutex_unlock(rContext->mMutex);
708  }
709  else
710  {
711  (void)pthread_mutex_unlock(rContext->mMutex);
712 
713  if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
714  {
716  goto exit;
717  }
718  }
719  }
720  }
721 
722  *pdwActiveProtocol = rContext->readerState->cardProtocol;
723 
724  if (dwShareMode != SCARD_SHARE_DIRECT)
725  {
726  switch (*pdwActiveProtocol)
727  {
728  case SCARD_PROTOCOL_T0:
729  case SCARD_PROTOCOL_T1:
730  Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
731  (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
732  break;
733 
734  case SCARD_PROTOCOL_RAW:
735  Log1(PCSC_LOG_DEBUG, "Active Protocol: RAW");
736  break;
737 
738  default:
739  Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %ld",
740  *pdwActiveProtocol);
741  }
742  }
743  else
744  Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected");
745 
746  if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
747  {
749  {
750  /*
751  * Do nothing - we are already exclusive
752  */
753  }
754  else
755  {
756  if (rContext->contexts == PCSCLITE_SHARING_LAST_CONTEXT)
757  {
759  (void)RFLockSharing(hCard, rContext);
760  }
761  else
762  {
764  goto exit;
765  }
766  }
767  }
768  else if (dwShareMode == SCARD_SHARE_SHARED)
769  {
771  {
772  /*
773  * Do nothing - in sharing mode already
774  */
775  }
776  else
777  {
778  /*
779  * We are in exclusive mode but want to share now
780  */
781  (void)RFUnlockSharing(hCard, rContext);
783  }
784  }
785  else if (dwShareMode == SCARD_SHARE_DIRECT)
786  {
788  {
789  /*
790  * Do nothing - in sharing mode already
791  */
792  }
793  else
794  {
795  /*
796  * We are in exclusive mode but want to share now
797  */
798  (void)RFUnlockSharing(hCard, rContext);
800  }
801  }
802  else
803  {
805  goto exit;
806  }
807 
808  /*
809  * Clear a previous event to the application
810  */
811  (void)RFClearReaderEventState(rContext, hCard);
812 
813  /*
814  * Propagate new state to reader state
815  */
816  rContext->readerState->readerSharing = rContext->contexts;
817 
818  rv = SCARD_S_SUCCESS;
819 
820 exit:
821  UNREF_READER(rContext)
822 
823  return rv;
824 }
825 
826 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
827 {
828  LONG rv;
829  READER_CONTEXT * rContext = NULL;
830 
831  if (hCard == 0)
832  return SCARD_E_INVALID_HANDLE;
833 
834  if ((dwDisposition != SCARD_LEAVE_CARD)
835  && (dwDisposition != SCARD_UNPOWER_CARD)
836  && (dwDisposition != SCARD_RESET_CARD)
837  && (dwDisposition != SCARD_EJECT_CARD))
838  return SCARD_E_INVALID_VALUE;
839 
840  /* get rContext corresponding to hCard */
841  rv = RFReaderInfoById(hCard, &rContext);
842  if (rv != SCARD_S_SUCCESS)
843  return rv;
844 
845  /*
846  * wait until a possible transaction is finished
847  */
848  if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->hLockId != 0)
849  && (rContext->hLockId != hCard))
850  {
851  Log1(PCSC_LOG_INFO, "Waiting for release of lock");
852  while (rContext->hLockId != 0)
854  Log1(PCSC_LOG_INFO, "Lock released");
855  }
856 
857  /*
858  * Try to unlock any blocks on this context
859  *
860  * This may fail with SCARD_E_SHARING_VIOLATION if a transaction is
861  * on going on another card context and dwDisposition == SCARD_LEAVE_CARD.
862  * We should not stop.
863  */
864  rv = RFUnlockAllSharing(hCard, rContext);
865  if (rv != SCARD_S_SUCCESS)
866  {
867  if (rv != SCARD_E_SHARING_VIOLATION)
868  {
869  goto exit;
870  }
871  else
872  {
873  if (SCARD_LEAVE_CARD != dwDisposition)
874  goto exit;
875  }
876  }
877 
878  Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->contexts);
879  Log2(PCSC_LOG_DEBUG, "dwDisposition: %ld", dwDisposition);
880 
881  if (dwDisposition == SCARD_RESET_CARD ||
882  dwDisposition == SCARD_UNPOWER_CARD)
883  {
884  DWORD dwAtrLen;
885 
886  /*
887  * Notify the card has been reset
888  */
889  RFSetReaderEventState(rContext, SCARD_RESET);
890 
891  dwAtrLen = sizeof(rContext->readerState->cardAtr);
892  if (SCARD_RESET_CARD == dwDisposition)
893  rv = IFDPowerICC(rContext, IFD_RESET,
894  rContext->readerState->cardAtr, &dwAtrLen);
895  else
896  {
897  /* SCARD_UNPOWER_CARD */
898  rv = IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
899 
900  rContext->powerState = POWER_STATE_UNPOWERED;
901  Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED");
902  }
903 
904  /* the protocol is unset after a power on */
906 
907  if (rv == SCARD_S_SUCCESS)
908  {
909  if (SCARD_UNPOWER_CARD == dwDisposition)
911  else
912  {
913  rContext->readerState->cardAtrLength = dwAtrLen;
914  rContext->readerState->readerState =
916 
917  Log1(PCSC_LOG_DEBUG, "Reset complete.");
918  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
919  rContext->readerState->cardAtr,
920  rContext->readerState->cardAtrLength);
921  }
922  }
923  else
924  {
925  if (SCARD_UNPOWER_CARD == dwDisposition)
926  Log3(PCSC_LOG_ERROR, "Error powering down card: %ld 0x%04lX",
927  rv, rv);
928  else
929  {
930  rContext->readerState->cardAtrLength = 0;
931  Log1(PCSC_LOG_ERROR, "Error resetting card.");
932  }
933 
934  if (rv == SCARD_W_REMOVED_CARD)
935  rContext->readerState->readerState = SCARD_ABSENT;
936  else
937  rContext->readerState->readerState =
939  }
940  }
941  else if (dwDisposition == SCARD_EJECT_CARD)
942  {
943  UCHAR controlBuffer[5];
944  UCHAR receiveBuffer[MAX_BUFFER_SIZE];
945  DWORD receiveLength;
946 
947  /*
948  * Set up the CTBCS command for Eject ICC
949  */
950  controlBuffer[0] = 0x20;
951  controlBuffer[1] = 0x15;
952  controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1;
953  controlBuffer[3] = 0x00;
954  controlBuffer[4] = 0x00;
955  receiveLength = 2;
956  rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
957  &receiveLength);
958 
959  if (rv == SCARD_S_SUCCESS)
960  {
961  if (receiveLength == 2 && receiveBuffer[0] == 0x90)
962  {
963  Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
964  /*
965  * Successful
966  */
967  }
968  else
969  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
970  }
971  else
972  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
973 
974  }
975  else if (dwDisposition == SCARD_LEAVE_CARD)
976  {
977  /*
978  * Do nothing
979  */
980  }
981 
982  /*
983  * Remove and destroy this handle
984  */
985  (void)RFRemoveReaderHandle(rContext, hCard);
986 
987  /*
988  * For exclusive connection reset it to no connections
989  */
992  else
993  {
994  /*
995  * Remove a connection from the context stack
996  */
997  rContext->contexts -= 1;
998 
999  if (rContext->contexts < 0)
1000  rContext->contexts = 0;
1001  }
1002 
1003  if (PCSCLITE_SHARING_NO_CONTEXT == rContext->contexts)
1004  {
1005  RESPONSECODE (*fct)(DWORD) = NULL;
1006  DWORD dwGetSize;
1007 
1008  (void)pthread_mutex_lock(&rContext->powerState_lock);
1009  /* Switch to POWER_STATE_GRACE_PERIOD unless the card was not
1010  * powered */
1011  if (POWER_STATE_POWERED <= rContext->powerState)
1012  {
1014  Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_GRACE_PERIOD");
1015  }
1016 
1017  (void)pthread_mutex_unlock(&rContext->powerState_lock);
1018 
1019  /* ask to stop the "polling" thread so it can be restarted using
1020  * the correct timeout */
1021  dwGetSize = sizeof(fct);
1023  &dwGetSize, (PUCHAR)&fct);
1024 
1025  if ((IFD_SUCCESS == rv) && (dwGetSize == sizeof(fct)))
1026  {
1027  Log1(PCSC_LOG_INFO, "Stopping polling thread");
1028  fct(rContext->slot);
1029  }
1030  }
1031 
1032  /*
1033  * Propagate new state to reader state
1034  */
1035  rContext->readerState->readerSharing = rContext->contexts;
1036 
1037  rv = SCARD_S_SUCCESS;
1038 
1039 exit:
1040  UNREF_READER(rContext)
1041 
1042  return rv;
1043 }
1044 
1045 LONG SCardBeginTransaction(SCARDHANDLE hCard)
1046 {
1047  LONG rv;
1048  READER_CONTEXT * rContext;
1049 
1050  if (hCard == 0)
1051  return SCARD_E_INVALID_HANDLE;
1052 
1053  /* get rContext corresponding to hCard */
1054  rv = RFReaderInfoById(hCard, &rContext);
1055  if (rv != SCARD_S_SUCCESS)
1056  return rv;
1057 
1058  /*
1059  * Make sure the reader is working properly
1060  */
1061  rv = RFCheckReaderStatus(rContext);
1062  if (rv != SCARD_S_SUCCESS)
1063  goto exit;
1064 
1065  /*
1066  * Make sure some event has not occurred
1067  */
1068  rv = RFCheckReaderEventState(rContext, hCard);
1069  if (rv != SCARD_S_SUCCESS)
1070  goto exit;
1071 
1072  rv = RFLockSharing(hCard, rContext);
1073 
1074  /* if the transaction is not yet ready we sleep a bit so the client
1075  * do not retry immediately */
1076  if (SCARD_E_SHARING_VIOLATION == rv)
1078 
1079  Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv);
1080 
1081 exit:
1082  UNREF_READER(rContext)
1083 
1084  return rv;
1085 }
1086 
1087 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
1088 {
1089  LONG rv;
1090  LONG rv2;
1091  READER_CONTEXT * rContext = NULL;
1092 
1093  /*
1094  * Ignoring dwDisposition for now
1095  */
1096  if (hCard == 0)
1097  return SCARD_E_INVALID_HANDLE;
1098 
1099  if ((dwDisposition != SCARD_LEAVE_CARD)
1100  && (dwDisposition != SCARD_UNPOWER_CARD)
1101  && (dwDisposition != SCARD_RESET_CARD)
1102  && (dwDisposition != SCARD_EJECT_CARD))
1103  return SCARD_E_INVALID_VALUE;
1104 
1105  /* get rContext corresponding to hCard */
1106  rv = RFReaderInfoById(hCard, &rContext);
1107  if (rv != SCARD_S_SUCCESS)
1108  return rv;
1109 
1110  /*
1111  * Make sure some event has not occurred
1112  */
1113  rv = RFCheckReaderEventState(rContext, hCard);
1114  if (rv != SCARD_S_SUCCESS)
1115  goto exit;
1116 
1117  /*
1118  * Error if another transaction is ongoing and a card action is
1119  * requested
1120  */
1121  if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->hLockId != 0)
1122  && (rContext->hLockId != hCard))
1123  {
1124  Log1(PCSC_LOG_INFO, "No card reset within a transaction");
1126  goto exit;
1127  }
1128 
1129  if (dwDisposition == SCARD_RESET_CARD ||
1130  dwDisposition == SCARD_UNPOWER_CARD)
1131  {
1132  DWORD dwAtrLen;
1133 
1134  /*
1135  * Currently pcsc-lite keeps the card always powered
1136  */
1137  dwAtrLen = sizeof(rContext->readerState->cardAtr);
1138  if (SCARD_RESET_CARD == dwDisposition)
1139  rv = IFDPowerICC(rContext, IFD_RESET,
1140  rContext->readerState->cardAtr, &dwAtrLen);
1141  else
1142  {
1143  IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
1144  rv = IFDPowerICC(rContext, IFD_POWER_UP,
1145  rContext->readerState->cardAtr, &dwAtrLen);
1146  }
1147 
1148  /* the protocol is unset after a power on */
1150 
1151  /*
1152  * Notify the card has been reset
1153  */
1154  RFSetReaderEventState(rContext, SCARD_RESET);
1155 
1156  /*
1157  * Set up the status bit masks on readerState
1158  */
1159  if (rv == SCARD_S_SUCCESS)
1160  {
1161  rContext->readerState->cardAtrLength = dwAtrLen;
1162  rContext->readerState->readerState =
1164 
1165  Log1(PCSC_LOG_DEBUG, "Reset complete.");
1166  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
1167  rContext->readerState->cardAtr,
1168  rContext->readerState->cardAtrLength);
1169  }
1170  else
1171  {
1172  rContext->readerState->cardAtrLength = 0;
1173  Log1(PCSC_LOG_ERROR, "Error resetting card.");
1174 
1175  if (rv == SCARD_W_REMOVED_CARD)
1176  rContext->readerState->readerState = SCARD_ABSENT;
1177  else
1178  rContext->readerState->readerState =
1180  }
1181  }
1182  else if (dwDisposition == SCARD_EJECT_CARD)
1183  {
1184  UCHAR controlBuffer[5];
1185  UCHAR receiveBuffer[MAX_BUFFER_SIZE];
1186  DWORD receiveLength;
1187 
1188  /*
1189  * Set up the CTBCS command for Eject ICC
1190  */
1191  controlBuffer[0] = 0x20;
1192  controlBuffer[1] = 0x15;
1193  controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1;
1194  controlBuffer[3] = 0x00;
1195  controlBuffer[4] = 0x00;
1196  receiveLength = 2;
1197  rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
1198  &receiveLength);
1199 
1200  if (rv == SCARD_S_SUCCESS)
1201  {
1202  if (receiveLength == 2 && receiveBuffer[0] == 0x90)
1203  {
1204  Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
1205  /*
1206  * Successful
1207  */
1208  }
1209  else
1210  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1211  }
1212  else
1213  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1214 
1215  }
1216  else if (dwDisposition == SCARD_LEAVE_CARD)
1217  {
1218  /*
1219  * Do nothing
1220  */
1221  }
1222 
1223  /*
1224  * Unlock any blocks on this context
1225  */
1226  /* we do not want to lose the previous rv value
1227  * So we use another variable */
1228  rv2 = RFUnlockSharing(hCard, rContext);
1229  if (rv2 != SCARD_S_SUCCESS)
1230  /* if rv is already in error then do not change its value */
1231  if (rv == SCARD_S_SUCCESS)
1232  rv = rv2;
1233 
1234  Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv);
1235 
1236 exit:
1237  UNREF_READER(rContext)
1238 
1239  return rv;
1240 }
1241 
1242 LONG SCardStatus(SCARDHANDLE hCard, LPSTR szReaderNames,
1243  LPDWORD pcchReaderLen, LPDWORD pdwState,
1244  LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1245 {
1246  LONG rv;
1247  READER_CONTEXT * rContext = NULL;
1248 
1249  /* These parameters are not used by the client
1250  * Client side code uses readerStates[] instead */
1251  (void)szReaderNames;
1252  (void)pcchReaderLen;
1253  (void)pdwState;
1254  (void)pdwProtocol;
1255  (void)pbAtr;
1256  (void)pcbAtrLen;
1257 
1258  if (hCard == 0)
1259  return SCARD_E_INVALID_HANDLE;
1260 
1261  /* get rContext corresponding to hCard */
1262  rv = RFReaderInfoById(hCard, &rContext);
1263  if (rv != SCARD_S_SUCCESS)
1264  return rv;
1265 
1266  /*
1267  * Make sure no one has a lock on this reader
1268  */
1269  rv = RFCheckSharing(hCard, rContext);
1270  if (rv != SCARD_S_SUCCESS)
1271  goto exit;
1272 
1273  if (rContext->readerState->cardAtrLength > MAX_ATR_SIZE)
1274  {
1276  goto exit;
1277  }
1278 
1279  /*
1280  * This is a client side function however the server maintains the
1281  * list of events between applications so it must be passed through to
1282  * obtain this event if it has occurred
1283  */
1284 
1285  /*
1286  * Make sure some event has not occurred
1287  */
1288  rv = RFCheckReaderEventState(rContext, hCard);
1289  if (rv != SCARD_S_SUCCESS)
1290  goto exit;
1291 
1292  /*
1293  * Make sure the reader is working properly
1294  */
1295  rv = RFCheckReaderStatus(rContext);
1296  if (rv != SCARD_S_SUCCESS)
1297  goto exit;
1298 
1299 exit:
1300  UNREF_READER(rContext)
1301 
1302  return rv;
1303 }
1304 
1305 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
1306  LPCVOID pbSendBuffer, DWORD cbSendLength,
1307  LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
1308 {
1309  LONG rv;
1310  READER_CONTEXT * rContext = NULL;
1311 
1312  /* 0 bytes returned by default */
1313  *lpBytesReturned = 0;
1314 
1315  if (0 == hCard)
1316  return SCARD_E_INVALID_HANDLE;
1317 
1318  /* get rContext corresponding to hCard */
1319  rv = RFReaderInfoById(hCard, &rContext);
1320  if (rv != SCARD_S_SUCCESS)
1321  return rv;
1322 
1323  /*
1324  * Make sure no one has a lock on this reader
1325  */
1326  rv = RFCheckSharing(hCard, rContext);
1327  if (rv != SCARD_S_SUCCESS)
1328  goto exit;
1329 
1330  if (IFD_HVERSION_2_0 == rContext->version)
1331  if (NULL == pbSendBuffer || 0 == cbSendLength)
1332  {
1334  goto exit;
1335  }
1336 
1337  /*
1338  * Make sure the reader is working properly
1339  */
1340  rv = RFCheckReaderStatus(rContext);
1341  if (rv != SCARD_S_SUCCESS)
1342  goto exit;
1343 
1344  if (IFD_HVERSION_2_0 == rContext->version)
1345  {
1346  /* we must wrap a API 3.0 client in an API 2.0 driver */
1347  *lpBytesReturned = cbRecvLength;
1348  rv = IFDControl_v2(rContext, (PUCHAR)pbSendBuffer,
1349  cbSendLength, pbRecvBuffer, lpBytesReturned);
1350  }
1351  else
1352  if (IFD_HVERSION_3_0 == rContext->version)
1353  rv = IFDControl(rContext, dwControlCode, pbSendBuffer,
1354  cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned);
1355  else
1357 
1358 exit:
1359  UNREF_READER(rContext)
1360 
1361  return rv;
1362 }
1363 
1364 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1365  LPBYTE pbAttr, LPDWORD pcbAttrLen)
1366 {
1367  LONG rv;
1368  READER_CONTEXT * rContext = NULL;
1369 
1370  if (0 == hCard)
1371  return SCARD_E_INVALID_HANDLE;
1372 
1373  /* get rContext corresponding to hCard */
1374  rv = RFReaderInfoById(hCard, &rContext);
1375  if (rv != SCARD_S_SUCCESS)
1376  return rv;
1377 
1378  /*
1379  * Make sure no one has a lock on this reader
1380  */
1381  rv = RFCheckSharing(hCard, rContext);
1382  if (rv != SCARD_S_SUCCESS)
1383  goto exit;
1384 
1385  /*
1386  * Make sure the reader is working properly
1387  */
1388  rv = RFCheckReaderStatus(rContext);
1389  if (rv != SCARD_S_SUCCESS)
1390  goto exit;
1391 
1392  /*
1393  * Make sure some event has not occurred
1394  */
1395  rv = RFCheckReaderEventState(rContext, hCard);
1396  if (rv != SCARD_S_SUCCESS)
1397  goto exit;
1398 
1399  rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr);
1400  switch(rv)
1401  {
1402  case IFD_SUCCESS:
1403  rv = SCARD_S_SUCCESS;
1404  break;
1405  case IFD_ERROR_TAG:
1406  /* Special case SCARD_ATTR_DEVICE_FRIENDLY_NAME as it is better
1407  * implemented in pcscd (it knows the friendly name)
1408  */
1409  if ((SCARD_ATTR_DEVICE_FRIENDLY_NAME == dwAttrId)
1410  || (SCARD_ATTR_DEVICE_SYSTEM_NAME == dwAttrId))
1411  {
1412  unsigned int len = strlen(rContext->readerState->readerName)+1;
1413 
1414  if (len > *pcbAttrLen)
1416  else
1417  {
1418  strcpy((char *)pbAttr, rContext->readerState->readerName);
1419  rv = SCARD_S_SUCCESS;
1420  }
1421  *pcbAttrLen = len;
1422  }
1423  else
1425  break;
1428  break;
1429  default:
1431  }
1432 
1433 exit:
1434  UNREF_READER(rContext)
1435 
1436  return rv;
1437 }
1438 
1439 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1440  LPCBYTE pbAttr, DWORD cbAttrLen)
1441 {
1442  LONG rv;
1443  READER_CONTEXT * rContext = NULL;
1444 
1445  if (0 == hCard)
1446  return SCARD_E_INVALID_HANDLE;
1447 
1448  /* get rContext corresponding to hCard */
1449  rv = RFReaderInfoById(hCard, &rContext);
1450  if (rv != SCARD_S_SUCCESS)
1451  return rv;
1452 
1453  /*
1454  * Make sure no one has a lock on this reader
1455  */
1456  rv = RFCheckSharing(hCard, rContext);
1457  if (rv != SCARD_S_SUCCESS)
1458  goto exit;
1459 
1460  /*
1461  * Make sure the reader is working properly
1462  */
1463  rv = RFCheckReaderStatus(rContext);
1464  if (rv != SCARD_S_SUCCESS)
1465  goto exit;
1466 
1467  /*
1468  * Make sure some event has not occurred
1469  */
1470  rv = RFCheckReaderEventState(rContext, hCard);
1471  if (rv != SCARD_S_SUCCESS)
1472  goto exit;
1473 
1474  rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr);
1475  if (rv == IFD_SUCCESS)
1476  rv = SCARD_S_SUCCESS;
1477  else
1478  if (rv == IFD_ERROR_TAG)
1480  else
1482 
1483 exit:
1484  UNREF_READER(rContext)
1485 
1486  return rv;
1487 }
1488 
1489 LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
1490  LPCBYTE pbSendBuffer, DWORD cbSendLength,
1491  SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer,
1492  LPDWORD pcbRecvLength)
1493 {
1494  LONG rv;
1495  READER_CONTEXT * rContext = NULL;
1496  SCARD_IO_HEADER sSendPci, sRecvPci;
1497  DWORD dwRxLength, tempRxLength;
1498 
1499  dwRxLength = *pcbRecvLength;
1500  *pcbRecvLength = 0;
1501 
1502  if (hCard == 0)
1503  return SCARD_E_INVALID_HANDLE;
1504 
1505  /*
1506  * Must at least have 2 status words even for SCardControl
1507  */
1508  if (dwRxLength < 2)
1510 
1511  /* get rContext corresponding to hCard */
1512  rv = RFReaderInfoById(hCard, &rContext);
1513  if (rv != SCARD_S_SUCCESS)
1514  return rv;
1515 
1516  /*
1517  * Make sure no one has a lock on this reader
1518  */
1519  rv = RFCheckSharing(hCard, rContext);
1520  if (rv != SCARD_S_SUCCESS)
1521  goto exit;
1522 
1523  /*
1524  * Make sure the reader is working properly
1525  */
1526  rv = RFCheckReaderStatus(rContext);
1527  if (rv != SCARD_S_SUCCESS)
1528  goto exit;
1529 
1530  /*
1531  * Make sure some event has not occurred
1532  */
1533  rv = RFCheckReaderEventState(rContext, hCard);
1534  if (rv != SCARD_S_SUCCESS)
1535  goto exit;
1536 
1537  /*
1538  * Check for some common errors
1539  */
1540  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1541  {
1542  if (rContext->readerState->readerState & SCARD_ABSENT)
1543  {
1544  rv = SCARD_E_NO_SMARTCARD;
1545  goto exit;
1546  }
1547  }
1548 
1549  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1550  {
1551  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD)
1552  {
1553  if (pioSendPci->dwProtocol != rContext->readerState->cardProtocol)
1554  {
1556  goto exit;
1557  }
1558  }
1559  }
1560 
1561  /*
1562  * Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler
1563  * just wants 0 or 1
1564  */
1565 
1566  sSendPci.Protocol = 0; /* protocol T=0 by default */
1567 
1568  if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1)
1569  {
1570  sSendPci.Protocol = 1;
1571  } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1572  {
1573  /*
1574  * This is temporary ......
1575  */
1576  sSendPci.Protocol = SCARD_PROTOCOL_RAW;
1577  } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD)
1578  {
1579  /* Fix by Amira (Athena) */
1580  unsigned long i;
1581  unsigned long prot = rContext->readerState->cardProtocol;
1582 
1583  for (i = 0 ; prot != 1 ; i++)
1584  prot >>= 1;
1585 
1586  sSendPci.Protocol = i;
1587  }
1588 
1589  sSendPci.Length = pioSendPci->cbPciLength;
1590 
1591  sRecvPci.Protocol = pioRecvPci->dwProtocol;
1592  sRecvPci.Length = pioRecvPci->cbPciLength;
1593 
1594  /* the protocol number is decoded a few lines above */
1595  Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%ld", sSendPci.Protocol);
1596 
1597  tempRxLength = dwRxLength;
1598 
1599  if ((pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1600  && (rContext->version == IFD_HVERSION_2_0))
1601  {
1602  rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength,
1603  pbRecvBuffer, &dwRxLength);
1604  } else
1605  {
1606  rv = IFDTransmit(rContext, sSendPci, (PUCHAR) pbSendBuffer,
1607  cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci);
1608  }
1609 
1610  pioRecvPci->dwProtocol = sRecvPci.Protocol;
1611  pioRecvPci->cbPciLength = sRecvPci.Length;
1612 
1613  /*
1614  * Check for any errors that might have occurred
1615  */
1616 
1617  if (rv != SCARD_S_SUCCESS)
1618  {
1619  *pcbRecvLength = 0;
1620  Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv);
1621  goto exit;
1622  }
1623 
1624  /*
1625  * Available is less than received
1626  */
1627  if (tempRxLength < dwRxLength)
1628  {
1629  *pcbRecvLength = 0;
1631  goto exit;
1632  }
1633 
1634  /*
1635  * Successful return
1636  */
1637  *pcbRecvLength = dwRxLength;
1638 
1639 exit:
1640  UNREF_READER(rContext)
1641 
1642  return rv;
1643 }
1644 
struct pubReaderStatesList * readerState
link to the reader state
#define SCARD_E_INVALID_VALUE
One or more of the supplied parameters values could not be properly interpreted.
Definition: pcsclite.h:141
uint32_t cardAtrLength
ATR length.
Definition: eventhandler.h:56
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME
Reader&#39;s display name.
Definition: reader.h:111
int32_t contexts
Number of open contexts.
#define IFD_ERROR_TAG
tag unknown
Definition: ifdhandler.h:352
volatile SCARDHANDLE hLockId
Lock Id.
#define SCARD_SCOPE_USER
Scope in user space.
Definition: pcsclite.h:234
#define TAG_IFD_STOP_POLLING_THREAD
method used to stop the polling thread (instead of just pthread_kill())
Definition: ifdhandler.h:330
#define SCARD_ATTR_DEVICE_SYSTEM_NAME
Reader&#39;s system name.
Definition: reader.h:112
#define SCARD_S_SUCCESS
No error was encountered.
Definition: pcsclite.h:107
#define PCSCLITE_SHARING_NO_CONTEXT
No application is using the reader.
Definition: eventhandler.h:73
#define SCARD_SCOPE_GLOBAL
Scope is global.
Definition: pcsclite.h:237
#define MAX_BUFFER_SIZE
Maximum Tx/Rx Buffer for short APDU.
Definition: pcsclite.h:297
#define SCARD_E_INVALID_PARAMETER
One or more of the supplied parameters could not be properly interpreted.
Definition: pcsclite.h:115
LONG IFDGetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, PDWORD pdwLength, PUCHAR pucValue)
Get&#39;s capabilities in the reader.
Definition: ifdwrapper.c:235
This keeps a list of defines shared between the driver and the application.
char readerName[MAX_READERNAME]
reader name
Definition: eventhandler.h:50
unsigned long cbPciLength
Protocol Control Inf Length.
Definition: pcsclite.h:82
int32_t readerSharing
PCSCLITE_SHARING_* sharing status.
Definition: eventhandler.h:53
#define SCARD_LEAVE_CARD
Do nothing on close.
Definition: pcsclite.h:252
This handles protocol defaults, PTS, etc.
This handles abstract system level calls.
int slot
Current Reader Slot.
#define SCARD_E_NO_SMARTCARD
The operation requires a Smart Card, but no Smart Card is currently in the device.
Definition: pcsclite.h:131
This wraps the dynamic ifdhandler functions.
#define SCARD_W_UNRESPONSIVE_CARD
The smart card is not responding to a reset.
Definition: pcsclite.h:212
#define SCARD_E_NOT_TRANSACTED
An attempt was made to end a non-existent transaction.
Definition: pcsclite.h:151
#define SCARD_PROTOCOL_T1
T=1 active protocol.
Definition: pcsclite.h:242
#define SCARD_SCOPE_TERMINAL
Scope in terminal.
Definition: pcsclite.h:235
#define SCARD_E_PROTO_MISMATCH
The requested protocols are incompatible with the protocol currently in use with the smart card...
Definition: pcsclite.h:137
#define SCARD_PROTOCOL_ANY_OLD
used for backward compatibility
Definition: winscard.c:191
#define SCARD_PRESENT
Card is present.
Definition: pcsclite.h:259
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
Definition: sys_unix.c:71
#define SCARD_NEGOTIABLE
Ready for PTS.
Definition: pcsclite.h:262
#define PCSCLITE_SHARING_EXCLUSIVE_CONTEXT
Reader used in exclusive mode.
Definition: eventhandler.h:75
#define PCSCLITE_LOCK_POLL_RATE
Lock polling rate.
Definition: pcscd.h:54
LONG SCARDCONTEXT
hContext returned by SCardEstablishContext()
Definition: pcsclite.h:52
This keeps track of smart card protocols, timing issues and Answer to Reset ATR handling.
#define SCARD_RESET
Card was reset.
Definition: pcscd.h:41
#define SCARD_SHARE_SHARED
Shared mode only.
Definition: pcsclite.h:249
LONG IFDTransmit(READER_CONTEXT *rContext, SCARD_IO_HEADER pioTxPci, PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer, PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
Transmit an APDU to the ICC.
Definition: ifdwrapper.c:502
unsigned long dwProtocol
Protocol identifier.
Definition: pcsclite.h:81
#define IFD_POWER_DOWN
power down the card
Definition: ifdhandler.h:344
card is used
Definition: pcscd.h:69
int version
IFD Handler version number.
#define SCARD_PROTOCOL_T0
T=0 active protocol.
Definition: pcsclite.h:241
pthread_mutex_t * mMutex
Mutex for this connection.
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:136
short ATRDecodeAtr(int *availableProtocols, int *currentProtocol, PUCHAR pucAtr, DWORD dwLength)
parse an ATR
Definition: atrhandler.c:66
This handles card insertion/removal events, updates ATR, protocol, and status information.
#define SCARD_UNPOWER_CARD
Power down on close.
Definition: pcsclite.h:254
LONG IFDSetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, DWORD dwLength, PUCHAR pucValue)
Set capabilities in the reader.
Definition: ifdwrapper.c:204
#define SCARD_SWALLOWED
Card not powered.
Definition: pcsclite.h:260
#define SCARD_W_REMOVED_CARD
The smart card has been removed, so further communication is not possible.
Definition: pcsclite.h:218
int powerState
auto power off state
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
Definition: pcsclite.h:239
#define SCARD_RESET_CARD
Reset on close.
Definition: pcsclite.h:253
UCHAR cardAtr[MAX_ATR_SIZE]
ATR.
Definition: eventhandler.h:55
int SYS_RandomInt(int, int)
Generate a pseudo random number.
Definition: sys_unix.c:95
LONG SCARDHANDLE
hCard returned by SCardConnect()
Definition: pcsclite.h:55
LONG IFDPowerICC(READER_CONTEXT *rContext, DWORD dwAction, PUCHAR pucAtr, PDWORD pdwAtrLen)
Power up/down or reset&#39;s an ICC located in the IFD.
Definition: ifdwrapper.c:265
#define SCARD_E_INSUFFICIENT_BUFFER
The data buffer to receive returned data is too small for the returned data.
Definition: pcsclite.h:123
#define SCARD_SHARE_EXCLUSIVE
Exclusive mode only.
Definition: pcsclite.h:248
#define SCARD_POWERED
Card is powered.
Definition: pcsclite.h:261
card was in use
Definition: pcscd.h:68
DWORD PHSetProtocol(struct ReaderContext *rContext, DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault)
Determine which protocol to use.
Definition: prothandler.c:60
This keeps a list of defines for pcsc-lite.
#define SCARD_PROTOCOL_RAW
Raw active protocol.
Definition: pcsclite.h:243
#define SCARD_EJECT_CARD
Eject on close.
Definition: pcsclite.h:255
Protocol Control Information (PCI)
Definition: pcsclite.h:79
#define SCARD_ABSENT
Card is absent.
Definition: pcsclite.h:258
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
Definition: eventhandler.h:57
auto power off
Definition: pcscd.h:66
#define SCARD_E_SHARING_VIOLATION
The smart card cannot be accessed because of other connections outstanding.
Definition: pcsclite.h:129
This keeps track of a list of currently available reader structures.
#define MAX_ATR_SIZE
Maximum ATR size.
Definition: pcsclite.h:59
#define IFD_ERROR_INSUFFICIENT_BUFFER
buffer is too small
Definition: ifdhandler.h:373
uint32_t readerState
SCARD_* bit field.
Definition: eventhandler.h:52
#define SCARD_F_INTERNAL_ERROR
An internal consistency check failed.
Definition: pcsclite.h:109
#define SCARD_SHARE_DIRECT
Raw mode only.
Definition: pcsclite.h:250
#define PCSCLITE_SHARING_LAST_CONTEXT
One application is using the reader.
Definition: eventhandler.h:71
pthread_mutex_t powerState_lock
powerState mutex
#define SCARD_E_UNSUPPORTED_FEATURE
This smart card does not support the requested feature.
Definition: pcsclite.h:171
Use by SCardTransmit()
Definition: ifdhandler.h:311
#define SCARD_E_INVALID_HANDLE
The supplied handle was invalid.
Definition: pcsclite.h:113
#define IFD_RESET
warm reset
Definition: ifdhandler.h:345
#define SCARD_SCOPE_SYSTEM
Scope in system.
Definition: pcsclite.h:236
This handles smart card reader communications.
#define IFD_POWER_UP
power up the card
Definition: ifdhandler.h:343
This handles debugging.
#define IFD_SUCCESS
no error
Definition: ifdhandler.h:351
LONG IFDControl(READER_CONTEXT *rContext, DWORD ControlCode, LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength, LPDWORD BytesReturned)
Provide a means for toggling a specific action on the reader such as swallow, eject, biometric.
Definition: ifdwrapper.c:442
#define SCARD_W_UNPOWERED_CARD
Power has been removed from the smart card, so that further communication is not possible.
Definition: pcsclite.h:214