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