87 #include <sys/types.h>
118 #define SCARD_PROTOCOL_ANY_OLD 0x1000
125 static char sharing_shall_block = TRUE;
127 #define COLOR_RED "\33[01;31m"
128 #define COLOR_GREEN "\33[32m"
129 #define COLOR_BLUE "\33[34m"
130 #define COLOR_MAGENTA "\33[35m"
131 #define COLOR_NORMAL "\33[0m"
138 static void trace(
const char *func,
const char direction,
const char *fmt, ...)
142 fprintf(stderr, COLOR_GREEN
"%c " COLOR_BLUE
"[%lX] " COLOR_GREEN
"%s ",
143 direction, pthread_self(), func);
145 fprintf(stderr, COLOR_MAGENTA);
147 vfprintf(stderr, fmt, args);
150 fprintf(stderr, COLOR_NORMAL
"\n");
153 #define API_TRACE_IN(...) trace(__FUNCTION__, '<', __VA_ARGS__);
154 #define API_TRACE_OUT(...) trace(__FUNCTION__, '>', __VA_ARGS__);
156 #define API_TRACE_IN(...)
157 #define API_TRACE_OUT(...)
162 #define PROFILE_FILE "/tmp/pcsc_profile"
164 #include <sys/time.h>
167 #define MAX_THREADS 5
168 pthread_t threads[MAX_THREADS];
169 struct timeval profile_time_start[MAX_THREADS];
173 #define PROFILE_START profile_start();
174 #define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
176 static void profile_start(
void)
178 static char initialized = FALSE;
187 sprintf(filename,
"%s-%d", PROFILE_FILE, getuid());
188 profile_fd = fopen(filename,
"a+");
189 if (NULL == profile_fd)
191 fprintf(stderr, COLOR_RED
"Can't open %s: %s" COLOR_NORMAL
"\n",
192 PROFILE_FILE, strerror(errno));
195 fprintf(profile_fd,
"\nStart a new profile\n");
197 if (isatty(fileno(stderr)))
204 for (i=0; i<MAX_THREADS; i++)
205 if (pthread_equal(0, threads[i]))
211 gettimeofday(&profile_time_start[i], NULL);
214 static void profile_end(
const char *f, LONG rv)
216 struct timeval profile_time_end;
221 gettimeofday(&profile_time_end, NULL);
224 for (i=0; i<MAX_THREADS; i++)
225 if (pthread_equal(t, threads[i]))
230 fprintf(stderr, COLOR_BLUE
" WARNING: no start info for %s\n", f);
234 d =
time_sub(&profile_time_end, &profile_time_start[i]);
243 COLOR_RED
"RESULT %s " COLOR_MAGENTA
"%ld "
244 COLOR_BLUE
"0x%08lX %s" COLOR_NORMAL
"\n",
247 fprintf(stderr, COLOR_RED
"RESULT %s " COLOR_MAGENTA
"%ld"
248 COLOR_NORMAL
"\n", f, d);
250 fprintf(profile_fd,
"%s %ld\n", f, d);
255 #define PROFILE_START
256 #define PROFILE_END(rv)
271 static int CHANNEL_MAP_seeker(
const void *el,
const void *key)
275 if ((el == NULL) || (key == NULL))
277 Log3(PCSC_LOG_CRITICAL,
278 "CHANNEL_MAP_seeker called with NULL pointer: el=%p, key=%p",
304 static list_t contextMapList;
306 static int SCONTEXTMAP_seeker(
const void *el,
const void *key)
310 if ((el == NULL) || (key == NULL))
312 Log3(PCSC_LOG_CRITICAL,
313 "SCONTEXTMAP_seeker called with NULL pointer: el=%p, key=%p",
356 static LONG SCardGetContextAndChannelFromHandle(
SCARDHANDLE,
358 static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE,
362 static void SCardInvalidateHandles(
void);
363 static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
364 LPBYTE pbAttr, LPDWORD pcbAttrLen);
366 static LONG getReaderStates(
SCONTEXTMAP * currentContextMap);
379 return pthread_mutex_lock(&clientMutex);
389 return pthread_mutex_unlock(&clientMutex);
429 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
432 static int first_time = TRUE;
434 API_TRACE_IN(
"%ld, %p, %p", dwScope, pvReserved1, pvReserved2)
443 pthread_atfork(NULL, NULL, SCardInvalidateHandles);
457 pvReserved2, phContext);
462 API_TRACE_OUT(
"%ld", *phContext)
495 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
499 uint32_t dwClientID = 0;
503 if (phContext == NULL)
520 lrv = list_init(&contextMapList);
523 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d",
528 lrv = list_attributes_seeker(&contextMapList,
532 Log2(PCSC_LOG_CRITICAL,
533 "list_attributes_seeker failed with return value: %d", lrv);
534 list_destroy(&contextMapList);
538 if (getenv(
"PCSCLITE_NO_BLOCKING"))
540 Log1(PCSC_LOG_INFO,
"Disable shared blocking");
541 sharing_shall_block = FALSE;
570 Log1(PCSC_LOG_CRITICAL,
571 "Your pcscd is too old and does not support CMD_VERSION");
575 Log3(PCSC_LOG_INFO,
"Server is protocol version %d:%d",
586 scEstablishStruct.dwScope = dwScope;
587 scEstablishStruct.hContext = 0;
591 sizeof(scEstablishStruct), (
void *) &scEstablishStruct);
599 rv =
MessageReceive(&scEstablishStruct,
sizeof(scEstablishStruct),
606 return scEstablishStruct.rv;
614 *phContext = scEstablishStruct.hContext;
651 API_TRACE_IN(
"%ld", hContext)
659 if (NULL == currentContextMap)
665 (void)pthread_mutex_lock(currentContextMap->mMutex);
669 if (NULL == currentContextMap)
678 scReleaseStruct.hContext = hContext;
682 currentContextMap->dwClientID,
683 sizeof(scReleaseStruct), (
void *) &scReleaseStruct);
692 currentContextMap->dwClientID);
697 rv = scReleaseStruct.rv;
699 (void)pthread_mutex_unlock(currentContextMap->mMutex);
772 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
773 LPDWORD pdwActiveProtocol)
780 API_TRACE_IN(
"%ld %s %ld %ld", hContext, szReader, dwShareMode, dwPreferredProtocols)
785 if (phCard == NULL || pdwActiveProtocol == NULL)
790 if (szReader == NULL)
796 if (strlen(szReader) > MAX_READERNAME)
803 if (NULL == currentContextMap)
806 (void)pthread_mutex_lock(currentContextMap->mMutex);
810 if (NULL == currentContextMap)
816 strlcpy(scConnectStruct.szReader, szReader,
sizeof scConnectStruct.szReader);
818 scConnectStruct.hContext = hContext;
819 scConnectStruct.dwShareMode = dwShareMode;
820 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
821 scConnectStruct.hCard = 0;
822 scConnectStruct.dwActiveProtocol = 0;
826 sizeof(scConnectStruct), (
void *) &scConnectStruct);
835 currentContextMap->dwClientID);
840 *phCard = scConnectStruct.hCard;
841 *pdwActiveProtocol = scConnectStruct.dwActiveProtocol;
848 rv = SCardAddHandle(*phCard, currentContextMap, szReader);
851 rv = scConnectStruct.rv;
854 (void)pthread_mutex_unlock(currentContextMap->mMutex);
857 API_TRACE_OUT(
"%d", *pdwActiveProtocol)
936 DWORD dwPreferredProtocols, DWORD dwInitialization,
937 LPDWORD pdwActiveProtocol)
946 if (pdwActiveProtocol == NULL)
952 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
957 (void)pthread_mutex_lock(currentContextMap->mMutex);
960 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
971 scReconnectStruct.hCard = hCard;
972 scReconnectStruct.dwShareMode = dwShareMode;
973 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
974 scReconnectStruct.dwInitialization = dwInitialization;
975 scReconnectStruct.dwActiveProtocol = *pdwActiveProtocol;
979 sizeof(scReconnectStruct), (
void *) &scReconnectStruct);
987 rv =
MessageReceive(&scReconnectStruct,
sizeof(scReconnectStruct),
988 currentContextMap->dwClientID);
993 rv = scReconnectStruct.rv;
1001 *pdwActiveProtocol = scReconnectStruct.dwActiveProtocol;
1004 (void)pthread_mutex_unlock(currentContextMap->mMutex);
1050 API_TRACE_IN(
"%ld %ld", hCard, dwDisposition)
1055 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
1063 (void)pthread_mutex_lock(currentContextMap->mMutex);
1066 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
1077 scDisconnectStruct.hCard = hCard;
1078 scDisconnectStruct.dwDisposition = dwDisposition;
1082 sizeof(scDisconnectStruct), (
void *) &scDisconnectStruct);
1090 rv =
MessageReceive(&scDisconnectStruct,
sizeof(scDisconnectStruct),
1091 currentContextMap->dwClientID);
1097 (void)SCardRemoveHandle(hCard);
1098 rv = scDisconnectStruct.rv;
1101 (void)pthread_mutex_unlock(currentContextMap->mMutex);
1158 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
1163 (void)pthread_mutex_lock(currentContextMap->mMutex);
1166 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
1174 scBeginStruct.hCard = hCard;
1185 currentContextMap->dwClientID,
1186 sizeof(scBeginStruct), (
void *) &scBeginStruct);
1195 currentContextMap->dwClientID);
1200 rv = scBeginStruct.rv;
1205 (void)pthread_mutex_unlock(currentContextMap->mMutex);
1265 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
1270 (void)pthread_mutex_lock(currentContextMap->
mMutex);
1273 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
1281 scEndStruct.hCard = hCard;
1282 scEndStruct.dwDisposition = dwDisposition;
1287 sizeof(scEndStruct), (
void *) &scEndStruct);
1304 randnum = SYS_RandomInt(1000, 10000);
1306 rv = scEndStruct.rv;
1309 (void)pthread_mutex_unlock(currentContextMap->
mMutex);
1412 LPDWORD pcchReaderLen, LPDWORD pdwState,
1413 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1415 DWORD dwReaderLen, dwAtrLen;
1422 char *bufReader = NULL;
1423 LPBYTE bufAtr = NULL;
1436 if (pcchReaderLen == NULL)
1437 pcchReaderLen = &dummy;
1439 if (pcbAtrLen == NULL)
1443 dwReaderLen = *pcchReaderLen;
1444 dwAtrLen = *pcbAtrLen;
1452 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
1457 (void)pthread_mutex_lock(currentContextMap->mMutex);
1460 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
1469 rv = getReaderStates(currentContextMap);
1473 r = pChannelMap->readerName;
1477 if (r && strcmp(r, readerStates[i].readerName) == 0)
1481 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
1491 memset(&scStatusStruct, 0,
sizeof(scStatusStruct));
1492 scStatusStruct.hCard = hCard;
1495 sizeof(scStatusStruct), (
void *) &scStatusStruct);
1504 currentContextMap->dwClientID);
1509 rv = scStatusStruct.rv;
1529 *pcchReaderLen = strlen(pChannelMap->readerName) + 1;
1533 *pdwState = (readerStates[i].
eventCounter << 16) + readerStates[i].readerState;
1540 dwReaderLen = *pcchReaderLen;
1541 bufReader = malloc(dwReaderLen);
1542 if (NULL == bufReader)
1547 if (NULL == mszReaderName)
1552 *(
char **)mszReaderName = bufReader;
1555 bufReader = mszReaderName;
1560 if (*pcchReaderLen > dwReaderLen)
1563 strncpy(bufReader, pChannelMap->readerName, dwReaderLen);
1568 dwAtrLen = *pcbAtrLen;
1569 bufAtr = malloc(dwAtrLen);
1580 *(LPBYTE *)pbAtr = bufAtr;
1587 if (*pcbAtrLen > dwAtrLen)
1590 memcpy(bufAtr, readerStates[i].cardAtr, min(*pcbAtrLen, dwAtrLen));
1594 (void)pthread_mutex_unlock(currentContextMap->mMutex);
1700 DWORD dwBreakFlag = 0;
1703 int currentReaderCount = 0;
1707 API_TRACE_IN(
"%ld %ld %d", hContext, dwTimeout, cReaders)
1709 for (j=0; j<cReaders; j++)
1711 API_TRACE_IN(
"[%d] %s %lX %lX", j, rgReaderStates[j].szReader,
1712 rgReaderStates[j].dwCurrentState, rgReaderStates[j].dwEventState)
1716 if ((rgReaderStates == NULL && cReaders > 0)
1724 for (j = 0; j < cReaders; j++)
1726 if (rgReaderStates[j].szReader == NULL)
1733 int nbNonIgnoredReaders = cReaders;
1735 for (j=0; j<cReaders; j++)
1737 nbNonIgnoredReaders--;
1739 if (0 == nbNonIgnoredReaders)
1756 if (NULL == currentContextMap)
1762 (void)pthread_mutex_lock(currentContextMap->
mMutex);
1766 if (NULL == currentContextMap)
1776 rv = getReaderStates(currentContextMap);
1781 for (j=0; j<cReaders; j++)
1783 const char *readerName;
1786 readerName = rgReaderStates[j].szReader;
1789 if (strcmp(readerName, readerStates[i].readerName) == 0)
1794 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
1797 if (strcasecmp(readerName,
"\\\\?PnP?\\Notification") != 0)
1806 for (j = 0; j < cReaders; j++)
1807 rgReaderStates[j].dwEventState = 0;
1810 Log2(PCSC_LOG_DEBUG,
"Event Loop Start, dwTimeout: %ld", dwTimeout);
1814 if (readerStates[j].readerName[0] !=
'\0')
1815 currentReaderCount++;
1818 if ((DWORD)-1 == dwTimeout)
1828 currReader = &rgReaderStates[j];
1833 const char *readerName;
1837 readerName = currReader->szReader;
1840 if (strcmp(readerName, readerStates[i].readerName) == 0)
1845 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
1848 if (strcasecmp(readerName,
"\\\\?PnP?\\Notification") == 0)
1850 int k, newReaderCount = 0;
1853 if (readerStates[k].readerName[0] !=
'\0')
1856 if (newReaderCount != currentReaderCount)
1858 Log1(PCSC_LOG_INFO,
"Reader list changed");
1859 currentReaderCount = newReaderCount;
1867 currReader->dwEventState =
1883 uint32_t readerState;
1890 Log0(PCSC_LOG_DEBUG);
1895 rContext = &readerStates[i];
1901 if (currReader->dwCurrentState & 0xFFFF0000)
1903 unsigned int currentCounter;
1905 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
1911 Log0(PCSC_LOG_DEBUG);
1917 currReader->dwEventState = ((currReader->dwEventState & 0xffff )
1929 Log0(PCSC_LOG_DEBUG);
1938 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
1940 Log0(PCSC_LOG_DEBUG);
1954 memcpy(currReader->rgbAtr, rContext->
cardAtr,
1958 currReader->cbAtr = 0;
1977 Log0(PCSC_LOG_DEBUG);
1982 else if (readerState & SCARD_PRESENT)
1995 Log0(PCSC_LOG_DEBUG);
2005 Log0(PCSC_LOG_DEBUG);
2015 Log0(PCSC_LOG_DEBUG);
2029 Log0(PCSC_LOG_DEBUG);
2036 if (readerState & SCARD_PRESENT)
2043 Log0(PCSC_LOG_DEBUG);
2056 Log0(PCSC_LOG_DEBUG);
2059 else if (currReader-> dwCurrentState
2063 Log0(PCSC_LOG_DEBUG);
2075 Log0(PCSC_LOG_DEBUG);
2091 if (dwBreakFlag == 1)
2097 struct timeval before, after;
2099 gettimeofday(&before, NULL);
2101 waitStatusStruct.
timeOut = dwTime;
2109 sizeof(waitStatusStruct), &waitStatusStruct);
2118 &waitStatusStruct,
sizeof(waitStatusStruct),
2130 sizeof(waitStatusStruct), &waitStatusStruct);
2137 sizeof(waitStatusStruct),
2150 rv = waitStatusStruct.rv;
2155 rv = getReaderStates(currentContextMap);
2163 gettimeofday(&after, NULL);
2165 dwTime -= diff/1000;
2185 Log1(PCSC_LOG_DEBUG,
"Event Loop End");
2187 (void)pthread_mutex_unlock(currentContextMap->
mMutex);
2192 for (j=0; j<cReaders; j++)
2194 API_TRACE_OUT(
"[%d] %s %X %X", j, rgReaderStates[j].szReader,
2195 rgReaderStates[j].dwCurrentState, rgReaderStates[j].dwEventState)
2253 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
2254 LPDWORD lpBytesReturned)
2264 if (NULL != lpBytesReturned)
2265 *lpBytesReturned = 0;
2270 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
2278 (void)pthread_mutex_lock(currentContextMap->mMutex);
2281 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
2296 scControlStruct.hCard = hCard;
2297 scControlStruct.dwControlCode = dwControlCode;
2298 scControlStruct.cbSendLength = cbSendLength;
2299 scControlStruct.cbRecvLength = cbRecvLength;
2300 scControlStruct.dwBytesReturned = 0;
2301 scControlStruct.rv = 0;
2304 sizeof(scControlStruct), &scControlStruct);
2310 rv =
MessageSend((
char *)pbSendBuffer, cbSendLength,
2311 currentContextMap->dwClientID);
2320 currentContextMap->dwClientID);
2328 rv =
MessageReceive(pbRecvBuffer, scControlStruct.dwBytesReturned,
2329 currentContextMap->dwClientID);
2336 if (NULL != lpBytesReturned)
2337 *lpBytesReturned = scControlStruct.dwBytesReturned;
2339 rv = scControlStruct.rv;
2342 (void)pthread_mutex_unlock(currentContextMap->mMutex);
2457 unsigned char *buf = NULL;
2461 if (NULL == pcbAttrLen)
2473 buf = malloc(*pcbAttrLen);
2480 *(
unsigned char **)pbAttr = buf;
2543 if (NULL == pbAttr || 0 == cbAttrLen)
2554 static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
2555 LPBYTE pbAttr, LPDWORD pcbAttrLen)
2565 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
2570 (void)pthread_mutex_lock(currentContextMap->mMutex);
2573 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
2587 scGetSetStruct.hCard = hCard;
2588 scGetSetStruct.dwAttrId = dwAttrId;
2589 scGetSetStruct.cbAttrLen = *pcbAttrLen;
2591 memset(scGetSetStruct.pbAttr, 0,
sizeof(scGetSetStruct.pbAttr));
2593 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
2596 sizeof(scGetSetStruct), &scGetSetStruct);
2605 currentContextMap->dwClientID);
2615 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
2617 scGetSetStruct.cbAttrLen = *pcbAttrLen;
2621 *pcbAttrLen = scGetSetStruct.cbAttrLen;
2624 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
2626 memset(scGetSetStruct.pbAttr, 0x00,
sizeof(scGetSetStruct.pbAttr));
2628 rv = scGetSetStruct.rv;
2631 (void)pthread_mutex_unlock(currentContextMap->mMutex);
2695 LPCBYTE pbSendBuffer, DWORD cbSendLength,
2697 LPDWORD pcbRecvLength)
2706 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
2707 pcbRecvLength == NULL || pioSendPci == NULL)
2713 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
2722 (void)pthread_mutex_lock(currentContextMap->
mMutex);
2725 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
2743 scTransmitStruct.hCard = hCard;
2744 scTransmitStruct.cbSendLength = cbSendLength;
2745 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
2746 scTransmitStruct.ioSendPciProtocol = pioSendPci->
dwProtocol;
2747 scTransmitStruct.ioSendPciLength = pioSendPci->
cbPciLength;
2752 scTransmitStruct.ioRecvPciProtocol = pioRecvPci->
dwProtocol;
2753 scTransmitStruct.ioRecvPciLength = pioRecvPci->
cbPciLength;
2762 sizeof(scTransmitStruct), (
void *) &scTransmitStruct);
2768 rv =
MessageSend((
void *)pbSendBuffer, cbSendLength,
2786 rv =
MessageReceive(pbRecvBuffer, scTransmitStruct.pcbRecvLength,
2794 pioRecvPci->
dwProtocol = scTransmitStruct.ioRecvPciProtocol;
2795 pioRecvPci->
cbPciLength = scTransmitStruct.ioRecvPciLength;
2799 rv = scTransmitStruct.rv;
2807 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
2810 (void)pthread_mutex_unlock(currentContextMap->
mMutex);
2868 LPSTR mszReaders, LPDWORD pcchReaders)
2870 DWORD dwReadersLen = 0;
2878 API_TRACE_IN(
"%ld", hContext)
2883 if (pcchReaders == NULL)
2890 if (NULL == currentContextMap)
2896 (void)pthread_mutex_lock(currentContextMap->
mMutex);
2900 if (NULL == currentContextMap)
2907 rv = getReaderStates(currentContextMap);
2913 if (readerStates[i].readerName[0] !=
'\0')
2914 dwReadersLen += strlen(readerStates[i].readerName) + 1;
2919 if (1 == dwReadersLen)
2927 buf = malloc(dwReadersLen);
2933 if (NULL == mszReaders)
2938 *(
char **)mszReaders = buf;
2945 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
2952 if (mszReaders == NULL)
2957 if (readerStates[i].readerName[0] !=
'\0')
2962 strcpy(buf, readerStates[i].readerName);
2963 buf += strlen(readerStates[i].readerName)+1;
2970 *pcchReaders = dwReadersLen;
2972 (void)pthread_mutex_unlock(currentContextMap->
mMutex);
2975 API_TRACE_OUT(
"%d", *pcchReaders)
3004 if (NULL == currentContextMap)
3007 free((
void *)pvMem);
3075 const char ReaderGroup[] =
"SCard$DefaultReaders\0";
3076 const unsigned int dwGroups =
sizeof(ReaderGroup);
3082 if (NULL == currentContextMap)
3085 (void)pthread_mutex_lock(currentContextMap->
mMutex);
3089 if (NULL == currentContextMap)
3097 buf = malloc(dwGroups);
3103 if (NULL == mszGroups)
3108 *(
char **)mszGroups = buf;
3114 if ((NULL != mszGroups) && (*pcchGroups < dwGroups))
3122 memcpy(buf, ReaderGroup, dwGroups);
3125 *pcchGroups = dwGroups;
3127 (void)pthread_mutex_unlock(currentContextMap->
mMutex);
3167 uint32_t dwClientID = 0;
3171 API_TRACE_IN(
"%ld", hContext)
3177 if (NULL == currentContextMap)
3183 if (! currentContextMap->cancellable)
3196 scCancelStruct.hContext = hContext;
3200 sizeof(scCancelStruct), (
void *) &scCancelStruct);
3208 rv =
MessageReceive(&scCancelStruct,
sizeof(scCancelStruct), dwClientID);
3213 rv = scCancelStruct.rv;
3253 API_TRACE_IN(
"%ld", hContext)
3261 if (currentContextMap == NULL)
3292 if (NULL == newContextMap)
3295 Log2(PCSC_LOG_DEBUG,
"Allocating new SCONTEXTMAP @%p", newContextMap);
3296 newContextMap->
hContext = hContext;
3300 newContextMap->
mMutex = malloc(
sizeof(pthread_mutex_t));
3301 if (NULL == newContextMap->
mMutex)
3303 Log2(PCSC_LOG_DEBUG,
"Freeing SCONTEXTMAP @%p", newContextMap);
3304 free(newContextMap);
3307 (void)pthread_mutex_init(newContextMap->
mMutex, NULL);
3309 lrv = list_init(&(newContextMap->channelMapList));
3312 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d", lrv);
3316 lrv = list_attributes_seeker(&(newContextMap->channelMapList),
3317 CHANNEL_MAP_seeker);
3320 Log2(PCSC_LOG_CRITICAL,
3321 "list_attributes_seeker failed with return value: %d", lrv);
3322 list_destroy(&(newContextMap->channelMapList));
3326 lrv = list_append(&contextMapList, newContextMap);
3329 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3331 list_destroy(&(newContextMap->channelMapList));
3339 (void)pthread_mutex_destroy(newContextMap->
mMutex);
3340 free(newContextMap->
mMutex);
3341 free(newContextMap);
3366 return currentContextMap;
3383 return list_seek(&contextMapList, &hContext);
3400 if (NULL == currentContextMap)
3403 return SCardCleanContext(currentContextMap);
3406 static LONG SCardCleanContext(
SCONTEXTMAP * targetContextMap)
3408 int list_index, lrv;
3415 (void)pthread_mutex_destroy(targetContextMap->
mMutex);
3416 free(targetContextMap->
mMutex);
3417 targetContextMap->
mMutex = NULL;
3419 listSize = list_size(&(targetContextMap->channelMapList));
3420 for (list_index = 0; list_index < listSize; list_index++)
3422 currentChannelMap = list_get_at(&(targetContextMap->channelMapList),
3424 if (NULL == currentChannelMap)
3426 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3432 free(currentChannelMap->readerName);
3433 free(currentChannelMap);
3437 list_destroy(&(targetContextMap->channelMapList));
3439 lrv = list_delete(&contextMapList, targetContextMap);
3442 Log2(PCSC_LOG_CRITICAL,
3443 "list_delete failed with return value: %d", lrv);
3446 free(targetContextMap);
3462 if (NULL == newChannelMap)
3465 newChannelMap->hCard = hCard;
3466 newChannelMap->readerName = strdup(readerName);
3468 lrv = list_append(&(currentContextMap->channelMapList), newChannelMap);
3471 free(newChannelMap->readerName);
3472 free(newChannelMap);
3473 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3488 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
3489 ¤tChannelMap);
3493 free(currentChannelMap->readerName);
3495 lrv = list_delete(&(currentContextMap->channelMapList), currentChannelMap);
3498 Log2(PCSC_LOG_CRITICAL,
3499 "list_delete failed with return value: %d", lrv);
3502 free(currentChannelMap);
3507 static LONG SCardGetContextAndChannelFromHandle(
SCARDHANDLE hCard,
3516 rv = SCardGetContextAndChannelFromHandleTH(hCard, targetContextMap,
3523 static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE hCard,
3532 *targetContextMap = NULL;
3533 *targetChannelMap = NULL;
3535 listSize = list_size(&contextMapList);
3537 for (list_index = 0; list_index < listSize; list_index++)
3539 currentContextMap = list_get_at(&contextMapList, list_index);
3540 if (currentContextMap == NULL)
3542 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3546 currentChannelMap = list_seek(&(currentContextMap->channelMapList),
3548 if (currentChannelMap != NULL)
3550 *targetContextMap = currentContextMap;
3551 *targetChannelMap = currentChannelMap;
3573 struct stat statBuffer;
3576 socketName = getSocketName();
3577 rv = stat(socketName, &statBuffer);
3581 Log3(PCSC_LOG_INFO,
"PCSC Not Running: %s: %s",
3582 socketName, strerror(errno));
3589 static void SCardInvalidateHandles(
void)
3594 while (list_size(&contextMapList) != 0)
3598 currentContextMap = list_get_at(&contextMapList, 0);
3599 if (currentContextMap != NULL)
3600 (void)SCardCleanContext(currentContextMap);
3602 Log1(PCSC_LOG_CRITICAL,
"list_get_at returned NULL");
3608 static LONG getReaderStates(
SCONTEXTMAP * currentContextMap)
3610 int32_t dwClientID = currentContextMap->
dwClientID;
3618 rv =
MessageReceive(&readerStates,
sizeof(readerStates), dwClientID);