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

Generated on Tue Aug 14 13:59:18 2007 for pcsc-lite by  doxygen 1.5.2