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 #define BLOCK_STATUS_CANCEL 0x0001
00049
00050 #ifndef TRUE
00051 #define TRUE 1
00052 #define FALSE 0
00053 #endif
00054
00055
00056 static long int time_sub(struct timeval *a, struct timeval *b)
00057 {
00058 struct timeval r;
00059 r.tv_sec = a -> tv_sec - b -> tv_sec;
00060 r.tv_usec = a -> tv_usec - b -> tv_usec;
00061 if (r.tv_usec < 0)
00062 {
00063 r.tv_sec--;
00064 r.tv_usec += 1000000;
00065 }
00066
00067 return r.tv_sec * 1000000 + r.tv_usec;
00068 }
00069
00070
00071 #undef DO_PROFILE
00072 #ifdef DO_PROFILE
00073
00074 #define PROFILE_FILE "/tmp/pcsc_profile"
00075 #include <stdio.h>
00076 #include <sys/time.h>
00077
00078 struct timeval profile_time_start;
00079 FILE *profile_fd;
00080 char profile_tty;
00081 char fct_name[100];
00082
00083 #define PROFILE_START profile_start(__FUNCTION__);
00084 #define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
00085
00086 static void profile_start(const char *f)
00087 {
00088 static char initialized = FALSE;
00089
00090 if (!initialized)
00091 {
00092 char filename[80];
00093
00094 initialized = TRUE;
00095 sprintf(filename, "%s-%d", PROFILE_FILE, getuid());
00096 profile_fd = fopen(filename, "a+");
00097 if (NULL == profile_fd)
00098 {
00099 fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n",
00100 PROFILE_FILE, strerror(errno));
00101 exit(-1);
00102 }
00103 fprintf(profile_fd, "\nStart a new profile\n");
00104
00105 if (isatty(fileno(stderr)))
00106 profile_tty = TRUE;
00107 else
00108 profile_tty = FALSE;
00109 }
00110
00111
00112 if (profile_tty && fct_name[0])
00113 printf("\33[01;34m WARNING: %s starts before %s finishes\33[0m\n",
00114 f, fct_name);
00115
00116 strlcpy(fct_name, f, sizeof(fct_name));
00117
00118 gettimeofday(&profile_time_start, NULL);
00119 }
00120
00121 static void profile_end(const char *f, LONG rv)
00122 {
00123 struct timeval profile_time_end;
00124 long d;
00125
00126 gettimeofday(&profile_time_end, NULL);
00127 d = time_sub(&profile_time_end, &profile_time_start);
00128
00129 if (profile_tty)
00130 {
00131 if (fct_name[0])
00132 {
00133 if (strncmp(fct_name, f, sizeof(fct_name)))
00134 printf("\33[01;34m WARNING: %s ends before %s\33[0m\n",
00135 f, fct_name);
00136 }
00137 else
00138 printf("\33[01;34m WARNING: %s ends but we lost its start\33[0m\n",
00139 f);
00140
00141
00142 fct_name[0] = '\0';
00143
00144 if (rv != SCARD_S_SUCCESS)
00145 fprintf(stderr,
00146 "\33[01;31mRESULT %s \33[35m%ld \33[34m0x%08lX %s\33[0m\n",
00147 f, d, rv, pcsc_stringify_error(rv));
00148 else
00149 fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m\n", f, d);
00150 }
00151 fprintf(profile_fd, "%s %ld\n", f, d);
00152 fflush(profile_fd);
00153 }
00154
00155 #else
00156 #define PROFILE_START
00157 #define PROFILE_END(rv)
00158 #endif
00159
00164 struct _psChannelMap
00165 {
00166 SCARDHANDLE hCard;
00167 LPSTR readerName;
00168 };
00169
00170 typedef struct _psChannelMap CHANNEL_MAP, *PCHANNEL_MAP;
00171
00177 static struct _psContextMap
00178 {
00179 DWORD dwClientID;
00180 SCARDCONTEXT hContext;
00181 DWORD contextBlockStatus;
00182 PCSCLITE_MUTEX_T mMutex;
00183 CHANNEL_MAP psChannelMap[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
00184 } psContextMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
00185
00189 static short isExecuted = 0;
00190
00191
00195 static time_t daemon_ctime = 0;
00196 static pid_t daemon_pid = 0;
00201 static pid_t client_pid = 0;
00202
00208 static int mapAddr = 0;
00209
00214 static PCSCLITE_MUTEX clientMutex = PTHREAD_MUTEX_INITIALIZER;
00215
00222 static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
00223
00224 PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
00225 PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
00226 PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
00229 static LONG SCardAddContext(SCARDCONTEXT, DWORD);
00230 static LONG SCardGetContextIndice(SCARDCONTEXT);
00231 static LONG SCardGetContextIndiceTH(SCARDCONTEXT);
00232 static LONG SCardRemoveContext(SCARDCONTEXT);
00233 static LONG SCardCleanContext(LONG indice);
00234
00235 static LONG SCardAddHandle(SCARDHANDLE, DWORD, LPCSTR);
00236 static LONG SCardGetIndicesFromHandle(SCARDHANDLE, PDWORD,
00237 PDWORD);
00238 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE, PDWORD,
00239 PDWORD);
00240 static LONG SCardRemoveHandle(SCARDHANDLE);
00241
00242 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
00243 LPBYTE pbAttr, LPDWORD pcbAttrLen);
00244
00245 void DESTRUCTOR SCardUnload(void);
00246
00247
00248
00249
00256 inline static LONG SCardLockThread(void)
00257 {
00258 return SYS_MutexLock(&clientMutex);
00259 }
00260
00266 inline static LONG SCardUnlockThread(void)
00267 {
00268 return SYS_MutexUnLock(&clientMutex);
00269 }
00270
00271 static LONG SCardEstablishContextTH(DWORD, LPCVOID, LPCVOID,
00272 LPSCARDCONTEXT);
00273
00306 LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
00307 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00308 {
00309 LONG rv;
00310
00311 PROFILE_START
00312
00313
00314 rv = SCardCheckDaemonAvailability();
00315 if (SCARD_E_INVALID_HANDLE == rv)
00316
00317 rv = SCardCheckDaemonAvailability();
00318
00319 if (rv != SCARD_S_SUCCESS)
00320 return rv;
00321
00322 (void)SCardLockThread();
00323 rv = SCardEstablishContextTH(dwScope, pvReserved1,
00324 pvReserved2, phContext);
00325 (void)SCardUnlockThread();
00326
00327 PROFILE_END(rv)
00328
00329 return rv;
00330 }
00331
00358 static LONG SCardEstablishContextTH(DWORD dwScope,
00359 LPCVOID pvReserved1,
00360 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00361 {
00362 LONG rv;
00363 int i;
00364 establish_struct scEstablishStruct;
00365 sharedSegmentMsg msgStruct;
00366 uint32_t dwClientID = 0;
00367
00368 (void)pvReserved1;
00369 (void)pvReserved2;
00370 if (phContext == NULL)
00371 return SCARD_E_INVALID_PARAMETER;
00372 else
00373 *phContext = 0;
00374
00375
00376
00377
00378
00379
00380
00381
00382 if (isExecuted == 0)
00383 {
00384 int pageSize;
00385
00386
00387
00388
00389 (void)SYS_Initialize();
00390
00391
00392
00393
00394 mapAddr = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDONLY, 0);
00395 if (mapAddr < 0)
00396 {
00397 Log3(PCSC_LOG_CRITICAL, "Cannot open public shared file %s: %s",
00398 PCSCLITE_PUBSHM_FILE, strerror(errno));
00399 return SCARD_E_NO_SERVICE;
00400 }
00401
00402
00403
00404
00405 (void)fcntl(mapAddr, F_SETFD, FD_CLOEXEC);
00406
00407 pageSize = SYS_GetPageSize();
00408
00409
00410
00411
00412 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00413 {
00414 readerStates[i] =
00415 (PREADER_STATE)SYS_PublicMemoryMap(sizeof(READER_STATE),
00416 mapAddr, (i * pageSize));
00417 if (readerStates[i] == NULL)
00418 {
00419 Log2(PCSC_LOG_CRITICAL, "Cannot public memory map: %s",
00420 strerror(errno));
00421 (void)SYS_CloseFile(mapAddr);
00422 return SCARD_F_INTERNAL_ERROR;
00423 }
00424 }
00425
00426
00427
00428
00429 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00430 {
00431 int j;
00432
00433
00434
00435
00436 psContextMap[i].dwClientID = 0;
00437 psContextMap[i].hContext = 0;
00438 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
00439 psContextMap[i].mMutex = NULL;
00440
00441 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
00442 {
00443
00444
00445
00446 psContextMap[i].psChannelMap[j].hCard = 0;
00447 psContextMap[i].psChannelMap[j].readerName = NULL;
00448 }
00449 }
00450
00451 }
00452
00453
00454
00455
00456
00457 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00458 {
00459 if (psContextMap[i].dwClientID == 0)
00460 break;
00461 }
00462
00463 if (i == PCSCLITE_MAX_APPLICATION_CONTEXTS)
00464 {
00465 return SCARD_E_NO_MEMORY;
00466 }
00467
00468
00469 if (SHMClientSetupSession(&dwClientID) != 0)
00470 {
00471 (void)SYS_CloseFile(mapAddr);
00472 return SCARD_E_NO_SERVICE;
00473 }
00474
00475 {
00476 version_struct *veStr;
00477
00478 memset(&msgStruct, 0, sizeof(msgStruct));
00479 msgStruct.mtype = CMD_VERSION;
00480 msgStruct.user_id = SYS_GetUID();
00481 msgStruct.group_id = SYS_GetGID();
00482 msgStruct.command = 0;
00483 msgStruct.date = time(NULL);
00484
00485 veStr = (version_struct *) msgStruct.data;
00486 veStr->major = PROTOCOL_VERSION_MAJOR;
00487 veStr->minor = PROTOCOL_VERSION_MINOR;
00488
00489 if (-1 == SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
00490 PCSCLITE_MCLIENT_ATTEMPTS))
00491 return SCARD_E_NO_SERVICE;
00492
00493
00494
00495
00496 if (-1 == SHMMessageReceive(&msgStruct, sizeof(msgStruct), dwClientID,
00497 PCSCLITE_CLIENT_ATTEMPTS))
00498 {
00499 Log1(PCSC_LOG_CRITICAL, "Your pcscd is too old and does not support CMD_VERSION");
00500 return SCARD_F_COMM_ERROR;
00501 }
00502
00503 Log3(PCSC_LOG_INFO, "Server is protocol version %d:%d",
00504 veStr->major, veStr->minor);
00505
00506 if (veStr->rv != SCARD_S_SUCCESS)
00507 return veStr->rv;
00508
00509 isExecuted = 1;
00510 }
00511
00512
00513
00514
00515
00516 scEstablishStruct.dwScope = dwScope;
00517 scEstablishStruct.phContext = 0;
00518 scEstablishStruct.rv = SCARD_S_SUCCESS;
00519
00520 rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
00521 sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
00522 (void *) &scEstablishStruct);
00523
00524 if (rv == -1)
00525 return SCARD_E_NO_SERVICE;
00526
00527
00528
00529
00530 rv = SHMClientRead(&msgStruct, dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00531
00532 if (rv == -1)
00533 return SCARD_F_COMM_ERROR;
00534
00535 memcpy(&scEstablishStruct, &msgStruct.data, sizeof(scEstablishStruct));
00536
00537 if (scEstablishStruct.rv != SCARD_S_SUCCESS)
00538 return scEstablishStruct.rv;
00539
00540 *phContext = scEstablishStruct.phContext;
00541
00542
00543
00544
00545 rv = SCardAddContext(*phContext, dwClientID);
00546
00547 return rv;
00548 }
00549
00571 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00572 {
00573 LONG rv;
00574 release_struct scReleaseStruct;
00575 sharedSegmentMsg msgStruct;
00576 LONG dwContextIndex;
00577
00578 PROFILE_START
00579
00580
00581
00582
00583
00584 dwContextIndex = SCardGetContextIndice(hContext);
00585 if (dwContextIndex == -1)
00586 return SCARD_E_INVALID_HANDLE;
00587
00588 rv = SCardCheckDaemonAvailability();
00589 if (rv != SCARD_S_SUCCESS)
00590 {
00591
00592
00593
00594 (void)SCardLockThread();
00595 (void)SCardRemoveContext(hContext);
00596 (void)SCardUnlockThread();
00597
00598 return rv;
00599 }
00600
00601 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00602
00603
00604 dwContextIndex = SCardGetContextIndice(hContext);
00605 if (dwContextIndex == -1)
00606
00607
00608
00609 return SCARD_E_INVALID_HANDLE;
00610
00611 scReleaseStruct.hContext = hContext;
00612 scReleaseStruct.rv = SCARD_S_SUCCESS;
00613
00614 rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT,
00615 psContextMap[dwContextIndex].dwClientID,
00616 sizeof(scReleaseStruct),
00617 PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);
00618
00619 if (rv == -1)
00620 {
00621 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00622 return SCARD_E_NO_SERVICE;
00623 }
00624
00625
00626
00627
00628 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00629 PCSCLITE_CLIENT_ATTEMPTS);
00630 memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));
00631
00632 if (rv == -1)
00633 {
00634 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00635 return SCARD_F_COMM_ERROR;
00636 }
00637
00638 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00639
00640
00641
00642
00643 (void)SCardLockThread();
00644 (void)SCardRemoveContext(hContext);
00645 (void)SCardUnlockThread();
00646
00647 PROFILE_END(scReleaseStruct.rv)
00648
00649 return scReleaseStruct.rv;
00650 }
00651
00667 LONG SCardSetTimeout( SCARDCONTEXT hContext,
00668 DWORD dwTimeout)
00669 {
00670
00671
00672
00673 (void)hContext;
00674 (void)dwTimeout;
00675 return SCARD_S_SUCCESS;
00676 }
00677
00728 LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,
00729 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00730 LPDWORD pdwActiveProtocol)
00731 {
00732 LONG rv;
00733 connect_struct scConnectStruct;
00734 sharedSegmentMsg msgStruct;
00735 LONG dwContextIndex;
00736
00737 PROFILE_START
00738
00739
00740
00741
00742 if (phCard == NULL || pdwActiveProtocol == NULL)
00743 return SCARD_E_INVALID_PARAMETER;
00744 else
00745 *phCard = 0;
00746
00747 if (szReader == NULL)
00748 return SCARD_E_UNKNOWN_READER;
00749
00750
00751
00752
00753 if (strlen(szReader) > MAX_READERNAME)
00754 return SCARD_E_INVALID_VALUE;
00755
00756 rv = SCardCheckDaemonAvailability();
00757 if (rv != SCARD_S_SUCCESS)
00758 return rv;
00759
00760
00761
00762
00763 dwContextIndex = SCardGetContextIndice(hContext);
00764 if (dwContextIndex == -1)
00765 return SCARD_E_INVALID_HANDLE;
00766
00767 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00768
00769
00770 dwContextIndex = SCardGetContextIndice(hContext);
00771 if (dwContextIndex == -1)
00772
00773
00774
00775 return SCARD_E_INVALID_HANDLE;
00776
00777 strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);
00778
00779 scConnectStruct.hContext = hContext;
00780 scConnectStruct.dwShareMode = dwShareMode;
00781 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00782 scConnectStruct.phCard = 0;
00783 scConnectStruct.pdwActiveProtocol = 0;
00784 scConnectStruct.rv = SCARD_S_SUCCESS;
00785
00786 rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
00787 sizeof(scConnectStruct),
00788 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);
00789
00790 if (rv == -1)
00791 {
00792 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00793 return SCARD_E_NO_SERVICE;
00794 }
00795
00796
00797
00798
00799 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00800 PCSCLITE_CLIENT_ATTEMPTS);
00801
00802 memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));
00803
00804 if (rv == -1)
00805 {
00806 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00807 return SCARD_F_COMM_ERROR;
00808 }
00809
00810 *phCard = scConnectStruct.phCard;
00811 *pdwActiveProtocol = scConnectStruct.pdwActiveProtocol;
00812
00813 if (scConnectStruct.rv == SCARD_S_SUCCESS)
00814 {
00815
00816
00817
00818 rv = SCardAddHandle(*phCard, dwContextIndex, szReader);
00819 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00820
00821 PROFILE_END(rv)
00822
00823 return rv;
00824 }
00825
00826 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00827
00828 PROFILE_END(scConnectStruct.rv)
00829
00830 return scConnectStruct.rv;
00831 }
00832
00900 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00901 DWORD dwPreferredProtocols, DWORD dwInitialization,
00902 LPDWORD pdwActiveProtocol)
00903 {
00904 LONG rv;
00905 reconnect_struct scReconnectStruct;
00906 sharedSegmentMsg msgStruct;
00907 int i;
00908 DWORD dwContextIndex, dwChannelIndex;
00909
00910 PROFILE_START
00911
00912 if (pdwActiveProtocol == NULL)
00913 return SCARD_E_INVALID_PARAMETER;
00914
00915 rv = SCardCheckDaemonAvailability();
00916 if (rv != SCARD_S_SUCCESS)
00917 return rv;
00918
00919
00920
00921
00922 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00923 if (rv == -1)
00924 return SCARD_E_INVALID_HANDLE;
00925
00926 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00927
00928
00929 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00930 if (rv == -1) {
00931
00932
00933
00934
00935
00936
00937 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00938 return SCARD_E_INVALID_HANDLE;
00939 }
00940
00941 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00942 {
00943 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
00944
00945
00946 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
00947 break;
00948 }
00949
00950 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00951 {
00952 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00953 return SCARD_E_READER_UNAVAILABLE;
00954 }
00955
00956 do
00957 {
00958 scReconnectStruct.hCard = hCard;
00959 scReconnectStruct.dwShareMode = dwShareMode;
00960 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00961 scReconnectStruct.dwInitialization = dwInitialization;
00962 scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00963 scReconnectStruct.rv = SCARD_S_SUCCESS;
00964
00965 rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
00966 sizeof(scReconnectStruct),
00967 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
00968
00969 if (rv == -1)
00970 {
00971 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00972 return SCARD_E_NO_SERVICE;
00973 }
00974
00975
00976
00977
00978 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00979 PCSCLITE_CLIENT_ATTEMPTS);
00980
00981 memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
00982
00983 if (rv == -1)
00984 {
00985 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00986 return SCARD_F_COMM_ERROR;
00987 }
00988 } while (SCARD_E_SHARING_VIOLATION == scReconnectStruct.rv);
00989
00990 *pdwActiveProtocol = scReconnectStruct.pdwActiveProtocol;
00991
00992 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00993
00994 PROFILE_END(scReconnectStruct.rv)
00995
00996 return scReconnectStruct.rv;
00997 }
00998
01029 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
01030 {
01031 LONG rv;
01032 disconnect_struct scDisconnectStruct;
01033 sharedSegmentMsg msgStruct;
01034 DWORD dwContextIndex, dwChannelIndex;
01035
01036 PROFILE_START
01037
01038 rv = SCardCheckDaemonAvailability();
01039 if (rv != SCARD_S_SUCCESS)
01040 return rv;
01041
01042
01043
01044
01045 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01046 if (rv == -1)
01047 return SCARD_E_INVALID_HANDLE;
01048
01049 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01050
01051
01052 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01053 if (rv == -1) {
01054
01055
01056
01057
01058
01059
01060 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01061 return SCARD_E_INVALID_HANDLE;
01062 }
01063
01064 scDisconnectStruct.hCard = hCard;
01065 scDisconnectStruct.dwDisposition = dwDisposition;
01066 scDisconnectStruct.rv = SCARD_S_SUCCESS;
01067
01068 rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
01069 sizeof(scDisconnectStruct),
01070 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
01071
01072 if (rv == -1)
01073 {
01074 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01075 return SCARD_E_NO_SERVICE;
01076 }
01077
01078
01079
01080
01081 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01082 PCSCLITE_CLIENT_ATTEMPTS);
01083
01084 memcpy(&scDisconnectStruct, &msgStruct.data,
01085 sizeof(scDisconnectStruct));
01086
01087 if (rv == -1)
01088 {
01089 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01090 return SCARD_F_COMM_ERROR;
01091 }
01092
01093 (void)SCardRemoveHandle(hCard);
01094
01095 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01096
01097 PROFILE_END(scDisconnectStruct.rv)
01098
01099 return scDisconnectStruct.rv;
01100 }
01101
01137 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01138 {
01139
01140 LONG rv;
01141 begin_struct scBeginStruct;
01142 int i;
01143 sharedSegmentMsg msgStruct;
01144 DWORD dwContextIndex, dwChannelIndex;
01145
01146 PROFILE_START
01147
01148 rv = SCardCheckDaemonAvailability();
01149 if (rv != SCARD_S_SUCCESS)
01150 return rv;
01151
01152
01153
01154
01155 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01156 if (rv == -1)
01157 return SCARD_E_INVALID_HANDLE;
01158
01159 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01160
01161
01162 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01163 if (rv == -1) {
01164
01165
01166
01167
01168
01169
01170 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01171 return SCARD_E_INVALID_HANDLE;
01172 }
01173
01174 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01175 {
01176 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01177
01178
01179 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01180 break;
01181 }
01182
01183 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01184 {
01185 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01186 return SCARD_E_READER_UNAVAILABLE;
01187 }
01188
01189 scBeginStruct.hCard = hCard;
01190 scBeginStruct.rv = SCARD_S_SUCCESS;
01191
01192
01193
01194
01195
01196
01197 do
01198 {
01199 rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01200 sizeof(scBeginStruct),
01201 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);
01202
01203 if (rv == -1)
01204 {
01205
01206 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01207 return SCARD_E_NO_SERVICE;
01208 }
01209
01210
01211
01212
01213 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01214 PCSCLITE_CLIENT_ATTEMPTS);
01215
01216 memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));
01217
01218 if (rv == -1)
01219 {
01220
01221 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01222 return SCARD_F_COMM_ERROR;
01223 }
01224
01225 }
01226 while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
01227
01228 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01229
01230 PROFILE_END(scBeginStruct.rv);
01231
01232 return scBeginStruct.rv;
01233 }
01234
01275 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01276 {
01277 LONG rv;
01278 end_struct scEndStruct;
01279 sharedSegmentMsg msgStruct;
01280 int randnum, i;
01281 DWORD dwContextIndex, dwChannelIndex;
01282
01283 PROFILE_START
01284
01285
01286
01287
01288 randnum = 0;
01289
01290 rv = SCardCheckDaemonAvailability();
01291 if (rv != SCARD_S_SUCCESS)
01292 return rv;
01293
01294
01295
01296
01297 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01298 if (rv == -1)
01299 return SCARD_E_INVALID_HANDLE;
01300
01301 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01302
01303
01304 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01305 if (rv == -1) {
01306
01307
01308
01309
01310
01311
01312 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01313 return SCARD_E_INVALID_HANDLE;
01314 }
01315
01316 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01317 {
01318 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01319
01320
01321 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01322 break;
01323 }
01324
01325 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01326 {
01327 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01328 return SCARD_E_READER_UNAVAILABLE;
01329 }
01330
01331 scEndStruct.hCard = hCard;
01332 scEndStruct.dwDisposition = dwDisposition;
01333 scEndStruct.rv = SCARD_S_SUCCESS;
01334
01335 rv = WrapSHMWrite(SCARD_END_TRANSACTION,
01336 psContextMap[dwContextIndex].dwClientID,
01337 sizeof(scEndStruct),
01338 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
01339
01340 if (rv == -1)
01341 {
01342 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01343 return SCARD_E_NO_SERVICE;
01344 }
01345
01346
01347
01348
01349 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01350 PCSCLITE_CLIENT_ATTEMPTS);
01351
01352 memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
01353
01354 if (rv == -1)
01355 {
01356 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01357 return SCARD_F_COMM_ERROR;
01358 }
01359
01360
01361
01362
01363 randnum = SYS_RandomInt(1000, 10000);
01364 (void)SYS_USleep(randnum);
01365
01366 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01367
01368 PROFILE_END(scEndStruct.rv)
01369
01370 return scEndStruct.rv;
01371 }
01372
01379 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01380 {
01381 LONG rv;
01382 cancel_struct scCancelStruct;
01383 sharedSegmentMsg msgStruct;
01384 int i;
01385 DWORD dwContextIndex, dwChannelIndex;
01386
01387 PROFILE_START
01388
01389 rv = SCardCheckDaemonAvailability();
01390 if (rv != SCARD_S_SUCCESS)
01391 return rv;
01392
01393
01394
01395
01396 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01397 if (rv == -1)
01398 return SCARD_E_INVALID_HANDLE;
01399
01400 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01401
01402
01403 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01404 if (rv == -1) {
01405
01406
01407
01408
01409
01410
01411 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01412 return SCARD_E_INVALID_HANDLE;
01413 }
01414
01415 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01416 {
01417 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01418
01419
01420 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01421 break;
01422 }
01423
01424 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01425 {
01426 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01427 return SCARD_E_READER_UNAVAILABLE;
01428 }
01429
01430 scCancelStruct.hCard = hCard;
01431
01432 rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION,
01433 psContextMap[dwContextIndex].dwClientID,
01434 sizeof(scCancelStruct),
01435 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
01436
01437 if (rv == -1)
01438 {
01439 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01440 return SCARD_E_NO_SERVICE;
01441 }
01442
01443
01444
01445
01446 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01447 PCSCLITE_CLIENT_ATTEMPTS);
01448
01449 memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
01450
01451 if (rv == -1)
01452 {
01453 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01454 return SCARD_F_COMM_ERROR;
01455 }
01456
01457 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01458
01459 PROFILE_END(scCancelStruct.rv)
01460
01461 return scCancelStruct.rv;
01462 }
01463
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 status_struct scStatusStruct;
01559 sharedSegmentMsg msgStruct;
01560 DWORD dwContextIndex, dwChannelIndex;
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 rv = SCardCheckDaemonAvailability();
01590 if (rv != SCARD_S_SUCCESS)
01591 return rv;
01592
01593
01594
01595
01596 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01597 if (rv == -1)
01598 return SCARD_E_INVALID_HANDLE;
01599
01600 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01601
01602
01603 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01604 if (rv == -1) {
01605
01606
01607
01608
01609
01610
01611 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01612 return SCARD_E_INVALID_HANDLE;
01613 }
01614
01615 r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].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 memset(&scStatusStruct, 0, sizeof(scStatusStruct));
01631 scStatusStruct.hCard = hCard;
01632
01633
01634 scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
01635 scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
01636
01637 rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
01638 sizeof(scStatusStruct),
01639 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
01640
01641 if (rv == -1)
01642 {
01643 rv = SCARD_E_NO_SERVICE;
01644 goto end;
01645 }
01646
01647
01648
01649
01650 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01651 PCSCLITE_CLIENT_ATTEMPTS);
01652
01653 memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
01654
01655 if (rv == -1)
01656 {
01657 rv = SCARD_F_COMM_ERROR;
01658 goto end;
01659 }
01660
01661 rv = scStatusStruct.rv;
01662 if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
01663 {
01664
01665
01666
01667 goto end;
01668 }
01669
01670
01671
01672
01673
01674 *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
01675 *pcbAtrLen = (readerStates[i])->cardAtrLength;
01676
01677 if (pdwState)
01678 *pdwState = (readerStates[i])->readerState;
01679
01680 if (pdwProtocol)
01681 *pdwProtocol = (readerStates[i])->cardProtocol;
01682
01683 if (SCARD_AUTOALLOCATE == dwReaderLen)
01684 {
01685 dwReaderLen = *pcchReaderLen;
01686 bufReader = malloc(dwReaderLen);
01687 if (NULL == bufReader)
01688 {
01689 rv = SCARD_E_NO_MEMORY;
01690 goto end;
01691 }
01692 if (NULL == mszReaderName)
01693 {
01694 rv = SCARD_E_INVALID_PARAMETER;
01695 goto end;
01696 }
01697 *(char **)mszReaderName = bufReader;
01698 }
01699 else
01700 bufReader = mszReaderName;
01701
01702
01703 if (bufReader)
01704 {
01705 if (*pcchReaderLen > dwReaderLen)
01706 rv = SCARD_E_INSUFFICIENT_BUFFER;
01707
01708 strncpy(bufReader,
01709 psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
01710 dwReaderLen);
01711 }
01712
01713 if (SCARD_AUTOALLOCATE == dwAtrLen)
01714 {
01715 dwAtrLen = *pcbAtrLen;
01716 bufAtr = malloc(dwAtrLen);
01717 if (NULL == bufAtr)
01718 {
01719 rv = SCARD_E_NO_MEMORY;
01720 goto end;
01721 }
01722 if (NULL == pbAtr)
01723 {
01724 rv = SCARD_E_INVALID_PARAMETER;
01725 goto end;
01726 }
01727 *(LPBYTE *)pbAtr = bufAtr;
01728 }
01729 else
01730 bufAtr = pbAtr;
01731
01732 if (bufAtr)
01733 {
01734 if (*pcbAtrLen > dwAtrLen)
01735 rv = SCARD_E_INSUFFICIENT_BUFFER;
01736
01737 memcpy(bufAtr, (readerStates[i])->cardAtr, min(*pcbAtrLen, dwAtrLen));
01738 }
01739
01740 end:
01741 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01742
01743 PROFILE_END(rv)
01744
01745 return rv;
01746 }
01747
01748 static long WaitForPcscdEvent(SCARDCONTEXT hContext, long dwTime)
01749 {
01750 char filename[FILENAME_MAX];
01751 char buf[1];
01752 int fd, r;
01753 struct timeval tv, *ptv = NULL;
01754 struct timeval before, after;
01755 fd_set read_fd;
01756
01757 if (INFINITE != dwTime)
01758 {
01759 if (dwTime < 0)
01760 return 0;
01761 gettimeofday(&before, NULL);
01762 tv.tv_sec = dwTime/1000;
01763 tv.tv_usec = dwTime*1000 - tv.tv_sec*1000000;
01764 ptv = &tv;
01765 }
01766
01767 (void)snprintf(filename, sizeof(filename), "%s/event.%d.%ld",
01768 PCSCLITE_EVENTS_DIR, SYS_GetPID(), hContext);
01769 r = mkfifo(filename, 0644);
01770 if ((-1 == r) && (errno != EEXIST))
01771 {
01772 Log2(PCSC_LOG_CRITICAL, "Can't create event fifo: %s", strerror(errno));
01773 goto exit;
01774 }
01775
01776 fd = SYS_OpenFile(filename, O_RDONLY | O_NONBLOCK, 0);
01777
01778 FD_ZERO(&read_fd);
01779 FD_SET(fd, &read_fd);
01780
01781 (void)select(fd+1, &read_fd, NULL, NULL, ptv);
01782
01783 (void)SYS_ReadFile(fd, buf, 1);
01784 (void)SYS_CloseFile(fd);
01785 (void)SYS_RemoveFile(filename);
01786
01787 if (INFINITE != dwTime)
01788 {
01789 long int diff;
01790
01791 gettimeofday(&after, NULL);
01792 diff = time_sub(&after, &before);
01793 dwTime -= diff/1000;
01794 }
01795
01796 exit:
01797 return dwTime;
01798 }
01799
01891 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01892 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01893 {
01894 PSCARD_READERSTATE_A currReader;
01895 PREADER_STATE rContext;
01896 long dwTime = dwTimeout;
01897 DWORD dwState;
01898 DWORD dwBreakFlag = 0;
01899 int j;
01900 LONG dwContextIndex;
01901 int currentReaderCount = 0;
01902 LONG rv = SCARD_S_SUCCESS;
01903
01904 PROFILE_START
01905
01906 if ((rgReaderStates == NULL && cReaders > 0)
01907 || (cReaders > PCSCLITE_MAX_READERS_CONTEXTS))
01908 return SCARD_E_INVALID_PARAMETER;
01909
01910
01911 for (j = 0; j < cReaders; j++)
01912 {
01913 if (rgReaderStates[j].szReader == NULL)
01914 return SCARD_E_INVALID_VALUE;
01915 }
01916
01917
01918 if (cReaders > 0)
01919 {
01920 int nbNonIgnoredReaders = cReaders;
01921
01922 for (j=0; j<cReaders; j++)
01923 if (rgReaderStates[j].dwCurrentState & SCARD_STATE_IGNORE)
01924 nbNonIgnoredReaders--;
01925
01926 if (0 == nbNonIgnoredReaders)
01927 return SCARD_S_SUCCESS;
01928 }
01929
01930 rv = SCardCheckDaemonAvailability();
01931 if (rv != SCARD_S_SUCCESS)
01932 return rv;
01933
01934
01935
01936
01937 dwContextIndex = SCardGetContextIndice(hContext);
01938 if (dwContextIndex == -1)
01939 return SCARD_E_INVALID_HANDLE;
01940
01941 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01942
01943
01944 dwContextIndex = SCardGetContextIndice(hContext);
01945 if (dwContextIndex == -1)
01946
01947
01948
01949 return SCARD_E_INVALID_HANDLE;
01950
01951
01952
01953
01954
01955
01956
01957 if (cReaders == 0)
01958 {
01959 while (1)
01960 {
01961 int i;
01962
01963 rv = SCardCheckDaemonAvailability();
01964 if (rv != SCARD_S_SUCCESS)
01965 goto end;
01966
01967 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01968 {
01969 if ((readerStates[i])->readerID != 0)
01970 {
01971
01972 rv = SCARD_S_SUCCESS;
01973 goto end;
01974 }
01975 }
01976
01977 if (dwTimeout == 0)
01978 {
01979
01980 rv = SCARD_E_READER_UNAVAILABLE;
01981 goto end;
01982 }
01983
01984 dwTime = WaitForPcscdEvent(hContext, dwTime);
01985 if (dwTimeout != INFINITE)
01986 {
01987 if (dwTime <= 0)
01988 {
01989 rv = SCARD_E_TIMEOUT;
01990 goto end;
01991 }
01992 }
01993 }
01994 }
01995
01996
01997
01998
01999
02000
02001 for (j = 0; j < cReaders; j++)
02002 rgReaderStates[j].dwEventState = 0;
02003
02004
02005 Log1(PCSC_LOG_DEBUG, "Event Loop Start");
02006
02007 if (psContextMap[dwContextIndex].contextBlockStatus == BLOCK_STATUS_CANCEL) {
02008 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
02009 rv = SCARD_E_CANCELLED;
02010 goto end;
02011 }
02012
02013 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
02014
02015
02016 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
02017 if ((readerStates[j])->readerID != 0)
02018 currentReaderCount++;
02019
02020 j = 0;
02021 do
02022 {
02023 rv = SCardCheckDaemonAvailability();
02024 if (rv != SCARD_S_SUCCESS)
02025 {
02026 if (psContextMap[dwContextIndex].mMutex)
02027 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02028
02029 PROFILE_END(rv)
02030
02031 return rv;
02032 }
02033
02034 currReader = &rgReaderStates[j];
02035
02036
02037 if (!(currReader->dwCurrentState & SCARD_STATE_IGNORE))
02038 {
02039 LPSTR lpcReaderName;
02040 int i;
02041
02042
02043
02044 lpcReaderName = (char *) currReader->szReader;
02045
02046 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02047 {
02048 if (strcmp(lpcReaderName, (readerStates[i])->readerName) == 0)
02049 break;
02050 }
02051
02052
02053 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02054 {
02055
02056 if (strcasecmp(lpcReaderName, "\\\\?PnP?\\Notification") == 0)
02057 {
02058 int k, newReaderCount = 0;
02059
02060 for (k=0; k < PCSCLITE_MAX_READERS_CONTEXTS; k++)
02061 if ((readerStates[k])->readerID != 0)
02062 newReaderCount++;
02063
02064 if (newReaderCount != currentReaderCount)
02065 {
02066 Log1(PCSC_LOG_INFO, "Reader list changed");
02067 currentReaderCount = newReaderCount;
02068
02069 currReader->dwEventState |= SCARD_STATE_CHANGED;
02070 dwBreakFlag = 1;
02071 }
02072 }
02073 else
02074 {
02075 currReader->dwEventState = SCARD_STATE_UNKNOWN | SCARD_STATE_UNAVAILABLE;
02076 if (!(currReader->dwCurrentState & SCARD_STATE_UNKNOWN))
02077 {
02078 currReader->dwEventState |= SCARD_STATE_CHANGED;
02079
02080
02081
02082
02083
02084 dwBreakFlag = 1;
02085 }
02086 }
02087 }
02088 else
02089 {
02090
02091 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
02092 {
02093 currReader->dwEventState |= SCARD_STATE_CHANGED;
02094 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02095 dwBreakFlag = 1;
02096 }
02097
02098
02099
02100
02101 rContext = readerStates[i];
02102
02103
02104 dwState = rContext->readerState;
02105 {
02106 int currentCounter, stateCounter;
02107
02108 stateCounter = (dwState >> 16) & 0xFFFF;
02109 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
02110
02111
02112 if (stateCounter != currentCounter)
02113 {
02114 currReader->dwEventState |= SCARD_STATE_CHANGED;
02115 dwBreakFlag = 1;
02116 }
02117
02118
02119 currReader->dwEventState =
02120 ((currReader->dwEventState & 0xffff )
02121 | (stateCounter << 16));
02122 }
02123
02124
02125 if (dwState & SCARD_UNKNOWN)
02126 {
02127
02128 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
02129 if (!(currReader->dwCurrentState & SCARD_STATE_UNAVAILABLE))
02130 {
02131
02132 currReader->dwEventState |= SCARD_STATE_CHANGED;
02133 dwBreakFlag = 1;
02134 }
02135 }
02136 else
02137 {
02138
02139 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
02140 {
02141 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02142 currReader->dwEventState |= SCARD_STATE_CHANGED;
02143 dwBreakFlag = 1;
02144 }
02145 }
02146
02147
02148
02149 if (dwState & SCARD_PRESENT)
02150 {
02151
02152 if (0 == rContext->cardAtrLength)
02153
02154 (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
02155
02156 currReader->cbAtr = rContext->cardAtrLength;
02157 memcpy(currReader->rgbAtr, rContext->cardAtr,
02158 currReader->cbAtr);
02159 }
02160 else
02161 currReader->cbAtr = 0;
02162
02163
02164 if (dwState & SCARD_ABSENT)
02165 {
02166 currReader->dwEventState |= SCARD_STATE_EMPTY;
02167 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
02168 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02169 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02170 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02171 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02172 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
02173 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02174 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02175
02176
02177 if (currReader->dwCurrentState & SCARD_STATE_PRESENT)
02178 {
02179 currReader->dwEventState |= SCARD_STATE_CHANGED;
02180 dwBreakFlag = 1;
02181 }
02182 }
02183
02184 else if (dwState & SCARD_PRESENT)
02185 {
02186 currReader->dwEventState |= SCARD_STATE_PRESENT;
02187 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
02188 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02189 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02190 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02191 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02192 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02193
02194 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
02195 {
02196 currReader->dwEventState |= SCARD_STATE_CHANGED;
02197 dwBreakFlag = 1;
02198 }
02199
02200 if (dwState & SCARD_SWALLOWED)
02201 {
02202 currReader->dwEventState |= SCARD_STATE_MUTE;
02203 if (!(currReader->dwCurrentState & SCARD_STATE_MUTE))
02204 {
02205 currReader->dwEventState |= SCARD_STATE_CHANGED;
02206 dwBreakFlag = 1;
02207 }
02208 }
02209 else
02210 {
02211
02212 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
02213 {
02214 currReader->dwEventState |= SCARD_STATE_CHANGED;
02215 dwBreakFlag = 1;
02216 }
02217 }
02218 }
02219
02220
02221 if (rContext->readerSharing == -1)
02222 {
02223 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
02224 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02225 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02226 {
02227 currReader->dwEventState |= SCARD_STATE_CHANGED;
02228 dwBreakFlag = 1;
02229 }
02230 }
02231 else if (rContext->readerSharing >= 1)
02232 {
02233
02234 if (dwState & SCARD_PRESENT)
02235 {
02236 currReader->dwEventState |= SCARD_STATE_INUSE;
02237 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02238 if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)
02239 {
02240 currReader->dwEventState |= SCARD_STATE_CHANGED;
02241 dwBreakFlag = 1;
02242 }
02243 }
02244 }
02245 else if (rContext->readerSharing == 0)
02246 {
02247 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02248 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02249
02250 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02251 {
02252 currReader->dwEventState |= SCARD_STATE_CHANGED;
02253 dwBreakFlag = 1;
02254 }
02255 else if (currReader-> dwCurrentState
02256 & SCARD_STATE_EXCLUSIVE)
02257 {
02258 currReader->dwEventState |= SCARD_STATE_CHANGED;
02259 dwBreakFlag = 1;
02260 }
02261 }
02262
02263 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02264 {
02265
02266
02267
02268
02269 currReader->dwEventState |= SCARD_STATE_CHANGED;
02270 dwBreakFlag = 1;
02271 }
02272 }
02273 }
02274
02275
02276 j++;
02277 if (j == cReaders)
02278 {
02279
02280 j = 0;
02281
02282
02283
02284
02285 if (dwBreakFlag == 1)
02286 break;
02287
02288 if (BLOCK_STATUS_BLOCKING
02289 != psContextMap[dwContextIndex].contextBlockStatus)
02290 break;
02291
02292
02293 dwTime = WaitForPcscdEvent(hContext, dwTime);
02294
02295 if (dwTimeout != INFINITE)
02296 {
02297
02298
02299
02300 if (dwTime <= 0)
02301 {
02302 rv = SCARD_E_TIMEOUT;
02303 goto end;
02304 }
02305 }
02306 }
02307 }
02308 while (1);
02309
02310 if (psContextMap[dwContextIndex].contextBlockStatus != BLOCK_STATUS_BLOCKING)
02311 rv = SCARD_E_CANCELLED;
02312
02313 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
02314
02315 end:
02316 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02317
02318 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02319
02320 PROFILE_END(rv)
02321
02322 return rv;
02323 }
02324
02376 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02377 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02378 LPDWORD lpBytesReturned)
02379 {
02380 LONG rv;
02381 control_struct scControlStruct;
02382 sharedSegmentMsg msgStruct;
02383 int i;
02384 DWORD dwContextIndex, dwChannelIndex;
02385
02386 PROFILE_START
02387
02388
02389 if (NULL != lpBytesReturned)
02390 *lpBytesReturned = 0;
02391
02392 rv = SCardCheckDaemonAvailability();
02393 if (rv != SCARD_S_SUCCESS)
02394 return rv;
02395
02396
02397
02398
02399 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02400 if (rv == -1)
02401 return SCARD_E_INVALID_HANDLE;
02402
02403 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02404
02405
02406 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02407 if (rv == -1) {
02408
02409
02410
02411
02412
02413
02414 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02415 return SCARD_E_INVALID_HANDLE;
02416 }
02417
02418 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02419 {
02420 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02421
02422
02423 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02424 break;
02425 }
02426
02427 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02428 {
02429 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02430 return SCARD_E_READER_UNAVAILABLE;
02431 }
02432
02433 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02434 || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02435 {
02436 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02437 return SCARD_E_INSUFFICIENT_BUFFER;
02438 }
02439
02440 if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
02441 {
02442
02443 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02444 control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
02445 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02446
02447 scControlStructExtended->hCard = hCard;
02448 scControlStructExtended->dwControlCode = dwControlCode;
02449 scControlStructExtended->cbSendLength = cbSendLength;
02450 scControlStructExtended->cbRecvLength = cbRecvLength;
02451 scControlStructExtended->pdwBytesReturned = 0;
02452 scControlStructExtended->rv = SCARD_S_SUCCESS;
02453
02454
02455
02456
02457 scControlStructExtended->size = sizeof(*scControlStructExtended)
02458 - (sizeof(control_struct_extended) - offsetof(control_struct_extended, data))
02459 + cbSendLength;
02460 memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
02461
02462 rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
02463 psContextMap[dwContextIndex].dwClientID,
02464 scControlStructExtended->size,
02465 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02466
02467 if (rv == -1)
02468 {
02469 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02470 return SCARD_E_NO_SERVICE;
02471 }
02472
02473
02474
02475
02476
02477 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg),
02478 psContextMap[dwContextIndex].dwClientID, 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 scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
02487
02488
02489 if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02490 {
02491 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02492 scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02493 psContextMap[dwContextIndex].dwClientID,
02494 PCSCLITE_CLIENT_ATTEMPTS);
02495 if (rv == -1)
02496 {
02497 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02498 return SCARD_F_COMM_ERROR;
02499 }
02500 }
02501
02502 if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
02503 {
02504
02505
02506
02507 memcpy(pbRecvBuffer, scControlStructExtended -> data,
02508 scControlStructExtended -> pdwBytesReturned);
02509 memset(scControlStructExtended -> data, 0x00,
02510 scControlStructExtended -> pdwBytesReturned);
02511 }
02512
02513 if (NULL != lpBytesReturned)
02514 *lpBytesReturned = scControlStructExtended -> pdwBytesReturned;
02515
02516 rv = scControlStructExtended -> rv;
02517 }
02518 else
02519 {
02520 scControlStruct.hCard = hCard;
02521 scControlStruct.dwControlCode = dwControlCode;
02522 scControlStruct.cbSendLength = cbSendLength;
02523 scControlStruct.cbRecvLength = cbRecvLength;
02524 memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02525
02526 rv = WrapSHMWrite(SCARD_CONTROL,
02527 psContextMap[dwContextIndex].dwClientID,
02528 sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
02529
02530 if (rv == -1)
02531 {
02532 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02533 return SCARD_E_NO_SERVICE;
02534 }
02535
02536
02537
02538
02539 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02540 PCSCLITE_CLIENT_ATTEMPTS);
02541
02542 if (rv == -1)
02543 {
02544 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02545 return SCARD_F_COMM_ERROR;
02546 }
02547
02548 memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
02549
02550 if (NULL != lpBytesReturned)
02551 *lpBytesReturned = scControlStruct.dwBytesReturned;
02552
02553 if (scControlStruct.rv == SCARD_S_SUCCESS)
02554 {
02555
02556
02557
02558 memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
02559 scControlStruct.cbRecvLength);
02560 memset(scControlStruct.pbRecvBuffer, 0x00,
02561 sizeof(scControlStruct.pbRecvBuffer));
02562 }
02563
02564 rv = scControlStruct.rv;
02565 }
02566
02567 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02568
02569 PROFILE_END(rv)
02570
02571 return rv;
02572 }
02573
02673 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02674 LPDWORD pcbAttrLen)
02675 {
02676 LONG ret;
02677 unsigned char *buf = NULL;
02678
02679 PROFILE_START
02680
02681 if (NULL == pcbAttrLen)
02682 return SCARD_E_INVALID_PARAMETER;
02683
02684 if (SCARD_AUTOALLOCATE == *pcbAttrLen)
02685 {
02686 if (NULL == pbAttr)
02687 return SCARD_E_INVALID_PARAMETER;
02688
02689 *pcbAttrLen = MAX_BUFFER_SIZE;
02690 buf = malloc(*pcbAttrLen);
02691 if (NULL == buf)
02692 return SCARD_E_NO_MEMORY;
02693
02694 *(unsigned char **)pbAttr = buf;
02695 }
02696 else
02697 {
02698 buf = pbAttr;
02699
02700
02701 if (NULL == pbAttr)
02702
02703 *pcbAttrLen = MAX_BUFFER_SIZE;
02704 }
02705
02706 ret = SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, buf,
02707 pcbAttrLen);
02708
02709 PROFILE_END(ret)
02710
02711 return ret;
02712 }
02713
02748 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02749 DWORD cbAttrLen)
02750 {
02751 LONG ret;
02752
02753 PROFILE_START
02754
02755 if (NULL == pbAttr || 0 == cbAttrLen)
02756 return SCARD_E_INVALID_PARAMETER;
02757
02758 ret = SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02759 &cbAttrLen);
02760
02761 PROFILE_END(ret)
02762
02763 return ret;
02764 }
02765
02766 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02767 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02768 {
02769 LONG rv;
02770 getset_struct scGetSetStruct;
02771 sharedSegmentMsg msgStruct;
02772 int i;
02773 DWORD dwContextIndex, dwChannelIndex;
02774
02775 rv = SCardCheckDaemonAvailability();
02776 if (rv != SCARD_S_SUCCESS)
02777 return rv;
02778
02779
02780
02781
02782 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02783 if (rv == -1)
02784 return SCARD_E_INVALID_HANDLE;
02785
02786 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02787
02788
02789 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02790 if (rv == -1) {
02791
02792
02793
02794
02795
02796
02797 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02798 return SCARD_E_INVALID_HANDLE;
02799 }
02800
02801 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02802 {
02803 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02804
02805
02806 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02807 break;
02808 }
02809
02810 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02811 {
02812 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02813 return SCARD_E_READER_UNAVAILABLE;
02814 }
02815
02816 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02817 {
02818 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02819 return SCARD_E_INSUFFICIENT_BUFFER;
02820 }
02821
02822 scGetSetStruct.hCard = hCard;
02823 scGetSetStruct.dwAttrId = dwAttrId;
02824 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02825 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02826 memset(scGetSetStruct.pbAttr, 0, sizeof(scGetSetStruct.pbAttr));
02827 if (SCARD_SET_ATTRIB == command)
02828 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02829
02830 rv = WrapSHMWrite(command,
02831 psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
02832 PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
02833
02834 if (rv == -1)
02835 {
02836 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02837 return SCARD_E_NO_SERVICE;
02838 }
02839
02840
02841
02842
02843 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02844 PCSCLITE_CLIENT_ATTEMPTS);
02845
02846 if (rv == -1)
02847 {
02848 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02849 return SCARD_F_COMM_ERROR;
02850 }
02851
02852 memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
02853
02854 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02855 {
02856
02857
02858
02859 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02860 {
02861 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02862 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02863 }
02864 else
02865 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02866
02867 if (pbAttr)
02868 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02869
02870 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02871 }
02872
02873 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02874
02875 return scGetSetStruct.rv;
02876 }
02877
02936 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02937 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02938 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02939 LPDWORD pcbRecvLength)
02940 {
02941 LONG rv;
02942 int i;
02943 DWORD dwContextIndex, dwChannelIndex;
02944
02945 PROFILE_START
02946
02947 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02948 pcbRecvLength == NULL || pioSendPci == NULL)
02949 return SCARD_E_INVALID_PARAMETER;
02950
02951 rv = SCardCheckDaemonAvailability();
02952 if (rv != SCARD_S_SUCCESS)
02953 return rv;
02954
02955
02956
02957
02958 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02959 if (rv == -1)
02960 {
02961 *pcbRecvLength = 0;
02962 return SCARD_E_INVALID_HANDLE;
02963 }
02964
02965 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02966
02967
02968 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02969 if (rv == -1) {
02970
02971
02972
02973
02974
02975
02976 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02977 return SCARD_E_INVALID_HANDLE;
02978 }
02979
02980 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02981 {
02982 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02983
02984
02985 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02986 break;
02987 }
02988
02989 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02990 {
02991 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02992 return SCARD_E_READER_UNAVAILABLE;
02993 }
02994
02995 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02996 || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02997 {
02998 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02999 return SCARD_E_INSUFFICIENT_BUFFER;
03000 }
03001
03002 if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
03003 {
03004
03005 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
03006 transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
03007 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
03008
03009 scTransmitStructExtended->hCard = hCard;
03010 scTransmitStructExtended->cbSendLength = cbSendLength;
03011 scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
03012
03013
03014
03015
03016 scTransmitStructExtended->size = sizeof(*scTransmitStructExtended)
03017 - (sizeof(transmit_struct_extended) - offsetof(transmit_struct_extended, data))
03018 + cbSendLength;
03019 scTransmitStructExtended->pioSendPciProtocol = pioSendPci->dwProtocol;
03020 scTransmitStructExtended->pioSendPciLength = pioSendPci->cbPciLength;
03021 memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
03022 scTransmitStructExtended->rv = SCARD_S_SUCCESS;
03023
03024 if (pioRecvPci)
03025 {
03026 scTransmitStructExtended->pioRecvPciProtocol = pioRecvPci->dwProtocol;
03027 scTransmitStructExtended->pioRecvPciLength = pioRecvPci->cbPciLength;
03028 }
03029 else
03030 {
03031 scTransmitStructExtended->pioRecvPciProtocol = SCARD_PROTOCOL_ANY;
03032 scTransmitStructExtended->pioRecvPciLength = sizeof(SCARD_IO_REQUEST);
03033 }
03034
03035 rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
03036 psContextMap[dwContextIndex].dwClientID,
03037 scTransmitStructExtended->size,
03038 PCSCLITE_CLIENT_ATTEMPTS, buffer);
03039
03040 if (rv == -1)
03041 {
03042 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03043 return SCARD_E_NO_SERVICE;
03044 }
03045
03046
03047
03048
03049
03050 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
03051 if (rv == -1)
03052 {
03053 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03054 return SCARD_F_COMM_ERROR;
03055 }
03056
03057
03058 scTransmitStructExtended = (transmit_struct_extended *)&(pmsgStruct -> data);
03059
03060
03061 if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
03062 {
03063 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
03064 scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
03065 psContextMap[dwContextIndex].dwClientID,
03066 PCSCLITE_CLIENT_ATTEMPTS);
03067 if (rv == -1)
03068 {
03069 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03070 return SCARD_F_COMM_ERROR;
03071 }
03072 }
03073
03074 if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
03075 {
03076
03077
03078
03079 memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
03080 scTransmitStructExtended -> pcbRecvLength);
03081 memset(scTransmitStructExtended -> data, 0x00,
03082 scTransmitStructExtended -> pcbRecvLength);
03083
03084 if (pioRecvPci)
03085 {
03086 pioRecvPci->dwProtocol = scTransmitStructExtended->pioRecvPciProtocol;
03087 pioRecvPci->cbPciLength = scTransmitStructExtended->pioRecvPciLength;
03088 }
03089 }
03090
03091 *pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
03092 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03093
03094 rv = scTransmitStructExtended -> rv;
03095 }
03096 else
03097 {
03098
03099 transmit_struct scTransmitStruct;
03100 sharedSegmentMsg msgStruct;
03101
03102 scTransmitStruct.hCard = hCard;
03103 scTransmitStruct.cbSendLength = cbSendLength;
03104 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
03105 scTransmitStruct.pioSendPciProtocol = pioSendPci->dwProtocol;
03106 scTransmitStruct.pioSendPciLength = pioSendPci->cbPciLength;
03107 memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
03108 memset(scTransmitStruct.pbSendBuffer+cbSendLength, 0, sizeof(scTransmitStruct.pbSendBuffer)-cbSendLength);
03109 memset(scTransmitStruct.pbRecvBuffer, 0, sizeof(scTransmitStruct.pbRecvBuffer));
03110 scTransmitStruct.rv = SCARD_S_SUCCESS;
03111
03112 if (pioRecvPci)
03113 {
03114 scTransmitStruct.pioRecvPciProtocol = pioRecvPci->dwProtocol;
03115 scTransmitStruct.pioRecvPciLength = pioRecvPci->cbPciLength;
03116 }
03117 else
03118 {
03119 scTransmitStruct.pioRecvPciProtocol = SCARD_PROTOCOL_ANY;
03120 scTransmitStruct.pioRecvPciLength = sizeof(SCARD_IO_REQUEST);
03121 }
03122
03123 rv = WrapSHMWrite(SCARD_TRANSMIT,
03124 psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
03125 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
03126
03127 if (rv == -1)
03128 {
03129 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03130 return SCARD_E_NO_SERVICE;
03131 }
03132
03133
03134
03135
03136 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
03137 PCSCLITE_CLIENT_ATTEMPTS);
03138
03139 memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
03140
03141 if (rv == -1)
03142 {
03143 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03144 return SCARD_F_COMM_ERROR;
03145 }
03146
03147
03148
03149
03150 memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
03151
03152 if (scTransmitStruct.rv == SCARD_S_SUCCESS)
03153 {
03154
03155
03156
03157 memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
03158 scTransmitStruct.pcbRecvLength);
03159 memset(scTransmitStruct.pbRecvBuffer, 0x00,
03160 scTransmitStruct.pcbRecvLength);
03161
03162 if (pioRecvPci)
03163 {
03164 pioRecvPci->dwProtocol = scTransmitStruct.pioRecvPciProtocol;
03165 pioRecvPci->cbPciLength = scTransmitStruct.pioRecvPciLength;
03166 }
03167 }
03168
03169 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
03170 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03171
03172 rv = scTransmitStruct.rv;
03173 }
03174
03175 PROFILE_END(rv)
03176
03177 return rv;
03178 }
03179
03228 LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
03229 LPSTR mszReaders, LPDWORD pcchReaders)
03230 {
03231 DWORD dwReadersLen;
03232 int i;
03233 LONG dwContextIndex;
03234 LONG rv = SCARD_S_SUCCESS;
03235 char *buf = NULL;
03236
03237 (void)mszGroups;
03238 PROFILE_START
03239
03240
03241
03242
03243 if (pcchReaders == NULL)
03244 return SCARD_E_INVALID_PARAMETER;
03245
03246 rv = SCardCheckDaemonAvailability();
03247 if (rv != SCARD_S_SUCCESS)
03248 return rv;
03249
03250
03251
03252
03253 dwContextIndex = SCardGetContextIndice(hContext);
03254 if (dwContextIndex == -1)
03255 return SCARD_E_INVALID_HANDLE;
03256
03257 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03258
03259
03260 dwContextIndex = SCardGetContextIndice(hContext);
03261 if (dwContextIndex == -1)
03262
03263
03264
03265 return SCARD_E_INVALID_HANDLE;
03266
03267 dwReadersLen = 0;
03268 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03269 if ((readerStates[i])->readerID != 0)
03270 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
03271
03272
03273 dwReadersLen += 1;
03274
03275 if (1 == dwReadersLen)
03276 {
03277 rv = SCARD_E_NO_READERS_AVAILABLE;
03278 goto end;
03279 }
03280
03281 if (SCARD_AUTOALLOCATE == *pcchReaders)
03282 {
03283 buf = malloc(dwReadersLen);
03284 if (NULL == buf)
03285 {
03286 rv = SCARD_E_NO_MEMORY;
03287 goto end;
03288 }
03289 if (NULL == mszReaders)
03290 {
03291 rv = SCARD_E_INVALID_PARAMETER;
03292 goto end;
03293 }
03294 *(char **)mszReaders = buf;
03295 }
03296 else
03297 {
03298 buf = mszReaders;
03299
03300
03301 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
03302 {
03303 rv = SCARD_E_INSUFFICIENT_BUFFER;
03304 goto end;
03305 }
03306 }
03307
03308 if (mszReaders == NULL)
03309 goto end;
03310
03311 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03312 {
03313 if ((readerStates[i])->readerID != 0)
03314 {
03315
03316
03317
03318 strcpy(buf, (readerStates[i])->readerName);
03319 buf += strlen((readerStates[i])->readerName)+1;
03320 }
03321 }
03322 *buf = '\0';
03323
03324 end:
03325
03326 *pcchReaders = dwReadersLen;
03327
03328 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03329
03330 PROFILE_END(rv)
03331
03332 return rv;
03333 }
03334
03347 LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
03348 {
03349 LONG rv = SCARD_S_SUCCESS;
03350 LONG dwContextIndex;
03351
03352 PROFILE_START
03353
03354 rv = SCardCheckDaemonAvailability();
03355 if (rv != SCARD_S_SUCCESS)
03356 return rv;
03357
03358
03359
03360
03361 dwContextIndex = SCardGetContextIndice(hContext);
03362 if (dwContextIndex == -1)
03363 return SCARD_E_INVALID_HANDLE;
03364
03365 free((void *)pvMem);
03366
03367 PROFILE_END(rv)
03368
03369 return rv;
03370 }
03371
03421 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
03422 LPDWORD pcchGroups)
03423 {
03424 LONG rv = SCARD_S_SUCCESS;
03425 LONG dwContextIndex;
03426 char *buf = NULL;
03427
03428 PROFILE_START
03429
03430
03431 const char ReaderGroup[] = "SCard$DefaultReaders\0";
03432 const int dwGroups = sizeof(ReaderGroup);
03433
03434 rv = SCardCheckDaemonAvailability();
03435 if (rv != SCARD_S_SUCCESS)
03436 return rv;
03437
03438
03439
03440
03441 dwContextIndex = SCardGetContextIndice(hContext);
03442 if (dwContextIndex == -1)
03443 return SCARD_E_INVALID_HANDLE;
03444
03445 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03446
03447
03448 dwContextIndex = SCardGetContextIndice(hContext);
03449 if (dwContextIndex == -1)
03450
03451
03452
03453 return SCARD_E_INVALID_HANDLE;
03454
03455 if (SCARD_AUTOALLOCATE == *pcchGroups)
03456 {
03457 buf = malloc(dwGroups);
03458 if (NULL == buf)
03459 {
03460 rv = SCARD_E_NO_MEMORY;
03461 goto end;
03462 }
03463 if (NULL == mszGroups)
03464 {
03465 rv = SCARD_E_INVALID_PARAMETER;
03466 goto end;
03467 }
03468 *(char **)mszGroups = buf;
03469 }
03470 else
03471 {
03472 buf = mszGroups;
03473
03474 if ((NULL != mszGroups) && (*pcchGroups < dwGroups))
03475 {
03476 rv = SCARD_E_INSUFFICIENT_BUFFER;
03477 goto end;
03478 }
03479 }
03480
03481 if (buf)
03482 memcpy(buf, ReaderGroup, dwGroups);
03483
03484 end:
03485 *pcchGroups = dwGroups;
03486
03487 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03488
03489 PROFILE_END(rv)
03490
03491 return rv;
03492 }
03493
03521 LONG SCardCancel(SCARDCONTEXT hContext)
03522 {
03523 LONG dwContextIndex;
03524 LONG rv = SCARD_S_SUCCESS;
03525
03526 PROFILE_START
03527
03528 dwContextIndex = SCardGetContextIndice(hContext);
03529 if (dwContextIndex == -1)
03530 return SCARD_E_INVALID_HANDLE;
03531
03532
03533
03534
03535
03536 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_CANCEL;
03537
03538 if (StatSynchronizeContext(hContext))
03539 rv = SCARD_F_INTERNAL_ERROR;
03540
03541 PROFILE_END(rv)
03542
03543 return rv;
03544 }
03545
03569 LONG SCardIsValidContext(SCARDCONTEXT hContext)
03570 {
03571 LONG rv;
03572 LONG dwContextIndex;
03573
03574 PROFILE_START
03575
03576 rv = SCARD_S_SUCCESS;
03577
03578
03579 rv = SCardCheckDaemonAvailability();
03580 if (rv != SCARD_S_SUCCESS)
03581 return rv;
03582
03583
03584
03585
03586 dwContextIndex = SCardGetContextIndice(hContext);
03587 if (dwContextIndex == -1)
03588 rv = SCARD_E_INVALID_HANDLE;
03589
03590 PROFILE_END(rv)
03591
03592 return rv;
03593 }
03594
03611 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
03612 {
03613 int i;
03614
03615 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03616 {
03617 if (psContextMap[i].hContext == 0)
03618 {
03619 psContextMap[i].hContext = hContext;
03620 psContextMap[i].dwClientID = dwClientID;
03621 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
03622 psContextMap[i].mMutex = malloc(sizeof(PCSCLITE_MUTEX));
03623 (void)SYS_MutexInit(psContextMap[i].mMutex);
03624 return SCARD_S_SUCCESS;
03625 }
03626 }
03627
03628 return SCARD_E_NO_MEMORY;
03629 }
03630
03643 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
03644 {
03645 LONG rv;
03646
03647 (void)SCardLockThread();
03648 rv = SCardGetContextIndiceTH(hContext);
03649 (void)SCardUnlockThread();
03650
03651 return rv;
03652 }
03653
03666 static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
03667 {
03668 int i;
03669
03670
03671
03672
03673 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03674 {
03675 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
03676 return i;
03677 }
03678
03679 return -1;
03680 }
03681
03691 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
03692 {
03693 LONG retIndice;
03694
03695 retIndice = SCardGetContextIndiceTH(hContext);
03696
03697 if (retIndice == -1)
03698 return SCARD_E_INVALID_HANDLE;
03699 else
03700 return SCardCleanContext(retIndice);
03701 }
03702
03703 static LONG SCardCleanContext(LONG indice)
03704 {
03705 int i;
03706
03707 psContextMap[indice].hContext = 0;
03708 (void)SHMClientCloseSession(psContextMap[indice].dwClientID);
03709 psContextMap[indice].dwClientID = 0;
03710 free(psContextMap[indice].mMutex);
03711 psContextMap[indice].mMutex = NULL;
03712 psContextMap[indice].contextBlockStatus = BLOCK_STATUS_RESUME;
03713
03714 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03715 {
03716
03717
03718
03719 psContextMap[indice].psChannelMap[i].hCard = 0;
03720 free(psContextMap[indice].psChannelMap[i].readerName);
03721 psContextMap[indice].psChannelMap[i].readerName = NULL;
03722 }
03723
03724 return SCARD_S_SUCCESS;
03725 }
03726
03727
03728
03729
03730
03731 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
03732 LPCSTR readerName)
03733 {
03734 int i;
03735
03736 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03737 {
03738 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
03739 {
03740 psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
03741 psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
03742 return SCARD_S_SUCCESS;
03743 }
03744 }
03745
03746 return SCARD_E_NO_MEMORY;
03747 }
03748
03749 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03750 {
03751 DWORD dwContextIndice, dwChannelIndice;
03752 LONG rv;
03753
03754 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
03755 if (rv == -1)
03756 return SCARD_E_INVALID_HANDLE;
03757 else
03758 {
03759 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
03760 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
03761 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
03762 return SCARD_S_SUCCESS;
03763 }
03764 }
03765
03766 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard,
03767 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03768 {
03769 LONG rv;
03770
03771 if (0 == hCard)
03772 return -1;
03773
03774 (void)SCardLockThread();
03775 rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
03776 (void)SCardUnlockThread();
03777
03778 return rv;
03779 }
03780
03781 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard,
03782 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03783 {
03784 int i;
03785
03786 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03787 {
03788 if (psContextMap[i].hContext != 0)
03789 {
03790 int j;
03791
03792 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
03793 {
03794 if (psContextMap[i].psChannelMap[j].hCard == hCard)
03795 {
03796 *pdwContextIndice = i;
03797 *pdwChannelIndice = j;
03798 return SCARD_S_SUCCESS;
03799 }
03800 }
03801
03802 }
03803 }
03804
03805 return -1;
03806 }
03807
03816 LONG SCardCheckDaemonAvailability(void)
03817 {
03818 LONG rv;
03819 struct stat statBuffer;
03820 int need_restart = 0;
03821
03822 rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &statBuffer);
03823
03824 if (rv != 0)
03825 {
03826 Log2(PCSC_LOG_INFO, "PCSC Not Running: " PCSCLITE_PUBSHM_FILE ": %s",
03827 strerror(errno));
03828 return SCARD_E_NO_SERVICE;
03829 }
03830
03831
03832
03833 if (daemon_ctime && statBuffer.st_ctime > daemon_ctime)
03834 {
03835
03836 if (GetDaemonPid() != daemon_pid)
03837 {
03838 Log1(PCSC_LOG_INFO, "PCSC restarted");
03839 need_restart = 1;
03840 }
03841 }
03842
03843
03844 if (client_pid && client_pid != getpid())
03845 {
03846 Log1(PCSC_LOG_INFO, "Client forked");
03847 need_restart = 1;
03848 }
03849
03850 if (need_restart)
03851 {
03852 int i;
03853
03854
03855 (void)SCardLockThread();
03856
03857 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03858 if (psContextMap[i].hContext)
03859 (void)SCardCleanContext(i);
03860
03861 (void)SCardUnlockThread();
03862
03863
03864 daemon_ctime = 0;
03865 client_pid = 0;
03866
03867
03868 SCardUnload();
03869
03870 return SCARD_E_INVALID_HANDLE;
03871 }
03872
03873 daemon_ctime = statBuffer.st_ctime;
03874 daemon_pid = GetDaemonPid();
03875 client_pid = getpid();
03876
03877 return SCARD_S_SUCCESS;
03878 }
03879
03886 #ifdef __SUNPRO_C
03887 #pragma fini (SCardUnload)
03888 #endif
03889
03890 void DESTRUCTOR SCardUnload(void)
03891 {
03892 int i;
03893
03894 if (!isExecuted)
03895 return;
03896
03897
03898 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03899 {
03900 if (readerStates[i] != NULL)
03901 {
03902 SYS_PublicMemoryUnmap(readerStates[i], sizeof(READER_STATE));
03903 readerStates[i] = NULL;
03904 }
03905 }
03906
03907 (void)SYS_CloseFile(mapAddr);
03908 isExecuted = 0;
03909 }
03910