00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00021 #include "config.h"
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <sys/types.h>
00025 #include <fcntl.h>
00026 #include <unistd.h>
00027 #include <sys/un.h>
00028 #include <errno.h>
00029 #include <stddef.h>
00030 #include <sys/time.h>
00031
00032 #include "misc.h"
00033 #include "pcscd.h"
00034 #include "winscard.h"
00035 #include "debug.h"
00036 #include "thread_generic.h"
00037 #include "strlcpycat.h"
00038
00039 #include "readerfactory.h"
00040 #include "eventhandler.h"
00041 #include "sys_generic.h"
00042 #include "winscard_msg.h"
00043 #include "utils.h"
00044
00046 #define SCARD_PROTOCOL_ANY_OLD 0x1000
00047
00048 #ifndef TRUE
00049 #define TRUE 1
00050 #define FALSE 0
00051 #endif
00052
00053
00054 static long int time_sub(struct timeval *a, struct timeval *b)
00055 {
00056 struct timeval r;
00057 r.tv_sec = a -> tv_sec - b -> tv_sec;
00058 r.tv_usec = a -> tv_usec - b -> tv_usec;
00059 if (r.tv_usec < 0)
00060 {
00061 r.tv_sec--;
00062 r.tv_usec += 1000000;
00063 }
00064
00065 return r.tv_sec * 1000000 + r.tv_usec;
00066 }
00067
00068
00069 #undef DO_PROFILE
00070 #ifdef DO_PROFILE
00071
00072 #define PROFILE_FILE "/tmp/pcsc_profile"
00073 #include <stdio.h>
00074 #include <sys/time.h>
00075
00076 struct timeval profile_time_start;
00077 FILE *profile_fd;
00078 char profile_tty;
00079 char fct_name[100];
00080
00081 #define PROFILE_START profile_start(__FUNCTION__);
00082 #define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
00083
00084 static void profile_start(const char *f)
00085 {
00086 static char initialized = FALSE;
00087
00088 if (!initialized)
00089 {
00090 char filename[80];
00091
00092 initialized = TRUE;
00093 sprintf(filename, "%s-%d", PROFILE_FILE, getuid());
00094 profile_fd = fopen(filename, "a+");
00095 if (NULL == profile_fd)
00096 {
00097 fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n",
00098 PROFILE_FILE, strerror(errno));
00099 exit(-1);
00100 }
00101 fprintf(profile_fd, "\nStart a new profile\n");
00102
00103 if (isatty(fileno(stderr)))
00104 profile_tty = TRUE;
00105 else
00106 profile_tty = FALSE;
00107 }
00108
00109
00110 if (profile_tty && fct_name[0])
00111 printf("\33[01;34m WARNING: %s starts before %s finishes\33[0m\n",
00112 f, fct_name);
00113
00114 strlcpy(fct_name, f, sizeof(fct_name));
00115
00116 gettimeofday(&profile_time_start, NULL);
00117 }
00118
00119 static void profile_end(const char *f, LONG rv)
00120 {
00121 struct timeval profile_time_end;
00122 long d;
00123
00124 gettimeofday(&profile_time_end, NULL);
00125 d = time_sub(&profile_time_end, &profile_time_start);
00126
00127 if (profile_tty)
00128 {
00129 if (fct_name[0])
00130 {
00131 if (strncmp(fct_name, f, sizeof(fct_name)))
00132 printf("\33[01;34m WARNING: %s ends before %s\33[0m\n",
00133 f, fct_name);
00134 }
00135 else
00136 printf("\33[01;34m WARNING: %s ends but we lost its start\33[0m\n",
00137 f);
00138
00139
00140 fct_name[0] = '\0';
00141
00142 if (rv != SCARD_S_SUCCESS)
00143 fprintf(stderr,
00144 "\33[01;31mRESULT %s \33[35m%ld \33[34m0x%08lX %s\33[0m\n",
00145 f, d, rv, pcsc_stringify_error(rv));
00146 else
00147 fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m\n", f, d);
00148 }
00149 fprintf(profile_fd, "%s %ld\n", f, d);
00150 fflush(profile_fd);
00151 }
00152
00153 #else
00154 #define PROFILE_START
00155 #define PROFILE_END(rv)
00156 #endif
00157
00162 struct _psChannelMap
00163 {
00164 SCARDHANDLE hCard;
00165 LPSTR readerName;
00166 };
00167
00168 typedef struct _psChannelMap CHANNEL_MAP, *PCHANNEL_MAP;
00169
00175 static struct _psContextMap
00176 {
00177 DWORD dwClientID;
00178 SCARDCONTEXT hContext;
00179 DWORD contextBlockStatus;
00180 PCSCLITE_MUTEX_T mMutex;
00181 CHANNEL_MAP psChannelMap[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
00182 } psContextMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
00183
00187 static short isExecuted = 0;
00188
00189
00193 static time_t daemon_ctime = 0;
00194 static pid_t daemon_pid = 0;
00199 static pid_t client_pid = 0;
00200
00206 static int mapAddr = 0;
00207
00212 static PCSCLITE_MUTEX clientMutex = PTHREAD_MUTEX_INITIALIZER;
00213
00220 static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
00221
00222 PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
00223 PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
00224 PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
00227 static LONG SCardAddContext(SCARDCONTEXT, DWORD);
00228 static LONG SCardGetContextIndice(SCARDCONTEXT);
00229 static LONG SCardGetContextIndiceTH(SCARDCONTEXT);
00230 static LONG SCardRemoveContext(SCARDCONTEXT);
00231 static LONG SCardCleanContext(LONG indice);
00232
00233 static LONG SCardAddHandle(SCARDHANDLE, DWORD, LPCSTR);
00234 static LONG SCardGetIndicesFromHandle(SCARDHANDLE, PDWORD,
00235 PDWORD);
00236 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE, PDWORD,
00237 PDWORD);
00238 static LONG SCardRemoveHandle(SCARDHANDLE);
00239
00240 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
00241 LPBYTE pbAttr, LPDWORD pcbAttrLen);
00242
00243 void DESTRUCTOR SCardUnload(void);
00244
00245
00246
00247
00254 inline static LONG SCardLockThread(void)
00255 {
00256 return SYS_MutexLock(&clientMutex);
00257 }
00258
00264 inline static LONG SCardUnlockThread(void)
00265 {
00266 return SYS_MutexUnLock(&clientMutex);
00267 }
00268
00269 static LONG SCardEstablishContextTH(DWORD, LPCVOID, LPCVOID,
00270 LPSCARDCONTEXT);
00271
00305 LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
00306 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00307 {
00308 LONG rv;
00309
00310 PROFILE_START
00311
00312
00313 rv = SCardCheckDaemonAvailability();
00314 if (SCARD_E_INVALID_HANDLE == rv)
00315
00316 rv = SCardCheckDaemonAvailability();
00317
00318 if (rv != SCARD_S_SUCCESS)
00319 return rv;
00320
00321 (void)SCardLockThread();
00322 rv = SCardEstablishContextTH(dwScope, pvReserved1,
00323 pvReserved2, phContext);
00324 (void)SCardUnlockThread();
00325
00326 PROFILE_END(rv)
00327
00328 return rv;
00329 }
00330
00357 static LONG SCardEstablishContextTH(DWORD dwScope,
00358 LPCVOID pvReserved1,
00359 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00360 {
00361 LONG rv;
00362 int i;
00363 establish_struct scEstablishStruct;
00364 sharedSegmentMsg msgStruct;
00365 uint32_t dwClientID = 0;
00366
00367 (void)pvReserved1;
00368 (void)pvReserved2;
00369 if (phContext == NULL)
00370 return SCARD_E_INVALID_PARAMETER;
00371 else
00372 *phContext = 0;
00373
00374
00375
00376
00377
00378
00379
00380
00381 if (isExecuted == 0)
00382 {
00383 int pageSize;
00384
00385
00386
00387
00388 (void)SYS_Initialize();
00389
00390
00391
00392
00393 mapAddr = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDONLY, 0);
00394 if (mapAddr < 0)
00395 {
00396 Log3(PCSC_LOG_CRITICAL, "Cannot open public shared file %s: %s",
00397 PCSCLITE_PUBSHM_FILE, strerror(errno));
00398 return SCARD_E_NO_SERVICE;
00399 }
00400
00401
00402
00403
00404 (void)fcntl(mapAddr, F_SETFD, FD_CLOEXEC);
00405
00406 pageSize = SYS_GetPageSize();
00407
00408
00409
00410
00411 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00412 {
00413 readerStates[i] =
00414 (PREADER_STATE)SYS_PublicMemoryMap(sizeof(READER_STATE),
00415 mapAddr, (i * pageSize));
00416 if (readerStates[i] == NULL)
00417 {
00418 Log2(PCSC_LOG_CRITICAL, "Cannot public memory map: %s",
00419 strerror(errno));
00420 (void)SYS_CloseFile(mapAddr);
00421 return SCARD_F_INTERNAL_ERROR;
00422 }
00423 }
00424
00425
00426
00427
00428 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00429 {
00430 int j;
00431
00432
00433
00434
00435 psContextMap[i].dwClientID = 0;
00436 psContextMap[i].hContext = 0;
00437 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
00438 psContextMap[i].mMutex = NULL;
00439
00440 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
00441 {
00442
00443
00444
00445 psContextMap[i].psChannelMap[j].hCard = 0;
00446 psContextMap[i].psChannelMap[j].readerName = NULL;
00447 }
00448 }
00449
00450 }
00451
00452
00453
00454
00455
00456 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00457 {
00458 if (psContextMap[i].dwClientID == 0)
00459 break;
00460 }
00461
00462 if (i == PCSCLITE_MAX_APPLICATION_CONTEXTS)
00463 {
00464 return SCARD_E_NO_MEMORY;
00465 }
00466
00467
00468 if (SHMClientSetupSession(&dwClientID) != 0)
00469 {
00470 (void)SYS_CloseFile(mapAddr);
00471 return SCARD_E_NO_SERVICE;
00472 }
00473
00474 {
00475 version_struct *veStr;
00476
00477 memset(&msgStruct, 0, sizeof(msgStruct));
00478 msgStruct.mtype = CMD_VERSION;
00479 msgStruct.user_id = SYS_GetUID();
00480 msgStruct.group_id = SYS_GetGID();
00481 msgStruct.command = 0;
00482 msgStruct.date = time(NULL);
00483
00484 veStr = &msgStruct.veStr;
00485 veStr->major = PROTOCOL_VERSION_MAJOR;
00486 veStr->minor = PROTOCOL_VERSION_MINOR;
00487
00488 if (-1 == SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
00489 PCSCLITE_MCLIENT_ATTEMPTS))
00490 return SCARD_E_NO_SERVICE;
00491
00492
00493
00494
00495 if (-1 == SHMMessageReceive(&msgStruct, sizeof(msgStruct), dwClientID,
00496 PCSCLITE_CLIENT_ATTEMPTS))
00497 {
00498 Log1(PCSC_LOG_CRITICAL, "Your pcscd is too old and does not support CMD_VERSION");
00499 return SCARD_F_COMM_ERROR;
00500 }
00501
00502 Log3(PCSC_LOG_INFO, "Server is protocol version %d:%d",
00503 veStr->major, veStr->minor);
00504
00505 if (veStr->rv != SCARD_S_SUCCESS)
00506 return veStr->rv;
00507
00508 isExecuted = 1;
00509 }
00510
00511 again:
00512
00513
00514
00515 scEstablishStruct.dwScope = dwScope;
00516 scEstablishStruct.hContext = 0;
00517 scEstablishStruct.rv = SCARD_S_SUCCESS;
00518
00519 rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
00520 sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
00521 (void *) &scEstablishStruct);
00522
00523 if (rv == -1)
00524 return SCARD_E_NO_SERVICE;
00525
00526
00527
00528
00529 rv = SHMClientRead(&msgStruct, dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00530
00531 if (rv == -1)
00532 return SCARD_F_COMM_ERROR;
00533
00534 memcpy(&scEstablishStruct, &msgStruct.data, sizeof(scEstablishStruct));
00535
00536 if (scEstablishStruct.rv != SCARD_S_SUCCESS)
00537 return scEstablishStruct.rv;
00538
00539
00540 if (-1 != SCardGetContextIndiceTH(scEstablishStruct.hContext))
00541
00542
00543 goto again;
00544
00545 *phContext = scEstablishStruct.hContext;
00546
00547
00548
00549
00550 rv = SCardAddContext(*phContext, dwClientID);
00551
00552 return rv;
00553 }
00554
00576 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00577 {
00578 LONG rv;
00579 release_struct scReleaseStruct;
00580 sharedSegmentMsg msgStruct;
00581 LONG dwContextIndex;
00582
00583 PROFILE_START
00584
00585
00586
00587
00588
00589 dwContextIndex = SCardGetContextIndice(hContext);
00590 if (dwContextIndex == -1)
00591 return SCARD_E_INVALID_HANDLE;
00592
00593 rv = SCardCheckDaemonAvailability();
00594 if (rv != SCARD_S_SUCCESS)
00595 {
00596
00597
00598
00599 (void)SCardLockThread();
00600 (void)SCardRemoveContext(hContext);
00601 (void)SCardUnlockThread();
00602
00603 return rv;
00604 }
00605
00606 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00607
00608
00609 dwContextIndex = SCardGetContextIndice(hContext);
00610 if (dwContextIndex == -1)
00611
00612
00613
00614 return SCARD_E_INVALID_HANDLE;
00615
00616 scReleaseStruct.hContext = hContext;
00617 scReleaseStruct.rv = SCARD_S_SUCCESS;
00618
00619 rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT,
00620 psContextMap[dwContextIndex].dwClientID,
00621 sizeof(scReleaseStruct),
00622 PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);
00623
00624 if (rv == -1)
00625 {
00626 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00627 return SCARD_E_NO_SERVICE;
00628 }
00629
00630
00631
00632
00633 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00634 PCSCLITE_CLIENT_ATTEMPTS);
00635 memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));
00636
00637 if (rv == -1)
00638 {
00639 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00640 return SCARD_F_COMM_ERROR;
00641 }
00642
00643 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00644
00645
00646
00647
00648 (void)SCardLockThread();
00649 (void)SCardRemoveContext(hContext);
00650 (void)SCardUnlockThread();
00651
00652 PROFILE_END(scReleaseStruct.rv)
00653
00654 return scReleaseStruct.rv;
00655 }
00656
00672 LONG SCardSetTimeout( SCARDCONTEXT hContext,
00673 DWORD dwTimeout)
00674 {
00675
00676
00677
00678 (void)hContext;
00679 (void)dwTimeout;
00680 return SCARD_S_SUCCESS;
00681 }
00682
00734 LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,
00735 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00736 LPDWORD pdwActiveProtocol)
00737 {
00738 LONG rv;
00739 connect_struct scConnectStruct;
00740 sharedSegmentMsg msgStruct;
00741 LONG dwContextIndex;
00742
00743 PROFILE_START
00744
00745
00746
00747
00748 if (phCard == NULL || pdwActiveProtocol == NULL)
00749 return SCARD_E_INVALID_PARAMETER;
00750 else
00751 *phCard = 0;
00752
00753 if (szReader == NULL)
00754 return SCARD_E_UNKNOWN_READER;
00755
00756
00757
00758
00759 if (strlen(szReader) > MAX_READERNAME)
00760 return SCARD_E_INVALID_VALUE;
00761
00762 rv = SCardCheckDaemonAvailability();
00763 if (rv != SCARD_S_SUCCESS)
00764 return rv;
00765
00766
00767
00768
00769 dwContextIndex = SCardGetContextIndice(hContext);
00770 if (dwContextIndex == -1)
00771 return SCARD_E_INVALID_HANDLE;
00772
00773 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00774
00775
00776 dwContextIndex = SCardGetContextIndice(hContext);
00777 if (dwContextIndex == -1)
00778
00779
00780
00781 return SCARD_E_INVALID_HANDLE;
00782
00783 strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);
00784
00785 scConnectStruct.hContext = hContext;
00786 scConnectStruct.dwShareMode = dwShareMode;
00787 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00788 scConnectStruct.hCard = 0;
00789 scConnectStruct.dwActiveProtocol = 0;
00790 scConnectStruct.rv = SCARD_S_SUCCESS;
00791
00792 rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
00793 sizeof(scConnectStruct),
00794 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);
00795
00796 if (rv == -1)
00797 {
00798 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00799 return SCARD_E_NO_SERVICE;
00800 }
00801
00802
00803
00804
00805 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00806 PCSCLITE_CLIENT_ATTEMPTS);
00807
00808 memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));
00809
00810 if (rv == -1)
00811 {
00812 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00813 return SCARD_F_COMM_ERROR;
00814 }
00815
00816 *phCard = scConnectStruct.hCard;
00817 *pdwActiveProtocol = scConnectStruct.dwActiveProtocol;
00818
00819 if (scConnectStruct.rv == SCARD_S_SUCCESS)
00820 {
00821
00822
00823
00824 rv = SCardAddHandle(*phCard, dwContextIndex, szReader);
00825 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00826
00827 PROFILE_END(rv)
00828
00829 return rv;
00830 }
00831
00832 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00833
00834 PROFILE_END(scConnectStruct.rv)
00835
00836 return scConnectStruct.rv;
00837 }
00838
00906 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00907 DWORD dwPreferredProtocols, DWORD dwInitialization,
00908 LPDWORD pdwActiveProtocol)
00909 {
00910 LONG rv;
00911 reconnect_struct scReconnectStruct;
00912 sharedSegmentMsg msgStruct;
00913 int i;
00914 DWORD dwContextIndex, dwChannelIndex;
00915
00916 PROFILE_START
00917
00918 if (pdwActiveProtocol == NULL)
00919 return SCARD_E_INVALID_PARAMETER;
00920
00921 rv = SCardCheckDaemonAvailability();
00922 if (rv != SCARD_S_SUCCESS)
00923 return rv;
00924
00925
00926
00927
00928 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00929 if (rv == -1)
00930 return SCARD_E_INVALID_HANDLE;
00931
00932 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00933
00934
00935 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00936 if (rv == -1)
00937
00938
00939
00940 return SCARD_E_INVALID_HANDLE;
00941
00942 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00943 {
00944 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
00945
00946
00947 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
00948 break;
00949 }
00950
00951 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00952 {
00953 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00954 return SCARD_E_READER_UNAVAILABLE;
00955 }
00956
00957 do
00958 {
00959 scReconnectStruct.hCard = hCard;
00960 scReconnectStruct.dwShareMode = dwShareMode;
00961 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00962 scReconnectStruct.dwInitialization = dwInitialization;
00963 scReconnectStruct.dwActiveProtocol = *pdwActiveProtocol;
00964 scReconnectStruct.rv = SCARD_S_SUCCESS;
00965
00966 rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
00967 sizeof(scReconnectStruct),
00968 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
00969
00970 if (rv == -1)
00971 {
00972 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00973 return SCARD_E_NO_SERVICE;
00974 }
00975
00976
00977
00978
00979 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00980 PCSCLITE_CLIENT_ATTEMPTS);
00981
00982 memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
00983
00984 if (rv == -1)
00985 {
00986 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00987 return SCARD_F_COMM_ERROR;
00988 }
00989 } while (SCARD_E_SHARING_VIOLATION == scReconnectStruct.rv);
00990
00991 *pdwActiveProtocol = scReconnectStruct.dwActiveProtocol;
00992
00993 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00994
00995 PROFILE_END(scReconnectStruct.rv)
00996
00997 return scReconnectStruct.rv;
00998 }
00999
01030 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
01031 {
01032 LONG rv;
01033 disconnect_struct scDisconnectStruct;
01034 sharedSegmentMsg msgStruct;
01035 DWORD dwContextIndex, dwChannelIndex;
01036
01037 PROFILE_START
01038
01039 rv = SCardCheckDaemonAvailability();
01040 if (rv != SCARD_S_SUCCESS)
01041 return rv;
01042
01043
01044
01045
01046 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01047 if (rv == -1)
01048 return SCARD_E_INVALID_HANDLE;
01049
01050 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01051
01052
01053 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01054 if (rv == -1)
01055
01056
01057
01058 return SCARD_E_INVALID_HANDLE;
01059
01060 scDisconnectStruct.hCard = hCard;
01061 scDisconnectStruct.dwDisposition = dwDisposition;
01062 scDisconnectStruct.rv = SCARD_S_SUCCESS;
01063
01064 rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
01065 sizeof(scDisconnectStruct),
01066 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
01067
01068 if (rv == -1)
01069 {
01070 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01071 return SCARD_E_NO_SERVICE;
01072 }
01073
01074
01075
01076
01077 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01078 PCSCLITE_CLIENT_ATTEMPTS);
01079
01080 memcpy(&scDisconnectStruct, &msgStruct.data,
01081 sizeof(scDisconnectStruct));
01082
01083 if (rv == -1)
01084 {
01085 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01086 return SCARD_F_COMM_ERROR;
01087 }
01088
01089 (void)SCardRemoveHandle(hCard);
01090
01091 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01092
01093 PROFILE_END(scDisconnectStruct.rv)
01094
01095 return scDisconnectStruct.rv;
01096 }
01097
01133 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01134 {
01135
01136 LONG rv;
01137 begin_struct scBeginStruct;
01138 int i;
01139 sharedSegmentMsg msgStruct;
01140 DWORD dwContextIndex, dwChannelIndex;
01141
01142 PROFILE_START
01143
01144 rv = SCardCheckDaemonAvailability();
01145 if (rv != SCARD_S_SUCCESS)
01146 return rv;
01147
01148
01149
01150
01151 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01152 if (rv == -1)
01153 return SCARD_E_INVALID_HANDLE;
01154
01155 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01156
01157
01158 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01159 if (rv == -1)
01160
01161
01162
01163 return SCARD_E_INVALID_HANDLE;
01164
01165 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01166 {
01167 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01168
01169
01170 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01171 break;
01172 }
01173
01174 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01175 {
01176 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01177 return SCARD_E_READER_UNAVAILABLE;
01178 }
01179
01180 scBeginStruct.hCard = hCard;
01181 scBeginStruct.rv = SCARD_S_SUCCESS;
01182
01183
01184
01185
01186
01187
01188 do
01189 {
01190 rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01191 sizeof(scBeginStruct),
01192 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);
01193
01194 if (rv == -1)
01195 {
01196
01197 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01198 return SCARD_E_NO_SERVICE;
01199 }
01200
01201
01202
01203
01204 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01205 PCSCLITE_CLIENT_ATTEMPTS);
01206
01207 memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));
01208
01209 if (rv == -1)
01210 {
01211
01212 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01213 return SCARD_F_COMM_ERROR;
01214 }
01215
01216 }
01217 while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
01218
01219 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01220
01221 PROFILE_END(scBeginStruct.rv);
01222
01223 return scBeginStruct.rv;
01224 }
01225
01266 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01267 {
01268 LONG rv;
01269 end_struct scEndStruct;
01270 sharedSegmentMsg msgStruct;
01271 int randnum, i;
01272 DWORD dwContextIndex, dwChannelIndex;
01273
01274 PROFILE_START
01275
01276
01277
01278
01279 randnum = 0;
01280
01281 rv = SCardCheckDaemonAvailability();
01282 if (rv != SCARD_S_SUCCESS)
01283 return rv;
01284
01285
01286
01287
01288 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01289 if (rv == -1)
01290 return SCARD_E_INVALID_HANDLE;
01291
01292 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01293
01294
01295 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01296 if (rv == -1)
01297
01298
01299
01300 return SCARD_E_INVALID_HANDLE;
01301
01302 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01303 {
01304 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01305
01306
01307 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01308 break;
01309 }
01310
01311 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01312 {
01313 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01314 return SCARD_E_READER_UNAVAILABLE;
01315 }
01316
01317 scEndStruct.hCard = hCard;
01318 scEndStruct.dwDisposition = dwDisposition;
01319 scEndStruct.rv = SCARD_S_SUCCESS;
01320
01321 rv = WrapSHMWrite(SCARD_END_TRANSACTION,
01322 psContextMap[dwContextIndex].dwClientID,
01323 sizeof(scEndStruct),
01324 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
01325
01326 if (rv == -1)
01327 {
01328 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01329 return SCARD_E_NO_SERVICE;
01330 }
01331
01332
01333
01334
01335 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01336 PCSCLITE_CLIENT_ATTEMPTS);
01337
01338 memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
01339
01340 if (rv == -1)
01341 {
01342 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01343 return SCARD_F_COMM_ERROR;
01344 }
01345
01346
01347
01348
01349 randnum = SYS_RandomInt(1000, 10000);
01350 (void)SYS_USleep(randnum);
01351
01352 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01353
01354 PROFILE_END(scEndStruct.rv)
01355
01356 return scEndStruct.rv;
01357 }
01358
01365 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01366 {
01367 LONG rv;
01368 cancel_struct scCancelStruct;
01369 sharedSegmentMsg msgStruct;
01370 int i;
01371 DWORD dwContextIndex, dwChannelIndex;
01372
01373 PROFILE_START
01374
01375 rv = SCardCheckDaemonAvailability();
01376 if (rv != SCARD_S_SUCCESS)
01377 return rv;
01378
01379
01380
01381
01382 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01383 if (rv == -1)
01384 return SCARD_E_INVALID_HANDLE;
01385
01386 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01387
01388
01389 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01390 if (rv == -1)
01391
01392
01393
01394 return SCARD_E_INVALID_HANDLE;
01395
01396 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01397 {
01398 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01399
01400
01401 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01402 break;
01403 }
01404
01405 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01406 {
01407 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01408 return SCARD_E_READER_UNAVAILABLE;
01409 }
01410
01411 scCancelStruct.hCard = hCard;
01412
01413 rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION,
01414 psContextMap[dwContextIndex].dwClientID,
01415 sizeof(scCancelStruct),
01416 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
01417
01418 if (rv == -1)
01419 {
01420 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01421 return SCARD_E_NO_SERVICE;
01422 }
01423
01424
01425
01426
01427 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01428 PCSCLITE_CLIENT_ATTEMPTS);
01429
01430 memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
01431
01432 if (rv == -1)
01433 {
01434 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01435 return SCARD_F_COMM_ERROR;
01436 }
01437
01438 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01439
01440 PROFILE_END(scCancelStruct.rv)
01441
01442 return scCancelStruct.rv;
01443 }
01444
01532 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName,
01533 LPDWORD pcchReaderLen, LPDWORD pdwState,
01534 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
01535 {
01536 DWORD dwReaderLen, dwAtrLen;
01537 LONG rv;
01538 int i;
01539 status_struct scStatusStruct;
01540 sharedSegmentMsg msgStruct;
01541 DWORD dwContextIndex, dwChannelIndex;
01542 char *r;
01543 char *bufReader = NULL;
01544 LPBYTE bufAtr = NULL;
01545 DWORD dummy;
01546
01547 PROFILE_START
01548
01549
01550 if (pdwState)
01551 *pdwState = 0;
01552
01553 if (pdwProtocol)
01554 *pdwProtocol = 0;
01555
01556
01557 if (pcchReaderLen == NULL)
01558 pcchReaderLen = &dummy;
01559
01560 if (pcbAtrLen == NULL)
01561 pcbAtrLen = &dummy;
01562
01563
01564 dwReaderLen = *pcchReaderLen;
01565 dwAtrLen = *pcbAtrLen;
01566
01567 *pcchReaderLen = 0;
01568 *pcbAtrLen = 0;
01569
01570 rv = SCardCheckDaemonAvailability();
01571 if (rv != SCARD_S_SUCCESS)
01572 return rv;
01573
01574
01575
01576
01577 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01578 if (rv == -1)
01579 return SCARD_E_INVALID_HANDLE;
01580
01581 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01582
01583
01584 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01585 if (rv == -1)
01586
01587
01588
01589 return SCARD_E_INVALID_HANDLE;
01590
01591 r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01592 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01593 {
01594
01595 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01596 break;
01597 }
01598
01599 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01600 {
01601 rv = SCARD_E_READER_UNAVAILABLE;
01602 goto end;
01603 }
01604
01605
01606 memset(&scStatusStruct, 0, sizeof(scStatusStruct));
01607 scStatusStruct.hCard = hCard;
01608
01609
01610 scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
01611 scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
01612
01613 rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
01614 sizeof(scStatusStruct),
01615 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
01616
01617 if (rv == -1)
01618 {
01619 rv = SCARD_E_NO_SERVICE;
01620 goto end;
01621 }
01622
01623
01624
01625
01626 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01627 PCSCLITE_CLIENT_ATTEMPTS);
01628
01629 memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
01630
01631 if (rv == -1)
01632 {
01633 rv = SCARD_F_COMM_ERROR;
01634 goto end;
01635 }
01636
01637 rv = scStatusStruct.rv;
01638 if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
01639 {
01640
01641
01642
01643 goto end;
01644 }
01645
01646
01647
01648
01649
01650 *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
01651 *pcbAtrLen = (readerStates[i])->cardAtrLength;
01652
01653 if (pdwState)
01654 *pdwState = (readerStates[i])->readerState;
01655
01656 if (pdwProtocol)
01657 *pdwProtocol = (readerStates[i])->cardProtocol;
01658
01659 if (SCARD_AUTOALLOCATE == dwReaderLen)
01660 {
01661 dwReaderLen = *pcchReaderLen;
01662 bufReader = malloc(dwReaderLen);
01663 if (NULL == bufReader)
01664 {
01665 rv = SCARD_E_NO_MEMORY;
01666 goto end;
01667 }
01668 if (NULL == mszReaderName)
01669 {
01670 rv = SCARD_E_INVALID_PARAMETER;
01671 goto end;
01672 }
01673 *(char **)mszReaderName = bufReader;
01674 }
01675 else
01676 bufReader = mszReaderName;
01677
01678
01679 if (bufReader)
01680 {
01681 if (*pcchReaderLen > dwReaderLen)
01682 rv = SCARD_E_INSUFFICIENT_BUFFER;
01683
01684 strncpy(bufReader,
01685 psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
01686 dwReaderLen);
01687 }
01688
01689 if (SCARD_AUTOALLOCATE == dwAtrLen)
01690 {
01691 dwAtrLen = *pcbAtrLen;
01692 bufAtr = malloc(dwAtrLen);
01693 if (NULL == bufAtr)
01694 {
01695 rv = SCARD_E_NO_MEMORY;
01696 goto end;
01697 }
01698 if (NULL == pbAtr)
01699 {
01700 rv = SCARD_E_INVALID_PARAMETER;
01701 goto end;
01702 }
01703 *(LPBYTE *)pbAtr = bufAtr;
01704 }
01705 else
01706 bufAtr = pbAtr;
01707
01708 if (bufAtr)
01709 {
01710 if (*pcbAtrLen > dwAtrLen)
01711 rv = SCARD_E_INSUFFICIENT_BUFFER;
01712
01713 memcpy(bufAtr, (readerStates[i])->cardAtr, min(*pcbAtrLen, dwAtrLen));
01714 }
01715
01716 end:
01717 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01718
01719 PROFILE_END(rv)
01720
01721 return rv;
01722 }
01723
01724 static long WaitForPcscdEvent(SCARDCONTEXT hContext, long dwTime)
01725 {
01726 char filename[FILENAME_MAX];
01727 char buf[1];
01728 int fd, r;
01729 struct timeval tv, *ptv = NULL;
01730 struct timeval before, after;
01731 fd_set read_fd;
01732
01733 if (INFINITE != dwTime)
01734 {
01735 if (dwTime < 0)
01736 return 0;
01737 gettimeofday(&before, NULL);
01738 tv.tv_sec = dwTime/1000;
01739 tv.tv_usec = dwTime*1000 - tv.tv_sec*1000000;
01740 ptv = &tv;
01741 }
01742
01743 (void)snprintf(filename, sizeof(filename), "%s/event.%d.%ld",
01744 PCSCLITE_EVENTS_DIR, SYS_GetPID(), hContext);
01745 r = mkfifo(filename, 0644);
01746 if (-1 == r)
01747 {
01748 Log2(PCSC_LOG_CRITICAL, "Can't create event fifo: %s", strerror(errno));
01749 goto exit;
01750 }
01751
01752 fd = SYS_OpenFile(filename, O_RDONLY | O_NONBLOCK, 0);
01753
01754
01755 if (-1 != fd)
01756 {
01757 FD_ZERO(&read_fd);
01758 FD_SET(fd, &read_fd);
01759
01760 (void)select(fd+1, &read_fd, NULL, NULL, ptv);
01761
01762 (void)SYS_ReadFile(fd, buf, 1);
01763 (void)SYS_CloseFile(fd);
01764 }
01765
01766 (void)SYS_RemoveFile(filename);
01767
01768 if (INFINITE != dwTime)
01769 {
01770 long int diff;
01771
01772 gettimeofday(&after, NULL);
01773 diff = time_sub(&after, &before);
01774 dwTime -= diff/1000;
01775 }
01776
01777 exit:
01778 return dwTime;
01779 }
01780
01872 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01873 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01874 {
01875 PSCARD_READERSTATE_A currReader;
01876 PREADER_STATE rContext;
01877 long dwTime = dwTimeout;
01878 DWORD dwState;
01879 DWORD dwBreakFlag = 0;
01880 int j;
01881 LONG dwContextIndex;
01882 int currentReaderCount = 0;
01883 LONG rv = SCARD_S_SUCCESS;
01884
01885 PROFILE_START
01886
01887 if ((rgReaderStates == NULL && cReaders > 0)
01888 || (cReaders > PCSCLITE_MAX_READERS_CONTEXTS))
01889 return SCARD_E_INVALID_PARAMETER;
01890
01891
01892 for (j = 0; j < cReaders; j++)
01893 {
01894 if (rgReaderStates[j].szReader == NULL)
01895 return SCARD_E_INVALID_VALUE;
01896 }
01897
01898
01899 if (cReaders > 0)
01900 {
01901 int nbNonIgnoredReaders = cReaders;
01902
01903 for (j=0; j<cReaders; j++)
01904 if (rgReaderStates[j].dwCurrentState & SCARD_STATE_IGNORE)
01905 nbNonIgnoredReaders--;
01906
01907 if (0 == nbNonIgnoredReaders)
01908 return SCARD_S_SUCCESS;
01909 }
01910
01911 rv = SCardCheckDaemonAvailability();
01912 if (rv != SCARD_S_SUCCESS)
01913 return rv;
01914
01915
01916
01917
01918 dwContextIndex = SCardGetContextIndice(hContext);
01919 if (dwContextIndex == -1)
01920 return SCARD_E_INVALID_HANDLE;
01921
01922 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01923
01924
01925 dwContextIndex = SCardGetContextIndice(hContext);
01926 if (dwContextIndex == -1)
01927
01928
01929
01930 return SCARD_E_INVALID_HANDLE;
01931
01932
01933
01934
01935
01936
01937
01938 if (cReaders == 0)
01939 {
01940 while (1)
01941 {
01942 int i;
01943
01944 rv = SCardCheckDaemonAvailability();
01945 if (rv != SCARD_S_SUCCESS)
01946 goto end;
01947
01948 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01949 {
01950 if ((readerStates[i])->readerID != 0)
01951 {
01952
01953 rv = SCARD_S_SUCCESS;
01954 goto end;
01955 }
01956 }
01957
01958 if (dwTimeout == 0)
01959 {
01960
01961 rv = SCARD_E_READER_UNAVAILABLE;
01962 goto end;
01963 }
01964
01965 dwTime = WaitForPcscdEvent(hContext, dwTime);
01966 if (dwTimeout != INFINITE)
01967 {
01968 if (dwTime <= 0)
01969 {
01970 rv = SCARD_E_TIMEOUT;
01971 goto end;
01972 }
01973 }
01974 }
01975 }
01976
01977
01978
01979
01980
01981
01982 for (j = 0; j < cReaders; j++)
01983 rgReaderStates[j].dwEventState = 0;
01984
01985
01986 Log1(PCSC_LOG_DEBUG, "Event Loop Start");
01987
01988 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
01989
01990
01991 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
01992 if ((readerStates[j])->readerID != 0)
01993 currentReaderCount++;
01994
01995 j = 0;
01996 do
01997 {
01998 rv = SCardCheckDaemonAvailability();
01999 if (rv != SCARD_S_SUCCESS)
02000 {
02001 if (psContextMap[dwContextIndex].mMutex)
02002 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02003
02004 PROFILE_END(rv)
02005
02006 return rv;
02007 }
02008
02009 currReader = &rgReaderStates[j];
02010
02011
02012 if (!(currReader->dwCurrentState & SCARD_STATE_IGNORE))
02013 {
02014 LPSTR lpcReaderName;
02015 int i;
02016
02017
02018
02019 lpcReaderName = (char *) currReader->szReader;
02020
02021 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02022 {
02023 if (strcmp(lpcReaderName, (readerStates[i])->readerName) == 0)
02024 break;
02025 }
02026
02027
02028 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02029 {
02030
02031 if (strcasecmp(lpcReaderName, "\\\\?PnP?\\Notification") == 0)
02032 {
02033 int k, newReaderCount = 0;
02034
02035 for (k=0; k < PCSCLITE_MAX_READERS_CONTEXTS; k++)
02036 if ((readerStates[k])->readerID != 0)
02037 newReaderCount++;
02038
02039 if (newReaderCount != currentReaderCount)
02040 {
02041 Log1(PCSC_LOG_INFO, "Reader list changed");
02042 currentReaderCount = newReaderCount;
02043
02044 currReader->dwEventState |= SCARD_STATE_CHANGED;
02045 dwBreakFlag = 1;
02046 }
02047 }
02048 else
02049 {
02050 currReader->dwEventState = SCARD_STATE_UNKNOWN | SCARD_STATE_UNAVAILABLE;
02051 if (!(currReader->dwCurrentState & SCARD_STATE_UNKNOWN))
02052 {
02053 currReader->dwEventState |= SCARD_STATE_CHANGED;
02054
02055
02056
02057
02058
02059 dwBreakFlag = 1;
02060 }
02061 }
02062 }
02063 else
02064 {
02065
02066 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
02067 {
02068 currReader->dwEventState |= SCARD_STATE_CHANGED;
02069 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02070 Log0(PCSC_LOG_DEBUG);
02071 dwBreakFlag = 1;
02072 }
02073
02074
02075
02076
02077 rContext = readerStates[i];
02078
02079
02080 dwState = rContext->readerState;
02081
02082
02083 if (currReader->dwCurrentState & 0xFFFF0000)
02084 {
02085 int currentCounter, stateCounter;
02086
02087 stateCounter = (dwState >> 16) & 0xFFFF;
02088 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
02089
02090
02091 if (stateCounter != currentCounter)
02092 {
02093 currReader->dwEventState |= SCARD_STATE_CHANGED;
02094 Log0(PCSC_LOG_DEBUG);
02095 dwBreakFlag = 1;
02096 }
02097
02098
02099 currReader->dwEventState =
02100 ((currReader->dwEventState & 0xffff )
02101 | (stateCounter << 16));
02102 }
02103
02104
02105 if (dwState & SCARD_UNKNOWN)
02106 {
02107
02108 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
02109 if (!(currReader->dwCurrentState & SCARD_STATE_UNAVAILABLE))
02110 {
02111
02112 currReader->dwEventState |= SCARD_STATE_CHANGED;
02113 Log0(PCSC_LOG_DEBUG);
02114 dwBreakFlag = 1;
02115 }
02116 }
02117 else
02118 {
02119
02120 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
02121 {
02122 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02123 currReader->dwEventState |= SCARD_STATE_CHANGED;
02124 Log0(PCSC_LOG_DEBUG);
02125 dwBreakFlag = 1;
02126 }
02127 }
02128
02129
02130
02131 if (dwState & SCARD_PRESENT)
02132 {
02133
02134 if (0 == rContext->cardAtrLength)
02135
02136 (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
02137
02138 currReader->cbAtr = rContext->cardAtrLength;
02139 memcpy(currReader->rgbAtr, rContext->cardAtr,
02140 currReader->cbAtr);
02141 }
02142 else
02143 currReader->cbAtr = 0;
02144
02145
02146 if (dwState & SCARD_ABSENT)
02147 {
02148 currReader->dwEventState |= SCARD_STATE_EMPTY;
02149 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
02150 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02151 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02152 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02153 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02154 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
02155 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02156 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02157
02158
02159 if (currReader->dwCurrentState & SCARD_STATE_PRESENT)
02160 {
02161 currReader->dwEventState |= SCARD_STATE_CHANGED;
02162 Log0(PCSC_LOG_DEBUG);
02163 dwBreakFlag = 1;
02164 }
02165 }
02166
02167 else if (dwState & SCARD_PRESENT)
02168 {
02169 currReader->dwEventState |= SCARD_STATE_PRESENT;
02170 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
02171 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02172 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02173 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02174 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02175 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02176
02177 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
02178 {
02179 currReader->dwEventState |= SCARD_STATE_CHANGED;
02180 Log0(PCSC_LOG_DEBUG);
02181 dwBreakFlag = 1;
02182 }
02183
02184 if (dwState & SCARD_SWALLOWED)
02185 {
02186 currReader->dwEventState |= SCARD_STATE_MUTE;
02187 if (!(currReader->dwCurrentState & SCARD_STATE_MUTE))
02188 {
02189 currReader->dwEventState |= SCARD_STATE_CHANGED;
02190 Log0(PCSC_LOG_DEBUG);
02191 dwBreakFlag = 1;
02192 }
02193 }
02194 else
02195 {
02196
02197 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
02198 {
02199 currReader->dwEventState |= SCARD_STATE_CHANGED;
02200 Log0(PCSC_LOG_DEBUG);
02201 dwBreakFlag = 1;
02202 }
02203 }
02204 }
02205
02206
02207 if (rContext->readerSharing == -1)
02208 {
02209 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
02210 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02211 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02212 {
02213 currReader->dwEventState |= SCARD_STATE_CHANGED;
02214 Log0(PCSC_LOG_DEBUG);
02215 dwBreakFlag = 1;
02216 }
02217 }
02218 else if (rContext->readerSharing >= 1)
02219 {
02220
02221 if (dwState & SCARD_PRESENT)
02222 {
02223 currReader->dwEventState |= SCARD_STATE_INUSE;
02224 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02225 if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)
02226 {
02227 currReader->dwEventState |= SCARD_STATE_CHANGED;
02228 Log0(PCSC_LOG_DEBUG);
02229 dwBreakFlag = 1;
02230 }
02231 }
02232 }
02233 else if (rContext->readerSharing == 0)
02234 {
02235 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02236 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02237
02238 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02239 {
02240 currReader->dwEventState |= SCARD_STATE_CHANGED;
02241 Log0(PCSC_LOG_DEBUG);
02242 dwBreakFlag = 1;
02243 }
02244 else if (currReader-> dwCurrentState
02245 & SCARD_STATE_EXCLUSIVE)
02246 {
02247 currReader->dwEventState |= SCARD_STATE_CHANGED;
02248 Log0(PCSC_LOG_DEBUG);
02249 dwBreakFlag = 1;
02250 }
02251 }
02252
02253 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02254 {
02255
02256
02257
02258
02259 currReader->dwEventState |= SCARD_STATE_CHANGED;
02260 Log0(PCSC_LOG_DEBUG);
02261 dwBreakFlag = 1;
02262 }
02263 }
02264 }
02265
02266
02267 j++;
02268 if (j == cReaders)
02269 {
02270
02271 j = 0;
02272
02273
02274
02275
02276 if (dwBreakFlag == 1)
02277 break;
02278
02279 if (BLOCK_STATUS_RESUME
02280 == psContextMap[dwContextIndex].contextBlockStatus)
02281 break;
02282
02283
02284 dwTime = WaitForPcscdEvent(hContext, dwTime);
02285
02286 if (dwTimeout != INFINITE)
02287 {
02288
02289
02290
02291 if (dwTime <= 0)
02292 {
02293 rv = SCARD_E_TIMEOUT;
02294 goto end;
02295 }
02296 }
02297 }
02298 }
02299 while (1);
02300
02301 if (psContextMap[dwContextIndex].contextBlockStatus == BLOCK_STATUS_RESUME)
02302 rv = SCARD_E_CANCELLED;
02303
02304 end:
02305 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02306
02307 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02308
02309 PROFILE_END(rv)
02310
02311 return rv;
02312 }
02313
02365 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02366 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02367 LPDWORD lpBytesReturned)
02368 {
02369 LONG rv;
02370 control_struct scControlStruct;
02371 sharedSegmentMsg msgStruct;
02372 int i;
02373 DWORD dwContextIndex, dwChannelIndex;
02374
02375 PROFILE_START
02376
02377
02378 if (NULL != lpBytesReturned)
02379 *lpBytesReturned = 0;
02380
02381 rv = SCardCheckDaemonAvailability();
02382 if (rv != SCARD_S_SUCCESS)
02383 return rv;
02384
02385
02386
02387
02388 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02389 if (rv == -1)
02390 return SCARD_E_INVALID_HANDLE;
02391
02392 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02393
02394
02395 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02396 if (rv == -1)
02397
02398
02399
02400 return SCARD_E_INVALID_HANDLE;
02401
02402 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02403 {
02404 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02405
02406
02407 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02408 break;
02409 }
02410
02411 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02412 {
02413 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02414 return SCARD_E_READER_UNAVAILABLE;
02415 }
02416
02417 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02418 || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02419 {
02420 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02421 return SCARD_E_INSUFFICIENT_BUFFER;
02422 }
02423
02424 if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
02425 {
02426
02427 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02428 control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
02429 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02430
02431 scControlStructExtended->hCard = hCard;
02432 scControlStructExtended->dwControlCode = dwControlCode;
02433 scControlStructExtended->cbSendLength = cbSendLength;
02434 scControlStructExtended->cbRecvLength = cbRecvLength;
02435 scControlStructExtended->dwBytesReturned = 0;
02436 scControlStructExtended->rv = SCARD_S_SUCCESS;
02437
02438
02439
02440
02441 scControlStructExtended->size = sizeof(*scControlStructExtended)
02442 - (sizeof(control_struct_extended) - offsetof(control_struct_extended, data))
02443 + cbSendLength;
02444 memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
02445
02446 rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
02447 psContextMap[dwContextIndex].dwClientID,
02448 scControlStructExtended->size,
02449 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02450
02451 if (rv == -1)
02452 {
02453 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02454 return SCARD_E_NO_SERVICE;
02455 }
02456
02457
02458
02459
02460
02461 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg),
02462 psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02463 if (rv == -1)
02464 {
02465 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02466 return SCARD_F_COMM_ERROR;
02467 }
02468
02469
02470 scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
02471
02472
02473 if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02474 {
02475 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02476 scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02477 psContextMap[dwContextIndex].dwClientID,
02478 PCSCLITE_CLIENT_ATTEMPTS);
02479 if (rv == -1)
02480 {
02481 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02482 return SCARD_F_COMM_ERROR;
02483 }
02484 }
02485
02486 if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
02487 {
02488
02489
02490
02491 memcpy(pbRecvBuffer, scControlStructExtended -> data,
02492 scControlStructExtended -> dwBytesReturned);
02493 memset(scControlStructExtended -> data, 0x00,
02494 scControlStructExtended -> dwBytesReturned);
02495 }
02496
02497 if (NULL != lpBytesReturned)
02498 *lpBytesReturned = scControlStructExtended -> dwBytesReturned;
02499
02500 rv = scControlStructExtended -> rv;
02501 }
02502 else
02503 {
02504 scControlStruct.hCard = hCard;
02505 scControlStruct.dwControlCode = dwControlCode;
02506 scControlStruct.cbSendLength = cbSendLength;
02507 scControlStruct.cbRecvLength = cbRecvLength;
02508 memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02509
02510 rv = WrapSHMWrite(SCARD_CONTROL,
02511 psContextMap[dwContextIndex].dwClientID,
02512 sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
02513
02514 if (rv == -1)
02515 {
02516 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02517 return SCARD_E_NO_SERVICE;
02518 }
02519
02520
02521
02522
02523 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02524 PCSCLITE_CLIENT_ATTEMPTS);
02525
02526 if (rv == -1)
02527 {
02528 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02529 return SCARD_F_COMM_ERROR;
02530 }
02531
02532 memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
02533
02534 if (NULL != lpBytesReturned)
02535 *lpBytesReturned = scControlStruct.dwBytesReturned;
02536
02537 if (scControlStruct.rv == SCARD_S_SUCCESS)
02538 {
02539
02540
02541
02542 memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
02543 scControlStruct.cbRecvLength);
02544 memset(scControlStruct.pbRecvBuffer, 0x00,
02545 sizeof(scControlStruct.pbRecvBuffer));
02546 }
02547
02548 rv = scControlStruct.rv;
02549 }
02550
02551 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02552
02553 PROFILE_END(rv)
02554
02555 return rv;
02556 }
02557
02658 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02659 LPDWORD pcbAttrLen)
02660 {
02661 LONG ret;
02662 unsigned char *buf = NULL;
02663
02664 PROFILE_START
02665
02666 if (NULL == pcbAttrLen)
02667 return SCARD_E_INVALID_PARAMETER;
02668
02669 if (SCARD_AUTOALLOCATE == *pcbAttrLen)
02670 {
02671 if (NULL == pbAttr)
02672 return SCARD_E_INVALID_PARAMETER;
02673
02674 *pcbAttrLen = MAX_BUFFER_SIZE;
02675 buf = malloc(*pcbAttrLen);
02676 if (NULL == buf)
02677 return SCARD_E_NO_MEMORY;
02678
02679 *(unsigned char **)pbAttr = buf;
02680 }
02681 else
02682 {
02683 buf = pbAttr;
02684
02685
02686 if (NULL == pbAttr)
02687
02688 *pcbAttrLen = MAX_BUFFER_SIZE;
02689 }
02690
02691 ret = SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, buf,
02692 pcbAttrLen);
02693
02694 PROFILE_END(ret)
02695
02696 return ret;
02697 }
02698
02732 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02733 DWORD cbAttrLen)
02734 {
02735 LONG ret;
02736
02737 PROFILE_START
02738
02739 if (NULL == pbAttr || 0 == cbAttrLen)
02740 return SCARD_E_INVALID_PARAMETER;
02741
02742 ret = SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02743 &cbAttrLen);
02744
02745 PROFILE_END(ret)
02746
02747 return ret;
02748 }
02749
02750 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02751 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02752 {
02753 LONG rv;
02754 getset_struct scGetSetStruct;
02755 sharedSegmentMsg msgStruct;
02756 int i;
02757 DWORD dwContextIndex, dwChannelIndex;
02758
02759 rv = SCardCheckDaemonAvailability();
02760 if (rv != SCARD_S_SUCCESS)
02761 return rv;
02762
02763
02764
02765
02766 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02767 if (rv == -1)
02768 return SCARD_E_INVALID_HANDLE;
02769
02770 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02771
02772
02773 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02774 if (rv == -1)
02775
02776
02777
02778 return SCARD_E_INVALID_HANDLE;
02779
02780 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02781 {
02782 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02783
02784
02785 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02786 break;
02787 }
02788
02789 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02790 {
02791 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02792 return SCARD_E_READER_UNAVAILABLE;
02793 }
02794
02795 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02796 {
02797 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02798 return SCARD_E_INSUFFICIENT_BUFFER;
02799 }
02800
02801 scGetSetStruct.hCard = hCard;
02802 scGetSetStruct.dwAttrId = dwAttrId;
02803 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02804 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02805 memset(scGetSetStruct.pbAttr, 0, sizeof(scGetSetStruct.pbAttr));
02806 if (SCARD_SET_ATTRIB == command)
02807 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02808
02809 rv = WrapSHMWrite(command,
02810 psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
02811 PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
02812
02813 if (rv == -1)
02814 {
02815 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02816 return SCARD_E_NO_SERVICE;
02817 }
02818
02819
02820
02821
02822 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02823 PCSCLITE_CLIENT_ATTEMPTS);
02824
02825 if (rv == -1)
02826 {
02827 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02828 return SCARD_F_COMM_ERROR;
02829 }
02830
02831 memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
02832
02833 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02834 {
02835
02836
02837
02838 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02839 {
02840 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02841 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02842 }
02843 else
02844 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02845
02846 if (pbAttr)
02847 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02848
02849 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02850 }
02851
02852 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02853
02854 return scGetSetStruct.rv;
02855 }
02856
02915 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02916 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02917 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02918 LPDWORD pcbRecvLength)
02919 {
02920 LONG rv;
02921 int i;
02922 DWORD dwContextIndex, dwChannelIndex;
02923
02924 PROFILE_START
02925
02926 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02927 pcbRecvLength == NULL || pioSendPci == NULL)
02928 return SCARD_E_INVALID_PARAMETER;
02929
02930 rv = SCardCheckDaemonAvailability();
02931 if (rv != SCARD_S_SUCCESS)
02932 return rv;
02933
02934
02935
02936
02937 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02938 if (rv == -1)
02939 {
02940 *pcbRecvLength = 0;
02941 return SCARD_E_INVALID_HANDLE;
02942 }
02943
02944 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02945
02946
02947 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02948 if (rv == -1)
02949
02950
02951
02952 return SCARD_E_INVALID_HANDLE;
02953
02954 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02955 {
02956 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02957
02958
02959 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02960 break;
02961 }
02962
02963 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02964 {
02965 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02966 return SCARD_E_READER_UNAVAILABLE;
02967 }
02968
02969 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02970 || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02971 {
02972 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02973 return SCARD_E_INSUFFICIENT_BUFFER;
02974 }
02975
02976 if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
02977 {
02978
02979 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02980 transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
02981 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02982
02983 scTransmitStructExtended->hCard = hCard;
02984 scTransmitStructExtended->cbSendLength = cbSendLength;
02985 scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
02986
02987
02988
02989
02990 scTransmitStructExtended->size = sizeof(*scTransmitStructExtended)
02991 - (sizeof(transmit_struct_extended) - offsetof(transmit_struct_extended, data))
02992 + cbSendLength;
02993 scTransmitStructExtended->ioSendPciProtocol = pioSendPci->dwProtocol;
02994 scTransmitStructExtended->ioSendPciLength = pioSendPci->cbPciLength;
02995 memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
02996 scTransmitStructExtended->rv = SCARD_S_SUCCESS;
02997
02998 if (pioRecvPci)
02999 {
03000 scTransmitStructExtended->ioRecvPciProtocol = pioRecvPci->dwProtocol;
03001 scTransmitStructExtended->ioRecvPciLength = pioRecvPci->cbPciLength;
03002 }
03003 else
03004 {
03005 scTransmitStructExtended->ioRecvPciProtocol = SCARD_PROTOCOL_ANY;
03006 scTransmitStructExtended->ioRecvPciLength = sizeof(SCARD_IO_REQUEST);
03007 }
03008
03009 rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
03010 psContextMap[dwContextIndex].dwClientID,
03011 scTransmitStructExtended->size,
03012 PCSCLITE_CLIENT_ATTEMPTS, buffer);
03013
03014 if (rv == -1)
03015 {
03016 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03017 return SCARD_E_NO_SERVICE;
03018 }
03019
03020
03021
03022
03023
03024 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
03025 if (rv == -1)
03026 {
03027 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03028 return SCARD_F_COMM_ERROR;
03029 }
03030
03031
03032 scTransmitStructExtended = (transmit_struct_extended *)&(pmsgStruct -> data);
03033
03034
03035 if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
03036 {
03037 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
03038 scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
03039 psContextMap[dwContextIndex].dwClientID,
03040 PCSCLITE_CLIENT_ATTEMPTS);
03041 if (rv == -1)
03042 {
03043 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03044 return SCARD_F_COMM_ERROR;
03045 }
03046 }
03047
03048 if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
03049 {
03050
03051
03052
03053 memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
03054 scTransmitStructExtended -> pcbRecvLength);
03055 memset(scTransmitStructExtended -> data, 0x00,
03056 scTransmitStructExtended -> pcbRecvLength);
03057
03058 if (pioRecvPci)
03059 {
03060 pioRecvPci->dwProtocol = scTransmitStructExtended->ioRecvPciProtocol;
03061 pioRecvPci->cbPciLength = scTransmitStructExtended->ioRecvPciLength;
03062 }
03063 }
03064
03065 *pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
03066 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03067
03068 rv = scTransmitStructExtended -> rv;
03069 }
03070 else
03071 {
03072
03073 transmit_struct scTransmitStruct;
03074 sharedSegmentMsg msgStruct;
03075
03076 scTransmitStruct.hCard = hCard;
03077 scTransmitStruct.cbSendLength = cbSendLength;
03078 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
03079 scTransmitStruct.ioSendPciProtocol = pioSendPci->dwProtocol;
03080 scTransmitStruct.ioSendPciLength = pioSendPci->cbPciLength;
03081 memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
03082 memset(scTransmitStruct.pbSendBuffer+cbSendLength, 0, sizeof(scTransmitStruct.pbSendBuffer)-cbSendLength);
03083 memset(scTransmitStruct.pbRecvBuffer, 0, sizeof(scTransmitStruct.pbRecvBuffer));
03084 scTransmitStruct.rv = SCARD_S_SUCCESS;
03085
03086 if (pioRecvPci)
03087 {
03088 scTransmitStruct.ioRecvPciProtocol = pioRecvPci->dwProtocol;
03089 scTransmitStruct.ioRecvPciLength = pioRecvPci->cbPciLength;
03090 }
03091 else
03092 {
03093 scTransmitStruct.ioRecvPciProtocol = SCARD_PROTOCOL_ANY;
03094 scTransmitStruct.ioRecvPciLength = sizeof(SCARD_IO_REQUEST);
03095 }
03096
03097 rv = WrapSHMWrite(SCARD_TRANSMIT,
03098 psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
03099 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
03100
03101 if (rv == -1)
03102 {
03103 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03104 return SCARD_E_NO_SERVICE;
03105 }
03106
03107
03108
03109
03110 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
03111 PCSCLITE_CLIENT_ATTEMPTS);
03112
03113 memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
03114
03115 if (rv == -1)
03116 {
03117 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03118 return SCARD_F_COMM_ERROR;
03119 }
03120
03121
03122
03123
03124 memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
03125
03126 if (scTransmitStruct.rv == SCARD_S_SUCCESS)
03127 {
03128
03129
03130
03131 memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
03132 scTransmitStruct.pcbRecvLength);
03133 memset(scTransmitStruct.pbRecvBuffer, 0x00,
03134 scTransmitStruct.pcbRecvLength);
03135
03136 if (pioRecvPci)
03137 {
03138 pioRecvPci->dwProtocol = scTransmitStruct.ioRecvPciProtocol;
03139 pioRecvPci->cbPciLength = scTransmitStruct.ioRecvPciLength;
03140 }
03141 }
03142
03143 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
03144 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03145
03146 rv = scTransmitStruct.rv;
03147 }
03148
03149 PROFILE_END(rv)
03150
03151 return rv;
03152 }
03153
03202 LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
03203 LPSTR mszReaders, LPDWORD pcchReaders)
03204 {
03205 DWORD dwReadersLen;
03206 int i;
03207 LONG dwContextIndex;
03208 LONG rv = SCARD_S_SUCCESS;
03209 char *buf = NULL;
03210
03211 (void)mszGroups;
03212 PROFILE_START
03213
03214
03215
03216
03217 if (pcchReaders == NULL)
03218 return SCARD_E_INVALID_PARAMETER;
03219
03220 rv = SCardCheckDaemonAvailability();
03221 if (rv != SCARD_S_SUCCESS)
03222 return rv;
03223
03224
03225
03226
03227 dwContextIndex = SCardGetContextIndice(hContext);
03228 if (dwContextIndex == -1)
03229 return SCARD_E_INVALID_HANDLE;
03230
03231 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03232
03233
03234 dwContextIndex = SCardGetContextIndice(hContext);
03235 if (dwContextIndex == -1)
03236
03237
03238
03239 return SCARD_E_INVALID_HANDLE;
03240
03241 dwReadersLen = 0;
03242 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03243 if ((readerStates[i])->readerID != 0)
03244 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
03245
03246
03247 dwReadersLen += 1;
03248
03249 if (1 == dwReadersLen)
03250 {
03251 rv = SCARD_E_NO_READERS_AVAILABLE;
03252 goto end;
03253 }
03254
03255 if (SCARD_AUTOALLOCATE == *pcchReaders)
03256 {
03257 buf = malloc(dwReadersLen);
03258 if (NULL == buf)
03259 {
03260 rv = SCARD_E_NO_MEMORY;
03261 goto end;
03262 }
03263 if (NULL == mszReaders)
03264 {
03265 rv = SCARD_E_INVALID_PARAMETER;
03266 goto end;
03267 }
03268 *(char **)mszReaders = buf;
03269 }
03270 else
03271 {
03272 buf = mszReaders;
03273
03274
03275 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
03276 {
03277 rv = SCARD_E_INSUFFICIENT_BUFFER;
03278 goto end;
03279 }
03280 }
03281
03282 if (mszReaders == NULL)
03283 goto end;
03284
03285 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03286 {
03287 if ((readerStates[i])->readerID != 0)
03288 {
03289
03290
03291
03292 strcpy(buf, (readerStates[i])->readerName);
03293 buf += strlen((readerStates[i])->readerName)+1;
03294 }
03295 }
03296 *buf = '\0';
03297
03298 end:
03299
03300 *pcchReaders = dwReadersLen;
03301
03302 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03303
03304 PROFILE_END(rv)
03305
03306 return rv;
03307 }
03308
03321 LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
03322 {
03323 LONG rv = SCARD_S_SUCCESS;
03324 LONG dwContextIndex;
03325
03326 PROFILE_START
03327
03328 rv = SCardCheckDaemonAvailability();
03329 if (rv != SCARD_S_SUCCESS)
03330 return rv;
03331
03332
03333
03334
03335 dwContextIndex = SCardGetContextIndice(hContext);
03336 if (dwContextIndex == -1)
03337 return SCARD_E_INVALID_HANDLE;
03338
03339 free((void *)pvMem);
03340
03341 PROFILE_END(rv)
03342
03343 return rv;
03344 }
03345
03395 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
03396 LPDWORD pcchGroups)
03397 {
03398 LONG rv = SCARD_S_SUCCESS;
03399 LONG dwContextIndex;
03400 char *buf = NULL;
03401
03402 PROFILE_START
03403
03404
03405 const char ReaderGroup[] = "SCard$DefaultReaders\0";
03406 const int dwGroups = sizeof(ReaderGroup);
03407
03408 rv = SCardCheckDaemonAvailability();
03409 if (rv != SCARD_S_SUCCESS)
03410 return rv;
03411
03412
03413
03414
03415 dwContextIndex = SCardGetContextIndice(hContext);
03416 if (dwContextIndex == -1)
03417 return SCARD_E_INVALID_HANDLE;
03418
03419 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03420
03421
03422 dwContextIndex = SCardGetContextIndice(hContext);
03423 if (dwContextIndex == -1)
03424
03425
03426
03427 return SCARD_E_INVALID_HANDLE;
03428
03429 if (SCARD_AUTOALLOCATE == *pcchGroups)
03430 {
03431 buf = malloc(dwGroups);
03432 if (NULL == buf)
03433 {
03434 rv = SCARD_E_NO_MEMORY;
03435 goto end;
03436 }
03437 if (NULL == mszGroups)
03438 {
03439 rv = SCARD_E_INVALID_PARAMETER;
03440 goto end;
03441 }
03442 *(char **)mszGroups = buf;
03443 }
03444 else
03445 {
03446 buf = mszGroups;
03447
03448 if ((NULL != mszGroups) && (*pcchGroups < dwGroups))
03449 {
03450 rv = SCARD_E_INSUFFICIENT_BUFFER;
03451 goto end;
03452 }
03453 }
03454
03455 if (buf)
03456 memcpy(buf, ReaderGroup, dwGroups);
03457
03458 end:
03459 *pcchGroups = dwGroups;
03460
03461 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03462
03463 PROFILE_END(rv)
03464
03465 return rv;
03466 }
03467
03495 LONG SCardCancel(SCARDCONTEXT hContext)
03496 {
03497 LONG dwContextIndex;
03498 LONG rv = SCARD_S_SUCCESS;
03499
03500 PROFILE_START
03501
03502 dwContextIndex = SCardGetContextIndice(hContext);
03503 if (dwContextIndex == -1)
03504 return SCARD_E_INVALID_HANDLE;
03505
03506
03507
03508
03509
03510 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
03511
03512 if (StatSynchronizeContext(hContext))
03513 rv = SCARD_F_INTERNAL_ERROR;
03514
03515 PROFILE_END(rv)
03516
03517 return rv;
03518 }
03519
03543 LONG SCardIsValidContext(SCARDCONTEXT hContext)
03544 {
03545 LONG rv;
03546 LONG dwContextIndex;
03547
03548 PROFILE_START
03549
03550 rv = SCARD_S_SUCCESS;
03551
03552
03553 rv = SCardCheckDaemonAvailability();
03554 if (rv != SCARD_S_SUCCESS)
03555 return rv;
03556
03557
03558
03559
03560 dwContextIndex = SCardGetContextIndice(hContext);
03561 if (dwContextIndex == -1)
03562 rv = SCARD_E_INVALID_HANDLE;
03563
03564 PROFILE_END(rv)
03565
03566 return rv;
03567 }
03568
03585 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
03586 {
03587 int i;
03588
03589 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03590 {
03591 if (psContextMap[i].hContext == 0)
03592 {
03593 psContextMap[i].hContext = hContext;
03594 psContextMap[i].dwClientID = dwClientID;
03595 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
03596 psContextMap[i].mMutex = malloc(sizeof(PCSCLITE_MUTEX));
03597 (void)SYS_MutexInit(psContextMap[i].mMutex);
03598 return SCARD_S_SUCCESS;
03599 }
03600 }
03601
03602 return SCARD_E_NO_MEMORY;
03603 }
03604
03617 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
03618 {
03619 LONG rv;
03620
03621 (void)SCardLockThread();
03622 rv = SCardGetContextIndiceTH(hContext);
03623 (void)SCardUnlockThread();
03624
03625 return rv;
03626 }
03627
03640 static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
03641 {
03642 int i;
03643
03644
03645
03646
03647 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03648 {
03649 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
03650 return i;
03651 }
03652
03653 return -1;
03654 }
03655
03665 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
03666 {
03667 LONG retIndice;
03668
03669 retIndice = SCardGetContextIndiceTH(hContext);
03670
03671 if (retIndice == -1)
03672 return SCARD_E_INVALID_HANDLE;
03673 else
03674 return SCardCleanContext(retIndice);
03675 }
03676
03677 static LONG SCardCleanContext(LONG indice)
03678 {
03679 int i;
03680
03681 psContextMap[indice].hContext = 0;
03682 (void)SHMClientCloseSession(psContextMap[indice].dwClientID);
03683 psContextMap[indice].dwClientID = 0;
03684 free(psContextMap[indice].mMutex);
03685 psContextMap[indice].mMutex = NULL;
03686 psContextMap[indice].contextBlockStatus = BLOCK_STATUS_RESUME;
03687
03688 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03689 {
03690
03691
03692
03693 psContextMap[indice].psChannelMap[i].hCard = 0;
03694 free(psContextMap[indice].psChannelMap[i].readerName);
03695 psContextMap[indice].psChannelMap[i].readerName = NULL;
03696 }
03697
03698 return SCARD_S_SUCCESS;
03699 }
03700
03701
03702
03703
03704
03705 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
03706 LPCSTR readerName)
03707 {
03708 int i;
03709
03710 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03711 {
03712 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
03713 {
03714 psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
03715 psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
03716 return SCARD_S_SUCCESS;
03717 }
03718 }
03719
03720 return SCARD_E_NO_MEMORY;
03721 }
03722
03723 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03724 {
03725 DWORD dwContextIndice, dwChannelIndice;
03726 LONG rv;
03727
03728 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
03729 if (rv == -1)
03730 return SCARD_E_INVALID_HANDLE;
03731 else
03732 {
03733 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
03734 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
03735 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
03736 return SCARD_S_SUCCESS;
03737 }
03738 }
03739
03740 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard,
03741 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03742 {
03743 LONG rv;
03744
03745 if (0 == hCard)
03746 return -1;
03747
03748 (void)SCardLockThread();
03749 rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
03750 (void)SCardUnlockThread();
03751
03752 return rv;
03753 }
03754
03755 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard,
03756 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03757 {
03758 int i;
03759
03760 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03761 {
03762 if (psContextMap[i].hContext != 0)
03763 {
03764 int j;
03765
03766 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
03767 {
03768 if (psContextMap[i].psChannelMap[j].hCard == hCard)
03769 {
03770 *pdwContextIndice = i;
03771 *pdwChannelIndice = j;
03772 return SCARD_S_SUCCESS;
03773 }
03774 }
03775
03776 }
03777 }
03778
03779 return -1;
03780 }
03781
03790 LONG SCardCheckDaemonAvailability(void)
03791 {
03792 LONG rv;
03793 struct stat statBuffer;
03794 int need_restart = 0;
03795
03796 rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &statBuffer);
03797
03798 if (rv != 0)
03799 {
03800 Log2(PCSC_LOG_INFO, "PCSC Not Running: " PCSCLITE_PUBSHM_FILE ": %s",
03801 strerror(errno));
03802 return SCARD_E_NO_SERVICE;
03803 }
03804
03805
03806
03807 if (daemon_ctime && statBuffer.st_ctime > daemon_ctime)
03808 {
03809
03810 if (GetDaemonPid() != daemon_pid)
03811 {
03812 Log1(PCSC_LOG_INFO, "PCSC restarted");
03813 need_restart = 1;
03814 }
03815 }
03816
03817
03818 if (client_pid && client_pid != getpid())
03819 {
03820 Log1(PCSC_LOG_INFO, "Client forked");
03821 need_restart = 1;
03822 }
03823
03824 if (need_restart)
03825 {
03826 int i;
03827
03828
03829 (void)SCardLockThread();
03830
03831 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03832 if (psContextMap[i].hContext)
03833 (void)SCardCleanContext(i);
03834
03835 (void)SCardUnlockThread();
03836
03837
03838 daemon_ctime = 0;
03839 client_pid = 0;
03840
03841
03842 SCardUnload();
03843
03844 return SCARD_E_INVALID_HANDLE;
03845 }
03846
03847 daemon_ctime = statBuffer.st_ctime;
03848 daemon_pid = GetDaemonPid();
03849 client_pid = getpid();
03850
03851 return SCARD_S_SUCCESS;
03852 }
03853
03860 #ifdef __SUNPRO_C
03861 #pragma fini (SCardUnload)
03862 #endif
03863
03864 void DESTRUCTOR SCardUnload(void)
03865 {
03866 int i;
03867
03868 if (!isExecuted)
03869 return;
03870
03871
03872 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03873 {
03874 if (readerStates[i] != NULL)
03875 {
03876 SYS_PublicMemoryUnmap(readerStates[i], sizeof(READER_STATE));
03877 readerStates[i] = NULL;
03878 }
03879 }
03880
03881 (void)SYS_CloseFile(mapAddr);
03882 isExecuted = 0;
03883 }
03884