00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00078 #include "config.h"
00079 #include <stdlib.h>
00080 #include <string.h>
00081 #include <sys/types.h>
00082 #include <fcntl.h>
00083 #include <unistd.h>
00084 #include <sys/un.h>
00085 #include <errno.h>
00086 #include <stddef.h>
00087 #include <sys/time.h>
00088 #include <pthread.h>
00089 #include <sys/wait.h>
00090
00091 #include "misc.h"
00092 #include "pcscd.h"
00093 #include "winscard.h"
00094 #include "debuglog.h"
00095 #include "strlcpycat.h"
00096
00097 #include "readerfactory.h"
00098 #include "eventhandler.h"
00099 #include "sys_generic.h"
00100 #include "winscard_msg.h"
00101 #include "utils.h"
00102
00104 #define SCARD_PROTOCOL_ANY_OLD 0x1000
00105
00106 #ifndef TRUE
00107 #define TRUE 1
00108 #define FALSE 0
00109 #endif
00110
00111 static char sharing_shall_block = TRUE;
00112
00113 #undef DO_PROFILE
00114 #ifdef DO_PROFILE
00115
00116 #define PROFILE_FILE "/tmp/pcsc_profile"
00117 #include <stdio.h>
00118 #include <sys/time.h>
00119
00120 struct timeval profile_time_start;
00121 FILE *profile_fd;
00122 char profile_tty;
00123 char fct_name[100];
00124
00125 #define PROFILE_START profile_start(__FUNCTION__);
00126 #define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
00127
00128 static void profile_start(const char *f)
00129 {
00130 static char initialized = FALSE;
00131
00132 if (!initialized)
00133 {
00134 char filename[80];
00135
00136 initialized = TRUE;
00137 sprintf(filename, "%s-%d", PROFILE_FILE, getuid());
00138 profile_fd = fopen(filename, "a+");
00139 if (NULL == profile_fd)
00140 {
00141 fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n",
00142 PROFILE_FILE, strerror(errno));
00143 exit(-1);
00144 }
00145 fprintf(profile_fd, "\nStart a new profile\n");
00146
00147 if (isatty(fileno(stderr)))
00148 profile_tty = TRUE;
00149 else
00150 profile_tty = FALSE;
00151 }
00152
00153
00154 if (profile_tty && fct_name[0])
00155 printf("\33[01;34m WARNING: %s starts before %s finishes\33[0m\n",
00156 f, fct_name);
00157
00158 strlcpy(fct_name, f, sizeof(fct_name));
00159
00160 gettimeofday(&profile_time_start, NULL);
00161 }
00162
00163 static void profile_end(const char *f, LONG rv)
00164 {
00165 struct timeval profile_time_end;
00166 long d;
00167
00168 gettimeofday(&profile_time_end, NULL);
00169 d = time_sub(&profile_time_end, &profile_time_start);
00170
00171 if (profile_tty)
00172 {
00173 if (fct_name[0])
00174 {
00175 if (strncmp(fct_name, f, sizeof(fct_name)))
00176 printf("\33[01;34m WARNING: %s ends before %s\33[0m\n",
00177 f, fct_name);
00178 }
00179 else
00180 printf("\33[01;34m WARNING: %s ends but we lost its start\33[0m\n",
00181 f);
00182
00183
00184 fct_name[0] = '\0';
00185
00186 if (rv != SCARD_S_SUCCESS)
00187 fprintf(stderr,
00188 "\33[01;31mRESULT %s \33[35m%ld \33[34m0x%08lX %s\33[0m\n",
00189 f, d, rv, pcsc_stringify_error(rv));
00190 else
00191 fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m\n", f, d);
00192 }
00193 fprintf(profile_fd, "%s %ld\n", f, d);
00194 fflush(profile_fd);
00195 }
00196
00197 #else
00198 #define PROFILE_START
00199 #define PROFILE_END(rv)
00200 #endif
00201
00206 struct _psChannelMap
00207 {
00208 SCARDHANDLE hCard;
00209 LPSTR readerName;
00210 };
00211
00212 typedef struct _psChannelMap CHANNEL_MAP;
00213
00214 static int CHANNEL_MAP_seeker(const void *el, const void *key)
00215 {
00216 const CHANNEL_MAP * channelMap = el;
00217
00218 if ((el == NULL) || (key == NULL))
00219 {
00220 Log3(PCSC_LOG_CRITICAL,
00221 "CHANNEL_MAP_seeker called with NULL pointer: el=%X, key=%X",
00222 el, key);
00223 }
00224
00225 if (channelMap->hCard == *(SCARDHANDLE *)key)
00226 return 1;
00227
00228 return 0;
00229 }
00230
00236 struct _psContextMap
00237 {
00238 DWORD dwClientID;
00239 SCARDCONTEXT hContext;
00240 pthread_mutex_t * mMutex;
00241 list_t channelMapList;
00242 };
00243 typedef struct _psContextMap SCONTEXTMAP;
00244
00245 static list_t contextMapList;
00246
00247 static int SCONTEXTMAP_seeker(const void *el, const void *key)
00248 {
00249 const SCONTEXTMAP * contextMap = el;
00250
00251 if ((el == NULL) || (key == NULL))
00252 {
00253 Log3(PCSC_LOG_CRITICAL,
00254 "SCONTEXTMAP_seeker called with NULL pointer: el=%X, key=%X",
00255 el, key);
00256 }
00257
00258 if (contextMap->hContext == *(SCARDCONTEXT *) key)
00259 return 1;
00260
00261 return 0;
00262 }
00263
00267 static short isExecuted = 0;
00268
00269
00273 static time_t daemon_ctime = 0;
00274 static pid_t daemon_pid = 0;
00279 static pid_t client_pid = 0;
00280
00285 static pthread_mutex_t clientMutex = PTHREAD_MUTEX_INITIALIZER;
00286
00290 static READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
00291
00293 PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, sizeof(SCARD_IO_REQUEST) };
00295 PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(SCARD_IO_REQUEST) };
00297 PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, sizeof(SCARD_IO_REQUEST) };
00298
00299
00300 static LONG SCardAddContext(SCARDCONTEXT, DWORD);
00301 static SCONTEXTMAP * SCardGetContext(SCARDCONTEXT);
00302 static SCONTEXTMAP * SCardGetContextTH(SCARDCONTEXT);
00303 static LONG SCardRemoveContext(SCARDCONTEXT);
00304 static LONG SCardCleanContext(SCONTEXTMAP *);
00305
00306 static LONG SCardAddHandle(SCARDHANDLE, SCONTEXTMAP *, LPCSTR);
00307 static LONG SCardGetContextAndChannelFromHandle(SCARDHANDLE, SCONTEXTMAP * *, CHANNEL_MAP * *);
00308 static LONG SCardGetContextAndChannelFromHandleTH(SCARDHANDLE, SCONTEXTMAP * *, CHANNEL_MAP * *);
00309 static LONG SCardRemoveHandle(SCARDHANDLE);
00310
00311 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
00312 LPBYTE pbAttr, LPDWORD pcbAttrLen);
00313
00314 #ifdef DO_CHECK_SAME_PROCESS
00315 static LONG SCardCheckSameProcess(void);
00316 #define CHECK_SAME_PROCESS \
00317 rv = SCardCheckSameProcess(); \
00318 if (rv != SCARD_S_SUCCESS) \
00319 return rv;
00320 #else
00321 #define CHECK_SAME_PROCESS
00322 #endif
00323
00324 static LONG getReaderStates(SCONTEXTMAP * currentContextMap);
00325
00326
00327
00328
00335 inline static LONG SCardLockThread(void)
00336 {
00337 return pthread_mutex_lock(&clientMutex);
00338 }
00339
00345 inline static LONG SCardUnlockThread(void)
00346 {
00347 return pthread_mutex_unlock(&clientMutex);
00348 }
00349
00350 static LONG SCardEstablishContextTH(DWORD, LPCVOID, LPCVOID,
00351 LPSCARDCONTEXT);
00352
00386 LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
00387 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00388 {
00389 LONG rv;
00390 int daemon_launched = FALSE;
00391 int retries = 0;
00392
00393 PROFILE_START
00394
00395 again:
00396
00397 rv = SCardCheckDaemonAvailability();
00398 if (SCARD_E_INVALID_HANDLE == rv)
00399
00400 rv = SCardCheckDaemonAvailability();
00401
00402 if (SCARD_E_NO_SERVICE == rv)
00403 {
00404 launch:
00405 if (daemon_launched)
00406 {
00407 retries++;
00408 if (retries < 50)
00409 {
00410
00411 SYS_USleep(100*1000);
00412 goto again;
00413 }
00414
00415
00416 goto end;
00417 }
00418 else
00419 {
00420 int pid;
00421
00422 pid = fork();
00423
00424 if (pid < 0)
00425 {
00426 Log2(PCSC_LOG_CRITICAL, "fork failed: %s", strerror(errno));
00427 rv = SCARD_F_INTERNAL_ERROR;
00428 goto end;
00429 }
00430
00431 if (0 == pid)
00432 {
00433 int ret;
00434 char *param = getenv("PCSCLITE_PCSCD_ARGS");
00435
00436
00437 ret = execl(PCSCD_BINARY, "pcscd", "--auto-exit", param,
00438 (char *)NULL);
00439 Log2(PCSC_LOG_CRITICAL, "exec " PCSCD_BINARY " failed: %s",
00440 strerror(errno));
00441 exit(1);
00442 }
00443
00444
00445 daemon_launched = TRUE;
00446
00447 if (waitpid(pid, NULL, 0) < 0)
00448 Log2(PCSC_LOG_CRITICAL, "waitpid failed: %s", strerror(errno));
00449
00450 goto again;
00451 }
00452 }
00453
00454 if (rv != SCARD_S_SUCCESS)
00455 goto end;
00456
00457 (void)SCardLockThread();
00458 rv = SCardEstablishContextTH(dwScope, pvReserved1,
00459 pvReserved2, phContext);
00460 (void)SCardUnlockThread();
00461
00462
00463
00464 if (SCARD_E_NO_SERVICE == rv)
00465 {
00466 retries++;
00467 if (retries <= 1)
00468 goto launch;
00469 }
00470
00471 end:
00472 PROFILE_END(rv)
00473
00474 return rv;
00475 }
00476
00503 static LONG SCardEstablishContextTH(DWORD dwScope,
00504 LPCVOID pvReserved1,
00505 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00506 {
00507 LONG rv;
00508 struct establish_struct scEstablishStruct;
00509 uint32_t dwClientID = 0;
00510
00511 (void)pvReserved1;
00512 (void)pvReserved2;
00513 if (phContext == NULL)
00514 return SCARD_E_INVALID_PARAMETER;
00515 else
00516 *phContext = 0;
00517
00518
00519
00520
00521
00522 if (isExecuted == 0)
00523 {
00524 int lrv;
00525
00526
00527
00528
00529
00530 lrv = list_init(&contextMapList);
00531 if (lrv < 0)
00532 {
00533 Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %X", lrv);
00534 return SCARD_E_NO_MEMORY;
00535 }
00536
00537 lrv = list_attributes_seeker(&contextMapList,
00538 SCONTEXTMAP_seeker);
00539 if (lrv <0)
00540 {
00541 Log2(PCSC_LOG_CRITICAL,
00542 "list_attributes_seeker failed with return value: %X", lrv);
00543 list_destroy(&contextMapList);
00544 return SCARD_E_NO_MEMORY;
00545 }
00546
00547 if (getenv("PCSCLITE_NO_BLOCKING"))
00548 {
00549 Log1(PCSC_LOG_INFO, "Disable shared blocking");
00550 sharing_shall_block = FALSE;
00551 }
00552
00553 isExecuted = 1;
00554 }
00555
00556
00557
00558 if (ClientSetupSession(&dwClientID) != 0)
00559 {
00560 return SCARD_E_NO_SERVICE;
00561 }
00562
00563 {
00564 struct version_struct veStr;
00565
00566 veStr.major = PROTOCOL_VERSION_MAJOR;
00567 veStr.minor = PROTOCOL_VERSION_MINOR;
00568 veStr.rv = SCARD_S_SUCCESS;
00569
00570 if (-1 == MessageSendWithHeader(CMD_VERSION, dwClientID, sizeof(veStr),
00571 &veStr))
00572 return SCARD_E_NO_SERVICE;
00573
00574
00575 if (MessageReceive(&veStr, sizeof(veStr), dwClientID) < 0)
00576 {
00577 Log1(PCSC_LOG_CRITICAL, "Your pcscd is too old and does not support CMD_VERSION");
00578 return SCARD_F_COMM_ERROR;
00579 }
00580
00581 Log3(PCSC_LOG_INFO, "Server is protocol version %d:%d",
00582 veStr.major, veStr.minor);
00583
00584 if (veStr.rv != SCARD_S_SUCCESS)
00585 return veStr.rv;
00586 }
00587
00588 again:
00589
00590
00591
00592 scEstablishStruct.dwScope = dwScope;
00593 scEstablishStruct.hContext = 0;
00594 scEstablishStruct.rv = SCARD_S_SUCCESS;
00595
00596 rv = MessageSendWithHeader(SCARD_ESTABLISH_CONTEXT, dwClientID,
00597 sizeof(scEstablishStruct), (void *) &scEstablishStruct);
00598
00599 if (rv == -1)
00600 return SCARD_E_NO_SERVICE;
00601
00602
00603
00604
00605 rv = MessageReceive(&scEstablishStruct, sizeof(scEstablishStruct), dwClientID);
00606
00607 if (rv < 0)
00608 return SCARD_F_COMM_ERROR;
00609
00610 if (scEstablishStruct.rv != SCARD_S_SUCCESS)
00611 return scEstablishStruct.rv;
00612
00613
00614 if (NULL != SCardGetContextTH(scEstablishStruct.hContext))
00615
00616
00617 goto again;
00618
00619 *phContext = scEstablishStruct.hContext;
00620
00621
00622
00623
00624 rv = SCardAddContext(*phContext, dwClientID);
00625
00626 return rv;
00627 }
00628
00650 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00651 {
00652 LONG rv;
00653 struct release_struct scReleaseStruct;
00654 SCONTEXTMAP * currentContextMap;
00655
00656 PROFILE_START
00657
00658 CHECK_SAME_PROCESS
00659
00660
00661
00662
00663
00664 currentContextMap = SCardGetContext(hContext);
00665 if (NULL == currentContextMap)
00666 {
00667 PROFILE_END(SCARD_E_INVALID_HANDLE)
00668 return SCARD_E_INVALID_HANDLE;
00669 }
00670
00671 (void)pthread_mutex_lock(currentContextMap->mMutex);
00672
00673
00674 currentContextMap = SCardGetContext(hContext);
00675 if (NULL == currentContextMap)
00676
00677
00678
00679 return SCARD_E_INVALID_HANDLE;
00680
00681 scReleaseStruct.hContext = hContext;
00682 scReleaseStruct.rv = SCARD_S_SUCCESS;
00683
00684 rv = MessageSendWithHeader(SCARD_RELEASE_CONTEXT,
00685 currentContextMap->dwClientID,
00686 sizeof(scReleaseStruct),
00687 (void *) &scReleaseStruct);
00688
00689 if (rv == -1)
00690 {
00691 rv = SCARD_E_NO_SERVICE;
00692 goto end;
00693 }
00694
00695
00696
00697
00698 rv = MessageReceive(&scReleaseStruct, sizeof(scReleaseStruct),
00699 currentContextMap->dwClientID);
00700
00701 if (rv < 0)
00702 {
00703 rv = SCARD_F_COMM_ERROR;
00704 goto end;
00705 }
00706
00707 rv = scReleaseStruct.rv;
00708 end:
00709 (void)pthread_mutex_unlock(currentContextMap->mMutex);
00710
00711
00712
00713
00714 (void)SCardLockThread();
00715 (void)SCardRemoveContext(hContext);
00716 (void)SCardUnlockThread();
00717
00718 PROFILE_END(rv)
00719
00720 return rv;
00721 }
00722
00738 LONG SCardSetTimeout( SCARDCONTEXT hContext,
00739 DWORD dwTimeout)
00740 {
00741
00742
00743
00744 (void)hContext;
00745 (void)dwTimeout;
00746 return SCARD_S_SUCCESS;
00747 }
00748
00806 LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,
00807 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00808 LPDWORD pdwActiveProtocol)
00809 {
00810 LONG rv;
00811 struct connect_struct scConnectStruct;
00812 SCONTEXTMAP * currentContextMap;
00813
00814 PROFILE_START
00815
00816
00817
00818
00819 if (phCard == NULL || pdwActiveProtocol == NULL)
00820 return SCARD_E_INVALID_PARAMETER;
00821 else
00822 *phCard = 0;
00823
00824 if (szReader == NULL)
00825 return SCARD_E_UNKNOWN_READER;
00826
00827
00828
00829
00830 if (strlen(szReader) > MAX_READERNAME)
00831 return SCARD_E_INVALID_VALUE;
00832
00833 CHECK_SAME_PROCESS
00834
00835
00836
00837
00838 currentContextMap = SCardGetContext(hContext);
00839 if (NULL == currentContextMap)
00840 return SCARD_E_INVALID_HANDLE;
00841
00842 (void)pthread_mutex_lock(currentContextMap->mMutex);
00843
00844
00845 currentContextMap = SCardGetContext(hContext);
00846 if (NULL == currentContextMap)
00847
00848
00849
00850 return SCARD_E_INVALID_HANDLE;
00851
00852 strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);
00853
00854 scConnectStruct.hContext = hContext;
00855 scConnectStruct.dwShareMode = dwShareMode;
00856 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00857 scConnectStruct.hCard = 0;
00858 scConnectStruct.dwActiveProtocol = 0;
00859 scConnectStruct.rv = SCARD_S_SUCCESS;
00860
00861 rv = MessageSendWithHeader(SCARD_CONNECT, currentContextMap->dwClientID,
00862 sizeof(scConnectStruct),
00863 (void *) &scConnectStruct);
00864
00865 if (rv == -1)
00866 {
00867 rv = SCARD_E_NO_SERVICE;
00868 goto end;
00869 }
00870
00871
00872
00873
00874 rv = MessageReceive(&scConnectStruct, sizeof(scConnectStruct),
00875 currentContextMap->dwClientID);
00876
00877 if (rv < 0)
00878 {
00879 rv = SCARD_F_COMM_ERROR;
00880 goto end;
00881 }
00882
00883 *phCard = scConnectStruct.hCard;
00884 *pdwActiveProtocol = scConnectStruct.dwActiveProtocol;
00885
00886 if (scConnectStruct.rv == SCARD_S_SUCCESS)
00887 {
00888
00889
00890
00891 rv = SCardAddHandle(*phCard, currentContextMap, szReader);
00892 }
00893 else
00894 rv = scConnectStruct.rv;
00895
00896 end:
00897 (void)pthread_mutex_unlock(currentContextMap->mMutex);
00898
00899 PROFILE_END(rv)
00900
00901 return rv;
00902 }
00903
00977 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00978 DWORD dwPreferredProtocols, DWORD dwInitialization,
00979 LPDWORD pdwActiveProtocol)
00980 {
00981 LONG rv;
00982 struct reconnect_struct scReconnectStruct;
00983 SCONTEXTMAP * currentContextMap;
00984 CHANNEL_MAP * pChannelMap;
00985
00986 PROFILE_START
00987
00988 if (pdwActiveProtocol == NULL)
00989 return SCARD_E_INVALID_PARAMETER;
00990
00991 CHECK_SAME_PROCESS
00992
00993
00994
00995
00996 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
00997 &pChannelMap);
00998 if (rv == -1)
00999 return SCARD_E_INVALID_HANDLE;
01000
01001 (void)pthread_mutex_lock(currentContextMap->mMutex);
01002
01003
01004 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01005 &pChannelMap);
01006 if (rv == -1)
01007
01008
01009
01010 return SCARD_E_INVALID_HANDLE;
01011
01012
01013 retry:
01014
01015 scReconnectStruct.hCard = hCard;
01016 scReconnectStruct.dwShareMode = dwShareMode;
01017 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
01018 scReconnectStruct.dwInitialization = dwInitialization;
01019 scReconnectStruct.dwActiveProtocol = *pdwActiveProtocol;
01020 scReconnectStruct.rv = SCARD_S_SUCCESS;
01021
01022 rv = MessageSendWithHeader(SCARD_RECONNECT,
01023 currentContextMap->dwClientID,
01024 sizeof(scReconnectStruct),
01025 (void *) &scReconnectStruct);
01026
01027 if (rv == -1)
01028 {
01029 rv = SCARD_E_NO_SERVICE;
01030 goto end;
01031 }
01032
01033
01034
01035
01036 rv = MessageReceive(&scReconnectStruct,
01037 sizeof(scReconnectStruct),
01038 currentContextMap->dwClientID);
01039
01040 if (rv < 0)
01041 {
01042 rv = SCARD_F_COMM_ERROR;
01043 goto end;
01044 }
01045
01046 rv = scReconnectStruct.rv;
01047
01048 if (sharing_shall_block && (SCARD_E_SHARING_VIOLATION == rv))
01049 {
01050 (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
01051 goto retry;
01052 }
01053
01054 *pdwActiveProtocol = scReconnectStruct.dwActiveProtocol;
01055
01056 end:
01057 (void)pthread_mutex_unlock(currentContextMap->mMutex);
01058
01059 PROFILE_END(rv)
01060
01061 return rv;
01062 }
01063
01095 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
01096 {
01097 LONG rv;
01098 struct disconnect_struct scDisconnectStruct;
01099 SCONTEXTMAP * currentContextMap;
01100 CHANNEL_MAP * pChannelMap;
01101
01102 PROFILE_START
01103
01104 CHECK_SAME_PROCESS
01105
01106
01107
01108
01109 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01110 &pChannelMap);
01111 if (rv == -1)
01112 return SCARD_E_INVALID_HANDLE;
01113
01114 (void)pthread_mutex_lock(currentContextMap->mMutex);
01115
01116
01117 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01118 &pChannelMap);
01119 if (rv == -1)
01120
01121
01122
01123 return SCARD_E_INVALID_HANDLE;
01124
01125 scDisconnectStruct.hCard = hCard;
01126 scDisconnectStruct.dwDisposition = dwDisposition;
01127 scDisconnectStruct.rv = SCARD_S_SUCCESS;
01128
01129 rv = MessageSendWithHeader(SCARD_DISCONNECT,
01130 currentContextMap->dwClientID,
01131 sizeof(scDisconnectStruct),
01132 (void *) &scDisconnectStruct);
01133
01134 if (rv == -1)
01135 {
01136 rv = SCARD_E_NO_SERVICE;
01137 goto end;
01138 }
01139
01140
01141
01142
01143 rv = MessageReceive(&scDisconnectStruct,
01144 sizeof(scDisconnectStruct),
01145 currentContextMap->dwClientID);
01146
01147 if (rv < 0)
01148 {
01149 rv = SCARD_F_COMM_ERROR;
01150 goto end;
01151 }
01152
01153 (void)SCardRemoveHandle(hCard);
01154 rv = scDisconnectStruct.rv;
01155
01156 end:
01157 (void)pthread_mutex_unlock(currentContextMap->mMutex);
01158
01159 PROFILE_END(rv)
01160
01161 return rv;
01162 }
01163
01199 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01200 {
01201
01202 LONG rv;
01203 struct begin_struct scBeginStruct;
01204 SCONTEXTMAP * currentContextMap;
01205 CHANNEL_MAP * pChannelMap;
01206
01207 PROFILE_START
01208
01209 CHECK_SAME_PROCESS
01210
01211
01212
01213
01214 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01215 &pChannelMap);
01216 if (rv == -1)
01217 return SCARD_E_INVALID_HANDLE;
01218
01219 (void)pthread_mutex_lock(currentContextMap->mMutex);
01220
01221
01222 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01223 &pChannelMap);
01224 if (rv == -1)
01225
01226
01227
01228 return SCARD_E_INVALID_HANDLE;
01229
01230 scBeginStruct.hCard = hCard;
01231 scBeginStruct.rv = SCARD_S_SUCCESS;
01232
01233
01234
01235
01236
01237
01238 do
01239 {
01240 rv = MessageSendWithHeader(SCARD_BEGIN_TRANSACTION,
01241 currentContextMap->dwClientID,
01242 sizeof(scBeginStruct),
01243 (void *) &scBeginStruct);
01244
01245 if (rv == -1)
01246 {
01247 rv = SCARD_E_NO_SERVICE;
01248 goto end;
01249 }
01250
01251
01252
01253
01254 rv = MessageReceive(&scBeginStruct, sizeof(scBeginStruct),
01255 currentContextMap->dwClientID);
01256
01257 if (rv < 0)
01258 {
01259 rv = SCARD_F_COMM_ERROR;
01260 goto end;
01261 }
01262
01263 rv = scBeginStruct.rv;
01264 }
01265 while (SCARD_E_SHARING_VIOLATION == rv);
01266
01267 end:
01268 (void)pthread_mutex_unlock(currentContextMap->mMutex);
01269
01270 PROFILE_END(rv);
01271
01272 return rv;
01273 }
01274
01315 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01316 {
01317 LONG rv;
01318 struct end_struct scEndStruct;
01319 int randnum;
01320 SCONTEXTMAP * currentContextMap;
01321 CHANNEL_MAP * pChannelMap;
01322
01323 PROFILE_START
01324
01325
01326
01327
01328 randnum = 0;
01329
01330 CHECK_SAME_PROCESS
01331
01332
01333
01334
01335 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01336 &pChannelMap);
01337 if (rv == -1)
01338 return SCARD_E_INVALID_HANDLE;
01339
01340 (void)pthread_mutex_lock(currentContextMap->mMutex);
01341
01342
01343 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01344 &pChannelMap);
01345 if (rv == -1)
01346
01347
01348
01349 return SCARD_E_INVALID_HANDLE;
01350
01351 scEndStruct.hCard = hCard;
01352 scEndStruct.dwDisposition = dwDisposition;
01353 scEndStruct.rv = SCARD_S_SUCCESS;
01354
01355 rv = MessageSendWithHeader(SCARD_END_TRANSACTION,
01356 currentContextMap->dwClientID,
01357 sizeof(scEndStruct),
01358 (void *) &scEndStruct);
01359
01360 if (rv == -1)
01361 {
01362 rv = SCARD_E_NO_SERVICE;
01363 goto end;
01364 }
01365
01366
01367
01368
01369 rv = MessageReceive(&scEndStruct, sizeof(scEndStruct),
01370 currentContextMap->dwClientID);
01371
01372 if (rv < 0)
01373 {
01374 rv = SCARD_F_COMM_ERROR;
01375 goto end;
01376 }
01377
01378
01379
01380
01381 randnum = SYS_RandomInt(1000, 10000);
01382 (void)SYS_USleep(randnum);
01383 rv = scEndStruct.rv;
01384
01385 end:
01386 (void)pthread_mutex_unlock(currentContextMap->mMutex);
01387
01388 PROFILE_END(rv)
01389
01390 return rv;
01391 }
01392
01399 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01400 {
01401 LONG rv;
01402 struct cancel_transaction_struct scCancelStruct;
01403 SCONTEXTMAP * currentContextMap;
01404 CHANNEL_MAP * pChannelMap;
01405
01406 PROFILE_START
01407
01408 CHECK_SAME_PROCESS
01409
01410
01411
01412
01413 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01414 &pChannelMap);
01415 if (rv == -1)
01416 return SCARD_E_INVALID_HANDLE;
01417
01418 (void)pthread_mutex_lock(currentContextMap->mMutex);
01419
01420
01421 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01422 &pChannelMap);
01423 if (rv == -1)
01424
01425
01426
01427 return SCARD_E_INVALID_HANDLE;
01428
01429 scCancelStruct.hCard = hCard;
01430
01431 rv = MessageSendWithHeader(SCARD_CANCEL_TRANSACTION,
01432 currentContextMap->dwClientID,
01433 sizeof(scCancelStruct), (void *) &scCancelStruct);
01434
01435 if (rv == -1)
01436 {
01437 rv = SCARD_E_NO_SERVICE;
01438 goto end;
01439 }
01440
01441
01442
01443
01444 rv = MessageReceive(&scCancelStruct, sizeof(scCancelStruct),
01445 currentContextMap->dwClientID);
01446
01447 if (rv < 0)
01448 {
01449 rv = SCARD_F_COMM_ERROR;
01450 goto end;
01451 }
01452 rv = scCancelStruct.rv;
01453
01454 end:
01455 (void)pthread_mutex_unlock(currentContextMap->mMutex);
01456
01457 PROFILE_END(rv)
01458
01459 return rv;
01460 }
01461
01551 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName,
01552 LPDWORD pcchReaderLen, LPDWORD pdwState,
01553 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
01554 {
01555 DWORD dwReaderLen, dwAtrLen;
01556 LONG rv;
01557 int i;
01558 struct status_struct scStatusStruct;
01559 SCONTEXTMAP * currentContextMap;
01560 CHANNEL_MAP * pChannelMap;
01561 char *r;
01562 char *bufReader = NULL;
01563 LPBYTE bufAtr = NULL;
01564 DWORD dummy;
01565
01566 PROFILE_START
01567
01568
01569 if (pdwState)
01570 *pdwState = 0;
01571
01572 if (pdwProtocol)
01573 *pdwProtocol = 0;
01574
01575
01576 if (pcchReaderLen == NULL)
01577 pcchReaderLen = &dummy;
01578
01579 if (pcbAtrLen == NULL)
01580 pcbAtrLen = &dummy;
01581
01582
01583 dwReaderLen = *pcchReaderLen;
01584 dwAtrLen = *pcbAtrLen;
01585
01586 *pcchReaderLen = 0;
01587 *pcbAtrLen = 0;
01588
01589 CHECK_SAME_PROCESS
01590
01591
01592
01593
01594 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01595 &pChannelMap);
01596 if (rv == -1)
01597 return SCARD_E_INVALID_HANDLE;
01598
01599 (void)pthread_mutex_lock(currentContextMap->mMutex);
01600
01601
01602 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
01603 &pChannelMap);
01604 if (rv == -1)
01605
01606
01607
01608 return SCARD_E_INVALID_HANDLE;
01609
01610
01611 rv = getReaderStates(currentContextMap);
01612 if (rv != SCARD_S_SUCCESS)
01613 goto end;
01614
01615 r = pChannelMap->readerName;
01616 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01617 {
01618
01619 if (r && strcmp(r, readerStates[i].readerName) == 0)
01620 break;
01621 }
01622
01623 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01624 {
01625 rv = SCARD_E_READER_UNAVAILABLE;
01626 goto end;
01627 }
01628
01629
01630 retry:
01631
01632
01633 memset(&scStatusStruct, 0, sizeof(scStatusStruct));
01634 scStatusStruct.hCard = hCard;
01635
01636
01637 scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
01638 scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
01639
01640 rv = MessageSendWithHeader(SCARD_STATUS, currentContextMap->dwClientID,
01641 sizeof(scStatusStruct),
01642 (void *) &scStatusStruct);
01643
01644 if (rv == -1)
01645 {
01646 rv = SCARD_E_NO_SERVICE;
01647 goto end;
01648 }
01649
01650
01651
01652
01653 rv = MessageReceive(&scStatusStruct, sizeof(scStatusStruct),
01654 currentContextMap->dwClientID);
01655
01656 if (rv < 0)
01657 {
01658 rv = SCARD_F_COMM_ERROR;
01659 goto end;
01660 }
01661
01662 rv = scStatusStruct.rv;
01663
01664 if (sharing_shall_block && (SCARD_E_SHARING_VIOLATION == rv))
01665 {
01666 (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
01667 goto retry;
01668 }
01669
01670 if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
01671 {
01672
01673
01674
01675 goto end;
01676 }
01677
01678
01679
01680
01681
01682 *pcchReaderLen = strlen(pChannelMap->readerName) + 1;
01683 *pcbAtrLen = readerStates[i].cardAtrLength;
01684
01685 if (pdwState)
01686 *pdwState = readerStates[i].readerState;
01687
01688 if (pdwProtocol)
01689 *pdwProtocol = readerStates[i].cardProtocol;
01690
01691 if (SCARD_AUTOALLOCATE == dwReaderLen)
01692 {
01693 dwReaderLen = *pcchReaderLen;
01694 bufReader = malloc(dwReaderLen);
01695 if (NULL == bufReader)
01696 {
01697 rv = SCARD_E_NO_MEMORY;
01698 goto end;
01699 }
01700 if (NULL == mszReaderName)
01701 {
01702 rv = SCARD_E_INVALID_PARAMETER;
01703 goto end;
01704 }
01705 *(char **)mszReaderName = bufReader;
01706 }
01707 else
01708 bufReader = mszReaderName;
01709
01710
01711 if (bufReader)
01712 {
01713 if (*pcchReaderLen > dwReaderLen)
01714 rv = SCARD_E_INSUFFICIENT_BUFFER;
01715
01716 strncpy(bufReader,
01717 pChannelMap->readerName,
01718 dwReaderLen);
01719 }
01720
01721 if (SCARD_AUTOALLOCATE == dwAtrLen)
01722 {
01723 dwAtrLen = *pcbAtrLen;
01724 bufAtr = malloc(dwAtrLen);
01725 if (NULL == bufAtr)
01726 {
01727 rv = SCARD_E_NO_MEMORY;
01728 goto end;
01729 }
01730 if (NULL == pbAtr)
01731 {
01732 rv = SCARD_E_INVALID_PARAMETER;
01733 goto end;
01734 }
01735 *(LPBYTE *)pbAtr = bufAtr;
01736 }
01737 else
01738 bufAtr = pbAtr;
01739
01740 if (bufAtr)
01741 {
01742 if (*pcbAtrLen > dwAtrLen)
01743 rv = SCARD_E_INSUFFICIENT_BUFFER;
01744
01745 memcpy(bufAtr, readerStates[i].cardAtr, min(*pcbAtrLen, dwAtrLen));
01746 }
01747
01748 end:
01749 (void)pthread_mutex_unlock(currentContextMap->mMutex);
01750
01751 PROFILE_END(rv)
01752
01753 return rv;
01754 }
01755
01850 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01851 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01852 {
01853 PSCARD_READERSTATE_A currReader;
01854 READER_STATE *rContext;
01855 long dwTime;
01856 DWORD dwState;
01857 DWORD dwBreakFlag = 0;
01858 unsigned int j;
01859 SCONTEXTMAP * currentContextMap;
01860 int currentReaderCount = 0;
01861 LONG rv = SCARD_S_SUCCESS;
01862
01863 PROFILE_START
01864
01865 if ((rgReaderStates == NULL && cReaders > 0)
01866 || (cReaders > PCSCLITE_MAX_READERS_CONTEXTS))
01867 return SCARD_E_INVALID_PARAMETER;
01868
01869
01870 for (j = 0; j < cReaders; j++)
01871 {
01872 if (rgReaderStates[j].szReader == NULL)
01873 return SCARD_E_INVALID_VALUE;
01874 }
01875
01876
01877 if (cReaders > 0)
01878 {
01879 int nbNonIgnoredReaders = cReaders;
01880
01881 for (j=0; j<cReaders; j++)
01882 if (rgReaderStates[j].dwCurrentState & SCARD_STATE_IGNORE)
01883 nbNonIgnoredReaders--;
01884
01885 if (0 == nbNonIgnoredReaders)
01886 return SCARD_S_SUCCESS;
01887 }
01888 else
01889
01890 return SCARD_S_SUCCESS;
01891
01892 CHECK_SAME_PROCESS
01893
01894
01895
01896
01897 currentContextMap = SCardGetContext(hContext);
01898 if (NULL == currentContextMap)
01899 return SCARD_E_INVALID_HANDLE;
01900
01901 (void)pthread_mutex_lock(currentContextMap->mMutex);
01902
01903
01904 currentContextMap = SCardGetContext(hContext);
01905 if (NULL == currentContextMap)
01906
01907
01908
01909 return SCARD_E_INVALID_HANDLE;
01910
01911
01912 rv = getReaderStates(currentContextMap);
01913 if (rv != SCARD_S_SUCCESS)
01914 goto end;
01915
01916
01917 for (j = 0; j < cReaders; j++)
01918 rgReaderStates[j].dwEventState = 0;
01919
01920
01921 Log2(PCSC_LOG_DEBUG, "Event Loop Start, dwTimeout: %ld", dwTimeout);
01922
01923
01924 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
01925 if (readerStates[j].readerID != 0)
01926 currentReaderCount++;
01927
01928 if (INFINITE == dwTimeout)
01929 dwTime = 60*1000;
01930 else
01931 dwTime = dwTimeout;
01932
01933 j = 0;
01934 do
01935 {
01936 currReader = &rgReaderStates[j];
01937
01938
01939 if (!(currReader->dwCurrentState & SCARD_STATE_IGNORE))
01940 {
01941 LPSTR lpcReaderName;
01942 int i;
01943
01944
01945
01946 lpcReaderName = (char *) currReader->szReader;
01947
01948 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01949 {
01950 if (strcmp(lpcReaderName, readerStates[i].readerName) == 0)
01951 break;
01952 }
01953
01954
01955 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01956 {
01957
01958 if (strcasecmp(lpcReaderName, "\\\\?PnP?\\Notification") == 0)
01959 {
01960 int k, newReaderCount = 0;
01961
01962 for (k=0; k < PCSCLITE_MAX_READERS_CONTEXTS; k++)
01963 if (readerStates[k].readerID != 0)
01964 newReaderCount++;
01965
01966 if (newReaderCount != currentReaderCount)
01967 {
01968 Log1(PCSC_LOG_INFO, "Reader list changed");
01969 currentReaderCount = newReaderCount;
01970
01971 currReader->dwEventState |= SCARD_STATE_CHANGED;
01972 dwBreakFlag = 1;
01973 }
01974 }
01975 else
01976 {
01977 currReader->dwEventState = SCARD_STATE_UNKNOWN | SCARD_STATE_UNAVAILABLE;
01978 if (!(currReader->dwCurrentState & SCARD_STATE_UNKNOWN))
01979 {
01980 currReader->dwEventState |= SCARD_STATE_CHANGED;
01981
01982
01983
01984
01985
01986 dwBreakFlag = 1;
01987 }
01988 }
01989 }
01990 else
01991 {
01992
01993 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01994 {
01995 currReader->dwEventState |= SCARD_STATE_CHANGED;
01996 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01997 Log0(PCSC_LOG_DEBUG);
01998 dwBreakFlag = 1;
01999 }
02000
02001
02002
02003
02004 rContext = &readerStates[i];
02005
02006
02007 dwState = rContext->readerState;
02008
02009
02010 if (currReader->dwCurrentState & 0xFFFF0000)
02011 {
02012 int currentCounter, stateCounter;
02013
02014 stateCounter = (dwState >> 16) & 0xFFFF;
02015 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
02016
02017
02018 if (stateCounter != currentCounter)
02019 {
02020 currReader->dwEventState |= SCARD_STATE_CHANGED;
02021 Log0(PCSC_LOG_DEBUG);
02022 dwBreakFlag = 1;
02023 }
02024
02025
02026 currReader->dwEventState =
02027 ((currReader->dwEventState & 0xffff )
02028 | (stateCounter << 16));
02029 }
02030
02031
02032 if (dwState & SCARD_UNKNOWN)
02033 {
02034
02035 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
02036 if (!(currReader->dwCurrentState & SCARD_STATE_UNAVAILABLE))
02037 {
02038
02039 currReader->dwEventState |= SCARD_STATE_CHANGED;
02040 Log0(PCSC_LOG_DEBUG);
02041 dwBreakFlag = 1;
02042 }
02043 }
02044 else
02045 {
02046
02047 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
02048 {
02049 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02050 currReader->dwEventState |= SCARD_STATE_CHANGED;
02051 Log0(PCSC_LOG_DEBUG);
02052 dwBreakFlag = 1;
02053 }
02054 }
02055
02056
02057
02058 if (dwState & SCARD_PRESENT)
02059 {
02060
02061 if (0 == rContext->cardAtrLength)
02062
02063 (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
02064
02065 currReader->cbAtr = rContext->cardAtrLength;
02066 memcpy(currReader->rgbAtr, rContext->cardAtr,
02067 currReader->cbAtr);
02068 }
02069 else
02070 currReader->cbAtr = 0;
02071
02072
02073 if (dwState & SCARD_ABSENT)
02074 {
02075 currReader->dwEventState |= SCARD_STATE_EMPTY;
02076 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
02077 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02078 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02079 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02080 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02081 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
02082 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02083 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02084
02085
02086 if (currReader->dwCurrentState & SCARD_STATE_PRESENT)
02087 {
02088 currReader->dwEventState |= SCARD_STATE_CHANGED;
02089 Log0(PCSC_LOG_DEBUG);
02090 dwBreakFlag = 1;
02091 }
02092 }
02093
02094 else if (dwState & SCARD_PRESENT)
02095 {
02096 currReader->dwEventState |= SCARD_STATE_PRESENT;
02097 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
02098 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02099 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02100 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02101 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02102 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02103
02104 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
02105 {
02106 currReader->dwEventState |= SCARD_STATE_CHANGED;
02107 Log0(PCSC_LOG_DEBUG);
02108 dwBreakFlag = 1;
02109 }
02110
02111 if (dwState & SCARD_SWALLOWED)
02112 {
02113 currReader->dwEventState |= SCARD_STATE_MUTE;
02114 if (!(currReader->dwCurrentState & SCARD_STATE_MUTE))
02115 {
02116 currReader->dwEventState |= SCARD_STATE_CHANGED;
02117 Log0(PCSC_LOG_DEBUG);
02118 dwBreakFlag = 1;
02119 }
02120 }
02121 else
02122 {
02123
02124 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
02125 {
02126 currReader->dwEventState |= SCARD_STATE_CHANGED;
02127 Log0(PCSC_LOG_DEBUG);
02128 dwBreakFlag = 1;
02129 }
02130 }
02131 }
02132
02133
02134 if (rContext->readerSharing == SCARD_EXCLUSIVE_CONTEXT)
02135 {
02136 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
02137 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02138 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02139 {
02140 currReader->dwEventState |= SCARD_STATE_CHANGED;
02141 Log0(PCSC_LOG_DEBUG);
02142 dwBreakFlag = 1;
02143 }
02144 }
02145 else if (rContext->readerSharing >= SCARD_LAST_CONTEXT)
02146 {
02147
02148 if (dwState & SCARD_PRESENT)
02149 {
02150 currReader->dwEventState |= SCARD_STATE_INUSE;
02151 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02152 if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)
02153 {
02154 currReader->dwEventState |= SCARD_STATE_CHANGED;
02155 Log0(PCSC_LOG_DEBUG);
02156 dwBreakFlag = 1;
02157 }
02158 }
02159 }
02160 else if (rContext->readerSharing == SCARD_NO_CONTEXT)
02161 {
02162 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02163 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02164
02165 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02166 {
02167 currReader->dwEventState |= SCARD_STATE_CHANGED;
02168 Log0(PCSC_LOG_DEBUG);
02169 dwBreakFlag = 1;
02170 }
02171 else if (currReader-> dwCurrentState
02172 & SCARD_STATE_EXCLUSIVE)
02173 {
02174 currReader->dwEventState |= SCARD_STATE_CHANGED;
02175 Log0(PCSC_LOG_DEBUG);
02176 dwBreakFlag = 1;
02177 }
02178 }
02179
02180 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02181 {
02182
02183
02184
02185
02186 currReader->dwEventState |= SCARD_STATE_CHANGED;
02187 Log0(PCSC_LOG_DEBUG);
02188 dwBreakFlag = 1;
02189 }
02190 }
02191 }
02192
02193
02194 j++;
02195 if (j == cReaders)
02196 {
02197
02198 j = 0;
02199
02200
02201
02202
02203 if (dwBreakFlag == 1)
02204 break;
02205
02206
02207 {
02208 struct wait_reader_state_change waitStatusStruct;
02209 struct timeval before, after;
02210
02211 gettimeofday(&before, NULL);
02212
02213 waitStatusStruct.timeOut = dwTime;
02214 waitStatusStruct.rv = SCARD_S_SUCCESS;
02215
02216 rv = MessageSendWithHeader(CMD_WAIT_READER_STATE_CHANGE,
02217 currentContextMap->dwClientID,
02218 sizeof(waitStatusStruct),
02219 &waitStatusStruct);
02220
02221 if (rv == -1)
02222 {
02223 rv = SCARD_E_NO_SERVICE;
02224 goto end;
02225 }
02226
02227
02228
02229
02230 rv = MessageReceiveTimeout(CMD_WAIT_READER_STATE_CHANGE,
02231 &waitStatusStruct, sizeof(waitStatusStruct),
02232 currentContextMap->dwClientID, dwTime);
02233
02234
02235 if (-2 == rv)
02236 {
02237
02238 rv = MessageSendWithHeader(CMD_STOP_WAITING_READER_STATE_CHANGE,
02239 currentContextMap->dwClientID,
02240 sizeof(waitStatusStruct),
02241 &waitStatusStruct);
02242
02243 if (rv == -1)
02244 {
02245 rv = SCARD_E_NO_SERVICE;
02246 goto end;
02247 }
02248
02249
02250 rv = MessageReceive(&waitStatusStruct,
02251 sizeof(waitStatusStruct),
02252 currentContextMap->dwClientID);
02253
02254 if (rv == -1)
02255 {
02256 rv = SCARD_E_NO_SERVICE;
02257 goto end;
02258 }
02259 }
02260
02261 if (rv < 0)
02262 {
02263 rv = SCARD_E_NO_SERVICE;
02264 goto end;
02265 }
02266
02267
02268 if (SCARD_S_SUCCESS != waitStatusStruct.rv)
02269 {
02270 rv = waitStatusStruct.rv;
02271 goto end;
02272 }
02273
02274
02275 rv = getReaderStates(currentContextMap);
02276 if (rv != SCARD_S_SUCCESS)
02277 goto end;
02278
02279 if (INFINITE != dwTimeout)
02280 {
02281 long int diff;
02282
02283 gettimeofday(&after, NULL);
02284 diff = time_sub(&after, &before);
02285 dwTime -= diff/1000;
02286 }
02287 }
02288
02289 if (dwTimeout != INFINITE)
02290 {
02291
02292
02293
02294 if (dwTime <= 0)
02295 {
02296 rv = SCARD_E_TIMEOUT;
02297 goto end;
02298 }
02299 }
02300 }
02301 }
02302 while (1);
02303
02304 end:
02305 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02306
02307 (void)pthread_mutex_unlock(currentContextMap->mMutex);
02308
02309 PROFILE_END(rv)
02310
02311 return rv;
02312 }
02313
02367 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02368 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02369 LPDWORD lpBytesReturned)
02370 {
02371 LONG rv;
02372 struct control_struct scControlStruct;
02373 SCONTEXTMAP * currentContextMap;
02374 CHANNEL_MAP * pChannelMap;
02375
02376 PROFILE_START
02377
02378
02379 if (NULL != lpBytesReturned)
02380 *lpBytesReturned = 0;
02381
02382 CHECK_SAME_PROCESS
02383
02384
02385
02386
02387 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
02388 &pChannelMap);
02389 if (rv == -1)
02390 {
02391 PROFILE_END(SCARD_E_INVALID_HANDLE)
02392 return SCARD_E_INVALID_HANDLE;
02393 }
02394
02395 (void)pthread_mutex_lock(currentContextMap->mMutex);
02396
02397
02398 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
02399 &pChannelMap);
02400 if (rv == -1)
02401
02402
02403
02404 return SCARD_E_INVALID_HANDLE;
02405
02406 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02407 || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02408 {
02409 rv = SCARD_E_INSUFFICIENT_BUFFER;
02410 goto end;
02411 }
02412
02413 scControlStruct.hCard = hCard;
02414 scControlStruct.dwControlCode = dwControlCode;
02415 scControlStruct.cbSendLength = cbSendLength;
02416 scControlStruct.cbRecvLength = cbRecvLength;
02417
02418 rv = MessageSendWithHeader(SCARD_CONTROL,
02419 currentContextMap->dwClientID,
02420 sizeof(scControlStruct), &scControlStruct);
02421
02422 if (rv == -1)
02423 {
02424 rv = SCARD_E_NO_SERVICE;
02425 goto end;
02426 }
02427
02428
02429 rv = MessageSend((char *)pbSendBuffer, cbSendLength,
02430 currentContextMap->dwClientID);
02431
02432 if (rv == -1)
02433 {
02434 rv = SCARD_E_NO_SERVICE;
02435 goto end;
02436 }
02437
02438
02439
02440
02441 rv = MessageReceive(&scControlStruct, sizeof(scControlStruct),
02442 currentContextMap->dwClientID);
02443
02444 if (rv < 0)
02445 {
02446 rv = SCARD_F_COMM_ERROR;
02447 goto end;
02448 }
02449
02450 if (SCARD_S_SUCCESS == scControlStruct.rv)
02451 {
02452
02453 rv = MessageReceive(pbRecvBuffer, scControlStruct.dwBytesReturned,
02454 currentContextMap->dwClientID);
02455
02456 if (rv < 0)
02457 {
02458 rv = SCARD_E_NO_SERVICE;
02459 goto end;
02460 }
02461
02462 }
02463
02464 if (NULL != lpBytesReturned)
02465 *lpBytesReturned = scControlStruct.dwBytesReturned;
02466
02467 rv = scControlStruct.rv;
02468
02469 end:
02470 (void)pthread_mutex_unlock(currentContextMap->mMutex);
02471
02472 PROFILE_END(rv)
02473
02474 return rv;
02475 }
02476
02581 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02582 LPDWORD pcbAttrLen)
02583 {
02584 LONG ret;
02585 unsigned char *buf = NULL;
02586
02587 PROFILE_START
02588
02589 if (NULL == pcbAttrLen)
02590 return SCARD_E_INVALID_PARAMETER;
02591
02592 if (SCARD_AUTOALLOCATE == *pcbAttrLen)
02593 {
02594 if (NULL == pbAttr)
02595 return SCARD_E_INVALID_PARAMETER;
02596
02597 *pcbAttrLen = MAX_BUFFER_SIZE;
02598 buf = malloc(*pcbAttrLen);
02599 if (NULL == buf)
02600 return SCARD_E_NO_MEMORY;
02601
02602 *(unsigned char **)pbAttr = buf;
02603 }
02604 else
02605 {
02606 buf = pbAttr;
02607
02608
02609 if (NULL == pbAttr)
02610
02611 *pcbAttrLen = MAX_BUFFER_SIZE;
02612 }
02613
02614 ret = SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, buf,
02615 pcbAttrLen);
02616
02617 PROFILE_END(ret)
02618
02619 return ret;
02620 }
02621
02657 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02658 DWORD cbAttrLen)
02659 {
02660 LONG ret;
02661
02662 PROFILE_START
02663
02664 if (NULL == pbAttr || 0 == cbAttrLen)
02665 return SCARD_E_INVALID_PARAMETER;
02666
02667 ret = SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02668 &cbAttrLen);
02669
02670 PROFILE_END(ret)
02671
02672 return ret;
02673 }
02674
02675 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02676 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02677 {
02678 LONG rv;
02679 struct getset_struct scGetSetStruct;
02680 SCONTEXTMAP * currentContextMap;
02681 CHANNEL_MAP * pChannelMap;
02682
02683 CHECK_SAME_PROCESS
02684
02685
02686
02687
02688 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
02689 &pChannelMap);
02690 if (rv == -1)
02691 return SCARD_E_INVALID_HANDLE;
02692
02693 (void)pthread_mutex_lock(currentContextMap->mMutex);
02694
02695
02696 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
02697 &pChannelMap);
02698 if (rv == -1)
02699
02700
02701
02702 return SCARD_E_INVALID_HANDLE;
02703
02704 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02705 {
02706 rv = SCARD_E_INSUFFICIENT_BUFFER;
02707 goto end;
02708 }
02709
02710 scGetSetStruct.hCard = hCard;
02711 scGetSetStruct.dwAttrId = dwAttrId;
02712 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02713 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02714 memset(scGetSetStruct.pbAttr, 0, sizeof(scGetSetStruct.pbAttr));
02715 if (SCARD_SET_ATTRIB == command)
02716 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02717
02718 rv = MessageSendWithHeader(command,
02719 currentContextMap->dwClientID, sizeof(scGetSetStruct),
02720 &scGetSetStruct);
02721
02722 if (rv == -1)
02723 {
02724 rv = SCARD_E_NO_SERVICE;
02725 goto end;
02726 }
02727
02728
02729
02730
02731 rv = MessageReceive(&scGetSetStruct, sizeof(scGetSetStruct),
02732 currentContextMap->dwClientID);
02733
02734 if (rv < 0)
02735 {
02736 rv = SCARD_F_COMM_ERROR;
02737 goto end;
02738 }
02739
02740 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02741 {
02742
02743
02744
02745 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02746 {
02747 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02748 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02749 }
02750 else
02751 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02752
02753 if (pbAttr)
02754 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02755
02756 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02757 }
02758 rv = scGetSetStruct.rv;
02759
02760 end:
02761 (void)pthread_mutex_unlock(currentContextMap->mMutex);
02762
02763 return rv;
02764 }
02765
02824 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02825 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02826 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02827 LPDWORD pcbRecvLength)
02828 {
02829 LONG rv;
02830 SCONTEXTMAP * currentContextMap;
02831 CHANNEL_MAP * pChannelMap;
02832 struct transmit_struct scTransmitStruct;
02833
02834 PROFILE_START
02835
02836 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02837 pcbRecvLength == NULL || pioSendPci == NULL)
02838 return SCARD_E_INVALID_PARAMETER;
02839
02840 CHECK_SAME_PROCESS
02841
02842
02843
02844
02845 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
02846 &pChannelMap);
02847 if (rv == -1)
02848 {
02849 *pcbRecvLength = 0;
02850 PROFILE_END(SCARD_E_INVALID_HANDLE)
02851 return SCARD_E_INVALID_HANDLE;
02852 }
02853
02854 (void)pthread_mutex_lock(currentContextMap->mMutex);
02855
02856
02857 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
02858 &pChannelMap);
02859 if (rv == -1)
02860
02861
02862
02863 return SCARD_E_INVALID_HANDLE;
02864
02865 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02866 || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02867 {
02868 rv = SCARD_E_INSUFFICIENT_BUFFER;
02869 goto end;
02870 }
02871
02872
02873 retry:
02874
02875 scTransmitStruct.hCard = hCard;
02876 scTransmitStruct.cbSendLength = cbSendLength;
02877 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
02878 scTransmitStruct.ioSendPciProtocol = pioSendPci->dwProtocol;
02879 scTransmitStruct.ioSendPciLength = pioSendPci->cbPciLength;
02880 scTransmitStruct.rv = SCARD_S_SUCCESS;
02881
02882 if (pioRecvPci)
02883 {
02884 scTransmitStruct.ioRecvPciProtocol = pioRecvPci->dwProtocol;
02885 scTransmitStruct.ioRecvPciLength = pioRecvPci->cbPciLength;
02886 }
02887 else
02888 {
02889 scTransmitStruct.ioRecvPciProtocol = SCARD_PROTOCOL_ANY;
02890 scTransmitStruct.ioRecvPciLength = sizeof(SCARD_IO_REQUEST);
02891 }
02892
02893 rv = MessageSendWithHeader(SCARD_TRANSMIT,
02894 currentContextMap->dwClientID, sizeof(scTransmitStruct),
02895 (void *) &scTransmitStruct);
02896
02897 if (rv == -1)
02898 {
02899 rv = SCARD_E_NO_SERVICE;
02900 goto end;
02901 }
02902
02903
02904 rv = MessageSend((void *)pbSendBuffer, cbSendLength,
02905 currentContextMap->dwClientID);
02906
02907 if (rv == -1)
02908 {
02909 rv = SCARD_E_NO_SERVICE;
02910 goto end;
02911 }
02912
02913
02914
02915
02916 rv = MessageReceive(&scTransmitStruct, sizeof(scTransmitStruct),
02917 currentContextMap->dwClientID);
02918
02919 if (rv < 0)
02920 {
02921 rv = SCARD_F_COMM_ERROR;
02922 goto end;
02923 }
02924
02925 if (SCARD_S_SUCCESS == scTransmitStruct.rv)
02926 {
02927
02928 rv = MessageReceive(pbRecvBuffer, scTransmitStruct.pcbRecvLength,
02929 currentContextMap->dwClientID);
02930
02931 if (rv < 0)
02932 {
02933 rv = SCARD_E_NO_SERVICE;
02934 goto end;
02935 }
02936
02937 if (pioRecvPci)
02938 {
02939 pioRecvPci->dwProtocol = scTransmitStruct.ioRecvPciProtocol;
02940 pioRecvPci->cbPciLength = scTransmitStruct.ioRecvPciLength;
02941 }
02942 }
02943
02944 rv = scTransmitStruct.rv;
02945
02946 if (sharing_shall_block && (SCARD_E_SHARING_VIOLATION == rv))
02947 {
02948 (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
02949 goto retry;
02950 }
02951
02952 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
02953
02954 end:
02955 (void)pthread_mutex_unlock(currentContextMap->mMutex);
02956
02957 PROFILE_END(rv)
02958
02959 return rv;
02960 }
02961
03012 LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
03013 LPSTR mszReaders, LPDWORD pcchReaders)
03014 {
03015 DWORD dwReadersLen = 0;
03016 int i;
03017 SCONTEXTMAP * currentContextMap;
03018 LONG rv = SCARD_S_SUCCESS;
03019 char *buf = NULL;
03020
03021 (void)mszGroups;
03022 PROFILE_START
03023
03024
03025
03026
03027 if (pcchReaders == NULL)
03028 return SCARD_E_INVALID_PARAMETER;
03029
03030 CHECK_SAME_PROCESS
03031
03032
03033
03034
03035 currentContextMap = SCardGetContext(hContext);
03036 if (NULL == currentContextMap)
03037 {
03038 PROFILE_END(SCARD_E_INVALID_HANDLE)
03039 return SCARD_E_INVALID_HANDLE;
03040 }
03041
03042 (void)pthread_mutex_lock(currentContextMap->mMutex);
03043
03044
03045 currentContextMap = SCardGetContext(hContext);
03046 if (NULL == currentContextMap)
03047
03048
03049
03050 return SCARD_E_INVALID_HANDLE;
03051
03052
03053 rv = getReaderStates(currentContextMap);
03054 if (rv != SCARD_S_SUCCESS)
03055 goto end;
03056
03057 dwReadersLen = 0;
03058 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03059 if (readerStates[i].readerID != 0)
03060 dwReadersLen += strlen(readerStates[i].readerName) + 1;
03061
03062
03063 dwReadersLen += 1;
03064
03065 if (1 == dwReadersLen)
03066 {
03067 rv = SCARD_E_NO_READERS_AVAILABLE;
03068 goto end;
03069 }
03070
03071 if (SCARD_AUTOALLOCATE == *pcchReaders)
03072 {
03073 buf = malloc(dwReadersLen);
03074 if (NULL == buf)
03075 {
03076 rv = SCARD_E_NO_MEMORY;
03077 goto end;
03078 }
03079 if (NULL == mszReaders)
03080 {
03081 rv = SCARD_E_INVALID_PARAMETER;
03082 goto end;
03083 }
03084 *(char **)mszReaders = buf;
03085 }
03086 else
03087 {
03088 buf = mszReaders;
03089
03090
03091 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
03092 {
03093 rv = SCARD_E_INSUFFICIENT_BUFFER;
03094 goto end;
03095 }
03096 }
03097
03098 if (mszReaders == NULL)
03099 goto end;
03100
03101 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03102 {
03103 if (readerStates[i].readerID != 0)
03104 {
03105
03106
03107
03108 strcpy(buf, readerStates[i].readerName);
03109 buf += strlen(readerStates[i].readerName)+1;
03110 }
03111 }
03112 *buf = '\0';
03113
03114 end:
03115
03116 *pcchReaders = dwReadersLen;
03117
03118 (void)pthread_mutex_unlock(currentContextMap->mMutex);
03119
03120 PROFILE_END(rv)
03121
03122 return rv;
03123 }
03124
03138 LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
03139 {
03140 LONG rv = SCARD_S_SUCCESS;
03141 SCONTEXTMAP * currentContextMap;
03142
03143 PROFILE_START
03144
03145 CHECK_SAME_PROCESS
03146
03147
03148
03149
03150 currentContextMap = SCardGetContext(hContext);
03151 if (NULL == currentContextMap)
03152 return SCARD_E_INVALID_HANDLE;
03153
03154 free((void *)pvMem);
03155
03156 PROFILE_END(rv)
03157
03158 return rv;
03159 }
03160
03212 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
03213 LPDWORD pcchGroups)
03214 {
03215 LONG rv = SCARD_S_SUCCESS;
03216 SCONTEXTMAP * currentContextMap;
03217 char *buf = NULL;
03218
03219 PROFILE_START
03220
03221
03222 const char ReaderGroup[] = "SCard$DefaultReaders\0";
03223 const unsigned int dwGroups = sizeof(ReaderGroup);
03224
03225 CHECK_SAME_PROCESS
03226
03227
03228
03229
03230 currentContextMap = SCardGetContext(hContext);
03231 if (NULL == currentContextMap)
03232 return SCARD_E_INVALID_HANDLE;
03233
03234 (void)pthread_mutex_lock(currentContextMap->mMutex);
03235
03236
03237 currentContextMap = SCardGetContext(hContext);
03238 if (NULL == currentContextMap)
03239
03240
03241
03242 return SCARD_E_INVALID_HANDLE;
03243
03244 if (SCARD_AUTOALLOCATE == *pcchGroups)
03245 {
03246 buf = malloc(dwGroups);
03247 if (NULL == buf)
03248 {
03249 rv = SCARD_E_NO_MEMORY;
03250 goto end;
03251 }
03252 if (NULL == mszGroups)
03253 {
03254 rv = SCARD_E_INVALID_PARAMETER;
03255 goto end;
03256 }
03257 *(char **)mszGroups = buf;
03258 }
03259 else
03260 {
03261 buf = mszGroups;
03262
03263 if ((NULL != mszGroups) && (*pcchGroups < dwGroups))
03264 {
03265 rv = SCARD_E_INSUFFICIENT_BUFFER;
03266 goto end;
03267 }
03268 }
03269
03270 if (buf)
03271 memcpy(buf, ReaderGroup, dwGroups);
03272
03273 end:
03274 *pcchGroups = dwGroups;
03275
03276 (void)pthread_mutex_unlock(currentContextMap->mMutex);
03277
03278 PROFILE_END(rv)
03279
03280 return rv;
03281 }
03282
03312 LONG SCardCancel(SCARDCONTEXT hContext)
03313 {
03314 SCONTEXTMAP * currentContextMap;
03315 LONG rv = SCARD_S_SUCCESS;
03316 uint32_t dwClientID = 0;
03317 struct cancel_struct scCancelStruct;
03318
03319 PROFILE_START
03320
03321
03322
03323
03324 currentContextMap = SCardGetContext(hContext);
03325 if (NULL == currentContextMap)
03326 return SCARD_E_INVALID_HANDLE;
03327
03328
03329 if (ClientSetupSession(&dwClientID) != 0)
03330 {
03331 rv = SCARD_E_NO_SERVICE;
03332 goto error;
03333 }
03334
03335 scCancelStruct.hContext = hContext;
03336 scCancelStruct.rv = SCARD_S_SUCCESS;
03337
03338 rv = MessageSendWithHeader(SCARD_CANCEL,
03339 dwClientID,
03340 sizeof(scCancelStruct), (void *) &scCancelStruct);
03341
03342 if (rv == -1)
03343 {
03344 rv = SCARD_E_NO_SERVICE;
03345 goto end;
03346 }
03347
03348
03349
03350
03351 rv = MessageReceive(&scCancelStruct, sizeof(scCancelStruct),
03352 dwClientID);
03353
03354 if (rv < 0)
03355 {
03356 rv = SCARD_F_COMM_ERROR;
03357 goto end;
03358 }
03359
03360 rv = scCancelStruct.rv;
03361 end:
03362 ClientCloseSession(dwClientID);
03363
03364 error:
03365 PROFILE_END(rv)
03366
03367 return rv;
03368 }
03369
03393 LONG SCardIsValidContext(SCARDCONTEXT hContext)
03394 {
03395 LONG rv;
03396 SCONTEXTMAP * currentContextMap;
03397
03398 PROFILE_START
03399
03400 rv = SCARD_S_SUCCESS;
03401
03402
03403 CHECK_SAME_PROCESS
03404
03405
03406
03407
03408 currentContextMap = SCardGetContext(hContext);
03409 if (currentContextMap == NULL)
03410 rv = SCARD_E_INVALID_HANDLE;
03411
03412 PROFILE_END(rv)
03413
03414 return rv;
03415 }
03416
03433 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
03434 {
03435 int lrv;
03436 SCONTEXTMAP * newContextMap;
03437
03438 newContextMap = malloc(sizeof(SCONTEXTMAP));
03439 if (NULL == newContextMap)
03440 return SCARD_E_NO_MEMORY;
03441
03442 Log2(PCSC_LOG_DEBUG, "Allocating new SCONTEXTMAP @%X", newContextMap);
03443 newContextMap->hContext = hContext;
03444 newContextMap->dwClientID = dwClientID;
03445
03446 newContextMap->mMutex = malloc(sizeof(pthread_mutex_t));
03447 if (NULL == newContextMap->mMutex)
03448 {
03449 Log2(PCSC_LOG_DEBUG, "Freeing SCONTEXTMAP @%X", newContextMap);
03450 free(newContextMap);
03451 return SCARD_E_NO_MEMORY;
03452 }
03453 (void)pthread_mutex_init(newContextMap->mMutex, NULL);
03454
03455 lrv = list_init(&(newContextMap->channelMapList));
03456 if (lrv < 0)
03457 {
03458 Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %X", lrv);
03459 goto error;
03460 }
03461
03462 lrv = list_attributes_seeker(&(newContextMap->channelMapList),
03463 CHANNEL_MAP_seeker);
03464 if (lrv <0)
03465 {
03466 Log2(PCSC_LOG_CRITICAL,
03467 "list_attributes_seeker failed with return value: %X", lrv);
03468 list_destroy(&(newContextMap->channelMapList));
03469 goto error;
03470 }
03471
03472 lrv = list_append(&contextMapList, newContextMap);
03473 if (lrv < 0)
03474 {
03475 Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %X",
03476 lrv);
03477 list_destroy(&(newContextMap->channelMapList));
03478 goto error;
03479 }
03480
03481 return SCARD_S_SUCCESS;
03482
03483 error:
03484
03485 (void)pthread_mutex_destroy(newContextMap->mMutex);
03486 free(newContextMap->mMutex);
03487 free(newContextMap);
03488
03489 return SCARD_E_NO_MEMORY;
03490 }
03491
03504 static SCONTEXTMAP * SCardGetContext(SCARDCONTEXT hContext)
03505 {
03506 SCONTEXTMAP * currentContextMap;
03507
03508 (void)SCardLockThread();
03509 currentContextMap = SCardGetContextTH(hContext);
03510 (void)SCardUnlockThread();
03511
03512 return currentContextMap;
03513 }
03514
03527 static SCONTEXTMAP * SCardGetContextTH(SCARDCONTEXT hContext)
03528 {
03529 return list_seek(&contextMapList, &hContext);
03530 }
03531
03541 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
03542 {
03543 SCONTEXTMAP * currentContextMap;
03544 currentContextMap = SCardGetContextTH(hContext);
03545
03546 if (NULL == currentContextMap)
03547 return SCARD_E_INVALID_HANDLE;
03548 else
03549 return SCardCleanContext(currentContextMap);
03550 }
03551
03552 static LONG SCardCleanContext(SCONTEXTMAP * targetContextMap)
03553 {
03554 int list_index, lrv;
03555 int listSize;
03556 CHANNEL_MAP * currentChannelMap;
03557
03558 targetContextMap->hContext = 0;
03559 (void)ClientCloseSession(targetContextMap->dwClientID);
03560 targetContextMap->dwClientID = 0;
03561 (void)pthread_mutex_destroy(targetContextMap->mMutex);
03562 free(targetContextMap->mMutex);
03563 targetContextMap->mMutex = NULL;
03564
03565 listSize = list_size(&(targetContextMap->channelMapList));
03566 for (list_index = 0; list_index < listSize; list_index++)
03567 {
03568 currentChannelMap = list_get_at(&(targetContextMap->channelMapList),
03569 list_index);
03570 if (NULL == currentChannelMap)
03571 {
03572 Log2(PCSC_LOG_CRITICAL, "list_get_at failed for index %d",
03573 list_index);
03574 continue;
03575 }
03576 else
03577 {
03578 free(currentChannelMap->readerName);
03579 free(currentChannelMap);
03580 }
03581
03582 }
03583 list_destroy(&(targetContextMap->channelMapList));
03584
03585 lrv = list_delete(&contextMapList, targetContextMap);
03586 if (lrv < 0)
03587 {
03588 Log2(PCSC_LOG_CRITICAL,
03589 "list_delete failed with return value: %X", lrv);
03590 }
03591
03592 free(targetContextMap);
03593
03594 return SCARD_S_SUCCESS;
03595 }
03596
03597
03598
03599
03600
03601 static LONG SCardAddHandle(SCARDHANDLE hCard, SCONTEXTMAP * currentContextMap,
03602 LPCSTR readerName)
03603 {
03604 CHANNEL_MAP * newChannelMap;
03605 int lrv = -1;
03606
03607 newChannelMap = malloc(sizeof(CHANNEL_MAP));
03608 if (NULL == newChannelMap)
03609 return SCARD_E_NO_MEMORY;
03610
03611 newChannelMap->hCard = hCard;
03612 newChannelMap->readerName = strdup(readerName);
03613
03614 lrv = list_append(&(currentContextMap->channelMapList), newChannelMap);
03615 if (lrv < 0)
03616 {
03617 free(newChannelMap->readerName);
03618 free(newChannelMap);
03619 Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %X", lrv);
03620 return SCARD_E_NO_MEMORY;
03621 }
03622
03623 return SCARD_S_SUCCESS;
03624 }
03625
03626 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03627 {
03628 SCONTEXTMAP * currentContextMap;
03629 CHANNEL_MAP * currentChannelMap;
03630 int lrv;
03631 LONG rv;
03632
03633 rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
03634 ¤tChannelMap);
03635 if (rv == -1)
03636 return SCARD_E_INVALID_HANDLE;
03637
03638 free(currentChannelMap->readerName);
03639
03640 lrv = list_delete(&(currentContextMap->channelMapList), currentChannelMap);
03641 if (lrv < 0)
03642 {
03643 Log2(PCSC_LOG_CRITICAL,
03644 "list_delete failed with return value: %X", lrv);
03645 }
03646
03647 free(currentChannelMap);
03648
03649 return SCARD_S_SUCCESS;
03650 }
03651
03652 static LONG SCardGetContextAndChannelFromHandle(SCARDHANDLE hCard,
03653 SCONTEXTMAP **targetContextMap, CHANNEL_MAP ** targetChannelMap)
03654 {
03655 LONG rv;
03656
03657 if (0 == hCard)
03658 return -1;
03659
03660 (void)SCardLockThread();
03661 rv = SCardGetContextAndChannelFromHandleTH(hCard, targetContextMap, targetChannelMap);
03662 (void)SCardUnlockThread();
03663
03664 return rv;
03665 }
03666
03667 static LONG SCardGetContextAndChannelFromHandleTH(SCARDHANDLE hCard,
03668 SCONTEXTMAP **targetContextMap, CHANNEL_MAP ** targetChannelMap)
03669 {
03670 int listSize;
03671 int list_index;
03672 SCONTEXTMAP * currentContextMap;
03673 CHANNEL_MAP * currentChannelMap;
03674
03675
03676 *targetContextMap = NULL;
03677 *targetChannelMap = NULL;
03678
03679 listSize = list_size(&contextMapList);
03680
03681 for (list_index = 0; list_index < listSize; list_index++)
03682 {
03683 currentContextMap = list_get_at(&contextMapList, list_index);
03684 if (currentContextMap == NULL)
03685 {
03686 Log2(PCSC_LOG_CRITICAL, "list_get_at failed for index %d", list_index);
03687 continue;
03688 }
03689 currentChannelMap = list_seek(&(currentContextMap->channelMapList),
03690 &hCard);
03691 if (currentChannelMap != NULL)
03692 {
03693 *targetContextMap = currentContextMap;
03694 *targetChannelMap = currentChannelMap;
03695 return SCARD_S_SUCCESS;
03696 }
03697 }
03698
03699 return -1;
03700 }
03701
03702 static LONG SCardInvalidateHandles(void)
03703 {
03704
03705 (void)SCardLockThread();
03706
03707 while (list_size(&contextMapList) != 0)
03708 {
03709 SCONTEXTMAP * currentContextMap;
03710
03711 currentContextMap = list_get_at(&contextMapList, 0);
03712 if (currentContextMap != NULL)
03713 (void)SCardCleanContext(currentContextMap);
03714 else
03715 Log1(PCSC_LOG_CRITICAL, "list_get_at returned NULL");
03716 }
03717
03718 (void)SCardUnlockThread();
03719
03720
03721 daemon_ctime = 0;
03722 client_pid = 0;
03723
03724 return SCARD_E_INVALID_HANDLE;
03725 }
03726
03739 LONG SCardCheckDaemonAvailability(void)
03740 {
03741 LONG rv;
03742 struct stat statBuffer;
03743 int need_restart = 0;
03744
03745 rv = stat(PCSCLITE_CSOCK_NAME, &statBuffer);
03746
03747 if (rv != 0)
03748 {
03749 Log2(PCSC_LOG_INFO, "PCSC Not Running: " PCSCLITE_CSOCK_NAME ": %s",
03750 strerror(errno));
03751 return SCARD_E_NO_SERVICE;
03752 }
03753
03754
03755
03756 if (daemon_ctime && statBuffer.st_ctime > daemon_ctime)
03757 {
03758
03759 if (GetDaemonPid() != daemon_pid)
03760 {
03761 Log1(PCSC_LOG_INFO, "PCSC restarted");
03762 need_restart = 1;
03763 }
03764 }
03765
03766
03767 if (client_pid && client_pid != getpid())
03768 {
03769 Log1(PCSC_LOG_INFO, "Client forked");
03770 need_restart = 1;
03771 }
03772
03773 if (need_restart)
03774 return SCardInvalidateHandles();
03775
03776 daemon_ctime = statBuffer.st_ctime;
03777 daemon_pid = GetDaemonPid();
03778 client_pid = getpid();
03779
03780 return SCARD_S_SUCCESS;
03781 }
03782
03783 #ifdef DO_CHECK_SAME_PROCESS
03784 static LONG SCardCheckSameProcess(void)
03785 {
03786
03787 if ((client_pid && client_pid != getpid()))
03788 {
03789 Log1(PCSC_LOG_INFO, "Client forked");
03790 return SCardInvalidateHandles();
03791 }
03792
03793 client_pid = getpid();
03794
03795 return SCARD_S_SUCCESS;
03796 }
03797 #endif
03798
03799 static LONG getReaderStates(SCONTEXTMAP * currentContextMap)
03800 {
03801 int32_t dwClientID = currentContextMap->dwClientID;
03802
03803 if (-1 == MessageSendWithHeader(CMD_GET_READERS_STATE, dwClientID, 0, NULL))
03804 return SCARD_E_NO_SERVICE;
03805
03806
03807 if (MessageReceive(&readerStates, sizeof(readerStates), dwClientID) < 0)
03808 return SCARD_F_COMM_ERROR;
03809
03810 return SCARD_S_SUCCESS;
03811 }
03812