pcsc-lite  1.8.15
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  if (dwDisposition == SCARD_RESET_CARD ||
1141  dwDisposition == SCARD_UNPOWER_CARD)
1142  {
1143  DWORD dwAtrLen;
1144 
1145  /*
1146  * Currently pcsc-lite keeps the card always powered
1147  */
1148  dwAtrLen = sizeof(rContext->readerState->cardAtr);
1149  if (SCARD_RESET_CARD == dwDisposition)
1150  rv = IFDPowerICC(rContext, IFD_RESET,
1151  rContext->readerState->cardAtr, &dwAtrLen);
1152  else
1153  {
1154  IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
1155  rv = IFDPowerICC(rContext, IFD_POWER_UP,
1156  rContext->readerState->cardAtr, &dwAtrLen);
1157  }
1158 
1159  /* the protocol is unset after a power on */
1161 
1162  /*
1163  * Notify the card has been reset
1164  */
1165  (void)RFSetReaderEventState(rContext, SCARD_RESET);
1166 
1167  /*
1168  * Set up the status bit masks on readerState
1169  */
1170  if (rv == SCARD_S_SUCCESS)
1171  {
1172  rContext->readerState->cardAtrLength = dwAtrLen;
1173  rContext->readerState->readerState =
1175 
1176  Log1(PCSC_LOG_DEBUG, "Reset complete.");
1177  LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
1178  rContext->readerState->cardAtr,
1179  rContext->readerState->cardAtrLength);
1180  }
1181  else
1182  {
1183  rContext->readerState->cardAtrLength = 0;
1184  Log1(PCSC_LOG_ERROR, "Error resetting card.");
1185 
1186  if (rv == SCARD_W_REMOVED_CARD)
1187  rContext->readerState->readerState = SCARD_ABSENT;
1188  else
1189  rContext->readerState->readerState =
1191  }
1192  }
1193  else if (dwDisposition == SCARD_EJECT_CARD)
1194  {
1195  UCHAR controlBuffer[5];
1196  UCHAR receiveBuffer[MAX_BUFFER_SIZE];
1197  DWORD receiveLength;
1198 
1199  /*
1200  * Set up the CTBCS command for Eject ICC
1201  */
1202  controlBuffer[0] = 0x20;
1203  controlBuffer[1] = 0x15;
1204  controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1;
1205  controlBuffer[3] = 0x00;
1206  controlBuffer[4] = 0x00;
1207  receiveLength = 2;
1208  rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
1209  &receiveLength);
1210 
1211  if (rv == SCARD_S_SUCCESS)
1212  {
1213  if (receiveLength == 2 && receiveBuffer[0] == 0x90)
1214  {
1215  Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
1216  /*
1217  * Successful
1218  */
1219  }
1220  else
1221  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1222  }
1223  else
1224  Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1225 
1226  }
1227  else if (dwDisposition == SCARD_LEAVE_CARD)
1228  {
1229  /*
1230  * Do nothing
1231  */
1232  }
1233 
1234  /*
1235  * Unlock any blocks on this context
1236  */
1237  /* we do not want to lose the previous rv value
1238  * So we use another variable */
1239  rv2 = RFUnlockSharing(hCard, rContext);
1240  if (rv2 != SCARD_S_SUCCESS)
1241  /* if rv is already in error then do not change its value */
1242  if (rv == SCARD_S_SUCCESS)
1243  rv = rv2;
1244 
1245  Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv);
1246 
1247 exit:
1248  UNREF_READER(rContext)
1249 
1250  return rv;
1251 }
1252 
1253 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames,
1254  LPDWORD pcchReaderLen, LPDWORD pdwState,
1255  LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1256 {
1257  LONG rv;
1258  READER_CONTEXT * rContext = NULL;
1259 
1260  /* These parameters are not used by the client
1261  * Client side code uses readerStates[] instead */
1262  (void)mszReaderNames;
1263  (void)pcchReaderLen;
1264  (void)pdwState;
1265  (void)pdwProtocol;
1266  (void)pbAtr;
1267  (void)pcbAtrLen;
1268 
1269  if (hCard == 0)
1270  return SCARD_E_INVALID_HANDLE;
1271 
1272  /* get rContext corresponding to hCard */
1273  rv = RFReaderInfoById(hCard, &rContext);
1274  if (rv != SCARD_S_SUCCESS)
1275  return rv;
1276 
1277  /*
1278  * Make sure no one has a lock on this reader
1279  */
1280  rv = RFCheckSharing(hCard, rContext);
1281  if (rv != SCARD_S_SUCCESS)
1282  goto exit;
1283 
1284  if (rContext->readerState->cardAtrLength > MAX_ATR_SIZE)
1285  {
1287  goto exit;
1288  }
1289 
1290  /*
1291  * This is a client side function however the server maintains the
1292  * list of events between applications so it must be passed through to
1293  * obtain this event if it has occurred
1294  */
1295 
1296  /*
1297  * Make sure some event has not occurred
1298  */
1299  rv = RFCheckReaderEventState(rContext, hCard);
1300  if (rv != SCARD_S_SUCCESS)
1301  goto exit;
1302 
1303  /*
1304  * Make sure the reader is working properly
1305  */
1306  rv = RFCheckReaderStatus(rContext);
1307  if (rv != SCARD_S_SUCCESS)
1308  goto exit;
1309 
1310 exit:
1311  UNREF_READER(rContext)
1312 
1313  return rv;
1314 }
1315 
1316 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
1317  LPCVOID pbSendBuffer, DWORD cbSendLength,
1318  LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
1319 {
1320  LONG rv;
1321  READER_CONTEXT * rContext = NULL;
1322 
1323  /* 0 bytes returned by default */
1324  *lpBytesReturned = 0;
1325 
1326  if (0 == hCard)
1327  return SCARD_E_INVALID_HANDLE;
1328 
1329  /* get rContext corresponding to hCard */
1330  rv = RFReaderInfoById(hCard, &rContext);
1331  if (rv != SCARD_S_SUCCESS)
1332  return rv;
1333 
1334  /*
1335  * Make sure no one has a lock on this reader
1336  */
1337  rv = RFCheckSharing(hCard, rContext);
1338  if (rv != SCARD_S_SUCCESS)
1339  goto exit;
1340 
1341  if (IFD_HVERSION_2_0 == rContext->version)
1342  if (NULL == pbSendBuffer || 0 == cbSendLength)
1343  {
1345  goto exit;
1346  }
1347 
1348  /*
1349  * Make sure the reader is working properly
1350  */
1351  rv = RFCheckReaderStatus(rContext);
1352  if (rv != SCARD_S_SUCCESS)
1353  goto exit;
1354 
1355  if (IFD_HVERSION_2_0 == rContext->version)
1356  {
1357  /* we must wrap a API 3.0 client in an API 2.0 driver */
1358  *lpBytesReturned = cbRecvLength;
1359  rv = IFDControl_v2(rContext, (PUCHAR)pbSendBuffer,
1360  cbSendLength, pbRecvBuffer, lpBytesReturned);
1361  }
1362  else
1363  if (IFD_HVERSION_3_0 == rContext->version)
1364  rv = IFDControl(rContext, dwControlCode, pbSendBuffer,
1365  cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned);
1366  else
1368 
1369 exit:
1370  UNREF_READER(rContext)
1371 
1372  return rv;
1373 }
1374 
1375 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1376  LPBYTE pbAttr, LPDWORD pcbAttrLen)
1377 {
1378  LONG rv;
1379  READER_CONTEXT * rContext = NULL;
1380 
1381  if (0 == hCard)
1382  return SCARD_E_INVALID_HANDLE;
1383 
1384  /* get rContext corresponding to hCard */
1385  rv = RFReaderInfoById(hCard, &rContext);
1386  if (rv != SCARD_S_SUCCESS)
1387  return rv;
1388 
1389  /*
1390  * Make sure no one has a lock on this reader
1391  */
1392  rv = RFCheckSharing(hCard, rContext);
1393  if (rv != SCARD_S_SUCCESS)
1394  goto exit;
1395 
1396  /*
1397  * Make sure the reader is working properly
1398  */
1399  rv = RFCheckReaderStatus(rContext);
1400  if (rv != SCARD_S_SUCCESS)
1401  goto exit;
1402 
1403  /*
1404  * Make sure some event has not occurred
1405  */
1406  rv = RFCheckReaderEventState(rContext, hCard);
1407  if (rv != SCARD_S_SUCCESS)
1408  goto exit;
1409 
1410  rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr);
1411  switch(rv)
1412  {
1413  case IFD_SUCCESS:
1414  rv = SCARD_S_SUCCESS;
1415  break;
1416  case IFD_ERROR_TAG:
1417  /* Special case SCARD_ATTR_DEVICE_FRIENDLY_NAME as it is better
1418  * implemented in pcscd (it knows the friendly name)
1419  */
1420  if ((SCARD_ATTR_DEVICE_FRIENDLY_NAME == dwAttrId)
1421  || (SCARD_ATTR_DEVICE_SYSTEM_NAME == dwAttrId))
1422  {
1423  unsigned int len = strlen(rContext->readerState->readerName)+1;
1424 
1425  if (len > *pcbAttrLen)
1427  else
1428  {
1429  strcpy((char *)pbAttr, rContext->readerState->readerName);
1430  rv = SCARD_S_SUCCESS;
1431  }
1432  *pcbAttrLen = len;
1433  }
1434  else
1436  break;
1439  break;
1440  default:
1442  }
1443 
1444 exit:
1445  UNREF_READER(rContext)
1446 
1447  return rv;
1448 }
1449 
1450 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1451  LPCBYTE pbAttr, DWORD cbAttrLen)
1452 {
1453  LONG rv;
1454  READER_CONTEXT * rContext = NULL;
1455 
1456  if (0 == hCard)
1457  return SCARD_E_INVALID_HANDLE;
1458 
1459  /* get rContext corresponding to hCard */
1460  rv = RFReaderInfoById(hCard, &rContext);
1461  if (rv != SCARD_S_SUCCESS)
1462  return rv;
1463 
1464  /*
1465  * Make sure no one has a lock on this reader
1466  */
1467  rv = RFCheckSharing(hCard, rContext);
1468  if (rv != SCARD_S_SUCCESS)
1469  goto exit;
1470 
1471  /*
1472  * Make sure the reader is working properly
1473  */
1474  rv = RFCheckReaderStatus(rContext);
1475  if (rv != SCARD_S_SUCCESS)
1476  goto exit;
1477 
1478  /*
1479  * Make sure some event has not occurred
1480  */
1481  rv = RFCheckReaderEventState(rContext, hCard);
1482  if (rv != SCARD_S_SUCCESS)
1483  goto exit;
1484 
1485  rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr);
1486  if (rv == IFD_SUCCESS)
1487  rv = SCARD_S_SUCCESS;
1488  else
1489  if (rv == IFD_ERROR_TAG)
1491  else
1493 
1494 exit:
1495  UNREF_READER(rContext)
1496 
1497  return rv;
1498 }
1499 
1500 LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
1501  LPCBYTE pbSendBuffer, DWORD cbSendLength,
1502  SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer,
1503  LPDWORD pcbRecvLength)
1504 {
1505  LONG rv;
1506  READER_CONTEXT * rContext = NULL;
1507  SCARD_IO_HEADER sSendPci, sRecvPci;
1508  DWORD dwRxLength, tempRxLength;
1509 
1510  dwRxLength = *pcbRecvLength;
1511  *pcbRecvLength = 0;
1512 
1513  if (hCard == 0)
1514  return SCARD_E_INVALID_HANDLE;
1515 
1516  /*
1517  * Must at least have 2 status words even for SCardControl
1518  */
1519  if (dwRxLength < 2)
1521 
1522  /* get rContext corresponding to hCard */
1523  rv = RFReaderInfoById(hCard, &rContext);
1524  if (rv != SCARD_S_SUCCESS)
1525  return rv;
1526 
1527  /*
1528  * Make sure no one has a lock on this reader
1529  */
1530  rv = RFCheckSharing(hCard, rContext);
1531  if (rv != SCARD_S_SUCCESS)
1532  goto exit;
1533 
1534  /*
1535  * Make sure the reader is working properly
1536  */
1537  rv = RFCheckReaderStatus(rContext);
1538  if (rv != SCARD_S_SUCCESS)
1539  goto exit;
1540 
1541  /*
1542  * Make sure some event has not occurred
1543  */
1544  rv = RFCheckReaderEventState(rContext, hCard);
1545  if (rv != SCARD_S_SUCCESS)
1546  goto exit;
1547 
1548  /*
1549  * Check for some common errors
1550  */
1551  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1552  {
1553  if (rContext->readerState->readerState & SCARD_ABSENT)
1554  {
1555  rv = SCARD_E_NO_SMARTCARD;
1556  goto exit;
1557  }
1558  }
1559 
1560  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1561  {
1562  if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD)
1563  {
1564  if (pioSendPci->dwProtocol != rContext->readerState->cardProtocol)
1565  {
1567  goto exit;
1568  }
1569  }
1570  }
1571 
1572  /*
1573  * Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler
1574  * just wants 0 or 1
1575  */
1576 
1577  sSendPci.Protocol = 0; /* protocol T=0 by default */
1578 
1579  if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1)
1580  {
1581  sSendPci.Protocol = 1;
1582  } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1583  {
1584  /*
1585  * This is temporary ......
1586  */
1587  sSendPci.Protocol = SCARD_PROTOCOL_RAW;
1588  } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD)
1589  {
1590  /* Fix by Amira (Athena) */
1591  unsigned long i;
1592  unsigned long prot = rContext->readerState->cardProtocol;
1593 
1594  for (i = 0 ; prot != 1 ; i++)
1595  prot >>= 1;
1596 
1597  sSendPci.Protocol = i;
1598  }
1599 
1600  sSendPci.Length = pioSendPci->cbPciLength;
1601 
1602  sRecvPci.Protocol = pioRecvPci->dwProtocol;
1603  sRecvPci.Length = pioRecvPci->cbPciLength;
1604 
1605  /* the protocol number is decoded a few lines above */
1606  Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%ld", sSendPci.Protocol);
1607 
1608  tempRxLength = dwRxLength;
1609 
1610  if ((pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1611  && (rContext->version == IFD_HVERSION_2_0))
1612  {
1613  rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength,
1614  pbRecvBuffer, &dwRxLength);
1615  } else
1616  {
1617  rv = IFDTransmit(rContext, sSendPci, (PUCHAR) pbSendBuffer,
1618  cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci);
1619  }
1620 
1621  pioRecvPci->dwProtocol = sRecvPci.Protocol;
1622  pioRecvPci->cbPciLength = sRecvPci.Length;
1623 
1624  /*
1625  * Check for any errors that might have occurred
1626  */
1627 
1628  if (rv != SCARD_S_SUCCESS)
1629  {
1630  *pcbRecvLength = 0;
1631  Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv);
1632  goto exit;
1633  }
1634 
1635  /*
1636  * Available is less than received
1637  */
1638  if (tempRxLength < dwRxLength)
1639  {
1640  *pcbRecvLength = 0;
1642  goto exit;
1643  }
1644 
1645  /*
1646  * Successful return
1647  */
1648  *pcbRecvLength = dwRxLength;
1649 
1650 exit:
1651  UNREF_READER(rContext)
1652 
1653  return rv;
1654 }
1655 
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'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'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 MAX_BUFFER_SIZE
Maximum Tx/Rx Buffer for short APDU.
Definition: pcsclite.h:296
#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'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:251
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:241
#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:258
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:261
#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:56
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:43
#define SCARD_SHARE_SHARED
Shared mode only.
Definition: pcsclite.h:248
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:71
int version
IFD Handler version number.
#define SCARD_PROTOCOL_T0
T=0 active protocol.
Definition: pcsclite.h:240
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:135
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:253
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:259
#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:238
#define SCARD_RESET_CARD
Reset on close.
Definition: pcsclite.h:252
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'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:247
#define SCARD_POWERED
Card is powered.
Definition: pcsclite.h:260
card was in use
Definition: pcscd.h:70
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:242
#define SCARD_EJECT_CARD
Eject on close.
Definition: pcsclite.h:254
Protocol Control Information (PCI)
Definition: pcsclite.h:79
#define SCARD_SCOPE_GLOBAL
Scope is global.
Definition: pcscd.h:41
#define SCARD_ABSENT
Card is absent.
Definition: pcsclite.h:257
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
Definition: eventhandler.h:57
auto power off
Definition: pcscd.h:68
#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:249
#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