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