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