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 return SCARD_E_INVALID_HANDLE;
00935
00936 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00937 {
00938 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
00939
00940
00941 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
00942 break;
00943 }
00944
00945 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00946 {
00947 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00948 return SCARD_E_READER_UNAVAILABLE;
00949 }
00950
00951 do
00952 {
00953 scReconnectStruct.hCard = hCard;
00954 scReconnectStruct.dwShareMode = dwShareMode;
00955 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00956 scReconnectStruct.dwInitialization = dwInitialization;
00957 scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00958 scReconnectStruct.rv = SCARD_S_SUCCESS;
00959
00960 rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
00961 sizeof(scReconnectStruct),
00962 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
00963
00964 if (rv == -1)
00965 {
00966 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00967 return SCARD_E_NO_SERVICE;
00968 }
00969
00970
00971
00972
00973 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00974 PCSCLITE_CLIENT_ATTEMPTS);
00975
00976 memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
00977
00978 if (rv == -1)
00979 {
00980 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00981 return SCARD_F_COMM_ERROR;
00982 }
00983 } while (SCARD_E_SHARING_VIOLATION == scReconnectStruct.rv);
00984
00985 *pdwActiveProtocol = scReconnectStruct.pdwActiveProtocol;
00986
00987 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00988
00989 PROFILE_END(scReconnectStruct.rv)
00990
00991 return scReconnectStruct.rv;
00992 }
00993
01024 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
01025 {
01026 LONG rv;
01027 disconnect_struct scDisconnectStruct;
01028 sharedSegmentMsg msgStruct;
01029 DWORD dwContextIndex, dwChannelIndex;
01030
01031 PROFILE_START
01032
01033 rv = SCardCheckDaemonAvailability();
01034 if (rv != SCARD_S_SUCCESS)
01035 return rv;
01036
01037
01038
01039
01040 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01041 if (rv == -1)
01042 return SCARD_E_INVALID_HANDLE;
01043
01044 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01045
01046
01047 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01048 if (rv == -1)
01049
01050
01051
01052 return SCARD_E_INVALID_HANDLE;
01053
01054 scDisconnectStruct.hCard = hCard;
01055 scDisconnectStruct.dwDisposition = dwDisposition;
01056 scDisconnectStruct.rv = SCARD_S_SUCCESS;
01057
01058 rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
01059 sizeof(scDisconnectStruct),
01060 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
01061
01062 if (rv == -1)
01063 {
01064 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01065 return SCARD_E_NO_SERVICE;
01066 }
01067
01068
01069
01070
01071 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01072 PCSCLITE_CLIENT_ATTEMPTS);
01073
01074 memcpy(&scDisconnectStruct, &msgStruct.data,
01075 sizeof(scDisconnectStruct));
01076
01077 if (rv == -1)
01078 {
01079 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01080 return SCARD_F_COMM_ERROR;
01081 }
01082
01083 (void)SCardRemoveHandle(hCard);
01084
01085 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01086
01087 PROFILE_END(scDisconnectStruct.rv)
01088
01089 return scDisconnectStruct.rv;
01090 }
01091
01127 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01128 {
01129
01130 LONG rv;
01131 begin_struct scBeginStruct;
01132 int i;
01133 sharedSegmentMsg msgStruct;
01134 DWORD dwContextIndex, dwChannelIndex;
01135
01136 PROFILE_START
01137
01138 rv = SCardCheckDaemonAvailability();
01139 if (rv != SCARD_S_SUCCESS)
01140 return rv;
01141
01142
01143
01144
01145 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01146 if (rv == -1)
01147 return SCARD_E_INVALID_HANDLE;
01148
01149 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01150
01151
01152 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01153 if (rv == -1)
01154
01155
01156
01157 return SCARD_E_INVALID_HANDLE;
01158
01159 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01160 {
01161 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01162
01163
01164 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01165 break;
01166 }
01167
01168 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01169 {
01170 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01171 return SCARD_E_READER_UNAVAILABLE;
01172 }
01173
01174 scBeginStruct.hCard = hCard;
01175 scBeginStruct.rv = SCARD_S_SUCCESS;
01176
01177
01178
01179
01180
01181
01182 do
01183 {
01184 rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01185 sizeof(scBeginStruct),
01186 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);
01187
01188 if (rv == -1)
01189 {
01190
01191 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01192 return SCARD_E_NO_SERVICE;
01193 }
01194
01195
01196
01197
01198 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01199 PCSCLITE_CLIENT_ATTEMPTS);
01200
01201 memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));
01202
01203 if (rv == -1)
01204 {
01205
01206 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01207 return SCARD_F_COMM_ERROR;
01208 }
01209
01210 }
01211 while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
01212
01213 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01214
01215 PROFILE_END(scBeginStruct.rv);
01216
01217 return scBeginStruct.rv;
01218 }
01219
01260 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01261 {
01262 LONG rv;
01263 end_struct scEndStruct;
01264 sharedSegmentMsg msgStruct;
01265 int randnum, i;
01266 DWORD dwContextIndex, dwChannelIndex;
01267
01268 PROFILE_START
01269
01270
01271
01272
01273 randnum = 0;
01274
01275 rv = SCardCheckDaemonAvailability();
01276 if (rv != SCARD_S_SUCCESS)
01277 return rv;
01278
01279
01280
01281
01282 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01283 if (rv == -1)
01284 return SCARD_E_INVALID_HANDLE;
01285
01286 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01287
01288
01289 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01290 if (rv == -1)
01291
01292
01293
01294 return SCARD_E_INVALID_HANDLE;
01295
01296 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01297 {
01298 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01299
01300
01301 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01302 break;
01303 }
01304
01305 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01306 {
01307 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01308 return SCARD_E_READER_UNAVAILABLE;
01309 }
01310
01311 scEndStruct.hCard = hCard;
01312 scEndStruct.dwDisposition = dwDisposition;
01313 scEndStruct.rv = SCARD_S_SUCCESS;
01314
01315 rv = WrapSHMWrite(SCARD_END_TRANSACTION,
01316 psContextMap[dwContextIndex].dwClientID,
01317 sizeof(scEndStruct),
01318 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
01319
01320 if (rv == -1)
01321 {
01322 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01323 return SCARD_E_NO_SERVICE;
01324 }
01325
01326
01327
01328
01329 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01330 PCSCLITE_CLIENT_ATTEMPTS);
01331
01332 memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
01333
01334 if (rv == -1)
01335 {
01336 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01337 return SCARD_F_COMM_ERROR;
01338 }
01339
01340
01341
01342
01343 randnum = SYS_RandomInt(1000, 10000);
01344 (void)SYS_USleep(randnum);
01345
01346 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01347
01348 PROFILE_END(scEndStruct.rv)
01349
01350 return scEndStruct.rv;
01351 }
01352
01359 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01360 {
01361 LONG rv;
01362 cancel_struct scCancelStruct;
01363 sharedSegmentMsg msgStruct;
01364 int i;
01365 DWORD dwContextIndex, dwChannelIndex;
01366
01367 PROFILE_START
01368
01369 rv = SCardCheckDaemonAvailability();
01370 if (rv != SCARD_S_SUCCESS)
01371 return rv;
01372
01373
01374
01375
01376 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01377 if (rv == -1)
01378 return SCARD_E_INVALID_HANDLE;
01379
01380 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01381
01382
01383 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01384 if (rv == -1)
01385
01386
01387
01388 return SCARD_E_INVALID_HANDLE;
01389
01390 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01391 {
01392 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01393
01394
01395 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01396 break;
01397 }
01398
01399 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01400 {
01401 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01402 return SCARD_E_READER_UNAVAILABLE;
01403 }
01404
01405 scCancelStruct.hCard = hCard;
01406
01407 rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION,
01408 psContextMap[dwContextIndex].dwClientID,
01409 sizeof(scCancelStruct),
01410 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
01411
01412 if (rv == -1)
01413 {
01414 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01415 return SCARD_E_NO_SERVICE;
01416 }
01417
01418
01419
01420
01421 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01422 PCSCLITE_CLIENT_ATTEMPTS);
01423
01424 memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
01425
01426 if (rv == -1)
01427 {
01428 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01429 return SCARD_F_COMM_ERROR;
01430 }
01431
01432 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01433
01434 PROFILE_END(scCancelStruct.rv)
01435
01436 return scCancelStruct.rv;
01437 }
01438
01526 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName,
01527 LPDWORD pcchReaderLen, LPDWORD pdwState,
01528 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
01529 {
01530 DWORD dwReaderLen, dwAtrLen;
01531 LONG rv;
01532 int i;
01533 status_struct scStatusStruct;
01534 sharedSegmentMsg msgStruct;
01535 DWORD dwContextIndex, dwChannelIndex;
01536 char *r;
01537 char *bufReader = NULL;
01538 LPBYTE bufAtr = NULL;
01539 DWORD dummy;
01540
01541 PROFILE_START
01542
01543
01544 if (pdwState)
01545 *pdwState = 0;
01546
01547 if (pdwProtocol)
01548 *pdwProtocol = 0;
01549
01550
01551 if (pcchReaderLen == NULL)
01552 pcchReaderLen = &dummy;
01553
01554 if (pcbAtrLen == NULL)
01555 pcbAtrLen = &dummy;
01556
01557
01558 dwReaderLen = *pcchReaderLen;
01559 dwAtrLen = *pcbAtrLen;
01560
01561 *pcchReaderLen = 0;
01562 *pcbAtrLen = 0;
01563
01564 rv = SCardCheckDaemonAvailability();
01565 if (rv != SCARD_S_SUCCESS)
01566 return rv;
01567
01568
01569
01570
01571 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01572 if (rv == -1)
01573 return SCARD_E_INVALID_HANDLE;
01574
01575 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01576
01577
01578 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01579 if (rv == -1)
01580
01581
01582
01583 return SCARD_E_INVALID_HANDLE;
01584
01585 r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01586 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01587 {
01588
01589 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01590 break;
01591 }
01592
01593 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01594 {
01595 rv = SCARD_E_READER_UNAVAILABLE;
01596 goto end;
01597 }
01598
01599
01600 memset(&scStatusStruct, 0, sizeof(scStatusStruct));
01601 scStatusStruct.hCard = hCard;
01602
01603
01604 scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
01605 scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
01606
01607 rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
01608 sizeof(scStatusStruct),
01609 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
01610
01611 if (rv == -1)
01612 {
01613 rv = SCARD_E_NO_SERVICE;
01614 goto end;
01615 }
01616
01617
01618
01619
01620 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01621 PCSCLITE_CLIENT_ATTEMPTS);
01622
01623 memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
01624
01625 if (rv == -1)
01626 {
01627 rv = SCARD_F_COMM_ERROR;
01628 goto end;
01629 }
01630
01631 rv = scStatusStruct.rv;
01632 if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
01633 {
01634
01635
01636
01637 goto end;
01638 }
01639
01640
01641
01642
01643
01644 *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
01645 *pcbAtrLen = (readerStates[i])->cardAtrLength;
01646
01647 if (pdwState)
01648 *pdwState = (readerStates[i])->readerState;
01649
01650 if (pdwProtocol)
01651 *pdwProtocol = (readerStates[i])->cardProtocol;
01652
01653 if (SCARD_AUTOALLOCATE == dwReaderLen)
01654 {
01655 dwReaderLen = *pcchReaderLen;
01656 bufReader = malloc(dwReaderLen);
01657 if (NULL == bufReader)
01658 {
01659 rv = SCARD_E_NO_MEMORY;
01660 goto end;
01661 }
01662 if (NULL == mszReaderName)
01663 {
01664 rv = SCARD_E_INVALID_PARAMETER;
01665 goto end;
01666 }
01667 *(char **)mszReaderName = bufReader;
01668 }
01669 else
01670 bufReader = mszReaderName;
01671
01672
01673 if (bufReader)
01674 {
01675 if (*pcchReaderLen > dwReaderLen)
01676 rv = SCARD_E_INSUFFICIENT_BUFFER;
01677
01678 strncpy(bufReader,
01679 psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
01680 dwReaderLen);
01681 }
01682
01683 if (SCARD_AUTOALLOCATE == dwAtrLen)
01684 {
01685 dwAtrLen = *pcbAtrLen;
01686 bufAtr = malloc(dwAtrLen);
01687 if (NULL == bufAtr)
01688 {
01689 rv = SCARD_E_NO_MEMORY;
01690 goto end;
01691 }
01692 if (NULL == pbAtr)
01693 {
01694 rv = SCARD_E_INVALID_PARAMETER;
01695 goto end;
01696 }
01697 *(LPBYTE *)pbAtr = bufAtr;
01698 }
01699 else
01700 bufAtr = pbAtr;
01701
01702 if (bufAtr)
01703 {
01704 if (*pcbAtrLen > dwAtrLen)
01705 rv = SCARD_E_INSUFFICIENT_BUFFER;
01706
01707 memcpy(bufAtr, (readerStates[i])->cardAtr, min(*pcbAtrLen, dwAtrLen));
01708 }
01709
01710 end:
01711 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01712
01713 PROFILE_END(rv)
01714
01715 return rv;
01716 }
01717
01718 static long WaitForPcscdEvent(SCARDCONTEXT hContext, long dwTime)
01719 {
01720 char filename[FILENAME_MAX];
01721 char buf[1];
01722 int fd, r;
01723 struct timeval tv, *ptv = NULL;
01724 struct timeval before, after;
01725 fd_set read_fd;
01726
01727 if (INFINITE != dwTime)
01728 {
01729 if (dwTime < 0)
01730 return 0;
01731 gettimeofday(&before, NULL);
01732 tv.tv_sec = dwTime/1000;
01733 tv.tv_usec = dwTime*1000 - tv.tv_sec*1000000;
01734 ptv = &tv;
01735 }
01736
01737 (void)snprintf(filename, sizeof(filename), "%s/event.%d.%ld",
01738 PCSCLITE_EVENTS_DIR, SYS_GetPID(), hContext);
01739 r = mkfifo(filename, 0644);
01740 if ((-1 == r) && (errno != EEXIST))
01741 {
01742 Log2(PCSC_LOG_CRITICAL, "Can't create event fifo: %s", strerror(errno));
01743 goto exit;
01744 }
01745
01746 fd = SYS_OpenFile(filename, O_RDONLY | O_NONBLOCK, 0);
01747
01748 FD_ZERO(&read_fd);
01749 FD_SET(fd, &read_fd);
01750
01751 (void)select(fd+1, &read_fd, NULL, NULL, ptv);
01752
01753 (void)SYS_ReadFile(fd, buf, 1);
01754 (void)SYS_CloseFile(fd);
01755 (void)SYS_RemoveFile(filename);
01756
01757 if (INFINITE != dwTime)
01758 {
01759 long int diff;
01760
01761 gettimeofday(&after, NULL);
01762 diff = time_sub(&after, &before);
01763 dwTime -= diff/1000;
01764 }
01765
01766 exit:
01767 return dwTime;
01768 }
01769
01861 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01862 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01863 {
01864 PSCARD_READERSTATE_A currReader;
01865 PREADER_STATE rContext;
01866 long dwTime = dwTimeout;
01867 DWORD dwState;
01868 DWORD dwBreakFlag = 0;
01869 int j;
01870 LONG dwContextIndex;
01871 int currentReaderCount = 0;
01872 LONG rv = SCARD_S_SUCCESS;
01873
01874 PROFILE_START
01875
01876 if ((rgReaderStates == NULL && cReaders > 0)
01877 || (cReaders > PCSCLITE_MAX_READERS_CONTEXTS))
01878 return SCARD_E_INVALID_PARAMETER;
01879
01880
01881 for (j = 0; j < cReaders; j++)
01882 {
01883 if (rgReaderStates[j].szReader == NULL)
01884 return SCARD_E_INVALID_VALUE;
01885 }
01886
01887
01888 if (cReaders > 0)
01889 {
01890 int nbNonIgnoredReaders = cReaders;
01891
01892 for (j=0; j<cReaders; j++)
01893 if (rgReaderStates[j].dwCurrentState & SCARD_STATE_IGNORE)
01894 nbNonIgnoredReaders--;
01895
01896 if (0 == nbNonIgnoredReaders)
01897 return SCARD_S_SUCCESS;
01898 }
01899
01900 rv = SCardCheckDaemonAvailability();
01901 if (rv != SCARD_S_SUCCESS)
01902 return rv;
01903
01904
01905
01906
01907 dwContextIndex = SCardGetContextIndice(hContext);
01908 if (dwContextIndex == -1)
01909 return SCARD_E_INVALID_HANDLE;
01910
01911 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01912
01913
01914 dwContextIndex = SCardGetContextIndice(hContext);
01915 if (dwContextIndex == -1)
01916
01917
01918
01919 return SCARD_E_INVALID_HANDLE;
01920
01921
01922
01923
01924
01925
01926
01927 if (cReaders == 0)
01928 {
01929 while (1)
01930 {
01931 int i;
01932
01933 rv = SCardCheckDaemonAvailability();
01934 if (rv != SCARD_S_SUCCESS)
01935 goto end;
01936
01937 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01938 {
01939 if ((readerStates[i])->readerID != 0)
01940 {
01941
01942 rv = SCARD_S_SUCCESS;
01943 goto end;
01944 }
01945 }
01946
01947 if (dwTimeout == 0)
01948 {
01949
01950 rv = SCARD_E_READER_UNAVAILABLE;
01951 goto end;
01952 }
01953
01954 dwTime = WaitForPcscdEvent(hContext, dwTime);
01955 if (dwTimeout != INFINITE)
01956 {
01957 if (dwTime <= 0)
01958 {
01959 rv = SCARD_E_TIMEOUT;
01960 goto end;
01961 }
01962 }
01963 }
01964 }
01965
01966
01967
01968
01969
01970
01971 for (j = 0; j < cReaders; j++)
01972 rgReaderStates[j].dwEventState = 0;
01973
01974
01975 Log1(PCSC_LOG_DEBUG, "Event Loop Start");
01976
01977 if (psContextMap[dwContextIndex].contextBlockStatus == BLOCK_STATUS_CANCEL) {
01978 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
01979 rv = SCARD_E_CANCELLED;
01980 goto end;
01981 }
01982
01983 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
01984
01985
01986 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
01987 if ((readerStates[j])->readerID != 0)
01988 currentReaderCount++;
01989
01990 j = 0;
01991 do
01992 {
01993 rv = SCardCheckDaemonAvailability();
01994 if (rv != SCARD_S_SUCCESS)
01995 {
01996 if (psContextMap[dwContextIndex].mMutex)
01997 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01998
01999 PROFILE_END(rv)
02000
02001 return rv;
02002 }
02003
02004 currReader = &rgReaderStates[j];
02005
02006
02007 if (!(currReader->dwCurrentState & SCARD_STATE_IGNORE))
02008 {
02009 LPSTR lpcReaderName;
02010 int i;
02011
02012
02013
02014 lpcReaderName = (char *) currReader->szReader;
02015
02016 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02017 {
02018 if (strcmp(lpcReaderName, (readerStates[i])->readerName) == 0)
02019 break;
02020 }
02021
02022
02023 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02024 {
02025
02026 if (strcasecmp(lpcReaderName, "\\\\?PnP?\\Notification") == 0)
02027 {
02028 int k, newReaderCount = 0;
02029
02030 for (k=0; k < PCSCLITE_MAX_READERS_CONTEXTS; k++)
02031 if ((readerStates[k])->readerID != 0)
02032 newReaderCount++;
02033
02034 if (newReaderCount != currentReaderCount)
02035 {
02036 Log1(PCSC_LOG_INFO, "Reader list changed");
02037 currentReaderCount = newReaderCount;
02038
02039 currReader->dwEventState |= SCARD_STATE_CHANGED;
02040 dwBreakFlag = 1;
02041 }
02042 }
02043 else
02044 {
02045 currReader->dwEventState = SCARD_STATE_UNKNOWN | SCARD_STATE_UNAVAILABLE;
02046 if (!(currReader->dwCurrentState & SCARD_STATE_UNKNOWN))
02047 {
02048 currReader->dwEventState |= SCARD_STATE_CHANGED;
02049
02050
02051
02052
02053
02054 dwBreakFlag = 1;
02055 }
02056 }
02057 }
02058 else
02059 {
02060
02061 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
02062 {
02063 currReader->dwEventState |= SCARD_STATE_CHANGED;
02064 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02065 dwBreakFlag = 1;
02066 }
02067
02068
02069
02070
02071 rContext = readerStates[i];
02072
02073
02074 dwState = rContext->readerState;
02075 {
02076 int currentCounter, stateCounter;
02077
02078 stateCounter = (dwState >> 16) & 0xFFFF;
02079 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
02080
02081
02082 if (stateCounter != currentCounter)
02083 {
02084 currReader->dwEventState |= SCARD_STATE_CHANGED;
02085 dwBreakFlag = 1;
02086 }
02087
02088
02089 currReader->dwEventState =
02090 ((currReader->dwEventState & 0xffff )
02091 | (stateCounter << 16));
02092 }
02093
02094
02095 if (dwState & SCARD_UNKNOWN)
02096 {
02097
02098 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
02099 if (!(currReader->dwCurrentState & SCARD_STATE_UNAVAILABLE))
02100 {
02101
02102 currReader->dwEventState |= SCARD_STATE_CHANGED;
02103 dwBreakFlag = 1;
02104 }
02105 }
02106 else
02107 {
02108
02109 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
02110 {
02111 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02112 currReader->dwEventState |= SCARD_STATE_CHANGED;
02113 dwBreakFlag = 1;
02114 }
02115 }
02116
02117
02118
02119 if (dwState & SCARD_PRESENT)
02120 {
02121
02122 if (0 == rContext->cardAtrLength)
02123
02124 (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
02125
02126 currReader->cbAtr = rContext->cardAtrLength;
02127 memcpy(currReader->rgbAtr, rContext->cardAtr,
02128 currReader->cbAtr);
02129 }
02130 else
02131 currReader->cbAtr = 0;
02132
02133
02134 if (dwState & SCARD_ABSENT)
02135 {
02136 currReader->dwEventState |= SCARD_STATE_EMPTY;
02137 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
02138 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02139 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02140 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02141 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02142 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
02143 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02144 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02145
02146
02147 if (currReader->dwCurrentState & SCARD_STATE_PRESENT)
02148 {
02149 currReader->dwEventState |= SCARD_STATE_CHANGED;
02150 dwBreakFlag = 1;
02151 }
02152 }
02153
02154 else if (dwState & SCARD_PRESENT)
02155 {
02156 currReader->dwEventState |= SCARD_STATE_PRESENT;
02157 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
02158 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02159 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02160 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02161 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02162 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02163
02164 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
02165 {
02166 currReader->dwEventState |= SCARD_STATE_CHANGED;
02167 dwBreakFlag = 1;
02168 }
02169
02170 if (dwState & SCARD_SWALLOWED)
02171 {
02172 currReader->dwEventState |= SCARD_STATE_MUTE;
02173 if (!(currReader->dwCurrentState & SCARD_STATE_MUTE))
02174 {
02175 currReader->dwEventState |= SCARD_STATE_CHANGED;
02176 dwBreakFlag = 1;
02177 }
02178 }
02179 else
02180 {
02181
02182 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
02183 {
02184 currReader->dwEventState |= SCARD_STATE_CHANGED;
02185 dwBreakFlag = 1;
02186 }
02187 }
02188 }
02189
02190
02191 if (rContext->readerSharing == -1)
02192 {
02193 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
02194 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02195 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02196 {
02197 currReader->dwEventState |= SCARD_STATE_CHANGED;
02198 dwBreakFlag = 1;
02199 }
02200 }
02201 else if (rContext->readerSharing >= 1)
02202 {
02203
02204 if (dwState & SCARD_PRESENT)
02205 {
02206 currReader->dwEventState |= SCARD_STATE_INUSE;
02207 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02208 if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)
02209 {
02210 currReader->dwEventState |= SCARD_STATE_CHANGED;
02211 dwBreakFlag = 1;
02212 }
02213 }
02214 }
02215 else if (rContext->readerSharing == 0)
02216 {
02217 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02218 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02219
02220 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02221 {
02222 currReader->dwEventState |= SCARD_STATE_CHANGED;
02223 dwBreakFlag = 1;
02224 }
02225 else if (currReader-> dwCurrentState
02226 & SCARD_STATE_EXCLUSIVE)
02227 {
02228 currReader->dwEventState |= SCARD_STATE_CHANGED;
02229 dwBreakFlag = 1;
02230 }
02231 }
02232
02233 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02234 {
02235
02236
02237
02238
02239 currReader->dwEventState |= SCARD_STATE_CHANGED;
02240 dwBreakFlag = 1;
02241 }
02242 }
02243 }
02244
02245
02246 j++;
02247 if (j == cReaders)
02248 {
02249
02250 j = 0;
02251
02252
02253
02254
02255 if (dwBreakFlag == 1)
02256 break;
02257
02258 if (BLOCK_STATUS_BLOCKING
02259 != psContextMap[dwContextIndex].contextBlockStatus)
02260 break;
02261
02262
02263 dwTime = WaitForPcscdEvent(hContext, dwTime);
02264
02265 if (dwTimeout != INFINITE)
02266 {
02267
02268
02269
02270 if (dwTime <= 0)
02271 {
02272 rv = SCARD_E_TIMEOUT;
02273 goto end;
02274 }
02275 }
02276 }
02277 }
02278 while (1);
02279
02280 if (psContextMap[dwContextIndex].contextBlockStatus != BLOCK_STATUS_BLOCKING)
02281 rv = SCARD_E_CANCELLED;
02282
02283 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
02284
02285 end:
02286 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02287
02288 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02289
02290 PROFILE_END(rv)
02291
02292 return rv;
02293 }
02294
02346 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02347 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02348 LPDWORD lpBytesReturned)
02349 {
02350 LONG rv;
02351 control_struct scControlStruct;
02352 sharedSegmentMsg msgStruct;
02353 int i;
02354 DWORD dwContextIndex, dwChannelIndex;
02355
02356 PROFILE_START
02357
02358
02359 if (NULL != lpBytesReturned)
02360 *lpBytesReturned = 0;
02361
02362 rv = SCardCheckDaemonAvailability();
02363 if (rv != SCARD_S_SUCCESS)
02364 return rv;
02365
02366
02367
02368
02369 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02370 if (rv == -1)
02371 return SCARD_E_INVALID_HANDLE;
02372
02373 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02374
02375
02376 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02377 if (rv == -1)
02378
02379
02380
02381 return SCARD_E_INVALID_HANDLE;
02382
02383 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02384 {
02385 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02386
02387
02388 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02389 break;
02390 }
02391
02392 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02393 {
02394 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02395 return SCARD_E_READER_UNAVAILABLE;
02396 }
02397
02398 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02399 || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02400 {
02401 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02402 return SCARD_E_INSUFFICIENT_BUFFER;
02403 }
02404
02405 if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
02406 {
02407
02408 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02409 control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
02410 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02411
02412 scControlStructExtended->hCard = hCard;
02413 scControlStructExtended->dwControlCode = dwControlCode;
02414 scControlStructExtended->cbSendLength = cbSendLength;
02415 scControlStructExtended->cbRecvLength = cbRecvLength;
02416 scControlStructExtended->pdwBytesReturned = 0;
02417 scControlStructExtended->rv = SCARD_S_SUCCESS;
02418
02419
02420
02421
02422 scControlStructExtended->size = sizeof(*scControlStructExtended)
02423 - (sizeof(control_struct_extended) - offsetof(control_struct_extended, data))
02424 + cbSendLength;
02425 memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
02426
02427 rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
02428 psContextMap[dwContextIndex].dwClientID,
02429 scControlStructExtended->size,
02430 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02431
02432 if (rv == -1)
02433 {
02434 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02435 return SCARD_E_NO_SERVICE;
02436 }
02437
02438
02439
02440
02441
02442 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg),
02443 psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02444 if (rv == -1)
02445 {
02446 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02447 return SCARD_F_COMM_ERROR;
02448 }
02449
02450
02451 scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
02452
02453
02454 if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02455 {
02456 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02457 scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02458 psContextMap[dwContextIndex].dwClientID,
02459 PCSCLITE_CLIENT_ATTEMPTS);
02460 if (rv == -1)
02461 {
02462 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02463 return SCARD_F_COMM_ERROR;
02464 }
02465 }
02466
02467 if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
02468 {
02469
02470
02471
02472 memcpy(pbRecvBuffer, scControlStructExtended -> data,
02473 scControlStructExtended -> pdwBytesReturned);
02474 memset(scControlStructExtended -> data, 0x00,
02475 scControlStructExtended -> pdwBytesReturned);
02476 }
02477
02478 if (NULL != lpBytesReturned)
02479 *lpBytesReturned = scControlStructExtended -> pdwBytesReturned;
02480
02481 rv = scControlStructExtended -> rv;
02482 }
02483 else
02484 {
02485 scControlStruct.hCard = hCard;
02486 scControlStruct.dwControlCode = dwControlCode;
02487 scControlStruct.cbSendLength = cbSendLength;
02488 scControlStruct.cbRecvLength = cbRecvLength;
02489 memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02490
02491 rv = WrapSHMWrite(SCARD_CONTROL,
02492 psContextMap[dwContextIndex].dwClientID,
02493 sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
02494
02495 if (rv == -1)
02496 {
02497 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02498 return SCARD_E_NO_SERVICE;
02499 }
02500
02501
02502
02503
02504 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02505 PCSCLITE_CLIENT_ATTEMPTS);
02506
02507 if (rv == -1)
02508 {
02509 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02510 return SCARD_F_COMM_ERROR;
02511 }
02512
02513 memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
02514
02515 if (NULL != lpBytesReturned)
02516 *lpBytesReturned = scControlStruct.dwBytesReturned;
02517
02518 if (scControlStruct.rv == SCARD_S_SUCCESS)
02519 {
02520
02521
02522
02523 memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
02524 scControlStruct.cbRecvLength);
02525 memset(scControlStruct.pbRecvBuffer, 0x00,
02526 sizeof(scControlStruct.pbRecvBuffer));
02527 }
02528
02529 rv = scControlStruct.rv;
02530 }
02531
02532 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02533
02534 PROFILE_END(rv)
02535
02536 return rv;
02537 }
02538
02638 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02639 LPDWORD pcbAttrLen)
02640 {
02641 LONG ret;
02642 unsigned char *buf = NULL;
02643
02644 PROFILE_START
02645
02646 if (NULL == pcbAttrLen)
02647 return SCARD_E_INVALID_PARAMETER;
02648
02649 if (SCARD_AUTOALLOCATE == *pcbAttrLen)
02650 {
02651 if (NULL == pbAttr)
02652 return SCARD_E_INVALID_PARAMETER;
02653
02654 *pcbAttrLen = MAX_BUFFER_SIZE;
02655 buf = malloc(*pcbAttrLen);
02656 if (NULL == buf)
02657 return SCARD_E_NO_MEMORY;
02658
02659 *(unsigned char **)pbAttr = buf;
02660 }
02661 else
02662 {
02663 buf = pbAttr;
02664
02665
02666 if (NULL == pbAttr)
02667
02668 *pcbAttrLen = MAX_BUFFER_SIZE;
02669 }
02670
02671 ret = SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, buf,
02672 pcbAttrLen);
02673
02674 PROFILE_END(ret)
02675
02676 return ret;
02677 }
02678
02713 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02714 DWORD cbAttrLen)
02715 {
02716 LONG ret;
02717
02718 PROFILE_START
02719
02720 if (NULL == pbAttr || 0 == cbAttrLen)
02721 return SCARD_E_INVALID_PARAMETER;
02722
02723 ret = SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02724 &cbAttrLen);
02725
02726 PROFILE_END(ret)
02727
02728 return ret;
02729 }
02730
02731 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02732 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02733 {
02734 LONG rv;
02735 getset_struct scGetSetStruct;
02736 sharedSegmentMsg msgStruct;
02737 int i;
02738 DWORD dwContextIndex, dwChannelIndex;
02739
02740 rv = SCardCheckDaemonAvailability();
02741 if (rv != SCARD_S_SUCCESS)
02742 return rv;
02743
02744
02745
02746
02747 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02748 if (rv == -1)
02749 return SCARD_E_INVALID_HANDLE;
02750
02751 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02752
02753
02754 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02755 if (rv == -1)
02756
02757
02758
02759 return SCARD_E_INVALID_HANDLE;
02760
02761 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02762 {
02763 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02764
02765
02766 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02767 break;
02768 }
02769
02770 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02771 {
02772 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02773 return SCARD_E_READER_UNAVAILABLE;
02774 }
02775
02776 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02777 {
02778 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02779 return SCARD_E_INSUFFICIENT_BUFFER;
02780 }
02781
02782 scGetSetStruct.hCard = hCard;
02783 scGetSetStruct.dwAttrId = dwAttrId;
02784 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02785 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02786 memset(scGetSetStruct.pbAttr, 0, sizeof(scGetSetStruct.pbAttr));
02787 if (SCARD_SET_ATTRIB == command)
02788 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02789
02790 rv = WrapSHMWrite(command,
02791 psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
02792 PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
02793
02794 if (rv == -1)
02795 {
02796 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02797 return SCARD_E_NO_SERVICE;
02798 }
02799
02800
02801
02802
02803 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02804 PCSCLITE_CLIENT_ATTEMPTS);
02805
02806 if (rv == -1)
02807 {
02808 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02809 return SCARD_F_COMM_ERROR;
02810 }
02811
02812 memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
02813
02814 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02815 {
02816
02817
02818
02819 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02820 {
02821 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02822 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02823 }
02824 else
02825 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02826
02827 if (pbAttr)
02828 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02829
02830 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02831 }
02832
02833 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02834
02835 return scGetSetStruct.rv;
02836 }
02837
02896 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02897 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02898 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02899 LPDWORD pcbRecvLength)
02900 {
02901 LONG rv;
02902 int i;
02903 DWORD dwContextIndex, dwChannelIndex;
02904
02905 PROFILE_START
02906
02907 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02908 pcbRecvLength == NULL || pioSendPci == NULL)
02909 return SCARD_E_INVALID_PARAMETER;
02910
02911 rv = SCardCheckDaemonAvailability();
02912 if (rv != SCARD_S_SUCCESS)
02913 return rv;
02914
02915
02916
02917
02918 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02919 if (rv == -1)
02920 {
02921 *pcbRecvLength = 0;
02922 return SCARD_E_INVALID_HANDLE;
02923 }
02924
02925 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02926
02927
02928 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02929 if (rv == -1)
02930
02931
02932
02933 return SCARD_E_INVALID_HANDLE;
02934
02935 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02936 {
02937 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02938
02939
02940 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02941 break;
02942 }
02943
02944 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02945 {
02946 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02947 return SCARD_E_READER_UNAVAILABLE;
02948 }
02949
02950 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02951 || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02952 {
02953 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02954 return SCARD_E_INSUFFICIENT_BUFFER;
02955 }
02956
02957 if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
02958 {
02959
02960 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02961 transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
02962 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02963
02964 scTransmitStructExtended->hCard = hCard;
02965 scTransmitStructExtended->cbSendLength = cbSendLength;
02966 scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
02967
02968
02969
02970
02971 scTransmitStructExtended->size = sizeof(*scTransmitStructExtended)
02972 - (sizeof(transmit_struct_extended) - offsetof(transmit_struct_extended, data))
02973 + cbSendLength;
02974 scTransmitStructExtended->pioSendPciProtocol = pioSendPci->dwProtocol;
02975 scTransmitStructExtended->pioSendPciLength = pioSendPci->cbPciLength;
02976 memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
02977 scTransmitStructExtended->rv = SCARD_S_SUCCESS;
02978
02979 if (pioRecvPci)
02980 {
02981 scTransmitStructExtended->pioRecvPciProtocol = pioRecvPci->dwProtocol;
02982 scTransmitStructExtended->pioRecvPciLength = pioRecvPci->cbPciLength;
02983 }
02984 else
02985 {
02986 scTransmitStructExtended->pioRecvPciProtocol = SCARD_PROTOCOL_ANY;
02987 scTransmitStructExtended->pioRecvPciLength = sizeof(SCARD_IO_REQUEST);
02988 }
02989
02990 rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
02991 psContextMap[dwContextIndex].dwClientID,
02992 scTransmitStructExtended->size,
02993 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02994
02995 if (rv == -1)
02996 {
02997 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02998 return SCARD_E_NO_SERVICE;
02999 }
03000
03001
03002
03003
03004
03005 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
03006 if (rv == -1)
03007 {
03008 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03009 return SCARD_F_COMM_ERROR;
03010 }
03011
03012
03013 scTransmitStructExtended = (transmit_struct_extended *)&(pmsgStruct -> data);
03014
03015
03016 if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
03017 {
03018 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
03019 scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
03020 psContextMap[dwContextIndex].dwClientID,
03021 PCSCLITE_CLIENT_ATTEMPTS);
03022 if (rv == -1)
03023 {
03024 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03025 return SCARD_F_COMM_ERROR;
03026 }
03027 }
03028
03029 if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
03030 {
03031
03032
03033
03034 memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
03035 scTransmitStructExtended -> pcbRecvLength);
03036 memset(scTransmitStructExtended -> data, 0x00,
03037 scTransmitStructExtended -> pcbRecvLength);
03038
03039 if (pioRecvPci)
03040 {
03041 pioRecvPci->dwProtocol = scTransmitStructExtended->pioRecvPciProtocol;
03042 pioRecvPci->cbPciLength = scTransmitStructExtended->pioRecvPciLength;
03043 }
03044 }
03045
03046 *pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
03047 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03048
03049 rv = scTransmitStructExtended -> rv;
03050 }
03051 else
03052 {
03053
03054 transmit_struct scTransmitStruct;
03055 sharedSegmentMsg msgStruct;
03056
03057 scTransmitStruct.hCard = hCard;
03058 scTransmitStruct.cbSendLength = cbSendLength;
03059 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
03060 scTransmitStruct.pioSendPciProtocol = pioSendPci->dwProtocol;
03061 scTransmitStruct.pioSendPciLength = pioSendPci->cbPciLength;
03062 memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
03063 memset(scTransmitStruct.pbSendBuffer+cbSendLength, 0, sizeof(scTransmitStruct.pbSendBuffer)-cbSendLength);
03064 memset(scTransmitStruct.pbRecvBuffer, 0, sizeof(scTransmitStruct.pbRecvBuffer));
03065 scTransmitStruct.rv = SCARD_S_SUCCESS;
03066
03067 if (pioRecvPci)
03068 {
03069 scTransmitStruct.pioRecvPciProtocol = pioRecvPci->dwProtocol;
03070 scTransmitStruct.pioRecvPciLength = pioRecvPci->cbPciLength;
03071 }
03072 else
03073 {
03074 scTransmitStruct.pioRecvPciProtocol = SCARD_PROTOCOL_ANY;
03075 scTransmitStruct.pioRecvPciLength = sizeof(SCARD_IO_REQUEST);
03076 }
03077
03078 rv = WrapSHMWrite(SCARD_TRANSMIT,
03079 psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
03080 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
03081
03082 if (rv == -1)
03083 {
03084 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03085 return SCARD_E_NO_SERVICE;
03086 }
03087
03088
03089
03090
03091 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
03092 PCSCLITE_CLIENT_ATTEMPTS);
03093
03094 memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
03095
03096 if (rv == -1)
03097 {
03098 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03099 return SCARD_F_COMM_ERROR;
03100 }
03101
03102
03103
03104
03105 memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
03106
03107 if (scTransmitStruct.rv == SCARD_S_SUCCESS)
03108 {
03109
03110
03111
03112 memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
03113 scTransmitStruct.pcbRecvLength);
03114 memset(scTransmitStruct.pbRecvBuffer, 0x00,
03115 scTransmitStruct.pcbRecvLength);
03116
03117 if (pioRecvPci)
03118 {
03119 pioRecvPci->dwProtocol = scTransmitStruct.pioRecvPciProtocol;
03120 pioRecvPci->cbPciLength = scTransmitStruct.pioRecvPciLength;
03121 }
03122 }
03123
03124 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
03125 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03126
03127 rv = scTransmitStruct.rv;
03128 }
03129
03130 PROFILE_END(rv)
03131
03132 return rv;
03133 }
03134
03183 LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
03184 LPSTR mszReaders, LPDWORD pcchReaders)
03185 {
03186 DWORD dwReadersLen;
03187 int i;
03188 LONG dwContextIndex;
03189 LONG rv = SCARD_S_SUCCESS;
03190 char *buf = NULL;
03191
03192 (void)mszGroups;
03193 PROFILE_START
03194
03195
03196
03197
03198 if (pcchReaders == NULL)
03199 return SCARD_E_INVALID_PARAMETER;
03200
03201 rv = SCardCheckDaemonAvailability();
03202 if (rv != SCARD_S_SUCCESS)
03203 return rv;
03204
03205
03206
03207
03208 dwContextIndex = SCardGetContextIndice(hContext);
03209 if (dwContextIndex == -1)
03210 return SCARD_E_INVALID_HANDLE;
03211
03212 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03213
03214
03215 dwContextIndex = SCardGetContextIndice(hContext);
03216 if (dwContextIndex == -1)
03217
03218
03219
03220 return SCARD_E_INVALID_HANDLE;
03221
03222 dwReadersLen = 0;
03223 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03224 if ((readerStates[i])->readerID != 0)
03225 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
03226
03227
03228 dwReadersLen += 1;
03229
03230 if (1 == dwReadersLen)
03231 {
03232 rv = SCARD_E_NO_READERS_AVAILABLE;
03233 goto end;
03234 }
03235
03236 if (SCARD_AUTOALLOCATE == *pcchReaders)
03237 {
03238 buf = malloc(dwReadersLen);
03239 if (NULL == buf)
03240 {
03241 rv = SCARD_E_NO_MEMORY;
03242 goto end;
03243 }
03244 if (NULL == mszReaders)
03245 {
03246 rv = SCARD_E_INVALID_PARAMETER;
03247 goto end;
03248 }
03249 *(char **)mszReaders = buf;
03250 }
03251 else
03252 {
03253 buf = mszReaders;
03254
03255
03256 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
03257 {
03258 rv = SCARD_E_INSUFFICIENT_BUFFER;
03259 goto end;
03260 }
03261 }
03262
03263 if (mszReaders == NULL)
03264 goto end;
03265
03266 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03267 {
03268 if ((readerStates[i])->readerID != 0)
03269 {
03270
03271
03272
03273 strcpy(buf, (readerStates[i])->readerName);
03274 buf += strlen((readerStates[i])->readerName)+1;
03275 }
03276 }
03277 *buf = '\0';
03278
03279 end:
03280
03281 *pcchReaders = dwReadersLen;
03282
03283 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03284
03285 PROFILE_END(rv)
03286
03287 return rv;
03288 }
03289
03302 LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
03303 {
03304 LONG rv = SCARD_S_SUCCESS;
03305 LONG dwContextIndex;
03306
03307 PROFILE_START
03308
03309 rv = SCardCheckDaemonAvailability();
03310 if (rv != SCARD_S_SUCCESS)
03311 return rv;
03312
03313
03314
03315
03316 dwContextIndex = SCardGetContextIndice(hContext);
03317 if (dwContextIndex == -1)
03318 return SCARD_E_INVALID_HANDLE;
03319
03320 free((void *)pvMem);
03321
03322 PROFILE_END(rv)
03323
03324 return rv;
03325 }
03326
03376 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
03377 LPDWORD pcchGroups)
03378 {
03379 LONG rv = SCARD_S_SUCCESS;
03380 LONG dwContextIndex;
03381 char *buf = NULL;
03382
03383 PROFILE_START
03384
03385
03386 const char ReaderGroup[] = "SCard$DefaultReaders\0";
03387 const int dwGroups = sizeof(ReaderGroup);
03388
03389 rv = SCardCheckDaemonAvailability();
03390 if (rv != SCARD_S_SUCCESS)
03391 return rv;
03392
03393
03394
03395
03396 dwContextIndex = SCardGetContextIndice(hContext);
03397 if (dwContextIndex == -1)
03398 return SCARD_E_INVALID_HANDLE;
03399
03400 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03401
03402
03403 dwContextIndex = SCardGetContextIndice(hContext);
03404 if (dwContextIndex == -1)
03405
03406
03407
03408 return SCARD_E_INVALID_HANDLE;
03409
03410 if (SCARD_AUTOALLOCATE == *pcchGroups)
03411 {
03412 buf = malloc(dwGroups);
03413 if (NULL == buf)
03414 {
03415 rv = SCARD_E_NO_MEMORY;
03416 goto end;
03417 }
03418 if (NULL == mszGroups)
03419 {
03420 rv = SCARD_E_INVALID_PARAMETER;
03421 goto end;
03422 }
03423 *(char **)mszGroups = buf;
03424 }
03425 else
03426 {
03427 buf = mszGroups;
03428
03429 if ((NULL != mszGroups) && (*pcchGroups < dwGroups))
03430 {
03431 rv = SCARD_E_INSUFFICIENT_BUFFER;
03432 goto end;
03433 }
03434 }
03435
03436 if (buf)
03437 memcpy(buf, ReaderGroup, dwGroups);
03438
03439 end:
03440 *pcchGroups = dwGroups;
03441
03442 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03443
03444 PROFILE_END(rv)
03445
03446 return rv;
03447 }
03448
03476 LONG SCardCancel(SCARDCONTEXT hContext)
03477 {
03478 LONG dwContextIndex;
03479 LONG rv = SCARD_S_SUCCESS;
03480
03481 PROFILE_START
03482
03483 dwContextIndex = SCardGetContextIndice(hContext);
03484 if (dwContextIndex == -1)
03485 return SCARD_E_INVALID_HANDLE;
03486
03487
03488
03489
03490
03491 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_CANCEL;
03492
03493 if (StatSynchronizeContext(hContext))
03494 rv = SCARD_F_INTERNAL_ERROR;
03495
03496 PROFILE_END(rv)
03497
03498 return rv;
03499 }
03500
03524 LONG SCardIsValidContext(SCARDCONTEXT hContext)
03525 {
03526 LONG rv;
03527 LONG dwContextIndex;
03528
03529 PROFILE_START
03530
03531 rv = SCARD_S_SUCCESS;
03532
03533
03534 rv = SCardCheckDaemonAvailability();
03535 if (rv != SCARD_S_SUCCESS)
03536 return rv;
03537
03538
03539
03540
03541 dwContextIndex = SCardGetContextIndice(hContext);
03542 if (dwContextIndex == -1)
03543 rv = SCARD_E_INVALID_HANDLE;
03544
03545 PROFILE_END(rv)
03546
03547 return rv;
03548 }
03549
03566 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
03567 {
03568 int i;
03569
03570 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03571 {
03572 if (psContextMap[i].hContext == 0)
03573 {
03574 psContextMap[i].hContext = hContext;
03575 psContextMap[i].dwClientID = dwClientID;
03576 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
03577 psContextMap[i].mMutex = malloc(sizeof(PCSCLITE_MUTEX));
03578 (void)SYS_MutexInit(psContextMap[i].mMutex);
03579 return SCARD_S_SUCCESS;
03580 }
03581 }
03582
03583 return SCARD_E_NO_MEMORY;
03584 }
03585
03598 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
03599 {
03600 LONG rv;
03601
03602 (void)SCardLockThread();
03603 rv = SCardGetContextIndiceTH(hContext);
03604 (void)SCardUnlockThread();
03605
03606 return rv;
03607 }
03608
03621 static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
03622 {
03623 int i;
03624
03625
03626
03627
03628 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03629 {
03630 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
03631 return i;
03632 }
03633
03634 return -1;
03635 }
03636
03646 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
03647 {
03648 LONG retIndice;
03649
03650 retIndice = SCardGetContextIndiceTH(hContext);
03651
03652 if (retIndice == -1)
03653 return SCARD_E_INVALID_HANDLE;
03654 else
03655 return SCardCleanContext(retIndice);
03656 }
03657
03658 static LONG SCardCleanContext(LONG indice)
03659 {
03660 int i;
03661
03662 psContextMap[indice].hContext = 0;
03663 (void)SHMClientCloseSession(psContextMap[indice].dwClientID);
03664 psContextMap[indice].dwClientID = 0;
03665 free(psContextMap[indice].mMutex);
03666 psContextMap[indice].mMutex = NULL;
03667 psContextMap[indice].contextBlockStatus = BLOCK_STATUS_RESUME;
03668
03669 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03670 {
03671
03672
03673
03674 psContextMap[indice].psChannelMap[i].hCard = 0;
03675 free(psContextMap[indice].psChannelMap[i].readerName);
03676 psContextMap[indice].psChannelMap[i].readerName = NULL;
03677 }
03678
03679 return SCARD_S_SUCCESS;
03680 }
03681
03682
03683
03684
03685
03686 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
03687 LPCSTR readerName)
03688 {
03689 int i;
03690
03691 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03692 {
03693 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
03694 {
03695 psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
03696 psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
03697 return SCARD_S_SUCCESS;
03698 }
03699 }
03700
03701 return SCARD_E_NO_MEMORY;
03702 }
03703
03704 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03705 {
03706 DWORD dwContextIndice, dwChannelIndice;
03707 LONG rv;
03708
03709 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
03710 if (rv == -1)
03711 return SCARD_E_INVALID_HANDLE;
03712 else
03713 {
03714 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
03715 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
03716 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
03717 return SCARD_S_SUCCESS;
03718 }
03719 }
03720
03721 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard,
03722 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03723 {
03724 LONG rv;
03725
03726 if (0 == hCard)
03727 return -1;
03728
03729 (void)SCardLockThread();
03730 rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
03731 (void)SCardUnlockThread();
03732
03733 return rv;
03734 }
03735
03736 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard,
03737 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03738 {
03739 int i;
03740
03741 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03742 {
03743 if (psContextMap[i].hContext != 0)
03744 {
03745 int j;
03746
03747 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
03748 {
03749 if (psContextMap[i].psChannelMap[j].hCard == hCard)
03750 {
03751 *pdwContextIndice = i;
03752 *pdwChannelIndice = j;
03753 return SCARD_S_SUCCESS;
03754 }
03755 }
03756
03757 }
03758 }
03759
03760 return -1;
03761 }
03762
03771 LONG SCardCheckDaemonAvailability(void)
03772 {
03773 LONG rv;
03774 struct stat statBuffer;
03775 int need_restart = 0;
03776
03777 rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &statBuffer);
03778
03779 if (rv != 0)
03780 {
03781 Log2(PCSC_LOG_INFO, "PCSC Not Running: " PCSCLITE_PUBSHM_FILE ": %s",
03782 strerror(errno));
03783 return SCARD_E_NO_SERVICE;
03784 }
03785
03786
03787
03788 if (daemon_ctime && statBuffer.st_ctime > daemon_ctime)
03789 {
03790
03791 if (GetDaemonPid() != daemon_pid)
03792 {
03793 Log1(PCSC_LOG_INFO, "PCSC restarted");
03794 need_restart = 1;
03795 }
03796 }
03797
03798
03799 if (client_pid && client_pid != getpid())
03800 {
03801 Log1(PCSC_LOG_INFO, "Client forked");
03802 need_restart = 1;
03803 }
03804
03805 if (need_restart)
03806 {
03807 int i;
03808
03809
03810 (void)SCardLockThread();
03811
03812 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03813 if (psContextMap[i].hContext)
03814 (void)SCardCleanContext(i);
03815
03816 (void)SCardUnlockThread();
03817
03818
03819 daemon_ctime = 0;
03820 client_pid = 0;
03821
03822
03823 SCardUnload();
03824
03825 return SCARD_E_INVALID_HANDLE;
03826 }
03827
03828 daemon_ctime = statBuffer.st_ctime;
03829 daemon_pid = GetDaemonPid();
03830 client_pid = getpid();
03831
03832 return SCARD_S_SUCCESS;
03833 }
03834
03841 #ifdef __SUNPRO_C
03842 #pragma fini (SCardUnload)
03843 #endif
03844
03845 void DESTRUCTOR SCardUnload(void)
03846 {
03847 int i;
03848
03849 if (!isExecuted)
03850 return;
03851
03852
03853 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03854 {
03855 if (readerStates[i] != NULL)
03856 {
03857 SYS_PublicMemoryUnmap(readerStates[i], sizeof(READER_STATE));
03858 readerStates[i] = NULL;
03859 }
03860 }
03861
03862 (void)SYS_CloseFile(mapAddr);
03863 isExecuted = 0;
03864 }
03865