pcsc-lite 1.6.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-2010 00009 * Ludovic Rousseau <ludovic.rousseau@free.fr> 00010 * Copyright (C) 2009 00011 * Jean-Luc Giraud <jlgiraud@googlemail.com> 00012 * 00013 * $Id: readerfactory.c 5070 2010-07-26 13:27:51Z 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 "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; /* Counter */ 00081 00082 if (customMaxReaderHandles != 0) 00083 maxReaderHandles = customMaxReaderHandles; 00084 00085 /* Allocate each reader structure */ 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 /* Create public event structures */ 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 /* Reader name too long? also count " 00 00"*/ 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 /* Same name, same port - duplicate reader cannot be used */ 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 /* get the reader name without the reader and slot numbers */ 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 /* We must find an empty slot to put the reader structure */ 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 /* No more spots left return */ 00155 return SCARD_E_NO_MEMORY; 00156 } 00157 00158 /* Check and set the readername to see if it must be enumerated */ 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 /* If a clone to this reader exists take some values from that clone */ 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 /* Call on the parent driver to see if it is thread safe */ 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 /* Initialize pFeeds to 1, otherwise multiple 00232 cloned readers will cause pcscd to crash when 00233 RFUnloadReader unloads the driver library 00234 and there are still devices attached using it --mikeg*/ 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 /* Cannot connect to reader. Exit gracefully */ 00257 Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader); 00258 (void)RFRemoveReader(lpcReader, port); 00259 return rv; 00260 } 00261 00262 /* asynchronous card movement? */ 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 /* Call on the driver to see if there are multiple slots */ 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 /* Reader does not have this defined. Must be a single slot 00294 * reader so we can just return SCARD_S_SUCCESS. */ 00295 return SCARD_S_SUCCESS; 00296 00297 if (rv == IFD_SUCCESS && dwGetSize == 1 && ucGetData[0] == 1) 00298 /* Reader has this defined and it only has one slot */ 00299 return SCARD_S_SUCCESS; 00300 00301 /* 00302 * Check the number of slots and create a different 00303 * structure for each one accordingly 00304 */ 00305 00306 /* Initialize the rest of the slots */ 00307 for (j = 1; j < ucGetData[0]; j++) 00308 { 00309 char *tmpReader = NULL; 00310 DWORD dwContextB = 0; 00311 RESPONSECODE (*fct)(DWORD) = NULL; 00312 00313 /* We must find an empty spot to put the reader structure */ 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 /* No more slot left return */ 00326 rv = RFRemoveReader(lpcReader, port); 00327 return SCARD_E_NO_MEMORY; 00328 } 00329 00330 /* Copy the previous reader name and increment the slot number */ 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 * Added by Dave - slots did not have a pFeeds 00355 * parameter so it was by luck they were working 00356 */ 00357 (sReadersContexts[dwContextB])->pFeeds = 00358 (sReadersContexts[dwContext])->pFeeds; 00359 00360 /* Added by Dave for multiple slots */ 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 /* Call on the parent driver to see if the slots are thread safe */ 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 /* Cannot connect to slot. Exit gracefully */ 00412 (void)RFRemoveReader(lpcReader, port); 00413 return rv; 00414 } 00415 00416 /* asynchronous card movement? */ 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 /* Try to destroy the thread */ 00454 rv = EHDestroyEventHandler(sContext); 00455 00456 rv = RFUnInitializeReader(sContext); 00457 if (rv != SCARD_S_SUCCESS) 00458 return rv; 00459 00460 /* Destroy and free the mutex */ 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 /* free shared resources when the last slot is closed */ 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 /* Added by Dave to free the pFeeds variable */ 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 /* signal an event to clients */ 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; /* reader number of the parent of the clone */ 00530 DWORD valueLength; 00531 int currentDigit = -1; 00532 int supportedChannels = 0; 00533 int usedDigits[PCSCLITE_MAX_READERS_CONTEXTS]; 00534 int i; 00535 00536 /* Clear the list */ 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 /* Ask the driver if it supports multiple channels */ 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 /* Check to see if it is a hotplug reader and different */ 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 * tells the caller who the parent of this 00577 * clone is so it can use it's shared 00578 * resources like mutex/etc. 00579 */ 00580 parent = i; 00581 00582 /* 00583 * If the same reader already exists and it is 00584 * hotplug then we must look for others and 00585 * enumerate the readername 00586 */ 00587 currentDigit = strtol(lpcReader + strlen(lpcReader) - 5, NULL, 16); 00588 00589 /* This spot is taken */ 00590 usedDigits[currentDigit] = TRUE; 00591 } 00592 } 00593 } 00594 } 00595 } 00596 00597 /* default value */ 00598 i = 0; 00599 00600 /* Other identical readers exist on the same bus */ 00601 if (currentDigit != -1) 00602 { 00603 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++) 00604 { 00605 /* get the first free digit */ 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 /* Set the slot in 0xDDDDCCCC */ 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 /* Strip off the lower nibble and get the identity */ 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 /* Another reader exists with this library loaded */ 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 * Use this function as a dummy to determine the IFD Handler version 00725 * type 1.0/2.0/3.0. Suppress error messaging since it can't be 1.0, 00726 * 2.0 and 3.0. 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 /* Neither version of the IFD Handler was found - exit */ 00740 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing"); 00741 00742 return SCARD_F_UNKNOWN_ERROR; 00743 } else if (rv1 == SCARD_S_SUCCESS) 00744 { 00745 /* Ifd Handler 1.0 found */ 00746 rContext->version = IFD_HVERSION_1_0; 00747 } else if (rv3 == SCARD_S_SUCCESS) 00748 { 00749 /* Ifd Handler 3.0 found */ 00750 rContext->version = IFD_HVERSION_3_0; 00751 } 00752 else 00753 { 00754 /* Ifd Handler 2.0 found */ 00755 rContext->version = IFD_HVERSION_2_0; 00756 } 00757 00758 /* The following binds version 1.0 of the IFD Handler specs */ 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 /* The following binds version 2.0 of the IFD Handler specs */ 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 /* The following binds version 3.0 of the IFD Handler specs */ 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 /* Who knows what could have happenned for it to get here. */ 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 /* Zero out everything */ 00876 memset(&rContext->psFunctions, 0, sizeof(rContext->psFunctions)); 00877 00878 return SCARD_S_SUCCESS; 00879 } 00880 00881 LONG RFUnloadReader(READER_CONTEXT * rContext) 00882 { 00883 /* Make sure no one else is using this library */ 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 /* Spawn the event handler thread */ 00958 Log3(PCSC_LOG_INFO, "Attempting startup of %s using %s", 00959 rContext->lpcReader, rContext->lpcLibrary); 00960 00961 #ifndef PCSCLITE_STATIC_DRIVER 00962 /* loads the library */ 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 /* binds the functions */ 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 /* define a fake vHandle. Can be any value except NULL */ 00981 rContext->vHandle = RFInitializeReader; 00982 #endif 00983 00984 /* tries to open the port */ 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 /* Close the port, unbind the functions, and unload the library */ 01008 01009 /* 01010 * If the reader is getting uninitialized then it is being unplugged 01011 * so I can't send a IFDPowerICC call to it 01012 * 01013 * IFDPowerICC( rContext, IFD_POWER_DOWN, Atr, &AtrLen ); 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 /* Create a random handle with 16 bits check to see if it already is 01027 * used. */ 01028 /* FIXME: THIS IS NOT STRONG ENOUGH: A 128-bit token should be 01029 * generated. The client and server would associate token and hCard 01030 * for authentication. */ 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 /* Get a new handle and loop again */ 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 /* Once the for loop is completed w/o restart a good handle was 01063 * found and the loop can be exited. */ 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(/*@unused@*/ 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 /* Throttle the number of possible handles */ 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 /* Not Found */ 01163 return rv; 01164 } 01165 01166 LONG RFSetReaderEventState(READER_CONTEXT * rContext, DWORD dwEvent) 01167 { 01168 /* Set all the handles for that reader to the event */ 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 /* unlock the card */ 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 /* Not Found */ 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 /* Not Found */ 01244 return SCARD_E_INVALID_HANDLE; 01245 01246 currentHandle->dwEventStatus = 0; 01247 01248 /* hCards should be unique so we 01249 * should be able to return 01250 * as soon as we have a hit */ 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 /* strip the 6 last char ' 00 00' */ 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 /* remember the configuration filename for RFReCheckReaderConf() */ 01298 ConfigFile = strdup(readerconf); 01299 01300 rv = DBGetReaderListDir(readerconf, &reader_list); 01301 01302 /* the list is empty */ 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 /* update the ConfigFileCRC (this false "CRC" is very weak) */ 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 /* free strings allocated by DBGetReaderListDir() */ 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 /* the list is empty */ 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 /* calculate a local crc */ 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 /* cancel if the configuration file has been modified */ 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 /* is the reader already present? */ 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 /* get the reader name without the reader and slot numbers */ 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 /* the reader was already started */ 01395 present = TRUE; 01396 01397 /* verify the reader is still connected */ 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 /* the reader was not present */ 01411 if (!present) 01412 /* we try to add it */ 01413 (void)RFAddReader(reader_list[i].pcFriendlyname, 01414 reader_list[i].channelId, reader_list[i].pcLibpath, 01415 reader_list[i].pcDevicename); 01416 01417 /* free strings allocated by DBGetReaderListDir() */ 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 /* If the library is loaded and the event handler is not running */ 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