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