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, READER_CONTEXT * rContext)
00896 {
00897 if (rContext->hLockId == 0 || rContext->hLockId == hCard)
00898 return SCARD_S_SUCCESS;
00899 else
00900 return SCARD_E_SHARING_VIOLATION;
00901 }
00902
00903 LONG RFLockSharing(SCARDHANDLE hCard, READER_CONTEXT * rContext)
00904 {
00905 LONG rv;
00906
00907 (void)pthread_mutex_lock(&LockMutex);
00908 rv = RFCheckSharing(hCard, rContext);
00909 if (SCARD_S_SUCCESS == rv)
00910 {
00911 rContext->LockCount += 1;
00912 rContext->hLockId = hCard;
00913 }
00914 (void)pthread_mutex_unlock(&LockMutex);
00915
00916 return rv;
00917 }
00918
00919 LONG RFUnlockSharing(SCARDHANDLE hCard, READER_CONTEXT * rContext)
00920 {
00921 LONG rv;
00922
00923 (void)pthread_mutex_lock(&LockMutex);
00924 rv = RFCheckSharing(hCard, rContext);
00925 if (SCARD_S_SUCCESS == rv)
00926 {
00927 if (rContext->LockCount > 0)
00928 rContext->LockCount -= 1;
00929 if (0 == rContext->LockCount)
00930 rContext->hLockId = 0;
00931 }
00932 (void)pthread_mutex_unlock(&LockMutex);
00933
00934 return rv;
00935 }
00936
00937 LONG RFUnlockAllSharing(SCARDHANDLE hCard, READER_CONTEXT * rContext)
00938 {
00939 LONG rv;
00940
00941 (void)pthread_mutex_lock(&LockMutex);
00942 rv = RFCheckSharing(hCard, rContext);
00943 if (SCARD_S_SUCCESS == rv)
00944 {
00945 rContext->LockCount = 0;
00946 rContext->hLockId = 0;
00947 }
00948 (void)pthread_mutex_unlock(&LockMutex);
00949
00950 return rv;
00951 }
00952
00953 LONG RFInitializeReader(READER_CONTEXT * rContext)
00954 {
00955 LONG rv;
00956
00957
00958 Log3(PCSC_LOG_INFO, "Attempting startup of %s using %s",
00959 rContext->lpcReader, rContext->lpcLibrary);
00960
00961 #ifndef PCSCLITE_STATIC_DRIVER
00962
00963 rv = RFLoadReader(rContext);
00964 if (rv != SCARD_S_SUCCESS)
00965 {
00966 Log2(PCSC_LOG_ERROR, "RFLoadReader failed: %X", rv);
00967 return rv;
00968 }
00969
00970
00971 rv = RFBindFunctions(rContext);
00972
00973 if (rv != SCARD_S_SUCCESS)
00974 {
00975 Log2(PCSC_LOG_ERROR, "RFBindFunctions failed: %X", rv);
00976 (void)RFUnloadReader(rContext);
00977 return rv;
00978 }
00979 #else
00980
00981 rContext->vHandle = RFInitializeReader;
00982 #endif
00983
00984
00985 rv = IFDOpenIFD(rContext);
00986
00987 if (rv != IFD_SUCCESS)
00988 {
00989 Log3(PCSC_LOG_CRITICAL, "Open Port %X Failed (%s)",
00990 rContext->port, rContext->lpcDevice);
00991 (void)RFUnBindFunctions(rContext);
00992 (void)RFUnloadReader(rContext);
00993 if (IFD_NO_SUCH_DEVICE == rv)
00994 return SCARD_E_UNKNOWN_READER;
00995 else
00996 return SCARD_E_INVALID_TARGET;
00997 }
00998
00999 return SCARD_S_SUCCESS;
01000 }
01001
01002 LONG RFUnInitializeReader(READER_CONTEXT * rContext)
01003 {
01004 Log2(PCSC_LOG_INFO, "Attempting shutdown of %s.",
01005 rContext->lpcReader);
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015 (void)IFDCloseIFD(rContext);
01016 (void)RFUnBindFunctions(rContext);
01017 (void)RFUnloadReader(rContext);
01018
01019 return SCARD_S_SUCCESS;
01020 }
01021
01022 SCARDHANDLE RFCreateReaderHandle(READER_CONTEXT * rContext)
01023 {
01024 USHORT randHandle;
01025
01026
01027
01028
01029
01030
01031 randHandle = SYS_RandomInt(10, 65000);
01032
01033 int i;
01034 again:
01035 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01036 {
01037 if ((sReadersContexts[i])->vHandle != 0)
01038 {
01039 RDR_CLIHANDLES *currentHandle;
01040 list_t * l = &((sReadersContexts[i])->handlesList);
01041
01042 (void)pthread_mutex_lock(&(sReadersContexts[i])->handlesList_lock);
01043 list_iterator_start(l);
01044 while (list_iterator_hasnext(l))
01045 {
01046 currentHandle = list_iterator_next(l);
01047 if ((rContext->dwIdentity + randHandle) ==
01048 (currentHandle->hCard))
01049 {
01050
01051 randHandle = SYS_RandomInt(10, 65000);
01052 list_iterator_stop(l);
01053 (void)pthread_mutex_unlock(&(sReadersContexts[i])->handlesList_lock);
01054 goto again;
01055 }
01056 }
01057 list_iterator_stop(l);
01058 (void)pthread_mutex_unlock(&(sReadersContexts[i])->handlesList_lock);
01059 }
01060 }
01061
01062
01063
01064 return rContext->dwIdentity + randHandle;
01065 }
01066
01067 LONG RFFindReaderHandle(SCARDHANDLE hCard)
01068 {
01069 int i;
01070
01071 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01072 {
01073 if ((sReadersContexts[i])->vHandle != 0)
01074 {
01075 RDR_CLIHANDLES * currentHandle;
01076 (void)pthread_mutex_lock(&(sReadersContexts[i])->handlesList_lock);
01077 currentHandle = list_seek(&((sReadersContexts[i])->handlesList),
01078 &hCard);
01079 (void)pthread_mutex_unlock(&(sReadersContexts[i])->handlesList_lock);
01080 if (currentHandle != NULL)
01081 return SCARD_S_SUCCESS;
01082 }
01083 }
01084
01085 return SCARD_E_INVALID_HANDLE;
01086 }
01087
01088 LONG RFDestroyReaderHandle( SCARDHANDLE hCard)
01089 {
01090 (void)hCard;
01091 return SCARD_S_SUCCESS;
01092 }
01093
01094 LONG RFAddReaderHandle(READER_CONTEXT * rContext, SCARDHANDLE hCard)
01095 {
01096 int listLength, lrv;
01097 RDR_CLIHANDLES *newHandle;
01098 LONG rv = SCARD_S_SUCCESS;
01099
01100 (void)pthread_mutex_lock(&rContext->handlesList_lock);
01101 listLength = list_size(&(rContext->handlesList));
01102
01103
01104 if (listLength >= maxReaderHandles)
01105 {
01106 Log2(PCSC_LOG_CRITICAL,
01107 "Too many handles opened, exceeding configured max (%d)",
01108 maxReaderHandles);
01109 rv = SCARD_E_NO_MEMORY;
01110 goto end;
01111 }
01112
01113 newHandle = malloc(sizeof(RDR_CLIHANDLES));
01114 if (NULL == newHandle)
01115 {
01116 Log1(PCSC_LOG_CRITICAL, "malloc failed");
01117 rv = SCARD_E_NO_MEMORY;
01118 goto end;
01119 }
01120
01121 newHandle->hCard = hCard;
01122 newHandle->dwEventStatus = 0;
01123
01124 lrv = list_append(&(rContext->handlesList), newHandle);
01125 if (lrv < 0)
01126 {
01127 free(newHandle);
01128 Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %X",
01129 lrv);
01130 rv = SCARD_E_NO_MEMORY;
01131 }
01132 end:
01133 (void)pthread_mutex_unlock(&rContext->handlesList_lock);
01134 return SCARD_S_SUCCESS;
01135 }
01136
01137 LONG RFRemoveReaderHandle(READER_CONTEXT * rContext, SCARDHANDLE hCard)
01138 {
01139 RDR_CLIHANDLES *currentHandle;
01140 int lrv;
01141 LONG rv = SCARD_S_SUCCESS;
01142
01143 (void)pthread_mutex_lock(&rContext->handlesList_lock);
01144 currentHandle = list_seek(&(rContext->handlesList), &hCard);
01145 if (NULL == currentHandle)
01146 {
01147 Log2(PCSC_LOG_CRITICAL, "list_seek failed to locate hCard=%X", hCard);
01148 rv = SCARD_E_INVALID_HANDLE;
01149 goto end;
01150 }
01151
01152 lrv = list_delete(&(rContext->handlesList), currentHandle);
01153 if (lrv < 0)
01154 Log2(PCSC_LOG_CRITICAL,
01155 "list_delete failed with return value: %X", lrv);
01156
01157 free(currentHandle);
01158
01159 end:
01160 (void)pthread_mutex_unlock(&rContext->handlesList_lock);
01161
01162
01163 return rv;
01164 }
01165
01166 LONG RFSetReaderEventState(READER_CONTEXT * rContext, DWORD dwEvent)
01167 {
01168
01169 int list_index, listSize;
01170 RDR_CLIHANDLES *currentHandle;
01171
01172 (void)pthread_mutex_lock(&rContext->handlesList_lock);
01173 listSize = list_size(&(rContext->handlesList));
01174
01175 for (list_index = 0; list_index < listSize; list_index++)
01176 {
01177 currentHandle = list_get_at(&(rContext->handlesList), list_index);
01178 if (NULL == currentHandle)
01179 {
01180 Log2(PCSC_LOG_CRITICAL, "list_get_at failed at index %s",
01181 list_index);
01182 continue;
01183 }
01184
01185 currentHandle->dwEventStatus = dwEvent;
01186 }
01187 (void)pthread_mutex_unlock(&rContext->handlesList_lock);
01188
01189 if (SCARD_REMOVED == dwEvent)
01190 {
01191
01192 rContext->hLockId = 0;
01193 rContext->LockCount = 0;
01194 }
01195
01196 return SCARD_S_SUCCESS;
01197 }
01198
01199 LONG RFCheckReaderEventState(READER_CONTEXT * rContext, SCARDHANDLE hCard)
01200 {
01201 LONG rv;
01202 RDR_CLIHANDLES *currentHandle;
01203
01204 (void)pthread_mutex_lock(&rContext->handlesList_lock);
01205 currentHandle = list_seek(&(rContext->handlesList), &hCard);
01206 (void)pthread_mutex_unlock(&rContext->handlesList_lock);
01207 if (NULL == currentHandle)
01208 {
01209
01210 Log2(PCSC_LOG_CRITICAL, "list_seek failed for hCard %X", hCard);
01211 return SCARD_E_INVALID_HANDLE;
01212 }
01213
01214 switch(currentHandle->dwEventStatus)
01215 {
01216 case 0:
01217 rv = SCARD_S_SUCCESS;
01218 break;
01219
01220 case SCARD_REMOVED:
01221 rv = SCARD_W_REMOVED_CARD;
01222 break;
01223
01224 case SCARD_RESET:
01225 rv = SCARD_W_RESET_CARD;
01226 break;
01227
01228 default:
01229 rv = SCARD_E_INVALID_VALUE;
01230 }
01231
01232 return rv;
01233 }
01234
01235 LONG RFClearReaderEventState(READER_CONTEXT * rContext, SCARDHANDLE hCard)
01236 {
01237 RDR_CLIHANDLES *currentHandle;
01238
01239 (void)pthread_mutex_lock(&rContext->handlesList_lock);
01240 currentHandle = list_seek(&(rContext->handlesList), &hCard);
01241 (void)pthread_mutex_unlock(&rContext->handlesList_lock);
01242 if (NULL == currentHandle)
01243
01244 return SCARD_E_INVALID_HANDLE;
01245
01246 currentHandle->dwEventStatus = 0;
01247
01248
01249
01250
01251 return SCARD_S_SUCCESS;
01252 }
01253
01254 LONG RFCheckReaderStatus(READER_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(void)
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
01281 lpcStripReader[strlen(lpcStripReader) - 6] = '\0';
01282
01283 rv = RFRemoveReader(lpcStripReader, sReadersContexts[i]->port);
01284
01285 if (rv != SCARD_S_SUCCESS)
01286 Log2(PCSC_LOG_ERROR, "RFRemoveReader error: 0x%08X", rv);
01287 }
01288 }
01289 }
01290
01291 #ifdef USE_SERIAL
01292 int RFStartSerialReaders(const char *readerconf)
01293 {
01294 SerialReader *reader_list = NULL;
01295 int i, rv;
01296
01297
01298 ConfigFile = strdup(readerconf);
01299
01300 rv = DBGetReaderListDir(readerconf, &reader_list);
01301
01302
01303 if (NULL == reader_list)
01304 return rv;
01305
01306 for (i=0; reader_list[i].pcFriendlyname; i++)
01307 {
01308 int j;
01309
01310 (void)RFAddReader(reader_list[i].pcFriendlyname,
01311 reader_list[i].channelId,
01312 reader_list[i].pcLibpath, reader_list[i].pcDevicename);
01313
01314
01315 for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
01316 ConfigFileCRC += reader_list[i].pcFriendlyname[j];
01317 for (j=0; j<reader_list[i].pcLibpath[j]; j++)
01318 ConfigFileCRC += reader_list[i].pcLibpath[j];
01319 for (j=0; j<reader_list[i].pcDevicename[j]; j++)
01320 ConfigFileCRC += reader_list[i].pcDevicename[j];
01321
01322
01323 free(reader_list[i].pcFriendlyname);
01324 free(reader_list[i].pcLibpath);
01325 free(reader_list[i].pcDevicename);
01326 }
01327 free(reader_list);
01328
01329 return rv;
01330 }
01331
01332 void RFReCheckReaderConf(void)
01333 {
01334 SerialReader *reader_list = NULL;
01335 int i, crc;
01336
01337 (void)DBGetReaderListDir(ConfigFile, &reader_list);
01338
01339
01340 if (NULL == reader_list)
01341 return;
01342
01343 crc = 0;
01344 for (i=0; reader_list[i].pcFriendlyname; i++)
01345 {
01346 int j;
01347
01348
01349 for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
01350 crc += reader_list[i].pcFriendlyname[j];
01351 for (j=0; j<reader_list[i].pcLibpath[j]; j++)
01352 crc += reader_list[i].pcLibpath[j];
01353 for (j=0; j<reader_list[i].pcDevicename[j]; j++)
01354 crc += reader_list[i].pcDevicename[j];
01355 }
01356
01357
01358 if (crc != ConfigFileCRC)
01359 {
01360 Log2(PCSC_LOG_CRITICAL,
01361 "configuration file: %s has been modified. Recheck canceled",
01362 ConfigFile);
01363 return;
01364 }
01365
01366 for (i=0; reader_list[i].pcFriendlyname; i++)
01367 {
01368 int r;
01369 char present = FALSE;
01370
01371 Log2(PCSC_LOG_DEBUG, "refresh reader: %s",
01372 reader_list[i].pcFriendlyname);
01373
01374
01375 for (r = 0; r < PCSCLITE_MAX_READERS_CONTEXTS; r++)
01376 {
01377 if (sReadersContexts[r]->vHandle != 0)
01378 {
01379 char lpcStripReader[MAX_READERNAME];
01380 int tmplen;
01381
01382
01383 strncpy(lpcStripReader, sReadersContexts[i]->lpcReader,
01384 sizeof(lpcStripReader));
01385 tmplen = strlen(lpcStripReader);
01386 lpcStripReader[tmplen - 6] = 0;
01387
01388 if ((strcmp(reader_list[i].pcFriendlyname, lpcStripReader) == 0)
01389 && (reader_list[r].channelId == sReadersContexts[i]->port))
01390 {
01391 DWORD dwStatus = 0, dwAtrLen = 0;
01392 UCHAR ucAtr[MAX_ATR_SIZE];
01393
01394
01395 present = TRUE;
01396
01397
01398 if (IFDStatusICC(sReadersContexts[r], &dwStatus, ucAtr,
01399 &dwAtrLen) != SCARD_S_SUCCESS)
01400 {
01401 Log2(PCSC_LOG_INFO, "Reader %s disappeared",
01402 reader_list[i].pcFriendlyname);
01403 (void)RFRemoveReader(reader_list[i].pcFriendlyname,
01404 reader_list[r].channelId);
01405 }
01406 }
01407 }
01408 }
01409
01410
01411 if (!present)
01412
01413 (void)RFAddReader(reader_list[i].pcFriendlyname,
01414 reader_list[i].channelId, reader_list[i].pcLibpath,
01415 reader_list[i].pcDevicename);
01416
01417
01418 free(reader_list[i].pcFriendlyname);
01419 free(reader_list[i].pcLibpath);
01420 free(reader_list[i].pcDevicename);
01421 }
01422 free(reader_list);
01423 }
01424 #endif
01425
01426 #if 0
01427 void RFSuspendAllReaders(void)
01428 {
01429 int i;
01430
01431 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01432 {
01433 if ((sReadersContexts[i])->vHandle != 0)
01434 {
01435 (void)EHDestroyEventHandler(sReadersContexts[i]);
01436 (void)IFDCloseIFD(sReadersContexts[i]);
01437 }
01438 }
01439 }
01440
01441 void RFAwakeAllReaders(void)
01442 {
01443 LONG rv = IFD_SUCCESS;
01444 int i;
01445 int initFlag;
01446
01447 initFlag = 0;
01448
01449 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01450 {
01451
01452 if ( ((sReadersContexts[i])->vHandle != 0) &&
01453 ((sReadersContexts[i])->pthThread == 0) )
01454 {
01455 int j;
01456
01457 for (j=0; j < i; j++)
01458 {
01459 if (((sReadersContexts[j])->vHandle == (sReadersContexts[i])->vHandle)&&
01460 ((sReadersContexts[j])->port == (sReadersContexts[i])->port))
01461 {
01462 initFlag = 1;
01463 }
01464 }
01465
01466 if (initFlag == 0)
01467 rv = IFDOpenIFD(sReadersContexts[i]);
01468 else
01469 initFlag = 0;
01470
01471 if (rv != IFD_SUCCESS)
01472 {
01473 Log3(PCSC_LOG_ERROR, "Open Port %X Failed (%s)",
01474 (sReadersContexts[i])->port, (sReadersContexts[i])->lpcDevice);
01475 }
01476
01477 (void)EHSpawnEventHandler(sReadersContexts[i], NULL);
01478 (void)RFSetReaderEventState(sReadersContexts[i], SCARD_RESET);
01479 }
01480 }
01481 }
01482 #endif
01483