108 #include <sys/types.h>
114 #include <sys/time.h>
116 #include <sys/wait.h>
138 static bool sharing_shall_block =
true;
140 #define COLOR_RED "\33[01;31m"
141 #define COLOR_GREEN "\33[32m"
142 #define COLOR_BLUE "\33[34m"
143 #define COLOR_MAGENTA "\33[35m"
144 #define COLOR_NORMAL "\33[0m"
151 static void trace(
const char *func,
const char direction,
const char *fmt, ...)
155 fprintf(stderr, COLOR_GREEN
"%c " COLOR_BLUE
"[%lX] " COLOR_GREEN
"%s ",
156 direction, pthread_self(), func);
158 fprintf(stderr, COLOR_MAGENTA);
160 vfprintf(stderr, fmt, args);
163 fprintf(stderr, COLOR_NORMAL
"\n");
166 #define API_TRACE_IN(...) trace(__FUNCTION__, '<', __VA_ARGS__);
167 #define API_TRACE_OUT(...) trace(__FUNCTION__, '>', __VA_ARGS__);
169 #define API_TRACE_IN(...)
170 #define API_TRACE_OUT(...)
175 #define PROFILE_FILE "/tmp/pcsc_profile"
177 #include <sys/time.h>
180 #define MAX_THREADS 5
181 pthread_t threads[MAX_THREADS];
182 struct timeval profile_time_start[MAX_THREADS];
186 #define PROFILE_START profile_start();
187 #define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
189 static void profile_start(
void)
191 static bool initialized =
false;
200 sprintf(filename,
"%s-%d", PROFILE_FILE, getuid());
201 profile_fd = fopen(filename,
"a+");
202 if (NULL == profile_fd)
204 fprintf(stderr, COLOR_RED
"Can't open %s: %s" COLOR_NORMAL
"\n",
205 PROFILE_FILE, strerror(errno));
208 fprintf(profile_fd,
"\nStart a new profile\n");
210 if (isatty(fileno(stderr)))
217 for (i=0; i<MAX_THREADS; i++)
218 if (pthread_equal(0, threads[i]))
224 gettimeofday(&profile_time_start[i], NULL);
227 static void profile_end(
const char *f, LONG rv)
229 struct timeval profile_time_end;
234 gettimeofday(&profile_time_end, NULL);
237 for (i=0; i<MAX_THREADS; i++)
238 if (pthread_equal(t, threads[i]))
243 fprintf(stderr, COLOR_BLUE
" WARNING: no start info for %s\n", f);
247 d =
time_sub(&profile_time_end, &profile_time_start[i]);
256 COLOR_RED
"RESULT %s " COLOR_MAGENTA
"%ld "
257 COLOR_BLUE
"0x%08lX %s" COLOR_NORMAL
"\n",
260 fprintf(stderr, COLOR_RED
"RESULT %s " COLOR_MAGENTA
"%ld"
261 COLOR_NORMAL
"\n", f, d);
263 fprintf(profile_fd,
"%s %ld\n", f, d);
268 #define PROFILE_START
269 #define PROFILE_END(rv)
284 static int CHANNEL_MAP_seeker(
const void *el,
const void *key)
288 if ((el == NULL) || (key == NULL))
290 Log3(PCSC_LOG_CRITICAL,
291 "CHANNEL_MAP_seeker called with NULL pointer: el=%p, key=%p",
322 static list_t contextMapList;
324 static int SCONTEXTMAP_seeker(
const void *el,
const void *key)
328 if ((el == NULL) || (key == NULL))
330 Log3(PCSC_LOG_CRITICAL,
331 "SCONTEXTMAP_seeker called with NULL pointer: el=%p, key=%p",
346 static pthread_once_t init_lib_control = PTHREAD_ONCE_INIT;
359 static pthread_mutex_t readerStatesMutex = PTHREAD_MUTEX_INITIALIZER;
369 static LONG SCardGetContextChannelAndLockFromHandle(
SCARDHANDLE,
371 static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE,
375 static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
376 LPBYTE pbAttr, LPDWORD pcbAttrLen);
378 static LONG getReaderStates(
SCONTEXTMAP * currentContextMap);
379 static LONG getReaderStatesAndRegisterForEvents(
SCONTEXTMAP * currentContextMap);
380 static LONG unregisterFromEvents(
SCONTEXTMAP * currentContextMap);
423 return currentContextMap != NULL;
465 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
469 API_TRACE_IN(
"%ld, %p, %p", dwScope, pvReserved1, pvReserved2)
479 pvReserved2, phContext);
484 API_TRACE_OUT(
"%ld", *phContext)
490 DESTRUCTOR
static void destructor(
void)
492 list_destroy(&contextMapList);
500 static void init_lib(
void)
507 lrv = list_init(&contextMapList);
510 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d",
515 lrv = list_attributes_seeker(&contextMapList,
519 Log2(PCSC_LOG_CRITICAL,
520 "list_attributes_seeker failed with return value: %d", lrv);
521 list_destroy(&contextMapList);
527 Log1(PCSC_LOG_INFO,
"Disable shared blocking");
528 sharing_shall_block =
false;
563 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
567 uint32_t dwClientID = 0;
571 if (phContext == NULL)
576 pthread_once(&init_lib_control, init_lib);
602 Log1(PCSC_LOG_CRITICAL,
603 "Your pcscd is too old and does not support CMD_VERSION");
607 Log3(PCSC_LOG_INFO,
"Server is protocol version %d:%d",
621 scEstablishStruct.dwScope = dwScope;
622 scEstablishStruct.hContext = 0;
626 sizeof(scEstablishStruct), (
void *) &scEstablishStruct);
634 rv =
MessageReceive(&scEstablishStruct,
sizeof(scEstablishStruct),
642 rv = scEstablishStruct.rv;
652 *phContext = scEstablishStruct.hContext;
694 API_TRACE_IN(
"%ld", hContext)
702 if (NULL == currentContextMap)
708 scReleaseStruct.hContext = hContext;
712 currentContextMap->dwClientID,
713 sizeof(scReleaseStruct), (
void *) &scReleaseStruct);
722 currentContextMap->dwClientID);
727 rv = scReleaseStruct.rv;
729 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
801 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
802 LPDWORD pdwActiveProtocol)
809 API_TRACE_IN(
"%ld %s %ld %ld", hContext, szReader, dwShareMode, dwPreferredProtocols)
814 if (phCard == NULL || pdwActiveProtocol == NULL)
819 if (szReader == NULL)
825 if (strlen(szReader) > MAX_READERNAME)
832 if (NULL == currentContextMap)
835 memset(scConnectStruct.szReader, 0,
sizeof scConnectStruct.szReader);
836 strncpy(scConnectStruct.szReader, szReader,
sizeof scConnectStruct.szReader);
837 scConnectStruct.szReader[
sizeof scConnectStruct.szReader -1] =
'\0';
839 scConnectStruct.hContext = hContext;
840 scConnectStruct.dwShareMode = dwShareMode;
841 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
842 scConnectStruct.hCard = 0;
843 scConnectStruct.dwActiveProtocol = 0;
847 sizeof(scConnectStruct), (
void *) &scConnectStruct);
856 currentContextMap->dwClientID);
861 *phCard = scConnectStruct.hCard;
862 *pdwActiveProtocol = scConnectStruct.dwActiveProtocol;
869 rv = SCardAddHandle(*phCard, currentContextMap, szReader);
872 rv = scConnectStruct.rv;
875 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
878 API_TRACE_OUT(
"%d", *pdwActiveProtocol)
956 DWORD dwPreferredProtocols, DWORD dwInitialization,
957 LPDWORD pdwActiveProtocol)
965 API_TRACE_IN(
"%ld %ld %ld", hCard, dwShareMode, dwPreferredProtocols)
967 if (pdwActiveProtocol == NULL)
976 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
981 scReconnectStruct.hCard = hCard;
982 scReconnectStruct.dwShareMode = dwShareMode;
983 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
984 scReconnectStruct.dwInitialization = dwInitialization;
985 scReconnectStruct.dwActiveProtocol = *pdwActiveProtocol;
989 sizeof(scReconnectStruct), (
void *) &scReconnectStruct);
997 rv =
MessageReceive(&scReconnectStruct,
sizeof(scReconnectStruct),
998 currentContextMap->dwClientID);
1003 rv = scReconnectStruct.rv;
1007 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1012 *pdwActiveProtocol = scReconnectStruct.dwActiveProtocol;
1015 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1018 API_TRACE_OUT(
"%ld", *pdwActiveProtocol)
1062 API_TRACE_IN(
"%ld %ld", hCard, dwDisposition)
1067 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
1075 scDisconnectStruct.hCard = hCard;
1076 scDisconnectStruct.dwDisposition = dwDisposition;
1080 sizeof(scDisconnectStruct), (
void *) &scDisconnectStruct);
1088 rv =
MessageReceive(&scDisconnectStruct,
sizeof(scDisconnectStruct),
1089 currentContextMap->dwClientID);
1095 SCardRemoveHandle(hCard);
1096 rv = scDisconnectStruct.rv;
1099 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1153 API_TRACE_IN(
"%ld", hCard)
1165 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
1170 scBeginStruct.hCard = hCard;
1174 currentContextMap->dwClientID,
1175 sizeof(scBeginStruct), (
void *) &scBeginStruct);
1184 currentContextMap->dwClientID);
1189 rv = scBeginStruct.rv;
1194 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1198 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1253 API_TRACE_IN(
"%ld", hCard)
1258 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
1263 scEndStruct.hCard = hCard;
1264 scEndStruct.dwDisposition = dwDisposition;
1268 currentContextMap->dwClientID,
1269 sizeof(scEndStruct), (
void *) &scEndStruct);
1278 currentContextMap->dwClientID);
1283 rv = scEndStruct.rv;
1286 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1390 LPDWORD pcchReaderLen, LPDWORD pdwState,
1391 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1393 DWORD dwReaderLen, dwAtrLen;
1400 char *bufReader = NULL;
1401 LPBYTE bufAtr = NULL;
1414 if (pcchReaderLen == NULL)
1415 pcchReaderLen = &dummy;
1417 if (pcbAtrLen == NULL)
1421 dwReaderLen = *pcchReaderLen;
1422 dwAtrLen = *pcbAtrLen;
1433 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
1439 (void)pthread_mutex_lock(&readerStatesMutex);
1442 rv = getReaderStates(currentContextMap);
1446 r = pChannelMap->readerName;
1461 memset(&scStatusStruct, 0,
sizeof(scStatusStruct));
1462 scStatusStruct.hCard = hCard;
1465 sizeof(scStatusStruct), (
void *) &scStatusStruct);
1474 currentContextMap->dwClientID);
1479 rv = scStatusStruct.rv;
1483 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1484 (void)pthread_mutex_unlock(&readerStatesMutex);
1501 *pcchReaderLen = strlen(pChannelMap->readerName) + 1;
1512 dwReaderLen = *pcchReaderLen;
1513 if (NULL == szReaderName)
1518 bufReader = malloc(dwReaderLen);
1519 if (NULL == bufReader)
1524 *(
char **)szReaderName = bufReader;
1527 bufReader = szReaderName;
1532 if (*pcchReaderLen > dwReaderLen)
1535 strncpy(bufReader, pChannelMap->readerName, dwReaderLen);
1540 dwAtrLen = *pcbAtrLen;
1546 bufAtr = malloc(dwAtrLen);
1552 *(LPBYTE *)pbAtr = bufAtr;
1559 if (*pcbAtrLen > dwAtrLen)
1562 memcpy(bufAtr,
readerStates[i].cardAtr, min(*pcbAtrLen, dwAtrLen));
1566 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
1567 (void)pthread_mutex_unlock(&readerStatesMutex);
1687 DWORD dwBreakFlag = 0;
1690 int currentReaderCount = 0;
1694 API_TRACE_IN(
"%ld %ld %d", hContext, dwTimeout, cReaders)
1696 for (j=0; j<cReaders; j++)
1698 API_TRACE_IN(
"[%d] %s %lX %lX", j, rgReaderStates[j].szReader,
1699 rgReaderStates[j].dwCurrentState, rgReaderStates[j].dwEventState)
1703 if ((rgReaderStates == NULL && cReaders > 0)
1711 for (j = 0; j < cReaders; j++)
1713 if (rgReaderStates[j].szReader == NULL)
1720 int nbNonIgnoredReaders = cReaders;
1722 for (j=0; j<cReaders; j++)
1724 nbNonIgnoredReaders--;
1726 if (0 == nbNonIgnoredReaders)
1743 if (NULL == currentContextMap)
1750 (void)pthread_mutex_lock(&readerStatesMutex);
1753 rv = getReaderStatesAndRegisterForEvents(currentContextMap);
1757 (void)pthread_mutex_unlock(&readerStatesMutex);
1762 for (j=0; j<cReaders; j++)
1764 const char *readerName;
1767 readerName = rgReaderStates[j].szReader;
1770 if (strcmp(readerName,
readerStates[i].readerName) == 0)
1778 if (strcasecmp(readerName,
"\\\\?PnP?\\Notification") != 0)
1781 (void)pthread_mutex_unlock(&readerStatesMutex);
1786 (void)pthread_mutex_unlock(&readerStatesMutex);
1789 for (j = 0; j < cReaders; j++)
1790 rgReaderStates[j].dwEventState = 0;
1793 Log2(PCSC_LOG_DEBUG,
"Event Loop Start, dwTimeout: %ld", dwTimeout);
1798 currentReaderCount++;
1801 if ((DWORD)-1 == dwTimeout)
1811 currReader = &rgReaderStates[j];
1816 const char *readerName;
1820 (void)pthread_mutex_lock(&readerStatesMutex);
1823 readerName = currReader->szReader;
1826 if (strcmp(readerName,
readerStates[i].readerName) == 0)
1834 if (strcasecmp(readerName,
"\\\\?PnP?\\Notification") == 0)
1836 int k, newReaderCount = 0;
1842 if (newReaderCount != currentReaderCount)
1844 Log1(PCSC_LOG_INFO,
"Reader list changed");
1845 currentReaderCount = newReaderCount;
1853 currReader->dwEventState =
1869 uint32_t readerState;
1876 Log0(PCSC_LOG_DEBUG);
1887 if (currReader->dwCurrentState & 0xFFFF0000)
1889 unsigned int currentCounter;
1891 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
1897 Log0(PCSC_LOG_DEBUG);
1903 currReader->dwEventState = ((currReader->dwEventState & 0xffff )
1915 Log0(PCSC_LOG_DEBUG);
1926 Log0(PCSC_LOG_DEBUG);
1934 #ifndef DISABLE_AUTO_POWER_ON
1938 (void)
SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
1942 memcpy(currReader->rgbAtr, rContext->
cardAtr,
1946 currReader->cbAtr = 0;
1965 Log0(PCSC_LOG_DEBUG);
1983 Log0(PCSC_LOG_DEBUG);
1993 Log0(PCSC_LOG_DEBUG);
2003 Log0(PCSC_LOG_DEBUG);
2017 Log0(PCSC_LOG_DEBUG);
2031 Log0(PCSC_LOG_DEBUG);
2044 Log0(PCSC_LOG_DEBUG);
2047 else if (currReader-> dwCurrentState
2051 Log0(PCSC_LOG_DEBUG);
2063 Log0(PCSC_LOG_DEBUG);
2068 (void)pthread_mutex_unlock(&readerStatesMutex);
2081 if (dwBreakFlag == 1)
2087 struct timeval before, after;
2089 gettimeofday(&before, NULL);
2100 &waitStatusStruct,
sizeof(waitStatusStruct),
2111 rv = unregisterFromEvents(currentContextMap);
2120 rv = waitStatusStruct.rv;
2125 (void)pthread_mutex_lock(&readerStatesMutex);
2126 rv = getReaderStatesAndRegisterForEvents(currentContextMap);
2127 (void)pthread_mutex_unlock(&readerStatesMutex);
2135 gettimeofday(&after, NULL);
2137 dwTime -= diff/1000;
2157 Log1(PCSC_LOG_DEBUG,
"Event Loop End");
2162 (void)unregisterFromEvents(currentContextMap);
2164 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
2169 for (j=0; j<cReaders; j++)
2171 API_TRACE_OUT(
"[%d] %s %X %X", j, rgReaderStates[j].szReader,
2172 rgReaderStates[j].dwCurrentState, rgReaderStates[j].dwEventState)
2230 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
2231 LPDWORD lpBytesReturned)
2241 if (NULL != lpBytesReturned)
2242 *lpBytesReturned = 0;
2247 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
2261 scControlStruct.hCard = hCard;
2262 scControlStruct.dwControlCode = dwControlCode;
2263 scControlStruct.cbSendLength = cbSendLength;
2264 scControlStruct.cbRecvLength = cbRecvLength;
2265 scControlStruct.dwBytesReturned = 0;
2266 scControlStruct.rv = 0;
2269 sizeof(scControlStruct), &scControlStruct);
2275 rv =
MessageSend((
char *)pbSendBuffer, cbSendLength,
2276 currentContextMap->dwClientID);
2285 currentContextMap->dwClientID);
2292 if (scControlStruct.dwBytesReturned > cbRecvLength)
2294 if (NULL != lpBytesReturned)
2295 *lpBytesReturned = scControlStruct.dwBytesReturned;
2301 rv =
MessageReceive(pbRecvBuffer, scControlStruct.dwBytesReturned,
2302 currentContextMap->dwClientID);
2309 if (NULL != lpBytesReturned)
2310 *lpBytesReturned = scControlStruct.dwBytesReturned;
2312 rv = scControlStruct.rv;
2315 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
2444 unsigned char *buf = NULL;
2448 if (NULL == pcbAttrLen)
2460 buf = malloc(*pcbAttrLen);
2467 *(
unsigned char **)pbAttr = buf;
2530 if (NULL == pbAttr || 0 == cbAttrLen)
2541 static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
2542 LPBYTE pbAttr, LPDWORD pcbAttrLen)
2552 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
2563 scGetSetStruct.hCard = hCard;
2564 scGetSetStruct.dwAttrId = dwAttrId;
2566 memset(scGetSetStruct.pbAttr, 0,
sizeof(scGetSetStruct.pbAttr));
2569 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
2570 scGetSetStruct.cbAttrLen = *pcbAttrLen;
2574 scGetSetStruct.cbAttrLen =
sizeof scGetSetStruct.pbAttr;
2577 sizeof(scGetSetStruct), &scGetSetStruct);
2586 currentContextMap->dwClientID);
2596 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
2600 DWORD correct_value = scGetSetStruct.cbAttrLen;
2601 scGetSetStruct.cbAttrLen = *pcbAttrLen;
2602 *pcbAttrLen = correct_value;
2607 *pcbAttrLen = scGetSetStruct.cbAttrLen;
2610 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
2612 memset(scGetSetStruct.pbAttr, 0x00,
sizeof(scGetSetStruct.pbAttr));
2614 rv = scGetSetStruct.rv;
2617 (void)pthread_mutex_unlock(¤tContextMap->mMutex);
2681 LPCBYTE pbSendBuffer, DWORD cbSendLength,
2683 LPDWORD pcbRecvLength)
2692 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
2693 pcbRecvLength == NULL || pioSendPci == NULL)
2702 rv = SCardGetContextChannelAndLockFromHandle(hCard, ¤tContextMap,
2717 scTransmitStruct.hCard = hCard;
2718 scTransmitStruct.cbSendLength = cbSendLength;
2719 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
2720 scTransmitStruct.ioSendPciProtocol = pioSendPci->
dwProtocol;
2721 scTransmitStruct.ioSendPciLength = pioSendPci->
cbPciLength;
2726 scTransmitStruct.ioRecvPciProtocol = pioRecvPci->
dwProtocol;
2727 scTransmitStruct.ioRecvPciLength = pioRecvPci->
cbPciLength;
2736 sizeof(scTransmitStruct), (
void *) &scTransmitStruct);
2742 rv =
MessageSend((
void *)pbSendBuffer, cbSendLength,
2759 if (scTransmitStruct.pcbRecvLength > *pcbRecvLength)
2761 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
2767 rv =
MessageReceive(pbRecvBuffer, scTransmitStruct.pcbRecvLength,
2775 pioRecvPci->
dwProtocol = scTransmitStruct.ioRecvPciProtocol;
2776 pioRecvPci->
cbPciLength = scTransmitStruct.ioRecvPciLength;
2780 rv = scTransmitStruct.rv;
2784 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
2789 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
2792 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
2862 LPSTR mszReaders, LPDWORD pcchReaders)
2864 DWORD dwReadersLen = 0;
2872 API_TRACE_IN(
"%ld", hContext)
2877 if (pcchReaders == NULL)
2884 if (NULL == currentContextMap)
2891 (void)pthread_mutex_lock(&readerStatesMutex);
2894 rv = getReaderStates(currentContextMap);
2901 dwReadersLen += strlen(
readerStates[i].readerName) + 1;
2906 if (1 == dwReadersLen)
2914 if (NULL == mszReaders)
2919 buf = malloc(dwReadersLen);
2925 *(
char **)mszReaders = buf;
2932 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
2939 if (mszReaders == NULL)
2957 *pcchReaders = dwReadersLen;
2959 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
2960 (void)pthread_mutex_unlock(&readerStatesMutex);
2963 API_TRACE_OUT(
"%d", *pcchReaders)
2993 free((
void *)pvMem);
3061 const char ReaderGroup[] =
"SCard$DefaultReaders\0";
3062 const unsigned int dwGroups =
sizeof(ReaderGroup);
3068 if (NULL == currentContextMap)
3073 if (NULL == mszGroups)
3078 buf = malloc(dwGroups);
3084 *(
char **)mszGroups = buf;
3090 if ((NULL != mszGroups) && (*pcchGroups < dwGroups))
3098 memcpy(buf, ReaderGroup, dwGroups);
3101 *pcchGroups = dwGroups;
3103 (void)pthread_mutex_unlock(¤tContextMap->
mMutex);
3145 uint32_t dwClientID = 0;
3150 API_TRACE_IN(
"%ld", hContext)
3158 if (NULL == currentContextMap)
3180 scCancelStruct.hContext = hContext;
3184 sizeof(scCancelStruct), (
void *) &scCancelStruct);
3192 rv =
MessageReceive(&scCancelStruct,
sizeof(scCancelStruct), dwClientID);
3197 rv = scCancelStruct.rv;
3236 API_TRACE_IN(
"%ld", hContext)
3274 if (NULL == newContextMap)
3277 Log2(PCSC_LOG_DEBUG,
"Allocating new SCONTEXTMAP @%p", newContextMap);
3278 newContextMap->
hContext = hContext;
3282 (void)pthread_mutex_init(&newContextMap->
mMutex, NULL);
3284 lrv = list_init(&newContextMap->channelMapList);
3287 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d", lrv);
3291 lrv = list_attributes_seeker(&newContextMap->channelMapList,
3292 CHANNEL_MAP_seeker);
3295 Log2(PCSC_LOG_CRITICAL,
3296 "list_attributes_seeker failed with return value: %d", lrv);
3297 list_destroy(&newContextMap->channelMapList);
3301 lrv = list_append(&contextMapList, newContextMap);
3304 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3306 list_destroy(&newContextMap->channelMapList);
3314 (void)pthread_mutex_destroy(&newContextMap->
mMutex);
3315 free(newContextMap);
3344 if (NULL != currentContextMap)
3345 (void)pthread_mutex_lock(¤tContextMap->
mMutex);
3349 return currentContextMap;
3366 return list_seek(&contextMapList, &hContext);
3380 if (NULL != currentContextMap)
3381 SCardCleanContext(currentContextMap);
3384 static void SCardCleanContext(
SCONTEXTMAP * targetContextMap)
3386 int list_index, lrv;
3393 (void)pthread_mutex_destroy(&targetContextMap->
mMutex);
3395 listSize = list_size(&targetContextMap->channelMapList);
3396 for (list_index = 0; list_index < listSize; list_index++)
3398 currentChannelMap = list_get_at(&targetContextMap->channelMapList,
3400 if (NULL == currentChannelMap)
3402 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3408 free(currentChannelMap->readerName);
3409 free(currentChannelMap);
3413 list_destroy(&targetContextMap->channelMapList);
3415 lrv = list_delete(&contextMapList, targetContextMap);
3418 Log2(PCSC_LOG_CRITICAL,
3419 "list_delete failed with return value: %d", lrv);
3422 free(targetContextMap);
3438 if (NULL == newChannelMap)
3441 newChannelMap->hCard = hCard;
3442 newChannelMap->readerName = strdup(readerName);
3444 lrv = list_append(¤tContextMap->channelMapList, newChannelMap);
3447 free(newChannelMap->readerName);
3448 free(newChannelMap);
3449 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3464 rv = SCardGetContextAndChannelFromHandleTH(hCard, ¤tContextMap,
3465 ¤tChannelMap);
3469 free(currentChannelMap->readerName);
3471 lrv = list_delete(¤tContextMap->channelMapList, currentChannelMap);
3474 Log2(PCSC_LOG_CRITICAL,
3475 "list_delete failed with return value: %d", lrv);
3478 free(currentChannelMap);
3483 static LONG SCardGetContextChannelAndLockFromHandle(
SCARDHANDLE hCard,
3492 rv = SCardGetContextAndChannelFromHandleTH(hCard, targetContextMap,
3496 (void)pthread_mutex_lock(&(*targetContextMap)->mMutex);
3503 static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE hCard,
3512 *targetContextMap = NULL;
3513 *targetChannelMap = NULL;
3515 listSize = list_size(&contextMapList);
3517 for (list_index = 0; list_index < listSize; list_index++)
3519 currentContextMap = list_get_at(&contextMapList, list_index);
3520 if (currentContextMap == NULL)
3522 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3526 currentChannelMap = list_seek(¤tContextMap->channelMapList,
3528 if (currentChannelMap != NULL)
3530 *targetContextMap = currentContextMap;
3531 *targetChannelMap = currentChannelMap;
3549 struct stat statBuffer;
3552 socketName = getSocketName();
3553 rv = stat(socketName, &statBuffer);
3557 Log3(PCSC_LOG_INFO,
"PCSC Not Running: %s: %s",
3558 socketName, strerror(errno));
3565 static LONG getReaderStates(
SCONTEXTMAP * currentContextMap)
3567 int32_t dwClientID = currentContextMap->
dwClientID;
3582 static LONG getReaderStatesAndRegisterForEvents(
SCONTEXTMAP * currentContextMap)
3584 int32_t dwClientID = currentContextMap->
dwClientID;
3598 static LONG unregisterFromEvents(
SCONTEXTMAP * currentContextMap)
3600 int32_t dwClientID = currentContextMap->
dwClientID;
3606 dwClientID, 0, NULL);
3623 rv = waitStatusStruct.rv;