readerfactory.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 1999-2004
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  *  Damien Sauveron <damien.sauveron@labri.fr>
00007  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00008  *
00009  * $Id: readerfactory.c 2882 2008-04-21 09:56:51Z rousseau $
00010  */
00011 
00017 #include "config.h"
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <unistd.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <errno.h>
00025 #include <fcntl.h>
00026 
00027 #include "misc.h"
00028 #include "pcscd.h"
00029 #include "ifdhandler.h"
00030 #include "debuglog.h"
00031 #include "thread_generic.h"
00032 #include "readerfactory.h"
00033 #include "dyn_generic.h"
00034 #include "sys_generic.h"
00035 #include "eventhandler.h"
00036 #include "ifdwrapper.h"
00037 #include "hotplug.h"
00038 #include "strlcpycat.h"
00039 #include "configfile.h"
00040 
00041 #ifndef TRUE
00042 #define TRUE 1
00043 #define FALSE 0
00044 #endif
00045 
00046 static PREADER_CONTEXT sReadersContexts[PCSCLITE_MAX_READERS_CONTEXTS];
00047 static DWORD dwNumReadersContexts = 0;
00048 static char *ConfigFile = NULL;
00049 static int ConfigFileCRC = 0;
00050 
00051 #define IDENTITY_SHIFT 16
00052 
00053 LONG RFAllocateReaderSpace(void)
00054 {
00055     int i;                      /* Counter */
00056 
00057     /*
00058      * Allocate each reader structure
00059      */
00060     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00061     {
00062         sReadersContexts[i] = malloc(sizeof(READER_CONTEXT));
00063         (sReadersContexts[i])->vHandle = NULL;
00064         (sReadersContexts[i])->readerState = NULL;
00065     }
00066 
00067     /*
00068      * Create public event structures
00069      */
00070     return EHInitializeEventStructures();
00071 }
00072 
00073 LONG RFAddReader(LPSTR lpcReader, DWORD dwPort, LPSTR lpcLibrary, LPSTR lpcDevice)
00074 {
00075     DWORD dwContext = 0, dwGetSize;
00076     UCHAR ucGetData[1], ucThread[1];
00077     LONG rv, parentNode;
00078     int i, j;
00079 
00080     if ((lpcReader == NULL) || (lpcLibrary == NULL) || (lpcDevice == NULL))
00081         return SCARD_E_INVALID_VALUE;
00082 
00083     /* Reader name too long? also count " 00 00"*/
00084     if (strlen(lpcReader) > MAX_READERNAME - sizeof(" 00 00"))
00085     {
00086         Log3(PCSC_LOG_ERROR, "Reader name too long: %d chars instead of max %d",
00087             strlen(lpcReader), MAX_READERNAME - sizeof(" 00 00"));
00088         return SCARD_E_INVALID_VALUE;
00089     }
00090 
00091     /* Library name too long? */
00092     if (strlen(lpcLibrary) >= MAX_LIBNAME)
00093     {
00094         Log3(PCSC_LOG_ERROR, "Library name too long: %d chars instead of max %d",
00095             strlen(lpcLibrary), MAX_LIBNAME);
00096         return SCARD_E_INVALID_VALUE;
00097     }
00098 
00099     /* Device name too long? */
00100     if (strlen(lpcDevice) >= MAX_DEVICENAME)
00101     {
00102         Log3(PCSC_LOG_ERROR, "Device name too long: %d chars instead of max %d",
00103             strlen(lpcDevice), MAX_DEVICENAME);
00104         return SCARD_E_INVALID_VALUE;
00105     }
00106 
00107     /*
00108      * Same name, same port - duplicate reader cannot be used
00109      */
00110     if (dwNumReadersContexts != 0)
00111     {
00112         for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00113         {
00114             if ((sReadersContexts[i])->vHandle != 0)
00115             {
00116                 char lpcStripReader[MAX_READERNAME];
00117                 int tmplen;
00118 
00119                 /* get the reader name without the reader and slot numbers */
00120                 strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
00121                     sizeof(lpcStripReader));
00122                 tmplen = strlen(lpcStripReader);
00123                 lpcStripReader[tmplen - 6] = 0;
00124 
00125                 if ((strcmp(lpcReader, lpcStripReader) == 0) &&
00126                     (dwPort == (sReadersContexts[i])->dwPort))
00127                 {
00128                     Log1(PCSC_LOG_ERROR, "Duplicate reader found.");
00129                     return SCARD_E_DUPLICATE_READER;
00130                 }
00131             }
00132         }
00133     }
00134 
00135     /*
00136      * We must find an empty slot to put the reader structure
00137      */
00138     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00139     {
00140         if ((sReadersContexts[i])->vHandle == 0)
00141         {
00142             dwContext = i;
00143             break;
00144         }
00145     }
00146 
00147     if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00148     {
00149         /*
00150          * No more spots left return
00151          */
00152         return SCARD_E_NO_MEMORY;
00153     }
00154 
00155     /*
00156      * Check and set the readername to see if it must be enumerated
00157      */
00158     parentNode = RFSetReaderName(sReadersContexts[dwContext], lpcReader,
00159         lpcLibrary, dwPort, 0);
00160     if (parentNode < -1)
00161         return SCARD_E_NO_MEMORY;
00162 
00163     strlcpy((sReadersContexts[dwContext])->lpcLibrary, lpcLibrary,
00164         sizeof((sReadersContexts[dwContext])->lpcLibrary));
00165     strlcpy((sReadersContexts[dwContext])->lpcDevice, lpcDevice,
00166         sizeof((sReadersContexts[dwContext])->lpcDevice));
00167     (sReadersContexts[dwContext])->dwVersion = 0;
00168     (sReadersContexts[dwContext])->dwPort = dwPort;
00169     (sReadersContexts[dwContext])->mMutex = NULL;
00170     (sReadersContexts[dwContext])->dwBlockStatus = 0;
00171     (sReadersContexts[dwContext])->dwContexts = 0;
00172     (sReadersContexts[dwContext])->pthThread = 0;
00173     (sReadersContexts[dwContext])->dwLockId = 0;
00174     (sReadersContexts[dwContext])->LockCount = 0;
00175     (sReadersContexts[dwContext])->vHandle = NULL;
00176     (sReadersContexts[dwContext])->pdwFeeds = NULL;
00177     (sReadersContexts[dwContext])->pdwMutex = NULL;
00178     (sReadersContexts[dwContext])->dwIdentity =
00179         (dwContext + 1) << IDENTITY_SHIFT;
00180     (sReadersContexts[dwContext])->readerState = NULL;
00181 
00182     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
00183         (sReadersContexts[dwContext])->psHandles[i].hCard = 0;
00184 
00185     /*
00186      * If a clone to this reader exists take some values from that clone
00187      */
00188     if (parentNode >= 0 && parentNode < PCSCLITE_MAX_READERS_CONTEXTS)
00189     {
00190         (sReadersContexts[dwContext])->pdwFeeds =
00191           (sReadersContexts[parentNode])->pdwFeeds;
00192         *(sReadersContexts[dwContext])->pdwFeeds += 1;
00193         (sReadersContexts[dwContext])->vHandle =
00194           (sReadersContexts[parentNode])->vHandle;
00195         (sReadersContexts[dwContext])->mMutex =
00196           (sReadersContexts[parentNode])->mMutex;
00197         (sReadersContexts[dwContext])->pdwMutex =
00198           (sReadersContexts[parentNode])->pdwMutex;
00199 
00200         /*
00201          * Call on the driver to see if it is thread safe
00202          */
00203         dwGetSize = sizeof(ucThread);
00204         rv = IFDGetCapabilities((sReadersContexts[parentNode]),
00205                TAG_IFD_THREAD_SAFE, &dwGetSize, ucThread);
00206 
00207         if (rv == IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
00208         {
00209             Log1(PCSC_LOG_INFO, "Driver is thread safe");
00210             (sReadersContexts[dwContext])->mMutex = NULL;
00211             (sReadersContexts[dwContext])->pdwMutex = NULL;
00212         }
00213         else
00214             *(sReadersContexts[dwContext])->pdwMutex += 1;
00215     }
00216 
00217     if ((sReadersContexts[dwContext])->pdwFeeds == NULL)
00218     {
00219         (sReadersContexts[dwContext])->pdwFeeds = malloc(sizeof(DWORD));
00220 
00221         /* Initialize pdwFeeds to 1, otherwise multiple
00222            cloned readers will cause pcscd to crash when
00223            RFUnloadReader unloads the driver library
00224            and there are still devices attached using it --mikeg*/
00225 
00226         *(sReadersContexts[dwContext])->pdwFeeds = 1;
00227     }
00228 
00229     if ((sReadersContexts[dwContext])->mMutex == 0)
00230     {
00231         (sReadersContexts[dwContext])->mMutex =
00232             malloc(sizeof(PCSCLITE_MUTEX));
00233         SYS_MutexInit((sReadersContexts[dwContext])->mMutex);
00234     }
00235 
00236     if ((sReadersContexts[dwContext])->pdwMutex == NULL)
00237     {
00238         (sReadersContexts[dwContext])->pdwMutex = malloc(sizeof(DWORD));
00239 
00240         *(sReadersContexts[dwContext])->pdwMutex = 1;
00241     }
00242 
00243     dwNumReadersContexts += 1;
00244 
00245     rv = RFInitializeReader(sReadersContexts[dwContext]);
00246     if (rv != SCARD_S_SUCCESS)
00247     {
00248         /*
00249          * Cannot connect to reader exit gracefully
00250          */
00251         /*
00252          * Clean up so it is not using needed space
00253          */
00254         Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader);
00255 
00256         (sReadersContexts[dwContext])->dwVersion = 0;
00257         (sReadersContexts[dwContext])->dwPort = 0;
00258         (sReadersContexts[dwContext])->vHandle = NULL;
00259         (sReadersContexts[dwContext])->readerState = NULL;
00260         (sReadersContexts[dwContext])->dwIdentity = 0;
00261 
00262         /*
00263          * Destroy and free the mutex
00264          */
00265         if (*(sReadersContexts[dwContext])->pdwMutex == 1)
00266         {
00267             SYS_MutexDestroy((sReadersContexts[dwContext])->mMutex);
00268             free((sReadersContexts[dwContext])->mMutex);
00269         }
00270 
00271         *(sReadersContexts[dwContext])->pdwMutex -= 1;
00272 
00273         if (*(sReadersContexts[dwContext])->pdwMutex == 0)
00274         {
00275             free((sReadersContexts[dwContext])->pdwMutex);
00276             (sReadersContexts[dwContext])->pdwMutex = NULL;
00277         }
00278 
00279         *(sReadersContexts[dwContext])->pdwFeeds -= 1;
00280 
00281         if (*(sReadersContexts[dwContext])->pdwFeeds == 0)
00282         {
00283             free((sReadersContexts[dwContext])->pdwFeeds);
00284             (sReadersContexts[dwContext])->pdwFeeds = NULL;
00285         }
00286 
00287         dwNumReadersContexts -= 1;
00288 
00289         return rv;
00290     }
00291 
00292     /*
00293      * asynchronous card movement?
00294      */
00295     {
00296         RESPONSECODE (*fct)(DWORD) = NULL;
00297 
00298         dwGetSize = sizeof(fct);
00299 
00300         rv = IFDGetCapabilities((sReadersContexts[dwContext]),
00301             TAG_IFD_POLLING_THREAD, &dwGetSize, (PUCHAR)&fct);
00302         if ((rv != SCARD_S_SUCCESS) || (dwGetSize != sizeof(fct)))
00303         {
00304             fct = NULL;
00305             Log1(PCSC_LOG_INFO, "Using the pcscd polling thread");
00306         }
00307         else
00308             Log1(PCSC_LOG_INFO, "Using the reader polling thread");
00309 
00310         rv = EHSpawnEventHandler(sReadersContexts[dwContext], fct);
00311         if (rv != SCARD_S_SUCCESS)
00312             return rv;
00313     }
00314 
00315     /*
00316      * Call on the driver to see if there are multiple slots
00317      */
00318 
00319     dwGetSize = sizeof(ucGetData);
00320     rv = IFDGetCapabilities((sReadersContexts[dwContext]),
00321         TAG_IFD_SLOTS_NUMBER, &dwGetSize, ucGetData);
00322 
00323     if (rv != IFD_SUCCESS || dwGetSize != 1 || ucGetData[0] == 0)
00324         /*
00325          * Reader does not have this defined.  Must be a single slot
00326          * reader so we can just return SCARD_S_SUCCESS.
00327          */
00328         return SCARD_S_SUCCESS;
00329 
00330     if (rv == IFD_SUCCESS && dwGetSize == 1 && ucGetData[0] == 1)
00331         /*
00332          * Reader has this defined and it only has one slot
00333          */
00334         return SCARD_S_SUCCESS;
00335 
00336     /*
00337      * Check the number of slots and create a different
00338      * structure for each one accordingly
00339      */
00340 
00341     /*
00342      * Initialize the rest of the slots
00343      */
00344 
00345     for (j = 1; j < ucGetData[0]; j++)
00346     {
00347         char *tmpReader = NULL;
00348         DWORD dwContextB = 0;
00349 
00350         /*
00351          * We must find an empty spot to put the
00352          * reader structure
00353          */
00354         for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00355         {
00356             if ((sReadersContexts[i])->vHandle == 0)
00357             {
00358                 dwContextB = i;
00359                 break;
00360             }
00361         }
00362 
00363         if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00364         {
00365             /*
00366              * No more spots left return
00367              */
00368             rv = RFRemoveReader(lpcReader, dwPort);
00369             return SCARD_E_NO_MEMORY;
00370         }
00371 
00372         /*
00373          * Copy the previous reader name and increment the slot number
00374          */
00375         tmpReader = sReadersContexts[dwContextB]->lpcReader;
00376         strlcpy(tmpReader, sReadersContexts[dwContext]->lpcReader,
00377             sizeof(sReadersContexts[dwContextB]->lpcReader));
00378         sprintf(tmpReader + strlen(tmpReader) - 2, "%02X", j);
00379 
00380         strlcpy((sReadersContexts[dwContextB])->lpcLibrary, lpcLibrary,
00381             sizeof((sReadersContexts[dwContextB])->lpcLibrary));
00382         strlcpy((sReadersContexts[dwContextB])->lpcDevice, lpcDevice,
00383             sizeof((sReadersContexts[dwContextB])->lpcDevice));
00384         (sReadersContexts[dwContextB])->dwVersion =
00385           (sReadersContexts[dwContext])->dwVersion;
00386         (sReadersContexts[dwContextB])->dwPort =
00387           (sReadersContexts[dwContext])->dwPort;
00388         (sReadersContexts[dwContextB])->vHandle =
00389           (sReadersContexts[dwContext])->vHandle;
00390         (sReadersContexts[dwContextB])->mMutex =
00391            (sReadersContexts[dwContext])->mMutex;
00392         (sReadersContexts[dwContextB])->pdwMutex =
00393            (sReadersContexts[dwContext])->pdwMutex;
00394         sReadersContexts[dwContextB]->dwSlot =
00395             sReadersContexts[dwContext]->dwSlot + j;
00396 
00397         /*
00398          * Added by Dave - slots did not have a pdwFeeds
00399          * parameter so it was by luck they were working
00400          */
00401 
00402         (sReadersContexts[dwContextB])->pdwFeeds =
00403           (sReadersContexts[dwContext])->pdwFeeds;
00404 
00405         /* Added by Dave for multiple slots */
00406         *(sReadersContexts[dwContextB])->pdwFeeds += 1;
00407 
00408         (sReadersContexts[dwContextB])->dwBlockStatus = 0;
00409         (sReadersContexts[dwContextB])->dwContexts = 0;
00410         (sReadersContexts[dwContextB])->dwLockId = 0;
00411         (sReadersContexts[dwContextB])->LockCount = 0;
00412         (sReadersContexts[dwContextB])->readerState = NULL;
00413         (sReadersContexts[dwContextB])->dwIdentity =
00414             (dwContextB + 1) << IDENTITY_SHIFT;
00415 
00416         for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
00417             (sReadersContexts[dwContextB])->psHandles[i].hCard = 0;
00418 
00419         /*
00420          * Call on the driver to see if the slots are thread safe
00421          */
00422 
00423         dwGetSize = sizeof(ucThread);
00424         rv = IFDGetCapabilities((sReadersContexts[dwContext]),
00425             TAG_IFD_SLOT_THREAD_SAFE, &dwGetSize, ucThread);
00426 
00427         if (rv == IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
00428         {
00429             (sReadersContexts[dwContextB])->mMutex =
00430                 malloc(sizeof(PCSCLITE_MUTEX));
00431             SYS_MutexInit((sReadersContexts[dwContextB])->mMutex);
00432 
00433             (sReadersContexts[dwContextB])->pdwMutex = malloc(sizeof(DWORD));
00434             *(sReadersContexts[dwContextB])->pdwMutex = 1;
00435         }
00436         else
00437             *(sReadersContexts[dwContextB])->pdwMutex += 1;
00438 
00439         dwNumReadersContexts += 1;
00440 
00441         rv = RFInitializeReader(sReadersContexts[dwContextB]);
00442         if (rv != SCARD_S_SUCCESS)
00443         {
00444             /*
00445              * Cannot connect to slot exit gracefully
00446              */
00447             /*
00448              * Clean up so it is not using needed space
00449              */
00450             Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader);
00451 
00452             (sReadersContexts[dwContextB])->dwVersion = 0;
00453             (sReadersContexts[dwContextB])->dwPort = 0;
00454             (sReadersContexts[dwContextB])->vHandle = NULL;
00455             (sReadersContexts[dwContextB])->readerState = NULL;
00456             (sReadersContexts[dwContextB])->dwIdentity = 0;
00457 
00458             /*
00459              * Destroy and free the mutex
00460              */
00461             if (*(sReadersContexts[dwContextB])->pdwMutex == 1)
00462             {
00463                 SYS_MutexDestroy((sReadersContexts[dwContextB])->mMutex);
00464                 free((sReadersContexts[dwContextB])->mMutex);
00465             }
00466 
00467             *(sReadersContexts[dwContextB])->pdwMutex -= 1;
00468 
00469             if (*(sReadersContexts[dwContextB])->pdwMutex == 0)
00470             {
00471                 free((sReadersContexts[dwContextB])->pdwMutex);
00472                 (sReadersContexts[dwContextB])->pdwMutex = NULL;
00473             }
00474 
00475             *(sReadersContexts[dwContextB])->pdwFeeds -= 1;
00476 
00477             if (*(sReadersContexts[dwContextB])->pdwFeeds == 0)
00478             {
00479                 free((sReadersContexts[dwContextB])->pdwFeeds);
00480                 (sReadersContexts[dwContextB])->pdwFeeds = NULL;
00481             }
00482 
00483             dwNumReadersContexts -= 1;
00484 
00485             return rv;
00486         }
00487 
00488         EHSpawnEventHandler(sReadersContexts[dwContextB], NULL);
00489     }
00490 
00491     return SCARD_S_SUCCESS;
00492 }
00493 
00494 LONG RFRemoveReader(LPSTR lpcReader, DWORD dwPort)
00495 {
00496     LONG rv;
00497     PREADER_CONTEXT sContext;
00498 
00499     if (lpcReader == 0)
00500         return SCARD_E_INVALID_VALUE;
00501 
00502     while ((rv = RFReaderInfoNamePort(dwPort, lpcReader, &sContext))
00503         == SCARD_S_SUCCESS)
00504     {
00505         int i;
00506 
00507         /*
00508          * Try to destroy the thread
00509          */
00510         rv = EHDestroyEventHandler(sContext);
00511 
00512         rv = RFUnInitializeReader(sContext);
00513         if (rv != SCARD_S_SUCCESS)
00514             return rv;
00515 
00516         /*
00517          * Destroy and free the mutex
00518          */
00519         if ((NULL == sContext->pdwMutex) || (NULL == sContext->pdwFeeds))
00520         {
00521             Log1(PCSC_LOG_ERROR,
00522                 "Trying to remove an already removed driver");
00523             return SCARD_E_INVALID_VALUE;
00524         }
00525 
00526         if (*sContext->pdwMutex == 1)
00527         {
00528             SYS_MutexDestroy(sContext->mMutex);
00529             free(sContext->mMutex);
00530         }
00531 
00532         *sContext->pdwMutex -= 1;
00533 
00534         if (*sContext->pdwMutex == 0)
00535         {
00536             free(sContext->pdwMutex);
00537             sContext->pdwMutex = NULL;
00538         }
00539 
00540         *sContext->pdwFeeds -= 1;
00541 
00542         /* Added by Dave to free the pdwFeeds variable */
00543 
00544         if (*sContext->pdwFeeds == 0)
00545         {
00546             free(sContext->pdwFeeds);
00547             sContext->pdwFeeds = NULL;
00548         }
00549 
00550         sContext->lpcDevice[0] = 0;
00551         sContext->dwVersion = 0;
00552         sContext->dwPort = 0;
00553         sContext->mMutex = NULL;
00554         sContext->dwBlockStatus = 0;
00555         sContext->dwContexts = 0;
00556         sContext->dwSlot = 0;
00557         sContext->dwLockId = 0;
00558         sContext->LockCount = 0;
00559         sContext->vHandle = NULL;
00560         sContext->dwIdentity = 0;
00561         sContext->readerState = NULL;
00562 
00563         for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
00564             sContext->psHandles[i].hCard = 0;
00565 
00566         dwNumReadersContexts -= 1;
00567     }
00568 
00569     return SCARD_S_SUCCESS;
00570 }
00571 
00572 LONG RFSetReaderName(PREADER_CONTEXT rContext, LPSTR readerName,
00573     LPSTR libraryName, DWORD dwPort, DWORD dwSlot)
00574 {
00575     LONG parent = -1;   /* reader number of the parent of the clone */
00576     DWORD valueLength;
00577     int currentDigit = -1;
00578     int supportedChannels = 0;
00579     int usedDigits[PCSCLITE_MAX_READERS_CONTEXTS];
00580     int i;
00581 
00582     /*
00583      * Clear the list
00584      */
00585     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00586         usedDigits[i] = FALSE;
00587 
00588     if ((0 == dwSlot) && (dwNumReadersContexts != 0))
00589     {
00590         for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00591         {
00592             if ((sReadersContexts[i])->vHandle != 0)
00593             {
00594                 if (strcmp((sReadersContexts[i])->lpcLibrary, libraryName) == 0)
00595                 {
00596                     UCHAR tagValue[1];
00597                     LONG ret;
00598 
00599                     /*
00600                      * Ask the driver if it supports multiple channels
00601                      */
00602                     valueLength = sizeof(tagValue);
00603                     ret = IFDGetCapabilities((sReadersContexts[i]),
00604                         TAG_IFD_SIMULTANEOUS_ACCESS,
00605                         &valueLength, tagValue);
00606 
00607                     if ((ret == IFD_SUCCESS) && (valueLength == 1) &&
00608                         (tagValue[0] > 1))
00609                     {
00610                         supportedChannels = tagValue[0];
00611                         Log2(PCSC_LOG_INFO,
00612                             "Support %d simultaneous readers", tagValue[0]);
00613                     }
00614                     else
00615                         supportedChannels = 1;
00616 
00617                     /*
00618                      * Check to see if it is a hotplug reader and
00619                      * different
00620                      */
00621                     if (((((sReadersContexts[i])->dwPort & 0xFFFF0000) ==
00622                             PCSCLITE_HP_BASE_PORT)
00623                         && ((sReadersContexts[i])->dwPort != dwPort))
00624                         || (supportedChannels > 1))
00625                     {
00626                         char *lpcReader = sReadersContexts[i]->lpcReader;
00627 
00628                         /*
00629                          * tells the caller who the parent of this
00630                          * clone is so it can use it's shared
00631                          * resources like mutex/etc.
00632                          */
00633                         parent = i;
00634 
00635                         /*
00636                          * If the same reader already exists and it is
00637                          * hotplug then we must look for others and
00638                          * enumerate the readername
00639                          */
00640                         currentDigit = strtol(lpcReader + strlen(lpcReader) - 5, NULL, 16);
00641 
00642                         /*
00643                          * This spot is taken
00644                          */
00645                         usedDigits[currentDigit] = TRUE;
00646                     }
00647                 }
00648             }
00649         }
00650 
00651     }
00652 
00653     /* default value */
00654     i = 0;
00655 
00656     /* Other identical readers exist on the same bus */
00657     if (currentDigit != -1)
00658     {
00659         for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00660         {
00661             /* get the first free digit */
00662             if (usedDigits[i] == FALSE)
00663                 break;
00664         }
00665 
00666         if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00667         {
00668             Log2(PCSC_LOG_ERROR, "Max number of readers reached: %d", PCSCLITE_MAX_READERS_CONTEXTS);
00669             return -2;
00670         }
00671 
00672         if (i >= supportedChannels)
00673         {
00674             Log3(PCSC_LOG_ERROR, "Driver %s does not support more than "
00675                 "%d reader(s). Maybe the driver should support "
00676                 "TAG_IFD_SIMULTANEOUS_ACCESS", libraryName, supportedChannels);
00677             return -2;
00678         }
00679     }
00680 
00681     sprintf(rContext->lpcReader, "%s %02X %02lX", readerName, i, dwSlot);
00682 
00683     /*
00684      * Set the slot in 0xDDDDCCCC
00685      */
00686     rContext->dwSlot = (i << 16) + dwSlot;
00687 
00688     return parent;
00689 }
00690 
00691 #if 0
00692 LONG RFListReaders(LPSTR lpcReaders, LPDWORD pdwReaderNum)
00693 {
00694     DWORD dwCSize;
00695     LPSTR lpcTReaders;
00696     int i, p;
00697 
00698     if (dwNumReadersContexts == 0)
00699         return SCARD_E_READER_UNAVAILABLE;
00700 
00701     /*
00702      * Ignore the groups for now, return all readers
00703      */
00704     dwCSize = 0;
00705     p = 0;
00706 
00707     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00708     {
00709         if ((sReadersContexts[i])->vHandle != 0)
00710         {
00711             dwCSize += strlen((sReadersContexts[i])->lpcReader) + 1;
00712             p += 1;
00713         }
00714     }
00715 
00716     if (p > dwNumReadersContexts)
00717         /*
00718          * We are severely hosed here
00719          */
00720         /*
00721          * Hopefully this will never be true
00722          */
00723         return SCARD_F_UNKNOWN_ERROR;
00724 
00725     /*
00726      * Added for extra NULL byte on MultiString
00727      */
00728     dwCSize += 1;
00729 
00730     /*
00731      * If lpcReaders is not allocated then just
00732      */
00733     /*
00734      * return the amount needed to allocate
00735      */
00736     if (lpcReaders == 0)
00737     {
00738         *pdwReaderNum = dwCSize;
00739         return SCARD_S_SUCCESS;
00740     }
00741 
00742     if (*pdwReaderNum < dwCSize)
00743         return SCARD_E_INSUFFICIENT_BUFFER;
00744 
00745     *pdwReaderNum = dwCSize;
00746     lpcTReaders = lpcReaders;
00747     p = 0;
00748 
00749     /*
00750      * Creating MultiString
00751      */
00752     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00753     {
00754         if ((sReadersContexts[i])->vHandle != 0)
00755         {
00756             strcpy(&lpcTReaders[p], (sReadersContexts[i])->lpcReader);
00757             p += strlen((sReadersContexts[i])->lpcReader);  /* Copy */
00758             lpcTReaders[p] = 0; /* Add NULL */
00759             p += 1; /* Move on */
00760         }
00761     }
00762 
00763     lpcTReaders[p] = 0; /* Add NULL */
00764 
00765     return SCARD_S_SUCCESS;
00766 }
00767 #endif
00768 
00769 LONG RFReaderInfo(LPSTR lpcReader, PREADER_CONTEXT * sReader)
00770 {
00771     int i;
00772 
00773     if (lpcReader == 0)
00774         return SCARD_E_UNKNOWN_READER;
00775 
00776     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00777     {
00778         if ((sReadersContexts[i])->vHandle != 0)
00779         {
00780             if (strcmp(lpcReader, (sReadersContexts[i])->lpcReader) == 0)
00781             {
00782                 *sReader = sReadersContexts[i];
00783                 return SCARD_S_SUCCESS;
00784             }
00785         }
00786     }
00787 
00788     return SCARD_E_UNKNOWN_READER;
00789 }
00790 
00791 LONG RFReaderInfoNamePort(DWORD dwPort, LPSTR lpcReader,
00792     PREADER_CONTEXT * sReader)
00793 {
00794     char lpcStripReader[MAX_READERNAME];
00795     int i;
00796 
00797     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00798     {
00799         if ((sReadersContexts[i])->vHandle != 0)
00800         {
00801             int tmplen;
00802 
00803             strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
00804                 sizeof(lpcStripReader));
00805             tmplen = strlen(lpcStripReader);
00806             lpcStripReader[tmplen - 6] = 0;
00807 
00808             if ((strcmp(lpcReader, lpcStripReader) == 0) &&
00809                 (dwPort == (sReadersContexts[i])->dwPort))
00810             {
00811                 *sReader = sReadersContexts[i];
00812                 return SCARD_S_SUCCESS;
00813             }
00814         }
00815     }
00816 
00817     return SCARD_E_INVALID_VALUE;
00818 }
00819 
00820 LONG RFReaderInfoById(DWORD dwIdentity, PREADER_CONTEXT * sReader)
00821 {
00822     int i;
00823 
00824     /*
00825      * Strip off the lower nibble and get the identity
00826      */
00827     dwIdentity = dwIdentity >> IDENTITY_SHIFT;
00828     dwIdentity = dwIdentity << IDENTITY_SHIFT;
00829 
00830     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00831     {
00832         if (dwIdentity == (sReadersContexts[i])->dwIdentity)
00833         {
00834             *sReader = sReadersContexts[i];
00835             return SCARD_S_SUCCESS;
00836         }
00837     }
00838 
00839     return SCARD_E_INVALID_VALUE;
00840 }
00841 
00842 LONG RFLoadReader(PREADER_CONTEXT rContext)
00843 {
00844     if (rContext->vHandle != 0)
00845     {
00846         Log2(PCSC_LOG_INFO, "Reusing already loaded driver for %s",
00847             rContext->lpcLibrary);
00848         /*
00849          * Another reader exists with this library loaded
00850          */
00851         return SCARD_S_SUCCESS;
00852     }
00853 
00854     return DYN_LoadLibrary(&rContext->vHandle, rContext->lpcLibrary);
00855 }
00856 
00857 LONG RFBindFunctions(PREADER_CONTEXT rContext)
00858 {
00859     int rv1, rv2, rv3;
00860     void *f;
00861 
00862     /*
00863      * Use this function as a dummy to determine the IFD Handler version
00864      * type  1.0/2.0/3.0.  Suppress error messaging since it can't be 1.0,
00865      * 2.0 and 3.0.
00866      */
00867 
00868     DebugLogSuppress(DEBUGLOG_IGNORE_ENTRIES);
00869 
00870     rv1 = DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");
00871     rv2 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannel");
00872     rv3 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannelByName");
00873 
00874     DebugLogSuppress(DEBUGLOG_LOG_ENTRIES);
00875 
00876     if (rv1 != SCARD_S_SUCCESS && rv2 != SCARD_S_SUCCESS && rv3 != SCARD_S_SUCCESS)
00877     {
00878         /*
00879          * Neither version of the IFD Handler was found - exit
00880          */
00881         Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
00882 
00883         exit(1);
00884     } else if (rv1 == SCARD_S_SUCCESS)
00885     {
00886         /*
00887          * Ifd Handler 1.0 found
00888          */
00889         rContext->dwVersion = IFD_HVERSION_1_0;
00890     } else if (rv3 == SCARD_S_SUCCESS)
00891     {
00892         /*
00893          * Ifd Handler 3.0 found
00894          */
00895         rContext->dwVersion = IFD_HVERSION_3_0;
00896     }
00897     else
00898     {
00899         /*
00900          * Ifd Handler 2.0 found
00901          */
00902         rContext->dwVersion = IFD_HVERSION_2_0;
00903     }
00904 
00905     /*
00906      * The following binds version 1.0 of the IFD Handler specs
00907      */
00908 
00909     if (rContext->dwVersion == IFD_HVERSION_1_0)
00910     {
00911         Log1(PCSC_LOG_INFO, "Loading IFD Handler 1.0");
00912 
00913 #define GET_ADDRESS_OPTIONALv1(field, function, code) \
00914 { \
00915     void *f1 = NULL; \
00916     if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFD_" #function)) \
00917     { \
00918         code \
00919     } \
00920     rContext->psFunctions.psFunctions_v1.pvf ## field = f1; \
00921 }
00922 
00923 #define GET_ADDRESSv1(field, function) \
00924     GET_ADDRESS_OPTIONALv1(field, function, \
00925         Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #function ); \
00926         exit(1); )
00927 
00928         DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");
00929         rContext->psFunctions.psFunctions_v1.pvfCreateChannel = f;
00930 
00931         if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f,
00932             "IO_Close_Channel"))
00933         {
00934             Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
00935             exit(1);
00936         }
00937         rContext->psFunctions.psFunctions_v1.pvfCloseChannel = f;
00938 
00939         GET_ADDRESSv1(GetCapabilities, Get_Capabilities)
00940         GET_ADDRESSv1(SetCapabilities, Set_Capabilities)
00941         GET_ADDRESSv1(PowerICC, Power_ICC)
00942         GET_ADDRESSv1(TransmitToICC, Transmit_to_ICC)
00943         GET_ADDRESSv1(ICCPresence, Is_ICC_Present)
00944 
00945         GET_ADDRESS_OPTIONALv1(SetProtocolParameters, Set_Protocol_Parameters, )
00946     }
00947     else if (rContext->dwVersion == IFD_HVERSION_2_0)
00948     {
00949         /*
00950          * The following binds version 2.0 of the IFD Handler specs
00951          */
00952 
00953 #define GET_ADDRESS_OPTIONALv2(s, code) \
00954 { \
00955     void *f1 = NULL; \
00956     if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s)) \
00957     { \
00958         code \
00959     } \
00960     rContext->psFunctions.psFunctions_v2.pvf ## s = f1; \
00961 }
00962 
00963 #define GET_ADDRESSv2(s) \
00964     GET_ADDRESS_OPTIONALv2(s, \
00965         Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
00966         exit(1); )
00967 
00968         Log1(PCSC_LOG_INFO, "Loading IFD Handler 2.0");
00969 
00970         GET_ADDRESSv2(CreateChannel)
00971         GET_ADDRESSv2(CloseChannel)
00972         GET_ADDRESSv2(GetCapabilities)
00973         GET_ADDRESSv2(SetCapabilities)
00974         GET_ADDRESSv2(PowerICC)
00975         GET_ADDRESSv2(TransmitToICC)
00976         GET_ADDRESSv2(ICCPresence)
00977         GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
00978 
00979         GET_ADDRESSv2(Control)
00980     }
00981     else if (rContext->dwVersion == IFD_HVERSION_3_0)
00982     {
00983         /*
00984          * The following binds version 3.0 of the IFD Handler specs
00985          */
00986 
00987 #define GET_ADDRESS_OPTIONALv3(s, code) \
00988 { \
00989     void *f1 = NULL; \
00990     if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s)) \
00991     { \
00992         code \
00993     } \
00994     rContext->psFunctions.psFunctions_v3.pvf ## s = f1; \
00995 }
00996 
00997 #define GET_ADDRESSv3(s) \
00998     GET_ADDRESS_OPTIONALv3(s, \
00999         Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
01000         exit(1); )
01001 
01002         Log1(PCSC_LOG_INFO, "Loading IFD Handler 3.0");
01003 
01004         GET_ADDRESSv2(CreateChannel)
01005         GET_ADDRESSv2(CloseChannel)
01006         GET_ADDRESSv2(GetCapabilities)
01007         GET_ADDRESSv2(SetCapabilities)
01008         GET_ADDRESSv2(PowerICC)
01009         GET_ADDRESSv2(TransmitToICC)
01010         GET_ADDRESSv2(ICCPresence)
01011         GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
01012 
01013         GET_ADDRESSv3(CreateChannelByName)
01014         GET_ADDRESSv3(Control)
01015     }
01016     else
01017     {
01018         /*
01019          * Who knows what could have happenned for it to get here.
01020          */
01021         Log1(PCSC_LOG_CRITICAL, "IFD Handler not 1.0/2.0 or 3.0");
01022         exit(1);
01023     }
01024 
01025     return SCARD_S_SUCCESS;
01026 }
01027 
01028 LONG RFUnBindFunctions(PREADER_CONTEXT rContext)
01029 {
01030     /*
01031      * Zero out everything
01032      */
01033 
01034     memset(&rContext->psFunctions, 0, sizeof(rContext->psFunctions));
01035 
01036     return SCARD_S_SUCCESS;
01037 }
01038 
01039 LONG RFUnloadReader(PREADER_CONTEXT rContext)
01040 {
01041     /*
01042      * Make sure no one else is using this library
01043      */
01044 
01045     if (*rContext->pdwFeeds == 1)
01046     {
01047         Log1(PCSC_LOG_INFO, "Unloading reader driver.");
01048         DYN_CloseLibrary(&rContext->vHandle);
01049     }
01050 
01051     rContext->vHandle = NULL;
01052 
01053     return SCARD_S_SUCCESS;
01054 }
01055 
01056 LONG RFCheckSharing(DWORD hCard)
01057 {
01058     LONG rv;
01059     PREADER_CONTEXT rContext = NULL;
01060 
01061     rv = RFReaderInfoById(hCard, &rContext);
01062 
01063     if (rv != SCARD_S_SUCCESS)
01064         return rv;
01065 
01066     if (rContext->dwLockId == 0 || rContext->dwLockId == hCard)
01067         return SCARD_S_SUCCESS;
01068     else
01069         return SCARD_E_SHARING_VIOLATION;
01070 
01071 }
01072 
01073 LONG RFLockSharing(DWORD hCard)
01074 {
01075     PREADER_CONTEXT rContext = NULL;
01076 
01077     RFReaderInfoById(hCard, &rContext);
01078 
01079     if (RFCheckSharing(hCard) == SCARD_S_SUCCESS)
01080     {
01081         rContext->LockCount += 1;
01082         rContext->dwLockId = hCard;
01083     }
01084     else
01085         return SCARD_E_SHARING_VIOLATION;
01086 
01087     return SCARD_S_SUCCESS;
01088 }
01089 
01090 LONG RFUnlockSharing(DWORD hCard)
01091 {
01092     PREADER_CONTEXT rContext = NULL;
01093     LONG rv;
01094 
01095     rv = RFReaderInfoById(hCard, &rContext);
01096     if (rv != SCARD_S_SUCCESS)
01097         return rv;
01098 
01099     rv = RFCheckSharing(hCard);
01100     if (rv != SCARD_S_SUCCESS)
01101         return rv;
01102 
01103     if (rContext->LockCount > 0)
01104         rContext->LockCount -= 1;
01105     if (0 == rContext->LockCount)
01106         rContext->dwLockId = 0;
01107 
01108     return SCARD_S_SUCCESS;
01109 }
01110 
01111 LONG RFUnblockContext(SCARDCONTEXT hContext)
01112 {
01113     int i;
01114 
01115     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01116         (sReadersContexts[i])->dwBlockStatus = hContext;
01117 
01118     return SCARD_S_SUCCESS;
01119 }
01120 
01121 LONG RFUnblockReader(PREADER_CONTEXT rContext)
01122 {
01123     rContext->dwBlockStatus = BLOCK_STATUS_RESUME;
01124     return SCARD_S_SUCCESS;
01125 }
01126 
01127 LONG RFInitializeReader(PREADER_CONTEXT rContext)
01128 {
01129     LONG rv;
01130 
01131     /*
01132      * Spawn the event handler thread
01133      */
01134     Log3(PCSC_LOG_INFO, "Attempting startup of %s using %s",
01135         rContext->lpcReader, rContext->lpcLibrary);
01136 
01137   /******************************************/
01138     /*
01139      * This section loads the library
01140      */
01141   /******************************************/
01142     rv = RFLoadReader(rContext);
01143     if (rv != SCARD_S_SUCCESS)
01144     {
01145         Log2(PCSC_LOG_ERROR, "RFLoadReader failed: %X", rv);
01146         return rv;
01147     }
01148 
01149   /*******************************************/
01150     /*
01151      * This section binds the functions
01152      */
01153   /*******************************************/
01154     rv = RFBindFunctions(rContext);
01155 
01156     if (rv != SCARD_S_SUCCESS)
01157     {
01158         Log2(PCSC_LOG_ERROR, "RFBindFunctions failed: %X", rv);
01159         RFUnloadReader(rContext);
01160         return rv;
01161     }
01162 
01163   /*******************************************/
01164     /*
01165      * This section tries to open the port
01166      */
01167   /*******************************************/
01168 
01169     rv = IFDOpenIFD(rContext);
01170 
01171     if (rv != IFD_SUCCESS)
01172     {
01173         Log3(PCSC_LOG_CRITICAL, "Open Port %X Failed (%s)",
01174             rContext->dwPort, rContext->lpcDevice);
01175         RFUnBindFunctions(rContext);
01176         RFUnloadReader(rContext);
01177         return SCARD_E_INVALID_TARGET;
01178     }
01179 
01180     return SCARD_S_SUCCESS;
01181 }
01182 
01183 LONG RFUnInitializeReader(PREADER_CONTEXT rContext)
01184 {
01185     Log2(PCSC_LOG_INFO, "Attempting shutdown of %s.",
01186         rContext->lpcReader);
01187 
01188     /*
01189      * Close the port, unbind the functions, and unload the library
01190      */
01191 
01192     /*
01193      * If the reader is getting uninitialized then it is being unplugged
01194      * so I can't send a IFDPowerICC call to it
01195      *
01196      * IFDPowerICC( rContext, IFD_POWER_DOWN, Atr, &AtrLen );
01197      */
01198     IFDCloseIFD(rContext);
01199     RFUnBindFunctions(rContext);
01200     RFUnloadReader(rContext);
01201 
01202     return SCARD_S_SUCCESS;
01203 }
01204 
01205 SCARDHANDLE RFCreateReaderHandle(PREADER_CONTEXT rContext)
01206 {
01207     USHORT randHandle;
01208 
01209     /*
01210      * Create a random handle with 16 bits check to see if it already is
01211      * used.
01212      */
01213     randHandle = SYS_RandomInt(10, 65000);
01214 
01215     while (1)
01216     {
01217         int i;
01218 
01219         for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01220         {
01221             if ((sReadersContexts[i])->vHandle != 0)
01222             {
01223                 int j;
01224 
01225                 for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
01226                 {
01227                     if ((rContext->dwIdentity + randHandle) ==
01228                         (sReadersContexts[i])->psHandles[j].hCard)
01229                     {
01230                         /*
01231                          * Get a new handle and loop again
01232                          */
01233                         randHandle = SYS_RandomInt(10, 65000);
01234                         continue;
01235                     }
01236                 }
01237             }
01238         }
01239 
01240         /*
01241          * Once the for loop is completed w/o restart a good handle was
01242          * found and the loop can be exited.
01243          */
01244 
01245         if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01246             break;
01247     }
01248 
01249     return rContext->dwIdentity + randHandle;
01250 }
01251 
01252 LONG RFFindReaderHandle(SCARDHANDLE hCard)
01253 {
01254     int i;
01255 
01256     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01257     {
01258         if ((sReadersContexts[i])->vHandle != 0)
01259         {
01260             int j;
01261 
01262             for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
01263             {
01264                 if (hCard == (sReadersContexts[i])->psHandles[j].hCard)
01265                     return SCARD_S_SUCCESS;
01266             }
01267         }
01268     }
01269 
01270     return SCARD_E_INVALID_HANDLE;
01271 }
01272 
01273 LONG RFDestroyReaderHandle(SCARDHANDLE hCard)
01274 {
01275     return SCARD_S_SUCCESS;
01276 }
01277 
01278 LONG RFAddReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01279 {
01280     int i;
01281 
01282     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01283     {
01284         if (rContext->psHandles[i].hCard == 0)
01285         {
01286             rContext->psHandles[i].hCard = hCard;
01287             rContext->psHandles[i].dwEventStatus = 0;
01288             break;
01289         }
01290     }
01291 
01292     if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
01293         /* List is full */
01294         return SCARD_E_INSUFFICIENT_BUFFER;
01295 
01296     return SCARD_S_SUCCESS;
01297 }
01298 
01299 LONG RFRemoveReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01300 {
01301     int i;
01302 
01303     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01304     {
01305         if (rContext->psHandles[i].hCard == hCard)
01306         {
01307             rContext->psHandles[i].hCard = 0;
01308             rContext->psHandles[i].dwEventStatus = 0;
01309             break;
01310         }
01311     }
01312 
01313     if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
01314         /* Not Found */
01315         return SCARD_E_INVALID_HANDLE;
01316 
01317     return SCARD_S_SUCCESS;
01318 }
01319 
01320 LONG RFSetReaderEventState(PREADER_CONTEXT rContext, DWORD dwEvent)
01321 {
01322     int i;
01323 
01324     /*
01325      * Set all the handles for that reader to the event
01326      */
01327     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01328     {
01329         if (rContext->psHandles[i].hCard != 0)
01330             rContext->psHandles[i].dwEventStatus = dwEvent;
01331     }
01332 
01333     if (SCARD_REMOVED == dwEvent)
01334     {
01335         /* unlock the card */
01336         rContext->dwLockId = 0;
01337         rContext->LockCount = 0;
01338     }
01339 
01340     return SCARD_S_SUCCESS;
01341 }
01342 
01343 LONG RFCheckReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01344 {
01345     int i;
01346 
01347     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01348     {
01349         if (rContext->psHandles[i].hCard == hCard)
01350         {
01351             if (rContext->psHandles[i].dwEventStatus == SCARD_REMOVED)
01352                 return SCARD_W_REMOVED_CARD;
01353             else
01354             {
01355                 if (rContext->psHandles[i].dwEventStatus == SCARD_RESET)
01356                     return SCARD_W_RESET_CARD;
01357                 else
01358                 {
01359                     if (rContext->psHandles[i].dwEventStatus == 0)
01360                         return SCARD_S_SUCCESS;
01361                     else
01362                         return SCARD_E_INVALID_VALUE;
01363                 }
01364             }
01365         }
01366     }
01367 
01368     return SCARD_E_INVALID_HANDLE;
01369 }
01370 
01371 LONG RFClearReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01372 {
01373     int i;
01374 
01375     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01376     {
01377         if (rContext->psHandles[i].hCard == hCard)
01378             rContext->psHandles[i].dwEventStatus = 0;
01379     }
01380 
01381     if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
01382         /* Not Found */
01383         return SCARD_E_INVALID_HANDLE;
01384 
01385     return SCARD_S_SUCCESS;
01386 }
01387 
01388 LONG RFCheckReaderStatus(PREADER_CONTEXT rContext)
01389 {
01390     if ((rContext->readerState == NULL)
01391         || (rContext->readerState->readerState & SCARD_UNKNOWN))
01392         return SCARD_E_READER_UNAVAILABLE;
01393     else
01394         return SCARD_S_SUCCESS;
01395 }
01396 
01397 void RFCleanupReaders(int shouldExit)
01398 {
01399     int i;
01400 
01401     Log1(PCSC_LOG_INFO, "entering cleaning function");
01402     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01403     {
01404         if (sReadersContexts[i]->vHandle != 0)
01405         {
01406             LONG rv;
01407             char lpcStripReader[MAX_READERNAME];
01408 
01409             Log2(PCSC_LOG_INFO, "Stopping reader: %s",
01410                 sReadersContexts[i]->lpcReader);
01411 
01412             strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
01413                 sizeof(lpcStripReader));
01414             /*
01415              * strip the 6 last char ' 00 00'
01416              */
01417             lpcStripReader[strlen(lpcStripReader) - 6] = '\0';
01418 
01419             rv = RFRemoveReader(lpcStripReader, sReadersContexts[i]->dwPort);
01420 
01421             if (rv != SCARD_S_SUCCESS)
01422                 Log2(PCSC_LOG_ERROR, "RFRemoveReader error: 0x%08X", rv);
01423         }
01424     }
01425 
01426     /*
01427      * exit() will call at_exit()
01428      */
01429 
01430     if (shouldExit)
01431         exit(0);
01432 }
01433 
01434 int RFStartSerialReaders(const char *readerconf)
01435 {
01436     SerialReader *reader_list;
01437     int i, rv;
01438 
01439     /* remember the ocnfiguration filename for RFReCheckReaderConf() */
01440     ConfigFile = strdup(readerconf);
01441 
01442     rv = DBGetReaderList(readerconf, &reader_list);
01443 
01444     /* the list is empty */
01445     if (NULL == reader_list)
01446         return rv;
01447 
01448     for (i=0; reader_list[i].pcFriendlyname; i++)
01449     {
01450         int j;
01451 
01452         RFAddReader(reader_list[i].pcFriendlyname, reader_list[i].dwChannelId,
01453             reader_list[i].pcLibpath, reader_list[i].pcDevicename);
01454 
01455         /* update the ConfigFileCRC (this false "CRC" is very weak) */
01456         for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
01457             ConfigFileCRC += reader_list[i].pcFriendlyname[j];
01458         for (j=0; j<reader_list[i].pcLibpath[j]; j++)
01459             ConfigFileCRC += reader_list[i].pcLibpath[j];
01460         for (j=0; j<reader_list[i].pcDevicename[j]; j++)
01461             ConfigFileCRC += reader_list[i].pcDevicename[j];
01462 
01463         /* free strings allocated by DBGetReaderList() */
01464         free(reader_list[i].pcFriendlyname);
01465         free(reader_list[i].pcLibpath);
01466         free(reader_list[i].pcDevicename);
01467     }
01468     free(reader_list);
01469 
01470     return rv;
01471 }
01472 
01473 void RFReCheckReaderConf(void)
01474 {
01475     SerialReader *reader_list;
01476     int i, crc;
01477 
01478     DBGetReaderList(ConfigFile, &reader_list);
01479 
01480     /* the list is empty */
01481     if (NULL == reader_list)
01482         return;
01483 
01484     crc = 0;
01485     for (i=0; reader_list[i].pcFriendlyname; i++)
01486     {
01487         int j;
01488 
01489         /* calculate a local crc */
01490         for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
01491             crc += reader_list[i].pcFriendlyname[j];
01492         for (j=0; j<reader_list[i].pcLibpath[j]; j++)
01493             crc += reader_list[i].pcLibpath[j];
01494         for (j=0; j<reader_list[i].pcDevicename[j]; j++)
01495             crc += reader_list[i].pcDevicename[j];
01496     }
01497 
01498     /* cancel if the configuration file has been modified */
01499     if (crc != ConfigFileCRC)
01500     {
01501         Log2(PCSC_LOG_CRITICAL,
01502             "configuration file: %s has been modified. Recheck canceled",
01503             ConfigFile);
01504         return;
01505     }
01506 
01507     for (i=0; reader_list[i].pcFriendlyname; i++)
01508     {
01509         int r;
01510         char present = FALSE;
01511 
01512         Log2(PCSC_LOG_DEBUG, "refresh reader: %s",
01513             reader_list[i].pcFriendlyname);
01514 
01515         /* is the reader already present? */
01516         for (r = 0; r < PCSCLITE_MAX_READERS_CONTEXTS; r++)
01517         {
01518             if (sReadersContexts[r]->vHandle != 0)
01519             {
01520                 char lpcStripReader[MAX_READERNAME];
01521                 int tmplen;
01522 
01523                 /* get the reader name without the reader and slot numbers */
01524                 strncpy(lpcStripReader, sReadersContexts[i]->lpcReader,
01525                     sizeof(lpcStripReader));
01526                 tmplen = strlen(lpcStripReader);
01527                 lpcStripReader[tmplen - 6] = 0;
01528 
01529                 if ((strcmp(reader_list[i].pcFriendlyname, lpcStripReader) == 0)
01530                     && (reader_list[r].dwChannelId == sReadersContexts[i]->dwPort))
01531                 {
01532                     DWORD dwStatus = 0, dwAtrLen = 0;
01533                     UCHAR ucAtr[MAX_ATR_SIZE];
01534 
01535                     /* the reader was already started */
01536                     present = TRUE;
01537 
01538                     /* verify the reader is still connected */
01539                     if (IFDStatusICC(sReadersContexts[r], &dwStatus, ucAtr,
01540                         &dwAtrLen) != SCARD_S_SUCCESS)
01541                     {
01542                         Log2(PCSC_LOG_INFO, "Reader %s disappeared",
01543                             reader_list[i].pcFriendlyname);
01544                         RFRemoveReader(reader_list[i].pcFriendlyname,
01545                             reader_list[r].dwChannelId);
01546                     }
01547                 }
01548             }
01549         }
01550 
01551         /* the reader was not present */
01552         if (!present)
01553             /* we try to add it */
01554             RFAddReader(reader_list[i].pcFriendlyname,
01555                 reader_list[i].dwChannelId, reader_list[i].pcLibpath,
01556                 reader_list[i].pcDevicename);
01557 
01558         /* free strings allocated by DBGetReaderList() */
01559         free(reader_list[i].pcFriendlyname);
01560         free(reader_list[i].pcLibpath);
01561         free(reader_list[i].pcDevicename);
01562     }
01563     free(reader_list);
01564 }
01565 
01566 void RFSuspendAllReaders(void)
01567 {
01568     int i;
01569 
01570     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01571     {
01572         if ((sReadersContexts[i])->vHandle != 0)
01573         {
01574             EHDestroyEventHandler(sReadersContexts[i]);
01575             IFDCloseIFD(sReadersContexts[i]);
01576         }
01577     }
01578 
01579 }
01580 
01581 void RFAwakeAllReaders(void)
01582 {
01583     LONG rv = IFD_SUCCESS;
01584     int i;
01585     int initFlag;
01586 
01587     initFlag = 0;
01588 
01589     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01590     {
01591         /* If the library is loaded and the event handler is not running */
01592         if ( ((sReadersContexts[i])->vHandle   != 0) &&
01593              ((sReadersContexts[i])->pthThread == 0) )
01594         {
01595             int j;
01596 
01597             for (j=0; j < i; j++)
01598             {
01599                 if (((sReadersContexts[j])->vHandle == (sReadersContexts[i])->vHandle)&&
01600                     ((sReadersContexts[j])->dwPort   == (sReadersContexts[i])->dwPort))
01601                 {
01602                     initFlag = 1;
01603                 }
01604             }
01605 
01606             if (initFlag == 0)
01607                 rv = IFDOpenIFD(sReadersContexts[i]);
01608             else
01609                 initFlag = 0;
01610 
01611             if (rv != IFD_SUCCESS)
01612             {
01613                 Log3(PCSC_LOG_ERROR, "Open Port %X Failed (%s)",
01614                     (sReadersContexts[i])->dwPort, (sReadersContexts[i])->lpcDevice);
01615             }
01616 
01617 
01618             EHSpawnEventHandler(sReadersContexts[i], NULL);
01619             RFSetReaderEventState(sReadersContexts[i], SCARD_RESET);
01620         }
01621     }
01622 }
01623 

Generated on Wed Apr 30 17:11:41 2008 for pcsc-lite by  doxygen 1.5.5