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

Generated on Fri Mar 24 04:30:05 2006 for pcsc-lite by  doxygen 1.4.6