pcsc-lite 1.9.9
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#define PROFILE_FILE "/tmp/pcscd_profile"
126#include <stdio.h>
127#include <sys/time.h>
128#include <errno.h>
129#include <unistd.h>
130
131struct timeval profile_time_start;
132FILE *fd;
133bool profile_tty;
134
135#define PROFILE_START profile_start(__FUNCTION__);
136#define PROFILE_END profile_end(__FUNCTION__, __LINE__);
137
138static void profile_start(const char *f)
139{
140 static bool initialized = false;
141
142 if (!initialized)
143 {
144 initialized = true;
145 fd = fopen(PROFILE_FILE, "a+");
146 if (NULL == fd)
147 {
148 fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n",
149 PROFILE_FILE, strerror(errno));
150 exit(-1);
151 }
152 fprintf(fd, "\nStart a new profile\n");
153 fflush(fd);
154
155 if (isatty(fileno(stderr)))
156 profile_tty = true;
157 else
158 profile_tty = false;
159 }
160
161 gettimeofday(&profile_time_start, NULL);
162} /* profile_start */
163
164
165static void profile_end(const char *f, int line)
166{
167 struct timeval profile_time_end;
168 long d;
169
170 gettimeofday(&profile_time_end, NULL);
171 d = time_sub(&profile_time_end, &profile_time_start);
172
173 if (profile_tty)
174 fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m (%d)\n", f, d,
175 line);
176 fprintf(fd, "%s %ld\n", f, d);
177 fflush(fd);
178} /* profile_end */
179
180#else
181#define PROFILE_START
182#define PROFILE_END
183#endif
184
186#define SCARD_PROTOCOL_ANY_OLD 0x1000
187
188static pthread_mutex_t LockMutex = PTHREAD_MUTEX_INITIALIZER;
189
190LONG SCardEstablishContext(DWORD dwScope, /*@unused@*/ LPCVOID pvReserved1,
191 /*@unused@*/ LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
192{
193 (void)pvReserved1;
194 (void)pvReserved2;
195
196 if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
197 dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
198 {
199 *phContext = 0;
201 }
202
203 /*
204 * Unique identifier for this server so that it can uniquely be
205 * identified by clients and distinguished from others
206 */
207
208 *phContext = SYS_RandomInt();
209
210 Log2(PCSC_LOG_DEBUG, "Establishing Context: 0x%lX", *phContext);
211
212 return SCARD_S_SUCCESS;
213}
214
215LONG SCardReleaseContext(SCARDCONTEXT hContext)
216{
217 /*
218 * Nothing to do here RPC layer will handle this
219 */
220#ifdef NO_LOG
221 (void)hContext;
222#endif
223
224 Log2(PCSC_LOG_DEBUG, "Releasing Context: 0x%lX", hContext);
225
226 return SCARD_S_SUCCESS;
227}
228
229LONG 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
236 (void)hContext;
237 PROFILE_START
238
239 *phCard = 0;
240
241 if ((dwShareMode != SCARD_SHARE_DIRECT) &&
242 !(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
243 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
244 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
245 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
247
248 if (dwShareMode != SCARD_SHARE_EXCLUSIVE &&
249 dwShareMode != SCARD_SHARE_SHARED &&
250 dwShareMode != SCARD_SHARE_DIRECT)
252
253 Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %ld",
254 szReader, dwPreferredProtocols);
255
256 rv = RFReaderInfo((LPSTR) szReader, &rContext);
257 if (rv != SCARD_S_SUCCESS)
258 {
259 Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader);
260 return rv;
261 }
262
263 /*
264 * Make sure the reader is working properly
265 */
266 rv = RFCheckReaderStatus(rContext);
267 if (rv != SCARD_S_SUCCESS)
268 goto exit;
269
270 /*******************************************
271 *
272 * This section checks for simple errors
273 *
274 *******************************************/
275
276 /*
277 * Connect if not exclusive mode
278 */
280 {
281 Log1(PCSC_LOG_ERROR, "Error Reader Exclusive");
283 goto exit;
284 }
285
286 /*
287 * wait until a possible transaction is finished
288 */
289 if (rContext->hLockId != 0)
290 {
291 Log1(PCSC_LOG_INFO, "Waiting for release of lock");
292 while (rContext->hLockId != 0)
294 Log1(PCSC_LOG_INFO, "Lock released");
295 }
296
297 /*******************************************
298 *
299 * This section tries to determine the
300 * presence of a card or not
301 *
302 *******************************************/
303 if (dwShareMode != SCARD_SHARE_DIRECT)
304 {
305 if (!(rContext->readerState->readerState & SCARD_PRESENT))
306 {
307 Log1(PCSC_LOG_DEBUG, "Card Not Inserted");
309 goto exit;
310 }
311
312 /* Power on (again) the card if needed */
313 (void)pthread_mutex_lock(&rContext->powerState_lock);
314 if (POWER_STATE_UNPOWERED == rContext->powerState)
315 {
316 DWORD dwAtrLen;
317
318 dwAtrLen = sizeof(rContext->readerState->cardAtr);
319 rv = IFDPowerICC(rContext, IFD_POWER_UP,
320 rContext->readerState->cardAtr, &dwAtrLen);
321 rContext->readerState->cardAtrLength = dwAtrLen;
322
323 if (rv == IFD_SUCCESS)
324 {
326
327 Log1(PCSC_LOG_DEBUG, "power up complete.");
328 LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
329 rContext->readerState->cardAtr,
330 rContext->readerState->cardAtrLength);
331 }
332 else
333 Log2(PCSC_LOG_ERROR, "Error powering up card: %s",
334 rv2text(rv));
335 }
336
337 if (! (rContext->readerState->readerState & SCARD_POWERED))
338 {
339 Log1(PCSC_LOG_ERROR, "Card Not Powered");
340 (void)pthread_mutex_unlock(&rContext->powerState_lock);
342 goto exit;
343 }
344
345 /* the card is now in use */
346 rContext->powerState = POWER_STATE_IN_USE;
347 Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_IN_USE");
348 (void)pthread_mutex_unlock(&rContext->powerState_lock);
349 }
350
351 /*******************************************
352 *
353 * This section tries to decode the ATR
354 * and set up which protocol to use
355 *
356 *******************************************/
357 if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
359 else
360 {
361 if (dwShareMode != SCARD_SHARE_DIRECT)
362 {
363 /* lock here instead in IFDSetPTS() to lock up to
364 * setting rContext->readerState->cardProtocol */
365 (void)pthread_mutex_lock(rContext->mMutex);
366
367 /* the protocol is not yet set (no PPS yet) */
369 {
370 int availableProtocols, defaultProtocol;
371 int ret;
372
373 ATRDecodeAtr(&availableProtocols, &defaultProtocol,
374 rContext->readerState->cardAtr,
375 rContext->readerState->cardAtrLength);
376
377 /* If it is set to ANY let it do any of the protocols */
378 if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
379 dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
380
381 ret = PHSetProtocol(rContext, dwPreferredProtocols,
382 availableProtocols, defaultProtocol);
383
384 /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error */
385 if (SET_PROTOCOL_PPS_FAILED == ret)
386 {
387 (void)pthread_mutex_unlock(rContext->mMutex);
389 goto exit;
390 }
391
392 if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
393 {
394 (void)pthread_mutex_unlock(rContext->mMutex);
396 goto exit;
397 }
398
399 /* use negotiated protocol */
400 rContext->readerState->cardProtocol = ret;
401
402 (void)pthread_mutex_unlock(rContext->mMutex);
403 }
404 else
405 {
406 (void)pthread_mutex_unlock(rContext->mMutex);
407
408 if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
409 {
411 goto exit;
412 }
413 }
414 }
415 }
416
417 *pdwActiveProtocol = rContext->readerState->cardProtocol;
418
419 if (dwShareMode != SCARD_SHARE_DIRECT)
420 {
421 switch (*pdwActiveProtocol)
422 {
425 Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
426 (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
427 break;
428
430 Log1(PCSC_LOG_DEBUG, "Active Protocol: RAW");
431 break;
432
433 default:
434 Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %ld",
435 *pdwActiveProtocol);
436 }
437 }
438 else
439 Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected");
440
441 /*
442 * Prepare the SCARDHANDLE identity
443 */
444
445 /* we need a lock to avoid concurrent generation of handles leading
446 * to a possible hCard handle duplication */
447 (void)pthread_mutex_lock(&LockMutex);
448
449 *phCard = RFCreateReaderHandle(rContext);
450
451 Log2(PCSC_LOG_DEBUG, "hCard Identity: %lx", *phCard);
452
453 /*******************************************
454 *
455 * This section tries to set up the
456 * exclusivity modes. -1 is exclusive
457 *
458 *******************************************/
459
460 if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
461 {
462 if (rContext->contexts == PCSCLITE_SHARING_NO_CONTEXT)
463 {
465 (void)RFLockSharing(*phCard, rContext);
466 }
467 else
468 {
469 *phCard = 0;
471 (void)pthread_mutex_unlock(&LockMutex);
472 goto exit;
473 }
474 }
475 else
476 {
477 /*
478 * Add a connection to the context stack
479 */
480 rContext->contexts += 1;
481 }
482
483 /*
484 * Add this handle to the handle list
485 */
486 rv = RFAddReaderHandle(rContext, *phCard);
487
488 (void)pthread_mutex_unlock(&LockMutex);
489
490 if (rv != SCARD_S_SUCCESS)
491 {
492 /*
493 * Clean up - there is no more room
494 */
497 else
499 rContext->contexts -= 1;
500
501 *phCard = 0;
502
504 goto exit;
505 }
506
507 /*
508 * Propagate new state to reader state
509 */
510 rContext->readerState->readerSharing = rContext->contexts;
511
512exit:
513 UNREF_READER(rContext)
514
515 PROFILE_END
516
517 return rv;
518}
519
520LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
521 DWORD dwPreferredProtocols, DWORD dwInitialization,
522 LPDWORD pdwActiveProtocol)
523{
524 LONG rv;
525 READER_CONTEXT * rContext = NULL;
526
527 Log1(PCSC_LOG_DEBUG, "Attempting reconnect to token.");
528
529 if (hCard == 0)
531
532 /*
533 * Handle the dwInitialization
534 */
535 if (dwInitialization != SCARD_LEAVE_CARD &&
536 dwInitialization != SCARD_RESET_CARD &&
537 dwInitialization != SCARD_UNPOWER_CARD)
539
540 if (dwShareMode != SCARD_SHARE_SHARED &&
541 dwShareMode != SCARD_SHARE_EXCLUSIVE &&
542 dwShareMode != SCARD_SHARE_DIRECT)
544
545 if ((dwShareMode != SCARD_SHARE_DIRECT) &&
546 !(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
547 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
548 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
549 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
551
552 /* get rContext corresponding to hCard */
553 rv = RFReaderInfoById(hCard, &rContext);
554 if (rv != SCARD_S_SUCCESS)
555 return rv;
556
557 /*
558 * Make sure the reader is working properly
559 */
560 rv = RFCheckReaderStatus(rContext);
561 if (rv != SCARD_S_SUCCESS)
562 goto exit;
563
564 /*
565 * Make sure no one has a lock on this reader
566 */
567 rv = RFCheckSharing(hCard, rContext);
568 if (rv != SCARD_S_SUCCESS)
569 goto exit;
570
571 if (dwInitialization == SCARD_RESET_CARD ||
572 dwInitialization == SCARD_UNPOWER_CARD)
573 {
574 DWORD dwAtrLen;
575
576 /*
577 * Notify the card has been reset
578 */
579 RFSetReaderEventState(rContext, SCARD_RESET);
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 == IFD_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 {
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 /* the card is now in use */
713 RFSetPowerState(rContext, POWER_STATE_IN_USE);
714 Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_IN_USE");
715 }
716 }
717
718 *pdwActiveProtocol = rContext->readerState->cardProtocol;
719
720 if (dwShareMode != SCARD_SHARE_DIRECT)
721 {
722 switch (*pdwActiveProtocol)
723 {
726 Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
727 (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
728 break;
729
731 Log1(PCSC_LOG_DEBUG, "Active Protocol: RAW");
732 break;
733
734 default:
735 Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %ld",
736 *pdwActiveProtocol);
737 }
738 }
739 else
740 Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected");
741
742 if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
743 {
745 {
746 /*
747 * Do nothing - we are already exclusive
748 */
749 }
750 else
751 {
753 {
755 (void)RFLockSharing(hCard, rContext);
756 }
757 else
758 {
760 goto exit;
761 }
762 }
763 }
764 else if (dwShareMode == SCARD_SHARE_SHARED)
765 {
767 {
768 /*
769 * Do nothing - in sharing mode already
770 */
771 }
772 else
773 {
774 /*
775 * We are in exclusive mode but want to share now
776 */
777 (void)RFUnlockSharing(hCard, rContext);
779 }
780 }
781 else if (dwShareMode == SCARD_SHARE_DIRECT)
782 {
784 {
785 /*
786 * Do nothing - in sharing mode already
787 */
788 }
789 else
790 {
791 /*
792 * We are in exclusive mode but want to share now
793 */
794 (void)RFUnlockSharing(hCard, rContext);
796 }
797 }
798 else
799 {
801 goto exit;
802 }
803
804 /*
805 * Clear a previous event to the application
806 */
807 (void)RFClearReaderEventState(rContext, hCard);
808
809 /*
810 * Propagate new state to reader state
811 */
812 rContext->readerState->readerSharing = rContext->contexts;
813
814 rv = SCARD_S_SUCCESS;
815
816exit:
817 UNREF_READER(rContext)
818
819 return rv;
820}
821
822LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
823{
824 LONG rv;
825 READER_CONTEXT * rContext = NULL;
826
827 if (hCard == 0)
829
830 if ((dwDisposition != SCARD_LEAVE_CARD)
831 && (dwDisposition != SCARD_UNPOWER_CARD)
832 && (dwDisposition != SCARD_RESET_CARD)
833 && (dwDisposition != SCARD_EJECT_CARD))
835
836 /* get rContext corresponding to hCard */
837 rv = RFReaderInfoById(hCard, &rContext);
838 /* ignore reader removal */
840 return SCARD_S_SUCCESS;
841 if (rv != SCARD_S_SUCCESS)
842 return rv;
843
844 /*
845 * wait until a possible transaction is finished
846 */
847 if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->hLockId != 0)
848 && (rContext->hLockId != hCard))
849 {
850 Log1(PCSC_LOG_INFO, "Waiting for release of lock");
851 while (rContext->hLockId != 0)
853 Log1(PCSC_LOG_INFO, "Lock released");
854 }
855
856 /*
857 * Try to unlock any blocks on this context
858 *
859 * This may fail with SCARD_E_SHARING_VIOLATION if a transaction is
860 * on going on another card context and dwDisposition == SCARD_LEAVE_CARD.
861 * We should not stop.
862 */
863 rv = RFUnlockAllSharing(hCard, rContext);
864 if (rv != SCARD_S_SUCCESS)
865 {
867 {
868 goto exit;
869 }
870 else
871 {
872 if (SCARD_LEAVE_CARD != dwDisposition)
873 goto exit;
874 }
875 }
876
877 Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->contexts);
878 Log2(PCSC_LOG_DEBUG, "dwDisposition: %ld", dwDisposition);
879
880 if (dwDisposition == SCARD_RESET_CARD ||
881 dwDisposition == SCARD_UNPOWER_CARD)
882 {
883 DWORD dwAtrLen;
884
885 /*
886 * Notify the card has been reset
887 */
888 RFSetReaderEventState(rContext, SCARD_RESET);
889
890 dwAtrLen = sizeof(rContext->readerState->cardAtr);
891 if (SCARD_RESET_CARD == dwDisposition)
892 rv = IFDPowerICC(rContext, IFD_RESET,
893 rContext->readerState->cardAtr, &dwAtrLen);
894 else
895 {
896 /* SCARD_UNPOWER_CARD */
897 rv = IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL);
898
899 RFSetPowerState(rContext, POWER_STATE_UNPOWERED);
900 Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED");
901 }
902
903 /* the protocol is unset after a power on */
905
906 if (rv == IFD_SUCCESS)
907 {
908 if (SCARD_UNPOWER_CARD == dwDisposition)
910 else
911 {
912 rContext->readerState->cardAtrLength = dwAtrLen;
913 rContext->readerState->readerState =
915
916 Log1(PCSC_LOG_DEBUG, "Reset complete.");
917 LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
918 rContext->readerState->cardAtr,
919 rContext->readerState->cardAtrLength);
920 }
921 }
922 else
923 {
924 if (SCARD_UNPOWER_CARD == dwDisposition)
925 Log2(PCSC_LOG_ERROR, "Error powering down card: %s",
926 rv2text(rv));
927 else
928 {
929 rContext->readerState->cardAtrLength = 0;
930 Log1(PCSC_LOG_ERROR, "Error resetting card.");
931 }
932
933 if (rv == SCARD_W_REMOVED_CARD)
935 else
936 rContext->readerState->readerState =
938 }
939 }
940 else if (dwDisposition == SCARD_EJECT_CARD)
941 {
942 UCHAR controlBuffer[5];
943 UCHAR receiveBuffer[MAX_BUFFER_SIZE];
944 DWORD receiveLength;
945
946 /*
947 * Set up the CTBCS command for Eject ICC
948 */
949 controlBuffer[0] = 0x20;
950 controlBuffer[1] = 0x15;
951 controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1;
952 controlBuffer[3] = 0x00;
953 controlBuffer[4] = 0x00;
954 receiveLength = 2;
955 rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
956 &receiveLength);
957
958 if (rv == SCARD_S_SUCCESS)
959 {
960 if (receiveLength == 2 && receiveBuffer[0] == 0x90)
961 {
962 Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
963 /*
964 * Successful
965 */
966 }
967 else
968 Log1(PCSC_LOG_ERROR, "Error ejecting card.");
969 }
970 else
971 Log1(PCSC_LOG_ERROR, "Error ejecting card.");
972
973 }
974 else if (dwDisposition == SCARD_LEAVE_CARD)
975 {
976 /*
977 * Do nothing
978 */
979 }
980
981 /*
982 * Remove and destroy this handle
983 */
984 (void)RFRemoveReaderHandle(rContext, hCard);
985
986 /*
987 * For exclusive connection reset it to no connections
988 */
991 else
992 {
993 /*
994 * Remove a connection from the context stack
995 */
996 rContext->contexts -= 1;
997
998 if (rContext->contexts < 0)
999 rContext->contexts = 0;
1000 }
1001
1002 if (PCSCLITE_SHARING_NO_CONTEXT == rContext->contexts)
1003 {
1004 RESPONSECODE (*fct)(DWORD) = NULL;
1005 DWORD dwGetSize;
1006
1007 (void)pthread_mutex_lock(&rContext->powerState_lock);
1008 /* Switch to POWER_STATE_GRACE_PERIOD unless the card was not
1009 * powered */
1011 {
1012 rContext->powerState = POWER_STATE_GRACE_PERIOD;
1013 Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_GRACE_PERIOD");
1014 }
1015
1016 (void)pthread_mutex_unlock(&rContext->powerState_lock);
1017
1018 /* ask to stop the "polling" thread so it can be restarted using
1019 * the correct timeout */
1020 dwGetSize = sizeof(fct);
1022 &dwGetSize, (PUCHAR)&fct);
1023
1024 if ((IFD_SUCCESS == rv) && (dwGetSize == sizeof(fct)))
1025 {
1026 Log1(PCSC_LOG_INFO, "Stopping polling thread");
1027 fct(rContext->slot);
1028 }
1029 }
1030
1031 /*
1032 * Propagate new state to reader state
1033 */
1034 rContext->readerState->readerSharing = rContext->contexts;
1035
1036 rv = SCARD_S_SUCCESS;
1037
1038exit:
1039 UNREF_READER(rContext)
1040
1041 return rv;
1042}
1043
1044LONG SCardBeginTransaction(SCARDHANDLE hCard)
1045{
1046 LONG rv;
1048
1049 if (hCard == 0)
1051
1052 /* get rContext corresponding to hCard */
1053 rv = RFReaderInfoById(hCard, &rContext);
1054 if (rv != SCARD_S_SUCCESS)
1055 return rv;
1056
1057 /*
1058 * Make sure the reader is working properly
1059 */
1060 rv = RFCheckReaderStatus(rContext);
1061 if (rv != SCARD_S_SUCCESS)
1062 goto exit;
1063
1064 /*
1065 * Make sure some event has not occurred
1066 */
1067 rv = RFCheckReaderEventState(rContext, hCard);
1068 if (rv != SCARD_S_SUCCESS)
1069 goto exit;
1070
1071 rv = RFLockSharing(hCard, rContext);
1072
1073 /* if the transaction is not yet ready we sleep a bit so the client
1074 * do not retry immediately */
1075 if (SCARD_E_SHARING_VIOLATION == rv)
1077
1078 Log2(PCSC_LOG_DEBUG, "Status: %s", rv2text(rv));
1079
1080exit:
1081 UNREF_READER(rContext)
1082
1083 return rv;
1084}
1085
1086LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
1087{
1088 LONG rv;
1089 LONG rv2;
1091
1092 /*
1093 * Ignoring dwDisposition for now
1094 */
1095 if (hCard == 0)
1097
1098 if ((dwDisposition != SCARD_LEAVE_CARD)
1099 && (dwDisposition != SCARD_UNPOWER_CARD)
1100 && (dwDisposition != SCARD_RESET_CARD)
1101 && (dwDisposition != SCARD_EJECT_CARD))
1102 return SCARD_E_INVALID_VALUE;
1103
1104 /* get rContext corresponding to hCard */
1105 rv = RFReaderInfoById(hCard, &rContext);
1106 if (rv != SCARD_S_SUCCESS)
1107 return rv;
1108
1109 /*
1110 * Make sure some event has not occurred
1111 */
1112 rv = RFCheckReaderEventState(rContext, hCard);
1113 if (rv != SCARD_S_SUCCESS)
1114 goto exit;
1115
1116 /*
1117 * Error if another transaction is ongoing and a card action is
1118 * requested
1119 */
1120 if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->hLockId != 0)
1121 && (rContext->hLockId != hCard))
1122 {
1123 Log1(PCSC_LOG_INFO, "No card reset within a transaction");
1125 goto exit;
1126 }
1127
1128 if (dwDisposition == SCARD_RESET_CARD ||
1129 dwDisposition == SCARD_UNPOWER_CARD)
1130 {
1131 DWORD dwAtrLen;
1132
1133 dwAtrLen = sizeof(rContext->readerState->cardAtr);
1134 if (SCARD_RESET_CARD == dwDisposition)
1136 rContext->readerState->cardAtr, &dwAtrLen);
1137 else
1138 {
1141 rContext->readerState->cardAtr, &dwAtrLen);
1142 }
1143
1144 /* the protocol is unset after a power on */
1145 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
1146
1147 /*
1148 * Notify the card has been reset
1149 */
1150 RFSetReaderEventState(rContext, SCARD_RESET);
1151
1152 /*
1153 * Set up the status bit masks on readerState
1154 */
1155 if (rv == IFD_SUCCESS)
1156 {
1157 rContext->readerState->cardAtrLength = dwAtrLen;
1158 rContext->readerState->readerState =
1160
1161 Log1(PCSC_LOG_DEBUG, "Reset complete.");
1162 LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
1163 rContext->readerState->cardAtr,
1164 rContext->readerState->cardAtrLength);
1165 }
1166 else
1167 {
1168 rContext->readerState->cardAtrLength = 0;
1169 Log1(PCSC_LOG_ERROR, "Error resetting card.");
1170
1171 if (rv == SCARD_W_REMOVED_CARD)
1172 rContext->readerState->readerState = SCARD_ABSENT;
1173 else
1174 rContext->readerState->readerState =
1176 }
1177 }
1178 else if (dwDisposition == SCARD_EJECT_CARD)
1179 {
1180 UCHAR controlBuffer[5];
1182 DWORD receiveLength;
1183
1184 /*
1185 * Set up the CTBCS command for Eject ICC
1186 */
1187 controlBuffer[0] = 0x20;
1188 controlBuffer[1] = 0x15;
1189 controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1;
1190 controlBuffer[3] = 0x00;
1191 controlBuffer[4] = 0x00;
1192 receiveLength = 2;
1193 rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
1194 &receiveLength);
1195
1196 if (rv == SCARD_S_SUCCESS)
1197 {
1198 if (receiveLength == 2 && receiveBuffer[0] == 0x90)
1199 {
1200 Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
1201 /*
1202 * Successful
1203 */
1204 }
1205 else
1206 Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1207 }
1208 else
1209 Log1(PCSC_LOG_ERROR, "Error ejecting card.");
1210
1211 }
1212 else if (dwDisposition == SCARD_LEAVE_CARD)
1213 {
1214 /*
1215 * Do nothing
1216 */
1217 }
1218
1219 /*
1220 * Unlock any blocks on this context
1221 */
1222 /* we do not want to lose the previous rv value
1223 * So we use another variable */
1224 rv2 = RFUnlockSharing(hCard, rContext);
1225 if (rv2 != SCARD_S_SUCCESS)
1226 /* if rv is already in error then do not change its value */
1227 if (rv == SCARD_S_SUCCESS)
1228 rv = rv2;
1229
1230 Log2(PCSC_LOG_DEBUG, "Status: %s", rv2text(rv));
1231
1232exit:
1233 UNREF_READER(rContext)
1234
1235 return rv;
1236}
1237
1238LONG SCardStatus(SCARDHANDLE hCard, LPSTR szReaderNames,
1239 LPDWORD pcchReaderLen, LPDWORD pdwState,
1240 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1241{
1242 LONG rv;
1244
1245 /* These parameters are not used by the client
1246 * Client side code uses readerStates[] instead */
1249 (void)pdwState;
1251 (void)pbAtr;
1252 (void)pcbAtrLen;
1253
1254 if (hCard == 0)
1256
1257 /* get rContext corresponding to hCard */
1258 rv = RFReaderInfoById(hCard, &rContext);
1259 if (rv != SCARD_S_SUCCESS)
1260 return rv;
1261
1262 /*
1263 * Make sure no one has a lock on this reader
1264 */
1265 rv = RFCheckSharing(hCard, rContext);
1266 if (rv != SCARD_S_SUCCESS)
1267 goto exit;
1268
1269 if (rContext->readerState->cardAtrLength > MAX_ATR_SIZE)
1270 {
1272 goto exit;
1273 }
1274
1275 /*
1276 * This is a client side function however the server maintains the
1277 * list of events between applications so it must be passed through to
1278 * obtain this event if it has occurred
1279 */
1280
1281 /*
1282 * Make sure some event has not occurred
1283 */
1284 rv = RFCheckReaderEventState(rContext, hCard);
1285 if (rv != SCARD_S_SUCCESS)
1286 goto exit;
1287
1288 /*
1289 * Make sure the reader is working properly
1290 */
1291 rv = RFCheckReaderStatus(rContext);
1292 if (rv != SCARD_S_SUCCESS)
1293 goto exit;
1294
1295exit:
1296 UNREF_READER(rContext)
1297
1298 return rv;
1299}
1300
1301LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
1302 LPCVOID pbSendBuffer, DWORD cbSendLength,
1303 LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
1304{
1305 LONG rv;
1307
1308 /* 0 bytes returned by default */
1309 *lpBytesReturned = 0;
1310
1311 if (0 == hCard)
1313
1314 /* get rContext corresponding to hCard */
1315 rv = RFReaderInfoById(hCard, &rContext);
1316 if (rv != SCARD_S_SUCCESS)
1317 return rv;
1318
1319 /*
1320 * Make sure no one has a lock on this reader
1321 */
1322 rv = RFCheckSharing(hCard, rContext);
1323 if (rv != SCARD_S_SUCCESS)
1324 goto exit;
1325
1326 if (IFD_HVERSION_2_0 == rContext->version)
1327 if (NULL == pbSendBuffer || 0 == cbSendLength)
1328 {
1330 goto exit;
1331 }
1332
1333 /*
1334 * Make sure the reader is working properly
1335 */
1336 rv = RFCheckReaderStatus(rContext);
1337 if (rv != SCARD_S_SUCCESS)
1338 goto exit;
1339
1340 if (IFD_HVERSION_2_0 == rContext->version)
1341 {
1342 /* we must wrap a API 3.0 client in an API 2.0 driver */
1343 *lpBytesReturned = cbRecvLength;
1344 rv = IFDControl_v2(rContext, (PUCHAR)pbSendBuffer,
1345 cbSendLength, pbRecvBuffer, lpBytesReturned);
1346 }
1347 else
1348 if (IFD_HVERSION_3_0 == rContext->version)
1349 rv = IFDControl(rContext, dwControlCode, pbSendBuffer,
1350 cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned);
1351 else
1353
1354exit:
1355 UNREF_READER(rContext)
1356
1357 return rv;
1358}
1359
1360LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1361 LPBYTE pbAttr, LPDWORD pcbAttrLen)
1362{
1363 LONG rv;
1365
1366 if (0 == hCard)
1368
1369 /* get rContext corresponding to hCard */
1370 rv = RFReaderInfoById(hCard, &rContext);
1371 if (rv != SCARD_S_SUCCESS)
1372 return rv;
1373
1374 /*
1375 * Make sure no one has a lock on this reader
1376 */
1377 rv = RFCheckSharing(hCard, rContext);
1378 if (rv != SCARD_S_SUCCESS)
1379 goto exit;
1380
1381 /*
1382 * Make sure the reader is working properly
1383 */
1384 rv = RFCheckReaderStatus(rContext);
1385 if (rv != SCARD_S_SUCCESS)
1386 goto exit;
1387
1388 /*
1389 * Make sure some event has not occurred
1390 */
1391 rv = RFCheckReaderEventState(rContext, hCard);
1392 if (rv != SCARD_S_SUCCESS)
1393 goto exit;
1394
1395 rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr);
1396 switch(rv)
1397 {
1398 case IFD_SUCCESS:
1399 rv = SCARD_S_SUCCESS;
1400 break;
1401 case IFD_ERROR_TAG:
1402 /* Special case SCARD_ATTR_DEVICE_FRIENDLY_NAME as it is better
1403 * implemented in pcscd (it knows the friendly name)
1404 */
1405 if ((SCARD_ATTR_DEVICE_FRIENDLY_NAME == dwAttrId)
1406 || (SCARD_ATTR_DEVICE_SYSTEM_NAME == dwAttrId))
1407 {
1408 unsigned int len = strlen(rContext->readerState->readerName)+1;
1409
1410 if (len > *pcbAttrLen)
1412 else
1413 {
1414 strcpy((char *)pbAttr, rContext->readerState->readerName);
1415 rv = SCARD_S_SUCCESS;
1416 }
1417 *pcbAttrLen = len;
1418 }
1419 else
1421 break;
1424 break;
1425 default:
1427 }
1428
1429exit:
1430 UNREF_READER(rContext)
1431
1432 return rv;
1433}
1434
1435LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1436 LPCBYTE pbAttr, DWORD cbAttrLen)
1437{
1438 LONG rv;
1440
1441 if (0 == hCard)
1443
1444 /* get rContext corresponding to hCard */
1445 rv = RFReaderInfoById(hCard, &rContext);
1446 if (rv != SCARD_S_SUCCESS)
1447 return rv;
1448
1449 /*
1450 * Make sure no one has a lock on this reader
1451 */
1452 rv = RFCheckSharing(hCard, rContext);
1453 if (rv != SCARD_S_SUCCESS)
1454 goto exit;
1455
1456 /*
1457 * Make sure the reader is working properly
1458 */
1459 rv = RFCheckReaderStatus(rContext);
1460 if (rv != SCARD_S_SUCCESS)
1461 goto exit;
1462
1463 /*
1464 * Make sure some event has not occurred
1465 */
1466 rv = RFCheckReaderEventState(rContext, hCard);
1467 if (rv != SCARD_S_SUCCESS)
1468 goto exit;
1469
1470 rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr);
1471 if (rv == IFD_SUCCESS)
1472 rv = SCARD_S_SUCCESS;
1473 else
1474 if (rv == IFD_ERROR_TAG)
1476 else
1478
1479exit:
1480 UNREF_READER(rContext)
1481
1482 return rv;
1483}
1484
1485LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
1486 LPCBYTE pbSendBuffer, DWORD cbSendLength,
1488 LPDWORD pcbRecvLength)
1489{
1490 LONG rv;
1493 DWORD dwRxLength, tempRxLength;
1494
1495 dwRxLength = *pcbRecvLength;
1496 *pcbRecvLength = 0;
1497
1498 if (hCard == 0)
1500
1501 /*
1502 * Must at least have 2 status words even for SCardControl
1503 */
1504 if (dwRxLength < 2)
1506
1507 /* get rContext corresponding to hCard */
1508 rv = RFReaderInfoById(hCard, &rContext);
1509 if (rv != SCARD_S_SUCCESS)
1510 return rv;
1511
1512 /*
1513 * Make sure no one has a lock on this reader
1514 */
1515 rv = RFCheckSharing(hCard, rContext);
1516 if (rv != SCARD_S_SUCCESS)
1517 goto exit;
1518
1519 /*
1520 * Make sure the reader is working properly
1521 */
1522 rv = RFCheckReaderStatus(rContext);
1523 if (rv != SCARD_S_SUCCESS)
1524 goto exit;
1525
1526 /*
1527 * Make sure some event has not occurred
1528 */
1529 rv = RFCheckReaderEventState(rContext, hCard);
1530 if (rv != SCARD_S_SUCCESS)
1531 goto exit;
1532
1533 /*
1534 * Check for some common errors
1535 */
1536 if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1537 {
1538 if (rContext->readerState->readerState & SCARD_ABSENT)
1539 {
1541 goto exit;
1542 }
1543 }
1544
1545 if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1546 {
1547 if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD)
1548 {
1549 if (pioSendPci->dwProtocol != rContext->readerState->cardProtocol)
1550 {
1552 goto exit;
1553 }
1554 }
1555 }
1556
1557 /*
1558 * Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler
1559 * just wants 0 or 1
1560 */
1561
1562 sSendPci.Protocol = 0; /* protocol T=0 by default */
1563
1564 if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1)
1565 {
1566 sSendPci.Protocol = 1;
1567 } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1568 {
1569 /*
1570 * This is temporary ......
1571 */
1572 sSendPci.Protocol = SCARD_PROTOCOL_RAW;
1573 } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD)
1574 {
1575 /* Fix by Amira (Athena) */
1576 unsigned long i;
1577 unsigned long prot = rContext->readerState->cardProtocol;
1578
1579 for (i = 0 ; prot != 1 && i < 16; i++)
1580 prot >>= 1;
1581
1582 sSendPci.Protocol = i;
1583 }
1584
1585 sSendPci.Length = pioSendPci->cbPciLength;
1586
1587 sRecvPci.Protocol = pioRecvPci->dwProtocol;
1588 sRecvPci.Length = pioRecvPci->cbPciLength;
1589
1590 /* the protocol number is decoded a few lines above */
1591 Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%ld", sSendPci.Protocol);
1592
1594
1595 if ((pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1596 && (rContext->version == IFD_HVERSION_2_0))
1597 {
1598 rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength,
1600 } else
1601 {
1602 rv = IFDTransmit(rContext, sSendPci, (PUCHAR) pbSendBuffer,
1603 cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci);
1604 }
1605
1606 pioRecvPci->dwProtocol = sRecvPci.Protocol;
1607 pioRecvPci->cbPciLength = sRecvPci.Length;
1608
1609 /*
1610 * Check for any errors that might have occurred
1611 */
1612
1613 if (rv != SCARD_S_SUCCESS)
1614 {
1615 *pcbRecvLength = 0;
1616 Log2(PCSC_LOG_ERROR, "Card not transacted: %s", rv2text(rv));
1617
1618 if (SCARD_E_NO_SMARTCARD == rv)
1619 {
1620 rContext->readerState->cardAtrLength = 0;
1621 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
1622 rContext->readerState->readerState = SCARD_ABSENT;
1623 }
1624
1625 goto exit;
1626 }
1627
1628 /*
1629 * Available is less than received
1630 */
1632 {
1633 *pcbRecvLength = 0;
1635 goto exit;
1636 }
1637
1638 /*
1639 * Successful return
1640 */
1641 *pcbRecvLength = dwRxLength;
1642
1643exit:
1644 UNREF_READER(rContext)
1645
1646 return rv;
1647}
1648
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_E_READER_UNAVAILABLE
The specified reader is not currently available for use.
Definition pcsclite.h:153
#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)
Gets 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:66
@ POWER_STATE_UNPOWERED
auto power off
Definition pcscd.h:63
@ POWER_STATE_POWERED
powered
Definition pcscd.h:64
@ POWER_STATE_GRACE_PERIOD
card was in use
Definition pcscd.h:65
#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.
pthread_mutex_t * mMutex
Mutex for this connection.
pthread_mutex_t powerState_lock
powerState mutex
_Atomic int32_t contexts
Number of open contexts.
int slot
Current Reader Slot.
_Atomic SCARDHANDLE hLockId
Lock Id.
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(void)
Generate a pseudo random number.
Definition sys_unix.c:108
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
Definition sys_unix.c:80
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:186
This handles smart card reader communications.