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

Generated on Mon Aug 17 01:00:11 2009 for pcsc-lite by  doxygen 1.5.9