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;
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 (void)mkfifo(filename, 0644);
01738 fd = SYS_OpenFile(filename, O_RDONLY | O_NONBLOCK, 0);
01739
01740 FD_ZERO(&read_fd);
01741 FD_SET(fd, &read_fd);
01742
01743 (void)select(fd+1, &read_fd, NULL, NULL, ptv);
01744
01745 (void)SYS_ReadFile(fd, buf, 1);
01746 (void)SYS_CloseFile(fd);
01747 (void)SYS_RemoveFile(filename);
01748
01749 if (INFINITE != dwTime)
01750 {
01751 long int diff;
01752
01753 gettimeofday(&after, NULL);
01754 diff = time_sub(&after, &before);
01755 dwTime -= diff/1000;
01756 }
01757
01758 return dwTime;
01759 }
01760
01852 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01853 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01854 {
01855 PSCARD_READERSTATE_A currReader;
01856 PREADER_STATE rContext;
01857 long dwTime = dwTimeout;
01858 DWORD dwState;
01859 DWORD dwBreakFlag = 0;
01860 int j;
01861 LONG dwContextIndex;
01862 int currentReaderCount = 0;
01863 LONG rv = SCARD_S_SUCCESS;
01864
01865 PROFILE_START
01866
01867 if ((rgReaderStates == NULL && cReaders > 0)
01868 || (cReaders > PCSCLITE_MAX_READERS_CONTEXTS))
01869 return SCARD_E_INVALID_PARAMETER;
01870
01871
01872 for (j = 0; j < cReaders; j++)
01873 {
01874 if (rgReaderStates[j].szReader == NULL)
01875 return SCARD_E_INVALID_VALUE;
01876 }
01877
01878
01879 if (cReaders > 0)
01880 {
01881 int nbNonIgnoredReaders = cReaders;
01882
01883 for (j=0; j<cReaders; j++)
01884 if (rgReaderStates[j].dwCurrentState & SCARD_STATE_IGNORE)
01885 nbNonIgnoredReaders--;
01886
01887 if (0 == nbNonIgnoredReaders)
01888 return SCARD_S_SUCCESS;
01889 }
01890
01891 rv = SCardCheckDaemonAvailability();
01892 if (rv != SCARD_S_SUCCESS)
01893 return rv;
01894
01895
01896
01897
01898 dwContextIndex = SCardGetContextIndice(hContext);
01899 if (dwContextIndex == -1)
01900 return SCARD_E_INVALID_HANDLE;
01901
01902 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01903
01904
01905 dwContextIndex = SCardGetContextIndice(hContext);
01906 if (dwContextIndex == -1)
01907
01908
01909
01910 return SCARD_E_INVALID_HANDLE;
01911
01912
01913
01914
01915
01916
01917
01918 if (cReaders == 0)
01919 {
01920 while (1)
01921 {
01922 int i;
01923
01924 rv = SCardCheckDaemonAvailability();
01925 if (rv != SCARD_S_SUCCESS)
01926 goto end;
01927
01928 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01929 {
01930 if ((readerStates[i])->readerID != 0)
01931 {
01932
01933 rv = SCARD_S_SUCCESS;
01934 goto end;
01935 }
01936 }
01937
01938 if (dwTimeout == 0)
01939 {
01940
01941 rv = SCARD_E_READER_UNAVAILABLE;
01942 goto end;
01943 }
01944
01945 dwTime = WaitForPcscdEvent(hContext, dwTime);
01946 if (dwTimeout != INFINITE)
01947 {
01948 if (dwTime <= 0)
01949 {
01950 rv = SCARD_E_TIMEOUT;
01951 goto end;
01952 }
01953 }
01954 }
01955 }
01956
01957
01958
01959
01960
01961
01962 for (j = 0; j < cReaders; j++)
01963 rgReaderStates[j].dwEventState = 0;
01964
01965
01966 Log1(PCSC_LOG_DEBUG, "Event Loop Start");
01967
01968 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
01969
01970
01971 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
01972 if ((readerStates[j])->readerID != 0)
01973 currentReaderCount++;
01974
01975 j = 0;
01976 do
01977 {
01978 rv = SCardCheckDaemonAvailability();
01979 if (rv != SCARD_S_SUCCESS)
01980 {
01981 if (psContextMap[dwContextIndex].mMutex)
01982 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01983
01984 PROFILE_END(rv)
01985
01986 return rv;
01987 }
01988
01989 currReader = &rgReaderStates[j];
01990
01991
01992 if (!(currReader->dwCurrentState & SCARD_STATE_IGNORE))
01993 {
01994 LPSTR lpcReaderName;
01995 int i;
01996
01997
01998
01999 lpcReaderName = (char *) currReader->szReader;
02000
02001 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02002 {
02003 if (strcmp(lpcReaderName, (readerStates[i])->readerName) == 0)
02004 break;
02005 }
02006
02007
02008 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02009 {
02010
02011 if (strcasecmp(lpcReaderName, "\\\\?PnP?\\Notification") == 0)
02012 {
02013 int k, newReaderCount = 0;
02014
02015 for (k=0; k < PCSCLITE_MAX_READERS_CONTEXTS; k++)
02016 if ((readerStates[k])->readerID != 0)
02017 newReaderCount++;
02018
02019 if (newReaderCount != currentReaderCount)
02020 {
02021 Log1(PCSC_LOG_INFO, "Reader list changed");
02022 currentReaderCount = newReaderCount;
02023
02024 currReader->dwEventState |= SCARD_STATE_CHANGED;
02025 dwBreakFlag = 1;
02026 }
02027 }
02028 else
02029 {
02030 currReader->dwEventState = SCARD_STATE_UNKNOWN | SCARD_STATE_UNAVAILABLE;
02031 if (!(currReader->dwCurrentState & SCARD_STATE_UNKNOWN))
02032 {
02033 currReader->dwEventState |= SCARD_STATE_CHANGED;
02034
02035
02036
02037
02038
02039 dwBreakFlag = 1;
02040 }
02041 }
02042 }
02043 else
02044 {
02045
02046 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
02047 {
02048 currReader->dwEventState |= SCARD_STATE_CHANGED;
02049 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02050 dwBreakFlag = 1;
02051 }
02052
02053
02054
02055
02056 rContext = readerStates[i];
02057
02058
02059 dwState = rContext->readerState;
02060 {
02061 int currentCounter, stateCounter;
02062
02063 stateCounter = (dwState >> 16) & 0xFFFF;
02064 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
02065
02066
02067 if (stateCounter != currentCounter)
02068 {
02069 currReader->dwEventState |= SCARD_STATE_CHANGED;
02070 dwBreakFlag = 1;
02071 }
02072
02073
02074 currReader->dwEventState =
02075 ((currReader->dwEventState & 0xffff )
02076 | (stateCounter << 16));
02077 }
02078
02079
02080 if (dwState & SCARD_UNKNOWN)
02081 {
02082
02083 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
02084 if (!(currReader->dwCurrentState & SCARD_STATE_UNAVAILABLE))
02085 {
02086
02087 currReader->dwEventState |= SCARD_STATE_CHANGED;
02088 dwBreakFlag = 1;
02089 }
02090 }
02091 else
02092 {
02093
02094 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
02095 {
02096 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02097 currReader->dwEventState |= SCARD_STATE_CHANGED;
02098 dwBreakFlag = 1;
02099 }
02100 }
02101
02102
02103
02104 if (dwState & SCARD_PRESENT)
02105 {
02106
02107 if (0 == rContext->cardAtrLength)
02108
02109 (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
02110
02111 currReader->cbAtr = rContext->cardAtrLength;
02112 memcpy(currReader->rgbAtr, rContext->cardAtr,
02113 currReader->cbAtr);
02114 }
02115 else
02116 currReader->cbAtr = 0;
02117
02118
02119 if (dwState & SCARD_ABSENT)
02120 {
02121 currReader->dwEventState |= SCARD_STATE_EMPTY;
02122 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
02123 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02124 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02125 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02126 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02127 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
02128 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02129 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02130
02131
02132 if (currReader->dwCurrentState & SCARD_STATE_PRESENT)
02133 {
02134 currReader->dwEventState |= SCARD_STATE_CHANGED;
02135 dwBreakFlag = 1;
02136 }
02137 }
02138
02139 else if (dwState & SCARD_PRESENT)
02140 {
02141 currReader->dwEventState |= SCARD_STATE_PRESENT;
02142 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
02143 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
02144 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
02145 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
02146 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
02147 currReader->dwEventState &= ~SCARD_STATE_MUTE;
02148
02149 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
02150 {
02151 currReader->dwEventState |= SCARD_STATE_CHANGED;
02152 dwBreakFlag = 1;
02153 }
02154
02155 if (dwState & SCARD_SWALLOWED)
02156 {
02157 currReader->dwEventState |= SCARD_STATE_MUTE;
02158 if (!(currReader->dwCurrentState & SCARD_STATE_MUTE))
02159 {
02160 currReader->dwEventState |= SCARD_STATE_CHANGED;
02161 dwBreakFlag = 1;
02162 }
02163 }
02164 else
02165 {
02166
02167 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
02168 {
02169 currReader->dwEventState |= SCARD_STATE_CHANGED;
02170 dwBreakFlag = 1;
02171 }
02172 }
02173 }
02174
02175
02176 if (rContext->readerSharing == -1)
02177 {
02178 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
02179 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02180 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02181 {
02182 currReader->dwEventState |= SCARD_STATE_CHANGED;
02183 dwBreakFlag = 1;
02184 }
02185 }
02186 else if (rContext->readerSharing >= 1)
02187 {
02188
02189 if (dwState & SCARD_PRESENT)
02190 {
02191 currReader->dwEventState |= SCARD_STATE_INUSE;
02192 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02193 if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)
02194 {
02195 currReader->dwEventState |= SCARD_STATE_CHANGED;
02196 dwBreakFlag = 1;
02197 }
02198 }
02199 }
02200 else if (rContext->readerSharing == 0)
02201 {
02202 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02203 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02204
02205 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02206 {
02207 currReader->dwEventState |= SCARD_STATE_CHANGED;
02208 dwBreakFlag = 1;
02209 }
02210 else if (currReader-> dwCurrentState
02211 & SCARD_STATE_EXCLUSIVE)
02212 {
02213 currReader->dwEventState |= SCARD_STATE_CHANGED;
02214 dwBreakFlag = 1;
02215 }
02216 }
02217
02218 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02219 {
02220
02221
02222
02223
02224 currReader->dwEventState |= SCARD_STATE_CHANGED;
02225 dwBreakFlag = 1;
02226 }
02227 }
02228 }
02229
02230
02231 j++;
02232 if (j == cReaders)
02233 {
02234
02235 j = 0;
02236
02237
02238
02239
02240 if (dwBreakFlag == 1)
02241 break;
02242
02243 if (BLOCK_STATUS_RESUME
02244 == psContextMap[dwContextIndex].contextBlockStatus)
02245 break;
02246
02247
02248 dwTime = WaitForPcscdEvent(hContext, dwTime);
02249
02250 if (dwTimeout != INFINITE)
02251 {
02252
02253
02254
02255 if (dwTime <= 0)
02256 {
02257 rv = SCARD_E_TIMEOUT;
02258 goto end;
02259 }
02260 }
02261 }
02262 }
02263 while (1);
02264
02265 if (psContextMap[dwContextIndex].contextBlockStatus == BLOCK_STATUS_RESUME)
02266 rv = SCARD_E_CANCELLED;
02267
02268 end:
02269 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02270
02271 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02272
02273 PROFILE_END(rv)
02274
02275 return rv;
02276 }
02277
02329 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02330 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02331 LPDWORD lpBytesReturned)
02332 {
02333 LONG rv;
02334 control_struct scControlStruct;
02335 sharedSegmentMsg msgStruct;
02336 int i;
02337 DWORD dwContextIndex, dwChannelIndex;
02338
02339 PROFILE_START
02340
02341
02342 if (NULL != lpBytesReturned)
02343 *lpBytesReturned = 0;
02344
02345 rv = SCardCheckDaemonAvailability();
02346 if (rv != SCARD_S_SUCCESS)
02347 return rv;
02348
02349
02350
02351
02352 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02353 if (rv == -1)
02354 return SCARD_E_INVALID_HANDLE;
02355
02356 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02357
02358
02359 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02360 if (rv == -1)
02361
02362
02363
02364 return SCARD_E_INVALID_HANDLE;
02365
02366 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02367 {
02368 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02369
02370
02371 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02372 break;
02373 }
02374
02375 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02376 {
02377 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02378 return SCARD_E_READER_UNAVAILABLE;
02379 }
02380
02381 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02382 || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02383 {
02384 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02385 return SCARD_E_INSUFFICIENT_BUFFER;
02386 }
02387
02388 if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
02389 {
02390
02391 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02392 control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
02393 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02394
02395 scControlStructExtended->hCard = hCard;
02396 scControlStructExtended->dwControlCode = dwControlCode;
02397 scControlStructExtended->cbSendLength = cbSendLength;
02398 scControlStructExtended->cbRecvLength = cbRecvLength;
02399 scControlStructExtended->pdwBytesReturned = 0;
02400 scControlStructExtended->rv = SCARD_S_SUCCESS;
02401
02402
02403
02404
02405 scControlStructExtended->size = sizeof(*scControlStructExtended)
02406 - (sizeof(control_struct_extended) - offsetof(control_struct_extended, data))
02407 + cbSendLength;
02408 memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
02409
02410 rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
02411 psContextMap[dwContextIndex].dwClientID,
02412 scControlStructExtended->size,
02413 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02414
02415 if (rv == -1)
02416 {
02417 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02418 return SCARD_E_NO_SERVICE;
02419 }
02420
02421
02422
02423
02424
02425 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg),
02426 psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02427 if (rv == -1)
02428 {
02429 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02430 return SCARD_F_COMM_ERROR;
02431 }
02432
02433
02434 scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
02435
02436
02437 if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02438 {
02439 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02440 scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02441 psContextMap[dwContextIndex].dwClientID,
02442 PCSCLITE_CLIENT_ATTEMPTS);
02443 if (rv == -1)
02444 {
02445 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02446 return SCARD_F_COMM_ERROR;
02447 }
02448 }
02449
02450 if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
02451 {
02452
02453
02454
02455 memcpy(pbRecvBuffer, scControlStructExtended -> data,
02456 scControlStructExtended -> pdwBytesReturned);
02457 memset(scControlStructExtended -> data, 0x00,
02458 scControlStructExtended -> pdwBytesReturned);
02459 }
02460
02461 if (NULL != lpBytesReturned)
02462 *lpBytesReturned = scControlStructExtended -> pdwBytesReturned;
02463
02464 rv = scControlStructExtended -> rv;
02465 }
02466 else
02467 {
02468 scControlStruct.hCard = hCard;
02469 scControlStruct.dwControlCode = dwControlCode;
02470 scControlStruct.cbSendLength = cbSendLength;
02471 scControlStruct.cbRecvLength = cbRecvLength;
02472 memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02473
02474 rv = WrapSHMWrite(SCARD_CONTROL,
02475 psContextMap[dwContextIndex].dwClientID,
02476 sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
02477
02478 if (rv == -1)
02479 {
02480 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02481 return SCARD_E_NO_SERVICE;
02482 }
02483
02484
02485
02486
02487 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02488 PCSCLITE_CLIENT_ATTEMPTS);
02489
02490 if (rv == -1)
02491 {
02492 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02493 return SCARD_F_COMM_ERROR;
02494 }
02495
02496 memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
02497
02498 if (NULL != lpBytesReturned)
02499 *lpBytesReturned = scControlStruct.dwBytesReturned;
02500
02501 if (scControlStruct.rv == SCARD_S_SUCCESS)
02502 {
02503
02504
02505
02506 memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
02507 scControlStruct.cbRecvLength);
02508 memset(scControlStruct.pbRecvBuffer, 0x00,
02509 sizeof(scControlStruct.pbRecvBuffer));
02510 }
02511
02512 rv = scControlStruct.rv;
02513 }
02514
02515 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02516
02517 PROFILE_END(rv)
02518
02519 return rv;
02520 }
02521
02621 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02622 LPDWORD pcbAttrLen)
02623 {
02624 LONG ret;
02625 unsigned char *buf = NULL;
02626
02627 PROFILE_START
02628
02629 if (NULL == pcbAttrLen)
02630 return SCARD_E_INVALID_PARAMETER;
02631
02632 if (SCARD_AUTOALLOCATE == *pcbAttrLen)
02633 {
02634 if (NULL == pbAttr)
02635 return SCARD_E_INVALID_PARAMETER;
02636
02637 *pcbAttrLen = MAX_BUFFER_SIZE;
02638 buf = malloc(*pcbAttrLen);
02639 if (NULL == buf)
02640 return SCARD_E_NO_MEMORY;
02641
02642 *(unsigned char **)pbAttr = buf;
02643 }
02644 else
02645 {
02646 buf = pbAttr;
02647
02648
02649 if (NULL == pbAttr)
02650
02651 *pcbAttrLen = MAX_BUFFER_SIZE;
02652 }
02653
02654 ret = SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, buf,
02655 pcbAttrLen);
02656
02657 PROFILE_END(ret)
02658
02659 return ret;
02660 }
02661
02696 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02697 DWORD cbAttrLen)
02698 {
02699 LONG ret;
02700
02701 PROFILE_START
02702
02703 if (NULL == pbAttr || 0 == cbAttrLen)
02704 return SCARD_E_INVALID_PARAMETER;
02705
02706 ret = SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02707 &cbAttrLen);
02708
02709 PROFILE_END(ret)
02710
02711 return ret;
02712 }
02713
02714 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02715 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02716 {
02717 LONG rv;
02718 getset_struct scGetSetStruct;
02719 sharedSegmentMsg msgStruct;
02720 int i;
02721 DWORD dwContextIndex, dwChannelIndex;
02722
02723 rv = SCardCheckDaemonAvailability();
02724 if (rv != SCARD_S_SUCCESS)
02725 return rv;
02726
02727
02728
02729
02730 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02731 if (rv == -1)
02732 return SCARD_E_INVALID_HANDLE;
02733
02734 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02735
02736
02737 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02738 if (rv == -1)
02739
02740
02741
02742 return SCARD_E_INVALID_HANDLE;
02743
02744 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02745 {
02746 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02747
02748
02749 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02750 break;
02751 }
02752
02753 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02754 {
02755 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02756 return SCARD_E_READER_UNAVAILABLE;
02757 }
02758
02759 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02760 {
02761 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02762 return SCARD_E_INSUFFICIENT_BUFFER;
02763 }
02764
02765 scGetSetStruct.hCard = hCard;
02766 scGetSetStruct.dwAttrId = dwAttrId;
02767 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02768 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02769 memset(scGetSetStruct.pbAttr, 0, sizeof(scGetSetStruct.pbAttr));
02770 if (SCARD_SET_ATTRIB == command)
02771 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02772
02773 rv = WrapSHMWrite(command,
02774 psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
02775 PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
02776
02777 if (rv == -1)
02778 {
02779 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02780 return SCARD_E_NO_SERVICE;
02781 }
02782
02783
02784
02785
02786 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
02787 PCSCLITE_CLIENT_ATTEMPTS);
02788
02789 if (rv == -1)
02790 {
02791 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02792 return SCARD_F_COMM_ERROR;
02793 }
02794
02795 memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
02796
02797 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02798 {
02799
02800
02801
02802 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02803 {
02804 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02805 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02806 }
02807 else
02808 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02809
02810 if (pbAttr)
02811 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02812
02813 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02814 }
02815
02816 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02817
02818 return scGetSetStruct.rv;
02819 }
02820
02879 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02880 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02881 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02882 LPDWORD pcbRecvLength)
02883 {
02884 LONG rv;
02885 int i;
02886 DWORD dwContextIndex, dwChannelIndex;
02887
02888 PROFILE_START
02889
02890 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02891 pcbRecvLength == NULL || pioSendPci == NULL)
02892 return SCARD_E_INVALID_PARAMETER;
02893
02894 rv = SCardCheckDaemonAvailability();
02895 if (rv != SCARD_S_SUCCESS)
02896 return rv;
02897
02898
02899
02900
02901 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02902 if (rv == -1)
02903 {
02904 *pcbRecvLength = 0;
02905 return SCARD_E_INVALID_HANDLE;
02906 }
02907
02908 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02909
02910
02911 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02912 if (rv == -1)
02913
02914
02915
02916 return SCARD_E_INVALID_HANDLE;
02917
02918 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02919 {
02920 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02921
02922
02923 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02924 break;
02925 }
02926
02927 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02928 {
02929 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02930 return SCARD_E_READER_UNAVAILABLE;
02931 }
02932
02933 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02934 || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02935 {
02936 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02937 return SCARD_E_INSUFFICIENT_BUFFER;
02938 }
02939
02940 if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
02941 {
02942
02943 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02944 transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
02945 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02946
02947 scTransmitStructExtended->hCard = hCard;
02948 scTransmitStructExtended->cbSendLength = cbSendLength;
02949 scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
02950
02951
02952
02953
02954 scTransmitStructExtended->size = sizeof(*scTransmitStructExtended)
02955 - (sizeof(transmit_struct_extended) - offsetof(transmit_struct_extended, data))
02956 + cbSendLength;
02957 scTransmitStructExtended->pioSendPciProtocol = pioSendPci->dwProtocol;
02958 scTransmitStructExtended->pioSendPciLength = pioSendPci->cbPciLength;
02959 memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
02960 scTransmitStructExtended->rv = SCARD_S_SUCCESS;
02961
02962 if (pioRecvPci)
02963 {
02964 scTransmitStructExtended->pioRecvPciProtocol = pioRecvPci->dwProtocol;
02965 scTransmitStructExtended->pioRecvPciLength = pioRecvPci->cbPciLength;
02966 }
02967 else
02968 {
02969 scTransmitStructExtended->pioRecvPciProtocol = SCARD_PROTOCOL_ANY;
02970 scTransmitStructExtended->pioRecvPciLength = sizeof(SCARD_IO_REQUEST);
02971 }
02972
02973 rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
02974 psContextMap[dwContextIndex].dwClientID,
02975 scTransmitStructExtended->size,
02976 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02977
02978 if (rv == -1)
02979 {
02980 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02981 return SCARD_E_NO_SERVICE;
02982 }
02983
02984
02985
02986
02987
02988 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02989 if (rv == -1)
02990 {
02991 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02992 return SCARD_F_COMM_ERROR;
02993 }
02994
02995
02996 scTransmitStructExtended = (transmit_struct_extended *)&(pmsgStruct -> data);
02997
02998
02999 if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
03000 {
03001 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
03002 scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
03003 psContextMap[dwContextIndex].dwClientID,
03004 PCSCLITE_CLIENT_ATTEMPTS);
03005 if (rv == -1)
03006 {
03007 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03008 return SCARD_F_COMM_ERROR;
03009 }
03010 }
03011
03012 if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
03013 {
03014
03015
03016
03017 memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
03018 scTransmitStructExtended -> pcbRecvLength);
03019 memset(scTransmitStructExtended -> data, 0x00,
03020 scTransmitStructExtended -> pcbRecvLength);
03021
03022 if (pioRecvPci)
03023 {
03024 pioRecvPci->dwProtocol = scTransmitStructExtended->pioRecvPciProtocol;
03025 pioRecvPci->cbPciLength = scTransmitStructExtended->pioRecvPciLength;
03026 }
03027 }
03028
03029 *pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
03030 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03031
03032 rv = scTransmitStructExtended -> rv;
03033 }
03034 else
03035 {
03036
03037 transmit_struct scTransmitStruct;
03038 sharedSegmentMsg msgStruct;
03039
03040 scTransmitStruct.hCard = hCard;
03041 scTransmitStruct.cbSendLength = cbSendLength;
03042 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
03043 scTransmitStruct.pioSendPciProtocol = pioSendPci->dwProtocol;
03044 scTransmitStruct.pioSendPciLength = pioSendPci->cbPciLength;
03045 memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
03046 memset(scTransmitStruct.pbSendBuffer+cbSendLength, 0, sizeof(scTransmitStruct.pbSendBuffer)-cbSendLength);
03047 memset(scTransmitStruct.pbRecvBuffer, 0, sizeof(scTransmitStruct.pbRecvBuffer));
03048 scTransmitStruct.rv = SCARD_S_SUCCESS;
03049
03050 if (pioRecvPci)
03051 {
03052 scTransmitStruct.pioRecvPciProtocol = pioRecvPci->dwProtocol;
03053 scTransmitStruct.pioRecvPciLength = pioRecvPci->cbPciLength;
03054 }
03055 else
03056 {
03057 scTransmitStruct.pioRecvPciProtocol = SCARD_PROTOCOL_ANY;
03058 scTransmitStruct.pioRecvPciLength = sizeof(SCARD_IO_REQUEST);
03059 }
03060
03061 rv = WrapSHMWrite(SCARD_TRANSMIT,
03062 psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
03063 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
03064
03065 if (rv == -1)
03066 {
03067 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03068 return SCARD_E_NO_SERVICE;
03069 }
03070
03071
03072
03073
03074 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
03075 PCSCLITE_CLIENT_ATTEMPTS);
03076
03077 memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
03078
03079 if (rv == -1)
03080 {
03081 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03082 return SCARD_F_COMM_ERROR;
03083 }
03084
03085
03086
03087
03088 memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
03089
03090 if (scTransmitStruct.rv == SCARD_S_SUCCESS)
03091 {
03092
03093
03094
03095 memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
03096 scTransmitStruct.pcbRecvLength);
03097 memset(scTransmitStruct.pbRecvBuffer, 0x00,
03098 scTransmitStruct.pcbRecvLength);
03099
03100 if (pioRecvPci)
03101 {
03102 pioRecvPci->dwProtocol = scTransmitStruct.pioRecvPciProtocol;
03103 pioRecvPci->cbPciLength = scTransmitStruct.pioRecvPciLength;
03104 }
03105 }
03106
03107 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
03108 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03109
03110 rv = scTransmitStruct.rv;
03111 }
03112
03113 PROFILE_END(rv)
03114
03115 return rv;
03116 }
03117
03166 LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
03167 LPSTR mszReaders, LPDWORD pcchReaders)
03168 {
03169 DWORD dwReadersLen;
03170 int i;
03171 LONG dwContextIndex;
03172 LONG rv = SCARD_S_SUCCESS;
03173 char *buf = NULL;
03174
03175 (void)mszGroups;
03176 PROFILE_START
03177
03178
03179
03180
03181 if (pcchReaders == NULL)
03182 return SCARD_E_INVALID_PARAMETER;
03183
03184 rv = SCardCheckDaemonAvailability();
03185 if (rv != SCARD_S_SUCCESS)
03186 return rv;
03187
03188
03189
03190
03191 dwContextIndex = SCardGetContextIndice(hContext);
03192 if (dwContextIndex == -1)
03193 return SCARD_E_INVALID_HANDLE;
03194
03195 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03196
03197
03198 dwContextIndex = SCardGetContextIndice(hContext);
03199 if (dwContextIndex == -1)
03200
03201
03202
03203 return SCARD_E_INVALID_HANDLE;
03204
03205 dwReadersLen = 0;
03206 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03207 if ((readerStates[i])->readerID != 0)
03208 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
03209
03210
03211 dwReadersLen += 1;
03212
03213 if (1 == dwReadersLen)
03214 {
03215 rv = SCARD_E_NO_READERS_AVAILABLE;
03216 goto end;
03217 }
03218
03219 if (SCARD_AUTOALLOCATE == *pcchReaders)
03220 {
03221 buf = malloc(dwReadersLen);
03222 if (NULL == buf)
03223 {
03224 rv = SCARD_E_NO_MEMORY;
03225 goto end;
03226 }
03227 if (NULL == mszReaders)
03228 {
03229 rv = SCARD_E_INVALID_PARAMETER;
03230 goto end;
03231 }
03232 *(char **)mszReaders = buf;
03233 }
03234 else
03235 {
03236 buf = mszReaders;
03237
03238
03239 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
03240 {
03241 rv = SCARD_E_INSUFFICIENT_BUFFER;
03242 goto end;
03243 }
03244 }
03245
03246 if (mszReaders == NULL)
03247 goto end;
03248
03249 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
03250 {
03251 if ((readerStates[i])->readerID != 0)
03252 {
03253
03254
03255
03256 strcpy(buf, (readerStates[i])->readerName);
03257 buf += strlen((readerStates[i])->readerName)+1;
03258 }
03259 }
03260 *buf = '\0';
03261
03262 end:
03263
03264 *pcchReaders = dwReadersLen;
03265
03266 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03267
03268 PROFILE_END(rv)
03269
03270 return rv;
03271 }
03272
03285 LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
03286 {
03287 LONG rv = SCARD_S_SUCCESS;
03288 LONG dwContextIndex;
03289
03290 PROFILE_START
03291
03292 rv = SCardCheckDaemonAvailability();
03293 if (rv != SCARD_S_SUCCESS)
03294 return rv;
03295
03296
03297
03298
03299 dwContextIndex = SCardGetContextIndice(hContext);
03300 if (dwContextIndex == -1)
03301 return SCARD_E_INVALID_HANDLE;
03302
03303 free((void *)pvMem);
03304
03305 PROFILE_END(rv)
03306
03307 return rv;
03308 }
03309
03359 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
03360 LPDWORD pcchGroups)
03361 {
03362 LONG rv = SCARD_S_SUCCESS;
03363 LONG dwContextIndex;
03364 char *buf = NULL;
03365
03366 PROFILE_START
03367
03368
03369 const char ReaderGroup[] = "SCard$DefaultReaders\0";
03370 const int dwGroups = sizeof(ReaderGroup);
03371
03372 rv = SCardCheckDaemonAvailability();
03373 if (rv != SCARD_S_SUCCESS)
03374 return rv;
03375
03376
03377
03378
03379 dwContextIndex = SCardGetContextIndice(hContext);
03380 if (dwContextIndex == -1)
03381 return SCARD_E_INVALID_HANDLE;
03382
03383 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03384
03385
03386 dwContextIndex = SCardGetContextIndice(hContext);
03387 if (dwContextIndex == -1)
03388
03389
03390
03391 return SCARD_E_INVALID_HANDLE;
03392
03393 if (SCARD_AUTOALLOCATE == *pcchGroups)
03394 {
03395 buf = malloc(dwGroups);
03396 if (NULL == buf)
03397 {
03398 rv = SCARD_E_NO_MEMORY;
03399 goto end;
03400 }
03401 if (NULL == mszGroups)
03402 {
03403 rv = SCARD_E_INVALID_PARAMETER;
03404 goto end;
03405 }
03406 *(char **)mszGroups = buf;
03407 }
03408 else
03409 {
03410 buf = mszGroups;
03411
03412 if ((NULL != mszGroups) && (*pcchGroups < dwGroups))
03413 {
03414 rv = SCARD_E_INSUFFICIENT_BUFFER;
03415 goto end;
03416 }
03417 }
03418
03419 if (buf)
03420 memcpy(buf, ReaderGroup, dwGroups);
03421
03422 end:
03423 *pcchGroups = dwGroups;
03424
03425 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03426
03427 PROFILE_END(rv)
03428
03429 return rv;
03430 }
03431
03459 LONG SCardCancel(SCARDCONTEXT hContext)
03460 {
03461 LONG dwContextIndex;
03462 LONG rv = SCARD_S_SUCCESS;
03463
03464 PROFILE_START
03465
03466 dwContextIndex = SCardGetContextIndice(hContext);
03467 if (dwContextIndex == -1)
03468 return SCARD_E_INVALID_HANDLE;
03469
03470
03471
03472
03473
03474 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
03475
03476 if (StatSynchronizeContext(hContext))
03477 rv = SCARD_F_INTERNAL_ERROR;
03478
03479 PROFILE_END(rv)
03480
03481 return rv;
03482 }
03483
03507 LONG SCardIsValidContext(SCARDCONTEXT hContext)
03508 {
03509 LONG rv;
03510 LONG dwContextIndex;
03511
03512 PROFILE_START
03513
03514 rv = SCARD_S_SUCCESS;
03515
03516
03517 rv = SCardCheckDaemonAvailability();
03518 if (rv != SCARD_S_SUCCESS)
03519 return rv;
03520
03521
03522
03523
03524 dwContextIndex = SCardGetContextIndice(hContext);
03525 if (dwContextIndex == -1)
03526 rv = SCARD_E_INVALID_HANDLE;
03527
03528 PROFILE_END(rv)
03529
03530 return rv;
03531 }
03532
03549 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
03550 {
03551 int i;
03552
03553 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03554 {
03555 if (psContextMap[i].hContext == 0)
03556 {
03557 psContextMap[i].hContext = hContext;
03558 psContextMap[i].dwClientID = dwClientID;
03559 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
03560 psContextMap[i].mMutex = malloc(sizeof(PCSCLITE_MUTEX));
03561 (void)SYS_MutexInit(psContextMap[i].mMutex);
03562 return SCARD_S_SUCCESS;
03563 }
03564 }
03565
03566 return SCARD_E_NO_MEMORY;
03567 }
03568
03581 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
03582 {
03583 LONG rv;
03584
03585 (void)SCardLockThread();
03586 rv = SCardGetContextIndiceTH(hContext);
03587 (void)SCardUnlockThread();
03588
03589 return rv;
03590 }
03591
03604 static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
03605 {
03606 int i;
03607
03608
03609
03610
03611 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03612 {
03613 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
03614 return i;
03615 }
03616
03617 return -1;
03618 }
03619
03629 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
03630 {
03631 LONG retIndice;
03632
03633 retIndice = SCardGetContextIndiceTH(hContext);
03634
03635 if (retIndice == -1)
03636 return SCARD_E_INVALID_HANDLE;
03637 else
03638 return SCardCleanContext(retIndice);
03639 }
03640
03641 static LONG SCardCleanContext(LONG indice)
03642 {
03643 int i;
03644
03645 psContextMap[indice].hContext = 0;
03646 (void)SHMClientCloseSession(psContextMap[indice].dwClientID);
03647 psContextMap[indice].dwClientID = 0;
03648 free(psContextMap[indice].mMutex);
03649 psContextMap[indice].mMutex = NULL;
03650 psContextMap[indice].contextBlockStatus = BLOCK_STATUS_RESUME;
03651
03652 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03653 {
03654
03655
03656
03657 psContextMap[indice].psChannelMap[i].hCard = 0;
03658 free(psContextMap[indice].psChannelMap[i].readerName);
03659 psContextMap[indice].psChannelMap[i].readerName = NULL;
03660 }
03661
03662 return SCARD_S_SUCCESS;
03663 }
03664
03665
03666
03667
03668
03669 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
03670 LPCSTR readerName)
03671 {
03672 int i;
03673
03674 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03675 {
03676 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
03677 {
03678 psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
03679 psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
03680 return SCARD_S_SUCCESS;
03681 }
03682 }
03683
03684 return SCARD_E_NO_MEMORY;
03685 }
03686
03687 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03688 {
03689 DWORD dwContextIndice, dwChannelIndice;
03690 LONG rv;
03691
03692 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
03693 if (rv == -1)
03694 return SCARD_E_INVALID_HANDLE;
03695 else
03696 {
03697 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
03698 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
03699 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
03700 return SCARD_S_SUCCESS;
03701 }
03702 }
03703
03704 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard,
03705 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03706 {
03707 LONG rv;
03708
03709 if (0 == hCard)
03710 return -1;
03711
03712 (void)SCardLockThread();
03713 rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
03714 (void)SCardUnlockThread();
03715
03716 return rv;
03717 }
03718
03719 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard,
03720 PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03721 {
03722 int i;
03723
03724 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03725 {
03726 if (psContextMap[i].hContext != 0)
03727 {
03728 int j;
03729
03730 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
03731 {
03732 if (psContextMap[i].psChannelMap[j].hCard == hCard)
03733 {
03734 *pdwContextIndice = i;
03735 *pdwChannelIndice = j;
03736 return SCARD_S_SUCCESS;
03737 }
03738 }
03739
03740 }
03741 }
03742
03743 return -1;
03744 }
03745
03754 LONG SCardCheckDaemonAvailability(void)
03755 {
03756 LONG rv;
03757 struct stat statBuffer;
03758 int need_restart = 0;
03759
03760 rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &statBuffer);
03761
03762 if (rv != 0)
03763 {
03764 Log2(PCSC_LOG_INFO, "PCSC Not Running: " PCSCLITE_PUBSHM_FILE ": %s",
03765 strerror(errno));
03766 return SCARD_E_NO_SERVICE;
03767 }
03768
03769
03770
03771 if (daemon_ctime && statBuffer.st_ctime > daemon_ctime)
03772 {
03773
03774 if (GetDaemonPid() != daemon_pid)
03775 {
03776 Log1(PCSC_LOG_INFO, "PCSC restarted");
03777 need_restart = 1;
03778 }
03779 }
03780
03781
03782 if (client_pid && client_pid != getpid())
03783 {
03784 Log1(PCSC_LOG_INFO, "Client forked");
03785 need_restart = 1;
03786 }
03787
03788 if (need_restart)
03789 {
03790 int i;
03791
03792
03793 (void)SCardLockThread();
03794
03795 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03796 if (psContextMap[i].hContext)
03797 (void)SCardCleanContext(i);
03798
03799 (void)SCardUnlockThread();
03800
03801
03802 daemon_ctime = 0;
03803 client_pid = 0;
03804
03805
03806 SCardUnload();
03807
03808 return SCARD_E_INVALID_HANDLE;
03809 }
03810
03811 daemon_ctime = statBuffer.st_ctime;
03812 daemon_pid = GetDaemonPid();
03813 client_pid = getpid();
03814
03815 return SCARD_S_SUCCESS;
03816 }
03817
03824 #ifdef __SUNPRO_C
03825 #pragma fini (SCardUnload)
03826 #endif
03827
03828 void DESTRUCTOR SCardUnload(void)
03829 {
03830 int i;
03831
03832 if (!isExecuted)
03833 return;
03834
03835
03836 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03837 {
03838 if (readerStates[i] != NULL)
03839 {
03840 SYS_PublicMemoryUnmap(readerStates[i], sizeof(READER_STATE));
03841 readerStates[i] = NULL;
03842 }
03843 }
03844
03845 (void)SYS_CloseFile(mapAddr);
03846 isExecuted = 0;
03847 }
03848