~ubuntu-branches/ubuntu/jaunty/pcsc-lite/jaunty-security

« back to all changes in this revision

Viewing changes to pcsc-lite/src/ifdwrapper.c

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Rousseau
  • Date: 2005-11-27 18:04:59 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051127180459-qrex2gzpq9d8jexd
Tags: 1.2.9-beta9-1
* New upstream version
* debian/compat: change from 3 to 4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * This wraps the dynamic ifdhandler functions.
3
 
 *
4
 
 * MUSCLE SmartCard Development ( http://www.linuxnet.com )
5
 
 *
6
 
 * Copyright (C) 1999-2004
7
 
 *  David Corcoran <corcoran@linuxnet.com>
8
 
 *  Damien Sauveron <damien.sauveron@labri.fr>
9
 
 *  Ludovic Rousseau <ludovic.rousseau@free.fr>
10
 
 *
11
 
 * $Id: ifdwrapper.c,v 1.29 2005/02/22 14:40:26 rousseau Exp $
12
 
 */
13
 
 
14
 
#include "config.h"
15
 
#include "pcsclite.h"
16
 
#include "ifdhandler.h"
17
 
#include "debuglog.h"
18
 
#include "readerfactory.h"
19
 
#include "ifdwrapper.h"
20
 
#include "atrhandler.h"
21
 
#include "dyn_generic.h"
22
 
#include "sys_generic.h"
23
 
 
24
 
#undef PCSCLITE_STATIC_DRIVER
25
 
 
26
 
/*
27
 
 * Function: IFDSetPTS Purpose : To set the protocol type selection (PTS). 
28
 
 * This function sets the appropriate protocol to be used on the card. 
29
 
 */
30
 
 
31
 
LONG IFDSetPTS(PREADER_CONTEXT rContext, DWORD dwProtocol, UCHAR ucFlags,
32
 
        UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
33
 
{
34
 
        RESPONSECODE rv = 0;
35
 
        UCHAR ucValue[1];
36
 
 
37
 
#ifndef PCSCLITE_STATIC_DRIVER
38
 
        RESPONSECODE(*IFD_set_protocol_parameters) (DWORD, UCHAR, UCHAR,
39
 
                UCHAR, UCHAR) = NULL;
40
 
        RESPONSECODE(*IFDH_set_protocol_parameters) (DWORD, DWORD, UCHAR,
41
 
                UCHAR, UCHAR, UCHAR) = NULL;
42
 
 
43
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
44
 
        {
45
 
                IFD_set_protocol_parameters = (RESPONSECODE(*)(DWORD, UCHAR, UCHAR,
46
 
                        UCHAR, UCHAR)) rContext->psFunctions.psFunctions_v1.pvfSetProtocolParameters;
47
 
 
48
 
                if (NULL == IFD_set_protocol_parameters)
49
 
                        return SCARD_E_UNSUPPORTED_FEATURE;
50
 
        }
51
 
        else
52
 
        {
53
 
                IFDH_set_protocol_parameters = (RESPONSECODE(*)(DWORD, DWORD, UCHAR,
54
 
                        UCHAR, UCHAR, UCHAR))
55
 
                        rContext->psFunctions.psFunctions_v2.pvfSetProtocolParameters;
56
 
 
57
 
                if (NULL == IFDH_set_protocol_parameters)
58
 
                        return SCARD_E_UNSUPPORTED_FEATURE;
59
 
        }
60
 
#endif
61
 
 
62
 
        /*
63
 
         * LOCK THIS CODE REGION 
64
 
         */
65
 
        SYS_MutexLock(rContext->mMutex);
66
 
 
67
 
        ucValue[0] = rContext->dwSlot;
68
 
 
69
 
#ifndef PCSCLITE_STATIC_DRIVER
70
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
71
 
        {
72
 
                ucValue[0] = rContext->dwSlot;
73
 
                IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
74
 
                rv = (*IFD_set_protocol_parameters) (dwProtocol,
75
 
                        ucFlags, ucPTS1, ucPTS2, ucPTS3);
76
 
        }
77
 
        else
78
 
        {
79
 
                rv = (*IFDH_set_protocol_parameters) (rContext->dwSlot, 
80
 
                                                      dwProtocol,
81
 
                                                      ucFlags, ucPTS1, 
82
 
                                                      ucPTS2, ucPTS3);
83
 
        }
84
 
#else
85
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
86
 
        {
87
 
                ucValue[0] = rContext->dwSlot;
88
 
                IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
89
 
                rv = IFD_Set_Protocol_Parameters(dwProtocol, ucFlags, ucPTS1,
90
 
                        ucPTS2, ucPTS3);
91
 
        }
92
 
        else
93
 
        {
94
 
                rv = IFDHSetProtocolParameters(rContext->dwSlot, dwProtocol,
95
 
                        ucFlags, ucPTS1, ucPTS2, ucPTS3);
96
 
        }
97
 
#endif
98
 
 
99
 
        SYS_MutexUnLock(rContext->mMutex);
100
 
        /*
101
 
         * END OF LOCKED REGION 
102
 
         */
103
 
 
104
 
        return rv;
105
 
}
106
 
 
107
 
/*
108
 
 * Function: IFDOpenIFD Purpose : This function opens a communication
109
 
 * channel to the IFD. 
110
 
 */
111
 
 
112
 
LONG IFDOpenIFD(PREADER_CONTEXT rContext)
113
 
{
114
 
        RESPONSECODE rv = 0;
115
 
 
116
 
#ifndef PCSCLITE_STATIC_DRIVER
117
 
        RESPONSECODE(*IO_create_channel) (DWORD) = NULL;
118
 
        RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
119
 
        RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPTSTR) = NULL;
120
 
 
121
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
122
 
                IO_create_channel =
123
 
                        rContext->psFunctions.psFunctions_v1.pvfCreateChannel;
124
 
        else
125
 
                if (rContext->dwVersion == IFD_HVERSION_2_0)
126
 
                        IFDH_create_channel =
127
 
                                rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
128
 
                else
129
 
                {
130
 
                        IFDH_create_channel =
131
 
                                rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
132
 
                        IFDH_create_channel_by_name =
133
 
                                rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
134
 
                }
135
 
#endif
136
 
 
137
 
        /*
138
 
         * LOCK THIS CODE REGION 
139
 
         */
140
 
 
141
 
        SYS_MutexLock(rContext->mMutex);
142
 
#ifndef PCSCLITE_STATIC_DRIVER
143
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
144
 
        {
145
 
                rv = (*IO_create_channel) (rContext->dwPort);
146
 
        } else if (rContext->dwVersion == IFD_HVERSION_2_0)
147
 
        {
148
 
                rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
149
 
        } else
150
 
        {
151
 
                /* use device name only if defined */
152
 
                if (rContext->lpcDevice[0] != '\0')
153
 
                        rv = (*IFDH_create_channel_by_name) (rContext->dwSlot, rContext->lpcDevice);
154
 
                else
155
 
                        rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
156
 
        }
157
 
#else
158
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
159
 
        {
160
 
                rv = IO_Create_Channel(rContext->dwPort);
161
 
        } else if (rContext->dwVersion == IFD_HVERSION_2_0)
162
 
        { 
163
 
                rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
164
 
        } else
165
 
        {
166
 
                /* Use device name only if defined */
167
 
                if (rContext->lpcDevice[0] != '\0')
168
 
                        rv = IFDHCreateChannelByName(rContext->dwSlot, rContext->lpcDevice);
169
 
                else
170
 
                        rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
171
 
        }
172
 
#endif
173
 
        SYS_MutexUnLock(rContext->mMutex);
174
 
 
175
 
        /*
176
 
         * END OF LOCKED REGION 
177
 
         */
178
 
 
179
 
        return rv;
180
 
}
181
 
 
182
 
/*
183
 
 * Function: IFDCloseIFD Purpose : This function closes a communication
184
 
 * channel to the IFD. 
185
 
 */
186
 
 
187
 
LONG IFDCloseIFD(PREADER_CONTEXT rContext)
188
 
{
189
 
        RESPONSECODE rv = 0;
190
 
 
191
 
#ifndef PCSCLITE_STATIC_DRIVER
192
 
        RESPONSECODE(*IO_close_channel) () = NULL;
193
 
        RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;
194
 
 
195
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
196
 
                IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel;
197
 
        else
198
 
                IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
199
 
#endif
200
 
 
201
 
        /*
202
 
         * LOCK THIS CODE REGION 
203
 
         */
204
 
 
205
 
        SYS_MutexLock(rContext->mMutex);
206
 
#ifndef PCSCLITE_STATIC_DRIVER
207
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
208
 
        
209
 
                rv = (*IO_close_channel) ();
210
 
        else
211
 
                rv = (*IFDH_close_channel) (rContext->dwSlot);
212
 
#else
213
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
214
 
                rv = IO_Close_Channel();
215
 
        else
216
 
                rv = IFDHCloseChannel(rContext->dwSlot);
217
 
#endif
218
 
        SYS_MutexUnLock(rContext->mMutex);
219
 
 
220
 
        /*
221
 
         * END OF LOCKED REGION 
222
 
         */
223
 
 
224
 
        return rv;
225
 
}
226
 
 
227
 
/*
228
 
 * Function: IFDSetCapabilites Purpose : This function set's capabilities
229
 
 * in the reader. 
230
 
 */
231
 
 
232
 
LONG IFDSetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
233
 
                        DWORD dwLength, PUCHAR pucValue)
234
 
{
235
 
        LONG rv = 0;
236
 
 
237
 
#ifndef PCSCLITE_STATIC_DRIVER
238
 
        RESPONSECODE(*IFD_set_capabilities) (DWORD, PUCHAR) = NULL;
239
 
        RESPONSECODE(*IFDH_set_capabilities) (DWORD, DWORD, DWORD, PUCHAR) = NULL;
240
 
 
241
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
242
 
                IFD_set_capabilities = rContext->psFunctions.psFunctions_v1.pvfSetCapabilities;
243
 
        else
244
 
                IFDH_set_capabilities = rContext->psFunctions.psFunctions_v2.pvfSetCapabilities;
245
 
#endif
246
 
 
247
 
        /*
248
 
         * Let the calling function lock this otherwise a deadlock will
249
 
         * result 
250
 
         */
251
 
 
252
 
#ifndef PCSCLITE_STATIC_DRIVER
253
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
254
 
                rv = (*IFD_set_capabilities) (dwTag, pucValue);
255
 
        else
256
 
                rv = (*IFDH_set_capabilities) (rContext->dwSlot, dwTag,
257
 
                        dwLength, pucValue);
258
 
#else
259
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
260
 
                rv = IFD_Set_Capabilities(dwTag, pucValue);
261
 
        else
262
 
                rv = IFDHSetCapabilities(rContext->dwSlot, dwTag, dwLength,
263
 
                        pucValue);
264
 
#endif
265
 
 
266
 
        return rv;
267
 
}
268
 
 
269
 
/*
270
 
 * Function: IFDGetCapabilites Purpose : This function get's capabilities
271
 
 * in the reader. Other functions int this file will call the driver
272
 
 * directly to not cause a deadlock. 
273
 
 */
274
 
 
275
 
LONG IFDGetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
276
 
        PDWORD pdwLength, PUCHAR pucValue)
277
 
{
278
 
        LONG rv = 0;
279
 
 
280
 
#ifndef PCSCLITE_STATIC_DRIVER
281
 
        RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
282
 
        RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, PUCHAR) = NULL;
283
 
 
284
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
285
 
                IFD_get_capabilities =
286
 
                        rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
287
 
        else
288
 
                IFDH_get_capabilities =
289
 
                        rContext->psFunctions.psFunctions_v2.pvfGetCapabilities;
290
 
#endif
291
 
 
292
 
        /*
293
 
         * LOCK THIS CODE REGION 
294
 
         */
295
 
 
296
 
        SYS_MutexLock(rContext->mMutex);
297
 
 
298
 
#ifndef PCSCLITE_STATIC_DRIVER
299
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
300
 
                rv = (*IFD_get_capabilities) (dwTag, pucValue);
301
 
        else
302
 
                rv = (*IFDH_get_capabilities) (rContext->dwSlot, dwTag,
303
 
                        pdwLength, pucValue);
304
 
#else
305
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
306
 
                rv = IFD_Get_Capabilities(dwTag, pucValue);
307
 
        else
308
 
                rv = IFDHGetCapabilities(rContext->dwSlot, dwTag, pdwLength,
309
 
                        pucValue);
310
 
#endif
311
 
 
312
 
        SYS_MutexUnLock(rContext->mMutex);
313
 
 
314
 
        /*
315
 
         * END OF LOCKED REGION 
316
 
         */
317
 
 
318
 
        return rv;
319
 
}
320
 
 
321
 
/*
322
 
 * Function: IFDPowerICC Purpose : This function powers up/down or reset's 
323
 
 * an ICC located in the IFD. 
324
 
 */
325
 
 
326
 
LONG IFDPowerICC(PREADER_CONTEXT rContext, DWORD dwAction,
327
 
        PUCHAR pucAtr, PDWORD pdwAtrLen)
328
 
{
329
 
        RESPONSECODE rv, ret;
330
 
        SMARTCARD_EXTENSION sSmartCard;
331
 
        DWORD dwStatus;
332
 
        UCHAR ucValue[1];
333
 
 
334
 
#ifndef PCSCLITE_STATIC_DRIVER
335
 
        RESPONSECODE(*IFD_power_icc) (DWORD) = NULL;
336
 
        RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL;
337
 
#endif
338
 
 
339
 
        /*
340
 
         * Zero out everything 
341
 
         */
342
 
        rv = 0;
343
 
        dwStatus = 0;
344
 
        ucValue[0] = 0;
345
 
 
346
 
        /*
347
 
         * Check that the card is inserted first 
348
 
         */
349
 
        IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
350
 
 
351
 
        if (dwStatus & SCARD_ABSENT)
352
 
                return SCARD_W_REMOVED_CARD;
353
 
#ifndef PCSCLITE_STATIC_DRIVER
354
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
355
 
                IFD_power_icc = rContext->psFunctions.psFunctions_v1.pvfPowerICC;
356
 
        else
357
 
                IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC;
358
 
#endif
359
 
 
360
 
        /*
361
 
         * LOCK THIS CODE REGION 
362
 
         */
363
 
 
364
 
        SYS_MutexLock(rContext->mMutex);
365
 
 
366
 
#ifndef PCSCLITE_STATIC_DRIVER
367
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
368
 
        {
369
 
                ucValue[0] = rContext->dwSlot;
370
 
                IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
371
 
                rv = (*IFD_power_icc) (dwAction);
372
 
        }
373
 
        else
374
 
        {
375
 
                rv = (*IFDH_power_icc) (rContext->dwSlot, dwAction,
376
 
                        pucAtr, pdwAtrLen);
377
 
 
378
 
                ret = ATRDecodeAtr(&sSmartCard, pucAtr, *pdwAtrLen);
379
 
        }
380
 
#else
381
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
382
 
        {
383
 
                ucValue[0] = rContext->dwSlot;
384
 
                IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
385
 
                rv = IFD_Power_ICC(dwAction);
386
 
        }
387
 
        else
388
 
                rv = IFDHPowerICC(rContext->dwSlot, dwAction, pucAtr, pdwAtrLen);
389
 
#endif
390
 
        SYS_MutexUnLock(rContext->mMutex);
391
 
 
392
 
        /*
393
 
         * END OF LOCKED REGION 
394
 
         */
395
 
 
396
 
        /* use clean values in case of error */
397
 
        if (rv != IFD_SUCCESS)
398
 
        {
399
 
                *pdwAtrLen = 0;
400
 
                pucAtr[0] = '\0';
401
 
        }
402
 
 
403
 
        /*
404
 
         * Get the ATR and it's length 
405
 
         */
406
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
407
 
                IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
408
 
 
409
 
        return rv;
410
 
}
411
 
 
412
 
/*
413
 
 * Function: IFDStatusICC Purpose : This function provides statistical
414
 
 * information about the IFD and ICC including insertions, atr, powering
415
 
 * status/etc. 
416
 
 */
417
 
 
418
 
LONG IFDStatusICC(PREADER_CONTEXT rContext, PDWORD pdwStatus,
419
 
        PUCHAR pucAtr, PDWORD pdwAtrLen)
420
 
{
421
 
        RESPONSECODE rv = 0;
422
 
        DWORD dwTag = 0, dwCardStatus = 0;
423
 
        SMARTCARD_EXTENSION sSmartCard;
424
 
        UCHAR ucValue[1] = "\x00";
425
 
 
426
 
#ifndef PCSCLITE_STATIC_DRIVER
427
 
        RESPONSECODE(*IFD_is_icc_present) () = NULL;
428
 
        RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;
429
 
        RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
430
 
 
431
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
432
 
        {
433
 
                IFD_is_icc_present =
434
 
                        rContext->psFunctions.psFunctions_v1.pvfICCPresence;
435
 
                IFD_get_capabilities =
436
 
                        rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
437
 
        }
438
 
        else
439
 
                IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
440
 
#endif
441
 
 
442
 
        /*
443
 
         * LOCK THIS CODE REGION 
444
 
         */
445
 
 
446
 
        SYS_MutexLock(rContext->mMutex);
447
 
 
448
 
#ifndef PCSCLITE_STATIC_DRIVER
449
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
450
 
        {
451
 
                ucValue[0] = rContext->dwSlot;
452
 
                IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
453
 
                rv = (*IFD_is_icc_present) ();
454
 
        }
455
 
        else
456
 
                rv = (*IFDH_icc_presence) (rContext->dwSlot);
457
 
#else
458
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
459
 
        {
460
 
                ucValue[0] = rContext->dwSlot;
461
 
                IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
462
 
                rv = IFD_Is_ICC_Present();
463
 
        }
464
 
        else
465
 
                rv = IFDHICCPresence(rContext->dwSlot);
466
 
#endif
467
 
        SYS_MutexUnLock(rContext->mMutex);
468
 
 
469
 
        /*
470
 
         * END OF LOCKED REGION 
471
 
         */
472
 
 
473
 
        if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
474
 
                dwCardStatus |= SCARD_PRESENT;
475
 
        else
476
 
                if (rv == IFD_ICC_NOT_PRESENT)
477
 
                        dwCardStatus |= SCARD_ABSENT;
478
 
                else
479
 
                {
480
 
                        Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
481
 
                        return SCARD_E_NOT_TRANSACTED;
482
 
                }
483
 
 
484
 
        /*
485
 
         * Now lets get the ATR and process it if IFD Handler version 1.0.
486
 
         * IFD Handler version 2.0 does this immediately after reset/power up
487
 
         * to conserve resources 
488
 
         */
489
 
 
490
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
491
 
        {
492
 
                if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
493
 
                {
494
 
                        dwTag = TAG_IFD_ATR;
495
 
 
496
 
                        /*
497
 
                         * LOCK THIS CODE REGION 
498
 
                         */
499
 
 
500
 
                        SYS_MutexLock(rContext->mMutex);
501
 
 
502
 
                        ucValue[0] = rContext->dwSlot;
503
 
                        IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
504
 
 
505
 
#ifndef PCSCLITE_STATIC_DRIVER
506
 
                        rv = (*IFD_get_capabilities) (dwTag, pucAtr);
507
 
#else
508
 
                        rv = IFD_Get_Capabilities(dwTag, pucAtr);
509
 
#endif
510
 
                        SYS_MutexUnLock(rContext->mMutex);
511
 
 
512
 
                        /*
513
 
                         * END OF LOCKED REGION 
514
 
                         */
515
 
 
516
 
                        /*
517
 
                         * FIX :: This is a temporary way to return the correct size
518
 
                         * of the ATR since most of the drivers return MAX_ATR_SIZE 
519
 
                         */
520
 
 
521
 
                        rv = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);
522
 
 
523
 
                        /*
524
 
                         * Might be a memory card without an ATR 
525
 
                         */
526
 
                        if (rv == 0)
527
 
                                *pdwAtrLen = 0;
528
 
                        else
529
 
                                *pdwAtrLen = sSmartCard.ATR.Length;
530
 
                }
531
 
                else
532
 
                {
533
 
                        /*
534
 
                         * No card is inserted - Atr length is 0 
535
 
                         */
536
 
                        *pdwAtrLen = 0;
537
 
                }
538
 
                /*
539
 
                 * End of FIX 
540
 
                 */
541
 
        }
542
 
 
543
 
        *pdwStatus = dwCardStatus;
544
 
 
545
 
        return SCARD_S_SUCCESS;
546
 
}
547
 
 
548
 
/*
549
 
 * Function: IFDControl Purpose : This function provides a means for
550
 
 * toggling a specific action on the reader such as swallow, eject,
551
 
 * biometric. 
552
 
 */
553
 
 
554
 
/*
555
 
 * Valid only for IFDHandler version 2.0
556
 
 */
557
 
 
558
 
LONG IFDControl_v2(PREADER_CONTEXT rContext, PUCHAR TxBuffer,
559
 
        DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
560
 
{
561
 
        RESPONSECODE rv = 0;
562
 
 
563
 
#ifndef PCSCLITE_STATIC_DRIVER
564
 
        RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, PUCHAR, PDWORD);
565
 
#endif
566
 
 
567
 
        if (rContext->dwVersion != IFD_HVERSION_2_0)
568
 
                return SCARD_E_UNSUPPORTED_FEATURE;
569
 
 
570
 
#ifndef PCSCLITE_STATIC_DRIVER
571
 
        IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
572
 
#endif
573
 
 
574
 
        /*
575
 
         * LOCK THIS CODE REGION 
576
 
         */
577
 
        SYS_MutexLock(rContext->mMutex);
578
 
 
579
 
#ifndef PCSCLITE_STATIC_DRIVER
580
 
        rv = (*IFDH_control_v2) (rContext->dwSlot, TxBuffer, TxLength,
581
 
                RxBuffer, RxLength);
582
 
#else
583
 
        rv = IFDHControl_v2(rContext->dwSlot, TxBuffer, TxLength,
584
 
                RxBuffer, RxLength);
585
 
#endif
586
 
        SYS_MutexUnLock(rContext->mMutex);
587
 
        /*
588
 
         * END OF LOCKED REGION 
589
 
         */
590
 
 
591
 
        if (rv == IFD_SUCCESS)
592
 
                return SCARD_S_SUCCESS;
593
 
        else
594
 
        {
595
 
                Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
596
 
                return SCARD_E_NOT_TRANSACTED;
597
 
        }
598
 
}
599
 
 
600
 
/*
601
 
 * Function: IFDControl Purpose : This function provides a means for
602
 
 * toggling a specific action on the reader such as swallow, eject,
603
 
 * biometric. 
604
 
 */
605
 
 
606
 
/*
607
 
 * Valid only for IFDHandler version 3.0 and up
608
 
 */
609
 
 
610
 
LONG IFDControl(PREADER_CONTEXT rContext, DWORD ControlCode,
611
 
        LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
612
 
        LPDWORD BytesReturned)
613
 
{
614
 
        RESPONSECODE rv = 0;
615
 
 
616
 
#ifndef PCSCLITE_STATIC_DRIVER
617
 
        RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
618
 
#endif
619
 
 
620
 
        if (rContext->dwVersion < IFD_HVERSION_3_0)
621
 
                return SCARD_E_UNSUPPORTED_FEATURE;
622
 
 
623
 
#ifndef PCSCLITE_STATIC_DRIVER
624
 
        IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
625
 
#endif
626
 
 
627
 
        /*
628
 
         * LOCK THIS CODE REGION 
629
 
         */
630
 
 
631
 
        SYS_MutexLock(rContext->mMutex);
632
 
 
633
 
#ifndef PCSCLITE_STATIC_DRIVER
634
 
        rv = (*IFDH_control) (rContext->dwSlot, ControlCode, TxBuffer,
635
 
                TxLength, RxBuffer, RxLength, BytesReturned);
636
 
#else
637
 
        rv = IFDHControl(rContext->dwSlot, ControlCode, TxBuffer,
638
 
                TxLength, RxBuffer, RxLength, BytesReturned);
639
 
#endif
640
 
        SYS_MutexUnLock(rContext->mMutex);
641
 
 
642
 
        /*
643
 
         * END OF LOCKED REGION 
644
 
         */
645
 
 
646
 
        if (rv == IFD_SUCCESS)
647
 
                return SCARD_S_SUCCESS;
648
 
        else
649
 
        {
650
 
                Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
651
 
                return SCARD_E_NOT_TRANSACTED;
652
 
        }
653
 
}
654
 
 
655
 
/*
656
 
 * Function: IFDTransmit Purpose : This function transmits an APDU to the
657
 
 * ICC. 
658
 
 */
659
 
 
660
 
LONG IFDTransmit(PREADER_CONTEXT rContext, SCARD_IO_HEADER pioTxPci,
661
 
        PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
662
 
        PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
663
 
{
664
 
        RESPONSECODE rv = 0;
665
 
        UCHAR ucValue[1] = "\x00";
666
 
 
667
 
#ifndef PCSCLITE_STATIC_DRIVER
668
 
        RESPONSECODE(*IFD_transmit_to_icc) (SCARD_IO_HEADER, PUCHAR, DWORD,
669
 
                PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
670
 
        RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
671
 
                DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
672
 
#endif
673
 
 
674
 
        /* log the APDU */
675
 
        DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);
676
 
 
677
 
#ifndef PCSCLITE_STATIC_DRIVER
678
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
679
 
                IFD_transmit_to_icc =
680
 
                        rContext->psFunctions.psFunctions_v1.pvfTransmitToICC;
681
 
        else
682
 
                IFDH_transmit_to_icc =
683
 
                        rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
684
 
#endif
685
 
 
686
 
        /*
687
 
         * LOCK THIS CODE REGION 
688
 
         */
689
 
 
690
 
        SYS_MutexLock(rContext->mMutex);
691
 
 
692
 
 
693
 
#ifndef PCSCLITE_STATIC_DRIVER
694
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
695
 
        {
696
 
                ucValue[0] = rContext->dwSlot;
697
 
                IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
698
 
                rv = (*IFD_transmit_to_icc) (pioTxPci, (LPBYTE) pucTxBuffer,
699
 
                        dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
700
 
        }
701
 
        else
702
 
                rv = (*IFDH_transmit_to_icc) (rContext->dwSlot, pioTxPci,
703
 
                        (LPBYTE) pucTxBuffer, dwTxLength,
704
 
                        pucRxBuffer, pdwRxLength, pioRxPci);
705
 
#else
706
 
        if (rContext->dwVersion == IFD_HVERSION_1_0)
707
 
        {
708
 
                ucValue[0] = rContext->dwSlot;
709
 
                IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
710
 
                rv = IFD_Transmit_to_ICC(pioTxPci, (LPBYTE) pucTxBuffer,
711
 
                        dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
712
 
        }
713
 
        else
714
 
                rv = IFDHTransmitToICC(rContext->dwSlot, pioTxPci,
715
 
                        (LPBYTE) pucTxBuffer, dwTxLength,
716
 
                        pucRxBuffer, pdwRxLength, pioRxPci);
717
 
#endif
718
 
        SYS_MutexUnLock(rContext->mMutex);
719
 
 
720
 
        /*
721
 
         * END OF LOCKED REGION 
722
 
         */
723
 
 
724
 
        /* log the returned status word */
725
 
        DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);
726
 
 
727
 
        if (rv == IFD_SUCCESS)
728
 
                return SCARD_S_SUCCESS;
729
 
        else
730
 
        {
731
 
                Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
732
 
                return SCARD_E_NOT_TRANSACTED;
733
 
        }
734
 
}
735