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 2024 2006-04-22 18:52:09Z 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     void *f;
00826 
00827     /*
00828      * Use this function as a dummy to determine the IFD Handler version
00829      * type  1.0/2.0/3.0.  Suppress error messaging since it can't be 1.0,
00830      * 2.0 and 3.0. 
00831      */
00832 
00833     DebugLogSuppress(DEBUGLOG_IGNORE_ENTRIES);
00834 
00835     rv1 = DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");
00836     rv2 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannel");
00837     rv3 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannelByName");
00838 
00839     DebugLogSuppress(DEBUGLOG_LOG_ENTRIES);
00840 
00841     if (rv1 != SCARD_S_SUCCESS && rv2 != SCARD_S_SUCCESS && rv3 != SCARD_S_SUCCESS)
00842     {
00843         /*
00844          * Neither version of the IFD Handler was found - exit 
00845          */
00846         Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
00847 
00848         exit(1);
00849     } else if (rv1 == SCARD_S_SUCCESS)
00850     {
00851         /*
00852          * Ifd Handler 1.0 found 
00853          */
00854         rContext->dwVersion = IFD_HVERSION_1_0;
00855     } else if (rv3 == SCARD_S_SUCCESS)
00856     {
00857         /*
00858          * Ifd Handler 3.0 found 
00859          */
00860         rContext->dwVersion = IFD_HVERSION_3_0;
00861     }
00862     else
00863     {
00864         /*
00865          * Ifd Handler 2.0 found 
00866          */
00867         rContext->dwVersion = IFD_HVERSION_2_0;
00868     }
00869 
00870     /*
00871      * The following binds version 1.0 of the IFD Handler specs 
00872      */
00873 
00874     if (rContext->dwVersion == IFD_HVERSION_1_0)
00875     {
00876         Log1(PCSC_LOG_INFO, "Loading IFD Handler 1.0");
00877 
00878 #define GET_ADDRESS_OPTIONALv1(field, function, code) \
00879 { \
00880     void *f = NULL; \
00881     if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f, "IFD_" #function)) \
00882     { \
00883         code \
00884     } \
00885     rContext->psFunctions.psFunctions_v1.pvf ## field = f; \
00886 }
00887 
00888 #define GET_ADDRESSv1(field, function) \
00889     GET_ADDRESS_OPTIONALv1(field, function, \
00890         Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #function ); \
00891         exit(1); )
00892 
00893         DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");
00894         rContext->psFunctions.psFunctions_v1.pvfCreateChannel = f;
00895 
00896         if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f,
00897             "IO_Close_Channel"))
00898         {
00899             Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
00900             exit(1);
00901         }
00902         rContext->psFunctions.psFunctions_v1.pvfCloseChannel = f;
00903 
00904         GET_ADDRESSv1(GetCapabilities, Get_Capabilities)
00905         GET_ADDRESSv1(SetCapabilities, Set_Capabilities)
00906         GET_ADDRESSv1(PowerICC, Power_ICC)
00907         GET_ADDRESSv1(TransmitToICC, Transmit_to_ICC)
00908         GET_ADDRESSv1(ICCPresence, Is_ICC_Present)
00909 
00910         GET_ADDRESS_OPTIONALv1(SetProtocolParameters, Set_Protocol_Parameters, )
00911     }
00912     else if (rContext->dwVersion == IFD_HVERSION_2_0)
00913     {
00914         /*
00915          * The following binds version 2.0 of the IFD Handler specs 
00916          */
00917 
00918 #define GET_ADDRESS_OPTIONALv2(s, code) \
00919 { \
00920     void *f = NULL; \
00921     if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f, "IFDH" #s)) \
00922     { \
00923         code \
00924     } \
00925     rContext->psFunctions.psFunctions_v2.pvf ## s = f; \
00926 }
00927 
00928 #define GET_ADDRESSv2(s) \
00929     GET_ADDRESS_OPTIONALv2(s, \
00930         Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
00931         exit(1); )
00932 
00933         Log1(PCSC_LOG_INFO, "Loading IFD Handler 2.0");
00934 
00935         GET_ADDRESSv2(CreateChannel)
00936         GET_ADDRESSv2(CloseChannel)
00937         GET_ADDRESSv2(GetCapabilities)
00938         GET_ADDRESSv2(SetCapabilities)
00939         GET_ADDRESSv2(PowerICC)
00940         GET_ADDRESSv2(TransmitToICC)
00941         GET_ADDRESSv2(ICCPresence)
00942         GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
00943 
00944         GET_ADDRESSv2(Control)
00945     }
00946     else if (rContext->dwVersion == IFD_HVERSION_3_0)
00947     {
00948         /*
00949          * The following binds version 3.0 of the IFD Handler specs 
00950          */
00951 
00952 #define GET_ADDRESS_OPTIONALv3(s, code) \
00953 { \
00954     void *f = NULL; \
00955     if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f, "IFDH" #s)) \
00956     { \
00957         code \
00958     } \
00959     rContext->psFunctions.psFunctions_v3.pvf ## s = f; \
00960 }
00961 
00962 #define GET_ADDRESSv3(s) \
00963     GET_ADDRESS_OPTIONALv3(s, \
00964         Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
00965         exit(1); )
00966 
00967         Log1(PCSC_LOG_INFO, "Loading IFD Handler 3.0");
00968 
00969         GET_ADDRESSv2(CreateChannel)
00970         GET_ADDRESSv2(CloseChannel)
00971         GET_ADDRESSv2(GetCapabilities)
00972         GET_ADDRESSv2(SetCapabilities)
00973         GET_ADDRESSv2(PowerICC)
00974         GET_ADDRESSv2(TransmitToICC)
00975         GET_ADDRESSv2(ICCPresence)
00976         GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
00977 
00978         GET_ADDRESSv3(CreateChannelByName)
00979         GET_ADDRESSv3(Control)
00980     }
00981     else
00982     {
00983         /*
00984          * Who knows what could have happenned for it to get here. 
00985          */
00986         Log1(PCSC_LOG_CRITICAL, "IFD Handler not 1.0/2.0 or 3.0");
00987         exit(1);
00988     }
00989 
00990     return SCARD_S_SUCCESS;
00991 }
00992 
00993 LONG RFUnBindFunctions(PREADER_CONTEXT rContext)
00994 {
00995     /*
00996      * Zero out everything 
00997      */
00998 
00999     memset(&rContext->psFunctions, 0, sizeof(rContext->psFunctions));
01000 
01001     return SCARD_S_SUCCESS;
01002 }
01003 
01004 LONG RFUnloadReader(PREADER_CONTEXT rContext)
01005 {
01006     /*
01007      * Make sure no one else is using this library 
01008      */
01009 
01010     if (*rContext->pdwFeeds == 1)
01011     {
01012         Log1(PCSC_LOG_INFO, "Unloading reader driver.");
01013         DYN_CloseLibrary(&rContext->vHandle);
01014     }
01015 
01016     rContext->vHandle = 0;
01017 
01018     return SCARD_S_SUCCESS;
01019 }
01020 
01021 LONG RFCheckSharing(DWORD hCard)
01022 {
01023     LONG rv;
01024     PREADER_CONTEXT rContext = NULL;
01025 
01026     rv = RFReaderInfoById(hCard, &rContext);
01027 
01028     if (rv != SCARD_S_SUCCESS)
01029         return rv;
01030 
01031     if (rContext->dwLockId == 0 || rContext->dwLockId == hCard)
01032         return SCARD_S_SUCCESS;
01033     else
01034         return SCARD_E_SHARING_VIOLATION;
01035 
01036 }
01037 
01038 LONG RFLockSharing(DWORD hCard)
01039 {
01040     PREADER_CONTEXT rContext = NULL;
01041 
01042     RFReaderInfoById(hCard, &rContext);
01043 
01044     if (RFCheckSharing(hCard) == SCARD_S_SUCCESS)
01045     {
01046         EHSetSharingEvent(rContext, 1);
01047         rContext->dwLockId = hCard;
01048     }
01049     else
01050         return SCARD_E_SHARING_VIOLATION;
01051 
01052     return SCARD_S_SUCCESS;
01053 }
01054 
01055 LONG RFUnlockSharing(DWORD hCard)
01056 {
01057     PREADER_CONTEXT rContext = NULL;
01058 
01059     RFReaderInfoById(hCard, &rContext);
01060 
01061     if (RFCheckSharing(hCard) == SCARD_S_SUCCESS)
01062     {
01063         EHSetSharingEvent(rContext, 0);
01064         rContext->dwLockId = 0;
01065     }
01066     else
01067         return SCARD_E_SHARING_VIOLATION;
01068 
01069     return SCARD_S_SUCCESS;
01070 }
01071 
01072 LONG RFUnblockContext(SCARDCONTEXT hContext)
01073 {
01074     int i;
01075 
01076     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01077         (sReadersContexts[i])->dwBlockStatus = hContext;
01078 
01079     return SCARD_S_SUCCESS;
01080 }
01081 
01082 LONG RFUnblockReader(PREADER_CONTEXT rContext)
01083 {
01084     rContext->dwBlockStatus = BLOCK_STATUS_RESUME;
01085     return SCARD_S_SUCCESS;
01086 }
01087 
01088 LONG RFInitializeReader(PREADER_CONTEXT rContext)
01089 {
01090     LONG rv;
01091 
01092     /*
01093      * Spawn the event handler thread 
01094      */
01095     Log2(PCSC_LOG_INFO, "Attempting startup of %s.", rContext->lpcReader);
01096 
01097   /******************************************/
01098     /*
01099      * This section loads the library 
01100      */
01101   /******************************************/
01102     rv = RFLoadReader(rContext);
01103     if (rv != SCARD_S_SUCCESS)
01104         return rv;
01105 
01106   /*******************************************/
01107     /*
01108      * This section binds the functions 
01109      */
01110   /*******************************************/
01111     rv = RFBindFunctions(rContext);
01112 
01113     if (rv != SCARD_S_SUCCESS)
01114     {
01115         RFUnloadReader(rContext);
01116         return rv;
01117     }
01118 
01119   /*******************************************/
01120     /*
01121      * This section tries to open the port 
01122      */
01123   /*******************************************/
01124 
01125     rv = IFDOpenIFD(rContext);
01126 
01127     if (rv != IFD_SUCCESS)
01128     {
01129         Log3(PCSC_LOG_CRITICAL, "Open Port %X Failed (%s)",
01130             rContext->dwPort, rContext->lpcDevice);
01131         RFUnBindFunctions(rContext);
01132         RFUnloadReader(rContext);
01133         return SCARD_E_INVALID_TARGET;
01134     }
01135 
01136     return SCARD_S_SUCCESS;
01137 }
01138 
01139 LONG RFUnInitializeReader(PREADER_CONTEXT rContext)
01140 {
01141     Log2(PCSC_LOG_INFO, "Attempting shutdown of %s.",
01142         rContext->lpcReader);
01143 
01144     /*
01145      * Close the port, unbind the functions, and unload the library 
01146      */
01147 
01148     /*
01149      * If the reader is getting uninitialized then it is being unplugged
01150      * so I can't send a IFDPowerICC call to it
01151      * 
01152      * IFDPowerICC( rContext, IFD_POWER_DOWN, Atr, &AtrLen ); 
01153      */
01154     IFDCloseIFD(rContext);
01155     RFUnBindFunctions(rContext);
01156     RFUnloadReader(rContext);
01157 
01158     return SCARD_S_SUCCESS;
01159 }
01160 
01161 SCARDHANDLE RFCreateReaderHandle(PREADER_CONTEXT rContext)
01162 {
01163     USHORT randHandle;
01164 
01165     /*
01166      * Create a random handle with 16 bits check to see if it already is
01167      * used. 
01168      */
01169     randHandle = SYS_RandomInt(10, 65000);
01170 
01171     while (1)
01172     {
01173         int i;
01174 
01175         for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01176         {
01177             if ((sReadersContexts[i])->vHandle != 0)
01178             {
01179                 int j;
01180 
01181                 for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
01182                 {
01183                     if ((rContext->dwIdentity + randHandle) ==
01184                         (sReadersContexts[i])->psHandles[j].hCard)
01185                     {
01186                         /*
01187                          * Get a new handle and loop again 
01188                          */
01189                         randHandle = SYS_RandomInt(10, 65000);
01190                         continue;
01191                     }
01192                 }
01193             }
01194         }
01195 
01196         /*
01197          * Once the for loop is completed w/o restart a good handle was
01198          * found and the loop can be exited. 
01199          */
01200 
01201         if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01202             break;
01203     }
01204 
01205     return rContext->dwIdentity + randHandle;
01206 }
01207 
01208 LONG RFFindReaderHandle(SCARDHANDLE hCard)
01209 {
01210     int i;
01211 
01212     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01213     {
01214         if ((sReadersContexts[i])->vHandle != 0)
01215         {
01216             int j;
01217 
01218             for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
01219             {
01220                 if (hCard == (sReadersContexts[i])->psHandles[j].hCard)
01221                     return SCARD_S_SUCCESS;
01222             }
01223         }
01224     }
01225 
01226     return SCARD_E_INVALID_HANDLE;
01227 }
01228 
01229 LONG RFDestroyReaderHandle(SCARDHANDLE hCard)
01230 {
01231     return SCARD_S_SUCCESS;
01232 }
01233 
01234 LONG RFAddReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01235 {
01236     int i;
01237 
01238     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01239     {
01240         if (rContext->psHandles[i].hCard == 0)
01241         {
01242             rContext->psHandles[i].hCard = hCard;
01243             rContext->psHandles[i].dwEventStatus = 0;
01244             break;
01245         }
01246     }
01247 
01248     if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
01249         /* List is full */
01250         return SCARD_E_INSUFFICIENT_BUFFER;
01251 
01252     return SCARD_S_SUCCESS;
01253 }
01254 
01255 LONG RFRemoveReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01256 {
01257     int i;
01258 
01259     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01260     {
01261         if (rContext->psHandles[i].hCard == hCard)
01262         {
01263             rContext->psHandles[i].hCard = 0;
01264             rContext->psHandles[i].dwEventStatus = 0;
01265             break;
01266         }
01267     }
01268 
01269     if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
01270         /* Not Found */
01271         return SCARD_E_INVALID_HANDLE;
01272 
01273     return SCARD_S_SUCCESS;
01274 }
01275 
01276 LONG RFSetReaderEventState(PREADER_CONTEXT rContext, DWORD dwEvent)
01277 {
01278     int i;
01279 
01280     /*
01281      * Set all the handles for that reader to the event 
01282      */
01283     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01284     {
01285         if (rContext->psHandles[i].hCard != 0)
01286             rContext->psHandles[i].dwEventStatus = dwEvent;
01287     }
01288 
01289     return SCARD_S_SUCCESS;
01290 }
01291 
01292 LONG RFCheckReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01293 {
01294     int i;
01295 
01296     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01297     {
01298         if (rContext->psHandles[i].hCard == hCard)
01299         {
01300             if (rContext->psHandles[i].dwEventStatus == SCARD_REMOVED)
01301                 return SCARD_W_REMOVED_CARD;
01302             else
01303             {
01304                 if (rContext->psHandles[i].dwEventStatus == SCARD_RESET)
01305                     return SCARD_W_RESET_CARD;
01306                 else
01307                 {
01308                     if (rContext->psHandles[i].dwEventStatus == 0)
01309                         return SCARD_S_SUCCESS;
01310                     else
01311                         return SCARD_E_INVALID_VALUE;
01312                 }
01313             }
01314         }
01315     }
01316 
01317     return SCARD_E_INVALID_HANDLE;
01318 }
01319 
01320 LONG RFClearReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01321 {
01322     int i;
01323 
01324     for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01325     {
01326         if (rContext->psHandles[i].hCard == hCard)
01327             rContext->psHandles[i].dwEventStatus = 0;
01328     }
01329 
01330     if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
01331         /* Not Found */
01332         return SCARD_E_INVALID_HANDLE;
01333 
01334     return SCARD_S_SUCCESS;
01335 }
01336 
01337 LONG RFCheckReaderStatus(PREADER_CONTEXT rContext)
01338 {
01339     if ((rContext->readerState == NULL)
01340         || (rContext->readerState->readerState & SCARD_UNKNOWN))
01341         return SCARD_E_READER_UNAVAILABLE;
01342     else
01343         return SCARD_S_SUCCESS;
01344 }
01345 
01346 void RFCleanupReaders(int shouldExit)
01347 {
01348     int i;
01349 
01350     Log1(PCSC_LOG_INFO, "entering cleaning function");
01351     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01352     {
01353         if (sReadersContexts[i]->vHandle != 0)
01354         {
01355             LONG rv;
01356             char lpcStripReader[MAX_READERNAME];
01357 
01358             Log2(PCSC_LOG_INFO, "Stopping reader: %s",
01359                 sReadersContexts[i]->lpcReader);
01360 
01361             strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
01362                 sizeof(lpcStripReader));
01363             /*
01364              * strip the 6 last char ' 00 00' 
01365              */
01366             lpcStripReader[strlen(lpcStripReader) - 6] = '\0';
01367 
01368             rv = RFRemoveReader(lpcStripReader, sReadersContexts[i]->dwPort);
01369 
01370             if (rv != SCARD_S_SUCCESS)
01371                 Log2(PCSC_LOG_ERROR, "RFRemoveReader error: 0x%08X", rv);
01372         }
01373     }
01374 
01375     /*
01376      * exit() will call at_exit() 
01377      */
01378 
01379     if (shouldExit) 
01380         exit(0);
01381 }
01382 
01383 int RFStartSerialReaders(char *readerconf)
01384 {
01385     SerialReader *reader_list;
01386     int i, rv;
01387 
01388     /* remember the ocnfiguration filename for RFReCheckReaderConf() */
01389     ConfigFile = strdup(readerconf);
01390 
01391     rv = DBGetReaderList(readerconf, &reader_list);
01392 
01393     /* the list is empty */
01394     if (NULL == reader_list)
01395         return rv;
01396 
01397     for (i=0; reader_list[i].pcFriendlyname; i++)
01398     {
01399         int j;
01400 
01401         RFAddReader(reader_list[i].pcFriendlyname, reader_list[i].dwChannelId,
01402             reader_list[i].pcLibpath, reader_list[i].pcDevicename);
01403 
01404         /* update the ConfigFileCRC (this false "CRC" is very weak) */
01405         for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
01406             ConfigFileCRC += reader_list[i].pcFriendlyname[j];
01407         for (j=0; j<reader_list[i].pcLibpath[j]; j++)
01408             ConfigFileCRC += reader_list[i].pcLibpath[j];
01409         for (j=0; j<reader_list[i].pcDevicename[j]; j++)
01410             ConfigFileCRC += reader_list[i].pcDevicename[j];
01411 
01412         /* free strings allocated by DBGetReaderList() */
01413         free(reader_list[i].pcFriendlyname);
01414         free(reader_list[i].pcLibpath);
01415         free(reader_list[i].pcDevicename);
01416     }
01417     free(reader_list);
01418 
01419     return rv;
01420 }
01421 
01422 void RFReCheckReaderConf(void)
01423 {
01424     SerialReader *reader_list;
01425     int i, crc;
01426 
01427     DBGetReaderList(ConfigFile, &reader_list);
01428 
01429     /* the list is empty */
01430     if (NULL == reader_list)
01431         return;
01432 
01433     crc = 0;
01434     for (i=0; reader_list[i].pcFriendlyname; i++)
01435     {
01436         int j;
01437 
01438         /* calculate a local crc */
01439         for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
01440             crc += reader_list[i].pcFriendlyname[j];
01441         for (j=0; j<reader_list[i].pcLibpath[j]; j++)
01442             crc += reader_list[i].pcLibpath[j];
01443         for (j=0; j<reader_list[i].pcDevicename[j]; j++)
01444             crc += reader_list[i].pcDevicename[j];
01445     }
01446 
01447     /* cancel if the configuration file has been modified */
01448     if (crc != ConfigFileCRC)
01449     {
01450         Log2(PCSC_LOG_CRITICAL,
01451             "configuration file: %s has been modified. Recheck canceled",
01452             ConfigFile);
01453         return;
01454     }
01455 
01456     for (i=0; reader_list[i].pcFriendlyname; i++)
01457     {
01458         int r;
01459         char present = FALSE;
01460 
01461         Log2(PCSC_LOG_DEBUG, "refresh reader: %s",
01462             reader_list[i].pcFriendlyname);
01463 
01464         /* is the reader already present? */
01465         for (r = 0; r < PCSCLITE_MAX_READERS_CONTEXTS; r++)
01466         {
01467             if (sReadersContexts[r]->vHandle != 0)
01468             {
01469                 char lpcStripReader[MAX_READERNAME];
01470                 int tmplen;
01471 
01472                 /* get the reader name without the reader and slot numbers */
01473                 strncpy(lpcStripReader, sReadersContexts[i]->lpcReader,
01474                     sizeof(lpcStripReader));
01475                 tmplen = strlen(lpcStripReader);
01476                 lpcStripReader[tmplen - 6] = 0;
01477 
01478                 if ((strcmp(reader_list[i].pcFriendlyname, lpcStripReader) == 0)
01479                     && (reader_list[r].dwChannelId == sReadersContexts[i]->dwPort))
01480                 {
01481                     DWORD dwStatus = 0, dwAtrLen = 0;
01482                     UCHAR ucAtr[MAX_ATR_SIZE];
01483 
01484                     /* the reader was already started */
01485                     present = TRUE;
01486 
01487                     /* verify the reader is still connected */
01488                     if (IFDStatusICC(sReadersContexts[r], &dwStatus, ucAtr,
01489                         &dwAtrLen) != SCARD_S_SUCCESS)
01490                     {
01491                         Log2(PCSC_LOG_INFO, "Reader %s disappeared",
01492                             reader_list[i].pcFriendlyname);
01493                         RFRemoveReader(reader_list[i].pcFriendlyname,
01494                             reader_list[r].dwChannelId);
01495                     }
01496                 }
01497             }
01498         }
01499 
01500         /* the reader was not present */
01501         if (!present)
01502             /* we try to add it */
01503             RFAddReader(reader_list[i].pcFriendlyname,
01504                 reader_list[i].dwChannelId, reader_list[i].pcLibpath,
01505                 reader_list[i].pcDevicename);
01506 
01507         /* free strings allocated by DBGetReaderList() */
01508         free(reader_list[i].pcFriendlyname);
01509         free(reader_list[i].pcLibpath);
01510         free(reader_list[i].pcDevicename);
01511     }
01512     free(reader_list);
01513 }
01514 
01515 void RFSuspendAllReaders(void) 
01516 {
01517     int i;
01518 
01519     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01520     {
01521         if ((sReadersContexts[i])->vHandle != 0)
01522         {
01523             EHDestroyEventHandler(sReadersContexts[i]);
01524             IFDCloseIFD(sReadersContexts[i]);
01525         }
01526     }
01527 
01528 }
01529 
01530 void RFAwakeAllReaders(void) 
01531 {
01532     LONG rv = IFD_SUCCESS;
01533     int i;
01534     int initFlag;
01535         
01536     initFlag = 0;
01537 
01538     for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01539     {
01540         /* If the library is loaded and the event handler is not running */
01541         if ( ((sReadersContexts[i])->vHandle   != 0) &&
01542              ((sReadersContexts[i])->pthThread == 0) )
01543         {
01544             int j;
01545 
01546             for (j=0; j < i; j++)
01547             {
01548                 if (((sReadersContexts[j])->vHandle == (sReadersContexts[i])->vHandle)&&
01549                     ((sReadersContexts[j])->dwPort   == (sReadersContexts[i])->dwPort)) 
01550                 {
01551                     initFlag = 1;
01552                 }
01553             }
01554                         
01555             if (initFlag == 0)
01556                 rv = IFDOpenIFD(sReadersContexts[i]);
01557             else
01558                 initFlag = 0;
01559 
01560             if (rv != IFD_SUCCESS)
01561             {
01562                 Log3(PCSC_LOG_ERROR, "Open Port %X Failed (%s)",
01563                     (sReadersContexts[i])->dwPort, (sReadersContexts[i])->lpcDevice);
01564             }
01565 
01566 
01567             EHSpawnEventHandler(sReadersContexts[i]);
01568             RFSetReaderEventState(sReadersContexts[i], SCARD_RESET);
01569         }
01570     }
01571 }
01572 

Generated on Sat Jan 6 09:29:28 2007 for pcsc-lite by  doxygen 1.4.7