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