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

Generated on Wed Jul 22 23:13:21 2009 for pcsc-lite by  doxygen 1.5.8