47 #include <sys/types.h> 63 #include "configfile.h" 73 static int maxReaderHandles = PCSC_MAX_READER_HANDLES;
74 static DWORD dwNumReadersContexts = 0;
76 static char *ConfigFile = NULL;
77 static int ConfigFileCRC = 0;
79 static pthread_mutex_t LockMutex = PTHREAD_MUTEX_INITIALIZER;
81 #define IDENTITY_SHIFT 16 84 static int RDR_CLIHANDLES_seeker(
const void *el,
const void *key)
88 if ((el == NULL) || (key == NULL))
90 Log3(PCSC_LOG_CRITICAL,
91 "RDR_CLIHANDLES_seeker called with NULL pointer: el=%p, key=%p",
125 removeReader(sReader);
130 LONG RFAllocateReaderSpace(
unsigned int customMaxReaderHandles)
134 if (customMaxReaderHandles != 0)
135 maxReaderHandles = customMaxReaderHandles;
141 sReadersContexts[i]->
vHandle = NULL;
144 memset(readerStates[i].readerName, 0, MAX_READERNAME);
152 sReadersContexts[i]->
readerState = &readerStates[i];
156 return EHInitializeEventStructures();
159 LONG RFAddReader(
const char *readerNameLong,
int port,
const char *library,
162 DWORD dwContext = 0, dwGetSize;
163 UCHAR ucGetData[1], ucThread[1];
167 char *readerName = NULL;
169 if ((readerNameLong == NULL) || (library == NULL) || (device == NULL))
173 const char *ro_filter = getenv(
"PCSCLITE_FILTER_IGNORE_READER_NAMES");
179 filter = alloca(strlen(ro_filter)+1);
180 strcpy(filter, ro_filter);
185 next = strchr(filter,
':');
193 if (*filter && strstr(readerNameLong, filter))
196 "Reader name \"%s\" contains \"%s\": ignored",
197 readerNameLong, filter);
212 readerName = alloca(strlen(readerNameLong)+1);
213 strcpy(readerName, readerNameLong);
216 if (strlen(readerName) > MAX_READERNAME -
sizeof(
" 00 00"))
219 "Reader name too long: %zd chars instead of max %zd. Truncating!",
220 strlen(readerName), MAX_READERNAME -
sizeof(
" 00 00"));
221 readerName[MAX_READERNAME -
sizeof(
" 00 00")] =
'\0';
225 if (dwNumReadersContexts != 0)
229 if (sReadersContexts[i]->vHandle != 0)
231 char lpcStripReader[MAX_READERNAME];
235 strncpy(lpcStripReader,
236 sReadersContexts[i]->readerState->readerName,
237 sizeof(lpcStripReader));
238 tmplen = strlen(lpcStripReader);
239 lpcStripReader[tmplen - 6] = 0;
241 if ((strcmp(readerName, lpcStripReader) == 0) &&
242 (port == sReadersContexts[i]->port))
244 Log1(PCSC_LOG_ERROR,
"Duplicate reader found.");
254 if (sReadersContexts[i]->vHandle == 0)
261 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
268 parentNode = RFSetReaderName(sReadersContexts[dwContext], readerName,
273 sReadersContexts[dwContext]->
library = strdup(library);
274 sReadersContexts[dwContext]->
device = strdup(device);
275 sReadersContexts[dwContext]->
version = 0;
276 sReadersContexts[dwContext]->
port = port;
277 sReadersContexts[dwContext]->
mMutex = NULL;
278 sReadersContexts[dwContext]->
contexts = 0;
279 sReadersContexts[dwContext]->
pthThread = 0;
280 sReadersContexts[dwContext]->
hLockId = 0;
281 sReadersContexts[dwContext]->
LockCount = 0;
282 sReadersContexts[dwContext]->
vHandle = NULL;
283 sReadersContexts[dwContext]->
pFeeds = NULL;
284 sReadersContexts[dwContext]->
pMutex = NULL;
287 lrv = list_init(&sReadersContexts[dwContext]->handlesList);
290 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d", lrv);
294 lrv = list_attributes_seeker(&sReadersContexts[dwContext]->handlesList,
295 RDR_CLIHANDLES_seeker);
298 Log2(PCSC_LOG_CRITICAL,
299 "list_attributes_seeker failed with return value: %d", lrv);
303 (void)pthread_mutex_init(&sReadersContexts[dwContext]->handlesList_lock,
306 (void)pthread_mutex_init(&sReadersContexts[dwContext]->powerState_lock,
311 (void)pthread_mutex_init(&sReadersContexts[dwContext]->reference_lock,
313 sReadersContexts[dwContext]->
reference = 1;
316 if (parentNode >= 0 && parentNode < PCSCLITE_MAX_READERS_CONTEXTS)
318 sReadersContexts[dwContext]->
pFeeds =
319 sReadersContexts[parentNode]->
pFeeds;
320 *(sReadersContexts[dwContext])->pFeeds += 1;
321 sReadersContexts[dwContext]->
vHandle =
322 sReadersContexts[parentNode]->
vHandle;
323 sReadersContexts[dwContext]->
mMutex =
324 sReadersContexts[parentNode]->
mMutex;
325 sReadersContexts[dwContext]->
pMutex =
326 sReadersContexts[parentNode]->
pMutex;
329 dwGetSize =
sizeof(ucThread);
333 if (rv ==
IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
335 Log1(PCSC_LOG_INFO,
"Driver is thread safe");
336 sReadersContexts[dwContext]->
mMutex = NULL;
337 sReadersContexts[dwContext]->
pMutex = NULL;
340 *(sReadersContexts[dwContext])->pMutex += 1;
343 if (sReadersContexts[dwContext]->pFeeds == NULL)
345 sReadersContexts[dwContext]->
pFeeds = malloc(
sizeof(
int));
351 *(sReadersContexts[dwContext])->pFeeds = 1;
354 if (sReadersContexts[dwContext]->mMutex == 0)
356 sReadersContexts[dwContext]->
mMutex =
357 malloc(
sizeof(pthread_mutex_t));
358 (void)pthread_mutex_init(sReadersContexts[dwContext]->mMutex, NULL);
361 if (sReadersContexts[dwContext]->pMutex == NULL)
363 sReadersContexts[dwContext]->
pMutex = malloc(
sizeof(
int));
364 *(sReadersContexts[dwContext])->pMutex = 1;
367 dwNumReadersContexts += 1;
369 rv = RFInitializeReader(sReadersContexts[dwContext]);
373 Log2(PCSC_LOG_ERROR,
"%s init failed.", readerName);
374 (void)RFRemoveReader(readerName, port);
380 RESPONSECODE (*fct)(DWORD, int) = NULL;
382 dwGetSize =
sizeof(fct);
388 Log1(PCSC_LOG_INFO,
"Using the pcscd polling thread");
393 Log1(PCSC_LOG_INFO,
"Using the reader polling thread");
396 rv = EHSpawnEventHandler(sReadersContexts[dwContext]);
399 Log2(PCSC_LOG_ERROR,
"%s init failed.", readerName);
400 (void)RFRemoveReader(readerName, port);
406 dwGetSize =
sizeof(ucGetData);
410 if (rv !=
IFD_SUCCESS || dwGetSize != 1 || ucGetData[0] == 0)
415 if (rv ==
IFD_SUCCESS && dwGetSize == 1 && ucGetData[0] == 1)
425 for (j = 1; j < ucGetData[0]; j++)
427 char *tmpReader = NULL;
428 DWORD dwContextB = 0;
429 RESPONSECODE (*fct)(DWORD, int) = NULL;
434 if (sReadersContexts[i]->vHandle == 0)
441 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
444 RFRemoveReader(readerName, port);
451 sReadersContexts[dwContext]->readerState->readerName,
453 snprintf(tmpReader + strlen(tmpReader) - 2, 3,
"%02X", j);
455 sReadersContexts[dwContextB]->
library =
456 sReadersContexts[dwContext]->
library;
457 sReadersContexts[dwContextB]->
device =
458 sReadersContexts[dwContext]->
device;
459 sReadersContexts[dwContextB]->
version =
460 sReadersContexts[dwContext]->
version;
461 sReadersContexts[dwContextB]->
port =
462 sReadersContexts[dwContext]->
port;
463 sReadersContexts[dwContextB]->
vHandle =
464 sReadersContexts[dwContext]->
vHandle;
465 sReadersContexts[dwContextB]->
mMutex =
466 sReadersContexts[dwContext]->
mMutex;
467 sReadersContexts[dwContextB]->
pMutex =
468 sReadersContexts[dwContext]->
pMutex;
469 sReadersContexts[dwContextB]->
slot =
470 sReadersContexts[dwContext]->
slot + j;
477 sReadersContexts[dwContextB]->
pFeeds =
478 sReadersContexts[dwContext]->
pFeeds;
481 *(sReadersContexts[dwContextB])->pFeeds += 1;
483 sReadersContexts[dwContextB]->
contexts = 0;
484 sReadersContexts[dwContextB]->
hLockId = 0;
485 sReadersContexts[dwContextB]->
LockCount = 0;
487 lrv = list_init(&sReadersContexts[dwContextB]->handlesList);
490 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d", lrv);
494 lrv = list_attributes_seeker(&sReadersContexts[dwContextB]->handlesList,
495 RDR_CLIHANDLES_seeker);
498 Log2(PCSC_LOG_CRITICAL,
499 "list_attributes_seeker failed with return value: %d", lrv);
503 (void)pthread_mutex_init(&sReadersContexts[dwContextB]->handlesList_lock, NULL);
504 (void)pthread_mutex_init(&sReadersContexts[dwContextB]->powerState_lock,
509 (void)pthread_mutex_init(&sReadersContexts[dwContextB]->reference_lock,
511 sReadersContexts[dwContextB]->
reference = 1;
514 dwGetSize =
sizeof(ucThread);
518 if (rv ==
IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
520 Log1(PCSC_LOG_INFO,
"Driver is slot thread safe");
522 sReadersContexts[dwContextB]->
library =
523 strdup(sReadersContexts[dwContext]->library);
524 sReadersContexts[dwContextB]->
device =
525 strdup(sReadersContexts[dwContext]->device);
526 sReadersContexts[dwContextB]->
mMutex =
527 malloc(
sizeof(pthread_mutex_t));
528 (void)pthread_mutex_init(sReadersContexts[dwContextB]->mMutex,
531 sReadersContexts[dwContextB]->
pMutex = malloc(
sizeof(
int));
532 *(sReadersContexts[dwContextB])->pMutex = 1;
535 *(sReadersContexts[dwContextB])->pMutex += 1;
537 dwNumReadersContexts += 1;
539 rv = RFInitializeReader(sReadersContexts[dwContextB]);
543 (void)RFRemoveReader(readerName, port);
548 dwGetSize =
sizeof(fct);
554 Log1(PCSC_LOG_INFO,
"Using the pcscd polling thread");
559 Log1(PCSC_LOG_INFO,
"Using the reader polling thread");
562 rv = EHSpawnEventHandler(sReadersContexts[dwContextB]);
565 Log2(PCSC_LOG_ERROR,
"%s init failed.", readerName);
566 (void)RFRemoveReader(readerName, port);
574 LONG RFRemoveReader(
const char *readerName,
int port)
576 char lpcStripReader[MAX_READERNAME];
583 if (readerName == NULL)
587 extend = getenv(
"PCSCLITE_FILTER_EXTEND_READER_NAMES");
589 extend_size = strlen(extend);
594 if (sReadersContexts[i]->vHandle != 0)
596 strncpy(lpcStripReader,
597 sReadersContexts[i]->readerState->readerName,
598 sizeof(lpcStripReader));
599 lpcStripReader[strlen(lpcStripReader) - 6 - extend_size] = 0;
602 if ((strncmp(readerName, lpcStripReader, MAX_READERNAME -
sizeof(
" 00 00")) == 0)
603 && (port == sReadersContexts[i]->port))
606 UNREF_READER(sReadersContexts[i])
620 if (sContext -> pthThread)
621 (void)EHDestroyEventHandler(sContext);
623 if ((NULL == sContext->
pMutex) || (NULL == sContext->
pFeeds))
626 "Trying to remove an already removed driver");
630 rv = RFUnInitializeReader(sContext);
637 if (0 == *sContext->
pMutex)
639 (void)pthread_mutex_destroy(sContext->
mMutex);
651 if (*sContext->
pFeeds == 0)
667 while (list_size(&sContext->handlesList) != 0)
672 currentHandle = list_get_at(&sContext->handlesList, 0);
673 lrv = list_delete_at(&sContext->handlesList, 0);
675 Log2(PCSC_LOG_CRITICAL,
676 "list_delete_at failed with return value: %d", lrv);
682 list_destroy(&sContext->handlesList);
683 dwNumReadersContexts -= 1;
692 LONG RFSetReaderName(
READER_CONTEXT * rContext,
const char *readerName,
693 const char *libraryName,
int port)
697 int currentDigit = -1;
698 int supportedChannels = 0;
701 const char *extend =
"";
705 usedDigits[i] = FALSE;
707 if (dwNumReadersContexts != 0)
711 if (sReadersContexts[i]->vHandle != 0)
713 if (strcmp(sReadersContexts[i]->library, libraryName) == 0)
719 valueLength =
sizeof(tagValue);
722 &valueLength, tagValue);
727 supportedChannels = tagValue[0];
729 "Support %d simultaneous readers", tagValue[0]);
732 supportedChannels = 1;
735 if ((((sReadersContexts[i]->port & 0xFFFF0000) ==
736 PCSCLITE_HP_BASE_PORT)
737 && (sReadersContexts[i]->port != port))
738 || (supportedChannels > 1))
754 currentDigit = strtol(reader + strlen(reader) - 5, NULL, 16);
757 usedDigits[currentDigit] = TRUE;
768 if (currentDigit != -1)
773 if (usedDigits[i] == FALSE)
777 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
779 Log2(PCSC_LOG_ERROR,
"Max number of readers reached: %d", PCSCLITE_MAX_READERS_CONTEXTS);
783 if (i >= supportedChannels)
785 Log3(PCSC_LOG_ERROR,
"Driver %s does not support more than " 786 "%d reader(s). Maybe the driver should support " 787 "TAG_IFD_SIMULTANEOUS_ACCESS", libraryName, supportedChannels);
793 extend = getenv(
"PCSCLITE_FILTER_EXTEND_READER_NAMES");
800 readerName, extend, i);
803 rContext->
slot = i << 16;
808 LONG RFReaderInfo(
const char *readerName,
READER_CONTEXT ** sReader)
812 if (readerName == NULL)
817 if (sReadersContexts[i]->vHandle != 0)
819 if (strcmp(readerName,
820 sReadersContexts[i]->readerState->readerName) == 0)
823 REF_READER(sReadersContexts[i])
825 *sReader = sReadersContexts[i];
840 if (sReadersContexts[i]->vHandle != 0)
843 (void)pthread_mutex_lock(&sReadersContexts[i]->handlesList_lock);
844 currentHandle = list_seek(&sReadersContexts[i]->handlesList,
846 (void)pthread_mutex_unlock(&sReadersContexts[i]->handlesList_lock);
847 if (currentHandle != NULL)
850 REF_READER(sReadersContexts[i])
852 *sReader = sReadersContexts[i];
865 Log2(PCSC_LOG_INFO,
"Reusing already loaded driver for %s",
879 rv = DYN_GetAddress(rContext->
vHandle, &f,
"IFDHCreateChannelByName", TRUE);
883 rContext->
version = IFD_HVERSION_3_0;
887 rv = DYN_GetAddress(rContext->
vHandle, &f,
"IFDHCreateChannel", FALSE);
891 rContext->
version = IFD_HVERSION_2_0;
896 Log1(PCSC_LOG_CRITICAL,
"IFDHandler functions missing");
901 if (rContext->
version == IFD_HVERSION_2_0)
904 #define GET_ADDRESS_OPTIONALv2(s, code) \ 907 int rvl = DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s, FALSE); \ 908 if (SCARD_S_SUCCESS != rvl) \ 912 rContext->psFunctions.psFunctions_v2.pvf ## s = f1; \ 915 #define GET_ADDRESSv2(s) \ 916 GET_ADDRESS_OPTIONALv2(s, \ 917 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \ 920 Log1(PCSC_LOG_INFO,
"Loading IFD Handler 2.0");
922 GET_ADDRESSv2(CreateChannel)
923 GET_ADDRESSv2(CloseChannel)
924 GET_ADDRESSv2(GetCapabilities)
925 GET_ADDRESSv2(SetCapabilities)
926 GET_ADDRESSv2(PowerICC)
927 GET_ADDRESSv2(TransmitToICC)
928 GET_ADDRESSv2(ICCPresence)
929 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
931 GET_ADDRESSv2(Control)
933 else if (rContext->version == IFD_HVERSION_3_0)
936 #define GET_ADDRESS_OPTIONALv3(s, code) \ 939 int rvl = DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s, FALSE); \ 940 if (SCARD_S_SUCCESS != rvl) \ 944 rContext->psFunctions.psFunctions_v3.pvf ## s = f1; \ 947 #define GET_ADDRESSv3(s) \ 948 GET_ADDRESS_OPTIONALv3(s, \ 949 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \ 952 Log1(PCSC_LOG_INFO,
"Loading IFD Handler 3.0");
954 GET_ADDRESSv2(CreateChannel)
955 GET_ADDRESSv2(CloseChannel)
956 GET_ADDRESSv2(GetCapabilities)
957 GET_ADDRESSv2(SetCapabilities)
958 GET_ADDRESSv2(PowerICC)
959 GET_ADDRESSv2(TransmitToICC)
960 GET_ADDRESSv2(ICCPresence)
961 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
963 GET_ADDRESSv3(CreateChannelByName)
964 GET_ADDRESSv3(Control)
969 Log1(PCSC_LOG_CRITICAL,
"IFD Handler not 1.0/2.0 or 3.0");
987 if (*rContext->
pFeeds == 1)
989 Log1(PCSC_LOG_INFO,
"Unloading reader driver.");
990 (void)DYN_CloseLibrary(&rContext->
vHandle);
1010 (void)pthread_mutex_lock(&LockMutex);
1011 rv = RFCheckSharing(hCard, rContext);
1017 (void)pthread_mutex_unlock(&LockMutex);
1026 (void)pthread_mutex_lock(&LockMutex);
1027 rv = RFCheckSharing(hCard, rContext);
1050 (void)pthread_mutex_unlock(&LockMutex);
1059 (void)pthread_mutex_lock(&LockMutex);
1060 rv = RFCheckSharing(hCard, rContext);
1066 (void)pthread_mutex_unlock(&LockMutex);
1076 Log3(PCSC_LOG_INFO,
"Attempting startup of %s using %s",
1079 #ifndef PCSCLITE_STATIC_DRIVER 1081 rv = RFLoadReader(rContext);
1084 Log2(PCSC_LOG_ERROR,
"RFLoadReader failed: 0x%lX", rv);
1089 rv = RFBindFunctions(rContext);
1093 Log2(PCSC_LOG_ERROR,
"RFBindFunctions failed: 0x%lX", rv);
1094 (void)RFUnloadReader(rContext);
1099 rContext->
vHandle = RFInitializeReader;
1107 Log3(PCSC_LOG_CRITICAL,
"Open Port 0x%X Failed (%s)",
1111 rContext->
slot = -1;
1114 rContext->
slot = -1;
1127 Log2(PCSC_LOG_INFO,
"Attempting shutdown of %s.",
1131 if (rContext->
slot != -1)
1134 (void)RFUnBindFunctions(rContext);
1135 (void)RFUnloadReader(rContext);
1169 randHandle = SYS_RandomInt(0, -1);
1172 ret = RFReaderInfoById(randHandle, &dummy_reader);
1174 UNREF_READER(dummy_reader)
1191 int listLength, lrv;
1196 listLength = list_size(&rContext->handlesList);
1199 if (listLength >= maxReaderHandles)
1201 Log2(PCSC_LOG_CRITICAL,
1202 "Too many handles opened, exceeding configured max (%d)",
1209 if (NULL == newHandle)
1211 Log1(PCSC_LOG_CRITICAL,
"malloc failed");
1216 newHandle->
hCard = hCard;
1219 lrv = list_append(&rContext->handlesList, newHandle);
1223 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
1239 currentHandle = list_seek(&rContext->handlesList, &hCard);
1240 if (NULL == currentHandle)
1242 Log2(PCSC_LOG_CRITICAL,
"list_seek failed to locate hCard=%lX", hCard);
1247 lrv = list_delete(&rContext->handlesList, currentHandle);
1249 Log2(PCSC_LOG_CRITICAL,
1250 "list_delete failed with return value: %d", lrv);
1252 free(currentHandle);
1261 LONG RFSetReaderEventState(
READER_CONTEXT * rContext, DWORD dwEvent)
1264 int list_index, listSize;
1268 listSize = list_size(&rContext->handlesList);
1270 for (list_index = 0; list_index < listSize; list_index++)
1272 currentHandle = list_get_at(&rContext->handlesList, list_index);
1273 if (NULL == currentHandle)
1275 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed at index %d",
1300 currentHandle = list_seek(&rContext->handlesList, &hCard);
1302 if (NULL == currentHandle)
1305 Log2(PCSC_LOG_CRITICAL,
"list_seek failed for hCard 0x%lX", hCard);
1335 currentHandle = list_seek(&rContext->handlesList, &hCard);
1337 if (NULL == currentHandle)
1357 void RFCleanupReaders(
void)
1361 Log1(PCSC_LOG_INFO,
"entering cleaning function");
1364 if (sReadersContexts[i]->vHandle != 0)
1367 char lpcStripReader[MAX_READERNAME];
1369 Log2(PCSC_LOG_INFO,
"Stopping reader: %s",
1370 sReadersContexts[i]->readerState->readerName);
1372 strncpy(lpcStripReader,
1373 sReadersContexts[i]->readerState->readerName,
1374 sizeof(lpcStripReader));
1376 lpcStripReader[strlen(lpcStripReader) - 6] =
'\0';
1378 rv = RFRemoveReader(lpcStripReader, sReadersContexts[i]->port);
1381 Log2(PCSC_LOG_ERROR,
"RFRemoveReader error: 0x%08lX", rv);
1383 free(sReadersContexts[i]);
1401 void RFWaitForReaderInit(
void)
1403 int i, need_to_wait;
1407 need_to_wait = FALSE;
1411 if (sReadersContexts[i]->vHandle != NULL)
1415 == sReadersContexts[i]->readerState->cardAtrLength)
1417 Log2(PCSC_LOG_DEBUG,
"Waiting init for reader: %s",
1418 sReadersContexts[i]->readerState->readerName);
1419 need_to_wait = TRUE;
1426 }
while (need_to_wait);
1431 int RFStartSerialReaders(
const char *readerconf)
1437 ConfigFile = strdup(readerconf);
1439 rv = DBGetReaderListDir(readerconf, &reader_list);
1442 if (NULL == reader_list)
1449 (void)RFAddReader(reader_list[i].pcFriendlyname,
1450 reader_list[i].channelId,
1451 reader_list[i].pcLibpath, reader_list[i].pcDevicename);
1455 ConfigFileCRC += reader_list[i].pcFriendlyname[j];
1456 for (j=0; j<reader_list[i].
pcLibpath[j]; j++)
1457 ConfigFileCRC += reader_list[i].pcLibpath[j];
1459 ConfigFileCRC += reader_list[i].pcDevicename[j];
1462 free(reader_list[i].pcFriendlyname);
1463 free(reader_list[i].pcLibpath);
1464 free(reader_list[i].pcDevicename);
1471 void RFReCheckReaderConf(
void)
1476 (void)DBGetReaderListDir(ConfigFile, &reader_list);
1479 if (NULL == reader_list)
1489 crc += reader_list[i].pcFriendlyname[j];
1490 for (j=0; j<reader_list[i].
pcLibpath[j]; j++)
1491 crc += reader_list[i].pcLibpath[j];
1493 crc += reader_list[i].pcDevicename[j];
1497 if (crc != ConfigFileCRC)
1499 Log2(PCSC_LOG_CRITICAL,
1500 "configuration file: %s has been modified. Recheck canceled",
1508 char present = FALSE;
1510 Log2(PCSC_LOG_DEBUG,
"refresh reader: %s",
1511 reader_list[i].pcFriendlyname);
1516 if (sReadersContexts[r]->vHandle != 0)
1518 char lpcStripReader[MAX_READERNAME];
1522 strncpy(lpcStripReader,
1523 sReadersContexts[i]->readerState->readerName,
1524 sizeof(lpcStripReader));
1525 tmplen = strlen(lpcStripReader);
1526 lpcStripReader[tmplen - 6] = 0;
1528 if ((strcmp(reader_list[i].pcFriendlyname, lpcStripReader) == 0)
1529 && (reader_list[r].channelId == sReadersContexts[i]->port))
1540 Log2(PCSC_LOG_INFO,
"Reader %s disappeared",
1541 reader_list[i].pcFriendlyname);
1542 (void)RFRemoveReader(reader_list[i].pcFriendlyname,
1543 reader_list[r].channelId);
1552 (void)RFAddReader(reader_list[i].pcFriendlyname,
1553 reader_list[i].channelId, reader_list[i].pcLibpath,
1554 reader_list[i].pcDevicename);
1557 free(reader_list[i].pcFriendlyname);
1558 free(reader_list[i].pcLibpath);
1559 free(reader_list[i].pcDevicename);
LONG IFDStatusICC(READER_CONTEXT *rContext, PDWORD pdwStatus)
Provide statistical information about the IFD and ICC including insertions, atr, powering status/etc...
This abstracts dynamic library loading functions.
struct pubReaderStatesList * readerState
link to the reader state
#define SCARD_E_INVALID_VALUE
One or more of the supplied parameters values could not be properly interpreted.
uint32_t cardAtrLength
ATR length.
int32_t contexts
Number of open contexts.
#define IFD_NO_SUCH_DEVICE
The IFD_NO_SUCH_DEVICE error must be returned by the driver when it detects the reader is no more pre...
#define TAG_IFD_THREAD_SAFE
driver is thread safe
volatile SCARDHANDLE hLockId
Lock Id.
#define SCARD_S_SUCCESS
No error was encountered.
pthread_t pthThread
Event polling thread.
#define SCARD_E_INVALID_TARGET
Registry startup information is missing or invalid.
LONG IFDGetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, PDWORD pdwLength, PUCHAR pucValue)
Get's capabilities in the reader.
#define SCARD_UNKNOWN
Unknown state.
DWORD dwEventStatus
Recent event that must be sent.
RESPONSECODE(* pthCardEvent)(DWORD, int)
Card Event sync.
char readerName[MAX_READERNAME]
reader name
int32_t readerSharing
PCSCLITE_SHARING_* sharing status.
This handles abstract system level calls.
int slot
Current Reader Slot.
uint32_t eventCounter
number of card events
union ReaderContext::@3 psFunctions
driver functions
LONG EHSignalEventToClients(void)
Sends an asynchronous event to any waiting client.
This wraps the dynamic ifdhandler functions.
int * pMutex
Number of client to mutex.
#define SCARD_E_NOT_TRANSACTED
An attempt was made to end a non-existent transaction.
pthread_mutex_t handlesList_lock
lock for the above list
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
char * library
Library Path.
#define PCSCLITE_SHARING_EXCLUSIVE_CONTEXT
Reader used in exclusive mode.
#define SCARD_F_UNKNOWN_ERROR
An internal error has been detected, but the source is unknown.
#define SCARD_E_NO_MEMORY
Not enough memory available to complete this command.
#define SCARD_E_READER_UNAVAILABLE
The specified reader is not currently available for use.
#define SCARD_RESET
Card was reset.
#define PCSCLITE_MAX_READERS_CONTEXTS
Maximum readers context (a slot is count as a reader)
int * pFeeds
Number of shared client to lib.
#define TAG_IFD_SLOTS_NUMBER
number of slots of the reader
int version
IFD Handler version number.
#define SCARD_W_RESET_CARD
The smart card has been reset, so any shared state information is invalid.
pthread_mutex_t * mMutex
Mutex for this connection.
static READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS]
Area used to read status information about the readers.
This handles card insertion/removal events, updates ATR, protocol, and status information.
LONG IFDCloseIFD(READER_CONTEXT *rContext)
Close a communication channel to the IFD.
#define TAG_IFD_SLOT_THREAD_SAFE
support access to different slots of the reader
#define SCARD_W_REMOVED_CARD
The smart card has been removed, so further communication is not possible.
int powerState
auto power off state
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
UCHAR cardAtr[MAX_ATR_SIZE]
ATR.
LONG SCARDHANDLE
hCard returned by SCardConnect()
LONG IFDOpenIFD(READER_CONTEXT *rContext)
Open a communication channel to the IFD.
int LockCount
number of recursive locks
#define TAG_IFD_POLLING_THREAD_WITH_TIMEOUT
driver uses a polling thread with a timeout parameter
LPVOID vHandle
Dlopen handle.
This keeps a list of defines for pcsc-lite.
#define TAG_IFD_SIMULTANEOUS_ACCESS
number of reader the driver can manage
#define SCARD_E_DUPLICATE_READER
The reader driver did not produce a unique reader name.
pthread_mutex_t reference_lock
reference mutex
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
Define an exported public reader state structure so each application gets instant notification of cha...
#define SCARD_E_SHARING_VIOLATION
The smart card cannot be accessed because of other connections outstanding.
char * device
Device Name.
This keeps track of a list of currently available reader structures.
#define MAX_ATR_SIZE
Maximum ATR size.
char * pcDevicename
DEVICENAME.
#define SCARD_E_UNKNOWN_READER
The specified reader name is not recognized.
uint32_t readerState
SCARD_* bit field.
int reference
number of users of the structure
This provides a search API for hot pluggble devices.
pthread_mutex_t powerState_lock
powerState mutex
char * pcFriendlyname
FRIENDLYNAME.
#define SCARD_E_INVALID_HANDLE
The supplied handle was invalid.
#define IFD_SUCCESS
no error
#define SCARD_REMOVED
Card was removed.
SCARDHANDLE hCard
hCard for this connection
#define READER_NOT_INITIALIZED
Special value to indicate that power up has not yet happen This is used to auto start mode to wait un...