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