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

« back to all changes in this revision

Viewing changes to src/readerfactory.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
 * MUSCLE SmartCard Development ( http://www.linuxnet.com )
 
3
 *
 
4
 * Copyright (C) 1999-2004
 
5
 *  David Corcoran <corcoran@linuxnet.com>
 
6
 *  Damien Sauveron <damien.sauveron@labri.fr>
 
7
 *  Ludovic Rousseau <ludovic.rousseau@free.fr>
 
8
 *
 
9
 * $Id: readerfactory.c 1722 2005-11-21 13:05:20Z rousseau $
 
10
 */
 
11
 
 
12
/**
 
13
 * @file
 
14
 * @brief This keeps track of a list of currently available reader structures.
 
15
 */
 
16
 
 
17
#include "config.h"
 
18
#include <stdio.h>
 
19
#include <stdlib.h>
 
20
#include <string.h>
 
21
#include <unistd.h>
 
22
#include <sys/types.h>
 
23
#include <sys/stat.h>
 
24
#include <errno.h>
 
25
#include <fcntl.h>
 
26
 
 
27
#include "pcsclite.h"
 
28
#include "ifdhandler.h"
 
29
#include "debuglog.h"
 
30
#include "thread_generic.h"
 
31
#include "readerfactory.h"
 
32
#include "dyn_generic.h"
 
33
#include "sys_generic.h"
 
34
#include "eventhandler.h"
 
35
#include "ifdwrapper.h"
 
36
#include "hotplug.h"
 
37
#include "strlcpycat.h"
 
38
#include "configfile.h"
 
39
 
 
40
#ifndef TRUE
 
41
#define TRUE 1
 
42
#define FALSE 0
 
43
#endif
 
44
 
 
45
static PREADER_CONTEXT sReadersContexts[PCSCLITE_MAX_READERS_CONTEXTS];
 
46
static DWORD dwNumReadersContexts = 0;
 
47
static char *ConfigFile = NULL;
 
48
static int ConfigFileCRC = 0;
 
49
 
 
50
LONG RFAllocateReaderSpace(void)
 
51
{
 
52
        int i;                                          /* Counter */
 
53
 
 
54
        /*
 
55
         * Allocate each reader structure 
 
56
         */
 
57
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
58
        {
 
59
                sReadersContexts[i] = (PREADER_CONTEXT) malloc(sizeof(READER_CONTEXT));
 
60
                (sReadersContexts[i])->vHandle = NULL;
 
61
                (sReadersContexts[i])->readerState = NULL;
 
62
        }
 
63
 
 
64
        /*
 
65
         * Create public event structures 
 
66
         */
 
67
        return EHInitializeEventStructures();
 
68
}
 
69
 
 
70
LONG RFAddReader(LPTSTR lpcReader, DWORD dwPort, LPTSTR lpcLibrary, LPTSTR lpcDevice)
 
71
{
 
72
        DWORD dwContext = 0, dwGetSize;
 
73
        UCHAR ucGetData[1], ucThread[1];
 
74
        LONG rv, parentNode;
 
75
        int i, j;
 
76
 
 
77
        if ((lpcReader == NULL) || (lpcLibrary == NULL) || (lpcDevice == NULL))
 
78
                return SCARD_E_INVALID_VALUE;
 
79
 
 
80
        /* Reader name too long? */
 
81
        if (strlen(lpcReader) >= MAX_READERNAME)
 
82
        {
 
83
                Log3(PCSC_LOG_ERROR, "Reader name too long: %d chars instead of max %d",
 
84
                        strlen(lpcReader), MAX_READERNAME);
 
85
                return SCARD_E_INVALID_VALUE;
 
86
        }
 
87
 
 
88
        /* Library name too long? */
 
89
        if (strlen(lpcLibrary) >= MAX_LIBNAME)
 
90
        {
 
91
                Log3(PCSC_LOG_ERROR, "Library name too long: %d chars instead of max %d",
 
92
                        strlen(lpcLibrary), MAX_LIBNAME);
 
93
                return SCARD_E_INVALID_VALUE;
 
94
        }
 
95
 
 
96
        /* Device name too long? */
 
97
        if (strlen(lpcDevice) >= MAX_DEVICENAME)
 
98
        {
 
99
                Log3(PCSC_LOG_ERROR, "Device name too long: %d chars instead of max %d",
 
100
                        strlen(lpcDevice), MAX_DEVICENAME);
 
101
                return SCARD_E_INVALID_VALUE;
 
102
        }
 
103
 
 
104
        /*
 
105
         * Same name, same port - duplicate reader cannot be used 
 
106
         */
 
107
        if (dwNumReadersContexts != 0)
 
108
        {
 
109
                for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
110
                {
 
111
                        if ((sReadersContexts[i])->vHandle != 0)
 
112
                        {
 
113
                                char lpcStripReader[MAX_READERNAME];
 
114
                                int tmplen;
 
115
 
 
116
                                /* get the reader name without the reader and slot numbers */
 
117
                                strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
 
118
                                        sizeof(lpcStripReader));
 
119
                                tmplen = strlen(lpcStripReader);
 
120
                                lpcStripReader[tmplen - 6] = 0;
 
121
 
 
122
                                if ((strcmp(lpcReader, lpcStripReader) == 0) &&
 
123
                                        (dwPort == (sReadersContexts[i])->dwPort))
 
124
                                {
 
125
                                        Log1(PCSC_LOG_ERROR, "Duplicate reader found.");
 
126
                                        return SCARD_E_DUPLICATE_READER;
 
127
                                }
 
128
                        }
 
129
                }
 
130
        }
 
131
 
 
132
        /*
 
133
         * We must find an empty slot to put the reader structure 
 
134
         */
 
135
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
136
        {
 
137
                if ((sReadersContexts[i])->vHandle == 0)
 
138
                {
 
139
                        dwContext = i;
 
140
                        break;
 
141
                }
 
142
        }
 
143
 
 
144
        if (i == PCSCLITE_MAX_READERS_CONTEXTS)
 
145
        {
 
146
                /*
 
147
                 * No more spots left return 
 
148
                 */
 
149
                return SCARD_E_NO_MEMORY;
 
150
        }
 
151
 
 
152
        /*
 
153
         * Check and set the readername to see if it must be enumerated 
 
154
         */
 
155
        parentNode = RFSetReaderName(sReadersContexts[dwContext], lpcReader,
 
156
                lpcLibrary, dwPort, 0);
 
157
 
 
158
        strlcpy((sReadersContexts[dwContext])->lpcLibrary, lpcLibrary,
 
159
                sizeof((sReadersContexts[dwContext])->lpcLibrary));
 
160
        strlcpy((sReadersContexts[dwContext])->lpcDevice, lpcDevice,
 
161
                sizeof((sReadersContexts[dwContext])->lpcDevice));
 
162
        (sReadersContexts[dwContext])->dwVersion = 0;
 
163
        (sReadersContexts[dwContext])->dwPort = dwPort;
 
164
        (sReadersContexts[dwContext])->mMutex = 0;
 
165
        (sReadersContexts[dwContext])->dwBlockStatus = 0;
 
166
        (sReadersContexts[dwContext])->dwContexts = 0;
 
167
        (sReadersContexts[dwContext])->pthThread = 0;
 
168
        (sReadersContexts[dwContext])->dwLockId = 0;
 
169
        (sReadersContexts[dwContext])->vHandle = 0;
 
170
        (sReadersContexts[dwContext])->pdwFeeds = NULL;
 
171
        (sReadersContexts[dwContext])->pdwMutex = NULL;
 
172
        (sReadersContexts[dwContext])->dwIdentity =
 
173
                (dwContext + 1) << (sizeof(DWORD) / 2) * 8;
 
174
        (sReadersContexts[dwContext])->readerState = NULL;
 
175
 
 
176
        for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
 
177
                (sReadersContexts[dwContext])->psHandles[i].hCard = 0;
 
178
 
 
179
        /*
 
180
         * If a clone to this reader exists take some values from that clone 
 
181
         */
 
182
        if (parentNode >= 0 && parentNode < PCSCLITE_MAX_READERS_CONTEXTS)
 
183
        {
 
184
                (sReadersContexts[dwContext])->pdwFeeds = 
 
185
                  (sReadersContexts[parentNode])->pdwFeeds;
 
186
                *(sReadersContexts[dwContext])->pdwFeeds += 1;
 
187
                (sReadersContexts[dwContext])->vHandle = 
 
188
                  (sReadersContexts[parentNode])->vHandle;
 
189
                (sReadersContexts[dwContext])->mMutex = 
 
190
                  (sReadersContexts[parentNode])->mMutex;
 
191
                (sReadersContexts[dwContext])->pdwMutex = 
 
192
                  (sReadersContexts[parentNode])->pdwMutex;
 
193
 
 
194
                /*
 
195
                 * Call on the driver to see if it is thread safe 
 
196
                 */
 
197
                dwGetSize = sizeof(ucThread);
 
198
                rv = IFDGetCapabilities((sReadersContexts[parentNode]),
 
199
                       TAG_IFD_THREAD_SAFE, &dwGetSize, ucThread);
 
200
 
 
201
                if (rv == IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
 
202
                {
 
203
                        Log1(PCSC_LOG_INFO, "Driver is thread safe");
 
204
                        (sReadersContexts[dwContext])->mMutex = 0;
 
205
                        (sReadersContexts[dwContext])->pdwMutex = NULL;
 
206
                }
 
207
                else
 
208
                        *(sReadersContexts[dwContext])->pdwMutex += 1;
 
209
        }
 
210
 
 
211
        if ((sReadersContexts[dwContext])->pdwFeeds == NULL)
 
212
        {
 
213
                (sReadersContexts[dwContext])->pdwFeeds = 
 
214
                  (DWORD *)malloc(sizeof(DWORD));
 
215
 
 
216
                /* Initialize pdwFeeds to 1, otherwise multiple 
 
217
                   cloned readers will cause pcscd to crash when 
 
218
                   RFUnloadReader unloads the driver library
 
219
                   and there are still devices attached using it --mikeg*/
 
220
 
 
221
                *(sReadersContexts[dwContext])->pdwFeeds = 1;
 
222
        }
 
223
 
 
224
        if ((sReadersContexts[dwContext])->mMutex == 0)
 
225
        {
 
226
                (sReadersContexts[dwContext])->mMutex =
 
227
                  (PCSCLITE_MUTEX_T) malloc(sizeof(PCSCLITE_MUTEX));
 
228
                SYS_MutexInit((sReadersContexts[dwContext])->mMutex);
 
229
        }
 
230
 
 
231
        if ((sReadersContexts[dwContext])->pdwMutex == NULL)
 
232
        {
 
233
                (sReadersContexts[dwContext])->pdwMutex = 
 
234
                  (DWORD *)malloc(sizeof(DWORD));
 
235
 
 
236
                *(sReadersContexts[dwContext])->pdwMutex = 1;
 
237
        }
 
238
 
 
239
        dwNumReadersContexts += 1;
 
240
 
 
241
        rv = RFInitializeReader(sReadersContexts[dwContext]);
 
242
        if (rv != SCARD_S_SUCCESS)
 
243
        {
 
244
                /*
 
245
                 * Cannot connect to reader exit gracefully 
 
246
                 */
 
247
                /*
 
248
                 * Clean up so it is not using needed space 
 
249
                 */
 
250
                Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader);
 
251
 
 
252
                (sReadersContexts[dwContext])->dwVersion = 0;
 
253
                (sReadersContexts[dwContext])->dwPort = 0;
 
254
                (sReadersContexts[dwContext])->vHandle = 0;
 
255
                (sReadersContexts[dwContext])->readerState = NULL;
 
256
                (sReadersContexts[dwContext])->dwIdentity = 0;
 
257
 
 
258
                /*
 
259
                 * Destroy and free the mutex 
 
260
                 */
 
261
                if (*(sReadersContexts[dwContext])->pdwMutex == 1)
 
262
                {
 
263
                        SYS_MutexDestroy((sReadersContexts[dwContext])->mMutex);
 
264
                        free((sReadersContexts[dwContext])->mMutex);
 
265
                }
 
266
 
 
267
                *(sReadersContexts[dwContext])->pdwMutex -= 1;
 
268
 
 
269
                if (*(sReadersContexts[dwContext])->pdwMutex == 0)
 
270
                {
 
271
                        free((sReadersContexts[dwContext])->pdwMutex);
 
272
                        (sReadersContexts[dwContext])->pdwMutex = NULL;
 
273
                }
 
274
 
 
275
                *(sReadersContexts[dwContext])->pdwFeeds -= 1;
 
276
 
 
277
                if (*(sReadersContexts[dwContext])->pdwFeeds == 0)
 
278
                {
 
279
                        free((sReadersContexts[dwContext])->pdwFeeds);
 
280
                        (sReadersContexts[dwContext])->pdwFeeds = NULL;
 
281
                }
 
282
 
 
283
                dwNumReadersContexts -= 1;
 
284
 
 
285
                return rv;
 
286
        }
 
287
 
 
288
        rv = EHSpawnEventHandler(sReadersContexts[dwContext]);
 
289
        if (rv != SCARD_S_SUCCESS)
 
290
                return rv;
 
291
 
 
292
        /*
 
293
         * Call on the driver to see if there are multiple slots 
 
294
         */
 
295
 
 
296
        dwGetSize = sizeof(ucGetData);
 
297
        rv = IFDGetCapabilities((sReadersContexts[dwContext]),
 
298
                TAG_IFD_SLOTS_NUMBER, &dwGetSize, ucGetData);
 
299
 
 
300
        if (rv != IFD_SUCCESS || dwGetSize != 1 || ucGetData[0] == 0)
 
301
                /*
 
302
                 * Reader does not have this defined.  Must be a single slot
 
303
                 * reader so we can just return SCARD_S_SUCCESS. 
 
304
                 */
 
305
                return SCARD_S_SUCCESS;
 
306
 
 
307
        if (rv == IFD_SUCCESS && dwGetSize == 1 && ucGetData[0] == 1)
 
308
                /*
 
309
                 * Reader has this defined and it only has one slot 
 
310
                 */
 
311
                return SCARD_S_SUCCESS;
 
312
 
 
313
        /*
 
314
         * Check the number of slots and create a different 
 
315
         * structure for each one accordingly 
 
316
         */
 
317
 
 
318
        /*
 
319
         * Initialize the rest of the slots 
 
320
         */
 
321
 
 
322
        for (j = 1; j < ucGetData[0]; j++)
 
323
        {
 
324
                char *tmpReader = NULL;
 
325
                DWORD dwContextB = 0;
 
326
 
 
327
                /*
 
328
                 * We must find an empty spot to put the 
 
329
                 * reader structure 
 
330
                 */
 
331
                for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
332
                {
 
333
                        if ((sReadersContexts[i])->vHandle == 0)
 
334
                        {
 
335
                                dwContextB = i;
 
336
                                break;
 
337
                        }
 
338
                }
 
339
 
 
340
                if (i == PCSCLITE_MAX_READERS_CONTEXTS)
 
341
                {
 
342
                        /*
 
343
                         * No more spots left return 
 
344
                         */
 
345
                        rv = RFRemoveReader(lpcReader, dwPort);
 
346
                        return SCARD_E_NO_MEMORY;
 
347
                }
 
348
 
 
349
                /*
 
350
                 * Copy the previous reader name and increment the slot number
 
351
                 */
 
352
                tmpReader = sReadersContexts[dwContextB]->lpcReader;
 
353
                strlcpy(tmpReader, sReadersContexts[dwContext]->lpcReader,
 
354
                        sizeof(sReadersContexts[dwContextB]->lpcReader));
 
355
                sprintf(tmpReader + strlen(tmpReader) - 2, "%02X", j);
 
356
 
 
357
                strlcpy((sReadersContexts[dwContextB])->lpcLibrary, lpcLibrary,
 
358
                        sizeof((sReadersContexts[dwContextB])->lpcLibrary));
 
359
                strlcpy((sReadersContexts[dwContextB])->lpcDevice, lpcDevice,
 
360
                        sizeof((sReadersContexts[dwContextB])->lpcDevice));
 
361
                (sReadersContexts[dwContextB])->dwVersion =
 
362
                  (sReadersContexts[dwContext])->dwVersion;
 
363
                (sReadersContexts[dwContextB])->dwPort =
 
364
                  (sReadersContexts[dwContext])->dwPort;
 
365
                (sReadersContexts[dwContextB])->vHandle =
 
366
                  (sReadersContexts[dwContext])->vHandle;
 
367
                (sReadersContexts[dwContextB])->mMutex =
 
368
                   (sReadersContexts[dwContext])->mMutex;
 
369
                (sReadersContexts[dwContextB])->pdwMutex =
 
370
                   (sReadersContexts[dwContext])->pdwMutex;
 
371
                sReadersContexts[dwContextB]->dwSlot =
 
372
                        sReadersContexts[dwContext]->dwSlot + j;
 
373
 
 
374
                /* 
 
375
                 * Added by Dave - slots did not have a pdwFeeds
 
376
                 * parameter so it was by luck they were working
 
377
                 */
 
378
 
 
379
                (sReadersContexts[dwContextB])->pdwFeeds =
 
380
                  (sReadersContexts[dwContext])->pdwFeeds;
 
381
 
 
382
                /* Added by Dave for multiple slots */
 
383
                *(sReadersContexts[dwContextB])->pdwFeeds += 1;
 
384
 
 
385
                (sReadersContexts[dwContextB])->dwBlockStatus = 0;
 
386
                (sReadersContexts[dwContextB])->dwContexts = 0;
 
387
                (sReadersContexts[dwContextB])->dwLockId = 0;
 
388
                (sReadersContexts[dwContextB])->readerState = NULL;
 
389
                (sReadersContexts[dwContextB])->dwIdentity =
 
390
                        (dwContextB + 1) << (sizeof(DWORD) / 2) * 8;
 
391
 
 
392
                for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
 
393
                        (sReadersContexts[dwContextB])->psHandles[i].hCard = 0;
 
394
 
 
395
                /*
 
396
                 * Call on the driver to see if the slots are thread safe 
 
397
                 */
 
398
 
 
399
                dwGetSize = sizeof(ucThread);
 
400
                rv = IFDGetCapabilities((sReadersContexts[dwContext]),
 
401
                        TAG_IFD_SLOT_THREAD_SAFE, &dwGetSize, ucThread);
 
402
 
 
403
                if (rv == IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
 
404
                {
 
405
                        (sReadersContexts[dwContextB])->mMutex =
 
406
                                (PCSCLITE_MUTEX_T) malloc(sizeof(PCSCLITE_MUTEX));
 
407
                        SYS_MutexInit((sReadersContexts[dwContextB])->mMutex);
 
408
 
 
409
                        (sReadersContexts[dwContextB])->pdwMutex = 
 
410
                                (DWORD *)malloc(sizeof(DWORD));
 
411
                        *(sReadersContexts[dwContextB])->pdwMutex = 1;
 
412
                }
 
413
                else
 
414
                        *(sReadersContexts[dwContextB])->pdwMutex += 1;
 
415
 
 
416
                dwNumReadersContexts += 1;
 
417
 
 
418
                rv = RFInitializeReader(sReadersContexts[dwContextB]);
 
419
                if (rv != SCARD_S_SUCCESS)
 
420
                {
 
421
                        /*
 
422
                         * Cannot connect to slot exit gracefully 
 
423
                         */
 
424
                        /*
 
425
                         * Clean up so it is not using needed space 
 
426
                         */
 
427
                        Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader);
 
428
 
 
429
                        (sReadersContexts[dwContextB])->dwVersion = 0;
 
430
                        (sReadersContexts[dwContextB])->dwPort = 0;
 
431
                        (sReadersContexts[dwContextB])->vHandle = 0;
 
432
                        (sReadersContexts[dwContextB])->readerState = NULL;
 
433
                        (sReadersContexts[dwContextB])->dwIdentity = 0;
 
434
 
 
435
                        /*
 
436
                         * Destroy and free the mutex 
 
437
                         */
 
438
                        if (*(sReadersContexts[dwContextB])->pdwMutex == 1)
 
439
                        {
 
440
                                SYS_MutexDestroy((sReadersContexts[dwContextB])->mMutex);
 
441
                                free((sReadersContexts[dwContextB])->mMutex);
 
442
                        }
 
443
 
 
444
                        *(sReadersContexts[dwContextB])->pdwMutex -= 1;
 
445
 
 
446
                        if (*(sReadersContexts[dwContextB])->pdwMutex == 0)
 
447
                        {
 
448
                                free((sReadersContexts[dwContextB])->pdwMutex);
 
449
                                (sReadersContexts[dwContextB])->pdwMutex = NULL;
 
450
                        }
 
451
 
 
452
                        *(sReadersContexts[dwContextB])->pdwFeeds -= 1;
 
453
 
 
454
                        if (*(sReadersContexts[dwContextB])->pdwFeeds == 0)
 
455
                        {
 
456
                                free((sReadersContexts[dwContextB])->pdwFeeds);
 
457
                                (sReadersContexts[dwContextB])->pdwFeeds = NULL;
 
458
                        }
 
459
 
 
460
                        dwNumReadersContexts -= 1;
 
461
 
 
462
                        return rv;
 
463
                }
 
464
 
 
465
                EHSpawnEventHandler(sReadersContexts[dwContextB]);
 
466
        }
 
467
 
 
468
        return SCARD_S_SUCCESS;
 
469
}
 
470
 
 
471
LONG RFRemoveReader(LPTSTR lpcReader, DWORD dwPort)
 
472
{
 
473
        LONG rv;
 
474
        PREADER_CONTEXT sContext;
 
475
 
 
476
        if (lpcReader == 0)
 
477
                return SCARD_E_INVALID_VALUE;
 
478
 
 
479
        while ((rv = RFReaderInfoNamePort(dwPort, lpcReader, &sContext))
 
480
                == SCARD_S_SUCCESS)
 
481
        {
 
482
                int i;
 
483
 
 
484
                /*
 
485
                 * Try to destroy the thread 
 
486
                 */
 
487
                rv = EHDestroyEventHandler(sContext);
 
488
 
 
489
                rv = RFUnInitializeReader(sContext);
 
490
                if (rv != SCARD_S_SUCCESS)
 
491
                        return rv;
 
492
 
 
493
                /*
 
494
                 * Destroy and free the mutex 
 
495
                 */
 
496
                if ((NULL == sContext->pdwMutex) || (NULL == sContext->pdwFeeds))
 
497
                {
 
498
                        Log1(PCSC_LOG_ERROR,
 
499
                                "Trying to remove an already removed driver");
 
500
                        return SCARD_E_INVALID_VALUE;
 
501
                }
 
502
 
 
503
                if (*sContext->pdwMutex == 1)
 
504
                {
 
505
                        SYS_MutexDestroy(sContext->mMutex);
 
506
                        free(sContext->mMutex);
 
507
                }
 
508
 
 
509
                *sContext->pdwMutex -= 1;
 
510
 
 
511
                if (*sContext->pdwMutex == 0)
 
512
                {
 
513
                        free(sContext->pdwMutex);
 
514
                        sContext->pdwMutex = NULL;
 
515
                }
 
516
 
 
517
                *sContext->pdwFeeds -= 1;
 
518
 
 
519
                /* Added by Dave to free the pdwFeeds variable */
 
520
 
 
521
                if (*sContext->pdwFeeds == 0)
 
522
                {
 
523
                        free(sContext->pdwFeeds);
 
524
                        sContext->pdwFeeds = NULL;
 
525
                }
 
526
 
 
527
                sContext->lpcDevice[0] = 0;
 
528
                sContext->dwVersion = 0;
 
529
                sContext->dwPort = 0;
 
530
                sContext->mMutex = 0;
 
531
                sContext->dwBlockStatus = 0;
 
532
                sContext->dwContexts = 0;
 
533
                sContext->dwSlot = 0;
 
534
                sContext->dwLockId = 0;
 
535
                sContext->vHandle = 0;
 
536
                sContext->dwIdentity = 0;
 
537
                sContext->readerState = NULL;
 
538
 
 
539
                for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
 
540
                        sContext->psHandles[i].hCard = 0;
 
541
 
 
542
                dwNumReadersContexts -= 1;
 
543
        }
 
544
 
 
545
        return SCARD_S_SUCCESS;
 
546
}
 
547
 
 
548
LONG RFSetReaderName(PREADER_CONTEXT rContext, LPTSTR readerName,
 
549
        LPTSTR libraryName, DWORD dwPort, DWORD dwSlot)
 
550
{
 
551
        LONG parent = -1;       /* reader number of the parent of the clone */
 
552
        DWORD valueLength;
 
553
        int currentDigit = -1;
 
554
        int supportedChannels = 0;
 
555
        int usedDigits[PCSCLITE_MAX_READERS_CONTEXTS];
 
556
        int i;
 
557
 
 
558
        /*
 
559
         * Clear the list 
 
560
         */
 
561
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
562
                usedDigits[i] = FALSE;
 
563
 
 
564
        if ((0 == dwSlot) && (dwNumReadersContexts != 0))
 
565
        {
 
566
                for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
567
                {
 
568
                        if ((sReadersContexts[i])->vHandle != 0)
 
569
                        {
 
570
                                if (strcmp((sReadersContexts[i])->lpcLibrary, libraryName) == 0)
 
571
                                {
 
572
                                        UCHAR tagValue[1];
 
573
                                        LONG ret;
 
574
 
 
575
                                        /*
 
576
                                         * Ask the driver if it supports multiple channels 
 
577
                                         */
 
578
                                        valueLength = sizeof(tagValue);
 
579
                                        ret = IFDGetCapabilities((sReadersContexts[i]),
 
580
                                                TAG_IFD_SIMULTANEOUS_ACCESS,
 
581
                                                &valueLength, tagValue);
 
582
 
 
583
                                        if ((ret == IFD_SUCCESS) && (valueLength == 1) &&
 
584
                                                (tagValue[0] > 1))
 
585
                                        {
 
586
                                                supportedChannels = tagValue[0];
 
587
                                                Log2(PCSC_LOG_INFO,
 
588
                                                        "Support %d simultaneous readers", tagValue[0]);
 
589
                                        }
 
590
                                        else
 
591
                                                supportedChannels = -1;
 
592
 
 
593
                                        /*
 
594
                                         * Check to see if it is a hotplug reader and
 
595
                                         * different 
 
596
                                         */
 
597
                                        if (((((sReadersContexts[i])->dwPort & 0xFFFF0000) ==
 
598
                                                        PCSCLITE_HP_BASE_PORT)
 
599
                                                && ((sReadersContexts[i])->dwPort != dwPort))
 
600
                                                || (supportedChannels > 1))
 
601
                                        {
 
602
                                                char *lpcReader = sReadersContexts[i]->lpcReader;
 
603
 
 
604
                                                /*
 
605
                                                 * tells the caller who the parent of this
 
606
                                                 * clone is so it can use it's shared
 
607
                                                 * resources like mutex/etc. 
 
608
                                                 */
 
609
                                                parent = i;
 
610
 
 
611
                                                /*
 
612
                                                 * If the same reader already exists and it is 
 
613
                                                 * hotplug then we must look for others and
 
614
                                                 * enumerate the readername 
 
615
                                                 */
 
616
                                                currentDigit = strtol(lpcReader + strlen(lpcReader) - 5, NULL, 16);
 
617
 
 
618
                                                /*
 
619
                                                 * This spot is taken 
 
620
                                                 */
 
621
                                                usedDigits[currentDigit] = TRUE;
 
622
                                        }
 
623
                                }
 
624
                        }
 
625
                }
 
626
 
 
627
        }
 
628
 
 
629
        /* default value */
 
630
        i = 0;
 
631
 
 
632
        /* Other identical readers exist on the same bus */
 
633
        if (currentDigit != -1)
 
634
        {
 
635
                for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
636
                {
 
637
                        /* get the first free digit */
 
638
                        if (usedDigits[i] == FALSE)
 
639
                                break;
 
640
                }
 
641
 
 
642
                if ((i == PCSCLITE_MAX_READERS_CONTEXTS) || (i > supportedChannels))
 
643
                        return -1;
 
644
        }
 
645
 
 
646
        sprintf(rContext->lpcReader, "%s %02X %02lX", readerName, i, dwSlot);
 
647
 
 
648
        /*
 
649
         * Set the slot in 0xDDDDCCCC 
 
650
         */
 
651
        rContext->dwSlot = (i << 16) + dwSlot;
 
652
 
 
653
        return parent;
 
654
}
 
655
 
 
656
#if 0
 
657
LONG RFListReaders(LPTSTR lpcReaders, LPDWORD pdwReaderNum)
 
658
{
 
659
        DWORD dwCSize;
 
660
        LPTSTR lpcTReaders;
 
661
        int i, p;
 
662
 
 
663
        if (dwNumReadersContexts == 0)
 
664
                return SCARD_E_READER_UNAVAILABLE;
 
665
 
 
666
        /*
 
667
         * Ignore the groups for now, return all readers 
 
668
         */
 
669
        dwCSize = 0;
 
670
        p = 0;
 
671
 
 
672
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
673
        {
 
674
                if ((sReadersContexts[i])->vHandle != 0)
 
675
                {
 
676
                        dwCSize += strlen((sReadersContexts[i])->lpcReader) + 1;
 
677
                        p += 1;
 
678
                }
 
679
        }
 
680
 
 
681
        if (p > dwNumReadersContexts)
 
682
                /*
 
683
                 * We are severely hosed here 
 
684
                 */
 
685
                /*
 
686
                 * Hopefully this will never be true 
 
687
                 */
 
688
                return SCARD_F_UNKNOWN_ERROR;
 
689
 
 
690
        /*
 
691
         * Added for extra NULL byte on MultiString 
 
692
         */
 
693
        dwCSize += 1;
 
694
 
 
695
        /*
 
696
         * If lpcReaders is not allocated then just 
 
697
         */
 
698
        /*
 
699
         * return the amount needed to allocate 
 
700
         */
 
701
        if (lpcReaders == 0)
 
702
        {
 
703
                *pdwReaderNum = dwCSize;
 
704
                return SCARD_S_SUCCESS;
 
705
        }
 
706
 
 
707
        if (*pdwReaderNum < dwCSize)
 
708
                return SCARD_E_INSUFFICIENT_BUFFER;
 
709
 
 
710
        *pdwReaderNum = dwCSize;
 
711
        lpcTReaders = lpcReaders;
 
712
        p = 0;
 
713
 
 
714
        /*
 
715
         * Creating MultiString 
 
716
         */
 
717
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
718
        {
 
719
                if ((sReadersContexts[i])->vHandle != 0)
 
720
                {
 
721
                        strcpy(&lpcTReaders[p], (sReadersContexts[i])->lpcReader);
 
722
                        p += strlen((sReadersContexts[i])->lpcReader);  /* Copy */
 
723
                        lpcTReaders[p] = 0;     /* Add NULL */
 
724
                        p += 1; /* Move on */
 
725
                }
 
726
        }
 
727
 
 
728
        lpcTReaders[p] = 0;     /* Add NULL */
 
729
 
 
730
        return SCARD_S_SUCCESS;
 
731
}
 
732
#endif
 
733
 
 
734
LONG RFReaderInfo(LPTSTR lpcReader, PREADER_CONTEXT * sReader)
 
735
{
 
736
        int i;
 
737
 
 
738
        if (lpcReader == 0)
 
739
                return SCARD_E_UNKNOWN_READER;
 
740
 
 
741
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
742
        {
 
743
                if ((sReadersContexts[i])->vHandle != 0)
 
744
                {
 
745
                        if (strcmp(lpcReader, (sReadersContexts[i])->lpcReader) == 0)
 
746
                        {
 
747
                                *sReader = sReadersContexts[i];
 
748
                                return SCARD_S_SUCCESS;
 
749
                        }
 
750
                }
 
751
        }
 
752
 
 
753
        return SCARD_E_UNKNOWN_READER;
 
754
}
 
755
 
 
756
LONG RFReaderInfoNamePort(DWORD dwPort, LPTSTR lpcReader,
 
757
        PREADER_CONTEXT * sReader)
 
758
{
 
759
        char lpcStripReader[MAX_READERNAME];
 
760
        int i;
 
761
 
 
762
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
763
        {
 
764
                if ((sReadersContexts[i])->vHandle != 0)
 
765
                {
 
766
                        int tmplen;
 
767
 
 
768
                        strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
 
769
                                sizeof(lpcStripReader));
 
770
                        tmplen = strlen(lpcStripReader);
 
771
                        lpcStripReader[tmplen - 6] = 0;
 
772
 
 
773
                        if ((strcmp(lpcReader, lpcStripReader) == 0) &&
 
774
                                (dwPort == (sReadersContexts[i])->dwPort))
 
775
                        {
 
776
                                *sReader = sReadersContexts[i];
 
777
                                return SCARD_S_SUCCESS;
 
778
                        }
 
779
                }
 
780
        }
 
781
 
 
782
        return SCARD_E_INVALID_VALUE;
 
783
}
 
784
 
 
785
LONG RFReaderInfoById(DWORD dwIdentity, PREADER_CONTEXT * sReader)
 
786
{
 
787
        int i;
 
788
 
 
789
        /*
 
790
         * Strip off the lower nibble and get the identity 
 
791
         */
 
792
        dwIdentity = dwIdentity >> (sizeof(DWORD) / 2) * 8;
 
793
        dwIdentity = dwIdentity << (sizeof(DWORD) / 2) * 8;
 
794
 
 
795
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
796
        {
 
797
                if (dwIdentity == (sReadersContexts[i])->dwIdentity)
 
798
                {
 
799
                        *sReader = sReadersContexts[i];
 
800
                        return SCARD_S_SUCCESS;
 
801
                }
 
802
        }
 
803
 
 
804
        return SCARD_E_INVALID_VALUE;
 
805
}
 
806
 
 
807
LONG RFLoadReader(PREADER_CONTEXT rContext)
 
808
{
 
809
        if (rContext->vHandle != 0)
 
810
        {
 
811
                Log1(PCSC_LOG_ERROR, "Warning library pointer not NULL");
 
812
                /*
 
813
                 * Another reader exists with this library loaded 
 
814
                 */
 
815
                return SCARD_S_SUCCESS;
 
816
        }
 
817
 
 
818
        return DYN_LoadLibrary(&rContext->vHandle, rContext->lpcLibrary);
 
819
}
 
820
 
 
821
LONG RFBindFunctions(PREADER_CONTEXT rContext)
 
822
{
 
823
        int rv1, rv2, rv3;
 
824
 
 
825
        /*
 
826
         * Use this function as a dummy to determine the IFD Handler version
 
827
         * type  1.0/2.0/3.0.  Suppress error messaging since it can't be 1.0,
 
828
         * 2.0 and 3.0. 
 
829
         */
 
830
 
 
831
        DebugLogSuppress(DEBUGLOG_IGNORE_ENTRIES);
 
832
 
 
833
        rv1 = DYN_GetAddress(rContext->vHandle,
 
834
                (void **)&rContext->psFunctions.psFunctions_v1.pvfCreateChannel,
 
835
                "IO_Create_Channel");
 
836
 
 
837
        rv2 = DYN_GetAddress(rContext->vHandle,
 
838
                (void **)&rContext->psFunctions.psFunctions_v2.pvfCreateChannel,
 
839
                "IFDHCreateChannel");
 
840
 
 
841
        rv3 = DYN_GetAddress(rContext->vHandle,
 
842
                (void **)&rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName,
 
843
                "IFDHCreateChannelByName");
 
844
 
 
845
        DebugLogSuppress(DEBUGLOG_LOG_ENTRIES);
 
846
 
 
847
        if (rv1 != SCARD_S_SUCCESS && rv2 != SCARD_S_SUCCESS && rv3 != SCARD_S_SUCCESS)
 
848
        {
 
849
                /*
 
850
                 * Neither version of the IFD Handler was found - exit 
 
851
                 */
 
852
                Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
 
853
 
 
854
                exit(1);
 
855
        } else if (rv1 == SCARD_S_SUCCESS)
 
856
        {
 
857
                /*
 
858
                 * Ifd Handler 1.0 found 
 
859
                 */
 
860
                rContext->dwVersion = IFD_HVERSION_1_0;
 
861
        } else if (rv3 == SCARD_S_SUCCESS)
 
862
        {
 
863
                /*
 
864
                 * Ifd Handler 3.0 found 
 
865
                 */
 
866
                rContext->dwVersion = IFD_HVERSION_3_0;
 
867
        }
 
868
        else
 
869
        {
 
870
                /*
 
871
                 * Ifd Handler 2.0 found 
 
872
                 */
 
873
                rContext->dwVersion = IFD_HVERSION_2_0;
 
874
        }
 
875
 
 
876
        /*
 
877
         * The following binds version 1.0 of the IFD Handler specs 
 
878
         */
 
879
 
 
880
        if (rContext->dwVersion == IFD_HVERSION_1_0)
 
881
        {
 
882
                Log1(PCSC_LOG_INFO, "Loading IFD Handler 1.0");
 
883
 
 
884
#define GET_ADDRESS_OPTIONALv1(field, function, code) \
 
885
{ \
 
886
        if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, (void **)&rContext->psFunctions.psFunctions_v1.pvf ## field, "IFD_" #function)) \
 
887
        { \
 
888
                rContext->psFunctions.psFunctions_v1.pvf ## field = NULL; \
 
889
                code \
 
890
        } \
 
891
}
 
892
 
 
893
#define GET_ADDRESSv1(field, function) \
 
894
        GET_ADDRESS_OPTIONALv1(field, function, \
 
895
                Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #function ); \
 
896
                exit(1); )
 
897
 
 
898
                DYN_GetAddress(rContext->vHandle,
 
899
                        (void **)&rContext->psFunctions.psFunctions_v1.pvfCreateChannel,
 
900
                        "IO_Create_Channel");
 
901
 
 
902
                if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle,
 
903
                        (void **)&rContext->psFunctions.psFunctions_v1.pvfCloseChannel,
 
904
                        "IO_Close_Channel"))
 
905
                {
 
906
                        rContext->psFunctions.psFunctions_v1.pvfCloseChannel = NULL;
 
907
                        Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
 
908
                        exit(1);
 
909
                }
 
910
 
 
911
                GET_ADDRESSv1(GetCapabilities, Get_Capabilities)
 
912
                GET_ADDRESSv1(SetCapabilities, Set_Capabilities)
 
913
                GET_ADDRESSv1(PowerICC, Power_ICC)
 
914
                GET_ADDRESSv1(TransmitToICC, Transmit_to_ICC)
 
915
                GET_ADDRESSv1(ICCPresence, Is_ICC_Present)
 
916
 
 
917
                GET_ADDRESS_OPTIONALv1(SetProtocolParameters, Set_Protocol_Parameters, )
 
918
        }
 
919
        else if (rContext->dwVersion == IFD_HVERSION_2_0)
 
920
        {
 
921
                /*
 
922
                 * The following binds version 2.0 of the IFD Handler specs 
 
923
                 */
 
924
 
 
925
#define GET_ADDRESS_OPTIONALv2(s, code) \
 
926
{ \
 
927
        if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, (void **)&rContext->psFunctions.psFunctions_v2.pvf ## s, "IFDH" #s)) \
 
928
        { \
 
929
                rContext->psFunctions.psFunctions_v2.pvf ## s = NULL; \
 
930
                code \
 
931
        } \
 
932
}
 
933
 
 
934
#define GET_ADDRESSv2(s) \
 
935
        GET_ADDRESS_OPTIONALv2(s, \
 
936
                Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
 
937
                exit(1); )
 
938
 
 
939
                Log1(PCSC_LOG_INFO, "Loading IFD Handler 2.0");
 
940
 
 
941
                GET_ADDRESSv2(CloseChannel)
 
942
                GET_ADDRESSv2(GetCapabilities)
 
943
                GET_ADDRESSv2(SetCapabilities)
 
944
                GET_ADDRESSv2(PowerICC)
 
945
                GET_ADDRESSv2(TransmitToICC)
 
946
                GET_ADDRESSv2(ICCPresence)
 
947
                GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
 
948
 
 
949
                GET_ADDRESSv2(Control)
 
950
        }
 
951
        else if (rContext->dwVersion == IFD_HVERSION_3_0)
 
952
        {
 
953
                /*
 
954
                 * The following binds version 3.0 of the IFD Handler specs 
 
955
                 */
 
956
 
 
957
#define GET_ADDRESS_OPTIONALv3(s, code) \
 
958
{ \
 
959
        if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, (void **)&rContext->psFunctions.psFunctions_v3.pvf ## s, "IFDH" #s)) \
 
960
        { \
 
961
                rContext->psFunctions.psFunctions_v3.pvf ## s = NULL; \
 
962
                code \
 
963
        } \
 
964
}
 
965
 
 
966
#define GET_ADDRESSv3(s) \
 
967
        GET_ADDRESS_OPTIONALv3(s, \
 
968
                Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
 
969
                exit(1); )
 
970
 
 
971
                Log1(PCSC_LOG_INFO, "Loading IFD Handler 3.0");
 
972
 
 
973
                GET_ADDRESSv2(CloseChannel)
 
974
                GET_ADDRESSv2(GetCapabilities)
 
975
                GET_ADDRESSv2(SetCapabilities)
 
976
                GET_ADDRESSv2(PowerICC)
 
977
                GET_ADDRESSv2(TransmitToICC)
 
978
                GET_ADDRESSv2(ICCPresence)
 
979
                GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
 
980
 
 
981
                GET_ADDRESSv3(Control)
 
982
        }
 
983
        else
 
984
        {
 
985
                /*
 
986
                 * Who knows what could have happenned for it to get here. 
 
987
                 */
 
988
                Log1(PCSC_LOG_CRITICAL, "IFD Handler not 1.0/2.0 or 3.0");
 
989
                exit(1);
 
990
        }
 
991
 
 
992
        return SCARD_S_SUCCESS;
 
993
}
 
994
 
 
995
LONG RFUnBindFunctions(PREADER_CONTEXT rContext)
 
996
{
 
997
        /*
 
998
         * Zero out everything 
 
999
         */
 
1000
 
 
1001
        memset(&rContext->psFunctions, 0, sizeof(rContext->psFunctions));
 
1002
 
 
1003
        return SCARD_S_SUCCESS;
 
1004
}
 
1005
 
 
1006
LONG RFUnloadReader(PREADER_CONTEXT rContext)
 
1007
{
 
1008
        /*
 
1009
         * Make sure no one else is using this library 
 
1010
         */
 
1011
 
 
1012
        if (*rContext->pdwFeeds == 1)
 
1013
        {
 
1014
                Log1(PCSC_LOG_INFO, "Unloading reader driver.");
 
1015
                DYN_CloseLibrary(&rContext->vHandle);
 
1016
        }
 
1017
 
 
1018
        rContext->vHandle = 0;
 
1019
 
 
1020
        return SCARD_S_SUCCESS;
 
1021
}
 
1022
 
 
1023
LONG RFCheckSharing(DWORD hCard)
 
1024
{
 
1025
        LONG rv;
 
1026
        PREADER_CONTEXT rContext = NULL;
 
1027
 
 
1028
        rv = RFReaderInfoById(hCard, &rContext);
 
1029
 
 
1030
        if (rv != SCARD_S_SUCCESS)
 
1031
                return rv;
 
1032
 
 
1033
        if (rContext->dwLockId == 0 || rContext->dwLockId == hCard)
 
1034
                return SCARD_S_SUCCESS;
 
1035
        else
 
1036
                return SCARD_E_SHARING_VIOLATION;
 
1037
 
 
1038
}
 
1039
 
 
1040
LONG RFLockSharing(DWORD hCard)
 
1041
{
 
1042
        PREADER_CONTEXT rContext = NULL;
 
1043
 
 
1044
        RFReaderInfoById(hCard, &rContext);
 
1045
 
 
1046
        if (RFCheckSharing(hCard) == SCARD_S_SUCCESS)
 
1047
        {
 
1048
                EHSetSharingEvent(rContext, 1);
 
1049
                rContext->dwLockId = hCard;
 
1050
        }
 
1051
        else
 
1052
                return SCARD_E_SHARING_VIOLATION;
 
1053
 
 
1054
        return SCARD_S_SUCCESS;
 
1055
}
 
1056
 
 
1057
LONG RFUnlockSharing(DWORD hCard)
 
1058
{
 
1059
        PREADER_CONTEXT rContext = NULL;
 
1060
 
 
1061
        RFReaderInfoById(hCard, &rContext);
 
1062
 
 
1063
        if (RFCheckSharing(hCard) == SCARD_S_SUCCESS)
 
1064
        {
 
1065
                EHSetSharingEvent(rContext, 0);
 
1066
                rContext->dwLockId = 0;
 
1067
        }
 
1068
        else
 
1069
                return SCARD_E_SHARING_VIOLATION;
 
1070
 
 
1071
        return SCARD_S_SUCCESS;
 
1072
}
 
1073
 
 
1074
LONG RFUnblockContext(SCARDCONTEXT hContext)
 
1075
{
 
1076
        int i;
 
1077
 
 
1078
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
1079
                (sReadersContexts[i])->dwBlockStatus = hContext;
 
1080
 
 
1081
        return SCARD_S_SUCCESS;
 
1082
}
 
1083
 
 
1084
LONG RFUnblockReader(PREADER_CONTEXT rContext)
 
1085
{
 
1086
        rContext->dwBlockStatus = BLOCK_STATUS_RESUME;
 
1087
        return SCARD_S_SUCCESS;
 
1088
}
 
1089
 
 
1090
LONG RFInitializeReader(PREADER_CONTEXT rContext)
 
1091
{
 
1092
        LONG rv;
 
1093
 
 
1094
        /*
 
1095
         * Spawn the event handler thread 
 
1096
         */
 
1097
        Log2(PCSC_LOG_INFO, "Attempting startup of %s.", rContext->lpcReader);
 
1098
 
 
1099
  /******************************************/
 
1100
        /*
 
1101
         * This section loads the library 
 
1102
         */
 
1103
  /******************************************/
 
1104
        rv = RFLoadReader(rContext);
 
1105
        if (rv != SCARD_S_SUCCESS)
 
1106
                return rv;
 
1107
 
 
1108
  /*******************************************/
 
1109
        /*
 
1110
         * This section binds the functions 
 
1111
         */
 
1112
  /*******************************************/
 
1113
        rv = RFBindFunctions(rContext);
 
1114
 
 
1115
        if (rv != SCARD_S_SUCCESS)
 
1116
        {
 
1117
                RFUnloadReader(rContext);
 
1118
                return rv;
 
1119
        }
 
1120
 
 
1121
  /*******************************************/
 
1122
        /*
 
1123
         * This section tries to open the port 
 
1124
         */
 
1125
  /*******************************************/
 
1126
 
 
1127
        rv = IFDOpenIFD(rContext);
 
1128
 
 
1129
        if (rv != IFD_SUCCESS)
 
1130
        {
 
1131
                Log3(PCSC_LOG_CRITICAL, "Open Port %X Failed (%s)",
 
1132
                        rContext->dwPort, rContext->lpcDevice);
 
1133
                RFUnBindFunctions(rContext);
 
1134
                RFUnloadReader(rContext);
 
1135
                return SCARD_E_INVALID_TARGET;
 
1136
        }
 
1137
 
 
1138
        return SCARD_S_SUCCESS;
 
1139
}
 
1140
 
 
1141
LONG RFUnInitializeReader(PREADER_CONTEXT rContext)
 
1142
{
 
1143
        Log2(PCSC_LOG_INFO, "Attempting shutdown of %s.",
 
1144
                rContext->lpcReader);
 
1145
 
 
1146
        /*
 
1147
         * Close the port, unbind the functions, and unload the library 
 
1148
         */
 
1149
 
 
1150
        /*
 
1151
         * If the reader is getting uninitialized then it is being unplugged
 
1152
         * so I can't send a IFDPowerICC call to it
 
1153
         * 
 
1154
         * IFDPowerICC( rContext, IFD_POWER_DOWN, Atr, &AtrLen ); 
 
1155
         */
 
1156
        IFDCloseIFD(rContext);
 
1157
        RFUnBindFunctions(rContext);
 
1158
        RFUnloadReader(rContext);
 
1159
 
 
1160
        return SCARD_S_SUCCESS;
 
1161
}
 
1162
 
 
1163
SCARDHANDLE RFCreateReaderHandle(PREADER_CONTEXT rContext)
 
1164
{
 
1165
        USHORT randHandle;
 
1166
 
 
1167
        /*
 
1168
         * Create a random handle with 16 bits check to see if it already is
 
1169
         * used. 
 
1170
         */
 
1171
        randHandle = SYS_RandomInt(10, 65000);
 
1172
 
 
1173
        while (1)
 
1174
        {
 
1175
                int i;
 
1176
 
 
1177
                for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
1178
                {
 
1179
                        if ((sReadersContexts[i])->vHandle != 0)
 
1180
                        {
 
1181
                                int j;
 
1182
 
 
1183
                                for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
 
1184
                                {
 
1185
                                        if ((rContext->dwIdentity + randHandle) ==
 
1186
                                                (sReadersContexts[i])->psHandles[j].hCard)
 
1187
                                        {
 
1188
                                                /*
 
1189
                                                 * Get a new handle and loop again 
 
1190
                                                 */
 
1191
                                                randHandle = SYS_RandomInt(10, 65000);
 
1192
                                                continue;
 
1193
                                        }
 
1194
                                }
 
1195
                        }
 
1196
                }
 
1197
 
 
1198
                /*
 
1199
                 * Once the for loop is completed w/o restart a good handle was
 
1200
                 * found and the loop can be exited. 
 
1201
                 */
 
1202
 
 
1203
                if (i == PCSCLITE_MAX_READERS_CONTEXTS)
 
1204
                        break;
 
1205
        }
 
1206
 
 
1207
        return rContext->dwIdentity + randHandle;
 
1208
}
 
1209
 
 
1210
LONG RFFindReaderHandle(SCARDHANDLE hCard)
 
1211
{
 
1212
        int i;
 
1213
 
 
1214
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
1215
        {
 
1216
                if ((sReadersContexts[i])->vHandle != 0)
 
1217
                {
 
1218
                        int j;
 
1219
 
 
1220
                        for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
 
1221
                        {
 
1222
                                if (hCard == (sReadersContexts[i])->psHandles[j].hCard)
 
1223
                                        return SCARD_S_SUCCESS;
 
1224
                        }
 
1225
                }
 
1226
        }
 
1227
 
 
1228
        return SCARD_E_INVALID_HANDLE;
 
1229
}
 
1230
 
 
1231
LONG RFDestroyReaderHandle(SCARDHANDLE hCard)
 
1232
{
 
1233
        return SCARD_S_SUCCESS;
 
1234
}
 
1235
 
 
1236
LONG RFAddReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
 
1237
{
 
1238
        int i;
 
1239
 
 
1240
        for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
 
1241
        {
 
1242
                if (rContext->psHandles[i].hCard == 0)
 
1243
                {
 
1244
                        rContext->psHandles[i].hCard = hCard;
 
1245
                        rContext->psHandles[i].dwEventStatus = 0;
 
1246
                        break;
 
1247
                }
 
1248
        }
 
1249
 
 
1250
        if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
 
1251
                /* List is full */
 
1252
                return SCARD_E_INSUFFICIENT_BUFFER;
 
1253
 
 
1254
        return SCARD_S_SUCCESS;
 
1255
}
 
1256
 
 
1257
LONG RFRemoveReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
 
1258
{
 
1259
        int i;
 
1260
 
 
1261
        for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
 
1262
        {
 
1263
                if (rContext->psHandles[i].hCard == hCard)
 
1264
                {
 
1265
                        rContext->psHandles[i].hCard = 0;
 
1266
                        rContext->psHandles[i].dwEventStatus = 0;
 
1267
                        break;
 
1268
                }
 
1269
        }
 
1270
 
 
1271
        if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
 
1272
                /* Not Found */
 
1273
                return SCARD_E_INVALID_HANDLE;
 
1274
 
 
1275
        return SCARD_S_SUCCESS;
 
1276
}
 
1277
 
 
1278
LONG RFSetReaderEventState(PREADER_CONTEXT rContext, DWORD dwEvent)
 
1279
{
 
1280
        int i;
 
1281
 
 
1282
        /*
 
1283
         * Set all the handles for that reader to the event 
 
1284
         */
 
1285
        for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
 
1286
        {
 
1287
                if (rContext->psHandles[i].hCard != 0)
 
1288
                        rContext->psHandles[i].dwEventStatus = dwEvent;
 
1289
        }
 
1290
 
 
1291
        return SCARD_S_SUCCESS;
 
1292
}
 
1293
 
 
1294
LONG RFCheckReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
 
1295
{
 
1296
        int i;
 
1297
 
 
1298
        for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
 
1299
        {
 
1300
                if (rContext->psHandles[i].hCard == hCard)
 
1301
                {
 
1302
                        if (rContext->psHandles[i].dwEventStatus == SCARD_REMOVED)
 
1303
                                return SCARD_W_REMOVED_CARD;
 
1304
                        else
 
1305
                        {
 
1306
                                if (rContext->psHandles[i].dwEventStatus == SCARD_RESET)
 
1307
                                        return SCARD_W_RESET_CARD;
 
1308
                                else
 
1309
                                {
 
1310
                                        if (rContext->psHandles[i].dwEventStatus == 0)
 
1311
                                                return SCARD_S_SUCCESS;
 
1312
                                        else
 
1313
                                                return SCARD_E_INVALID_VALUE;
 
1314
                                }
 
1315
                        }
 
1316
                }
 
1317
        }
 
1318
 
 
1319
        return SCARD_E_INVALID_HANDLE;
 
1320
}
 
1321
 
 
1322
LONG RFClearReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
 
1323
{
 
1324
        int i;
 
1325
 
 
1326
        for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
 
1327
        {
 
1328
                if (rContext->psHandles[i].hCard == hCard)
 
1329
                        rContext->psHandles[i].dwEventStatus = 0;
 
1330
        }
 
1331
 
 
1332
        if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
 
1333
                /* Not Found */
 
1334
                return SCARD_E_INVALID_HANDLE;
 
1335
 
 
1336
        return SCARD_S_SUCCESS;
 
1337
}
 
1338
 
 
1339
LONG RFCheckReaderStatus(PREADER_CONTEXT rContext)
 
1340
{
 
1341
        if ((rContext->readerState == NULL)
 
1342
                || (rContext->readerState->readerState & SCARD_UNKNOWN))
 
1343
                return SCARD_E_READER_UNAVAILABLE;
 
1344
        else
 
1345
                return SCARD_S_SUCCESS;
 
1346
}
 
1347
 
 
1348
void RFCleanupReaders(int shouldExit)
 
1349
{
 
1350
        int i;
 
1351
 
 
1352
        Log1(PCSC_LOG_INFO, "entering cleaning function");
 
1353
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
1354
        {
 
1355
                if (sReadersContexts[i]->vHandle != 0)
 
1356
                {
 
1357
                        LONG rv;
 
1358
                        char lpcStripReader[MAX_READERNAME];
 
1359
 
 
1360
                        Log2(PCSC_LOG_INFO, "Stopping reader: %s",
 
1361
                                sReadersContexts[i]->lpcReader);
 
1362
 
 
1363
                        strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
 
1364
                                sizeof(lpcStripReader));
 
1365
                        /*
 
1366
                         * strip the 6 last char ' 00 00' 
 
1367
                         */
 
1368
                        lpcStripReader[strlen(lpcStripReader) - 6] = '\0';
 
1369
 
 
1370
                        rv = RFRemoveReader(lpcStripReader, sReadersContexts[i]->dwPort);
 
1371
 
 
1372
                        if (rv != SCARD_S_SUCCESS)
 
1373
                                Log2(PCSC_LOG_ERROR, "RFRemoveReader error: %s",
 
1374
                                        pcsc_stringify_error(rv));
 
1375
                }
 
1376
        }
 
1377
 
 
1378
        /*
 
1379
         * exit() will call at_exit() 
 
1380
         */
 
1381
 
 
1382
        if (shouldExit) 
 
1383
                exit(0);
 
1384
}
 
1385
 
 
1386
int RFStartSerialReaders(char *readerconf)
 
1387
{
 
1388
        SerialReader *reader_list;
 
1389
        int i, rv;
 
1390
 
 
1391
        /* remember the ocnfiguration filename for RFReCheckReaderConf() */
 
1392
        ConfigFile = strdup(readerconf);
 
1393
 
 
1394
        rv = DBGetReaderList(readerconf, &reader_list);
 
1395
 
 
1396
        /* the list is empty */
 
1397
        if (NULL == reader_list)
 
1398
                return rv;
 
1399
 
 
1400
        for (i=0; reader_list[i].pcFriendlyname; i++)
 
1401
        {
 
1402
                int j;
 
1403
 
 
1404
                RFAddReader(reader_list[i].pcFriendlyname, reader_list[i].dwChannelId,
 
1405
                        reader_list[i].pcLibpath, reader_list[i].pcDevicename);
 
1406
 
 
1407
                /* update the ConfigFileCRC (this false "CRC" is very weak) */
 
1408
                for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
 
1409
                        ConfigFileCRC += reader_list[i].pcFriendlyname[j];
 
1410
                for (j=0; j<reader_list[i].pcLibpath[j]; j++)
 
1411
                        ConfigFileCRC += reader_list[i].pcLibpath[j];
 
1412
                for (j=0; j<reader_list[i].pcDevicename[j]; j++)
 
1413
                        ConfigFileCRC += reader_list[i].pcDevicename[j];
 
1414
 
 
1415
                /* free strings allocated by DBGetReaderList() */
 
1416
                free(reader_list[i].pcFriendlyname);
 
1417
                free(reader_list[i].pcLibpath);
 
1418
                free(reader_list[i].pcDevicename);
 
1419
        }
 
1420
        free(reader_list);
 
1421
 
 
1422
        return rv;
 
1423
}
 
1424
 
 
1425
void RFReCheckReaderConf(void)
 
1426
{
 
1427
        SerialReader *reader_list;
 
1428
        int i, crc;
 
1429
 
 
1430
        DBGetReaderList(ConfigFile, &reader_list);
 
1431
 
 
1432
        /* the list is empty */
 
1433
        if (NULL == reader_list)
 
1434
                return;
 
1435
 
 
1436
        crc = 0;
 
1437
        for (i=0; reader_list[i].pcFriendlyname; i++)
 
1438
        {
 
1439
                int j;
 
1440
 
 
1441
                /* calculate a local crc */
 
1442
                for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
 
1443
                        crc += reader_list[i].pcFriendlyname[j];
 
1444
                for (j=0; j<reader_list[i].pcLibpath[j]; j++)
 
1445
                        crc += reader_list[i].pcLibpath[j];
 
1446
                for (j=0; j<reader_list[i].pcDevicename[j]; j++)
 
1447
                        crc += reader_list[i].pcDevicename[j];
 
1448
        }
 
1449
 
 
1450
        /* cancel if the configuration file has been modified */
 
1451
        if (crc != ConfigFileCRC)
 
1452
        {
 
1453
                Log2(PCSC_LOG_CRITICAL,
 
1454
                        "configuration file: %s has been modified. Recheck canceled",
 
1455
                        ConfigFile);
 
1456
                return;
 
1457
        }
 
1458
 
 
1459
        for (i=0; reader_list[i].pcFriendlyname; i++)
 
1460
        {
 
1461
                int r;
 
1462
                char present = FALSE;
 
1463
 
 
1464
                Log2(PCSC_LOG_DEBUG, "refresh reader: %s",
 
1465
                        reader_list[i].pcFriendlyname);
 
1466
 
 
1467
                /* is the reader already present? */
 
1468
                for (r = 0; r < PCSCLITE_MAX_READERS_CONTEXTS; r++)
 
1469
                {
 
1470
                        if (sReadersContexts[r]->vHandle != 0)
 
1471
                        {
 
1472
                                char lpcStripReader[MAX_READERNAME];
 
1473
                                int tmplen;
 
1474
 
 
1475
                                /* get the reader name without the reader and slot numbers */
 
1476
                                strncpy(lpcStripReader, sReadersContexts[i]->lpcReader,
 
1477
                                        sizeof(lpcStripReader));
 
1478
                                tmplen = strlen(lpcStripReader);
 
1479
                                lpcStripReader[tmplen - 6] = 0;
 
1480
 
 
1481
                                if ((strcmp(reader_list[i].pcFriendlyname, lpcStripReader) == 0)
 
1482
                                        && (reader_list[r].dwChannelId == sReadersContexts[i]->dwPort))
 
1483
                                {
 
1484
                                        DWORD dwStatus = 0, dwAtrLen = 0;
 
1485
                                        UCHAR ucAtr[MAX_ATR_SIZE];
 
1486
 
 
1487
                                        /* the reader was already started */
 
1488
                                        present = TRUE;
 
1489
 
 
1490
                                        /* verify the reader is still connected */
 
1491
                                        if (IFDStatusICC(sReadersContexts[r], &dwStatus, ucAtr,
 
1492
                                                &dwAtrLen) != SCARD_S_SUCCESS)
 
1493
                                        {
 
1494
                                                Log2(PCSC_LOG_INFO, "Reader %s disappeared",
 
1495
                                                        reader_list[i].pcFriendlyname);
 
1496
                                                RFRemoveReader(reader_list[i].pcFriendlyname,
 
1497
                                                        reader_list[r].dwChannelId);
 
1498
                                        }
 
1499
                                }
 
1500
                        }
 
1501
                }
 
1502
 
 
1503
                /* the reader was not present */
 
1504
                if (!present)
 
1505
                        /* we try to add it */
 
1506
                        RFAddReader(reader_list[i].pcFriendlyname,
 
1507
                                reader_list[i].dwChannelId, reader_list[i].pcLibpath,
 
1508
                                reader_list[i].pcDevicename);
 
1509
 
 
1510
                /* free strings allocated by DBGetReaderList() */
 
1511
                free(reader_list[i].pcFriendlyname);
 
1512
                free(reader_list[i].pcLibpath);
 
1513
                free(reader_list[i].pcDevicename);
 
1514
        }
 
1515
        free(reader_list);
 
1516
}
 
1517
 
 
1518
void RFSuspendAllReaders(void) 
 
1519
{
 
1520
        int i;
 
1521
 
 
1522
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
1523
        {
 
1524
                if ((sReadersContexts[i])->vHandle != 0)
 
1525
                {
 
1526
                        EHDestroyEventHandler(sReadersContexts[i]);
 
1527
                        IFDCloseIFD(sReadersContexts[i]);
 
1528
                }
 
1529
        }
 
1530
 
 
1531
}
 
1532
 
 
1533
void RFAwakeAllReaders(void) 
 
1534
{
 
1535
        LONG rv = IFD_SUCCESS;
 
1536
        int i;
 
1537
        int initFlag;
 
1538
        
 
1539
        initFlag = 0;
 
1540
 
 
1541
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
1542
        {
 
1543
                /* If the library is loaded and the event handler is not running */
 
1544
                if ( ((sReadersContexts[i])->vHandle   != 0) &&
 
1545
                     ((sReadersContexts[i])->pthThread == 0) )
 
1546
                {
 
1547
                        int j;
 
1548
 
 
1549
                        for (j=0; j < i; j++)
 
1550
                        {
 
1551
                                if (((sReadersContexts[j])->vHandle == (sReadersContexts[i])->vHandle)&&
 
1552
                                        ((sReadersContexts[j])->dwPort   == (sReadersContexts[i])->dwPort)) 
 
1553
                                {
 
1554
                                        initFlag = 1;
 
1555
                                }
 
1556
                        }
 
1557
                        
 
1558
                        if (initFlag == 0)
 
1559
                                rv = IFDOpenIFD(sReadersContexts[i]);
 
1560
                        else
 
1561
                                initFlag = 0;
 
1562
 
 
1563
                        if (rv != IFD_SUCCESS)
 
1564
                        {
 
1565
                                Log3(PCSC_LOG_ERROR, "Open Port %X Failed (%s)",
 
1566
                                        (sReadersContexts[i])->dwPort, (sReadersContexts[i])->lpcDevice);
 
1567
                        }
 
1568
 
 
1569
 
 
1570
                        EHSpawnEventHandler(sReadersContexts[i]);
 
1571
                        RFSetReaderEventState(sReadersContexts[i], SCARD_RESET);
 
1572
                }
 
1573
        }
 
1574
}
 
1575