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