47 #include <sys/types.h>
65 #include "configfile.h"
75 static int maxReaderHandles = PCSC_MAX_READER_HANDLES;
76 static DWORD dwNumReadersContexts = 0;
78 static char *ConfigFile = NULL;
79 static int ConfigFileCRC = 0;
81 static pthread_mutex_t LockMutex = PTHREAD_MUTEX_INITIALIZER;
83 #define IDENTITY_SHIFT 16
86 static int RDR_CLIHANDLES_seeker(
const void *el,
const void *key)
90 if ((el == NULL) || (key == NULL))
92 Log3(PCSC_LOG_CRITICAL,
93 "RDR_CLIHANDLES_seeker called with NULL pointer: el=%p, key=%p",
127 removeReader(sReader);
132 LONG RFAllocateReaderSpace(
unsigned int customMaxReaderHandles)
136 if (customMaxReaderHandles != 0)
137 maxReaderHandles = customMaxReaderHandles;
143 sReadersContexts[i]->
vHandle = NULL;
158 return EHInitializeEventStructures();
161 LONG RFAddReader(
const char *readerNameLong,
int port,
const char *library,
164 DWORD dwContext = 0, dwGetSize;
165 UCHAR ucGetData[1], ucThread[1];
169 char *readerName = NULL;
171 if ((readerNameLong == NULL) || (library == NULL) || (device == NULL))
175 const char *ro_filter = getenv(
"PCSCLITE_FILTER_IGNORE_READER_NAMES");
181 filter = alloca(strlen(ro_filter)+1);
182 strcpy(filter, ro_filter);
187 next = strchr(filter,
':');
195 if (*filter && strstr(readerNameLong, filter))
198 "Reader name \"%s\" contains \"%s\": ignored",
199 readerNameLong, filter);
214 readerName = alloca(strlen(readerNameLong)+1);
215 strcpy(readerName, readerNameLong);
218 if (strlen(readerName) > MAX_READERNAME -
sizeof(
" 00 00"))
221 "Reader name too long: %zd chars instead of max %zd. Truncating!",
222 strlen(readerName), MAX_READERNAME -
sizeof(
" 00 00"));
223 readerName[MAX_READERNAME -
sizeof(
" 00 00")] =
'\0';
227 if (dwNumReadersContexts != 0)
231 if (sReadersContexts[i]->vHandle != 0)
233 char lpcStripReader[MAX_READERNAME];
237 strncpy(lpcStripReader,
238 sReadersContexts[i]->readerState->readerName,
239 sizeof(lpcStripReader));
240 tmplen = strlen(lpcStripReader);
241 lpcStripReader[tmplen - 6] = 0;
243 if ((strcmp(readerName, lpcStripReader) == 0)
244 && (port == sReadersContexts[i]->port)
245 && (strcmp(device, sReadersContexts[i]->device) == 0))
247 Log1(PCSC_LOG_ERROR,
"Duplicate reader found.");
257 if (sReadersContexts[i]->vHandle == 0)
271 parentNode = RFSetReaderName(sReadersContexts[dwContext], readerName,
276 sReadersContexts[dwContext]->
library = strdup(library);
277 sReadersContexts[dwContext]->
device = strdup(device);
278 sReadersContexts[dwContext]->
version = 0;
279 sReadersContexts[dwContext]->
port = port;
280 sReadersContexts[dwContext]->
mMutex = NULL;
281 sReadersContexts[dwContext]->
contexts = 0;
282 sReadersContexts[dwContext]->
pthThread = 0;
283 sReadersContexts[dwContext]->
hLockId = 0;
284 sReadersContexts[dwContext]->
LockCount = 0;
285 sReadersContexts[dwContext]->
vHandle = NULL;
286 sReadersContexts[dwContext]->
pFeeds = NULL;
287 sReadersContexts[dwContext]->
pMutex = NULL;
290 lrv = list_init(&sReadersContexts[dwContext]->handlesList);
293 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d", lrv);
297 lrv = list_attributes_seeker(&sReadersContexts[dwContext]->handlesList,
298 RDR_CLIHANDLES_seeker);
301 Log2(PCSC_LOG_CRITICAL,
302 "list_attributes_seeker failed with return value: %d", lrv);
306 (void)pthread_mutex_init(&sReadersContexts[dwContext]->handlesList_lock,
309 (void)pthread_mutex_init(&sReadersContexts[dwContext]->powerState_lock,
314 (void)pthread_mutex_init(&sReadersContexts[dwContext]->reference_lock,
316 sReadersContexts[dwContext]->
reference = 1;
321 sReadersContexts[dwContext]->
pFeeds =
322 sReadersContexts[parentNode]->
pFeeds;
323 *(sReadersContexts[dwContext])->pFeeds += 1;
324 sReadersContexts[dwContext]->
vHandle =
325 sReadersContexts[parentNode]->
vHandle;
326 sReadersContexts[dwContext]->
mMutex =
327 sReadersContexts[parentNode]->
mMutex;
328 sReadersContexts[dwContext]->
pMutex =
329 sReadersContexts[parentNode]->
pMutex;
332 dwGetSize =
sizeof(ucThread);
336 if (rv ==
IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
338 Log1(PCSC_LOG_INFO,
"Driver is thread safe");
339 sReadersContexts[dwContext]->
mMutex = NULL;
340 sReadersContexts[dwContext]->
pMutex = NULL;
343 *(sReadersContexts[dwContext])->pMutex += 1;
346 if (sReadersContexts[dwContext]->pFeeds == NULL)
348 sReadersContexts[dwContext]->
pFeeds = malloc(
sizeof(
int));
354 *(sReadersContexts[dwContext])->pFeeds = 1;
357 if (sReadersContexts[dwContext]->mMutex == 0)
359 sReadersContexts[dwContext]->
mMutex =
360 malloc(
sizeof(pthread_mutex_t));
361 (void)pthread_mutex_init(sReadersContexts[dwContext]->mMutex, NULL);
364 if (sReadersContexts[dwContext]->pMutex == NULL)
366 sReadersContexts[dwContext]->
pMutex = malloc(
sizeof(
int));
367 *(sReadersContexts[dwContext])->pMutex = 1;
370 dwNumReadersContexts += 1;
372 rv = RFInitializeReader(sReadersContexts[dwContext]);
375 int log_level = PCSC_LOG_ERROR;
377 log_level = PCSC_LOG_INFO;
380 Log2(log_level,
"%s init failed.", readerName);
381 (void)RFRemoveReader(readerName, port, REMOVE_READER_NO_FLAG);
387 RESPONSECODE (*fct)(DWORD, int) = NULL;
389 dwGetSize =
sizeof(fct);
395 Log1(PCSC_LOG_INFO,
"Using the pcscd polling thread");
400 Log1(PCSC_LOG_INFO,
"Using the reader polling thread");
403 rv = EHSpawnEventHandler(sReadersContexts[dwContext]);
406 Log2(PCSC_LOG_ERROR,
"%s init failed.", readerName);
407 (void)RFRemoveReader(readerName, port, REMOVE_READER_NO_FLAG);
413 dwGetSize =
sizeof(ucGetData);
417 int nbSlots = ucGetData[0];
418 if (rv !=
IFD_SUCCESS || dwGetSize != 1 || nbSlots == 0)
433 for (j = 1; j < nbSlots; j++)
435 char *tmpReader = NULL;
436 DWORD dwContextB = 0;
437 RESPONSECODE (*fct)(DWORD, int) = NULL;
442 if (sReadersContexts[i]->vHandle == 0)
452 RFRemoveReader(readerName, port, REMOVE_READER_NO_FLAG);
459 sReadersContexts[dwContext]->readerState->readerName,
460 sizeof(sReadersContexts[dwContextB]->readerState->readerName));
461 snprintf(tmpReader + strlen(tmpReader) - 2, 3,
"%02X", j);
463 sReadersContexts[dwContextB]->
library =
464 sReadersContexts[dwContext]->
library;
465 sReadersContexts[dwContextB]->
device =
466 sReadersContexts[dwContext]->
device;
467 sReadersContexts[dwContextB]->
version =
468 sReadersContexts[dwContext]->
version;
469 sReadersContexts[dwContextB]->
port =
470 sReadersContexts[dwContext]->
port;
471 sReadersContexts[dwContextB]->
vHandle =
472 sReadersContexts[dwContext]->
vHandle;
473 sReadersContexts[dwContextB]->
mMutex =
474 sReadersContexts[dwContext]->
mMutex;
475 sReadersContexts[dwContextB]->
pMutex =
476 sReadersContexts[dwContext]->
pMutex;
477 sReadersContexts[dwContextB]->
slot =
478 sReadersContexts[dwContext]->
slot + j;
485 sReadersContexts[dwContextB]->
pFeeds =
486 sReadersContexts[dwContext]->
pFeeds;
489 *(sReadersContexts[dwContextB])->pFeeds += 1;
491 sReadersContexts[dwContextB]->
contexts = 0;
492 sReadersContexts[dwContextB]->
hLockId = 0;
493 sReadersContexts[dwContextB]->
LockCount = 0;
495 lrv = list_init(&sReadersContexts[dwContextB]->handlesList);
498 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d", lrv);
502 lrv = list_attributes_seeker(&sReadersContexts[dwContextB]->handlesList,
503 RDR_CLIHANDLES_seeker);
506 Log2(PCSC_LOG_CRITICAL,
507 "list_attributes_seeker failed with return value: %d", lrv);
511 (void)pthread_mutex_init(&sReadersContexts[dwContextB]->handlesList_lock, NULL);
512 (void)pthread_mutex_init(&sReadersContexts[dwContextB]->powerState_lock,
517 (void)pthread_mutex_init(&sReadersContexts[dwContextB]->reference_lock,
519 sReadersContexts[dwContextB]->
reference = 1;
522 dwGetSize =
sizeof(ucThread);
526 if (rv ==
IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
528 Log1(PCSC_LOG_INFO,
"Driver is slot thread safe");
530 sReadersContexts[dwContextB]->
library =
531 strdup(sReadersContexts[dwContext]->library);
532 sReadersContexts[dwContextB]->
device =
533 strdup(sReadersContexts[dwContext]->device);
534 sReadersContexts[dwContextB]->
mMutex =
535 malloc(
sizeof(pthread_mutex_t));
536 (void)pthread_mutex_init(sReadersContexts[dwContextB]->mMutex,
539 sReadersContexts[dwContextB]->
pMutex = malloc(
sizeof(
int));
540 *(sReadersContexts[dwContextB])->pMutex = 1;
543 *(sReadersContexts[dwContextB])->pMutex += 1;
545 dwNumReadersContexts += 1;
547 rv = RFInitializeReader(sReadersContexts[dwContextB]);
551 (void)RFRemoveReader(readerName, port, REMOVE_READER_NO_FLAG);
556 dwGetSize =
sizeof(fct);
562 Log1(PCSC_LOG_INFO,
"Using the pcscd polling thread");
567 Log1(PCSC_LOG_INFO,
"Using the reader polling thread");
570 rv = EHSpawnEventHandler(sReadersContexts[dwContextB]);
573 Log2(PCSC_LOG_ERROR,
"%s init failed.", readerName);
574 (void)RFRemoveReader(readerName, port, REMOVE_READER_NO_FLAG);
582 LONG RFRemoveReader(
const char *readerName,
int port,
int flags)
584 char lpcStripReader[MAX_READERNAME];
591 if (readerName == NULL)
595 extend = getenv(
"PCSCLITE_FILTER_EXTEND_READER_NAMES");
597 extend_size = strlen(extend);
602 if (sReadersContexts[i] && (sReadersContexts[i]->vHandle != 0))
604 strncpy(lpcStripReader,
605 sReadersContexts[i]->readerState->readerName,
606 sizeof(lpcStripReader));
607 lpcStripReader[strlen(lpcStripReader) - 6 - extend_size] = 0;
610 if ((strncmp(readerName, lpcStripReader, MAX_READERNAME -
sizeof(
" 00 00")) == 0)
611 && (port == sReadersContexts[i]->port))
613 if (flags & REMOVE_READER_FLAG_REMOVED)
620 valueLength =
sizeof(tagValue);
632 UNREF_READER(sReadersContexts[i])
643 if (sContext -> pthThread)
644 EHDestroyEventHandler(sContext);
646 if ((NULL == sContext->
pMutex) || (NULL == sContext->
pFeeds))
649 "Trying to remove an already removed driver");
653 RFUnInitializeReader(sContext);
658 if (0 == *sContext->
pMutex)
660 (void)pthread_mutex_destroy(sContext->
mMutex);
672 if (*sContext->
pFeeds == 0)
688 while (list_size(&sContext->handlesList) != 0)
693 currentHandle = list_get_at(&sContext->handlesList, 0);
694 lrv = list_delete_at(&sContext->handlesList, 0);
696 Log2(PCSC_LOG_CRITICAL,
697 "list_delete_at failed with return value: %d", lrv);
703 list_destroy(&sContext->handlesList);
704 dwNumReadersContexts -= 1;
712 LONG RFSetReaderName(
READER_CONTEXT * rContext,
const char *readerName,
713 const char *libraryName,
int port)
717 int currentDigit = -1;
718 int supportedChannels = 0;
721 const char *extend =
"";
725 usedDigits[i] = FALSE;
727 if (dwNumReadersContexts != 0)
731 if (sReadersContexts[i]->vHandle != 0)
733 if (strcmp(sReadersContexts[i]->library, libraryName) == 0)
739 valueLength =
sizeof(tagValue);
742 &valueLength, tagValue);
747 supportedChannels = tagValue[0];
749 "Support %d simultaneous readers", tagValue[0]);
752 supportedChannels = 1;
755 if ((((sReadersContexts[i]->port & 0xFFFF0000) ==
756 PCSCLITE_HP_BASE_PORT)
757 && (sReadersContexts[i]->port != port))
758 || (supportedChannels > 1))
774 currentDigit = strtol(reader + strlen(reader) - 5, NULL, 16);
777 usedDigits[currentDigit] = TRUE;
788 if (currentDigit != -1)
793 if (usedDigits[i] == FALSE)
803 if (i >= supportedChannels)
805 Log3(PCSC_LOG_ERROR,
"Driver %s does not support more than "
806 "%d reader(s). Maybe the driver should support "
807 "TAG_IFD_SIMULTANEOUS_ACCESS", libraryName, supportedChannels);
813 extend = getenv(
"PCSCLITE_FILTER_EXTEND_READER_NAMES");
820 readerName, extend, i);
823 rContext->
slot = i << 16;
828 LONG RFReaderInfo(
const char *readerName,
READER_CONTEXT ** sReader)
832 if (readerName == NULL)
837 if (sReadersContexts[i]->vHandle != 0)
839 if (strcmp(readerName,
840 sReadersContexts[i]->readerState->readerName) == 0)
843 REF_READER(sReadersContexts[i])
845 *sReader = sReadersContexts[i];
860 if (sReadersContexts[i]->vHandle != 0)
863 (void)pthread_mutex_lock(&sReadersContexts[i]->handlesList_lock);
864 currentHandle = list_seek(&sReadersContexts[i]->handlesList,
866 (void)pthread_mutex_unlock(&sReadersContexts[i]->handlesList_lock);
867 if (currentHandle != NULL)
870 REF_READER(sReadersContexts[i])
872 *sReader = sReadersContexts[i];
885 Log2(PCSC_LOG_INFO,
"Reusing already loaded driver for %s",
899 rv = DYN_GetAddress(rContext->
vHandle, &f,
"IFDHCreateChannelByName", TRUE);
903 rContext->
version = IFD_HVERSION_3_0;
907 rv = DYN_GetAddress(rContext->
vHandle, &f,
"IFDHCreateChannel", FALSE);
911 rContext->
version = IFD_HVERSION_2_0;
916 Log1(PCSC_LOG_CRITICAL,
"IFDHandler functions missing");
921 if (rContext->
version == IFD_HVERSION_2_0)
924 #define GET_ADDRESS_OPTIONALv2(s, code) \
927 int rvl = DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s, FALSE); \
928 if (SCARD_S_SUCCESS != rvl) \
932 rContext->psFunctions.psFunctions_v2.pvf ## s = f1; \
935 #define GET_ADDRESSv2(s) \
936 GET_ADDRESS_OPTIONALv2(s, \
937 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
940 Log1(PCSC_LOG_INFO,
"Loading IFD Handler 2.0");
942 GET_ADDRESSv2(CreateChannel)
943 GET_ADDRESSv2(CloseChannel)
944 GET_ADDRESSv2(GetCapabilities)
945 GET_ADDRESSv2(SetCapabilities)
946 GET_ADDRESSv2(PowerICC)
947 GET_ADDRESSv2(TransmitToICC)
948 GET_ADDRESSv2(ICCPresence)
949 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
951 GET_ADDRESSv2(Control)
953 else if (rContext->version == IFD_HVERSION_3_0)
956 #define GET_ADDRESS_OPTIONALv3(s, code) \
959 int rvl = DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s, FALSE); \
960 if (SCARD_S_SUCCESS != rvl) \
964 rContext->psFunctions.psFunctions_v3.pvf ## s = f1; \
967 #define GET_ADDRESSv3(s) \
968 GET_ADDRESS_OPTIONALv3(s, \
969 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
972 Log1(PCSC_LOG_INFO,
"Loading IFD Handler 3.0");
974 GET_ADDRESSv2(CreateChannel)
975 GET_ADDRESSv2(CloseChannel)
976 GET_ADDRESSv2(GetCapabilities)
977 GET_ADDRESSv2(SetCapabilities)
978 GET_ADDRESSv2(PowerICC)
979 GET_ADDRESSv2(TransmitToICC)
980 GET_ADDRESSv2(ICCPresence)
981 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
983 GET_ADDRESSv3(CreateChannelByName)
984 GET_ADDRESSv3(Control)
989 Log1(PCSC_LOG_CRITICAL,
"IFD Handler not 1.0/2.0 or 3.0");
1007 if (*rContext->
pFeeds == 1)
1009 Log1(PCSC_LOG_INFO,
"Unloading reader driver.");
1010 (void)DYN_CloseLibrary(&rContext->
vHandle);
1030 (void)pthread_mutex_lock(&LockMutex);
1031 rv = RFCheckSharing(hCard, rContext);
1037 (void)pthread_mutex_unlock(&LockMutex);
1046 (void)pthread_mutex_lock(&LockMutex);
1047 rv = RFCheckSharing(hCard, rContext);
1070 (void)pthread_mutex_unlock(&LockMutex);
1079 (void)pthread_mutex_lock(&LockMutex);
1080 rv = RFCheckSharing(hCard, rContext);
1086 (void)pthread_mutex_unlock(&LockMutex);
1097 Log3(PCSC_LOG_INFO,
"Attempting startup of %s using %s",
1100 #ifndef PCSCLITE_STATIC_DRIVER
1102 rv = RFLoadReader(rContext);
1105 Log2(PCSC_LOG_ERROR,
"RFLoadReader failed: 0x%lX", rv);
1110 rv = RFBindFunctions(rContext);
1114 Log2(PCSC_LOG_ERROR,
"RFBindFunctions failed: 0x%lX", rv);
1115 (void)RFUnloadReader(rContext);
1120 rContext->
vHandle = RFInitializeReader;
1128 int log_level = PCSC_LOG_CRITICAL;
1134 log_level = PCSC_LOG_INFO;
1138 Log3(log_level,
"Open Port 0x%X Failed (%s)",
1143 rContext->
slot = -1;
1151 Log2(PCSC_LOG_INFO,
"Attempting shutdown of %s.",
1155 if (rContext->
slot != -1)
1158 (void)RFUnBindFunctions(rContext);
1159 (void)RFUnloadReader(rContext);
1196 ret = RFReaderInfoById(randHandle, &dummy_reader);
1198 UNREF_READER(dummy_reader)
1209 int listLength, lrv;
1214 listLength = list_size(&rContext->handlesList);
1217 if (listLength >= maxReaderHandles)
1219 Log2(PCSC_LOG_CRITICAL,
1220 "Too many handles opened, exceeding configured max (%d)",
1227 if (NULL == newHandle)
1229 Log1(PCSC_LOG_CRITICAL,
"malloc failed");
1234 newHandle->
hCard = hCard;
1237 lrv = list_append(&rContext->handlesList, newHandle);
1241 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
1257 currentHandle = list_seek(&rContext->handlesList, &hCard);
1258 if (NULL == currentHandle)
1260 Log2(PCSC_LOG_CRITICAL,
"list_seek failed to locate hCard=%lX", hCard);
1265 lrv = list_delete(&rContext->handlesList, currentHandle);
1267 Log2(PCSC_LOG_CRITICAL,
1268 "list_delete failed with return value: %d", lrv);
1270 free(currentHandle);
1279 void RFSetReaderEventState(
READER_CONTEXT * rContext, DWORD dwEvent)
1282 int list_index, listSize;
1286 listSize = list_size(&rContext->handlesList);
1288 for (list_index = 0; list_index < listSize; list_index++)
1290 currentHandle = list_get_at(&rContext->handlesList, list_index);
1291 if (NULL == currentHandle)
1293 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed at index %d",
1318 currentHandle = list_seek(&rContext->handlesList, &hCard);
1320 if (NULL == currentHandle)
1323 Log2(PCSC_LOG_CRITICAL,
"list_seek failed for hCard 0x%lX", hCard);
1353 currentHandle = list_seek(&rContext->handlesList, &hCard);
1355 if (NULL == currentHandle)
1375 void RFCleanupReaders(
void)
1379 Log1(PCSC_LOG_INFO,
"entering cleaning function");
1382 if (sReadersContexts[i]->vHandle != 0)
1385 char lpcStripReader[MAX_READERNAME];
1387 Log2(PCSC_LOG_INFO,
"Stopping reader: %s",
1388 sReadersContexts[i]->readerState->readerName);
1390 strncpy(lpcStripReader,
1391 sReadersContexts[i]->readerState->readerName,
1392 sizeof(lpcStripReader));
1394 lpcStripReader[strlen(lpcStripReader) - 6] =
'\0';
1396 rv = RFRemoveReader(lpcStripReader, sReadersContexts[i]->port,
1397 REMOVE_READER_NO_FLAG);
1400 Log2(PCSC_LOG_ERROR,
"RFRemoveReader error: 0x%08lX", rv);
1402 free(sReadersContexts[i]);
1404 sReadersContexts[i] = NULL;
1422 void RFWaitForReaderInit(
void)
1424 int i, need_to_wait;
1428 need_to_wait = FALSE;
1432 if (sReadersContexts[i]->vHandle != NULL)
1436 == sReadersContexts[i]->readerState->cardAtrLength)
1438 Log2(PCSC_LOG_DEBUG,
"Waiting init for reader: %s",
1439 sReadersContexts[i]->readerState->readerName);
1440 need_to_wait = TRUE;
1447 }
while (need_to_wait);
1452 int RFStartSerialReaders(
const char *readerconf)
1458 ConfigFile = strdup(readerconf);
1460 rv = DBGetReaderListDir(readerconf, &reader_list);
1463 if (NULL == reader_list)
1470 (void)RFAddReader(reader_list[i].pcFriendlyname,
1471 reader_list[i].channelId,
1472 reader_list[i].pcLibpath, reader_list[i].pcDevicename);
1476 ConfigFileCRC += reader_list[i].pcFriendlyname[j];
1477 for (j=0; j<reader_list[i].
pcLibpath[j]; j++)
1478 ConfigFileCRC += reader_list[i].pcLibpath[j];
1480 ConfigFileCRC += reader_list[i].pcDevicename[j];
1483 free(reader_list[i].pcFriendlyname);
1484 free(reader_list[i].pcLibpath);
1485 free(reader_list[i].pcDevicename);
1492 void RFReCheckReaderConf(
void)
1497 (void)DBGetReaderListDir(ConfigFile, &reader_list);
1500 if (NULL == reader_list)
1510 crc += reader_list[i].pcFriendlyname[j];
1511 for (j=0; j<reader_list[i].
pcLibpath[j]; j++)
1512 crc += reader_list[i].pcLibpath[j];
1514 crc += reader_list[i].pcDevicename[j];
1518 if (crc != ConfigFileCRC)
1520 Log2(PCSC_LOG_CRITICAL,
1521 "configuration file: %s has been modified. Recheck canceled",
1529 char present = FALSE;
1531 Log2(PCSC_LOG_DEBUG,
"refresh reader: %s",
1532 reader_list[i].pcFriendlyname);
1537 if (sReadersContexts[r]->vHandle != 0)
1539 char lpcStripReader[MAX_READERNAME];
1543 strncpy(lpcStripReader,
1544 sReadersContexts[i]->readerState->readerName,
1545 sizeof(lpcStripReader));
1546 tmplen = strlen(lpcStripReader);
1547 lpcStripReader[tmplen - 6] = 0;
1549 if ((strcmp(reader_list[i].pcFriendlyname, lpcStripReader) == 0)
1550 && (reader_list[r].channelId == sReadersContexts[i]->port))
1561 Log2(PCSC_LOG_INFO,
"Reader %s disappeared",
1562 reader_list[i].pcFriendlyname);
1563 (void)RFRemoveReader(reader_list[i].pcFriendlyname,
1564 reader_list[r].channelId, REMOVE_READER_NO_FLAG);
1573 (void)RFAddReader(reader_list[i].pcFriendlyname,
1574 reader_list[i].channelId, reader_list[i].pcLibpath,
1575 reader_list[i].pcDevicename);
1578 free(reader_list[i].pcFriendlyname);
1579 free(reader_list[i].pcLibpath);
1580 free(reader_list[i].pcDevicename);
This abstracts dynamic library loading functions.
void EHSignalEventToClients(void)
Sends an asynchronous event to any waiting client.
This handles card insertion/removal events, updates ATR, protocol, and status information.
#define PCSCLITE_SHARING_EXCLUSIVE_CONTEXT
Reader used in exclusive mode.
#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...
#define SCARD_E_INVALID_HANDLE
The supplied handle was invalid.
#define SCARD_E_UNKNOWN_READER
The specified reader name is not recognized.
#define SCARD_W_RESET_CARD
The smart card has been reset, so any shared state information is invalid.
#define SCARD_F_UNKNOWN_ERROR
An internal error has been detected, but the source is unknown.
#define SCARD_E_INVALID_TARGET
Registry startup information is missing or invalid.
#define SCARD_S_SUCCESS
No error was encountered.
#define SCARD_E_NO_MEMORY
Not enough memory available to complete this command.
#define SCARD_E_SHARING_VIOLATION
The smart card cannot be accessed because of other connections outstanding.
#define SCARD_E_DUPLICATE_READER
The reader driver did not produce a unique reader name.
#define SCARD_E_INVALID_VALUE
One or more of the supplied parameters values could not be properly interpreted.
#define SCARD_W_REMOVED_CARD
The smart card has been removed, so further communication is not possible.
#define SCARD_E_NOT_TRANSACTED
An attempt was made to end a non-existent transaction.
#define SCARD_E_READER_UNAVAILABLE
The specified reader is not currently available for use.
This provides a search API for hot pluggble devices.
#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_SIMULTANEOUS_ACCESS
number of reader the driver can manage
#define TAG_IFD_THREAD_SAFE
driver is thread safe
#define TAG_IFD_SLOTS_NUMBER
number of slots of the reader
#define TAG_IFD_POLLING_THREAD_WITH_TIMEOUT
driver uses a polling thread with a timeout parameter
#define TAG_IFD_SLOT_THREAD_SAFE
support access to different slots of the reader
#define IFD_SUCCESS
no error
#define TAG_IFD_DEVICE_REMOVED
signals the reader has been removed
RESPONSECODE IFDCloseIFD(READER_CONTEXT *rContext)
Close a communication channel to the IFD.
RESPONSECODE IFDOpenIFD(READER_CONTEXT *rContext)
Open a communication channel to the IFD.
RESPONSECODE IFDGetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, PDWORD pdwLength, PUCHAR pucValue)
Get's capabilities in the reader.
LONG IFDStatusICC(READER_CONTEXT *rContext, PDWORD pdwStatus)
Provide statistical information about the IFD and ICC including insertions, atr, powering status/etc.
RESPONSECODE IFDSetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, DWORD dwLength, PUCHAR pucValue)
Set capabilities in the reader.
This wraps the dynamic ifdhandler functions.
This keeps a list of defines for pcsc-lite.
@ POWER_STATE_UNPOWERED
auto power off
#define SCARD_RESET
Card was reset.
#define SCARD_REMOVED
Card was removed.
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
#define MAX_ATR_SIZE
Maximum ATR size.
#define SCARD_UNKNOWN
Unknown state.
LONG SCARDHANDLE
hCard returned by SCardConnect()
#define PCSCLITE_MAX_READERS_CONTEXTS
Maximum readers context (a slot is count as a reader)
int RFGetPowerState(READER_CONTEXT *rContext)
Wait until all connected readers have a chance to power up a possibly inserted card.
This keeps track of a list of currently available reader structures.
DWORD dwEventStatus
Recent event that must be sent.
SCARDHANDLE hCard
hCard for this connection
volatile SCARDHANDLE hLockId
Lock Id.
RESPONSECODE(* pthCardEvent)(DWORD, int)
Card Event sync.
pthread_mutex_t * mMutex
Mutex for this connection.
pthread_mutex_t powerState_lock
powerState mutex
LPVOID vHandle
Dlopen handle.
pthread_t pthThread
Event polling thread.
int LockCount
number of recursive locks
union ReaderContext::@3 psFunctions
driver functions
int slot
Current Reader Slot.
int * pFeeds
Number of shared client to lib.
int * pMutex
Number of client to mutex.
pthread_mutex_t reference_lock
reference mutex
int version
IFD Handler version number.
int reference
number of users of the structure
int32_t contexts
Number of open contexts.
pthread_mutex_t handlesList_lock
lock for the above list
char * library
Library Path.
struct pubReaderStatesList * readerState
link to the reader state
int powerState
auto power off state
char * device
Device Name.
char * pcFriendlyname
FRIENDLYNAME.
char * pcDevicename
DEVICENAME.
Define an exported public reader state structure so each application gets instant notification of cha...
char readerName[MAX_READERNAME]
reader name
int32_t readerSharing
PCSCLITE_SHARING_* sharing status.
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
UCHAR cardAtr[MAX_ATR_SIZE]
ATR.
uint32_t eventCounter
number of card events
uint32_t readerState
SCARD_* bit field.
uint32_t cardAtrLength
ATR length.
This handles abstract system level calls.
int SYS_RandomInt(int, int)
Generate a pseudo random number.
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
static READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS]
Area used to read status information about the readers.