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
00031 #include "misc.h"
00032 #include "pcscd.h"
00033 #include "winscard.h"
00034 #include "debug.h"
00035 #include "thread_generic.h"
00036 #include "strlcpycat.h"
00037
00038 #include "readerfactory.h"
00039 #include "eventhandler.h"
00040 #include "sys_generic.h"
00041 #include "winscard_msg.h"
00042 #include "utils.h"
00043
00045 #define SCARD_PROTOCOL_ANY_OLD 0x1000
00046
00047 #ifndef TRUE
00048 #define TRUE 1
00049 #define FALSE 0
00050 #endif
00051
00052 #undef DO_PROFILE
00053 #ifdef DO_PROFILE
00054
00055 #define PROFILE_FILE "/tmp/pcsc_profile"
00056 #include <stdio.h>
00057 #include <sys/time.h>
00058
00059 struct timeval profile_time_start;
00060 FILE *fd;
00061 char profile_tty;
00062 char fct_name[100];
00063
00064 #define PROFILE_START profile_start(__FUNCTION__);
00065 #define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
00066
00067 static void profile_start(const char *f)
00068 {
00069 static char initialized = FALSE;
00070
00071 if (!initialized)
00072 {
00073 char filename[80];
00074
00075 initialized = TRUE;
00076 sprintf(filename, "%s-%d", PROFILE_FILE, getuid());
00077 fd = fopen(filename, "a+");
00078 if (NULL == fd)
00079 {
00080 fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n",
00081 PROFILE_FILE, strerror(errno));
00082 exit(-1);
00083 }
00084 fprintf(fd, "\nStart a new profile\n");
00085
00086 if (isatty(fileno(stderr)))
00087 profile_tty = TRUE;
00088 else
00089 profile_tty = FALSE;
00090 }
00091
00092
00093 if (profile_tty && fct_name[0])
00094 printf("\33[01;34m WARNING: %s starts before %s finishes\33[0m\n",
00095 f, fct_name);
00096
00097 strlcpy(fct_name, f, sizeof(fct_name));
00098
00099 gettimeofday(&profile_time_start, NULL);
00100 }
00101
00102
00103 static long int time_sub(struct timeval *a, struct timeval *b)
00104 {
00105 struct timeval r;
00106 r.tv_sec = a -> tv_sec - b -> tv_sec;
00107 r.tv_usec = a -> tv_usec - b -> tv_usec;
00108 if (r.tv_usec < 0)
00109 {
00110 r.tv_sec--;
00111 r.tv_usec += 1000000;
00112 }
00113
00114 return r.tv_sec * 1000000 + r.tv_usec;
00115 }
00116
00117
00118 static void profile_end(const char *f, LONG rv)
00119 {
00120 struct timeval profile_time_end;
00121 long d;
00122
00123 gettimeofday(&profile_time_end, NULL);
00124 d = time_sub(&profile_time_end, &profile_time_start);
00125
00126 if (profile_tty)
00127 {
00128 if (fct_name[0])
00129 {
00130 if (strncmp(fct_name, f, sizeof(fct_name)))
00131 printf("\33[01;34m WARNING: %s ends before %s\33[0m\n",
00132 f, fct_name);
00133 }
00134 else
00135 printf("\33[01;34m WARNING: %s ends but we lost its start\33[0m\n",
00136 f);
00137
00138
00139 fct_name[0] = '\0';
00140
00141 if (rv != SCARD_S_SUCCESS)
00142 fprintf(stderr,
00143 "\33[01;31mRESULT %s \33[35m%ld \33[34m0x%08lX %s\33[0m\n",
00144 f, d, rv, pcsc_stringify_error(rv));
00145 else
00146 fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m\n", f, d);
00147 }
00148 fprintf(fd, "%s %ld\n", f, d);
00149 fflush(fd);
00150 }
00151
00152 #else
00153 #define PROFILE_START
00154 #define PROFILE_END(rv)
00155 #endif
00156
00161 struct _psChannelMap
00162 {
00163 SCARDHANDLE hCard;
00164 LPSTR readerName;
00165 };
00166
00167 typedef struct _psChannelMap CHANNEL_MAP, *PCHANNEL_MAP;
00168
00174 static struct _psContextMap
00175 {
00176 DWORD dwClientID;
00177 SCARDCONTEXT hContext;
00178 DWORD contextBlockStatus;
00179 PCSCLITE_MUTEX_T mMutex;
00180 CHANNEL_MAP psChannelMap[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
00181 } psContextMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
00182
00186 static short isExecuted = 0;
00187
00188
00192 static time_t daemon_ctime = 0;
00193 static pid_t daemon_pid = 0;
00198 static pid_t client_pid = 0;
00199
00205 static int mapAddr = 0;
00206
00211 static PCSCLITE_MUTEX clientMutex = PTHREAD_MUTEX_INITIALIZER;
00212
00219 static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
00220
00221 PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
00222 PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
00223 PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
00224
00225
00226 static LONG SCardAddContext(SCARDCONTEXT, DWORD);
00227 static LONG SCardGetContextIndice(SCARDCONTEXT);
00228 static LONG SCardGetContextIndiceTH(SCARDCONTEXT);
00229 static LONG SCardRemoveContext(SCARDCONTEXT);
00230 static LONG SCardCleanContext(LONG indice);
00231
00232 static LONG SCardAddHandle(SCARDHANDLE, DWORD, LPCSTR);
00233 static LONG SCardGetIndicesFromHandle(SCARDHANDLE, PDWORD, PDWORD);
00234 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE, PDWORD, PDWORD);
00235 static LONG SCardRemoveHandle(SCARDHANDLE);
00236
00237 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
00238 LPBYTE pbAttr, LPDWORD pcbAttrLen);
00239
00240 void DESTRUCTOR SCardUnload(void);
00241
00242
00243
00244
00251 inline static LONG SCardLockThread(void)
00252 {
00253 return SYS_MutexLock(&clientMutex);
00254 }
00255
00261 inline static LONG SCardUnlockThread(void)
00262 {
00263 return SYS_MutexUnLock(&clientMutex);
00264 }
00265
00266 static LONG SCardEstablishContextTH(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
00267
00302 LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
00303 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00304 {
00305 LONG rv;
00306
00307 PROFILE_START
00308
00309
00310 rv = SCardCheckDaemonAvailability();
00311 if (SCARD_E_INVALID_HANDLE == rv)
00312
00313 rv = SCardCheckDaemonAvailability();
00314
00315 if (rv != SCARD_S_SUCCESS)
00316 return rv;
00317
00318 SCardLockThread();
00319 rv = SCardEstablishContextTH(dwScope, pvReserved1,
00320 pvReserved2, phContext);
00321 SCardUnlockThread();
00322
00323 PROFILE_END(rv)
00324
00325 return rv;
00326 }
00327
00354 static LONG SCardEstablishContextTH(DWORD dwScope, LPCVOID pvReserved1,
00355 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00356 {
00357 LONG rv;
00358 int i;
00359 establish_struct scEstablishStruct;
00360 sharedSegmentMsg msgStruct;
00361 uint32_t dwClientID = 0;
00362
00363 if (phContext == NULL)
00364 return SCARD_E_INVALID_PARAMETER;
00365 else
00366 *phContext = 0;
00367
00368
00369
00370
00371
00372
00373
00374
00375 if (isExecuted == 0)
00376 {
00377 int pageSize;
00378
00379
00380
00381
00382 SYS_Initialize();
00383
00384
00385
00386
00387 mapAddr = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDONLY, 0);
00388 if (mapAddr < 0)
00389 {
00390 Log3(PCSC_LOG_CRITICAL, "Cannot open public shared file %s: %s",
00391 PCSCLITE_PUBSHM_FILE, strerror(errno));
00392 return SCARD_E_NO_SERVICE;
00393 }
00394
00395
00396
00397
00398 fcntl(mapAddr, F_SETFD, FD_CLOEXEC);
00399
00400 pageSize = SYS_GetPageSize();
00401
00402
00403
00404
00405 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00406 {
00407 readerStates[i] =
00408 (PREADER_STATE)SYS_PublicMemoryMap(sizeof(READER_STATE),
00409 mapAddr, (i * pageSize));
00410 if (readerStates[i] == NULL)
00411 {
00412 Log2(PCSC_LOG_CRITICAL, "Cannot public memory map: %s",
00413 strerror(errno));
00414 SYS_CloseFile(mapAddr);
00415 return SCARD_F_INTERNAL_ERROR;
00416 }
00417 }
00418
00419
00420
00421
00422 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00423 {
00424 int j;
00425
00426
00427
00428
00429 psContextMap[i].dwClientID = 0;
00430 psContextMap[i].hContext = 0;
00431 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
00432 psContextMap[i].mMutex = NULL;
00433
00434 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
00435 {
00436
00437
00438
00439 psContextMap[i].psChannelMap[j].hCard = 0;
00440 psContextMap[i].psChannelMap[j].readerName = NULL;
00441 }
00442 }
00443
00444 }
00445
00446
00447
00448
00449
00450 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00451 {
00452 if (psContextMap[i].dwClientID == 0)
00453 break;
00454 }
00455
00456 if (i == PCSCLITE_MAX_APPLICATION_CONTEXTS)
00457 {
00458 return SCARD_E_NO_MEMORY;
00459 }
00460
00461
00462 if (SHMClientSetupSession(&dwClientID) != 0)
00463 {
00464 SYS_CloseFile(mapAddr);
00465 return SCARD_E_NO_SERVICE;
00466 }
00467
00468 {
00469 version_struct *veStr;
00470
00471 memset(&msgStruct, 0, sizeof(msgStruct));
00472 msgStruct.mtype = CMD_VERSION;
00473 msgStruct.user_id = SYS_GetUID();
00474 msgStruct.group_id = SYS_GetGID();
00475 msgStruct.command = 0;
00476 msgStruct.date = time(NULL);
00477
00478 veStr = (version_struct *) msgStruct.data;
00479 veStr->major = PROTOCOL_VERSION_MAJOR;
00480 veStr->minor = PROTOCOL_VERSION_MINOR;
00481
00482 if (-1 == SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
00483 PCSCLITE_MCLIENT_ATTEMPTS))
00484 return SCARD_E_NO_SERVICE;
00485
00486
00487
00488
00489 if (-1 == SHMMessageReceive(&msgStruct, sizeof(msgStruct), dwClientID,
00490 PCSCLITE_CLIENT_ATTEMPTS))
00491 {
00492 Log1(PCSC_LOG_CRITICAL, "Your pcscd is too old and does not support CMD_VERSION");
00493 return SCARD_F_COMM_ERROR;
00494 }
00495
00496 Log3(PCSC_LOG_INFO, "Server is protocol version %d:%d",
00497 veStr->major, veStr->minor);
00498
00499 if (veStr->rv != SCARD_S_SUCCESS)
00500 return veStr->rv;
00501
00502 isExecuted = 1;
00503 }
00504
00505
00506
00507
00508
00509 scEstablishStruct.dwScope = dwScope;
00510 scEstablishStruct.phContext = 0;
00511 scEstablishStruct.rv = SCARD_S_SUCCESS;
00512
00513 rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
00514 sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
00515 (void *) &scEstablishStruct);
00516
00517 if (rv == -1)
00518 return SCARD_E_NO_SERVICE;
00519
00520
00521
00522
00523 rv = SHMClientRead(&msgStruct, dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00524
00525 if (rv == -1)
00526 return SCARD_F_COMM_ERROR;
00527
00528 memcpy(&scEstablishStruct, &msgStruct.data, sizeof(scEstablishStruct));
00529
00530 if (scEstablishStruct.rv != SCARD_S_SUCCESS)
00531 return scEstablishStruct.rv;
00532
00533 *phContext = scEstablishStruct.phContext;
00534
00535
00536
00537
00538 rv = SCardAddContext(*phContext, dwClientID);
00539
00540 return rv;
00541 }
00542
00565 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00566 {
00567 LONG rv;
00568 release_struct scReleaseStruct;
00569 sharedSegmentMsg msgStruct;
00570 LONG dwContextIndex;
00571
00572 PROFILE_START
00573
00574
00575
00576
00577
00578 dwContextIndex = SCardGetContextIndice(hContext);
00579 if (dwContextIndex == -1)
00580 return SCARD_E_INVALID_HANDLE;
00581
00582 rv = SCardCheckDaemonAvailability();
00583 if (rv != SCARD_S_SUCCESS)
00584 {
00585
00586
00587
00588 SCardLockThread();
00589 SCardRemoveContext(hContext);
00590 SCardUnlockThread();
00591
00592 return rv;
00593 }
00594
00595 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00596
00597
00598 dwContextIndex = SCardGetContextIndice(hContext);
00599 if (dwContextIndex == -1)
00600
00601
00602
00603 return SCARD_E_INVALID_HANDLE;
00604
00605 scReleaseStruct.hContext = hContext;
00606 scReleaseStruct.rv = SCARD_S_SUCCESS;
00607
00608 rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT,
00609 psContextMap[dwContextIndex].dwClientID,
00610 sizeof(scReleaseStruct),
00611 PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);
00612
00613 if (rv == -1)
00614 {
00615 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00616 return SCARD_E_NO_SERVICE;
00617 }
00618
00619
00620
00621
00622 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00623 PCSCLITE_CLIENT_ATTEMPTS);
00624 memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));
00625
00626 if (rv == -1)
00627 {
00628 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00629 return SCARD_F_COMM_ERROR;
00630 }
00631
00632 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00633
00634
00635
00636
00637 SCardLockThread();
00638 SCardRemoveContext(hContext);
00639 SCardUnlockThread();
00640
00641 PROFILE_END(scReleaseStruct.rv)
00642
00643 return scReleaseStruct.rv;
00644 }
00645
00659 LONG SCardSetTimeout(SCARDCONTEXT hContext, DWORD dwTimeout)
00660 {
00661
00662
00663
00664
00665 return SCARD_S_SUCCESS;
00666 }
00667
00720 LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,
00721 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00722 LPDWORD pdwActiveProtocol)
00723 {
00724 LONG rv;
00725 connect_struct scConnectStruct;
00726 sharedSegmentMsg msgStruct;
00727 LONG dwContextIndex;
00728
00729 PROFILE_START
00730
00731
00732
00733
00734 if (phCard == NULL || pdwActiveProtocol == NULL)
00735 return SCARD_E_INVALID_PARAMETER;
00736 else
00737 *phCard = 0;
00738
00739 if (szReader == NULL)
00740 return SCARD_E_UNKNOWN_READER;
00741
00742
00743
00744
00745 if (strlen(szReader) > MAX_READERNAME)
00746 return SCARD_E_INVALID_VALUE;
00747
00748 rv = SCardCheckDaemonAvailability();
00749 if (rv != SCARD_S_SUCCESS)
00750 return rv;
00751
00752
00753
00754
00755 dwContextIndex = SCardGetContextIndice(hContext);
00756 if (dwContextIndex == -1)
00757 return SCARD_E_INVALID_HANDLE;
00758
00759 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00760
00761
00762 dwContextIndex = SCardGetContextIndice(hContext);
00763 if (dwContextIndex == -1)
00764
00765
00766
00767 return SCARD_E_INVALID_HANDLE;
00768
00769 strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);
00770
00771 scConnectStruct.hContext = hContext;
00772 scConnectStruct.dwShareMode = dwShareMode;
00773 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00774 scConnectStruct.phCard = 0;
00775 scConnectStruct.pdwActiveProtocol = 0;
00776 scConnectStruct.rv = SCARD_S_SUCCESS;
00777
00778 rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
00779 sizeof(scConnectStruct),
00780 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);
00781
00782 if (rv == -1)
00783 {
00784 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00785 return SCARD_E_NO_SERVICE;
00786 }
00787
00788
00789
00790
00791 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00792 PCSCLITE_CLIENT_ATTEMPTS);
00793
00794 memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));
00795
00796 if (rv == -1)
00797 {
00798 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00799 return SCARD_F_COMM_ERROR;
00800 }
00801
00802 *phCard = scConnectStruct.phCard;
00803 *pdwActiveProtocol = scConnectStruct.pdwActiveProtocol;
00804
00805 if (scConnectStruct.rv == SCARD_S_SUCCESS)
00806 {
00807
00808
00809
00810 rv = SCardAddHandle(*phCard, dwContextIndex, szReader);
00811 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00812
00813 PROFILE_END(rv)
00814
00815 return rv;
00816 }
00817
00818 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00819
00820 PROFILE_END(scConnectStruct.rv)
00821
00822 return scConnectStruct.rv;
00823 }
00824
00890 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00891 DWORD dwPreferredProtocols, DWORD dwInitialization,
00892 LPDWORD pdwActiveProtocol)
00893 {
00894 LONG rv;
00895 reconnect_struct scReconnectStruct;
00896 sharedSegmentMsg msgStruct;
00897 int i;
00898 DWORD dwContextIndex, dwChannelIndex;
00899
00900 PROFILE_START
00901
00902 if (pdwActiveProtocol == NULL)
00903 return SCARD_E_INVALID_PARAMETER;
00904
00905 rv = SCardCheckDaemonAvailability();
00906 if (rv != SCARD_S_SUCCESS)
00907 return rv;
00908
00909
00910
00911
00912 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00913 if (rv == -1)
00914 return SCARD_E_INVALID_HANDLE;
00915
00916 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00917
00918
00919 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00920 if (rv == -1)
00921
00922
00923
00924 return SCARD_E_INVALID_HANDLE;
00925
00926 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00927 {
00928 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
00929
00930
00931 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
00932 break;
00933 }
00934
00935 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00936 {
00937 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00938 return SCARD_E_READER_UNAVAILABLE;
00939 }
00940
00941 do
00942 {
00943 scReconnectStruct.hCard = hCard;
00944 scReconnectStruct.dwShareMode = dwShareMode;
00945 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00946 scReconnectStruct.dwInitialization = dwInitialization;
00947 scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00948 scReconnectStruct.rv = SCARD_S_SUCCESS;
00949
00950 rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
00951 sizeof(scReconnectStruct),
00952 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
00953
00954 if (rv == -1)
00955 {
00956 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00957 return SCARD_E_NO_SERVICE;
00958 }
00959
00960
00961
00962
00963 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
00964 PCSCLITE_CLIENT_ATTEMPTS);
00965
00966 memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
00967
00968 if (rv == -1)
00969 {
00970 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00971 return SCARD_F_COMM_ERROR;
00972 }
00973 } while (SCARD_E_SHARING_VIOLATION == scReconnectStruct.rv);
00974
00975 *pdwActiveProtocol = scReconnectStruct.pdwActiveProtocol;
00976
00977 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00978
00979 PROFILE_END(scReconnectStruct.rv)
00980
00981 return scReconnectStruct.rv;
00982 }
00983
01015 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
01016 {
01017 LONG rv;
01018 disconnect_struct scDisconnectStruct;
01019 sharedSegmentMsg msgStruct;
01020 DWORD dwContextIndex, dwChannelIndex;
01021
01022 PROFILE_START
01023
01024 rv = SCardCheckDaemonAvailability();
01025 if (rv != SCARD_S_SUCCESS)
01026 return rv;
01027
01028
01029
01030
01031 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01032 if (rv == -1)
01033 return SCARD_E_INVALID_HANDLE;
01034
01035 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01036
01037
01038 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01039 if (rv == -1)
01040
01041
01042
01043 return SCARD_E_INVALID_HANDLE;
01044
01045 scDisconnectStruct.hCard = hCard;
01046 scDisconnectStruct.dwDisposition = dwDisposition;
01047 scDisconnectStruct.rv = SCARD_S_SUCCESS;
01048
01049 rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
01050 sizeof(scDisconnectStruct),
01051 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
01052
01053 if (rv == -1)
01054 {
01055 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01056 return SCARD_E_NO_SERVICE;
01057 }
01058
01059
01060
01061
01062 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01063 PCSCLITE_CLIENT_ATTEMPTS);
01064
01065 memcpy(&scDisconnectStruct, &msgStruct.data,
01066 sizeof(scDisconnectStruct));
01067
01068 if (rv == -1)
01069 {
01070 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01071 return SCARD_F_COMM_ERROR;
01072 }
01073
01074 SCardRemoveHandle(hCard);
01075
01076 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01077
01078 PROFILE_END(scDisconnectStruct.rv)
01079
01080 return scDisconnectStruct.rv;
01081 }
01082
01118 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01119 {
01120
01121 LONG rv;
01122 begin_struct scBeginStruct;
01123 int i;
01124 sharedSegmentMsg msgStruct;
01125 DWORD dwContextIndex, dwChannelIndex;
01126
01127 PROFILE_START
01128
01129 rv = SCardCheckDaemonAvailability();
01130 if (rv != SCARD_S_SUCCESS)
01131 return rv;
01132
01133
01134
01135
01136 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01137 if (rv == -1)
01138 return SCARD_E_INVALID_HANDLE;
01139
01140 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01141
01142
01143 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01144 if (rv == -1)
01145
01146
01147
01148 return SCARD_E_INVALID_HANDLE;
01149
01150 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01151 {
01152 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01153
01154
01155 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01156 break;
01157 }
01158
01159 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01160 {
01161 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01162 return SCARD_E_READER_UNAVAILABLE;
01163 }
01164
01165 scBeginStruct.hCard = hCard;
01166 scBeginStruct.rv = SCARD_S_SUCCESS;
01167
01168
01169
01170
01171
01172
01173 do
01174 {
01175 rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01176 sizeof(scBeginStruct),
01177 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);
01178
01179 if (rv == -1)
01180 {
01181
01182 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01183 return SCARD_E_NO_SERVICE;
01184 }
01185
01186
01187
01188
01189 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01190 PCSCLITE_CLIENT_ATTEMPTS);
01191
01192 memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));
01193
01194 if (rv == -1)
01195 {
01196
01197 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01198 return SCARD_F_COMM_ERROR;
01199 }
01200
01201 }
01202 while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
01203
01204 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01205
01206 PROFILE_END(scBeginStruct.rv);
01207
01208 return scBeginStruct.rv;
01209 }
01210
01251 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01252 {
01253 LONG rv;
01254 end_struct scEndStruct;
01255 sharedSegmentMsg msgStruct;
01256 int randnum, i;
01257 DWORD dwContextIndex, dwChannelIndex;
01258
01259 PROFILE_START
01260
01261
01262
01263
01264 randnum = 0;
01265
01266 rv = SCardCheckDaemonAvailability();
01267 if (rv != SCARD_S_SUCCESS)
01268 return rv;
01269
01270
01271
01272
01273 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01274 if (rv == -1)
01275 return SCARD_E_INVALID_HANDLE;
01276
01277 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01278
01279
01280 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01281 if (rv == -1)
01282
01283
01284
01285 return SCARD_E_INVALID_HANDLE;
01286
01287 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01288 {
01289 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01290
01291
01292 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01293 break;
01294 }
01295
01296 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01297 {
01298 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01299 return SCARD_E_READER_UNAVAILABLE;
01300 }
01301
01302 scEndStruct.hCard = hCard;
01303 scEndStruct.dwDisposition = dwDisposition;
01304 scEndStruct.rv = SCARD_S_SUCCESS;
01305
01306 rv = WrapSHMWrite(SCARD_END_TRANSACTION,
01307 psContextMap[dwContextIndex].dwClientID,
01308 sizeof(scEndStruct),
01309 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
01310
01311 if (rv == -1)
01312 {
01313 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01314 return SCARD_E_NO_SERVICE;
01315 }
01316
01317
01318
01319
01320 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01321 PCSCLITE_CLIENT_ATTEMPTS);
01322
01323 memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
01324
01325 if (rv == -1)
01326 {
01327 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01328 return SCARD_F_COMM_ERROR;
01329 }
01330
01331
01332
01333
01334 randnum = SYS_RandomInt(1000, 10000);
01335 SYS_USleep(randnum);
01336
01337 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01338
01339 PROFILE_END(scEndStruct.rv)
01340
01341 return scEndStruct.rv;
01342 }
01343
01350 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01351 {
01352 LONG rv;
01353 cancel_struct scCancelStruct;
01354 sharedSegmentMsg msgStruct;
01355 int i;
01356 DWORD dwContextIndex, dwChannelIndex;
01357
01358 PROFILE_START
01359
01360 rv = SCardCheckDaemonAvailability();
01361 if (rv != SCARD_S_SUCCESS)
01362 return rv;
01363
01364
01365
01366
01367 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01368 if (rv == -1)
01369 return SCARD_E_INVALID_HANDLE;
01370
01371 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01372
01373
01374 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01375 if (rv == -1)
01376
01377
01378
01379 return SCARD_E_INVALID_HANDLE;
01380
01381 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01382 {
01383 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01384
01385
01386 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01387 break;
01388 }
01389
01390 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01391 {
01392 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01393 return SCARD_E_READER_UNAVAILABLE;
01394 }
01395
01396 scCancelStruct.hCard = hCard;
01397
01398 rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION,
01399 psContextMap[dwContextIndex].dwClientID,
01400 sizeof(scCancelStruct),
01401 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
01402
01403 if (rv == -1)
01404 {
01405 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01406 return SCARD_E_NO_SERVICE;
01407 }
01408
01409
01410
01411
01412 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01413 PCSCLITE_CLIENT_ATTEMPTS);
01414
01415 memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
01416
01417 if (rv == -1)
01418 {
01419 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01420 return SCARD_F_COMM_ERROR;
01421 }
01422
01423 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01424
01425 PROFILE_END(scCancelStruct.rv)
01426
01427 return scCancelStruct.rv;
01428 }
01429
01491 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames,
01492 LPDWORD pcchReaderLen, LPDWORD pdwState,
01493 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
01494 {
01495 DWORD dwReaderLen, dwAtrLen;
01496 LONG rv;
01497 int i;
01498 status_struct scStatusStruct;
01499 sharedSegmentMsg msgStruct;
01500 DWORD dwContextIndex, dwChannelIndex;
01501 char *r;
01502
01503 PROFILE_START
01504
01505
01506
01507
01508
01509 if (pcchReaderLen == NULL || pcbAtrLen == NULL)
01510 return SCARD_E_INVALID_PARAMETER;
01511
01512
01513 dwReaderLen = *pcchReaderLen;
01514 dwAtrLen = *pcbAtrLen;
01515
01516
01517 if (pdwState)
01518 *pdwState = 0;
01519
01520 if (pdwProtocol)
01521 *pdwProtocol = 0;
01522
01523 *pcchReaderLen = 0;
01524 *pcbAtrLen = 0;
01525
01526 rv = SCardCheckDaemonAvailability();
01527 if (rv != SCARD_S_SUCCESS)
01528 return rv;
01529
01530
01531
01532
01533 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01534 if (rv == -1)
01535 return SCARD_E_INVALID_HANDLE;
01536
01537 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01538
01539
01540 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01541 if (rv == -1)
01542
01543
01544
01545 return SCARD_E_INVALID_HANDLE;
01546
01547 r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01548 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01549 {
01550
01551 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01552 break;
01553 }
01554
01555 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01556 {
01557 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01558 return SCARD_E_READER_UNAVAILABLE;
01559 }
01560
01561
01562 memset(&scStatusStruct, 0, sizeof(scStatusStruct));
01563 scStatusStruct.hCard = hCard;
01564
01565
01566 scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
01567 scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
01568
01569 rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
01570 sizeof(scStatusStruct),
01571 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
01572
01573 if (rv == -1)
01574 {
01575 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01576 return SCARD_E_NO_SERVICE;
01577 }
01578
01579
01580
01581
01582 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
01583 PCSCLITE_CLIENT_ATTEMPTS);
01584
01585 memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
01586
01587 if (rv == -1)
01588 {
01589 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01590 return SCARD_F_COMM_ERROR;
01591 }
01592
01593 rv = scStatusStruct.rv;
01594 if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
01595 {
01596
01597
01598
01599 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01600 return rv;
01601 }
01602
01603
01604
01605
01606
01607 *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
01608 *pcbAtrLen = (readerStates[i])->cardAtrLength;
01609
01610 if (pdwState)
01611 *pdwState = (readerStates[i])->readerState;
01612
01613 if (pdwProtocol)
01614 *pdwProtocol = (readerStates[i])->cardProtocol;
01615
01616
01617 if (mszReaderNames)
01618 {
01619 if (*pcchReaderLen > dwReaderLen)
01620 rv = SCARD_E_INSUFFICIENT_BUFFER;
01621
01622 strncpy(mszReaderNames,
01623 psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
01624 dwReaderLen);
01625 }
01626
01627 if (pbAtr)
01628 {
01629 if (*pcbAtrLen > dwAtrLen)
01630 rv = SCARD_E_INSUFFICIENT_BUFFER;
01631
01632 memcpy(pbAtr, (readerStates[i])->cardAtr,
01633 min(*pcbAtrLen, dwAtrLen));
01634 }
01635
01636 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01637
01638 PROFILE_END(rv)
01639
01640 return rv;
01641 }
01642
01730 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01731 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01732 {
01733 PSCARD_READERSTATE_A currReader;
01734 PREADER_STATE rContext;
01735 DWORD dwTime = 0;
01736 DWORD dwState;
01737 DWORD dwBreakFlag = 0;
01738 int j;
01739 LONG dwContextIndex;
01740 int currentReaderCount = 0;
01741 LONG rv;
01742
01743 PROFILE_START
01744
01745 if (rgReaderStates == NULL && cReaders > 0)
01746 return SCARD_E_INVALID_PARAMETER;
01747
01748 rv = SCardCheckDaemonAvailability();
01749 if (rv != SCARD_S_SUCCESS)
01750 return rv;
01751
01752
01753
01754
01755
01756 dwContextIndex = SCardGetContextIndice(hContext);
01757 if (dwContextIndex == -1)
01758 return SCARD_E_INVALID_HANDLE;
01759
01760 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01761
01762
01763 dwContextIndex = SCardGetContextIndice(hContext);
01764 if (dwContextIndex == -1)
01765
01766
01767
01768 return SCARD_E_INVALID_HANDLE;
01769
01770
01771
01772
01773
01774
01775 if (cReaders == 0)
01776 {
01777 while (1)
01778 {
01779 int i;
01780
01781 rv = SCardCheckDaemonAvailability();
01782 if (rv != SCARD_S_SUCCESS)
01783 {
01784 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01785 return rv;
01786 }
01787
01788 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01789 {
01790 if ((readerStates[i])->readerID != 0)
01791 {
01792
01793
01794
01795 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01796
01797 PROFILE_END(SCARD_S_SUCCESS)
01798
01799 return SCARD_S_SUCCESS;
01800 }
01801 }
01802
01803 if (dwTimeout == 0)
01804 {
01805
01806
01807
01808 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01809 return SCARD_E_READER_UNAVAILABLE;
01810 }
01811
01812 SYS_USleep(PCSCLITE_STATUS_WAIT);
01813
01814 if (dwTimeout != INFINITE)
01815 {
01816 dwTime += PCSCLITE_STATUS_WAIT;
01817
01818 if (dwTime >= (dwTimeout * 1000))
01819 {
01820 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01821
01822 PROFILE_END(SCARD_E_TIMEOUT)
01823
01824 return SCARD_E_TIMEOUT;
01825 }
01826 }
01827 }
01828 }
01829 else
01830 if (cReaders >= PCSCLITE_MAX_READERS_CONTEXTS)
01831 {
01832 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01833 return SCARD_E_INVALID_VALUE;
01834 }
01835
01836
01837
01838
01839
01840 for (j = 0; j < cReaders; j++)
01841 {
01842 currReader = &rgReaderStates[j];
01843
01844 if (currReader->szReader == NULL)
01845 {
01846 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01847 return SCARD_E_INVALID_VALUE;
01848 }
01849 }
01850
01851
01852
01853
01854
01855
01856
01857
01858 for (j = 0; j < cReaders; j++)
01859 {
01860 currReader = &rgReaderStates[j];
01861 currReader->dwEventState = 0;
01862 }
01863
01864
01865
01866
01867
01868 Log1(PCSC_LOG_DEBUG, "Event Loop Start");
01869
01870 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
01871
01872
01873 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
01874 if ((readerStates[j])->readerID != 0)
01875 currentReaderCount++;
01876
01877 j = 0;
01878
01879 do
01880 {
01881 int newReaderCount = 0;
01882 char ReaderCountChanged = FALSE;
01883
01884 rv = SCardCheckDaemonAvailability();
01885 if (rv != SCARD_S_SUCCESS)
01886 {
01887 if (psContextMap[dwContextIndex].mMutex)
01888 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01889
01890 PROFILE_END(rv)
01891
01892 return rv;
01893 }
01894
01895 if (j == 0)
01896 {
01897 int i;
01898
01899 for (i=0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01900 if ((readerStates[i])->readerID != 0)
01901 newReaderCount++;
01902
01903 if (newReaderCount != currentReaderCount)
01904 {
01905 Log1(PCSC_LOG_INFO, "Reader list changed");
01906 ReaderCountChanged = TRUE;
01907 currentReaderCount = newReaderCount;
01908 }
01909 }
01910 currReader = &rgReaderStates[j];
01911
01912
01913
01914 if (currReader->dwCurrentState & SCARD_STATE_IGNORE)
01915 currReader->dwEventState = SCARD_STATE_IGNORE;
01916 else
01917 {
01918 LPSTR lpcReaderName;
01919 int i;
01920
01921
01922
01923 lpcReaderName = (char *) currReader->szReader;
01924
01925 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01926 {
01927 if (strcmp(lpcReaderName, (readerStates[i])->readerName) == 0)
01928 break;
01929 }
01930
01931
01932
01933
01934 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01935 {
01936 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01937 currReader->dwEventState = SCARD_STATE_UNKNOWN;
01938 else
01939 {
01940 currReader->dwEventState =
01941 SCARD_STATE_UNKNOWN | SCARD_STATE_CHANGED;
01942
01943
01944
01945
01946
01947 dwBreakFlag = 1;
01948 }
01949 }
01950 else
01951 {
01952
01953
01954
01955
01956 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01957 {
01958 currReader->dwEventState |= SCARD_STATE_CHANGED;
01959 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01960 dwBreakFlag = 1;
01961 }
01962
01963
01964
01965
01966
01967
01968 rContext = readerStates[i];
01969
01970
01971
01972
01973 dwState = rContext->readerState;
01974 {
01975 int currentCounter, stateCounter;
01976
01977 stateCounter = (dwState >> 16) & 0xFFFF;
01978 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
01979
01980
01981 if (stateCounter != currentCounter)
01982 currReader->dwEventState |= SCARD_STATE_CHANGED;
01983
01984
01985 currReader->dwEventState =
01986 ((currReader->dwEventState & 0xffff )
01987 | (stateCounter << 16));
01988 }
01989
01990
01991 if (dwState & SCARD_UNKNOWN)
01992 {
01993
01994
01995
01996 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
01997 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
01998 else
01999 {
02000
02001
02002
02003
02004 currReader->dwEventState = SCARD_STATE_CHANGED |
02005 SCARD_STATE_UNAVAILABLE;
02006 dwBreakFlag = 1;
02007 }
02008 }
02009 else
02010 {
02011
02012
02013
02014 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
02015 {
02016 currReader->dwEventState &=
02017 ~SCARD_STATE_UNAVAILABLE;
02018 currReader->dwEventState |= SCARD_STATE_CHANGED;
02019 dwBreakFlag = 1;
02020 }
02021 }
02022
02023
02024
02025 if (dwState & SCARD_PRESENT)
02026 {
02027
02028 if (0 == rContext->cardAtrLength)
02029
02030 SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
02031
02032 currReader->cbAtr = rContext->cardAtrLength;
02033 memcpy(currReader->rgbAtr, rContext->cardAtr,
02034 currReader->cbAtr);
02035 }
02036 else
02037 currReader->cbAtr = 0;
02038
02039
02040
02041
02042 if (dwState & SCARD_ABSENT)
02043 {
02044 currReader->dwEventState |= SCARD_STATE_EMPTY;
02045 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
02046 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02047 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02048 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02049 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02050 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
02051 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02052 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02053
02054
02055
02056
02057 if (currReader->dwCurrentState & SCARD_STATE_PRESENT)
02058 {
02059 currReader->dwEventState |= SCARD_STATE_CHANGED;
02060 dwBreakFlag = 1;
02061 }
02062
02063
02064
02065
02066 } else if (dwState & SCARD_PRESENT)
02067 {
02068 currReader->dwEventState |= SCARD_STATE_PRESENT;
02069 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
02070 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02071 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02072 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02073 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02074 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02075
02076 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
02077 {
02078 currReader->dwEventState |= SCARD_STATE_CHANGED;
02079 dwBreakFlag = 1;
02080 }
02081
02082 if (dwState & SCARD_SWALLOWED)
02083 {
02084 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
02085 currReader->dwEventState |= SCARD_STATE_MUTE;
02086 else
02087 {
02088 currReader->dwEventState |= SCARD_STATE_MUTE;
02089 if (currReader->dwCurrentState
02090 != SCARD_STATE_UNAWARE)
02091 currReader->dwEventState |= SCARD_STATE_CHANGED;
02092 dwBreakFlag = 1;
02093 }
02094 }
02095 else
02096 {
02097
02098
02099
02100 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
02101 {
02102 currReader->dwEventState |=
02103 SCARD_STATE_CHANGED;
02104 dwBreakFlag = 1;
02105 }
02106 }
02107 }
02108
02109
02110
02111
02112 if (rContext->readerSharing == -1)
02113 {
02114 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
02115 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02116 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02117 {
02118 currReader->dwEventState |= SCARD_STATE_CHANGED;
02119 dwBreakFlag = 1;
02120 }
02121 }
02122 else if (rContext->readerSharing >= 1)
02123 {
02124
02125
02126
02127 if (dwState & SCARD_PRESENT)
02128 {
02129 currReader->dwEventState |= SCARD_STATE_INUSE;
02130 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02131 if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)
02132 {
02133 currReader->dwEventState |= SCARD_STATE_CHANGED;
02134 dwBreakFlag = 1;
02135 }
02136 }
02137 }
02138 else if (rContext->readerSharing == 0)
02139 {
02140 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02141 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02142
02143 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02144 {
02145 currReader->dwEventState |= SCARD_STATE_CHANGED;
02146 dwBreakFlag = 1;
02147 }
02148 else if (currReader-> dwCurrentState
02149 & SCARD_STATE_EXCLUSIVE)
02150 {
02151 currReader->dwEventState |= SCARD_STATE_CHANGED;
02152 dwBreakFlag = 1;
02153 }
02154 }
02155
02156 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02157 {
02158
02159
02160
02161
02162 currReader->dwEventState |= SCARD_STATE_CHANGED;
02163 dwBreakFlag = 1;
02164 }
02165
02166 }
02167
02168 }
02169
02170
02171
02172
02173 j = j + 1;
02174 if (j == cReaders)
02175 {
02176 if (!dwBreakFlag)
02177 {
02178
02179
02180
02181
02182 if (ReaderCountChanged)
02183 break;
02184 }
02185 j = 0;
02186 }
02187
02188
02189
02190
02191
02192 if (psContextMap[dwContextIndex].contextBlockStatus
02193 == BLOCK_STATUS_RESUME)
02194 break;
02195
02196
02197
02198
02199 if ((dwBreakFlag == 1) && (j == 0))
02200 break;
02201
02202
02203
02204
02205 if ((dwTimeout == 0) && (j == 0))
02206 break;
02207
02208 if (dwTimeout != INFINITE && dwTimeout != 0)
02209 {
02210
02211
02212
02213
02214 if ((dwTime >= (dwTimeout * 1000)) && (j == 0))
02215 {
02216 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02217 PROFILE_END(SCARD_E_TIMEOUT)
02218 return SCARD_E_TIMEOUT;
02219 }
02220 }
02221
02222
02223
02224
02225 if (j == 0)
02226 {
02227 SYS_USleep(PCSCLITE_STATUS_WAIT);
02228 dwTime += PCSCLITE_STATUS_WAIT;
02229 }
02230 }
02231 while (1);
02232
02233 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02234
02235 if (psContextMap[dwContextIndex].contextBlockStatus ==
02236 BLOCK_STATUS_RESUME)
02237 {
02238 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02239 PROFILE_END(SCARD_E_CANCELLED)
02240 return SCARD_E_CANCELLED;
02241 }
02242
02243 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02244
02245 PROFILE_END(SCARD_S_SUCCESS)
02246
02247 return SCARD_S_SUCCESS;
02248 }
02249
02302 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02303 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02304 LPDWORD lpBytesReturned)
02305 {
02306 LONG rv;
02307 control_struct scControlStruct;
02308 sharedSegmentMsg msgStruct;
02309 int i;
02310 DWORD dwContextIndex, dwChannelIndex;
02311
02312 PROFILE_START
02313
02314
02315 if (NULL != lpBytesReturned)
02316 *lpBytesReturned = 0;
02317
02318 rv = SCardCheckDaemonAvailability();
02319 if (rv != SCARD_S_SUCCESS)
02320 return rv;
02321
02322
02323
02324
02325 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02326 if (rv == -1)
02327 return SCARD_E_INVALID_HANDLE;
02328
02329 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02330
02331
02332 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02333 if (rv == -1)
02334
02335
02336
02337 return SCARD_E_INVALID_HANDLE;
02338
02339 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02340 {
02341 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02342
02343
02344 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02345 break;
02346 }
02347
02348 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02349 {
02350 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02351 return SCARD_E_READER_UNAVAILABLE;
02352 }
02353
02354 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02355 || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02356 {
02357 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02358 return SCARD_E_INSUFFICIENT_BUFFER;
02359 }
02360
02361 if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
02362 {
02363
02364 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02365 control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
02366 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02367
02368 scControlStructExtended->hCard = hCard;
02369 scControlStructExtended->dwControlCode = dwControlCode;
02370 scControlStructExtended->cbSendLength = cbSendLength;
02371 scControlStructExtended->cbRecvLength = cbRecvLength;
02372 scControlStructExtended->pdwBytesReturned = 0;
02373 scControlStructExtended->rv = SCARD_S_SUCCESS;
02374
02375
02376
02377
02378 scControlStructExtended->size = sizeof(*scControlStructExtended)
02379 - (sizeof(control_struct_extended) - offsetof(control_struct_extended, data))
02380 + cbSendLength;
02381 memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
02382
02383 rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
02384 psContextMap[dwContextIndex].dwClientID,
02385 scControlStructExtended->size,
02386 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02387
02388 if (rv == -1)
02389 {
02390 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02391 return SCARD_E_NO_SERVICE;
02392 }
02393
02394
02395
02396
02397
02398 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg),
02399 psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02400 if (rv == -1)
02401 {
02402 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02403 return SCARD_F_COMM_ERROR;
02404 }
02405
02406
02407 scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
02408
02409
02410 if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02411 {
02412 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02413 scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02414 psContextMap[dwContextIndex].dwClientID,
02415 PCSCLITE_CLIENT_ATTEMPTS);
02416 if (rv == -1)
02417 {
02418 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02419 return SCARD_F_COMM_ERROR;
02420 }
02421 }
02422
02423 if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
02424 {
02425
02426
02427
02428 memcpy(pbRecvBuffer, scControlStructExtended -> data,
02429 scControlStructExtended -> pdwBytesReturned);
02430 memset(scControlStructExtended -> data, 0x00,
02431 scControlStructExtended -> pdwBytesReturned);
02432 }
02433
02434 if (NULL != lpBytesReturned)
02435 *lpBytesReturned = scControlStructExtended -> pdwBytesReturned;
02436
02437 rv = scControlStructExtended -> rv;
02438 }
02439 else
02440 {
02441 scControlStruct.hCard = hCard;
02442 scControlStruct.dwControlCode = dwControlCode;
02443 scControlStruct.cbSendLength = cbSendLength;
02444 scControlStruct.cbRecvLength = cbRecvLength;
02445 memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02446
02447 rv = WrapSHMWrite(SCARD_CONTROL,
02448 psContextMap[dwContextIndex].dwClientID,
02449 sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
02450
02451 if (rv == -1)
02452 {
02453 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02454 return SCARD_E_NO_SERVICE;
02455 }
02456
02457
02458
02459
02460 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02461 PCSCLITE_CLIENT_ATTEMPTS);
02462
02463 if (rv == -1)
02464 {
02465 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02466 return SCARD_F_COMM_ERROR;
02467 }
02468
02469 memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
02470
02471 if (NULL != lpBytesReturned)
02472 *lpBytesReturned = scControlStruct.dwBytesReturned;
02473
02474 if (scControlStruct.rv == SCARD_S_SUCCESS)
02475 {
02476
02477
02478
02479 memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
02480 scControlStruct.cbRecvLength);
02481 memset(scControlStruct.pbRecvBuffer, 0x00,
02482 sizeof(scControlStruct.pbRecvBuffer));
02483 }
02484
02485 rv = scControlStruct.rv;
02486 }
02487
02488 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02489
02490 PROFILE_END(rv)
02491
02492 return rv;
02493 }
02494
02576 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02577 LPDWORD pcbAttrLen)
02578 {
02579 LONG ret;
02580 unsigned char *buf = NULL;
02581
02582 PROFILE_START
02583
02584 if (NULL == pcbAttrLen)
02585 return SCARD_E_INVALID_PARAMETER;
02586
02587 if (SCARD_AUTOALLOCATE == *pcbAttrLen)
02588 {
02589 *pcbAttrLen = MAX_BUFFER_SIZE;
02590 buf = malloc(*pcbAttrLen);
02591 if (NULL == buf)
02592 return SCARD_E_NO_MEMORY;
02593
02594 *(unsigned char **)pbAttr = buf;
02595 }
02596 else
02597 {
02598 buf = pbAttr;
02599
02600
02601 if (NULL == pbAttr)
02602
02603 *pcbAttrLen = MAX_BUFFER_SIZE;
02604 }
02605
02606 ret = SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, buf,
02607 pcbAttrLen);
02608
02609 PROFILE_END(ret)
02610
02611 return ret;
02612 }
02613
02649 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02650 DWORD cbAttrLen)
02651 {
02652 LONG ret;
02653
02654 PROFILE_START
02655
02656 if (NULL == pbAttr || 0 == cbAttrLen)
02657 return SCARD_E_INVALID_PARAMETER;
02658
02659 ret = SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02660 &cbAttrLen);
02661
02662 PROFILE_END(ret)
02663
02664 return ret;
02665 }
02666
02667 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02668 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02669 {
02670 LONG rv;
02671 getset_struct scGetSetStruct;
02672 sharedSegmentMsg msgStruct;
02673 int i;
02674 DWORD dwContextIndex, dwChannelIndex;
02675
02676 rv = SCardCheckDaemonAvailability();
02677 if (rv != SCARD_S_SUCCESS)
02678 return rv;
02679
02680
02681
02682
02683 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02684 if (rv == -1)
02685 return SCARD_E_INVALID_HANDLE;
02686
02687 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02688
02689
02690 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02691 if (rv == -1)
02692
02693
02694
02695 return SCARD_E_INVALID_HANDLE;
02696
02697 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02698 {
02699 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02700
02701
02702 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02703 break;
02704 }
02705
02706 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02707 {
02708 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02709 return SCARD_E_READER_UNAVAILABLE;
02710 }
02711
02712 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02713 {
02714 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02715 return SCARD_E_INSUFFICIENT_BUFFER;
02716 }
02717
02718 scGetSetStruct.hCard = hCard;
02719 scGetSetStruct.dwAttrId = dwAttrId;
02720 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02721 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02722 memset(scGetSetStruct.pbAttr, 0, sizeof(scGetSetStruct.pbAttr));
02723 if (SCARD_SET_ATTRIB == command)
02724 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02725
02726 rv = WrapSHMWrite(command,
02727 psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
02728 PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
02729
02730 if (rv == -1)
02731 {
02732 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02733 return SCARD_E_NO_SERVICE;
02734 }
02735
02736
02737
02738
02739 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02740 PCSCLITE_CLIENT_ATTEMPTS);
02741
02742 if (rv == -1)
02743 {
02744 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02745 return SCARD_F_COMM_ERROR;
02746 }
02747
02748 memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
02749
02750 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02751 {
02752
02753
02754
02755 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02756 {
02757 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02758 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02759 }
02760 else
02761 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02762
02763 if (pbAttr)
02764 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02765
02766 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02767 }
02768
02769 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02770
02771 return scGetSetStruct.rv;
02772 }
02773
02830 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02831 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02832 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02833 LPDWORD pcbRecvLength)
02834 {
02835 LONG rv;
02836 int i;
02837 DWORD dwContextIndex, dwChannelIndex;
02838
02839 PROFILE_START
02840
02841 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02842 pcbRecvLength == NULL || pioSendPci == NULL)
02843 return SCARD_E_INVALID_PARAMETER;
02844
02845 rv = SCardCheckDaemonAvailability();
02846 if (rv != SCARD_S_SUCCESS)
02847 return rv;
02848
02849
02850
02851
02852 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02853 if (rv == -1)
02854 {
02855 *pcbRecvLength = 0;
02856 return SCARD_E_INVALID_HANDLE;
02857 }
02858
02859 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02860
02861
02862 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02863 if (rv == -1)
02864
02865
02866
02867 return SCARD_E_INVALID_HANDLE;
02868
02869 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02870 {
02871 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02872
02873
02874 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02875 break;
02876 }
02877
02878 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02879 {
02880 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02881 return SCARD_E_READER_UNAVAILABLE;
02882 }
02883
02884 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02885 || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02886 {
02887 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02888 return SCARD_E_INSUFFICIENT_BUFFER;
02889 }
02890
02891 if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
02892 {
02893
02894 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02895 transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
02896 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02897
02898 scTransmitStructExtended->hCard = hCard;
02899 scTransmitStructExtended->cbSendLength = cbSendLength;
02900 scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
02901
02902
02903
02904
02905 scTransmitStructExtended->size = sizeof(*scTransmitStructExtended)
02906 - (sizeof(transmit_struct_extended) - offsetof(transmit_struct_extended, data))
02907 + cbSendLength;
02908 scTransmitStructExtended->pioSendPciProtocol = pioSendPci->dwProtocol;
02909 scTransmitStructExtended->pioSendPciLength = pioSendPci->cbPciLength;
02910 memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
02911 scTransmitStructExtended->rv = SCARD_S_SUCCESS;
02912
02913 if (pioRecvPci)
02914 {
02915 scTransmitStructExtended->pioRecvPciProtocol = pioRecvPci->dwProtocol;
02916 scTransmitStructExtended->pioRecvPciLength = pioRecvPci->cbPciLength;
02917 }
02918 else
02919 {
02920 scTransmitStructExtended->pioRecvPciProtocol = SCARD_PROTOCOL_ANY;
02921 scTransmitStructExtended->pioRecvPciLength = sizeof(SCARD_IO_REQUEST);
02922 }
02923
02924 rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
02925 psContextMap[dwContextIndex].dwClientID,
02926 scTransmitStructExtended->size,
02927 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02928
02929 if (rv == -1)
02930 {
02931 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02932 return SCARD_E_NO_SERVICE;
02933 }
02934
02935
02936
02937
02938
02939 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02940 if (rv == -1)
02941 {
02942 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02943 return SCARD_F_COMM_ERROR;
02944 }
02945
02946
02947 scTransmitStructExtended = (transmit_struct_extended *)&(pmsgStruct -> data);
02948
02949
02950 if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02951 {
02952 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02953 scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02954 psContextMap[dwContextIndex].dwClientID,
02955 PCSCLITE_CLIENT_ATTEMPTS);
02956 if (rv == -1)
02957 {
02958 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02959 return SCARD_F_COMM_ERROR;
02960 }
02961 }
02962
02963 if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
02964 {
02965
02966
02967
02968 memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
02969 scTransmitStructExtended -> pcbRecvLength);
02970 memset(scTransmitStructExtended -> data, 0x00,
02971 scTransmitStructExtended -> pcbRecvLength);
02972
02973 if (pioRecvPci)
02974 {
02975 pioRecvPci->dwProtocol = scTransmitStructExtended->pioRecvPciProtocol;
02976 pioRecvPci->cbPciLength = scTransmitStructExtended->pioRecvPciLength;
02977 }
02978 }
02979
02980 *pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
02981 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02982
02983 rv = scTransmitStructExtended -> rv;
02984 }
02985 else
02986 {
02987
02988 transmit_struct scTransmitStruct;
02989 sharedSegmentMsg msgStruct;
02990
02991 scTransmitStruct.hCard = hCard;
02992 scTransmitStruct.cbSendLength = cbSendLength;
02993 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
02994 scTransmitStruct.pioSendPciProtocol = pioSendPci->dwProtocol;
02995 scTransmitStruct.pioSendPciLength = pioSendPci->cbPciLength;
02996 memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02997 memset(scTransmitStruct.pbSendBuffer+cbSendLength, 0, sizeof(scTransmitStruct.pbSendBuffer)-cbSendLength);
02998 memset(scTransmitStruct.pbRecvBuffer, 0, sizeof(scTransmitStruct.pbRecvBuffer));
02999 scTransmitStruct.rv = SCARD_S_SUCCESS;
03000
03001 scTransmitStruct.pioRecvPciProtocol = SCARD_PROTOCOL_ANY;
03002 scTransmitStruct.pioRecvPciLength = sizeof(SCARD_IO_REQUEST);
03003
03004 rv = WrapSHMWrite(SCARD_TRANSMIT,
03005 psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
03006 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
03007
03008 if (rv == -1)
03009 {
03010 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03011 return SCARD_E_NO_SERVICE;
03012 }
03013
03014
03015
03016
03017 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
03018 PCSCLITE_CLIENT_ATTEMPTS);
03019
03020 memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
03021
03022 if (rv == -1)
03023 {
03024 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03025 return SCARD_F_COMM_ERROR;
03026 }
03027
03028
03029
03030
03031 memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
03032
03033 if (scTransmitStruct.rv == SCARD_S_SUCCESS)
03034 {
03035
03036
03037
03038 memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
03039 scTransmitStruct.pcbRecvLength);
03040 memset(scTransmitStruct.pbRecvBuffer, 0x00,
03041 scTransmitStruct.pcbRecvLength);
03042
03043 if (pioRecvPci)
03044 {
03045 pioRecvPci->dwProtocol = scTransmitStruct.pioRecvPciProtocol;
03046 pioRecvPci->cbPciLength = scTransmitStruct.pioRecvPciLength;
03047 }
03048 }
03049
03050 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
03051 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03052
03053 rv = scTransmitStruct.rv;
03054 }
03055
03056 PROFILE_END(rv)
03057
03058 return rv;
03059 }
03060
03094 LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
03095 LPSTR mszReaders, LPDWORD pcchReaders)
03096 {
03097 DWORD dwReadersLen;
03098 int i;
03099 LONG dwContextIndex;
03100 LONG rv = SCARD_S_SUCCESS;
03101 char *buf = NULL;
03102
03103 PROFILE_START
03104
03105
03106
03107
03108 if (pcchReaders == NULL)
03109 return SCARD_E_INVALID_PARAMETER;
03110
03111 rv = SCardCheckDaemonAvailability();
03112 if (rv != SCARD_S_SUCCESS)
03113 return rv;
03114
03115
03116
03117
03118 dwContextIndex = SCardGetContextIndice(hContext);
03119 if (dwContextIndex == -1)
03120 return SCARD_E_INVALID_HANDLE;
03121
03122 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03123
03124
03125 dwContextIndex = SCardGetContextIndice(hContext);
03126 if (dwContextIndex == -1)
03127
03128
03129
03130 return SCARD_E_INVALID_HANDLE;
03131
03132 dwReadersLen = 0;
03133 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03134 if ((readerStates[i])->readerID != 0)
03135 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
03136
03137
03138 dwReadersLen += 1;
03139
03140 if (1 == dwReadersLen)
03141 {
03142 rv = SCARD_E_NO_READERS_AVAILABLE;
03143 goto end;
03144 }
03145
03146 if (SCARD_AUTOALLOCATE == *pcchReaders)
03147 {
03148 buf = malloc(dwReadersLen);
03149 if (NULL == buf)
03150 {
03151 rv = SCARD_E_NO_MEMORY;
03152 goto end;
03153 }
03154 *(char **)mszReaders = buf;
03155 }
03156 else
03157 {
03158 buf = mszReaders;
03159
03160
03161 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
03162 {
03163 rv = SCARD_E_INSUFFICIENT_BUFFER;
03164 goto end;
03165 }
03166 }
03167
03168 if (mszReaders == NULL)
03169 goto end;
03170
03171 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03172 {
03173 if ((readerStates[i])->readerID != 0)
03174 {
03175
03176
03177
03178 strcpy(buf, (readerStates[i])->readerName);
03179 buf += strlen((readerStates[i])->readerName)+1;
03180 }
03181 }
03182 *buf = '\0';
03183
03184 end:
03185
03186 *pcchReaders = dwReadersLen;
03187
03188 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03189
03190 PROFILE_END(rv)
03191
03192 return rv;
03193 }
03194
03207 LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
03208 {
03209 LONG rv = SCARD_S_SUCCESS;
03210 LONG dwContextIndex;
03211
03212 PROFILE_START
03213
03214 rv = SCardCheckDaemonAvailability();
03215 if (rv != SCARD_S_SUCCESS)
03216 return rv;
03217
03218
03219
03220
03221 dwContextIndex = SCardGetContextIndice(hContext);
03222 if (dwContextIndex == -1)
03223 return SCARD_E_INVALID_HANDLE;
03224
03225 free((void *)pvMem);
03226
03227 PROFILE_END(rv)
03228
03229 return rv;
03230 }
03231
03266 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
03267 LPDWORD pcchGroups)
03268 {
03269 LONG rv = SCARD_S_SUCCESS;
03270 LONG dwContextIndex;
03271 char *buf = NULL;
03272
03273 PROFILE_START
03274
03275
03276 const char ReaderGroup[] = "SCard$DefaultReaders\0";
03277 const int dwGroups = sizeof(ReaderGroup);
03278
03279 rv = SCardCheckDaemonAvailability();
03280 if (rv != SCARD_S_SUCCESS)
03281 return rv;
03282
03283
03284
03285
03286 dwContextIndex = SCardGetContextIndice(hContext);
03287 if (dwContextIndex == -1)
03288 return SCARD_E_INVALID_HANDLE;
03289
03290 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03291
03292
03293 dwContextIndex = SCardGetContextIndice(hContext);
03294 if (dwContextIndex == -1)
03295
03296
03297
03298 return SCARD_E_INVALID_HANDLE;
03299
03300 if (SCARD_AUTOALLOCATE == *pcchGroups)
03301 {
03302 buf = malloc(dwGroups);
03303 if (NULL == buf)
03304 {
03305 rv = SCARD_E_NO_MEMORY;
03306 goto end;
03307 }
03308 *(char **)mszGroups = buf;
03309 }
03310 else
03311 {
03312 buf = mszGroups;
03313
03314 if ((NULL != mszGroups) && (*pcchGroups < dwGroups))
03315 {
03316 rv = SCARD_E_INSUFFICIENT_BUFFER;
03317 goto end;
03318 }
03319 }
03320
03321 if (buf)
03322 memcpy(buf, ReaderGroup, dwGroups);
03323
03324 end:
03325 *pcchGroups = dwGroups;
03326
03327 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03328
03329 PROFILE_END(rv)
03330
03331 return rv;
03332 }
03333
03362 LONG SCardCancel(SCARDCONTEXT hContext)
03363 {
03364 LONG dwContextIndex;
03365
03366 PROFILE_START
03367
03368 dwContextIndex = SCardGetContextIndice(hContext);
03369 if (dwContextIndex == -1)
03370 return SCARD_E_INVALID_HANDLE;
03371
03372
03373
03374
03375
03376 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
03377
03378 PROFILE_END(SCARD_S_SUCCESS)
03379
03380 return SCARD_S_SUCCESS;
03381 }
03382
03407 LONG SCardIsValidContext(SCARDCONTEXT hContext)
03408 {
03409 LONG rv;
03410 LONG dwContextIndex;
03411
03412 PROFILE_START
03413
03414 rv = SCARD_S_SUCCESS;
03415
03416
03417 rv = SCardCheckDaemonAvailability();
03418 if (rv != SCARD_S_SUCCESS)
03419 return rv;
03420
03421
03422
03423
03424 dwContextIndex = SCardGetContextIndice(hContext);
03425 if (dwContextIndex == -1)
03426 rv = SCARD_E_INVALID_HANDLE;
03427
03428 PROFILE_END(rv)
03429
03430 return rv;
03431 }
03432
03449 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
03450 {
03451 int i;
03452
03453 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03454 {
03455 if (psContextMap[i].hContext == 0)
03456 {
03457 psContextMap[i].hContext = hContext;
03458 psContextMap[i].dwClientID = dwClientID;
03459 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
03460 psContextMap[i].mMutex = malloc(sizeof(PCSCLITE_MUTEX));
03461 SYS_MutexInit(psContextMap[i].mMutex);
03462 return SCARD_S_SUCCESS;
03463 }
03464 }
03465
03466 return SCARD_E_NO_MEMORY;
03467 }
03468
03481 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
03482 {
03483 LONG rv;
03484
03485 SCardLockThread();
03486 rv = SCardGetContextIndiceTH(hContext);
03487 SCardUnlockThread();
03488
03489 return rv;
03490 }
03491
03504 static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
03505 {
03506 int i;
03507
03508
03509
03510
03511 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03512 {
03513 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
03514 return i;
03515 }
03516
03517 return -1;
03518 }
03519
03529 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
03530 {
03531 LONG retIndice;
03532
03533 retIndice = SCardGetContextIndiceTH(hContext);
03534
03535 if (retIndice == -1)
03536 return SCARD_E_INVALID_HANDLE;
03537 else
03538 return SCardCleanContext(retIndice);
03539 }
03540
03541 static LONG SCardCleanContext(LONG indice)
03542 {
03543 int i;
03544
03545 psContextMap[indice].hContext = 0;
03546 SHMClientCloseSession(psContextMap[indice].dwClientID);
03547 psContextMap[indice].dwClientID = 0;
03548 free(psContextMap[indice].mMutex);
03549 psContextMap[indice].mMutex = NULL;
03550 psContextMap[indice].contextBlockStatus = BLOCK_STATUS_RESUME;
03551
03552 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03553 {
03554
03555
03556
03557 psContextMap[indice].psChannelMap[i].hCard = 0;
03558 free(psContextMap[indice].psChannelMap[i].readerName);
03559 psContextMap[indice].psChannelMap[i].readerName = NULL;
03560 }
03561
03562 return SCARD_S_SUCCESS;
03563 }
03564
03565
03566
03567
03568
03569 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
03570 LPCSTR readerName)
03571 {
03572 int i;
03573
03574 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03575 {
03576 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
03577 {
03578 psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
03579 psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
03580 return SCARD_S_SUCCESS;
03581 }
03582 }
03583
03584 return SCARD_E_NO_MEMORY;
03585 }
03586
03587 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03588 {
03589 DWORD dwContextIndice, dwChannelIndice;
03590 LONG rv;
03591
03592 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
03593 if (rv == -1)
03594 return SCARD_E_INVALID_HANDLE;
03595 else
03596 {
03597 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
03598 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
03599 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
03600 return SCARD_S_SUCCESS;
03601 }
03602 }
03603
03604 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard,
03605 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03606 {
03607 LONG rv;
03608
03609 if (0 == hCard)
03610 return -1;
03611
03612 SCardLockThread();
03613 rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
03614 SCardUnlockThread();
03615
03616 return rv;
03617 }
03618
03619 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard,
03620 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03621 {
03622 int i;
03623
03624 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03625 {
03626 if (psContextMap[i].hContext != 0)
03627 {
03628 int j;
03629
03630 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
03631 {
03632 if (psContextMap[i].psChannelMap[j].hCard == hCard)
03633 {
03634 *pdwContextIndice = i;
03635 *pdwChannelIndice = j;
03636 return SCARD_S_SUCCESS;
03637 }
03638 }
03639
03640 }
03641 }
03642
03643 return -1;
03644 }
03645
03654 LONG SCardCheckDaemonAvailability(void)
03655 {
03656 LONG rv;
03657 struct stat statBuffer;
03658 int need_restart = 0;
03659
03660 rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &statBuffer);
03661
03662 if (rv != 0)
03663 {
03664 Log2(PCSC_LOG_INFO, "PCSC Not Running: " PCSCLITE_PUBSHM_FILE ": %s",
03665 strerror(errno));
03666 return SCARD_E_NO_SERVICE;
03667 }
03668
03669
03670
03671 if (daemon_ctime && statBuffer.st_ctime > daemon_ctime)
03672 {
03673
03674 if (GetDaemonPid() != daemon_pid)
03675 {
03676 Log1(PCSC_LOG_INFO, "PCSC restarted");
03677 need_restart = 1;
03678 }
03679 }
03680
03681
03682 if (client_pid && client_pid != getpid())
03683 {
03684 Log1(PCSC_LOG_INFO, "Client forked");
03685 need_restart = 1;
03686 }
03687
03688 if (need_restart)
03689 {
03690 int i;
03691
03692
03693 SCardLockThread();
03694
03695 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03696 if (psContextMap[i].hContext)
03697 SCardCleanContext(i);
03698
03699 SCardUnlockThread();
03700
03701
03702 daemon_ctime = 0;
03703 client_pid = 0;
03704
03705
03706 SCardUnload();
03707
03708 return SCARD_E_INVALID_HANDLE;
03709 }
03710
03711 daemon_ctime = statBuffer.st_ctime;
03712 daemon_pid = GetDaemonPid();
03713 client_pid = getpid();
03714
03715 return SCARD_S_SUCCESS;
03716 }
03717
03723 #ifdef __SUNPRO_C
03724 #pragma fini (SCardUnload)
03725 #endif
03726
03727 void DESTRUCTOR SCardUnload(void)
03728 {
03729 int i;
03730
03731 if (!isExecuted)
03732 return;
03733
03734
03735 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03736 {
03737 if (readerStates[i] != NULL)
03738 {
03739 SYS_PublicMemoryUnmap(readerStates[i], sizeof(READER_STATE));
03740 readerStates[i] = NULL;
03741 }
03742 }
03743
03744 SYS_CloseFile(mapAddr);
03745 isExecuted = 0;
03746 }
03747