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