00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00020 #include "config.h"
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <sys/types.h>
00024 #include <fcntl.h>
00025 #include <unistd.h>
00026 #include <sys/un.h>
00027 #include <errno.h>
00028
00029 #include "misc.h"
00030 #include "pcsclite.h"
00031 #include "winscard.h"
00032 #include "debug.h"
00033 #include "thread_generic.h"
00034
00035 #include "readerfactory.h"
00036 #include "eventhandler.h"
00037 #include "sys_generic.h"
00038 #include "winscard_msg.h"
00039
00041 #define SCARD_PROTOCOL_ANY_OLD 0x1000
00042
00043 #ifndef min
00044 #define min(a,b) (((a) < (b)) ? (a) : (b))
00045 #endif
00046
00047 #ifndef TRUE
00048 #define TRUE 1
00049 #define FALSE 0
00050 #endif
00051
00052 #undef DO_PROFILE
00053 #ifdef DO_PROFILE
00054
00055 #define PROFILE_FILE "/tmp/pcsc_profile"
00056 #include <stdio.h>
00057 #include <sys/time.h>
00058
00059 struct timeval profile_time_start;
00060 FILE *fd;
00061 char profile_tty;
00062
00063 #define PROFILE_START profile_start(__FUNCTION__);
00064 #define PROFILE_END profile_end(__FUNCTION__);
00065
00066 static void profile_start(const char *f)
00067 {
00068 static char initialized = FALSE;
00069
00070 if (!initialized)
00071 {
00072 initialized = TRUE;
00073 fd = fopen(PROFILE_FILE, "a+");
00074 if (NULL == fd)
00075 {
00076 fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n",
00077 PROFILE_FILE, strerror(errno));
00078 exit(-1);
00079 }
00080 fprintf(fd, "\nStart a new profile\n");
00081
00082 if (isatty(fileno(stderr)))
00083 profile_tty = TRUE;
00084 else
00085 profile_tty = FALSE;
00086 }
00087
00088 gettimeofday(&profile_time_start, NULL);
00089 }
00090
00091
00092 static long int time_sub(struct timeval *a, struct timeval *b)
00093 {
00094 struct timeval r;
00095 r.tv_sec = a -> tv_sec - b -> tv_sec;
00096 r.tv_usec = a -> tv_usec - b -> tv_usec;
00097 if (r.tv_usec < 0)
00098 {
00099 r.tv_sec--;
00100 r.tv_usec += 1000000;
00101 }
00102
00103 return r.tv_sec * 1000000 + r.tv_usec;
00104 }
00105
00106
00107 static void profile_end(const char *f)
00108 {
00109 struct timeval profile_time_end;
00110 long d;
00111
00112 gettimeofday(&profile_time_end, NULL);
00113 d = time_sub(&profile_time_end, &profile_time_start);
00114
00115 if (profile_tty)
00116 fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m\n", f, d);
00117 fprintf(fd, "%s %ld\n", f, d);
00118 }
00119
00120 #else
00121 #define PROFILE_START
00122 #define PROFILE_END
00123 #endif
00124
00129 struct _psChannelMap
00130 {
00131 SCARDHANDLE hCard;
00132 LPSTR readerName;
00133 };
00134
00135 typedef struct _psChannelMap CHANNEL_MAP, *PCHANNEL_MAP;
00136
00142 static struct _psContextMap
00143 {
00144 DWORD dwClientID;
00145 SCARDCONTEXT hContext;
00146 DWORD contextBlockStatus;
00147 PCSCLITE_MUTEX_T mMutex;
00148 CHANNEL_MAP psChannelMap[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
00149 } psContextMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
00150
00154 static short isExecuted = 0;
00155
00161 static int mapAddr = 0;
00162
00167 static PCSCLITE_MUTEX clientMutex = PTHREAD_MUTEX_INITIALIZER;
00168
00175 static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
00176
00177 PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
00178 PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
00179 PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
00180
00181
00182 static LONG SCardAddContext(SCARDCONTEXT, DWORD);
00183 static LONG SCardGetContextIndice(SCARDCONTEXT);
00184 static LONG SCardGetContextIndiceTH(SCARDCONTEXT);
00185 static LONG SCardRemoveContext(SCARDCONTEXT);
00186
00187 static LONG SCardAddHandle(SCARDHANDLE, DWORD, LPSTR);
00188 static LONG SCardGetIndicesFromHandle(SCARDHANDLE, PDWORD, PDWORD);
00189 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE, PDWORD, PDWORD);
00190 static LONG SCardRemoveHandle(SCARDHANDLE);
00191
00192 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
00193 LPBYTE pbAttr, LPDWORD pcbAttrLen);
00194
00195 static LONG SCardCheckDaemonAvailability(void);
00196
00197
00198
00199
00200 inline static LONG SCardLockThread(void);
00201 inline static LONG SCardUnlockThread(void);
00202
00203 static LONG SCardEstablishContextTH(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
00204
00237 LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
00238 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00239 {
00240 LONG rv;
00241
00242 PROFILE_START
00243
00244 SCardLockThread();
00245 rv = SCardEstablishContextTH(dwScope, pvReserved1,
00246 pvReserved2, phContext);
00247 SCardUnlockThread();
00248
00249 PROFILE_END
00250
00251 return rv;
00252 }
00253
00279 static LONG SCardEstablishContextTH(DWORD dwScope, LPCVOID pvReserved1,
00280 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00281 {
00282 LONG rv;
00283 int i;
00284 establish_struct scEstablishStruct;
00285 sharedSegmentMsg msgStruct;
00286 DWORD dwClientID = 0;
00287
00288 if (phContext == NULL)
00289 return SCARD_E_INVALID_PARAMETER;
00290 else
00291 *phContext = 0;
00292
00293
00294 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00295 return SCARD_E_NO_SERVICE;
00296
00297
00298
00299
00300
00301
00302
00303
00304 if (isExecuted == 0)
00305 {
00306 int pageSize;
00307
00308
00309
00310
00311 SYS_Initialize();
00312
00313
00314
00315
00316 mapAddr = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDONLY, 0);
00317 if (mapAddr < 0)
00318 {
00319 Log2(PCSC_LOG_CRITICAL, "Cannot open public shared file: %s",
00320 PCSCLITE_PUBSHM_FILE);
00321 return SCARD_E_NO_SERVICE;
00322 }
00323
00324 pageSize = SYS_GetPageSize();
00325
00326
00327
00328
00329 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00330 {
00331 readerStates[i] =
00332 (PREADER_STATE)SYS_PublicMemoryMap(sizeof(READER_STATE),
00333 mapAddr, (i * pageSize));
00334 if (readerStates[i] == NULL)
00335 {
00336 Log1(PCSC_LOG_CRITICAL, "Cannot public memory map");
00337 SYS_CloseFile(mapAddr);
00338 return SCARD_F_INTERNAL_ERROR;
00339 }
00340 }
00341
00342
00343
00344
00345 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00346 {
00347 int j;
00348
00349
00350
00351
00352 psContextMap[i].dwClientID = 0;
00353 psContextMap[i].hContext = 0;
00354 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
00355 psContextMap[i].mMutex = NULL;
00356
00357 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
00358 {
00359
00360
00361
00362 psContextMap[i].psChannelMap[j].hCard = 0;
00363 psContextMap[i].psChannelMap[j].readerName = NULL;
00364 }
00365 }
00366
00367 }
00368
00369
00370
00371
00372
00373 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00374 {
00375 if (psContextMap[i].dwClientID == 0)
00376 break;
00377 }
00378
00379 if (i == PCSCLITE_MAX_APPLICATION_CONTEXTS)
00380 {
00381 return SCARD_E_NO_MEMORY;
00382 }
00383
00384
00385 if (SHMClientSetupSession(&dwClientID) != 0)
00386 {
00387 SYS_CloseFile(mapAddr);
00388 return SCARD_E_NO_SERVICE;
00389 }
00390
00391 {
00392 sharedSegmentMsg msgStruct;
00393 version_struct *veStr;
00394
00395 memset(&msgStruct, 0, sizeof(msgStruct));
00396 msgStruct.mtype = CMD_VERSION;
00397 msgStruct.user_id = SYS_GetUID();
00398 msgStruct.group_id = SYS_GetGID();
00399 msgStruct.command = 0;
00400 msgStruct.date = time(NULL);
00401
00402 veStr = (version_struct *) msgStruct.data;
00403 veStr->major = PROTOCOL_VERSION_MAJOR;
00404 veStr->minor = PROTOCOL_VERSION_MINOR;
00405
00406 if (-1 == SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
00407 PCSCLITE_MCLIENT_ATTEMPTS))
00408 return SCARD_E_NO_SERVICE;
00409
00410
00411
00412
00413 if (-1 == SHMMessageReceive(&msgStruct, sizeof(msgStruct), dwClientID,
00414 PCSCLITE_CLIENT_ATTEMPTS))
00415 {
00416 Log1(PCSC_LOG_CRITICAL, "Your pcscd is too old and does not support CMD_VERSION");
00417 return SCARD_F_COMM_ERROR;
00418 }
00419
00420 Log3(PCSC_LOG_INFO, "Server is protocol version %d:%d",
00421 veStr->major, veStr->minor);
00422
00423 if (veStr->rv != SCARD_S_SUCCESS)
00424 return veStr->rv;
00425
00426 isExecuted = 1;
00427 }
00428
00429
00430 if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
00431 dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
00432 {
00433 return SCARD_E_INVALID_VALUE;
00434 }
00435
00436
00437
00438
00439 scEstablishStruct.dwScope = dwScope;
00440 scEstablishStruct.phContext = 0;
00441 scEstablishStruct.rv = 0;
00442
00443 rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
00444 sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
00445 (void *) &scEstablishStruct);
00446
00447 if (rv == -1)
00448 return SCARD_E_NO_SERVICE;
00449
00450
00451
00452
00453 rv = SHMClientRead(&msgStruct, dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00454
00455 if (rv == -1)
00456 return SCARD_F_COMM_ERROR;
00457
00458 memcpy(&scEstablishStruct, &msgStruct.data, sizeof(scEstablishStruct));
00459
00460 if (scEstablishStruct.rv != SCARD_S_SUCCESS)
00461 return scEstablishStruct.rv;
00462
00463 *phContext = scEstablishStruct.phContext;
00464
00465
00466
00467
00468 rv = SCardAddContext(*phContext, dwClientID);
00469
00470 return rv;
00471 }
00472
00491 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00492 {
00493 LONG rv;
00494 release_struct scReleaseStruct;
00495 sharedSegmentMsg msgStruct;
00496 LONG dwContextIndex;
00497
00498 PROFILE_START
00499
00500 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00501 return SCARD_E_NO_SERVICE;
00502
00503
00504
00505
00506 dwContextIndex = SCardGetContextIndice(hContext);
00507 if (dwContextIndex == -1)
00508 return SCARD_E_INVALID_HANDLE;
00509
00510 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00511
00512 scReleaseStruct.hContext = hContext;
00513 scReleaseStruct.rv = 0;
00514
00515 rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT, psContextMap[dwContextIndex].dwClientID,
00516 sizeof(scReleaseStruct),
00517 PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);
00518
00519 if (rv == -1)
00520 {
00521 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00522 return SCARD_E_NO_SERVICE;
00523 }
00524
00525
00526
00527
00528 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00529 memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));
00530
00531 if (rv == -1)
00532 {
00533 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00534 return SCARD_F_COMM_ERROR;
00535 }
00536
00537 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00538
00539
00540
00541
00542 SCardLockThread();
00543 SCardRemoveContext(hContext);
00544 SCardUnlockThread();
00545
00546 PROFILE_END
00547
00548 return scReleaseStruct.rv;
00549 }
00550
00563 LONG SCardSetTimeout(SCARDCONTEXT hContext, DWORD dwTimeout)
00564 {
00565
00566
00567
00568
00569 return SCARD_S_SUCCESS;
00570 }
00571
00622 LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,
00623 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00624 LPDWORD pdwActiveProtocol)
00625 {
00626 LONG rv;
00627 connect_struct scConnectStruct;
00628 sharedSegmentMsg msgStruct;
00629 LONG dwContextIndex;
00630
00631 PROFILE_START
00632
00633
00634
00635
00636 if (phCard == NULL || pdwActiveProtocol == NULL)
00637 return SCARD_E_INVALID_PARAMETER;
00638 else
00639 *phCard = 0;
00640
00641 if (szReader == NULL)
00642 return SCARD_E_UNKNOWN_READER;
00643
00644
00645
00646
00647 if (strlen(szReader) > MAX_READERNAME)
00648 return SCARD_E_INVALID_VALUE;
00649
00650 if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00651 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00652 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00653 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00654 {
00655 return SCARD_E_INVALID_VALUE;
00656 }
00657
00658 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00659 return SCARD_E_NO_SERVICE;
00660
00661
00662
00663
00664 dwContextIndex = SCardGetContextIndice(hContext);
00665 if (dwContextIndex == -1)
00666 return SCARD_E_INVALID_HANDLE;
00667
00668 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00669
00670 strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);
00671
00672 scConnectStruct.hContext = hContext;
00673 scConnectStruct.dwShareMode = dwShareMode;
00674 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00675 scConnectStruct.phCard = *phCard;
00676 scConnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00677
00678 rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
00679 sizeof(scConnectStruct),
00680 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);
00681
00682 if (rv == -1)
00683 {
00684 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00685 return SCARD_E_NO_SERVICE;
00686 }
00687
00688
00689
00690
00691 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00692
00693 memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));
00694
00695 if (rv == -1)
00696 {
00697 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00698 return SCARD_F_COMM_ERROR;
00699 }
00700
00701 *phCard = scConnectStruct.phCard;
00702 *pdwActiveProtocol = scConnectStruct.pdwActiveProtocol;
00703
00704 if (scConnectStruct.rv == SCARD_S_SUCCESS)
00705 {
00706
00707
00708
00709 rv = SCardAddHandle(*phCard, dwContextIndex, (LPSTR) szReader);
00710 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00711
00712 PROFILE_END
00713
00714 return rv;
00715 }
00716
00717 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00718
00719 PROFILE_END
00720
00721 return scConnectStruct.rv;
00722 }
00723
00791 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00792 DWORD dwPreferredProtocols, DWORD dwInitialization,
00793 LPDWORD pdwActiveProtocol)
00794 {
00795 LONG rv;
00796 reconnect_struct scReconnectStruct;
00797 sharedSegmentMsg msgStruct;
00798 int i;
00799 DWORD dwContextIndex, dwChannelIndex;
00800
00801 PROFILE_START
00802
00803 if (dwInitialization != SCARD_LEAVE_CARD &&
00804 dwInitialization != SCARD_RESET_CARD &&
00805 dwInitialization != SCARD_UNPOWER_CARD &&
00806 dwInitialization != SCARD_EJECT_CARD)
00807 {
00808 return SCARD_E_INVALID_VALUE;
00809 }
00810
00811 if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00812 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00813 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00814 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00815 {
00816 return SCARD_E_INVALID_VALUE;
00817 }
00818
00819 if (pdwActiveProtocol == NULL)
00820 return SCARD_E_INVALID_PARAMETER;
00821
00822 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00823 return SCARD_E_NO_SERVICE;
00824
00825
00826
00827
00828 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00829
00830 if (rv == -1)
00831 return SCARD_E_INVALID_HANDLE;
00832
00833 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00834
00835
00836 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00837 {
00838 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
00839
00840
00841 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
00842 break;
00843 }
00844
00845 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00846 {
00847 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00848 return SCARD_E_READER_UNAVAILABLE;
00849 }
00850
00851 scReconnectStruct.hCard = hCard;
00852 scReconnectStruct.dwShareMode = dwShareMode;
00853 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00854 scReconnectStruct.dwInitialization = dwInitialization;
00855 scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00856
00857 rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
00858 sizeof(scReconnectStruct),
00859 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
00860
00861 if (rv == -1)
00862 {
00863 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00864 return SCARD_E_NO_SERVICE;
00865 }
00866
00867
00868
00869
00870 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00871
00872 memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
00873
00874 if (rv == -1)
00875 {
00876 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00877 return SCARD_F_COMM_ERROR;
00878 }
00879
00880 *pdwActiveProtocol = scReconnectStruct.pdwActiveProtocol;
00881
00882 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00883
00884 PROFILE_END
00885
00886 return scReconnectStruct.rv;
00887 }
00888
00919 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
00920 {
00921 LONG rv;
00922 disconnect_struct scDisconnectStruct;
00923 sharedSegmentMsg msgStruct;
00924 DWORD dwContextIndex, dwChannelIndex;
00925
00926 PROFILE_START
00927
00928 if (dwDisposition != SCARD_LEAVE_CARD &&
00929 dwDisposition != SCARD_RESET_CARD &&
00930 dwDisposition != SCARD_UNPOWER_CARD &&
00931 dwDisposition != SCARD_EJECT_CARD)
00932 {
00933 return SCARD_E_INVALID_VALUE;
00934 }
00935
00936 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00937 return SCARD_E_NO_SERVICE;
00938
00939
00940
00941
00942 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00943
00944 if (rv == -1)
00945 return SCARD_E_INVALID_HANDLE;
00946
00947 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00948
00949 scDisconnectStruct.hCard = hCard;
00950 scDisconnectStruct.dwDisposition = dwDisposition;
00951
00952 rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
00953 sizeof(scDisconnectStruct),
00954 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
00955
00956 if (rv == -1)
00957 {
00958 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00959 return SCARD_E_NO_SERVICE;
00960 }
00961
00962
00963
00964
00965 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00966
00967 memcpy(&scDisconnectStruct, &msgStruct.data,
00968 sizeof(scDisconnectStruct));
00969
00970 if (rv == -1)
00971 {
00972 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00973 return SCARD_F_COMM_ERROR;
00974 }
00975
00976 SCardRemoveHandle(hCard);
00977
00978 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00979
00980 PROFILE_END
00981
00982 return scDisconnectStruct.rv;
00983 }
00984
01017 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01018 {
01019
01020 LONG rv;
01021 begin_struct scBeginStruct;
01022 int i;
01023 sharedSegmentMsg msgStruct;
01024 DWORD dwContextIndex, dwChannelIndex;
01025
01026 PROFILE_START
01027
01028 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01029 return SCARD_E_NO_SERVICE;
01030
01031
01032
01033
01034 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01035
01036 if (rv == -1)
01037 return SCARD_E_INVALID_HANDLE;
01038
01039 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01040
01041 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01042 {
01043 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01044
01045
01046 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01047 break;
01048 }
01049
01050 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01051 {
01052 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01053 return SCARD_E_READER_UNAVAILABLE;
01054 }
01055
01056 scBeginStruct.hCard = hCard;
01057
01058
01059
01060
01061
01062
01063 do
01064 {
01065
01066
01067
01068
01069 if ((readerStates[i])->lockState != 0)
01070 {
01071 int randnum = 0;
01072 int j;
01073
01074 for (j = 0; j < 100; j++)
01075 {
01076
01077
01078
01079 randnum = SYS_RandomInt(1000, 10000);
01080 SYS_USleep(randnum);
01081
01082 if ((readerStates[i])->lockState == 0)
01083 {
01084 break;
01085 }
01086 }
01087 }
01088
01089 rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01090 sizeof(scBeginStruct),
01091 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);
01092
01093 if (rv == -1)
01094 {
01095
01096 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01097 return SCARD_E_NO_SERVICE;
01098 }
01099
01100
01101
01102
01103 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01104
01105
01106 memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));
01107
01108 if (rv == -1)
01109 {
01110
01111 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01112 return SCARD_F_COMM_ERROR;
01113 }
01114
01115 }
01116 while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
01117
01118 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01119
01120 PROFILE_END
01121
01122 return scBeginStruct.rv;
01123 }
01124
01163 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01164 {
01165 LONG rv;
01166 end_struct scEndStruct;
01167 sharedSegmentMsg msgStruct;
01168 int randnum, i;
01169 DWORD dwContextIndex, dwChannelIndex;
01170
01171 PROFILE_START
01172
01173
01174
01175
01176 randnum = 0;
01177
01178 if (dwDisposition != SCARD_LEAVE_CARD &&
01179 dwDisposition != SCARD_RESET_CARD &&
01180 dwDisposition != SCARD_UNPOWER_CARD &&
01181 dwDisposition != SCARD_EJECT_CARD)
01182 {
01183 return SCARD_E_INVALID_VALUE;
01184 }
01185
01186 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01187 return SCARD_E_NO_SERVICE;
01188
01189
01190
01191
01192 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01193
01194 if (rv == -1)
01195 return SCARD_E_INVALID_HANDLE;
01196
01197 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01198
01199 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01200 {
01201 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01202
01203
01204 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01205 break;
01206 }
01207
01208 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01209 {
01210 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01211 return SCARD_E_READER_UNAVAILABLE;
01212 }
01213
01214 scEndStruct.hCard = hCard;
01215 scEndStruct.dwDisposition = dwDisposition;
01216
01217 rv = WrapSHMWrite(SCARD_END_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01218 sizeof(scEndStruct),
01219 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
01220
01221 if (rv == -1)
01222 {
01223 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01224 return SCARD_E_NO_SERVICE;
01225 }
01226
01227
01228
01229
01230 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01231
01232 memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
01233
01234 if (rv == -1)
01235 {
01236 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01237 return SCARD_F_COMM_ERROR;
01238 }
01239
01240
01241
01242
01243 randnum = SYS_RandomInt(1000, 10000);
01244 SYS_USleep(randnum);
01245
01246 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01247
01248 PROFILE_END
01249
01250 return scEndStruct.rv;
01251 }
01252
01258 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01259 {
01260 LONG rv;
01261 cancel_struct scCancelStruct;
01262 sharedSegmentMsg msgStruct;
01263 int i;
01264 DWORD dwContextIndex, dwChannelIndex;
01265
01266 PROFILE_START
01267
01268 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01269 return SCARD_E_NO_SERVICE;
01270
01271
01272
01273
01274 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01275
01276 if (rv == -1)
01277 return SCARD_E_INVALID_HANDLE;
01278
01279 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01280
01281 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01282 {
01283 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01284
01285
01286 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01287 break;
01288 }
01289
01290 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01291 {
01292 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01293 return SCARD_E_READER_UNAVAILABLE;
01294 }
01295
01296 scCancelStruct.hCard = hCard;
01297
01298 rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01299 sizeof(scCancelStruct),
01300 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
01301
01302 if (rv == -1)
01303 {
01304 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01305 return SCARD_E_NO_SERVICE;
01306 }
01307
01308
01309
01310
01311 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01312
01313 memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
01314
01315 if (rv == -1)
01316 {
01317 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01318 return SCARD_F_COMM_ERROR;
01319 }
01320
01321 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01322
01323 PROFILE_END
01324
01325 return scCancelStruct.rv;
01326 }
01327
01385 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames,
01386 LPDWORD pcchReaderLen, LPDWORD pdwState,
01387 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
01388 {
01389 DWORD dwReaderLen, dwAtrLen;
01390 LONG rv;
01391 int i;
01392 status_struct scStatusStruct;
01393 sharedSegmentMsg msgStruct;
01394 DWORD dwContextIndex, dwChannelIndex;
01395 char *r;
01396
01397 PROFILE_START
01398
01399
01400
01401
01402
01403 if (pcchReaderLen == NULL || pcbAtrLen == NULL)
01404 return SCARD_E_INVALID_PARAMETER;
01405
01406
01407 dwReaderLen = *pcchReaderLen;
01408 dwAtrLen = *pcbAtrLen;
01409
01410
01411 if (pdwState)
01412 *pdwState = 0;
01413
01414 if (pdwProtocol)
01415 *pdwProtocol = 0;
01416
01417 *pcchReaderLen = 0;
01418 *pcbAtrLen = 0;
01419
01420 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01421 return SCARD_E_NO_SERVICE;
01422
01423
01424
01425
01426 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01427
01428 if (rv == -1)
01429 return SCARD_E_INVALID_HANDLE;
01430
01431 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01432
01433 r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01434 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01435 {
01436
01437 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01438 break;
01439 }
01440
01441 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01442 {
01443 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01444 return SCARD_E_READER_UNAVAILABLE;
01445 }
01446
01447
01448 memset(&scStatusStruct, 0, sizeof(scStatusStruct));
01449 scStatusStruct.hCard = hCard;
01450
01451
01452 scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
01453 scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
01454
01455 rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
01456 sizeof(scStatusStruct),
01457 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
01458
01459 if (rv == -1)
01460 {
01461 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01462 return SCARD_E_NO_SERVICE;
01463 }
01464
01465
01466
01467
01468 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01469
01470 memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
01471
01472 if (rv == -1)
01473 {
01474 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01475 return SCARD_F_COMM_ERROR;
01476 }
01477
01478 rv = scStatusStruct.rv;
01479 if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
01480 {
01481
01482
01483
01484 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01485 return rv;
01486 }
01487
01488
01489
01490
01491
01492 *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
01493 *pcbAtrLen = (readerStates[i])->cardAtrLength;
01494
01495 if (pdwState)
01496 *pdwState = (readerStates[i])->readerState;
01497
01498 if (pdwProtocol)
01499 *pdwProtocol = (readerStates[i])->cardProtocol;
01500
01501
01502 if (mszReaderNames)
01503 {
01504 if (*pcchReaderLen > dwReaderLen)
01505 rv = SCARD_E_INSUFFICIENT_BUFFER;
01506
01507 strncpy(mszReaderNames,
01508 psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
01509 dwReaderLen);
01510 }
01511
01512 if (pbAtr)
01513 {
01514 if (*pcbAtrLen > dwAtrLen)
01515 rv = SCARD_E_INSUFFICIENT_BUFFER;
01516
01517 memcpy(pbAtr, (readerStates[i])->cardAtr,
01518 min(*pcbAtrLen, dwAtrLen));
01519 }
01520
01521 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01522
01523 PROFILE_END
01524
01525 return rv;
01526 }
01527
01613 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01614 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01615 {
01616 PSCARD_READERSTATE_A currReader;
01617 PREADER_STATE rContext;
01618 DWORD dwTime = 0;
01619 DWORD dwState;
01620 DWORD dwBreakFlag = 0;
01621 int j;
01622 LONG dwContextIndex;
01623 int currentReaderCount = 0;
01624
01625 PROFILE_START
01626
01627 if (rgReaderStates == NULL && cReaders > 0)
01628 return SCARD_E_INVALID_PARAMETER;
01629
01630 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01631 return SCARD_E_NO_SERVICE;
01632
01633
01634
01635
01636
01637 dwContextIndex = SCardGetContextIndice(hContext);
01638 if (dwContextIndex == -1)
01639 return SCARD_E_INVALID_HANDLE;
01640
01641 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01642
01643
01644
01645
01646
01647
01648 if (cReaders == 0)
01649 {
01650 while (1)
01651 {
01652 int i;
01653
01654 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01655 {
01656 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01657 return SCARD_E_NO_SERVICE;
01658 }
01659
01660 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01661 {
01662 if ((readerStates[i])->readerID != 0)
01663 {
01664
01665
01666
01667 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01668
01669 PROFILE_END
01670
01671 return SCARD_S_SUCCESS;
01672 }
01673 }
01674
01675 if (dwTimeout == 0)
01676 {
01677
01678
01679
01680 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01681 return SCARD_E_READER_UNAVAILABLE;
01682 }
01683
01684 SYS_USleep(PCSCLITE_STATUS_WAIT);
01685
01686 if (dwTimeout != INFINITE)
01687 {
01688 dwTime += PCSCLITE_STATUS_WAIT;
01689
01690 if (dwTime >= (dwTimeout * 1000))
01691 {
01692 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01693
01694 PROFILE_END
01695
01696 return SCARD_E_TIMEOUT;
01697 }
01698 }
01699 }
01700 }
01701 else
01702 if (cReaders >= PCSCLITE_MAX_READERS_CONTEXTS)
01703 {
01704 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01705 return SCARD_E_INVALID_VALUE;
01706 }
01707
01708
01709
01710
01711
01712 for (j = 0; j < cReaders; j++)
01713 {
01714 currReader = &rgReaderStates[j];
01715
01716 if (currReader->szReader == NULL)
01717 {
01718 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01719 return SCARD_E_INVALID_VALUE;
01720 }
01721 }
01722
01723
01724
01725
01726
01727
01728
01729
01730 for (j = 0; j < cReaders; j++)
01731 {
01732 currReader = &rgReaderStates[j];
01733 currReader->dwEventState = 0;
01734 }
01735
01736
01737
01738
01739
01740 Log1(PCSC_LOG_DEBUG, "Event Loop Start");
01741
01742 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
01743
01744
01745 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
01746 if ((readerStates[j])->readerID != 0)
01747 currentReaderCount++;
01748
01749 j = 0;
01750
01751 do
01752 {
01753 int newReaderCount = 0;
01754 char ReaderCountChanged = FALSE;
01755
01756 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01757 {
01758 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01759
01760 PROFILE_END
01761
01762 return SCARD_E_NO_SERVICE;
01763 }
01764
01765 if (j == 0)
01766 {
01767 int i;
01768
01769 for (i=0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01770 if ((readerStates[i])->readerID != 0)
01771 newReaderCount++;
01772
01773 if (newReaderCount != currentReaderCount)
01774 {
01775 Log1(PCSC_LOG_INFO, "Reader list changed");
01776 ReaderCountChanged = TRUE;
01777 currentReaderCount = newReaderCount;
01778 }
01779 }
01780 currReader = &rgReaderStates[j];
01781
01782
01783
01784 if (currReader->dwCurrentState & SCARD_STATE_IGNORE)
01785 currReader->dwEventState = SCARD_STATE_IGNORE;
01786 else
01787 {
01788 LPSTR lpcReaderName;
01789 int i;
01790
01791
01792
01793 lpcReaderName = (char *) currReader->szReader;
01794
01795 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01796 {
01797 if (strcmp(lpcReaderName, (readerStates[i])->readerName) == 0)
01798 break;
01799 }
01800
01801
01802
01803
01804 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01805 {
01806 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01807 currReader->dwEventState = SCARD_STATE_UNKNOWN;
01808 else
01809 {
01810 currReader->dwEventState =
01811 SCARD_STATE_UNKNOWN | SCARD_STATE_CHANGED;
01812
01813
01814
01815
01816
01817 dwBreakFlag = 1;
01818 }
01819 }
01820 else
01821 {
01822
01823
01824
01825
01826 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01827 {
01828 currReader->dwEventState |= SCARD_STATE_CHANGED;
01829 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01830 dwBreakFlag = 1;
01831 }
01832
01833
01834
01835
01836
01837
01838 rContext = readerStates[i];
01839
01840
01841
01842
01843 dwState = rContext->readerState;
01844
01845
01846 if (dwState & SCARD_UNKNOWN)
01847 {
01848
01849
01850
01851 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
01852 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
01853 else
01854 {
01855
01856
01857
01858
01859 currReader->dwEventState = SCARD_STATE_CHANGED |
01860 SCARD_STATE_UNAVAILABLE;
01861 dwBreakFlag = 1;
01862 }
01863 }
01864 else
01865 {
01866
01867
01868
01869 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
01870 {
01871 currReader->dwEventState &=
01872 ~SCARD_STATE_UNAVAILABLE;
01873 currReader->dwEventState |= SCARD_STATE_CHANGED;
01874 dwBreakFlag = 1;
01875 }
01876 }
01877
01878
01879
01880 if (dwState & SCARD_PRESENT)
01881 {
01882
01883 if (0 == rContext->cardAtrLength)
01884
01885 SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
01886
01887 currReader->cbAtr = rContext->cardAtrLength;
01888 memcpy(currReader->rgbAtr, rContext->cardAtr,
01889 currReader->cbAtr);
01890 }
01891 else
01892 currReader->cbAtr = 0;
01893
01894
01895
01896
01897 if (dwState & SCARD_ABSENT)
01898 {
01899 currReader->dwEventState |= SCARD_STATE_EMPTY;
01900 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
01901 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
01902 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
01903 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01904 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
01905 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
01906 currReader->dwEventState &= ~SCARD_STATE_MUTE;
01907 currReader->dwEventState &= ~SCARD_STATE_INUSE;
01908
01909
01910
01911
01912 if (currReader->dwCurrentState & SCARD_STATE_PRESENT
01913 || currReader->dwCurrentState & SCARD_STATE_ATRMATCH
01914 || currReader->dwCurrentState & SCARD_STATE_EXCLUSIVE
01915 || currReader->dwCurrentState & SCARD_STATE_INUSE)
01916 {
01917 currReader->dwEventState |= SCARD_STATE_CHANGED;
01918 dwBreakFlag = 1;
01919 }
01920
01921
01922
01923
01924 } else if (dwState & SCARD_PRESENT)
01925 {
01926 currReader->dwEventState |= SCARD_STATE_PRESENT;
01927 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
01928 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
01929 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
01930 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01931 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
01932 currReader->dwEventState &= ~SCARD_STATE_MUTE;
01933
01934 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
01935 {
01936 currReader->dwEventState |= SCARD_STATE_CHANGED;
01937 dwBreakFlag = 1;
01938 }
01939
01940 if (dwState & SCARD_SWALLOWED)
01941 {
01942 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
01943 currReader->dwEventState |= SCARD_STATE_MUTE;
01944 else
01945 {
01946 currReader->dwEventState |= SCARD_STATE_MUTE;
01947 if (currReader->dwCurrentState
01948 != SCARD_STATE_UNAWARE)
01949 currReader->dwEventState |= SCARD_STATE_CHANGED;
01950 dwBreakFlag = 1;
01951 }
01952 }
01953 else
01954 {
01955
01956
01957
01958 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
01959 {
01960 currReader->dwEventState |=
01961 SCARD_STATE_CHANGED;
01962 dwBreakFlag = 1;
01963 }
01964 }
01965 }
01966
01967
01968
01969
01970 if (rContext->readerSharing == -1)
01971 {
01972 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
01973 currReader->dwEventState &= ~SCARD_STATE_INUSE;
01974 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
01975 {
01976 currReader->dwEventState |= SCARD_STATE_CHANGED;
01977 dwBreakFlag = 1;
01978 }
01979 }
01980 else if (rContext->readerSharing >= 1)
01981 {
01982
01983
01984
01985 if (dwState & SCARD_PRESENT)
01986 {
01987 currReader->dwEventState |= SCARD_STATE_INUSE;
01988 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
01989 if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)
01990 {
01991 currReader->dwEventState |= SCARD_STATE_CHANGED;
01992 dwBreakFlag = 1;
01993 }
01994 }
01995 }
01996 else if (rContext->readerSharing == 0)
01997 {
01998 currReader->dwEventState &= ~SCARD_STATE_INUSE;
01999 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02000
02001 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02002 {
02003 currReader->dwEventState |= SCARD_STATE_CHANGED;
02004 dwBreakFlag = 1;
02005 }
02006 else if (currReader-> dwCurrentState
02007 & SCARD_STATE_EXCLUSIVE)
02008 {
02009 currReader->dwEventState |= SCARD_STATE_CHANGED;
02010 dwBreakFlag = 1;
02011 }
02012 }
02013
02014 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02015 {
02016
02017
02018
02019
02020 currReader->dwEventState |= SCARD_STATE_CHANGED;
02021 dwBreakFlag = 1;
02022 }
02023
02024 }
02025
02026 }
02027
02028
02029
02030
02031 j = j + 1;
02032 if (j == cReaders)
02033 {
02034 if (!dwBreakFlag)
02035 {
02036
02037
02038
02039
02040 if (ReaderCountChanged)
02041 break;
02042 }
02043 j = 0;
02044 }
02045
02046
02047
02048
02049
02050 if (psContextMap[dwContextIndex].contextBlockStatus
02051 == BLOCK_STATUS_RESUME)
02052 break;
02053
02054
02055
02056
02057 if ((dwBreakFlag == 1) && (j == 0))
02058 break;
02059
02060
02061
02062
02063 if ((dwTimeout == 0) && (j == 0))
02064 break;
02065
02066 if (dwTimeout != INFINITE && dwTimeout != 0)
02067 {
02068
02069
02070
02071
02072 if ((dwTime >= (dwTimeout * 1000)) && (j == 0))
02073 {
02074 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02075 return SCARD_E_TIMEOUT;
02076 }
02077 }
02078
02079
02080
02081
02082 if (j == 0)
02083 {
02084 SYS_USleep(PCSCLITE_STATUS_WAIT);
02085 dwTime += PCSCLITE_STATUS_WAIT;
02086 }
02087 }
02088 while (1);
02089
02090 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02091
02092 if (psContextMap[dwContextIndex].contextBlockStatus ==
02093 BLOCK_STATUS_RESUME)
02094 {
02095 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02096 return SCARD_E_CANCELLED;
02097 }
02098
02099 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02100
02101 PROFILE_END
02102
02103 return SCARD_S_SUCCESS;
02104 }
02105
02152 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02153 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02154 LPDWORD lpBytesReturned)
02155 {
02156 LONG rv;
02157 control_struct scControlStruct;
02158 sharedSegmentMsg msgStruct;
02159 int i;
02160 DWORD dwContextIndex, dwChannelIndex;
02161
02162 PROFILE_START
02163
02164
02165 if (NULL != lpBytesReturned)
02166 *lpBytesReturned = 0;
02167
02168 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02169 return SCARD_E_NO_SERVICE;
02170
02171
02172
02173
02174 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02175
02176 if (rv == -1)
02177 return SCARD_E_INVALID_HANDLE;
02178
02179 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02180
02181 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02182 {
02183 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02184
02185
02186 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02187 break;
02188 }
02189
02190 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02191 {
02192 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02193 return SCARD_E_READER_UNAVAILABLE;
02194 }
02195
02196 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02197 || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02198 {
02199 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02200 return SCARD_E_INSUFFICIENT_BUFFER;
02201 }
02202
02203 if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
02204 {
02205
02206 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02207 control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
02208 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02209
02210 scControlStructExtended->hCard = hCard;
02211 scControlStructExtended->dwControlCode = dwControlCode;
02212 scControlStructExtended->cbSendLength = cbSendLength;
02213 scControlStructExtended->cbRecvLength = cbRecvLength;
02214 scControlStructExtended->size = sizeof(*scControlStructExtended) + cbSendLength;
02215 memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
02216
02217 rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
02218 psContextMap[dwContextIndex].dwClientID,
02219 scControlStructExtended->size,
02220 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02221
02222 if (rv == -1)
02223 {
02224 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02225 return SCARD_E_NO_SERVICE;
02226 }
02227
02228
02229
02230
02231
02232 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02233 if (rv == -1)
02234 {
02235 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02236 return SCARD_F_COMM_ERROR;
02237 }
02238
02239
02240 scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
02241
02242
02243 if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02244 {
02245 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02246 scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02247 psContextMap[dwContextIndex].dwClientID,
02248 PCSCLITE_CLIENT_ATTEMPTS);
02249 if (rv == -1)
02250 {
02251 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02252 return SCARD_F_COMM_ERROR;
02253 }
02254 }
02255
02256 if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
02257 {
02258
02259
02260
02261 memcpy(pbRecvBuffer, scControlStructExtended -> data,
02262 scControlStructExtended -> pdwBytesReturned);
02263 memset(scControlStructExtended -> data, 0x00,
02264 scControlStructExtended -> pdwBytesReturned);
02265 }
02266
02267 if (NULL != lpBytesReturned)
02268 *lpBytesReturned = scControlStructExtended -> pdwBytesReturned;
02269
02270 rv = scControlStructExtended -> rv;
02271 }
02272 else
02273 {
02274 scControlStruct.hCard = hCard;
02275 scControlStruct.dwControlCode = dwControlCode;
02276 scControlStruct.cbSendLength = cbSendLength;
02277 scControlStruct.cbRecvLength = cbRecvLength;
02278 memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02279
02280 rv = WrapSHMWrite(SCARD_CONTROL, psContextMap[dwContextIndex].dwClientID,
02281 sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
02282
02283 if (rv == -1)
02284 {
02285 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02286 return SCARD_E_NO_SERVICE;
02287 }
02288
02289
02290
02291
02292 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02293
02294 if (rv == -1)
02295 {
02296 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02297 return SCARD_F_COMM_ERROR;
02298 }
02299
02300 memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
02301
02302 if (NULL != lpBytesReturned)
02303 *lpBytesReturned = scControlStruct.dwBytesReturned;
02304
02305 if (scControlStruct.rv == SCARD_S_SUCCESS)
02306 {
02307
02308
02309
02310 memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
02311 scControlStruct.cbRecvLength);
02312 memset(scControlStruct.pbRecvBuffer, 0x00,
02313 sizeof(scControlStruct.pbRecvBuffer));
02314 }
02315
02316 rv = scControlStruct.rv;
02317 }
02318
02319 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02320
02321 PROFILE_END
02322
02323 return rv;
02324 }
02325
02406 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02407 LPDWORD pcbAttrLen)
02408 {
02409 PROFILE_START
02410
02411 if (NULL == pcbAttrLen)
02412 return SCARD_E_INVALID_PARAMETER;
02413
02414
02415 if (NULL == pbAttr)
02416
02417 *pcbAttrLen = MAX_BUFFER_SIZE;
02418
02419 PROFILE_END
02420
02421 return SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, pbAttr,
02422 pcbAttrLen);
02423 }
02424
02455 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02456 DWORD cbAttrLen)
02457 {
02458 PROFILE_START
02459
02460 if (NULL == pbAttr || 0 == cbAttrLen)
02461 return SCARD_E_INVALID_PARAMETER;
02462
02463 PROFILE_END
02464
02465 return SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02466 &cbAttrLen);
02467 }
02468
02469 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02470 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02471 {
02472 PROFILE_START
02473
02474 LONG rv;
02475 getset_struct scGetSetStruct;
02476 sharedSegmentMsg msgStruct;
02477 int i;
02478 DWORD dwContextIndex, dwChannelIndex;
02479
02480 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02481 return SCARD_E_NO_SERVICE;
02482
02483
02484
02485
02486 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02487
02488 if (rv == -1)
02489 return SCARD_E_INVALID_HANDLE;
02490
02491 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02492
02493 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02494 {
02495 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02496
02497
02498 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02499 break;
02500 }
02501
02502 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02503 {
02504 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02505 return SCARD_E_READER_UNAVAILABLE;
02506 }
02507
02508 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02509 {
02510 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02511 return SCARD_E_INSUFFICIENT_BUFFER;
02512 }
02513
02514 scGetSetStruct.hCard = hCard;
02515 scGetSetStruct.dwAttrId = dwAttrId;
02516 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02517 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02518 if (SCARD_SET_ATTRIB == command)
02519 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02520
02521 rv = WrapSHMWrite(command,
02522 psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
02523 PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
02524
02525 if (rv == -1)
02526 {
02527 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02528 return SCARD_E_NO_SERVICE;
02529 }
02530
02531
02532
02533
02534 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02535
02536 if (rv == -1)
02537 {
02538 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02539 return SCARD_F_COMM_ERROR;
02540 }
02541
02542 memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
02543
02544 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02545 {
02546
02547
02548
02549 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02550 {
02551 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02552 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02553 }
02554 else
02555 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02556
02557 if (pbAttr)
02558 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02559
02560 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02561 }
02562
02563 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02564
02565 PROFILE_END
02566
02567 return scGetSetStruct.rv;
02568 }
02569
02623 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02624 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02625 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02626 LPDWORD pcbRecvLength)
02627 {
02628 LONG rv;
02629 int i;
02630 DWORD dwContextIndex, dwChannelIndex;
02631
02632 PROFILE_START
02633
02634 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02635 pcbRecvLength == NULL || pioSendPci == NULL)
02636 return SCARD_E_INVALID_PARAMETER;
02637
02638 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02639 return SCARD_E_NO_SERVICE;
02640
02641
02642
02643
02644 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02645
02646 if (rv == -1)
02647 {
02648 *pcbRecvLength = 0;
02649 return SCARD_E_INVALID_HANDLE;
02650 }
02651
02652 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02653
02654 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02655 {
02656 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02657
02658
02659 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02660 break;
02661 }
02662
02663 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02664 {
02665 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02666 return SCARD_E_READER_UNAVAILABLE;
02667 }
02668
02669 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02670 || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02671 {
02672 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02673 return SCARD_E_INSUFFICIENT_BUFFER;
02674 }
02675
02676 if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
02677 {
02678
02679 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02680 transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
02681 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02682
02683 scTransmitStructExtended->hCard = hCard;
02684 scTransmitStructExtended->cbSendLength = cbSendLength;
02685 scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
02686 scTransmitStructExtended->size = sizeof(*scTransmitStructExtended) + cbSendLength;
02687 memcpy(&scTransmitStructExtended->pioSendPci, pioSendPci,
02688 sizeof(SCARD_IO_REQUEST));
02689 memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
02690
02691 if (pioRecvPci)
02692 {
02693 memcpy(&scTransmitStructExtended->pioRecvPci, pioRecvPci,
02694 sizeof(SCARD_IO_REQUEST));
02695 }
02696 else
02697 scTransmitStructExtended->pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
02698
02699 rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
02700 psContextMap[dwContextIndex].dwClientID,
02701 scTransmitStructExtended->size,
02702 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02703
02704 if (rv == -1)
02705 {
02706 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02707 return SCARD_E_NO_SERVICE;
02708 }
02709
02710
02711
02712
02713
02714 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02715 if (rv == -1)
02716 {
02717 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02718 return SCARD_F_COMM_ERROR;
02719 }
02720
02721
02722 scTransmitStructExtended = (transmit_struct_extended *)&(pmsgStruct -> data);
02723
02724
02725 if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02726 {
02727 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02728 scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02729 psContextMap[dwContextIndex].dwClientID,
02730 PCSCLITE_CLIENT_ATTEMPTS);
02731 if (rv == -1)
02732 {
02733 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02734 return SCARD_F_COMM_ERROR;
02735 }
02736 }
02737
02738 if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
02739 {
02740
02741
02742
02743 memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
02744 scTransmitStructExtended -> pcbRecvLength);
02745 memset(scTransmitStructExtended -> data, 0x00,
02746 scTransmitStructExtended -> pcbRecvLength);
02747
02748 if (pioRecvPci)
02749 memcpy(pioRecvPci, &scTransmitStructExtended -> pioRecvPci,
02750 sizeof(SCARD_IO_REQUEST));
02751 }
02752
02753 *pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
02754 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02755
02756 rv = scTransmitStructExtended -> rv;
02757 }
02758 else
02759 {
02760
02761 transmit_struct scTransmitStruct;
02762 sharedSegmentMsg msgStruct;
02763
02764 scTransmitStruct.hCard = hCard;
02765 scTransmitStruct.cbSendLength = cbSendLength;
02766 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
02767 memcpy(&scTransmitStruct.pioSendPci, pioSendPci,
02768 sizeof(SCARD_IO_REQUEST));
02769 memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02770
02771 if (pioRecvPci)
02772 {
02773 memcpy(&scTransmitStruct.pioRecvPci, pioRecvPci,
02774 sizeof(SCARD_IO_REQUEST));
02775 }
02776 else
02777 scTransmitStruct.pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
02778
02779 rv = WrapSHMWrite(SCARD_TRANSMIT,
02780 psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
02781 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
02782
02783 if (rv == -1)
02784 {
02785 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02786 return SCARD_E_NO_SERVICE;
02787 }
02788
02789
02790
02791
02792 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02793
02794 memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
02795
02796 if (rv == -1)
02797 {
02798 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02799 return SCARD_F_COMM_ERROR;
02800 }
02801
02802
02803
02804
02805 memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
02806
02807 if (scTransmitStruct.rv == SCARD_S_SUCCESS)
02808 {
02809
02810
02811
02812 memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
02813 scTransmitStruct.pcbRecvLength);
02814 memset(scTransmitStruct.pbRecvBuffer, 0x00,
02815 scTransmitStruct.pcbRecvLength);
02816
02817 if (pioRecvPci)
02818 memcpy(pioRecvPci, &scTransmitStruct.pioRecvPci,
02819 sizeof(SCARD_IO_REQUEST));
02820 }
02821
02822 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
02823 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02824
02825 rv = scTransmitStruct.rv;
02826 }
02827
02828 PROFILE_END
02829
02830 return rv;
02831 }
02832
02862 LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
02863 LPSTR mszReaders, LPDWORD pcchReaders)
02864 {
02865 DWORD dwReadersLen;
02866 int i, lastChrPtr;
02867 LONG dwContextIndex;
02868
02869 PROFILE_START
02870
02871
02872
02873
02874 if (pcchReaders == NULL)
02875 return SCARD_E_INVALID_PARAMETER;
02876
02877 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02878 return SCARD_E_NO_SERVICE;
02879
02880
02881
02882
02883 dwContextIndex = SCardGetContextIndice(hContext);
02884 if (dwContextIndex == -1)
02885 return SCARD_E_INVALID_HANDLE;
02886
02887 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02888
02889 dwReadersLen = 0;
02890 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02891 if ((readerStates[i])->readerID != 0)
02892 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
02893
02894
02895 dwReadersLen += 1;
02896
02897 if ((mszReaders == NULL)
02898 || (*pcchReaders == 0))
02899 {
02900 *pcchReaders = dwReadersLen;
02901 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02902 return SCARD_S_SUCCESS;
02903 }
02904
02905 if (*pcchReaders < dwReadersLen)
02906 {
02907 *pcchReaders = dwReadersLen;
02908 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02909 return SCARD_E_INSUFFICIENT_BUFFER;
02910 }
02911
02912 lastChrPtr = 0;
02913 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02914 {
02915 if ((readerStates[i])->readerID != 0)
02916 {
02917
02918
02919
02920 strcpy(&mszReaders[lastChrPtr], (readerStates[i])->readerName);
02921 lastChrPtr += strlen((readerStates[i])->readerName)+1;
02922 }
02923 }
02924 mszReaders[lastChrPtr] = '\0';
02925
02926 *pcchReaders = dwReadersLen;
02927
02928 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02929
02930 PROFILE_END
02931
02932 return SCARD_S_SUCCESS;
02933 }
02934
02966 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
02967 LPDWORD pcchGroups)
02968 {
02969 LONG rv = SCARD_S_SUCCESS;
02970 LONG dwContextIndex;
02971
02972 PROFILE_START
02973
02974 const char ReaderGroup[] = "SCard$DefaultReaders";
02975 const int dwGroups = strlen(ReaderGroup) + 2;
02976
02977 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02978 return SCARD_E_NO_SERVICE;
02979
02980
02981
02982
02983 dwContextIndex = SCardGetContextIndice(hContext);
02984 if (dwContextIndex == -1)
02985 return SCARD_E_INVALID_HANDLE;
02986
02987 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02988
02989 if (mszGroups)
02990 {
02991
02992 if (*pcchGroups < dwGroups)
02993 rv = SCARD_E_INSUFFICIENT_BUFFER;
02994 else
02995 {
02996 memset(mszGroups, 0, dwGroups);
02997 memcpy(mszGroups, ReaderGroup, strlen(ReaderGroup));
02998 }
02999 }
03000
03001 *pcchGroups = dwGroups;
03002
03003 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03004
03005 PROFILE_END
03006
03007 return rv;
03008 }
03009
03037 LONG SCardCancel(SCARDCONTEXT hContext)
03038 {
03039 LONG dwContextIndex;
03040
03041 PROFILE_START
03042
03043 dwContextIndex = SCardGetContextIndice(hContext);
03044
03045 if (dwContextIndex == -1)
03046 return SCARD_E_INVALID_HANDLE;
03047
03048
03049
03050
03051
03052 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
03053
03054 PROFILE_END
03055
03056 return SCARD_S_SUCCESS;
03057 }
03058
03082 LONG SCardIsValidContext(SCARDCONTEXT hContext)
03083 {
03084 LONG rv;
03085 LONG dwContextIndex;
03086
03087 PROFILE_START
03088
03089 rv = SCARD_S_SUCCESS;
03090
03091
03092
03093
03094 dwContextIndex = SCardGetContextIndice(hContext);
03095 if (dwContextIndex == -1)
03096 rv = SCARD_E_INVALID_HANDLE;
03097
03098 PROFILE_END
03099
03100 return rv;
03101 }
03102
03119 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
03120 {
03121 int i;
03122
03123 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03124 {
03125 if (psContextMap[i].hContext == 0)
03126 {
03127 psContextMap[i].hContext = hContext;
03128 psContextMap[i].dwClientID = dwClientID;
03129 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
03130 psContextMap[i].mMutex = malloc(sizeof(PCSCLITE_MUTEX));
03131 SYS_MutexInit(psContextMap[i].mMutex);
03132 return SCARD_S_SUCCESS;
03133 }
03134 }
03135
03136 return SCARD_E_NO_MEMORY;
03137 }
03138
03151 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
03152 {
03153 LONG rv;
03154
03155 SCardLockThread();
03156 rv = SCardGetContextIndiceTH(hContext);
03157 SCardUnlockThread();
03158
03159 return rv;
03160 }
03161
03174 static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
03175 {
03176 int i;
03177
03178
03179
03180
03181 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03182 {
03183 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
03184 return i;
03185 }
03186
03187 return -1;
03188 }
03189
03199 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
03200 {
03201 LONG retIndice;
03202
03203 retIndice = SCardGetContextIndiceTH(hContext);
03204
03205 if (retIndice == -1)
03206 return SCARD_E_INVALID_HANDLE;
03207 else
03208 {
03209 int i;
03210
03211 psContextMap[retIndice].hContext = 0;
03212 SHMClientCloseSession(psContextMap[retIndice].dwClientID);
03213 psContextMap[retIndice].dwClientID = 0;
03214 free(psContextMap[retIndice].mMutex);
03215 psContextMap[retIndice].mMutex = NULL;
03216 psContextMap[retIndice].contextBlockStatus = BLOCK_STATUS_RESUME;
03217
03218 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03219 {
03220
03221
03222
03223 psContextMap[retIndice].psChannelMap[i].hCard = 0;
03224 free(psContextMap[retIndice].psChannelMap[i].readerName);
03225 psContextMap[retIndice].psChannelMap[i].readerName = NULL;
03226 }
03227
03228 return SCARD_S_SUCCESS;
03229 }
03230 }
03231
03232
03233
03234
03235
03236 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
03237 LPSTR readerName)
03238 {
03239 int i;
03240
03241 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03242 {
03243 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
03244 {
03245 psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
03246 psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
03247 return SCARD_S_SUCCESS;
03248 }
03249 }
03250
03251 return SCARD_E_NO_MEMORY;
03252 }
03253
03254 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03255 {
03256 DWORD dwContextIndice, dwChannelIndice;
03257 LONG rv;
03258
03259 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
03260
03261 if (rv == -1)
03262 return SCARD_E_INVALID_HANDLE;
03263 else
03264 {
03265 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
03266 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
03267 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
03268 return SCARD_S_SUCCESS;
03269 }
03270 }
03271
03272 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03273 {
03274 LONG rv;
03275
03276 if (0 == hCard)
03277 return -1;
03278
03279 SCardLockThread();
03280 rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
03281 SCardUnlockThread();
03282
03283 return rv;
03284 }
03285
03286 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03287 {
03288 int i;
03289
03290 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03291 {
03292 if (psContextMap[i].hContext != 0)
03293 {
03294 int j;
03295
03296 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
03297 {
03298 if (psContextMap[i].psChannelMap[j].hCard == hCard)
03299 {
03300 *pdwContextIndice = i;
03301 *pdwChannelIndice = j;
03302 return SCARD_S_SUCCESS;
03303 }
03304 }
03305
03306 }
03307 }
03308
03309 return -1;
03310 }
03311
03318 inline static LONG SCardLockThread(void)
03319 {
03320 return SYS_MutexLock(&clientMutex);
03321 }
03322
03328 inline static LONG SCardUnlockThread(void)
03329 {
03330 return SYS_MutexUnLock(&clientMutex);
03331 }
03332
03340 static LONG SCardCheckDaemonAvailability(void)
03341 {
03342 LONG rv;
03343 struct stat statBuffer;
03344
03345 rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &statBuffer);
03346
03347 if (rv != 0)
03348 {
03349 Log1(PCSC_LOG_ERROR, "PCSC Not Running");
03350 return SCARD_E_NO_SERVICE;
03351 }
03352
03353 return SCARD_S_SUCCESS;
03354 }
03355
03361 #ifdef __SUNPRO_C
03362 #pragma fini (SCardUnload)
03363 #endif
03364
03365 void DESTRUCTOR SCardUnload(void)
03366 {
03367 int i;
03368
03369 if (!isExecuted)
03370 return;
03371
03372
03373 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03374 {
03375 if (readerStates[i] != NULL)
03376 {
03377 SYS_PublicMemoryUnmap(readerStates[i], sizeof(READER_STATE));
03378 readerStates[i] = NULL;
03379 }
03380 }
03381
03382 SYS_CloseFile(mapAddr);
03383 isExecuted = 0;
03384 }
03385