108 #include <sys/types.h>
114 #include <sys/time.h>
116 #include <sys/wait.h>
138 #define SCARD_PROTOCOL_ANY_OLD 0x1000
145 static char sharing_shall_block = TRUE;
147 #define COLOR_RED "\33[01;31m"
148 #define COLOR_GREEN "\33[32m"
149 #define COLOR_BLUE "\33[34m"
150 #define COLOR_MAGENTA "\33[35m"
151 #define COLOR_NORMAL "\33[0m"
158 static void trace(
const char *func,
const char direction,
const char *fmt, ...)
162 fprintf(stderr, COLOR_GREEN
"%c " COLOR_BLUE
"[%lX] " COLOR_GREEN
"%s ",
163 direction, pthread_self(), func);
165 fprintf(stderr, COLOR_MAGENTA);
167 vfprintf(stderr, fmt, args);
170 fprintf(stderr, COLOR_NORMAL
"\n");
173 #define API_TRACE_IN(...) trace(__FUNCTION__, '<', __VA_ARGS__);
174 #define API_TRACE_OUT(...) trace(__FUNCTION__, '>', __VA_ARGS__);
176 #define API_TRACE_IN(...)
177 #define API_TRACE_OUT(...)
182 #define PROFILE_FILE "/tmp/pcsc_profile"
184 #include <sys/time.h>
187 #define MAX_THREADS 5
188 pthread_t threads[MAX_THREADS];
189 struct timeval profile_time_start[MAX_THREADS];
193 #define PROFILE_START profile_start();
194 #define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
196 static void profile_start(
void)
198 static char initialized = FALSE;
207 sprintf(filename,
"%s-%d", PROFILE_FILE, getuid());
208 profile_fd = fopen(filename,
"a+");
209 if (NULL == profile_fd)
211 fprintf(stderr, COLOR_RED
"Can't open %s: %s" COLOR_NORMAL
"\n",
212 PROFILE_FILE, strerror(errno));
215 fprintf(profile_fd,
"\nStart a new profile\n");
217 if (isatty(fileno(stderr)))
224 for (i=0; i<MAX_THREADS; i++)
225 if (pthread_equal(0, threads[i]))
231 gettimeofday(&profile_time_start[i], NULL);
234 static void profile_end(
const char *f, LONG rv)
236 struct timeval profile_time_end;
241 gettimeofday(&profile_time_end, NULL);
244 for (i=0; i<MAX_THREADS; i++)
245 if (pthread_equal(t, threads[i]))
250 fprintf(stderr, COLOR_BLUE
" WARNING: no start info for %s\n", f);
254 d =
time_sub(&profile_time_end, &profile_time_start[i]);
263 COLOR_RED
"RESULT %s " COLOR_MAGENTA
"%ld "
264 COLOR_BLUE
"0x%08lX %s" COLOR_NORMAL
"\n",
267 fprintf(stderr, COLOR_RED
"RESULT %s " COLOR_MAGENTA
"%ld"
268 COLOR_NORMAL
"\n", f, d);
270 fprintf(profile_fd,
"%s %ld\n", f, d);
275 #define PROFILE_START
276 #define PROFILE_END(rv)
291 static int CHANNEL_MAP_seeker(
const void *el,
const void *key)
295 if ((el == NULL) || (key == NULL))
297 Log3(PCSC_LOG_CRITICAL,
298 "CHANNEL_MAP_seeker called with NULL pointer: el=%p, key=%p",
329 static list_t contextMapList;
331 static int SCONTEXTMAP_seeker(
const void *el,
const void *key)
335 if ((el == NULL) || (key == NULL))
337 Log3(PCSC_LOG_CRITICAL,
338 "SCONTEXTMAP_seeker called with NULL pointer: el=%p, key=%p",
381 static LONG SCardGetContextChannelAndLockFromHandle(
SCARDHANDLE,
383 static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE,
387 static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
388 LPBYTE pbAttr, LPDWORD pcbAttrLen);
390 static LONG getReaderStates(
SCONTEXTMAP * currentContextMap);
391 static LONG getReaderStatesAndRegisterForEvents(
SCONTEXTMAP * currentContextMap);
392 static LONG unregisterFromEvents(
SCONTEXTMAP * currentContextMap);
435 return currentContextMap != NULL;
477 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
481 API_TRACE_IN(
"%ld, %p, %p", dwScope, pvReserved1, pvReserved2)
491 pvReserved2, phContext);
496 API_TRACE_OUT(
"%ld", *phContext)
529 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
533 uint32_t dwClientID = 0;
537 if (phContext == NULL)
554 lrv = list_init(&contextMapList);
557 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d",
562 lrv = list_attributes_seeker(&contextMapList,
566 Log2(PCSC_LOG_CRITICAL,
567 "list_attributes_seeker failed with return value: %d", lrv);
568 list_destroy(&contextMapList);
572 if (getenv(
"PCSCLITE_NO_BLOCKING"))
574 Log1(PCSC_LOG_INFO,
"Disable shared blocking");
575 sharing_shall_block = FALSE;
604 Log1(PCSC_LOG_CRITICAL,
605 "Your pcscd is too old and does not support CMD_VERSION");
610 Log3(PCSC_LOG_INFO,
"Server is protocol version %d:%d",
624 scEstablishStruct.dwScope = dwScope;
625 scEstablishStruct.hContext = 0;
629 sizeof(scEstablishStruct), (
void *) &scEstablishStruct);
637 rv =
MessageReceive(&scEstablishStruct,
sizeof(scEstablishStruct),
645 rv = scEstablishStruct.rv;
655 *phContext = scEstablishStruct.hContext;
697 API_TRACE_IN(
"%ld", hContext)
705 if (NULL == currentContextMap)
711 scReleaseStruct.hContext = hContext;
715 currentContextMap->dwClientID,
716 sizeof(scReleaseStruct), (
void *) &scReleaseStruct);
725 currentContextMap->dwClientID);
730 rv = scReleaseStruct.rv;
732 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
804 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
805 LPDWORD pdwActiveProtocol)
812 API_TRACE_IN(
"%ld %s %ld %ld", hContext, szReader, dwShareMode, dwPreferredProtocols)
817 if (phCard == NULL || pdwActiveProtocol == NULL)
822 if (szReader == NULL)
828 if (strlen(szReader) > MAX_READERNAME)
835 if (NULL == currentContextMap)
838 memset(scConnectStruct.szReader, 0,
sizeof scConnectStruct.szReader);
839 strncpy(scConnectStruct.szReader, szReader,
sizeof scConnectStruct.szReader);
840 scConnectStruct.szReader[
sizeof scConnectStruct.szReader -1] =
'\0';
842 scConnectStruct.hContext = hContext;
843 scConnectStruct.dwShareMode = dwShareMode;
844 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
845 scConnectStruct.hCard = 0;
846 scConnectStruct.dwActiveProtocol = 0;
850 sizeof(scConnectStruct), (
void *) &scConnectStruct);
859 currentContextMap->dwClientID);
864 *phCard = scConnectStruct.hCard;
865 *pdwActiveProtocol = scConnectStruct.dwActiveProtocol;
872 rv = SCardAddHandle(*phCard, currentContextMap, szReader);
875 rv = scConnectStruct.rv;
878 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
881 API_TRACE_OUT(
"%d", *pdwActiveProtocol)
959 DWORD dwPreferredProtocols, DWORD dwInitialization,
960 LPDWORD pdwActiveProtocol)
968 API_TRACE_IN(
"%ld %ld %ld", hCard, dwShareMode, dwPreferredProtocols)
970 if (pdwActiveProtocol == NULL)
979 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
984 scReconnectStruct.hCard = hCard;
985 scReconnectStruct.dwShareMode = dwShareMode;
986 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
987 scReconnectStruct.dwInitialization = dwInitialization;
988 scReconnectStruct.dwActiveProtocol = *pdwActiveProtocol;
992 sizeof(scReconnectStruct), (
void *) &scReconnectStruct);
1000 rv =
MessageReceive(&scReconnectStruct,
sizeof(scReconnectStruct),
1001 currentContextMap->dwClientID);
1006 rv = scReconnectStruct.rv;
1010 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1015 *pdwActiveProtocol = scReconnectStruct.dwActiveProtocol;
1018 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1021 API_TRACE_OUT(
"%ld", *pdwActiveProtocol)
1065 API_TRACE_IN(
"%ld %ld", hCard, dwDisposition)
1070 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
1078 scDisconnectStruct.hCard = hCard;
1079 scDisconnectStruct.dwDisposition = dwDisposition;
1083 sizeof(scDisconnectStruct), (
void *) &scDisconnectStruct);
1091 rv =
MessageReceive(&scDisconnectStruct,
sizeof(scDisconnectStruct),
1092 currentContextMap->dwClientID);
1098 SCardRemoveHandle(hCard);
1099 rv = scDisconnectStruct.rv;
1102 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1155 API_TRACE_IN(
"%ld", hCard)
1167 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
1172 scBeginStruct.hCard = hCard;
1176 currentContextMap->dwClientID,
1177 sizeof(scBeginStruct), (
void *) &scBeginStruct);
1186 currentContextMap->dwClientID);
1191 rv = scBeginStruct.rv;
1196 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1200 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1256 API_TRACE_IN(
"%ld", hCard)
1261 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
1266 scEndStruct.hCard = hCard;
1267 scEndStruct.dwDisposition = dwDisposition;
1272 sizeof(scEndStruct), (
void *) &scEndStruct);
1291 rv = scEndStruct.rv;
1294 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
1398 LPDWORD pcchReaderLen, LPDWORD pdwState,
1399 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1401 DWORD dwReaderLen, dwAtrLen;
1408 char *bufReader = NULL;
1409 LPBYTE bufAtr = NULL;
1422 if (pcchReaderLen == NULL)
1423 pcchReaderLen = &dummy;
1425 if (pcbAtrLen == NULL)
1429 dwReaderLen = *pcchReaderLen;
1430 dwAtrLen = *pcbAtrLen;
1441 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
1447 rv = getReaderStates(currentContextMap);
1451 r = pChannelMap->readerName;
1466 memset(&scStatusStruct, 0,
sizeof(scStatusStruct));
1467 scStatusStruct.hCard = hCard;
1470 sizeof(scStatusStruct), (
void *) &scStatusStruct);
1479 currentContextMap->dwClientID);
1484 rv = scStatusStruct.rv;
1488 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1505 *pcchReaderLen = strlen(pChannelMap->readerName) + 1;
1516 dwReaderLen = *pcchReaderLen;
1517 if (NULL == szReaderName)
1522 bufReader = malloc(dwReaderLen);
1523 if (NULL == bufReader)
1528 *(
char **)szReaderName = bufReader;
1531 bufReader = szReaderName;
1536 if (*pcchReaderLen > dwReaderLen)
1539 strncpy(bufReader, pChannelMap->readerName, dwReaderLen);
1544 dwAtrLen = *pcbAtrLen;
1550 bufAtr = malloc(dwAtrLen);
1556 *(LPBYTE *)pbAtr = bufAtr;
1563 if (*pcbAtrLen > dwAtrLen)
1566 memcpy(bufAtr,
readerStates[i].cardAtr, min(*pcbAtrLen, dwAtrLen));
1570 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1690 DWORD dwBreakFlag = 0;
1693 int currentReaderCount = 0;
1697 API_TRACE_IN(
"%ld %ld %d", hContext, dwTimeout, cReaders)
1699 for (j=0; j<cReaders; j++)
1701 API_TRACE_IN(
"[%d] %s %lX %lX", j, rgReaderStates[j].szReader,
1702 rgReaderStates[j].dwCurrentState, rgReaderStates[j].dwEventState)
1706 if ((rgReaderStates == NULL && cReaders > 0)
1714 for (j = 0; j < cReaders; j++)
1716 if (rgReaderStates[j].szReader == NULL)
1723 int nbNonIgnoredReaders = cReaders;
1725 for (j=0; j<cReaders; j++)
1727 nbNonIgnoredReaders--;
1729 if (0 == nbNonIgnoredReaders)
1746 if (NULL == currentContextMap)
1753 rv = getReaderStatesAndRegisterForEvents(currentContextMap);
1758 for (j=0; j<cReaders; j++)
1760 const char *readerName;
1763 readerName = rgReaderStates[j].szReader;
1766 if (strcmp(readerName,
readerStates[i].readerName) == 0)
1774 if (strcasecmp(readerName,
"\\\\?PnP?\\Notification") != 0)
1783 for (j = 0; j < cReaders; j++)
1784 rgReaderStates[j].dwEventState = 0;
1787 Log2(PCSC_LOG_DEBUG,
"Event Loop Start, dwTimeout: %ld", dwTimeout);
1792 currentReaderCount++;
1795 if ((DWORD)-1 == dwTimeout)
1805 currReader = &rgReaderStates[j];
1810 const char *readerName;
1814 readerName = currReader->szReader;
1817 if (strcmp(readerName,
readerStates[i].readerName) == 0)
1825 if (strcasecmp(readerName,
"\\\\?PnP?\\Notification") == 0)
1827 int k, newReaderCount = 0;
1833 if (newReaderCount != currentReaderCount)
1835 Log1(PCSC_LOG_INFO,
"Reader list changed");
1836 currentReaderCount = newReaderCount;
1844 currReader->dwEventState =
1860 uint32_t readerState;
1867 Log0(PCSC_LOG_DEBUG);
1878 if (currReader->dwCurrentState & 0xFFFF0000)
1880 unsigned int currentCounter;
1882 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
1888 Log0(PCSC_LOG_DEBUG);
1894 currReader->dwEventState = ((currReader->dwEventState & 0xffff )
1906 Log0(PCSC_LOG_DEBUG);
1917 Log0(PCSC_LOG_DEBUG);
1931 memcpy(currReader->rgbAtr, rContext->
cardAtr,
1935 currReader->cbAtr = 0;
1954 Log0(PCSC_LOG_DEBUG);
1972 Log0(PCSC_LOG_DEBUG);
1982 Log0(PCSC_LOG_DEBUG);
1992 Log0(PCSC_LOG_DEBUG);
2006 Log0(PCSC_LOG_DEBUG);
2020 Log0(PCSC_LOG_DEBUG);
2033 Log0(PCSC_LOG_DEBUG);
2036 else if (currReader-> dwCurrentState
2040 Log0(PCSC_LOG_DEBUG);
2052 Log0(PCSC_LOG_DEBUG);
2068 if (dwBreakFlag == 1)
2074 struct timeval before, after;
2076 gettimeofday(&before, NULL);
2087 &waitStatusStruct,
sizeof(waitStatusStruct),
2098 rv = unregisterFromEvents(currentContextMap);
2107 rv = waitStatusStruct.rv;
2112 rv = getReaderStatesAndRegisterForEvents(currentContextMap);
2120 gettimeofday(&after, NULL);
2122 dwTime -= diff/1000;
2142 Log1(PCSC_LOG_DEBUG,
"Event Loop End");
2147 (void)unregisterFromEvents(currentContextMap);
2149 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
2154 for (j=0; j<cReaders; j++)
2156 API_TRACE_OUT(
"[%d] %s %X %X", j, rgReaderStates[j].szReader,
2157 rgReaderStates[j].dwCurrentState, rgReaderStates[j].dwEventState)
2215 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
2216 LPDWORD lpBytesReturned)
2226 if (NULL != lpBytesReturned)
2227 *lpBytesReturned = 0;
2232 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
2247 scControlStruct.hCard = hCard;
2248 scControlStruct.dwControlCode = dwControlCode;
2249 scControlStruct.cbSendLength = cbSendLength;
2250 scControlStruct.cbRecvLength = cbRecvLength;
2251 scControlStruct.dwBytesReturned = 0;
2252 scControlStruct.rv = 0;
2255 sizeof(scControlStruct), &scControlStruct);
2261 rv =
MessageSend((
char *)pbSendBuffer, cbSendLength,
2262 currentContextMap->dwClientID);
2271 currentContextMap->dwClientID);
2279 rv =
MessageReceive(pbRecvBuffer, scControlStruct.dwBytesReturned,
2280 currentContextMap->dwClientID);
2287 if (NULL != lpBytesReturned)
2288 *lpBytesReturned = scControlStruct.dwBytesReturned;
2290 rv = scControlStruct.rv;
2293 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
2421 unsigned char *buf = NULL;
2425 if (NULL == pcbAttrLen)
2437 buf = malloc(*pcbAttrLen);
2444 *(
unsigned char **)pbAttr = buf;
2507 if (NULL == pbAttr || 0 == cbAttrLen)
2518 static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
2519 LPBYTE pbAttr, LPDWORD pcbAttrLen)
2529 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
2540 scGetSetStruct.hCard = hCard;
2541 scGetSetStruct.dwAttrId = dwAttrId;
2543 memset(scGetSetStruct.pbAttr, 0,
sizeof(scGetSetStruct.pbAttr));
2546 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
2547 scGetSetStruct.cbAttrLen = *pcbAttrLen;
2551 scGetSetStruct.cbAttrLen =
sizeof scGetSetStruct.pbAttr;
2554 sizeof(scGetSetStruct), &scGetSetStruct);
2563 currentContextMap->dwClientID);
2573 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
2577 DWORD correct_value = scGetSetStruct.cbAttrLen;
2578 scGetSetStruct.cbAttrLen = *pcbAttrLen;
2579 *pcbAttrLen = correct_value;
2584 *pcbAttrLen = scGetSetStruct.cbAttrLen;
2587 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
2589 memset(scGetSetStruct.pbAttr, 0x00,
sizeof(scGetSetStruct.pbAttr));
2591 rv = scGetSetStruct.rv;
2594 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
2658 LPCBYTE pbSendBuffer, DWORD cbSendLength,
2660 LPDWORD pcbRecvLength)
2669 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
2670 pcbRecvLength == NULL || pioSendPci == NULL)
2679 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
2695 scTransmitStruct.hCard = hCard;
2696 scTransmitStruct.cbSendLength = cbSendLength;
2697 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
2698 scTransmitStruct.ioSendPciProtocol = pioSendPci->
dwProtocol;
2699 scTransmitStruct.ioSendPciLength = pioSendPci->
cbPciLength;
2704 scTransmitStruct.ioRecvPciProtocol = pioRecvPci->
dwProtocol;
2705 scTransmitStruct.ioRecvPciLength = pioRecvPci->
cbPciLength;
2714 sizeof(scTransmitStruct), (
void *) &scTransmitStruct);
2720 rv =
MessageSend((
void *)pbSendBuffer, cbSendLength,
2738 rv =
MessageReceive(pbRecvBuffer, scTransmitStruct.pcbRecvLength,
2746 pioRecvPci->
dwProtocol = scTransmitStruct.ioRecvPciProtocol;
2747 pioRecvPci->
cbPciLength = scTransmitStruct.ioRecvPciLength;
2751 rv = scTransmitStruct.rv;
2755 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
2760 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
2763 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
2833 LPSTR mszReaders, LPDWORD pcchReaders)
2835 DWORD dwReadersLen = 0;
2843 API_TRACE_IN(
"%ld", hContext)
2848 if (pcchReaders == NULL)
2855 if (NULL == currentContextMap)
2862 rv = getReaderStates(currentContextMap);
2869 dwReadersLen += strlen(
readerStates[i].readerName) + 1;
2874 if (1 == dwReadersLen)
2882 if (NULL == mszReaders)
2887 buf = malloc(dwReadersLen);
2893 *(
char **)mszReaders = buf;
2900 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
2907 if (mszReaders == NULL)
2925 *pcchReaders = dwReadersLen;
2927 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
2930 API_TRACE_OUT(
"%d", *pcchReaders)
2960 free((
void *)pvMem);
3028 const char ReaderGroup[] =
"SCard$DefaultReaders\0";
3029 const unsigned int dwGroups =
sizeof(ReaderGroup);
3035 if (NULL == currentContextMap)
3040 if (NULL == mszGroups)
3045 buf = malloc(dwGroups);
3051 *(
char **)mszGroups = buf;
3057 if ((NULL != mszGroups) && (*pcchGroups < dwGroups))
3065 memcpy(buf, ReaderGroup, dwGroups);
3068 *pcchGroups = dwGroups;
3070 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
3112 uint32_t dwClientID = 0;
3117 API_TRACE_IN(
"%ld", hContext)
3125 if (NULL == currentContextMap)
3147 scCancelStruct.hContext = hContext;
3151 sizeof(scCancelStruct), (
void *) &scCancelStruct);
3159 rv =
MessageReceive(&scCancelStruct,
sizeof(scCancelStruct), dwClientID);
3164 rv = scCancelStruct.rv;
3203 API_TRACE_IN(
"%ld", hContext)
3241 if (NULL == newContextMap)
3244 Log2(PCSC_LOG_DEBUG,
"Allocating new SCONTEXTMAP @%p", newContextMap);
3245 newContextMap->
hContext = hContext;
3249 (void)pthread_mutex_init(&newContextMap->
mMutex, NULL);
3251 lrv = list_init(&newContextMap->channelMapList);
3254 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d", lrv);
3258 lrv = list_attributes_seeker(&newContextMap->channelMapList,
3259 CHANNEL_MAP_seeker);
3262 Log2(PCSC_LOG_CRITICAL,
3263 "list_attributes_seeker failed with return value: %d", lrv);
3264 list_destroy(&newContextMap->channelMapList);
3268 lrv = list_append(&contextMapList, newContextMap);
3271 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3273 list_destroy(&newContextMap->channelMapList);
3281 (void)pthread_mutex_destroy(&newContextMap->
mMutex);
3282 free(newContextMap);
3311 if (NULL != currentContextMap)
3312 (void)pthread_mutex_lock(¤tContextMap->
mMutex);
3316 return currentContextMap;
3333 return list_seek(&contextMapList, &hContext);
3347 if (NULL != currentContextMap)
3348 SCardCleanContext(currentContextMap);
3351 static void SCardCleanContext(
SCONTEXTMAP * targetContextMap)
3353 int list_index, lrv;
3360 (void)pthread_mutex_destroy(&targetContextMap->
mMutex);
3362 listSize = list_size(&targetContextMap->channelMapList);
3363 for (list_index = 0; list_index < listSize; list_index++)
3365 currentChannelMap = list_get_at(&targetContextMap->channelMapList,
3367 if (NULL == currentChannelMap)
3369 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3375 free(currentChannelMap->readerName);
3376 free(currentChannelMap);
3380 list_destroy(&targetContextMap->channelMapList);
3382 lrv = list_delete(&contextMapList, targetContextMap);
3385 Log2(PCSC_LOG_CRITICAL,
3386 "list_delete failed with return value: %d", lrv);
3389 free(targetContextMap);
3405 if (NULL == newChannelMap)
3408 newChannelMap->hCard = hCard;
3409 newChannelMap->readerName = strdup(readerName);
3411 lrv = list_append(¤tContextMap->channelMapList, newChannelMap);
3414 free(newChannelMap->readerName);
3415 free(newChannelMap);
3416 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3431 rv = SCardGetContextAndChannelFromHandleTH(hCard, ¤tContextMap,
3432 ¤tChannelMap);
3436 free(currentChannelMap->readerName);
3438 lrv = list_delete(¤tContextMap->channelMapList, currentChannelMap);
3441 Log2(PCSC_LOG_CRITICAL,
3442 "list_delete failed with return value: %d", lrv);
3445 free(currentChannelMap);
3450 static LONG SCardGetContextChannelAndLockFromHandle(
SCARDHANDLE hCard,
3459 rv = SCardGetContextAndChannelFromHandleTH(hCard, targetContextMap,
3463 (void)pthread_mutex_lock(&(*targetContextMap)->mMutex);
3470 static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE hCard,
3479 *targetContextMap = NULL;
3480 *targetChannelMap = NULL;
3482 listSize = list_size(&contextMapList);
3484 for (list_index = 0; list_index < listSize; list_index++)
3486 currentContextMap = list_get_at(&contextMapList, list_index);
3487 if (currentContextMap == NULL)
3489 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3493 currentChannelMap = list_seek(¤tContextMap->channelMapList,
3495 if (currentChannelMap != NULL)
3497 *targetContextMap = currentContextMap;
3498 *targetChannelMap = currentChannelMap;
3516 struct stat statBuffer;
3519 socketName = getSocketName();
3520 rv = stat(socketName, &statBuffer);
3524 Log3(PCSC_LOG_INFO,
"PCSC Not Running: %s: %s",
3525 socketName, strerror(errno));
3532 static LONG getReaderStates(
SCONTEXTMAP * currentContextMap)
3534 int32_t dwClientID = currentContextMap->
dwClientID;
3549 static LONG getReaderStatesAndRegisterForEvents(
SCONTEXTMAP * currentContextMap)
3551 int32_t dwClientID = currentContextMap->
dwClientID;
3565 static LONG unregisterFromEvents(
SCONTEXTMAP * currentContextMap)
3567 int32_t dwClientID = currentContextMap->
dwClientID;
3573 dwClientID, 0, NULL);
3590 rv = waitStatusStruct.rv;