2
* This handles smartcard reader communications.
3
* This is the heart of the M$ smartcard API.
5
* MUSCLE SmartCard Development ( http://www.linuxnet.com )
7
* Copyright (C) 1999-2004
8
* David Corcoran <corcoran@linuxnet.com>
9
* Ludovic Rousseau <ludovic.rousseau@free.fr>
11
* $Id: winscard.c,v 1.51 2005/03/01 09:22:52 rousseau Exp $
21
#include "ifdhandler.h"
23
#include "readerfactory.h"
24
#include "prothandler.h"
25
#include "ifdwrapper.h"
26
#include "atrhandler.h"
27
#include "configfile.h"
28
#include "sys_generic.h"
29
#include "eventhandler.h"
31
#define SCARD_PROTOCOL_ANY_OLD 0x1000 /* used for backward compatibility */
34
* Some defines for context stack
36
#define SCARD_LAST_CONTEXT 1
37
#define SCARD_NO_CONTEXT 0
38
#define SCARD_EXCLUSIVE_CONTEXT -1
39
#define SCARD_NO_LOCK 0
41
SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
42
SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
43
SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
45
LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
46
LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
49
* Check for NULL pointer
52
return SCARD_E_INVALID_PARAMETER;
54
if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
55
dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
59
return SCARD_E_INVALID_VALUE;
63
* Unique identifier for this server so that it can uniquely be
64
* identified by clients and distinguished from others
67
*phContext = (PCSCLITE_SVC_IDENTITY + SYS_RandomInt(1, 65535));
69
Log2(PCSC_LOG_DEBUG, "Establishing Context: %d", *phContext);
71
return SCARD_S_SUCCESS;
74
LONG SCardReleaseContext(SCARDCONTEXT hContext)
77
* Nothing to do here RPC layer will handle this
80
Log2(PCSC_LOG_DEBUG, "Releasing Context: %d", hContext);
82
return SCARD_S_SUCCESS;
85
LONG SCardSetTimeout(SCARDCONTEXT hContext, DWORD dwTimeout)
88
* This is only used at the client side of an RPC call but just in
89
* case someone calls it here
92
return SCARD_E_UNSUPPORTED_FEATURE;
95
LONG SCardConnect(SCARDCONTEXT hContext, LPCTSTR szReader,
96
DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
97
LPDWORD pdwActiveProtocol)
100
PREADER_CONTEXT rContext = NULL;
104
* Check for NULL parameters
106
if (szReader == 0 || phCard == 0 || pdwActiveProtocol == 0)
107
return SCARD_E_INVALID_PARAMETER;
111
if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
112
!(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
113
!(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
114
!(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
115
return SCARD_E_PROTO_MISMATCH;
117
if (dwShareMode != SCARD_SHARE_EXCLUSIVE &&
118
dwShareMode != SCARD_SHARE_SHARED &&
119
dwShareMode != SCARD_SHARE_DIRECT)
120
return SCARD_E_INVALID_VALUE;
122
Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %d",
123
szReader, dwPreferredProtocols);
125
rv = RFReaderInfo((LPTSTR) szReader, &rContext);
127
if (rv != SCARD_S_SUCCESS)
129
Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader);
134
* Make sure the reader is working properly
136
rv = RFCheckReaderStatus(rContext);
137
if (rv != SCARD_S_SUCCESS)
140
/*******************************************
142
* This section checks for simple errors
144
*******************************************/
147
* Connect if not exclusive mode
149
if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
151
Log1(PCSC_LOG_ERROR, "Error Reader Exclusive");
152
return SCARD_E_SHARING_VIOLATION;
155
/*******************************************
157
* This section tries to determine the
158
* presence of a card or not
160
*******************************************/
161
dwStatus = rContext->readerState->readerState;
163
if (dwShareMode != SCARD_SHARE_DIRECT)
165
if (!(dwStatus & SCARD_PRESENT))
167
Log1(PCSC_LOG_ERROR, "Card Not Inserted");
168
return SCARD_E_NO_SMARTCARD;
172
/*******************************************
174
* This section tries to decode the ATR
175
* and set up which protocol to use
177
*******************************************/
178
if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
179
rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW;
182
if (dwShareMode != SCARD_SHARE_DIRECT)
184
/* the protocol is not yet set (no PPS yet) */
185
if (SCARD_PROTOCOL_UNSET == rContext->readerState->cardProtocol)
187
UCHAR ucAvailable, ucDefault;
190
ucDefault = PHGetDefaultProtocol(rContext->readerState->cardAtr,
191
rContext->readerState->cardAtrLength);
193
PHGetAvailableProtocols(rContext->readerState->cardAtr,
194
rContext->readerState->cardAtrLength);
197
* If it is set to ANY let it do any of the protocols
199
if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
200
dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
202
ret = PHSetProtocol(rContext, dwPreferredProtocols,
203
ucAvailable, ucDefault);
205
/* keep cardProtocol = SCARD_PROTOCOL_UNSET in case of error */
206
if (SET_PROTOCOL_PPS_FAILED == ret)
207
return SCARD_W_UNRESPONSIVE_CARD;
209
if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
210
return SCARD_E_PROTO_MISMATCH;
212
/* use negociated protocol */
213
rContext->readerState->cardProtocol = ret;
217
if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
218
return SCARD_E_PROTO_MISMATCH;
223
*pdwActiveProtocol = rContext->readerState->cardProtocol;
225
if ((*pdwActiveProtocol != SCARD_PROTOCOL_T0)
226
&& (*pdwActiveProtocol != SCARD_PROTOCOL_T1))
227
Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %d",
230
Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
231
(*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
234
* Prepare the SCARDHANDLE identity
236
*phCard = RFCreateReaderHandle(rContext);
238
Log2(PCSC_LOG_DEBUG, "hCard Identity: %x", *phCard);
240
/*******************************************
242
* This section tries to set up the
243
* exclusivity modes. -1 is exclusive
245
*******************************************/
247
if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
249
if (rContext->dwContexts == SCARD_NO_CONTEXT)
251
rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT;
252
RFLockSharing(*phCard);
256
RFDestroyReaderHandle(*phCard);
258
return SCARD_E_SHARING_VIOLATION;
264
* Add a connection to the context stack
266
rContext->dwContexts += 1;
270
* Add this handle to the handle list
272
rv = RFAddReaderHandle(rContext, *phCard);
274
if (rv != SCARD_S_SUCCESS)
277
* Clean up - there is no more room
279
RFDestroyReaderHandle(*phCard);
280
if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
281
rContext->dwContexts = SCARD_NO_CONTEXT;
283
if (rContext->dwContexts > SCARD_NO_CONTEXT)
284
rContext->dwContexts -= 1;
287
return SCARD_F_INTERNAL_ERROR;
291
* Allow the status thread to convey information
293
SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
295
return SCARD_S_SUCCESS;
298
LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
299
DWORD dwPreferredProtocols, DWORD dwInitialization,
300
LPDWORD pdwActiveProtocol)
303
PREADER_CONTEXT rContext = NULL;
305
Log1(PCSC_LOG_DEBUG, "Attempting reconnect to token.");
308
return SCARD_E_INVALID_HANDLE;
310
if (dwInitialization != SCARD_LEAVE_CARD &&
311
dwInitialization != SCARD_RESET_CARD &&
312
dwInitialization != SCARD_UNPOWER_CARD)
313
return SCARD_E_INVALID_VALUE;
315
if (dwShareMode != SCARD_SHARE_SHARED &&
316
dwShareMode != SCARD_SHARE_EXCLUSIVE &&
317
dwShareMode != SCARD_SHARE_DIRECT)
318
return SCARD_E_INVALID_VALUE;
320
if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
321
!(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
322
!(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
323
!(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
324
return SCARD_E_PROTO_MISMATCH;
326
if (pdwActiveProtocol == 0)
327
return SCARD_E_INVALID_PARAMETER;
329
rv = RFReaderInfoById(hCard, &rContext);
330
if (rv != SCARD_S_SUCCESS)
334
* Make sure the reader is working properly
336
rv = RFCheckReaderStatus(rContext);
337
if (rv != SCARD_S_SUCCESS)
340
rv = RFFindReaderHandle(hCard);
341
if (rv != SCARD_S_SUCCESS)
345
* Make sure no one has a lock on this reader
347
if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
351
* Handle the dwInitialization
353
if ((dwInitialization != SCARD_LEAVE_CARD)
354
&& (dwInitialization != SCARD_UNPOWER_CARD)
355
&& (dwInitialization != SCARD_RESET_CARD))
356
return SCARD_E_INVALID_VALUE;
359
* RFUnblockReader( rContext ); FIX - this doesn't work
362
if (dwInitialization == SCARD_RESET_CARD ||
363
dwInitialization == SCARD_UNPOWER_CARD)
366
* Currently pcsc-lite keeps the card powered constantly
368
if (SCARD_RESET_CARD == dwInitialization)
369
rv = IFDPowerICC(rContext, IFD_RESET,
370
rContext->readerState->cardAtr,
371
&rContext->readerState->cardAtrLength);
374
rv = IFDPowerICC(rContext, IFD_POWER_DOWN,
375
rContext->readerState->cardAtr,
376
&rContext->readerState->cardAtrLength);
377
rv = IFDPowerICC(rContext, IFD_POWER_UP,
378
rContext->readerState->cardAtr,
379
&rContext->readerState->cardAtrLength);
382
/* the protocol is unset after a power on */
383
rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNSET;
386
* Notify the card has been reset
387
* Not doing this could result in deadlock
389
rv = RFCheckReaderEventState(rContext, hCard);
393
case SCARD_W_RESET_CARD:
396
case SCARD_W_REMOVED_CARD:
397
Log1(PCSC_LOG_ERROR, "card removed");
398
return SCARD_W_REMOVED_CARD;
400
/* invalid EventStatus */
401
case SCARD_E_INVALID_VALUE:
402
Log1(PCSC_LOG_ERROR, "invalid EventStatus");
403
return SCARD_F_INTERNAL_ERROR;
405
/* invalid hCard, but hCard was widely used some lines above :( */
406
case SCARD_E_INVALID_HANDLE:
407
Log1(PCSC_LOG_ERROR, "invalid handle");
408
return SCARD_F_INTERNAL_ERROR;
410
case SCARD_S_SUCCESS:
412
* Notify the card has been reset
414
RFSetReaderEventState(rContext, SCARD_RESET);
417
* Set up the status bit masks on dwStatus
419
if (rv == SCARD_S_SUCCESS)
421
rContext->readerState->readerState |= SCARD_PRESENT;
422
rContext->readerState->readerState &= ~SCARD_ABSENT;
423
rContext->readerState->readerState |= SCARD_POWERED;
424
rContext->readerState->readerState |= SCARD_NEGOTIABLE;
425
rContext->readerState->readerState &= ~SCARD_SPECIFIC;
426
rContext->readerState->readerState &= ~SCARD_SWALLOWED;
427
rContext->readerState->readerState &= ~SCARD_UNKNOWN;
431
rContext->readerState->readerState |= SCARD_PRESENT;
432
rContext->readerState->readerState &= ~SCARD_ABSENT;
433
rContext->readerState->readerState |= SCARD_SWALLOWED;
434
rContext->readerState->readerState &= ~SCARD_POWERED;
435
rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
436
rContext->readerState->readerState &= ~SCARD_SPECIFIC;
437
rContext->readerState->readerState &= ~SCARD_UNKNOWN;
438
rContext->readerState->cardAtrLength = 0;
441
if (rContext->readerState->cardAtrLength > 0)
443
Log1(PCSC_LOG_DEBUG, "Reset complete.");
444
LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
445
rContext->readerState->cardAtr,
446
rContext->readerState->cardAtrLength);
450
DWORD dwStatus, dwAtrLen;
451
UCHAR ucAtr[MAX_ATR_SIZE];
453
Log1(PCSC_LOG_ERROR, "Error resetting card.");
454
IFDStatusICC(rContext, &dwStatus, ucAtr, &dwAtrLen);
455
if (dwStatus & SCARD_PRESENT)
456
return SCARD_W_UNRESPONSIVE_CARD;
458
return SCARD_E_NO_SMARTCARD;
464
"invalid retcode from RFCheckReaderEventState (%X)", rv);
465
return SCARD_F_INTERNAL_ERROR;
471
if (dwInitialization == SCARD_LEAVE_CARD)
478
/*******************************************
480
* This section tries to decode the ATR
481
* and set up which protocol to use
483
*******************************************/
484
if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
485
rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW;
488
if (dwShareMode != SCARD_SHARE_DIRECT)
490
/* the protocol is not yet set (no PPS yet) */
491
if (SCARD_PROTOCOL_UNSET == rContext->readerState->cardProtocol)
493
UCHAR ucAvailable, ucDefault;
496
ucDefault = PHGetDefaultProtocol(rContext->readerState->cardAtr,
497
rContext->readerState->cardAtrLength);
499
PHGetAvailableProtocols(rContext->readerState->cardAtr,
500
rContext->readerState->cardAtrLength);
502
/* If it is set to ANY let it do any of the protocols */
503
if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
504
dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
506
ret = PHSetProtocol(rContext, dwPreferredProtocols,
507
ucAvailable, ucDefault);
509
/* keep cardProtocol = SCARD_PROTOCOL_UNSET in case of error */
510
if (SET_PROTOCOL_PPS_FAILED == ret)
511
return SCARD_W_UNRESPONSIVE_CARD;
513
if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
514
return SCARD_E_PROTO_MISMATCH;
516
/* use negociated protocol */
517
rContext->readerState->cardProtocol = ret;
521
if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
522
return SCARD_E_PROTO_MISMATCH;
527
*pdwActiveProtocol = rContext->readerState->cardProtocol;
529
if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
531
if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
534
* Do nothing - we are already exclusive
538
if (rContext->dwContexts == SCARD_LAST_CONTEXT)
540
rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT;
541
RFLockSharing(hCard);
544
return SCARD_E_SHARING_VIOLATION;
547
} else if (dwShareMode == SCARD_SHARE_SHARED)
549
if (rContext->dwContexts != SCARD_EXCLUSIVE_CONTEXT)
552
* Do nothing - in sharing mode already
557
* We are in exclusive mode but want to share now
559
RFUnlockSharing(hCard);
560
rContext->dwContexts = SCARD_LAST_CONTEXT;
562
} else if (dwShareMode == SCARD_SHARE_DIRECT)
564
if (rContext->dwContexts != SCARD_EXCLUSIVE_CONTEXT)
567
* Do nothing - in sharing mode already
572
* We are in exclusive mode but want to share now
574
RFUnlockSharing(hCard);
575
rContext->dwContexts = SCARD_LAST_CONTEXT;
578
return SCARD_E_INVALID_VALUE;
581
* Clear a previous event to the application
583
RFClearReaderEventState(rContext, hCard);
586
* Allow the status thread to convey information
588
SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
590
return SCARD_S_SUCCESS;
593
LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
596
PREADER_CONTEXT rContext = NULL;
599
return SCARD_E_INVALID_HANDLE;
601
rv = RFReaderInfoById(hCard, &rContext);
602
if (rv != SCARD_S_SUCCESS)
605
rv = RFFindReaderHandle(hCard);
606
if (rv != SCARD_S_SUCCESS)
609
if ((dwDisposition != SCARD_LEAVE_CARD)
610
&& (dwDisposition != SCARD_UNPOWER_CARD)
611
&& (dwDisposition != SCARD_RESET_CARD)
612
&& (dwDisposition != SCARD_EJECT_CARD))
613
return SCARD_E_INVALID_VALUE;
616
* Unlock any blocks on this context
618
RFUnlockSharing(hCard);
620
Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->dwContexts);
622
if (dwDisposition == SCARD_RESET_CARD ||
623
dwDisposition == SCARD_UNPOWER_CARD)
626
* Currently pcsc-lite keeps the card powered constantly
628
if (SCARD_RESET_CARD == dwDisposition)
629
rv = IFDPowerICC(rContext, IFD_RESET,
630
rContext->readerState->cardAtr,
631
&rContext->readerState->cardAtrLength);
634
rv = IFDPowerICC(rContext, IFD_POWER_DOWN,
635
rContext->readerState->cardAtr,
636
&rContext->readerState->cardAtrLength);
637
rv = IFDPowerICC(rContext, IFD_POWER_UP,
638
rContext->readerState->cardAtr,
639
&rContext->readerState->cardAtrLength);
642
/* the protocol is unset after a power on */
643
rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNSET;
646
* Notify the card has been reset
648
RFSetReaderEventState(rContext, SCARD_RESET);
651
* Set up the status bit masks on dwStatus
653
if (rv == SCARD_S_SUCCESS)
655
rContext->readerState->readerState |= SCARD_PRESENT;
656
rContext->readerState->readerState &= ~SCARD_ABSENT;
657
rContext->readerState->readerState |= SCARD_POWERED;
658
rContext->readerState->readerState |= SCARD_NEGOTIABLE;
659
rContext->readerState->readerState &= ~SCARD_SPECIFIC;
660
rContext->readerState->readerState &= ~SCARD_SWALLOWED;
661
rContext->readerState->readerState &= ~SCARD_UNKNOWN;
665
if (rContext->readerState->readerState & SCARD_ABSENT)
666
rContext->readerState->readerState &= ~SCARD_PRESENT;
668
rContext->readerState->readerState |= SCARD_PRESENT;
669
/* SCARD_ABSENT flag is already set */
670
rContext->readerState->readerState |= SCARD_SWALLOWED;
671
rContext->readerState->readerState &= ~SCARD_POWERED;
672
rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
673
rContext->readerState->readerState &= ~SCARD_SPECIFIC;
674
rContext->readerState->readerState &= ~SCARD_UNKNOWN;
675
rContext->readerState->cardAtrLength = 0;
678
if (rContext->readerState->cardAtrLength > 0)
679
Log1(PCSC_LOG_DEBUG, "Reset complete.");
681
Log1(PCSC_LOG_ERROR, "Error resetting card.");
684
else if (dwDisposition == SCARD_EJECT_CARD)
686
UCHAR controlBuffer[5];
687
UCHAR receiveBuffer[MAX_BUFFER_SIZE];
691
* Set up the CTBCS command for Eject ICC
693
controlBuffer[0] = 0x20;
694
controlBuffer[1] = 0x15;
695
controlBuffer[2] = (rContext->dwSlot & 0x0000FFFF) + 1;
696
controlBuffer[3] = 0x00;
697
controlBuffer[4] = 0x00;
699
rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
702
if (rv == SCARD_S_SUCCESS)
704
if (receiveLength == 2 && receiveBuffer[0] == 0x90)
706
Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
712
Log1(PCSC_LOG_ERROR, "Error ejecting card.");
715
Log1(PCSC_LOG_ERROR, "Error ejecting card.");
718
else if (dwDisposition == SCARD_LEAVE_CARD)
726
* Remove and destroy this handle
728
RFRemoveReaderHandle(rContext, hCard);
729
RFDestroyReaderHandle(hCard);
732
* For exclusive connection reset it to no connections
734
if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
736
rContext->dwContexts = SCARD_NO_CONTEXT;
737
return SCARD_S_SUCCESS;
741
* Remove a connection from the context stack
743
rContext->dwContexts -= 1;
745
if (rContext->dwContexts < 0)
746
rContext->dwContexts = 0;
749
* Allow the status thread to convey information
751
SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
753
return SCARD_S_SUCCESS;
756
LONG SCardBeginTransaction(SCARDHANDLE hCard)
759
PREADER_CONTEXT rContext;
762
return SCARD_E_INVALID_HANDLE;
764
rv = RFReaderInfoById(hCard, &rContext);
767
* Cannot find the hCard in this context
769
if (rv != SCARD_S_SUCCESS)
773
* Make sure the reader is working properly
775
rv = RFCheckReaderStatus(rContext);
776
if (rv != SCARD_S_SUCCESS)
779
rv = RFFindReaderHandle(hCard);
780
if (rv != SCARD_S_SUCCESS)
784
* Make sure some event has not occurred
786
if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
789
rv = RFLockSharing(hCard);
791
Log2(PCSC_LOG_DEBUG, "Status: %d.", rv);
796
LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
799
PREADER_CONTEXT rContext = NULL;
802
* Ignoring dwDisposition for now
805
return SCARD_E_INVALID_HANDLE;
807
if ((dwDisposition != SCARD_LEAVE_CARD)
808
&& (dwDisposition != SCARD_UNPOWER_CARD)
809
&& (dwDisposition != SCARD_RESET_CARD)
810
&& (dwDisposition != SCARD_EJECT_CARD))
811
return SCARD_E_INVALID_VALUE;
813
rv = RFReaderInfoById(hCard, &rContext);
816
* Cannot find the hCard in this context
818
if (rv != SCARD_S_SUCCESS)
821
rv = RFFindReaderHandle(hCard);
822
if (rv != SCARD_S_SUCCESS)
826
* Make sure some event has not occurred
828
if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
831
if (dwDisposition == SCARD_RESET_CARD ||
832
dwDisposition == SCARD_UNPOWER_CARD)
835
* Currently pcsc-lite keeps the card always powered
837
if (SCARD_RESET_CARD == dwDisposition)
838
rv = IFDPowerICC(rContext, IFD_RESET,
839
rContext->readerState->cardAtr,
840
&rContext->readerState->cardAtrLength);
843
rv = IFDPowerICC(rContext, IFD_POWER_DOWN,
844
rContext->readerState->cardAtr,
845
&rContext->readerState->cardAtrLength);
846
rv = IFDPowerICC(rContext, IFD_POWER_UP,
847
rContext->readerState->cardAtr,
848
&rContext->readerState->cardAtrLength);
851
/* the protocol is unset after a power on */
852
rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNSET;
855
* Notify the card has been reset
857
RFSetReaderEventState(rContext, SCARD_RESET);
860
* Set up the status bit masks on dwStatus
862
if (rv == SCARD_S_SUCCESS)
864
rContext->readerState->readerState |= SCARD_PRESENT;
865
rContext->readerState->readerState &= ~SCARD_ABSENT;
866
rContext->readerState->readerState |= SCARD_POWERED;
867
rContext->readerState->readerState |= SCARD_NEGOTIABLE;
868
rContext->readerState->readerState &= ~SCARD_SPECIFIC;
869
rContext->readerState->readerState &= ~SCARD_SWALLOWED;
870
rContext->readerState->readerState &= ~SCARD_UNKNOWN;
874
if (rContext->readerState->readerState & SCARD_ABSENT)
875
rContext->readerState->readerState &= ~SCARD_PRESENT;
877
rContext->readerState->readerState |= SCARD_PRESENT;
878
/* SCARD_ABSENT flag is already set */
879
rContext->readerState->readerState |= SCARD_SWALLOWED;
880
rContext->readerState->readerState &= ~SCARD_POWERED;
881
rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
882
rContext->readerState->readerState &= ~SCARD_SPECIFIC;
883
rContext->readerState->readerState &= ~SCARD_UNKNOWN;
884
rContext->readerState->cardAtrLength = 0;
887
if (rContext->readerState->cardAtrLength > 0)
888
Log1(PCSC_LOG_DEBUG, "Reset complete.");
890
Log1(PCSC_LOG_ERROR, "Error resetting card.");
893
else if (dwDisposition == SCARD_EJECT_CARD)
895
UCHAR controlBuffer[5];
896
UCHAR receiveBuffer[MAX_BUFFER_SIZE];
900
* Set up the CTBCS command for Eject ICC
902
controlBuffer[0] = 0x20;
903
controlBuffer[1] = 0x15;
904
controlBuffer[2] = (rContext->dwSlot & 0x0000FFFF) + 1;
905
controlBuffer[3] = 0x00;
906
controlBuffer[4] = 0x00;
908
rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
911
if (rv == SCARD_S_SUCCESS)
913
if (receiveLength == 2 && receiveBuffer[0] == 0x90)
915
Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
921
Log1(PCSC_LOG_ERROR, "Error ejecting card.");
924
Log1(PCSC_LOG_ERROR, "Error ejecting card.");
927
else if (dwDisposition == SCARD_LEAVE_CARD)
935
* Unlock any blocks on this context
937
RFUnlockSharing(hCard);
939
Log2(PCSC_LOG_DEBUG, "Status: %d.", rv);
944
LONG SCardCancelTransaction(SCARDHANDLE hCard)
947
PREADER_CONTEXT rContext = NULL;
950
* Ignoring dwDisposition for now
953
return SCARD_E_INVALID_HANDLE;
955
rv = RFReaderInfoById(hCard, &rContext);
958
* Cannot find the hCard in this context
960
if (rv != SCARD_S_SUCCESS)
963
rv = RFFindReaderHandle(hCard);
964
if (rv != SCARD_S_SUCCESS)
968
* Make sure some event has not occurred
970
if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
973
rv = RFUnlockSharing(hCard);
975
Log2(PCSC_LOG_DEBUG, "Status: %d.", rv);
980
LONG SCardStatus(SCARDHANDLE hCard, LPTSTR mszReaderNames,
981
LPDWORD pcchReaderLen, LPDWORD pdwState,
982
LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
985
PREADER_CONTEXT rContext = NULL;
987
rv = RFReaderInfoById(hCard, &rContext);
990
* Cannot find the hCard in this context
992
if (rv != SCARD_S_SUCCESS)
995
if (strlen(rContext->lpcReader) > MAX_BUFFER_SIZE
996
|| rContext->readerState->cardAtrLength > MAX_ATR_SIZE
997
|| rContext->readerState->cardAtrLength < 0)
998
return SCARD_F_INTERNAL_ERROR;
1001
* This is a client side function however the server maintains the
1002
* list of events between applications so it must be passed through to
1003
* obtain this event if it has occurred
1007
* Make sure some event has not occurred
1009
if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
1013
* Make sure the reader is working properly
1015
rv = RFCheckReaderStatus(rContext);
1016
if (rv != SCARD_S_SUCCESS)
1020
{ /* want reader name */
1022
{ /* & present reader name length */
1023
if (*pcchReaderLen >= strlen(rContext->lpcReader))
1024
{ /* & enough room */
1025
*pcchReaderLen = strlen(rContext->lpcReader);
1026
strncpy(mszReaderNames, rContext->lpcReader, MAX_READERNAME);
1029
{ /* may report only reader name len */
1030
*pcchReaderLen = strlen(rContext->lpcReader);
1031
rv = SCARD_E_INSUFFICIENT_BUFFER;
1035
{ /* present buf & no buflen */
1036
return SCARD_E_INVALID_PARAMETER;
1042
{ /* want reader len only */
1043
*pcchReaderLen = strlen(rContext->lpcReader);
1052
*pdwState = rContext->readerState->readerState;
1055
*pdwProtocol = rContext->readerState->cardProtocol;
1060
{ /* & present ATR length */
1061
if (*pcbAtrLen >= rContext->readerState->cardAtrLength)
1062
{ /* & enough room */
1063
*pcbAtrLen = rContext->readerState->cardAtrLength;
1064
memcpy(pbAtr, rContext->readerState->cardAtr,
1065
rContext->readerState->cardAtrLength);
1068
{ /* may report only ATR len */
1069
*pcbAtrLen = rContext->readerState->cardAtrLength;
1070
rv = SCARD_E_INSUFFICIENT_BUFFER;
1074
{ /* present buf & no buflen */
1075
return SCARD_E_INVALID_PARAMETER;
1081
{ /* want ATR len only */
1082
*pcbAtrLen = rContext->readerState->cardAtrLength;
1093
LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
1094
LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
1097
* Client side function
1099
return SCARD_S_SUCCESS;
1102
LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
1103
LPCVOID pbSendBuffer, DWORD cbSendLength,
1104
LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
1107
PREADER_CONTEXT rContext = NULL;
1109
/* 0 bytes returned by default */
1110
*lpBytesReturned = 0;
1113
return SCARD_E_INVALID_HANDLE;
1116
* Make sure no one has a lock on this reader
1118
if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
1121
rv = RFReaderInfoById(hCard, &rContext);
1122
if (rv != SCARD_S_SUCCESS)
1125
if (IFD_HVERSION_2_0 == rContext->dwVersion)
1126
if (NULL == pbSendBuffer || 0 == cbSendLength)
1127
return SCARD_E_INVALID_PARAMETER;
1130
* Make sure the reader is working properly
1132
rv = RFCheckReaderStatus(rContext);
1133
if (rv != SCARD_S_SUCCESS)
1136
rv = RFFindReaderHandle(hCard);
1137
if (rv != SCARD_S_SUCCESS)
1141
* Make sure some event has not occurred
1143
if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
1146
if (cbSendLength > MAX_BUFFER_SIZE)
1147
return SCARD_E_INSUFFICIENT_BUFFER;
1149
if (IFD_HVERSION_2_0 == rContext->dwVersion)
1151
/* we must wrap a API 3.0 client in an API 2.0 driver */
1152
*lpBytesReturned = cbRecvLength;
1153
return IFDControl_v2(rContext, (PUCHAR)pbSendBuffer,
1154
cbSendLength, pbRecvBuffer, lpBytesReturned);
1157
if (IFD_HVERSION_3_0 == rContext->dwVersion)
1158
return IFDControl(rContext, dwControlCode, pbSendBuffer,
1159
cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned);
1161
return SCARD_E_UNSUPPORTED_FEATURE;
1164
LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1165
LPBYTE pbAttr, LPDWORD pcbAttrLen)
1168
PREADER_CONTEXT rContext = NULL;
1171
return SCARD_E_INVALID_HANDLE;
1174
* Make sure no one has a lock on this reader
1176
if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
1179
rv = RFReaderInfoById(hCard, &rContext);
1180
if (rv != SCARD_S_SUCCESS)
1184
* Make sure the reader is working properly
1186
rv = RFCheckReaderStatus(rContext);
1187
if (rv != SCARD_S_SUCCESS)
1190
rv = RFFindReaderHandle(hCard);
1191
if (rv != SCARD_S_SUCCESS)
1195
* Make sure some event has not occurred
1197
if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
1200
rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr);
1201
if (rv == IFD_SUCCESS)
1202
return SCARD_S_SUCCESS;
1204
return SCARD_E_NOT_TRANSACTED;
1207
LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
1208
LPCBYTE pbAttr, DWORD cbAttrLen)
1211
PREADER_CONTEXT rContext = NULL;
1214
return SCARD_E_INVALID_HANDLE;
1217
* Make sure no one has a lock on this reader
1219
if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
1222
rv = RFReaderInfoById(hCard, &rContext);
1223
if (rv != SCARD_S_SUCCESS)
1227
* Make sure the reader is working properly
1229
rv = RFCheckReaderStatus(rContext);
1230
if (rv != SCARD_S_SUCCESS)
1233
rv = RFFindReaderHandle(hCard);
1234
if (rv != SCARD_S_SUCCESS)
1238
* Make sure some event has not occurred
1240
if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
1243
rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr);
1244
if (rv == IFD_SUCCESS)
1245
return SCARD_S_SUCCESS;
1247
return SCARD_E_NOT_TRANSACTED;
1250
LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
1251
LPCBYTE pbSendBuffer, DWORD cbSendLength,
1252
LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
1253
LPDWORD pcbRecvLength)
1256
PREADER_CONTEXT rContext = NULL;
1257
SCARD_IO_HEADER sSendPci, sRecvPci;
1258
DWORD dwRxLength, tempRxLength;
1260
if (pcbRecvLength == 0)
1261
return SCARD_E_INVALID_PARAMETER;
1263
dwRxLength = *pcbRecvLength;
1267
return SCARD_E_INVALID_HANDLE;
1269
if (pbSendBuffer == NULL || pbRecvBuffer == NULL || pioSendPci == NULL)
1270
return SCARD_E_INVALID_PARAMETER;
1273
* Must at least send a 4 bytes APDU
1275
if (cbSendLength < 4)
1276
return SCARD_E_INVALID_PARAMETER;
1279
* Must at least have 2 status words even for SCardControl
1282
return SCARD_E_INSUFFICIENT_BUFFER;
1285
* Make sure no one has a lock on this reader
1287
if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
1290
rv = RFReaderInfoById(hCard, &rContext);
1291
if (rv != SCARD_S_SUCCESS)
1295
* Make sure the reader is working properly
1297
rv = RFCheckReaderStatus(rContext);
1298
if (rv != SCARD_S_SUCCESS)
1301
rv = RFFindReaderHandle(hCard);
1302
if (rv != SCARD_S_SUCCESS)
1306
* Make sure some event has not occurred
1308
if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
1312
* Check for some common errors
1314
if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1316
if (rContext->readerState->readerState & SCARD_ABSENT)
1318
return SCARD_E_NO_SMARTCARD;
1322
if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
1324
if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD)
1326
if (pioSendPci->dwProtocol != rContext->readerState->cardProtocol)
1328
return SCARD_E_PROTO_MISMATCH;
1333
if (cbSendLength > MAX_BUFFER_SIZE)
1335
return SCARD_E_INSUFFICIENT_BUFFER;
1339
* Removed - a user may allocate a larger buffer if ( dwRxLength >
1340
* MAX_BUFFER_SIZE ) { return SCARD_E_INSUFFICIENT_BUFFER; }
1344
* Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler
1348
if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T0)
1350
sSendPci.Protocol = 0;
1351
} else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1)
1353
sSendPci.Protocol = 1;
1354
} else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1357
* This is temporary ......
1359
sSendPci.Protocol = SCARD_PROTOCOL_RAW;
1360
} else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD)
1362
/* Fix by Amira (Athena) */
1364
unsigned long prot = rContext->readerState->cardProtocol;
1366
for (i = 0 ; prot != 1 ; i++)
1369
sSendPci.Protocol = i;
1372
sSendPci.Length = pioSendPci->cbPciLength;
1374
/* the protocol number is decoded a few lines above */
1375
Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%d", sSendPci.Protocol);
1377
tempRxLength = dwRxLength;
1379
if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
1381
rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength,
1382
pbRecvBuffer, &dwRxLength);
1385
rv = IFDTransmit(rContext, sSendPci, (PUCHAR) pbSendBuffer,
1386
cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci);
1391
pioRecvPci->dwProtocol = sRecvPci.Protocol;
1392
pioRecvPci->cbPciLength = sRecvPci.Length;
1396
* Check for any errors that might have occurred
1399
if (rv != SCARD_S_SUCCESS)
1402
Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
1403
return SCARD_E_NOT_TRANSACTED;
1407
* Available is less than received
1409
if (tempRxLength < dwRxLength)
1412
return SCARD_E_INSUFFICIENT_BUFFER;
1415
if (dwRxLength > MAX_BUFFER_SIZE)
1418
return SCARD_E_INSUFFICIENT_BUFFER;
1424
*pcbRecvLength = dwRxLength;
1425
return SCARD_S_SUCCESS;
1428
LONG SCardListReaders(SCARDCONTEXT hContext, LPCTSTR mszGroups,
1429
LPTSTR mszReaders, LPDWORD pcchReaders)
1432
* Client side function
1434
return SCARD_S_SUCCESS;
1437
LONG SCardCancel(SCARDCONTEXT hContext)
1440
* Client side function
1442
return SCARD_S_SUCCESS;