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 "debuglog.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 LPTSTR 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, LPTSTR);
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 if (getenv("MUSCLECARD_DEBUG"))
00312 {
00313 DebugLogSetLogType(DEBUGLOG_STDERR_DEBUG);
00314 DebugLogSetLevel(PCSC_LOG_DEBUG);
00315 }
00316
00317
00318
00319
00320 SYS_Initialize();
00321
00322
00323
00324
00325 mapAddr = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDONLY, 0);
00326 if (mapAddr < 0)
00327 {
00328 Log2(PCSC_LOG_CRITICAL, "Cannot open public shared file: %s",
00329 PCSCLITE_PUBSHM_FILE);
00330 return SCARD_E_NO_SERVICE;
00331 }
00332
00333 pageSize = SYS_GetPageSize();
00334
00335
00336
00337
00338 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00339 {
00340 readerStates[i] = (PREADER_STATE)
00341 SYS_PublicMemoryMap(sizeof(READER_STATE),
00342 mapAddr, (i * pageSize));
00343 if (readerStates[i] == NULL)
00344 {
00345 Log1(PCSC_LOG_CRITICAL, "Cannot public memory map");
00346 SYS_CloseFile(mapAddr);
00347 return SCARD_F_INTERNAL_ERROR;
00348 }
00349 }
00350
00351
00352
00353
00354 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00355 {
00356 int j;
00357
00358
00359
00360
00361 psContextMap[i].dwClientID = 0;
00362 psContextMap[i].hContext = 0;
00363 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
00364 psContextMap[i].mMutex = NULL;
00365
00366 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
00367 {
00368
00369
00370
00371 psContextMap[i].psChannelMap[j].hCard = 0;
00372 psContextMap[i].psChannelMap[j].readerName = NULL;
00373 }
00374 }
00375
00376 }
00377
00378
00379
00380
00381
00382 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00383 {
00384 if (psContextMap[i].dwClientID == 0)
00385 break;
00386 }
00387
00388 if (i == PCSCLITE_MAX_APPLICATION_CONTEXTS)
00389 {
00390 return SCARD_E_NO_MEMORY;
00391 }
00392
00393
00394 if (SHMClientSetupSession(&dwClientID) != 0)
00395 {
00396 SYS_CloseFile(mapAddr);
00397 return SCARD_E_NO_SERVICE;
00398 }
00399
00400 {
00401 sharedSegmentMsg msgStruct;
00402 version_struct *veStr;
00403
00404 memset(&msgStruct, 0, sizeof(msgStruct));
00405 msgStruct.mtype = CMD_VERSION;
00406 msgStruct.user_id = SYS_GetUID();
00407 msgStruct.group_id = SYS_GetGID();
00408 msgStruct.command = 0;
00409 msgStruct.date = time(NULL);
00410
00411 veStr = (version_struct *) msgStruct.data;
00412 veStr->major = PROTOCOL_VERSION_MAJOR;
00413 veStr->minor = PROTOCOL_VERSION_MINOR;
00414
00415 if (-1 == SHMMessageSend(&msgStruct, dwClientID,
00416 PCSCLITE_MCLIENT_ATTEMPTS))
00417 return SCARD_E_NO_SERVICE;
00418
00419
00420
00421
00422 if (-1 == SHMMessageReceive(&msgStruct, dwClientID,
00423 PCSCLITE_CLIENT_ATTEMPTS))
00424 {
00425 Log1(PCSC_LOG_CRITICAL, "Your pcscd is too old and does not support CMD_VERSION");
00426 return SCARD_F_COMM_ERROR;
00427 }
00428
00429 Log3(PCSC_LOG_INFO, "Server is protocol version %d:%d",
00430 veStr->major, veStr->minor);
00431
00432 isExecuted = 1;
00433 }
00434
00435
00436 if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
00437 dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
00438 {
00439 return SCARD_E_INVALID_VALUE;
00440 }
00441
00442
00443
00444
00445 scEstablishStruct.dwScope = dwScope;
00446 scEstablishStruct.phContext = 0;
00447 scEstablishStruct.rv = 0;
00448
00449 rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
00450 sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
00451 (void *) &scEstablishStruct);
00452
00453 if (rv == -1)
00454 return SCARD_E_NO_SERVICE;
00455
00456
00457
00458
00459 rv = SHMClientRead(&msgStruct, dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00460
00461 if (rv == -1)
00462 return SCARD_F_COMM_ERROR;
00463
00464 memcpy(&scEstablishStruct, &msgStruct.data, sizeof(scEstablishStruct));
00465
00466 if (scEstablishStruct.rv != SCARD_S_SUCCESS)
00467 return scEstablishStruct.rv;
00468
00469 *phContext = scEstablishStruct.phContext;
00470
00471
00472
00473
00474 rv = SCardAddContext(*phContext, dwClientID);
00475
00476 return rv;
00477 }
00478
00497 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00498 {
00499 LONG rv;
00500 release_struct scReleaseStruct;
00501 sharedSegmentMsg msgStruct;
00502 DWORD dwContextIndex;
00503
00504 PROFILE_START
00505
00506 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00507 return SCARD_E_NO_SERVICE;
00508
00509
00510
00511
00512 dwContextIndex = SCardGetContextIndice(hContext);
00513 if (dwContextIndex == -1)
00514 return SCARD_E_INVALID_HANDLE;
00515
00516 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00517
00518 scReleaseStruct.hContext = hContext;
00519 scReleaseStruct.rv = 0;
00520
00521 rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT, psContextMap[dwContextIndex].dwClientID,
00522 sizeof(scReleaseStruct),
00523 PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);
00524
00525 if (rv == -1)
00526 {
00527 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00528 return SCARD_E_NO_SERVICE;
00529 }
00530
00531
00532
00533
00534 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00535 memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));
00536
00537 if (rv == -1)
00538 {
00539 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00540 return SCARD_F_COMM_ERROR;
00541 }
00542
00543 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00544
00545
00546
00547
00548 SCardLockThread();
00549 SCardRemoveContext(hContext);
00550 SCardUnlockThread();
00551
00552 PROFILE_END
00553
00554 return scReleaseStruct.rv;
00555 }
00556
00569 LONG SCardSetTimeout(SCARDCONTEXT hContext, DWORD dwTimeout)
00570 {
00571
00572
00573
00574
00575 return SCARD_S_SUCCESS;
00576 }
00577
00626 LONG SCardConnect(SCARDCONTEXT hContext, LPCTSTR szReader,
00627 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00628 LPDWORD pdwActiveProtocol)
00629 {
00630 LONG rv;
00631 connect_struct scConnectStruct;
00632 sharedSegmentMsg msgStruct;
00633 DWORD dwContextIndex;
00634
00635 PROFILE_START
00636
00637
00638
00639
00640 if (phCard == NULL || pdwActiveProtocol == NULL)
00641 return SCARD_E_INVALID_PARAMETER;
00642 else
00643 *phCard = 0;
00644
00645 if (szReader == NULL)
00646 return SCARD_E_UNKNOWN_READER;
00647
00648
00649
00650
00651 if (strlen(szReader) > MAX_READERNAME)
00652 return SCARD_E_INVALID_VALUE;
00653
00654 if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00655 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00656 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00657 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00658 {
00659 return SCARD_E_INVALID_VALUE;
00660 }
00661
00662 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00663 return SCARD_E_NO_SERVICE;
00664
00665
00666
00667
00668 dwContextIndex = SCardGetContextIndice(hContext);
00669 if (dwContextIndex == -1)
00670 return SCARD_E_INVALID_HANDLE;
00671
00672 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00673
00674 strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);
00675
00676 scConnectStruct.hContext = hContext;
00677 scConnectStruct.dwShareMode = dwShareMode;
00678 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00679 scConnectStruct.phCard = *phCard;
00680 scConnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00681
00682 rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
00683 sizeof(scConnectStruct),
00684 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);
00685
00686 if (rv == -1)
00687 {
00688 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00689 return SCARD_E_NO_SERVICE;
00690 }
00691
00692
00693
00694
00695 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00696
00697 memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));
00698
00699 if (rv == -1)
00700 {
00701 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00702 return SCARD_F_COMM_ERROR;
00703 }
00704
00705 *phCard = scConnectStruct.phCard;
00706 *pdwActiveProtocol = scConnectStruct.pdwActiveProtocol;
00707
00708 if (scConnectStruct.rv == SCARD_S_SUCCESS)
00709 {
00710
00711
00712
00713 rv = SCardAddHandle(*phCard, dwContextIndex, (LPTSTR) szReader);
00714 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00715
00716 PROFILE_END
00717
00718 return rv;
00719 }
00720
00721 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00722
00723 PROFILE_END
00724
00725 return scConnectStruct.rv;
00726 }
00727
00793 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00794 DWORD dwPreferredProtocols, DWORD dwInitialization,
00795 LPDWORD pdwActiveProtocol)
00796 {
00797 LONG rv;
00798 reconnect_struct scReconnectStruct;
00799 sharedSegmentMsg msgStruct;
00800 int i;
00801 DWORD dwContextIndex, dwChannelIndex;
00802
00803 PROFILE_START
00804
00805 if (dwInitialization != SCARD_LEAVE_CARD &&
00806 dwInitialization != SCARD_RESET_CARD &&
00807 dwInitialization != SCARD_UNPOWER_CARD &&
00808 dwInitialization != SCARD_EJECT_CARD)
00809 {
00810 return SCARD_E_INVALID_VALUE;
00811 }
00812
00813 if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00814 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00815 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00816 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00817 {
00818 return SCARD_E_INVALID_VALUE;
00819 }
00820
00821 if (pdwActiveProtocol == NULL)
00822 return SCARD_E_INVALID_PARAMETER;
00823
00824 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00825 return SCARD_E_NO_SERVICE;
00826
00827
00828
00829
00830 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00831
00832 if (rv == -1)
00833 return SCARD_E_INVALID_HANDLE;
00834
00835 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00836
00837
00838 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00839 {
00840 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
00841
00842
00843 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
00844 break;
00845 }
00846
00847 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00848 {
00849 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00850 return SCARD_E_READER_UNAVAILABLE;
00851 }
00852
00853 scReconnectStruct.hCard = hCard;
00854 scReconnectStruct.dwShareMode = dwShareMode;
00855 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00856 scReconnectStruct.dwInitialization = dwInitialization;
00857 scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00858
00859 rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
00860 sizeof(scReconnectStruct),
00861 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
00862
00863 if (rv == -1)
00864 {
00865 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00866 return SCARD_E_NO_SERVICE;
00867 }
00868
00869
00870
00871
00872 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00873
00874 memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
00875
00876 if (rv == -1)
00877 {
00878 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00879 return SCARD_F_COMM_ERROR;
00880 }
00881
00882 *pdwActiveProtocol = scReconnectStruct.pdwActiveProtocol;
00883
00884 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00885
00886 PROFILE_END
00887
00888 return scReconnectStruct.rv;
00889 }
00890
00921 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
00922 {
00923 LONG rv;
00924 disconnect_struct scDisconnectStruct;
00925 sharedSegmentMsg msgStruct;
00926 DWORD dwContextIndex, dwChannelIndex;
00927
00928 PROFILE_START
00929
00930 if (dwDisposition != SCARD_LEAVE_CARD &&
00931 dwDisposition != SCARD_RESET_CARD &&
00932 dwDisposition != SCARD_UNPOWER_CARD &&
00933 dwDisposition != SCARD_EJECT_CARD)
00934 {
00935 return SCARD_E_INVALID_VALUE;
00936 }
00937
00938 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00939 return SCARD_E_NO_SERVICE;
00940
00941
00942
00943
00944 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00945
00946 if (rv == -1)
00947 return SCARD_E_INVALID_HANDLE;
00948
00949 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00950
00951 scDisconnectStruct.hCard = hCard;
00952 scDisconnectStruct.dwDisposition = dwDisposition;
00953
00954 rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
00955 sizeof(scDisconnectStruct),
00956 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
00957
00958 if (rv == -1)
00959 {
00960 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00961 return SCARD_E_NO_SERVICE;
00962 }
00963
00964
00965
00966
00967 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00968
00969 memcpy(&scDisconnectStruct, &msgStruct.data,
00970 sizeof(scDisconnectStruct));
00971
00972 if (rv == -1)
00973 {
00974 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00975 return SCARD_F_COMM_ERROR;
00976 }
00977
00978 SCardRemoveHandle(hCard);
00979
00980 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00981
00982 PROFILE_END
00983
00984 return scDisconnectStruct.rv;
00985 }
00986
01019 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01020 {
01021
01022 LONG rv;
01023 begin_struct scBeginStruct;
01024 int i;
01025 sharedSegmentMsg msgStruct;
01026 DWORD dwContextIndex, dwChannelIndex;
01027
01028 PROFILE_START
01029
01030 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01031 return SCARD_E_NO_SERVICE;
01032
01033
01034
01035
01036 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01037
01038 if (rv == -1)
01039 return SCARD_E_INVALID_HANDLE;
01040
01041 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01042
01043 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01044 {
01045 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01046
01047
01048 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01049 break;
01050 }
01051
01052 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01053 {
01054 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01055 return SCARD_E_READER_UNAVAILABLE;
01056 }
01057
01058 scBeginStruct.hCard = hCard;
01059
01060
01061
01062
01063
01064
01065 do
01066 {
01067
01068
01069
01070
01071 if ((readerStates[i])->lockState != 0)
01072 {
01073 int randnum = 0;
01074 int j;
01075
01076 for (j = 0; j < 100; j++)
01077 {
01078
01079
01080
01081 randnum = SYS_RandomInt(1000, 10000);
01082 SYS_USleep(randnum);
01083
01084 if ((readerStates[i])->lockState == 0)
01085 {
01086 break;
01087 }
01088 }
01089 }
01090
01091 rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01092 sizeof(scBeginStruct),
01093 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);
01094
01095 if (rv == -1)
01096 {
01097
01098 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01099 return SCARD_E_NO_SERVICE;
01100 }
01101
01102
01103
01104
01105 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01106
01107
01108 memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));
01109
01110 if (rv == -1)
01111 {
01112
01113 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01114 return SCARD_F_COMM_ERROR;
01115 }
01116
01117 }
01118 while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
01119
01120 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01121
01122 PROFILE_END
01123
01124 return scBeginStruct.rv;
01125 }
01126
01165 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01166 {
01167 LONG rv;
01168 end_struct scEndStruct;
01169 sharedSegmentMsg msgStruct;
01170 int randnum, i;
01171 DWORD dwContextIndex, dwChannelIndex;
01172
01173 PROFILE_START
01174
01175
01176
01177
01178 randnum = 0;
01179
01180 if (dwDisposition != SCARD_LEAVE_CARD &&
01181 dwDisposition != SCARD_RESET_CARD &&
01182 dwDisposition != SCARD_UNPOWER_CARD &&
01183 dwDisposition != SCARD_EJECT_CARD)
01184 {
01185 return SCARD_E_INVALID_VALUE;
01186 }
01187
01188 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01189 return SCARD_E_NO_SERVICE;
01190
01191
01192
01193
01194 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01195
01196 if (rv == -1)
01197 return SCARD_E_INVALID_HANDLE;
01198
01199 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01200
01201 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01202 {
01203 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01204
01205
01206 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01207 break;
01208 }
01209
01210 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01211 {
01212 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01213 return SCARD_E_READER_UNAVAILABLE;
01214 }
01215
01216 scEndStruct.hCard = hCard;
01217 scEndStruct.dwDisposition = dwDisposition;
01218
01219 rv = WrapSHMWrite(SCARD_END_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01220 sizeof(scEndStruct),
01221 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
01222
01223 if (rv == -1)
01224 {
01225 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01226 return SCARD_E_NO_SERVICE;
01227 }
01228
01229
01230
01231
01232 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01233
01234 memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
01235
01236 if (rv == -1)
01237 {
01238 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01239 return SCARD_F_COMM_ERROR;
01240 }
01241
01242
01243
01244
01245 randnum = SYS_RandomInt(1000, 10000);
01246 SYS_USleep(randnum);
01247
01248 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01249
01250 PROFILE_END
01251
01252 return scEndStruct.rv;
01253 }
01254
01260 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01261 {
01262 LONG rv;
01263 cancel_struct scCancelStruct;
01264 sharedSegmentMsg msgStruct;
01265 int i;
01266 DWORD dwContextIndex, dwChannelIndex;
01267
01268 PROFILE_START
01269
01270 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01271 return SCARD_E_NO_SERVICE;
01272
01273
01274
01275
01276 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01277
01278 if (rv == -1)
01279 return SCARD_E_INVALID_HANDLE;
01280
01281 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01282
01283 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01284 {
01285 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01286
01287
01288 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01289 break;
01290 }
01291
01292 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01293 {
01294 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01295 return SCARD_E_READER_UNAVAILABLE;
01296 }
01297
01298 scCancelStruct.hCard = hCard;
01299
01300 rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01301 sizeof(scCancelStruct),
01302 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
01303
01304 if (rv == -1)
01305 {
01306 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01307 return SCARD_E_NO_SERVICE;
01308 }
01309
01310
01311
01312
01313 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01314
01315 memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
01316
01317 if (rv == -1)
01318 {
01319 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01320 return SCARD_F_COMM_ERROR;
01321 }
01322
01323 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01324
01325 PROFILE_END
01326
01327 return scCancelStruct.rv;
01328 }
01329
01386 LONG SCardStatus(SCARDHANDLE hCard, LPTSTR mszReaderNames,
01387 LPDWORD pcchReaderLen, LPDWORD pdwState,
01388 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
01389 {
01390 DWORD dwReaderLen, dwAtrLen;
01391 LONG rv;
01392 int i;
01393 status_struct scStatusStruct;
01394 sharedSegmentMsg msgStruct;
01395 DWORD dwContextIndex, dwChannelIndex;
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 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01434 {
01435 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01436
01437
01438 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01439 break;
01440 }
01441
01442 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01443 {
01444 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01445 return SCARD_E_READER_UNAVAILABLE;
01446 }
01447
01448
01449 memset(&scStatusStruct, 0, sizeof(scStatusStruct));
01450 scStatusStruct.hCard = hCard;
01451
01452
01453 scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
01454 scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
01455
01456 rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
01457 sizeof(scStatusStruct),
01458 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
01459
01460 if (rv == -1)
01461 {
01462 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01463 return SCARD_E_NO_SERVICE;
01464 }
01465
01466
01467
01468
01469 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01470
01471 memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
01472
01473 if (rv == -1)
01474 {
01475 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01476 return SCARD_F_COMM_ERROR;
01477 }
01478
01479 rv = scStatusStruct.rv;
01480 if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
01481 {
01482
01483
01484
01485 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01486 return rv;
01487 }
01488
01489
01490
01491
01492
01493 *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
01494 *pcbAtrLen = (readerStates[i])->cardAtrLength;
01495
01496 if (pdwState)
01497 *pdwState = (readerStates[i])->readerState;
01498
01499 if (pdwProtocol)
01500 *pdwProtocol = (readerStates[i])->cardProtocol;
01501
01502
01503 if (mszReaderNames)
01504 {
01505 if (*pcchReaderLen > dwReaderLen)
01506 rv = SCARD_E_INSUFFICIENT_BUFFER;
01507
01508 strncpy(mszReaderNames,
01509 psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
01510 dwReaderLen);
01511 }
01512
01513 if (pbAtr)
01514 {
01515 if (*pcbAtrLen > dwAtrLen)
01516 rv = SCARD_E_INSUFFICIENT_BUFFER;
01517
01518 memcpy(pbAtr, (readerStates[i])->cardAtr,
01519 min(*pcbAtrLen, dwAtrLen));
01520 }
01521
01522 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01523
01524 PROFILE_END
01525
01526 return rv;
01527 }
01528
01614 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01615 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01616 {
01617 PSCARD_READERSTATE_A currReader;
01618 PREADER_STATE rContext;
01619 DWORD dwTime = 0;
01620 DWORD dwState;
01621 DWORD dwBreakFlag = 0;
01622 int j;
01623 DWORD dwContextIndex;
01624 int currentReaderCount = 0;
01625
01626 PROFILE_START
01627
01628 if (rgReaderStates == NULL && cReaders > 0)
01629 return SCARD_E_INVALID_PARAMETER;
01630
01631 if (cReaders < 0)
01632 return SCARD_E_INVALID_VALUE;
01633
01634 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01635 return SCARD_E_NO_SERVICE;
01636
01637
01638
01639
01640
01641 dwContextIndex = SCardGetContextIndice(hContext);
01642 if (dwContextIndex == -1)
01643 return SCARD_E_INVALID_HANDLE;
01644
01645 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01646
01647
01648
01649
01650
01651
01652 if (cReaders == 0)
01653 {
01654 while (1)
01655 {
01656 int i;
01657
01658 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01659 {
01660 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01661 return SCARD_E_NO_SERVICE;
01662 }
01663
01664 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01665 {
01666 if ((readerStates[i])->readerID != 0)
01667 {
01668
01669
01670
01671 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01672
01673 PROFILE_END
01674
01675 return SCARD_S_SUCCESS;
01676 }
01677 }
01678
01679 if (dwTimeout == 0)
01680 {
01681
01682
01683
01684 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01685 return SCARD_E_READER_UNAVAILABLE;
01686 }
01687
01688 SYS_USleep(PCSCLITE_STATUS_WAIT);
01689
01690 if (dwTimeout != INFINITE)
01691 {
01692 dwTime += PCSCLITE_STATUS_WAIT;
01693
01694 if (dwTime >= (dwTimeout * 1000))
01695 {
01696 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01697
01698 PROFILE_END
01699
01700 return SCARD_E_TIMEOUT;
01701 }
01702 }
01703 }
01704 }
01705 else
01706 if (cReaders >= PCSCLITE_MAX_READERS_CONTEXTS)
01707 {
01708 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01709 return SCARD_E_INVALID_VALUE;
01710 }
01711
01712
01713
01714
01715
01716 for (j = 0; j < cReaders; j++)
01717 {
01718 currReader = &rgReaderStates[j];
01719
01720 if (currReader->szReader == NULL)
01721 {
01722 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01723 return SCARD_E_INVALID_VALUE;
01724 }
01725 }
01726
01727
01728
01729
01730
01731
01732
01733
01734 for (j = 0; j < cReaders; j++)
01735 {
01736 currReader = &rgReaderStates[j];
01737 currReader->dwEventState = 0;
01738 }
01739
01740
01741
01742
01743
01744 Log1(PCSC_LOG_DEBUG, "Event Loop Start");
01745
01746 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
01747
01748
01749 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
01750 if ((readerStates[j])->readerID != 0)
01751 currentReaderCount++;
01752
01753 j = 0;
01754
01755 do
01756 {
01757 int newReaderCount = 0;
01758 char ReaderCountChanged = FALSE;
01759
01760 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01761 {
01762 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01763
01764 PROFILE_END
01765
01766 return SCARD_E_NO_SERVICE;
01767 }
01768
01769 if (j == 0)
01770 {
01771 int i;
01772
01773 for (i=0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01774 if ((readerStates[i])->readerID != 0)
01775 newReaderCount++;
01776
01777 if (newReaderCount != currentReaderCount)
01778 {
01779 Log1(PCSC_LOG_INFO, "Reader list changed");
01780 ReaderCountChanged = TRUE;
01781 currentReaderCount = newReaderCount;
01782 }
01783 }
01784 currReader = &rgReaderStates[j];
01785
01786
01787
01788 if (currReader->dwCurrentState & SCARD_STATE_IGNORE)
01789 {
01790 currReader->dwEventState = SCARD_STATE_IGNORE;
01791 } else
01792 {
01793 LPTSTR lpcReaderName;
01794 int i;
01795
01796
01797
01798 lpcReaderName = (char *) currReader->szReader;
01799
01800 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01801 {
01802 if (strcmp(lpcReaderName,
01803 (readerStates[i])->readerName) == 0)
01804 {
01805 break;
01806 }
01807 }
01808
01809
01810
01811
01812 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01813 {
01814 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01815 {
01816 currReader->dwEventState = SCARD_STATE_UNKNOWN;
01817 } else
01818 {
01819 currReader->dwEventState =
01820 SCARD_STATE_UNKNOWN | SCARD_STATE_CHANGED;
01821
01822
01823
01824
01825
01826 dwBreakFlag = 1;
01827 }
01828 } else
01829 {
01830
01831
01832
01833
01834 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01835 {
01836 currReader->dwEventState |= SCARD_STATE_CHANGED;
01837 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01838 dwBreakFlag = 1;
01839 }
01840
01841
01842
01843
01844
01845
01846 rContext = readerStates[i];
01847
01848
01849
01850
01851 dwState = rContext->readerState;
01852
01853
01854 if (dwState & SCARD_UNKNOWN)
01855 {
01856
01857
01858
01859 if (currReader->
01860 dwCurrentState & SCARD_STATE_UNAVAILABLE)
01861 {
01862 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
01863 } else
01864 {
01865
01866
01867
01868
01869 currReader->dwEventState = SCARD_STATE_CHANGED |
01870 SCARD_STATE_UNAVAILABLE;
01871 dwBreakFlag = 1;
01872 }
01873 } else
01874 {
01875
01876
01877
01878 if (currReader->
01879 dwCurrentState & SCARD_STATE_UNAVAILABLE)
01880 {
01881 currReader->dwEventState &=
01882 ~SCARD_STATE_UNAVAILABLE;
01883 currReader->dwEventState |= SCARD_STATE_CHANGED;
01884 dwBreakFlag = 1;
01885 }
01886 }
01887
01888
01889
01890 if (dwState & SCARD_PRESENT)
01891 {
01892
01893 if (0 == rContext->cardAtrLength)
01894
01895 SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
01896
01897 currReader->cbAtr = rContext->cardAtrLength;
01898 memcpy(currReader->rgbAtr, rContext->cardAtr,
01899 currReader->cbAtr);
01900 } else
01901 {
01902 currReader->cbAtr = 0;
01903 }
01904
01905
01906
01907
01908 if (dwState & SCARD_ABSENT)
01909 {
01910 currReader->dwEventState |= SCARD_STATE_EMPTY;
01911 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
01912 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
01913 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
01914 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01915 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
01916 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
01917 currReader->dwEventState &= ~SCARD_STATE_MUTE;
01918 currReader->dwEventState &= ~SCARD_STATE_INUSE;
01919
01920
01921
01922
01923 if (currReader->dwCurrentState & SCARD_STATE_PRESENT ||
01924 currReader->dwCurrentState & SCARD_STATE_ATRMATCH
01925 || currReader->
01926 dwCurrentState & SCARD_STATE_EXCLUSIVE
01927 || currReader->dwCurrentState & SCARD_STATE_INUSE)
01928 {
01929 currReader->dwEventState |= SCARD_STATE_CHANGED;
01930 dwBreakFlag = 1;
01931 }
01932
01933
01934
01935
01936 } else if (dwState & SCARD_PRESENT)
01937 {
01938 currReader->dwEventState |= SCARD_STATE_PRESENT;
01939 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
01940 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
01941 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
01942 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01943 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
01944 currReader->dwEventState &= ~SCARD_STATE_MUTE;
01945
01946 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
01947 {
01948 currReader->dwEventState |= SCARD_STATE_CHANGED;
01949 dwBreakFlag = 1;
01950 }
01951
01952 if (dwState & SCARD_SWALLOWED)
01953 {
01954 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
01955 {
01956 currReader->dwEventState |= SCARD_STATE_MUTE;
01957 } else
01958 {
01959 currReader->dwEventState |= SCARD_STATE_MUTE;
01960 if (currReader->dwCurrentState !=
01961 SCARD_STATE_UNAWARE)
01962 {
01963 currReader->dwEventState |=
01964 SCARD_STATE_CHANGED;
01965 }
01966 dwBreakFlag = 1;
01967 }
01968 } else
01969 {
01970
01971
01972
01973 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
01974 {
01975 currReader->dwEventState |=
01976 SCARD_STATE_CHANGED;
01977 dwBreakFlag = 1;
01978 }
01979 }
01980 }
01981
01982
01983
01984
01985 if (rContext->readerSharing == -1)
01986 {
01987 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
01988 currReader->dwEventState &= ~SCARD_STATE_INUSE;
01989 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
01990 {
01991 currReader->dwEventState |= SCARD_STATE_CHANGED;
01992 dwBreakFlag = 1;
01993 }
01994 } else if (rContext->readerSharing >= 1)
01995 {
01996
01997
01998
01999 if (dwState & SCARD_PRESENT)
02000 {
02001 currReader->dwEventState |= SCARD_STATE_INUSE;
02002 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02003 if (currReader->
02004 dwCurrentState & SCARD_STATE_EXCLUSIVE)
02005 {
02006 currReader->dwEventState |=
02007 SCARD_STATE_CHANGED;
02008 dwBreakFlag = 1;
02009 }
02010 }
02011 } else if (rContext->readerSharing == 0)
02012 {
02013 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02014 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02015
02016 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02017 {
02018 currReader->dwEventState |= SCARD_STATE_CHANGED;
02019 dwBreakFlag = 1;
02020 } else if (currReader->
02021 dwCurrentState & SCARD_STATE_EXCLUSIVE)
02022 {
02023 currReader->dwEventState |= SCARD_STATE_CHANGED;
02024 dwBreakFlag = 1;
02025 }
02026 }
02027
02028 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02029 {
02030
02031
02032
02033
02034 currReader->dwEventState |= SCARD_STATE_CHANGED;
02035 dwBreakFlag = 1;
02036 }
02037
02038 }
02039
02040 }
02041
02042
02043
02044
02045 j = j + 1;
02046 if (j == cReaders)
02047 {
02048 if (!dwBreakFlag)
02049 {
02050
02051
02052
02053
02054 if (ReaderCountChanged)
02055 break;
02056 }
02057 j = 0;
02058 }
02059
02060
02061
02062
02063
02064 if (psContextMap[dwContextIndex].contextBlockStatus ==
02065 BLOCK_STATUS_RESUME)
02066 break;
02067
02068
02069
02070
02071 if ((dwBreakFlag == 1) && (j == 0))
02072 break;
02073
02074
02075
02076
02077 if ((dwTimeout == 0) && (j == 0))
02078 break;
02079
02080 if (dwTimeout != INFINITE && dwTimeout != 0)
02081 {
02082
02083
02084
02085
02086 if ((dwTime >= (dwTimeout * 1000)) && (j == 0))
02087 {
02088 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02089 return SCARD_E_TIMEOUT;
02090 }
02091 }
02092
02093
02094
02095
02096 if (j == 0)
02097 {
02098 SYS_USleep(PCSCLITE_STATUS_WAIT);
02099 dwTime += PCSCLITE_STATUS_WAIT;
02100 }
02101 }
02102 while (1);
02103
02104 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02105
02106 if (psContextMap[dwContextIndex].contextBlockStatus ==
02107 BLOCK_STATUS_RESUME)
02108 {
02109 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02110 return SCARD_E_CANCELLED;
02111 }
02112
02113 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02114
02115 PROFILE_END
02116
02117 return SCARD_S_SUCCESS;
02118 }
02119
02166 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02167 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02168 LPDWORD lpBytesReturned)
02169 {
02170 LONG rv;
02171 control_struct scControlStruct;
02172 sharedSegmentMsg msgStruct;
02173 int i;
02174 DWORD dwContextIndex, dwChannelIndex;
02175
02176 PROFILE_START
02177
02178
02179 if (NULL != lpBytesReturned)
02180 *lpBytesReturned = 0;
02181
02182 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02183 return SCARD_E_NO_SERVICE;
02184
02185
02186
02187
02188 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02189
02190 if (rv == -1)
02191 return SCARD_E_INVALID_HANDLE;
02192
02193 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02194
02195 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02196 {
02197 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02198
02199
02200 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02201 break;
02202 }
02203
02204 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02205 {
02206 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02207 return SCARD_E_READER_UNAVAILABLE;
02208 }
02209
02210 if (cbSendLength > MAX_BUFFER_SIZE)
02211 {
02212 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02213 return SCARD_E_INSUFFICIENT_BUFFER;
02214 }
02215
02216 scControlStruct.hCard = hCard;
02217 scControlStruct.dwControlCode = dwControlCode;
02218 scControlStruct.cbSendLength = cbSendLength;
02219 scControlStruct.cbRecvLength = cbRecvLength;
02220 memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02221
02222 rv = WrapSHMWrite(SCARD_CONTROL, psContextMap[dwContextIndex].dwClientID,
02223 sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
02224
02225 if (rv == -1)
02226 {
02227 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02228 return SCARD_E_NO_SERVICE;
02229 }
02230
02231
02232
02233
02234 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02235
02236 if (rv == -1)
02237 {
02238 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02239 return SCARD_F_COMM_ERROR;
02240 }
02241
02242 memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
02243
02244 if (NULL != lpBytesReturned)
02245 *lpBytesReturned = scControlStruct.dwBytesReturned;
02246
02247 if (scControlStruct.rv == SCARD_S_SUCCESS)
02248 {
02249
02250
02251
02252 memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
02253 scControlStruct.cbRecvLength);
02254 memset(scControlStruct.pbRecvBuffer, 0x00,
02255 sizeof(scControlStruct.pbRecvBuffer));
02256 }
02257
02258 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02259
02260 PROFILE_END
02261
02262 return scControlStruct.rv;
02263 }
02264
02345 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02346 LPDWORD pcbAttrLen)
02347 {
02348 PROFILE_START
02349
02350 if (NULL == pcbAttrLen)
02351 return SCARD_E_INVALID_PARAMETER;
02352
02353
02354 if (NULL == pbAttr)
02355
02356 *pcbAttrLen = MAX_BUFFER_SIZE;
02357
02358 PROFILE_END
02359
02360 return SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, pbAttr,
02361 pcbAttrLen);
02362 }
02363
02394 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02395 DWORD cbAttrLen)
02396 {
02397 PROFILE_START
02398
02399 if (NULL == pbAttr || 0 == cbAttrLen)
02400 return SCARD_E_INVALID_PARAMETER;
02401
02402 PROFILE_END
02403
02404 return SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02405 &cbAttrLen);
02406 }
02407
02408 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02409 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02410 {
02411 PROFILE_START
02412
02413 LONG rv;
02414 getset_struct scGetSetStruct;
02415 sharedSegmentMsg msgStruct;
02416 int i;
02417 DWORD dwContextIndex, dwChannelIndex;
02418
02419 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02420 return SCARD_E_NO_SERVICE;
02421
02422
02423
02424
02425 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02426
02427 if (rv == -1)
02428 return SCARD_E_INVALID_HANDLE;
02429
02430 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02431
02432 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02433 {
02434 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02435
02436
02437 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02438 break;
02439 }
02440
02441 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02442 {
02443 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02444 return SCARD_E_READER_UNAVAILABLE;
02445 }
02446
02447 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02448 {
02449 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02450 return SCARD_E_INSUFFICIENT_BUFFER;
02451 }
02452
02453 scGetSetStruct.hCard = hCard;
02454 scGetSetStruct.dwAttrId = dwAttrId;
02455 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02456 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02457 if (SCARD_SET_ATTRIB == command)
02458 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02459
02460 rv = WrapSHMWrite(command,
02461 psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
02462 PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
02463
02464 if (rv == -1)
02465 {
02466 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02467 return SCARD_E_NO_SERVICE;
02468 }
02469
02470
02471
02472
02473 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02474
02475 if (rv == -1)
02476 {
02477 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02478 return SCARD_F_COMM_ERROR;
02479 }
02480
02481 memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
02482
02483 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02484 {
02485
02486
02487
02488 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02489 {
02490 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02491 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02492 }
02493 else
02494 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02495
02496 if (pbAttr)
02497 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02498
02499 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02500 }
02501
02502 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02503
02504 PROFILE_END
02505
02506 return scGetSetStruct.rv;
02507 }
02508
02562 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02563 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02564 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02565 LPDWORD pcbRecvLength)
02566 {
02567 LONG rv;
02568 transmit_struct scTransmitStruct;
02569 sharedSegmentMsg msgStruct;
02570 int i;
02571 DWORD dwContextIndex, dwChannelIndex;
02572
02573 PROFILE_START
02574
02575 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02576 pcbRecvLength == NULL || pioSendPci == NULL)
02577 return SCARD_E_INVALID_PARAMETER;
02578
02579 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02580 return SCARD_E_NO_SERVICE;
02581
02582
02583
02584
02585 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02586
02587 if (rv == -1)
02588 {
02589 *pcbRecvLength = 0;
02590 return SCARD_E_INVALID_HANDLE;
02591 }
02592
02593 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02594
02595 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02596 {
02597 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02598
02599
02600 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02601 break;
02602 }
02603
02604 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02605 {
02606 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02607 return SCARD_E_READER_UNAVAILABLE;
02608 }
02609
02610 if (cbSendLength > MAX_BUFFER_SIZE)
02611 {
02612 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02613 return SCARD_E_INSUFFICIENT_BUFFER;
02614 }
02615
02616 scTransmitStruct.hCard = hCard;
02617 scTransmitStruct.cbSendLength = cbSendLength;
02618 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
02619 memcpy(&scTransmitStruct.pioSendPci, pioSendPci,
02620 sizeof(SCARD_IO_REQUEST));
02621 memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02622
02623 if (pioRecvPci)
02624 {
02625 memcpy(&scTransmitStruct.pioRecvPci, pioRecvPci,
02626 sizeof(SCARD_IO_REQUEST));
02627 }
02628 else
02629 scTransmitStruct.pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
02630
02631 rv = WrapSHMWrite(SCARD_TRANSMIT, psContextMap[dwContextIndex].dwClientID,
02632 sizeof(scTransmitStruct),
02633 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
02634
02635 if (rv == -1)
02636 {
02637 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02638 return SCARD_E_NO_SERVICE;
02639 }
02640
02641
02642
02643
02644 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02645
02646 memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
02647
02648 if (rv == -1)
02649 {
02650 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02651 return SCARD_F_COMM_ERROR;
02652 }
02653
02654
02655
02656
02657 memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
02658
02659 if (scTransmitStruct.rv == SCARD_S_SUCCESS)
02660 {
02661
02662
02663
02664 memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
02665 scTransmitStruct.pcbRecvLength);
02666 memset(scTransmitStruct.pbRecvBuffer, 0x00,
02667 scTransmitStruct.pcbRecvLength);
02668
02669 if (pioRecvPci)
02670 memcpy(pioRecvPci, &scTransmitStruct.pioRecvPci,
02671 sizeof(SCARD_IO_REQUEST));
02672 }
02673
02674 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
02675 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02676
02677 PROFILE_END
02678
02679 return scTransmitStruct.rv;
02680 }
02681
02711 LONG SCardListReaders(SCARDCONTEXT hContext, LPCTSTR mszGroups,
02712 LPTSTR mszReaders, LPDWORD pcchReaders)
02713 {
02714 DWORD dwReadersLen;
02715 int i, lastChrPtr;
02716 DWORD dwContextIndex;
02717
02718 PROFILE_START
02719
02720
02721
02722
02723 if (pcchReaders == NULL)
02724 return SCARD_E_INVALID_PARAMETER;
02725
02726 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02727 return SCARD_E_NO_SERVICE;
02728
02729
02730
02731
02732 dwContextIndex = SCardGetContextIndice(hContext);
02733 if (dwContextIndex == -1)
02734 return SCARD_E_INVALID_HANDLE;
02735
02736 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02737
02738 dwReadersLen = 0;
02739 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02740 if ((readerStates[i])->readerID != 0)
02741 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
02742
02743
02744 dwReadersLen += 1;
02745
02746 if ((mszReaders == NULL)
02747 || (*pcchReaders == 0))
02748 {
02749 *pcchReaders = dwReadersLen;
02750 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02751 return SCARD_S_SUCCESS;
02752 }
02753
02754 if (*pcchReaders < dwReadersLen)
02755 {
02756 *pcchReaders = dwReadersLen;
02757 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02758 return SCARD_E_INSUFFICIENT_BUFFER;
02759 }
02760
02761 lastChrPtr = 0;
02762 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02763 {
02764 if ((readerStates[i])->readerID != 0)
02765 {
02766
02767
02768
02769 strcpy(&mszReaders[lastChrPtr], (readerStates[i])->readerName);
02770 lastChrPtr += strlen((readerStates[i])->readerName)+1;
02771 }
02772 }
02773 mszReaders[lastChrPtr] = '\0';
02774
02775 *pcchReaders = dwReadersLen;
02776
02777 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02778
02779 PROFILE_END
02780
02781 return SCARD_S_SUCCESS;
02782 }
02783
02815 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPTSTR mszGroups,
02816 LPDWORD pcchGroups)
02817 {
02818 LONG rv = SCARD_S_SUCCESS;
02819 DWORD dwContextIndex;
02820
02821 PROFILE_START
02822
02823 const char ReaderGroup[] = "SCard$DefaultReaders";
02824 const int dwGroups = strlen(ReaderGroup) + 2;
02825
02826 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02827 return SCARD_E_NO_SERVICE;
02828
02829
02830
02831
02832 dwContextIndex = SCardGetContextIndice(hContext);
02833 if (dwContextIndex == -1)
02834 return SCARD_E_INVALID_HANDLE;
02835
02836 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02837
02838 if (mszGroups)
02839 {
02840
02841 if (*pcchGroups < dwGroups)
02842 rv = SCARD_E_INSUFFICIENT_BUFFER;
02843 else
02844 {
02845 memset(mszGroups, 0, dwGroups);
02846 memcpy(mszGroups, ReaderGroup, strlen(ReaderGroup));
02847 }
02848 }
02849
02850 *pcchGroups = dwGroups;
02851
02852 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02853
02854 PROFILE_END
02855
02856 return rv;
02857 }
02858
02886 LONG SCardCancel(SCARDCONTEXT hContext)
02887 {
02888 DWORD dwContextIndex;
02889
02890 PROFILE_START
02891
02892 dwContextIndex = SCardGetContextIndice(hContext);
02893
02894 if (dwContextIndex == -1)
02895 return SCARD_E_INVALID_HANDLE;
02896
02897
02898
02899
02900
02901 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
02902
02903 PROFILE_END
02904
02905 return SCARD_S_SUCCESS;
02906 }
02907
02924 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
02925 {
02926 int i;
02927
02928 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
02929 {
02930 if (psContextMap[i].hContext == 0)
02931 {
02932 psContextMap[i].hContext = hContext;
02933 psContextMap[i].dwClientID = dwClientID;
02934 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
02935 psContextMap[i].mMutex = (PCSCLITE_MUTEX_T) malloc(sizeof(PCSCLITE_MUTEX));
02936 SYS_MutexInit(psContextMap[i].mMutex);
02937 return SCARD_S_SUCCESS;
02938 }
02939 }
02940
02941 return SCARD_E_NO_MEMORY;
02942 }
02943
02956 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
02957 {
02958 LONG rv;
02959
02960 SCardLockThread();
02961 rv = SCardGetContextIndiceTH(hContext);
02962 SCardUnlockThread();
02963
02964 return rv;
02965 }
02966
02979 static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
02980 {
02981 int i;
02982
02983
02984
02985
02986 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
02987 {
02988 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
02989 return i;
02990 }
02991
02992 return -1;
02993 }
02994
03004 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
03005 {
03006 LONG retIndice;
03007
03008 retIndice = SCardGetContextIndiceTH(hContext);
03009
03010 if (retIndice == -1)
03011 return SCARD_E_INVALID_HANDLE;
03012 else
03013 {
03014 int i;
03015
03016 psContextMap[retIndice].hContext = 0;
03017 SHMClientCloseSession(psContextMap[retIndice].dwClientID);
03018 psContextMap[retIndice].dwClientID = 0;
03019 free(psContextMap[retIndice].mMutex);
03020 psContextMap[retIndice].mMutex = NULL;
03021 psContextMap[retIndice].contextBlockStatus = BLOCK_STATUS_RESUME;
03022
03023 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03024 {
03025
03026
03027
03028 psContextMap[retIndice].psChannelMap[i].hCard = 0;
03029 free(psContextMap[retIndice].psChannelMap[i].readerName);
03030 psContextMap[retIndice].psChannelMap[i].readerName = NULL;
03031 }
03032
03033 return SCARD_S_SUCCESS;
03034 }
03035 }
03036
03037
03038
03039
03040
03041 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
03042 LPTSTR readerName)
03043 {
03044 int i;
03045
03046 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03047 {
03048 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
03049 {
03050 psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
03051 psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
03052 return SCARD_S_SUCCESS;
03053 }
03054 }
03055
03056 return SCARD_E_NO_MEMORY;
03057 }
03058
03059 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03060 {
03061 DWORD dwContextIndice, dwChannelIndice;
03062 LONG rv;
03063
03064 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
03065
03066 if (rv == -1)
03067 return SCARD_E_INVALID_HANDLE;
03068 else
03069 {
03070 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
03071 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
03072 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
03073 return SCARD_S_SUCCESS;
03074 }
03075 }
03076
03077 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03078 {
03079 LONG rv;
03080
03081 SCardLockThread();
03082 rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
03083 SCardUnlockThread();
03084
03085 return rv;
03086 }
03087
03088 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03089 {
03090 int i;
03091
03092 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03093 {
03094 if (psContextMap[i].hContext != 0)
03095 {
03096 int j;
03097
03098 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
03099 {
03100 if (psContextMap[i].psChannelMap[j].hCard == hCard)
03101 {
03102 *pdwContextIndice = i;
03103 *pdwChannelIndice = j;
03104 return SCARD_S_SUCCESS;
03105 }
03106 }
03107
03108 }
03109 }
03110
03111 return -1;
03112 }
03113
03120 inline static LONG SCardLockThread(void)
03121 {
03122 return SYS_MutexLock(&clientMutex);
03123 }
03124
03130 inline static LONG SCardUnlockThread(void)
03131 {
03132 return SYS_MutexUnLock(&clientMutex);
03133 }
03134
03142 static LONG SCardCheckDaemonAvailability(void)
03143 {
03144 LONG rv;
03145 struct stat statBuffer;
03146
03147 rv = SYS_Stat(PCSCLITE_IPC_DIR, &statBuffer);
03148
03149 if (rv != 0)
03150 {
03151 Log1(PCSC_LOG_ERROR, "PCSC Not Running");
03152 return SCARD_E_NO_SERVICE;
03153 }
03154
03155 return SCARD_S_SUCCESS;
03156 }
03157
03163 #ifdef __SUNPRO_C
03164 #pragma fini (SCardUnload)
03165 #endif
03166
03167 void DESTRUCTOR SCardUnload(void)
03168 {
03169 if (!isExecuted)
03170 return;
03171
03172 SYS_CloseFile(mapAddr);
03173 isExecuted = 0;
03174 }
03175