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

Generated on Wed Jul 14 18:43:52 2010 for pcsc-lite by  doxygen 1.4.7