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