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 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 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] = (PREADER_STATE)
00332 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, dwClientID,
00407 PCSCLITE_MCLIENT_ATTEMPTS))
00408 return SCARD_E_NO_SERVICE;
00409
00410
00411
00412
00413 if (-1 == SHMMessageReceive(&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 isExecuted = 1;
00424 }
00425
00426
00427 if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
00428 dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
00429 {
00430 return SCARD_E_INVALID_VALUE;
00431 }
00432
00433
00434
00435
00436 scEstablishStruct.dwScope = dwScope;
00437 scEstablishStruct.phContext = 0;
00438 scEstablishStruct.rv = 0;
00439
00440 rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
00441 sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
00442 (void *) &scEstablishStruct);
00443
00444 if (rv == -1)
00445 return SCARD_E_NO_SERVICE;
00446
00447
00448
00449
00450 rv = SHMClientRead(&msgStruct, dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00451
00452 if (rv == -1)
00453 return SCARD_F_COMM_ERROR;
00454
00455 memcpy(&scEstablishStruct, &msgStruct.data, sizeof(scEstablishStruct));
00456
00457 if (scEstablishStruct.rv != SCARD_S_SUCCESS)
00458 return scEstablishStruct.rv;
00459
00460 *phContext = scEstablishStruct.phContext;
00461
00462
00463
00464
00465 rv = SCardAddContext(*phContext, dwClientID);
00466
00467 return rv;
00468 }
00469
00488 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00489 {
00490 LONG rv;
00491 release_struct scReleaseStruct;
00492 sharedSegmentMsg msgStruct;
00493 DWORD dwContextIndex;
00494
00495 PROFILE_START
00496
00497 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00498 return SCARD_E_NO_SERVICE;
00499
00500
00501
00502
00503 dwContextIndex = SCardGetContextIndice(hContext);
00504 if (dwContextIndex == -1)
00505 return SCARD_E_INVALID_HANDLE;
00506
00507 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00508
00509 scReleaseStruct.hContext = hContext;
00510 scReleaseStruct.rv = 0;
00511
00512 rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT, psContextMap[dwContextIndex].dwClientID,
00513 sizeof(scReleaseStruct),
00514 PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);
00515
00516 if (rv == -1)
00517 {
00518 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00519 return SCARD_E_NO_SERVICE;
00520 }
00521
00522
00523
00524
00525 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00526 memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));
00527
00528 if (rv == -1)
00529 {
00530 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00531 return SCARD_F_COMM_ERROR;
00532 }
00533
00534 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00535
00536
00537
00538
00539 SCardLockThread();
00540 SCardRemoveContext(hContext);
00541 SCardUnlockThread();
00542
00543 PROFILE_END
00544
00545 return scReleaseStruct.rv;
00546 }
00547
00560 LONG SCardSetTimeout(SCARDCONTEXT hContext, DWORD dwTimeout)
00561 {
00562
00563
00564
00565
00566 return SCARD_S_SUCCESS;
00567 }
00568
00617 LONG SCardConnect(SCARDCONTEXT hContext, LPCTSTR szReader,
00618 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00619 LPDWORD pdwActiveProtocol)
00620 {
00621 LONG rv;
00622 connect_struct scConnectStruct;
00623 sharedSegmentMsg msgStruct;
00624 DWORD dwContextIndex;
00625
00626 PROFILE_START
00627
00628
00629
00630
00631 if (phCard == NULL || pdwActiveProtocol == NULL)
00632 return SCARD_E_INVALID_PARAMETER;
00633 else
00634 *phCard = 0;
00635
00636 if (szReader == NULL)
00637 return SCARD_E_UNKNOWN_READER;
00638
00639
00640
00641
00642 if (strlen(szReader) > MAX_READERNAME)
00643 return SCARD_E_INVALID_VALUE;
00644
00645 if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00646 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00647 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00648 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00649 {
00650 return SCARD_E_INVALID_VALUE;
00651 }
00652
00653 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00654 return SCARD_E_NO_SERVICE;
00655
00656
00657
00658
00659 dwContextIndex = SCardGetContextIndice(hContext);
00660 if (dwContextIndex == -1)
00661 return SCARD_E_INVALID_HANDLE;
00662
00663 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00664
00665 strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);
00666
00667 scConnectStruct.hContext = hContext;
00668 scConnectStruct.dwShareMode = dwShareMode;
00669 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00670 scConnectStruct.phCard = *phCard;
00671 scConnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00672
00673 rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
00674 sizeof(scConnectStruct),
00675 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);
00676
00677 if (rv == -1)
00678 {
00679 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00680 return SCARD_E_NO_SERVICE;
00681 }
00682
00683
00684
00685
00686 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00687
00688 memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));
00689
00690 if (rv == -1)
00691 {
00692 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00693 return SCARD_F_COMM_ERROR;
00694 }
00695
00696 *phCard = scConnectStruct.phCard;
00697 *pdwActiveProtocol = scConnectStruct.pdwActiveProtocol;
00698
00699 if (scConnectStruct.rv == SCARD_S_SUCCESS)
00700 {
00701
00702
00703
00704 rv = SCardAddHandle(*phCard, dwContextIndex, (LPTSTR) szReader);
00705 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00706
00707 PROFILE_END
00708
00709 return rv;
00710 }
00711
00712 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00713
00714 PROFILE_END
00715
00716 return scConnectStruct.rv;
00717 }
00718
00784 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00785 DWORD dwPreferredProtocols, DWORD dwInitialization,
00786 LPDWORD pdwActiveProtocol)
00787 {
00788 LONG rv;
00789 reconnect_struct scReconnectStruct;
00790 sharedSegmentMsg msgStruct;
00791 int i;
00792 DWORD dwContextIndex, dwChannelIndex;
00793
00794 PROFILE_START
00795
00796 if (dwInitialization != SCARD_LEAVE_CARD &&
00797 dwInitialization != SCARD_RESET_CARD &&
00798 dwInitialization != SCARD_UNPOWER_CARD &&
00799 dwInitialization != SCARD_EJECT_CARD)
00800 {
00801 return SCARD_E_INVALID_VALUE;
00802 }
00803
00804 if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00805 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00806 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00807 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00808 {
00809 return SCARD_E_INVALID_VALUE;
00810 }
00811
00812 if (pdwActiveProtocol == NULL)
00813 return SCARD_E_INVALID_PARAMETER;
00814
00815 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00816 return SCARD_E_NO_SERVICE;
00817
00818
00819
00820
00821 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00822
00823 if (rv == -1)
00824 return SCARD_E_INVALID_HANDLE;
00825
00826 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00827
00828
00829 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00830 {
00831 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
00832
00833
00834 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
00835 break;
00836 }
00837
00838 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00839 {
00840 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00841 return SCARD_E_READER_UNAVAILABLE;
00842 }
00843
00844 scReconnectStruct.hCard = hCard;
00845 scReconnectStruct.dwShareMode = dwShareMode;
00846 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00847 scReconnectStruct.dwInitialization = dwInitialization;
00848 scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00849
00850 rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
00851 sizeof(scReconnectStruct),
00852 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
00853
00854 if (rv == -1)
00855 {
00856 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00857 return SCARD_E_NO_SERVICE;
00858 }
00859
00860
00861
00862
00863 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00864
00865 memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
00866
00867 if (rv == -1)
00868 {
00869 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00870 return SCARD_F_COMM_ERROR;
00871 }
00872
00873 *pdwActiveProtocol = scReconnectStruct.pdwActiveProtocol;
00874
00875 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00876
00877 PROFILE_END
00878
00879 return scReconnectStruct.rv;
00880 }
00881
00912 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
00913 {
00914 LONG rv;
00915 disconnect_struct scDisconnectStruct;
00916 sharedSegmentMsg msgStruct;
00917 DWORD dwContextIndex, dwChannelIndex;
00918
00919 PROFILE_START
00920
00921 if (dwDisposition != SCARD_LEAVE_CARD &&
00922 dwDisposition != SCARD_RESET_CARD &&
00923 dwDisposition != SCARD_UNPOWER_CARD &&
00924 dwDisposition != SCARD_EJECT_CARD)
00925 {
00926 return SCARD_E_INVALID_VALUE;
00927 }
00928
00929 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00930 return SCARD_E_NO_SERVICE;
00931
00932
00933
00934
00935 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00936
00937 if (rv == -1)
00938 return SCARD_E_INVALID_HANDLE;
00939
00940 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00941
00942 scDisconnectStruct.hCard = hCard;
00943 scDisconnectStruct.dwDisposition = dwDisposition;
00944
00945 rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
00946 sizeof(scDisconnectStruct),
00947 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
00948
00949 if (rv == -1)
00950 {
00951 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00952 return SCARD_E_NO_SERVICE;
00953 }
00954
00955
00956
00957
00958 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00959
00960 memcpy(&scDisconnectStruct, &msgStruct.data,
00961 sizeof(scDisconnectStruct));
00962
00963 if (rv == -1)
00964 {
00965 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00966 return SCARD_F_COMM_ERROR;
00967 }
00968
00969 SCardRemoveHandle(hCard);
00970
00971 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00972
00973 PROFILE_END
00974
00975 return scDisconnectStruct.rv;
00976 }
00977
01010 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01011 {
01012
01013 LONG rv;
01014 begin_struct scBeginStruct;
01015 int i;
01016 sharedSegmentMsg msgStruct;
01017 DWORD dwContextIndex, dwChannelIndex;
01018
01019 PROFILE_START
01020
01021 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01022 return SCARD_E_NO_SERVICE;
01023
01024
01025
01026
01027 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01028
01029 if (rv == -1)
01030 return SCARD_E_INVALID_HANDLE;
01031
01032 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01033
01034 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01035 {
01036 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01037
01038
01039 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01040 break;
01041 }
01042
01043 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01044 {
01045 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01046 return SCARD_E_READER_UNAVAILABLE;
01047 }
01048
01049 scBeginStruct.hCard = hCard;
01050
01051
01052
01053
01054
01055
01056 do
01057 {
01058
01059
01060
01061
01062 if ((readerStates[i])->lockState != 0)
01063 {
01064 int randnum = 0;
01065 int j;
01066
01067 for (j = 0; j < 100; j++)
01068 {
01069
01070
01071
01072 randnum = SYS_RandomInt(1000, 10000);
01073 SYS_USleep(randnum);
01074
01075 if ((readerStates[i])->lockState == 0)
01076 {
01077 break;
01078 }
01079 }
01080 }
01081
01082 rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01083 sizeof(scBeginStruct),
01084 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);
01085
01086 if (rv == -1)
01087 {
01088
01089 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01090 return SCARD_E_NO_SERVICE;
01091 }
01092
01093
01094
01095
01096 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01097
01098
01099 memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));
01100
01101 if (rv == -1)
01102 {
01103
01104 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01105 return SCARD_F_COMM_ERROR;
01106 }
01107
01108 }
01109 while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
01110
01111 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01112
01113 PROFILE_END
01114
01115 return scBeginStruct.rv;
01116 }
01117
01156 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01157 {
01158 LONG rv;
01159 end_struct scEndStruct;
01160 sharedSegmentMsg msgStruct;
01161 int randnum, i;
01162 DWORD dwContextIndex, dwChannelIndex;
01163
01164 PROFILE_START
01165
01166
01167
01168
01169 randnum = 0;
01170
01171 if (dwDisposition != SCARD_LEAVE_CARD &&
01172 dwDisposition != SCARD_RESET_CARD &&
01173 dwDisposition != SCARD_UNPOWER_CARD &&
01174 dwDisposition != SCARD_EJECT_CARD)
01175 {
01176 return SCARD_E_INVALID_VALUE;
01177 }
01178
01179 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01180 return SCARD_E_NO_SERVICE;
01181
01182
01183
01184
01185 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01186
01187 if (rv == -1)
01188 return SCARD_E_INVALID_HANDLE;
01189
01190 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01191
01192 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01193 {
01194 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01195
01196
01197 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01198 break;
01199 }
01200
01201 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01202 {
01203 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01204 return SCARD_E_READER_UNAVAILABLE;
01205 }
01206
01207 scEndStruct.hCard = hCard;
01208 scEndStruct.dwDisposition = dwDisposition;
01209
01210 rv = WrapSHMWrite(SCARD_END_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01211 sizeof(scEndStruct),
01212 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
01213
01214 if (rv == -1)
01215 {
01216 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01217 return SCARD_E_NO_SERVICE;
01218 }
01219
01220
01221
01222
01223 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01224
01225 memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
01226
01227 if (rv == -1)
01228 {
01229 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01230 return SCARD_F_COMM_ERROR;
01231 }
01232
01233
01234
01235
01236 randnum = SYS_RandomInt(1000, 10000);
01237 SYS_USleep(randnum);
01238
01239 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01240
01241 PROFILE_END
01242
01243 return scEndStruct.rv;
01244 }
01245
01251 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01252 {
01253 LONG rv;
01254 cancel_struct scCancelStruct;
01255 sharedSegmentMsg msgStruct;
01256 int i;
01257 DWORD dwContextIndex, dwChannelIndex;
01258
01259 PROFILE_START
01260
01261 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01262 return SCARD_E_NO_SERVICE;
01263
01264
01265
01266
01267 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01268
01269 if (rv == -1)
01270 return SCARD_E_INVALID_HANDLE;
01271
01272 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01273
01274 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01275 {
01276 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01277
01278
01279 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01280 break;
01281 }
01282
01283 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01284 {
01285 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01286 return SCARD_E_READER_UNAVAILABLE;
01287 }
01288
01289 scCancelStruct.hCard = hCard;
01290
01291 rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01292 sizeof(scCancelStruct),
01293 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
01294
01295 if (rv == -1)
01296 {
01297 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01298 return SCARD_E_NO_SERVICE;
01299 }
01300
01301
01302
01303
01304 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01305
01306 memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
01307
01308 if (rv == -1)
01309 {
01310 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01311 return SCARD_F_COMM_ERROR;
01312 }
01313
01314 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01315
01316 PROFILE_END
01317
01318 return scCancelStruct.rv;
01319 }
01320
01377 LONG SCardStatus(SCARDHANDLE hCard, LPTSTR mszReaderNames,
01378 LPDWORD pcchReaderLen, LPDWORD pdwState,
01379 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
01380 {
01381 DWORD dwReaderLen, dwAtrLen;
01382 LONG rv;
01383 int i;
01384 status_struct scStatusStruct;
01385 sharedSegmentMsg msgStruct;
01386 DWORD dwContextIndex, dwChannelIndex;
01387
01388 PROFILE_START
01389
01390
01391
01392
01393
01394 if (pcchReaderLen == NULL || pcbAtrLen == NULL)
01395 return SCARD_E_INVALID_PARAMETER;
01396
01397
01398 dwReaderLen = *pcchReaderLen;
01399 dwAtrLen = *pcbAtrLen;
01400
01401
01402 if (pdwState)
01403 *pdwState = 0;
01404
01405 if (pdwProtocol)
01406 *pdwProtocol = 0;
01407
01408 *pcchReaderLen = 0;
01409 *pcbAtrLen = 0;
01410
01411 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01412 return SCARD_E_NO_SERVICE;
01413
01414
01415
01416
01417 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01418
01419 if (rv == -1)
01420 return SCARD_E_INVALID_HANDLE;
01421
01422 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01423
01424 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01425 {
01426 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01427
01428
01429 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01430 break;
01431 }
01432
01433 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01434 {
01435 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01436 return SCARD_E_READER_UNAVAILABLE;
01437 }
01438
01439
01440 memset(&scStatusStruct, 0, sizeof(scStatusStruct));
01441 scStatusStruct.hCard = hCard;
01442
01443
01444 scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
01445 scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
01446
01447 rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
01448 sizeof(scStatusStruct),
01449 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
01450
01451 if (rv == -1)
01452 {
01453 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01454 return SCARD_E_NO_SERVICE;
01455 }
01456
01457
01458
01459
01460 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01461
01462 memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
01463
01464 if (rv == -1)
01465 {
01466 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01467 return SCARD_F_COMM_ERROR;
01468 }
01469
01470 rv = scStatusStruct.rv;
01471 if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
01472 {
01473
01474
01475
01476 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01477 return rv;
01478 }
01479
01480
01481
01482
01483
01484 *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
01485 *pcbAtrLen = (readerStates[i])->cardAtrLength;
01486
01487 if (pdwState)
01488 *pdwState = (readerStates[i])->readerState;
01489
01490 if (pdwProtocol)
01491 *pdwProtocol = (readerStates[i])->cardProtocol;
01492
01493
01494 if (mszReaderNames)
01495 {
01496 if (*pcchReaderLen > dwReaderLen)
01497 rv = SCARD_E_INSUFFICIENT_BUFFER;
01498
01499 strncpy(mszReaderNames,
01500 psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
01501 dwReaderLen);
01502 }
01503
01504 if (pbAtr)
01505 {
01506 if (*pcbAtrLen > dwAtrLen)
01507 rv = SCARD_E_INSUFFICIENT_BUFFER;
01508
01509 memcpy(pbAtr, (readerStates[i])->cardAtr,
01510 min(*pcbAtrLen, dwAtrLen));
01511 }
01512
01513 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01514
01515 PROFILE_END
01516
01517 return rv;
01518 }
01519
01605 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01606 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01607 {
01608 PSCARD_READERSTATE_A currReader;
01609 PREADER_STATE rContext;
01610 DWORD dwTime = 0;
01611 DWORD dwState;
01612 DWORD dwBreakFlag = 0;
01613 int j;
01614 DWORD dwContextIndex;
01615 int currentReaderCount = 0;
01616
01617 PROFILE_START
01618
01619 if (rgReaderStates == NULL && cReaders > 0)
01620 return SCARD_E_INVALID_PARAMETER;
01621
01622 if (cReaders < 0)
01623 return SCARD_E_INVALID_VALUE;
01624
01625 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01626 return SCARD_E_NO_SERVICE;
01627
01628
01629
01630
01631
01632 dwContextIndex = SCardGetContextIndice(hContext);
01633 if (dwContextIndex == -1)
01634 return SCARD_E_INVALID_HANDLE;
01635
01636 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01637
01638
01639
01640
01641
01642
01643 if (cReaders == 0)
01644 {
01645 while (1)
01646 {
01647 int i;
01648
01649 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01650 {
01651 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01652 return SCARD_E_NO_SERVICE;
01653 }
01654
01655 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01656 {
01657 if ((readerStates[i])->readerID != 0)
01658 {
01659
01660
01661
01662 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01663
01664 PROFILE_END
01665
01666 return SCARD_S_SUCCESS;
01667 }
01668 }
01669
01670 if (dwTimeout == 0)
01671 {
01672
01673
01674
01675 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01676 return SCARD_E_READER_UNAVAILABLE;
01677 }
01678
01679 SYS_USleep(PCSCLITE_STATUS_WAIT);
01680
01681 if (dwTimeout != INFINITE)
01682 {
01683 dwTime += PCSCLITE_STATUS_WAIT;
01684
01685 if (dwTime >= (dwTimeout * 1000))
01686 {
01687 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01688
01689 PROFILE_END
01690
01691 return SCARD_E_TIMEOUT;
01692 }
01693 }
01694 }
01695 }
01696 else
01697 if (cReaders >= PCSCLITE_MAX_READERS_CONTEXTS)
01698 {
01699 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01700 return SCARD_E_INVALID_VALUE;
01701 }
01702
01703
01704
01705
01706
01707 for (j = 0; j < cReaders; j++)
01708 {
01709 currReader = &rgReaderStates[j];
01710
01711 if (currReader->szReader == NULL)
01712 {
01713 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01714 return SCARD_E_INVALID_VALUE;
01715 }
01716 }
01717
01718
01719
01720
01721
01722
01723
01724
01725 for (j = 0; j < cReaders; j++)
01726 {
01727 currReader = &rgReaderStates[j];
01728 currReader->dwEventState = 0;
01729 }
01730
01731
01732
01733
01734
01735 Log1(PCSC_LOG_DEBUG, "Event Loop Start");
01736
01737 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
01738
01739
01740 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
01741 if ((readerStates[j])->readerID != 0)
01742 currentReaderCount++;
01743
01744 j = 0;
01745
01746 do
01747 {
01748 int newReaderCount = 0;
01749 char ReaderCountChanged = FALSE;
01750
01751 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01752 {
01753 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01754
01755 PROFILE_END
01756
01757 return SCARD_E_NO_SERVICE;
01758 }
01759
01760 if (j == 0)
01761 {
01762 int i;
01763
01764 for (i=0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01765 if ((readerStates[i])->readerID != 0)
01766 newReaderCount++;
01767
01768 if (newReaderCount != currentReaderCount)
01769 {
01770 Log1(PCSC_LOG_INFO, "Reader list changed");
01771 ReaderCountChanged = TRUE;
01772 currentReaderCount = newReaderCount;
01773 }
01774 }
01775 currReader = &rgReaderStates[j];
01776
01777
01778
01779 if (currReader->dwCurrentState & SCARD_STATE_IGNORE)
01780 {
01781 currReader->dwEventState = SCARD_STATE_IGNORE;
01782 } else
01783 {
01784 LPTSTR lpcReaderName;
01785 int i;
01786
01787
01788
01789 lpcReaderName = (char *) currReader->szReader;
01790
01791 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01792 {
01793 if (strcmp(lpcReaderName,
01794 (readerStates[i])->readerName) == 0)
01795 {
01796 break;
01797 }
01798 }
01799
01800
01801
01802
01803 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01804 {
01805 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01806 {
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 } else
01820 {
01821
01822
01823
01824
01825 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01826 {
01827 currReader->dwEventState |= SCARD_STATE_CHANGED;
01828 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01829 dwBreakFlag = 1;
01830 }
01831
01832
01833
01834
01835
01836
01837 rContext = readerStates[i];
01838
01839
01840
01841
01842 dwState = rContext->readerState;
01843
01844
01845 if (dwState & SCARD_UNKNOWN)
01846 {
01847
01848
01849
01850 if (currReader->
01851 dwCurrentState & SCARD_STATE_UNAVAILABLE)
01852 {
01853 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
01854 } else
01855 {
01856
01857
01858
01859
01860 currReader->dwEventState = SCARD_STATE_CHANGED |
01861 SCARD_STATE_UNAVAILABLE;
01862 dwBreakFlag = 1;
01863 }
01864 } else
01865 {
01866
01867
01868
01869 if (currReader->
01870 dwCurrentState & SCARD_STATE_UNAVAILABLE)
01871 {
01872 currReader->dwEventState &=
01873 ~SCARD_STATE_UNAVAILABLE;
01874 currReader->dwEventState |= SCARD_STATE_CHANGED;
01875 dwBreakFlag = 1;
01876 }
01877 }
01878
01879
01880
01881 if (dwState & SCARD_PRESENT)
01882 {
01883
01884 if (0 == rContext->cardAtrLength)
01885
01886 SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
01887
01888 currReader->cbAtr = rContext->cardAtrLength;
01889 memcpy(currReader->rgbAtr, rContext->cardAtr,
01890 currReader->cbAtr);
01891 } else
01892 {
01893 currReader->cbAtr = 0;
01894 }
01895
01896
01897
01898
01899 if (dwState & SCARD_ABSENT)
01900 {
01901 currReader->dwEventState |= SCARD_STATE_EMPTY;
01902 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
01903 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
01904 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
01905 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01906 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
01907 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
01908 currReader->dwEventState &= ~SCARD_STATE_MUTE;
01909 currReader->dwEventState &= ~SCARD_STATE_INUSE;
01910
01911
01912
01913
01914 if (currReader->dwCurrentState & SCARD_STATE_PRESENT ||
01915 currReader->dwCurrentState & SCARD_STATE_ATRMATCH
01916 || currReader->
01917 dwCurrentState & SCARD_STATE_EXCLUSIVE
01918 || currReader->dwCurrentState & SCARD_STATE_INUSE)
01919 {
01920 currReader->dwEventState |= SCARD_STATE_CHANGED;
01921 dwBreakFlag = 1;
01922 }
01923
01924
01925
01926
01927 } else if (dwState & SCARD_PRESENT)
01928 {
01929 currReader->dwEventState |= SCARD_STATE_PRESENT;
01930 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
01931 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
01932 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
01933 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01934 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
01935 currReader->dwEventState &= ~SCARD_STATE_MUTE;
01936
01937 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
01938 {
01939 currReader->dwEventState |= SCARD_STATE_CHANGED;
01940 dwBreakFlag = 1;
01941 }
01942
01943 if (dwState & SCARD_SWALLOWED)
01944 {
01945 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
01946 {
01947 currReader->dwEventState |= SCARD_STATE_MUTE;
01948 } else
01949 {
01950 currReader->dwEventState |= SCARD_STATE_MUTE;
01951 if (currReader->dwCurrentState !=
01952 SCARD_STATE_UNAWARE)
01953 {
01954 currReader->dwEventState |=
01955 SCARD_STATE_CHANGED;
01956 }
01957 dwBreakFlag = 1;
01958 }
01959 } else
01960 {
01961
01962
01963
01964 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
01965 {
01966 currReader->dwEventState |=
01967 SCARD_STATE_CHANGED;
01968 dwBreakFlag = 1;
01969 }
01970 }
01971 }
01972
01973
01974
01975
01976 if (rContext->readerSharing == -1)
01977 {
01978 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
01979 currReader->dwEventState &= ~SCARD_STATE_INUSE;
01980 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
01981 {
01982 currReader->dwEventState |= SCARD_STATE_CHANGED;
01983 dwBreakFlag = 1;
01984 }
01985 } else if (rContext->readerSharing >= 1)
01986 {
01987
01988
01989
01990 if (dwState & SCARD_PRESENT)
01991 {
01992 currReader->dwEventState |= SCARD_STATE_INUSE;
01993 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
01994 if (currReader->
01995 dwCurrentState & SCARD_STATE_EXCLUSIVE)
01996 {
01997 currReader->dwEventState |=
01998 SCARD_STATE_CHANGED;
01999 dwBreakFlag = 1;
02000 }
02001 }
02002 } else if (rContext->readerSharing == 0)
02003 {
02004 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02005 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02006
02007 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02008 {
02009 currReader->dwEventState |= SCARD_STATE_CHANGED;
02010 dwBreakFlag = 1;
02011 } else if (currReader->
02012 dwCurrentState & SCARD_STATE_EXCLUSIVE)
02013 {
02014 currReader->dwEventState |= SCARD_STATE_CHANGED;
02015 dwBreakFlag = 1;
02016 }
02017 }
02018
02019 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02020 {
02021
02022
02023
02024
02025 currReader->dwEventState |= SCARD_STATE_CHANGED;
02026 dwBreakFlag = 1;
02027 }
02028
02029 }
02030
02031 }
02032
02033
02034
02035
02036 j = j + 1;
02037 if (j == cReaders)
02038 {
02039 if (!dwBreakFlag)
02040 {
02041
02042
02043
02044
02045 if (ReaderCountChanged)
02046 break;
02047 }
02048 j = 0;
02049 }
02050
02051
02052
02053
02054
02055 if (psContextMap[dwContextIndex].contextBlockStatus ==
02056 BLOCK_STATUS_RESUME)
02057 break;
02058
02059
02060
02061
02062 if ((dwBreakFlag == 1) && (j == 0))
02063 break;
02064
02065
02066
02067
02068 if ((dwTimeout == 0) && (j == 0))
02069 break;
02070
02071 if (dwTimeout != INFINITE && dwTimeout != 0)
02072 {
02073
02074
02075
02076
02077 if ((dwTime >= (dwTimeout * 1000)) && (j == 0))
02078 {
02079 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02080 return SCARD_E_TIMEOUT;
02081 }
02082 }
02083
02084
02085
02086
02087 if (j == 0)
02088 {
02089 SYS_USleep(PCSCLITE_STATUS_WAIT);
02090 dwTime += PCSCLITE_STATUS_WAIT;
02091 }
02092 }
02093 while (1);
02094
02095 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02096
02097 if (psContextMap[dwContextIndex].contextBlockStatus ==
02098 BLOCK_STATUS_RESUME)
02099 {
02100 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02101 return SCARD_E_CANCELLED;
02102 }
02103
02104 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02105
02106 PROFILE_END
02107
02108 return SCARD_S_SUCCESS;
02109 }
02110
02157 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02158 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02159 LPDWORD lpBytesReturned)
02160 {
02161 LONG rv;
02162 control_struct scControlStruct;
02163 sharedSegmentMsg msgStruct;
02164 int i;
02165 DWORD dwContextIndex, dwChannelIndex;
02166
02167 PROFILE_START
02168
02169
02170 if (NULL != lpBytesReturned)
02171 *lpBytesReturned = 0;
02172
02173 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02174 return SCARD_E_NO_SERVICE;
02175
02176
02177
02178
02179 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02180
02181 if (rv == -1)
02182 return SCARD_E_INVALID_HANDLE;
02183
02184 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02185
02186 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02187 {
02188 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02189
02190
02191 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02192 break;
02193 }
02194
02195 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02196 {
02197 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02198 return SCARD_E_READER_UNAVAILABLE;
02199 }
02200
02201 if (cbSendLength > MAX_BUFFER_SIZE)
02202 {
02203 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02204 return SCARD_E_INSUFFICIENT_BUFFER;
02205 }
02206
02207 scControlStruct.hCard = hCard;
02208 scControlStruct.dwControlCode = dwControlCode;
02209 scControlStruct.cbSendLength = cbSendLength;
02210 scControlStruct.cbRecvLength = cbRecvLength;
02211 memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02212
02213 rv = WrapSHMWrite(SCARD_CONTROL, psContextMap[dwContextIndex].dwClientID,
02214 sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
02215
02216 if (rv == -1)
02217 {
02218 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02219 return SCARD_E_NO_SERVICE;
02220 }
02221
02222
02223
02224
02225 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02226
02227 if (rv == -1)
02228 {
02229 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02230 return SCARD_F_COMM_ERROR;
02231 }
02232
02233 memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
02234
02235 if (NULL != lpBytesReturned)
02236 *lpBytesReturned = scControlStruct.dwBytesReturned;
02237
02238 if (scControlStruct.rv == SCARD_S_SUCCESS)
02239 {
02240
02241
02242
02243 memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
02244 scControlStruct.cbRecvLength);
02245 memset(scControlStruct.pbRecvBuffer, 0x00,
02246 sizeof(scControlStruct.pbRecvBuffer));
02247 }
02248
02249 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02250
02251 PROFILE_END
02252
02253 return scControlStruct.rv;
02254 }
02255
02336 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02337 LPDWORD pcbAttrLen)
02338 {
02339 PROFILE_START
02340
02341 if (NULL == pcbAttrLen)
02342 return SCARD_E_INVALID_PARAMETER;
02343
02344
02345 if (NULL == pbAttr)
02346
02347 *pcbAttrLen = MAX_BUFFER_SIZE;
02348
02349 PROFILE_END
02350
02351 return SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, pbAttr,
02352 pcbAttrLen);
02353 }
02354
02385 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02386 DWORD cbAttrLen)
02387 {
02388 PROFILE_START
02389
02390 if (NULL == pbAttr || 0 == cbAttrLen)
02391 return SCARD_E_INVALID_PARAMETER;
02392
02393 PROFILE_END
02394
02395 return SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02396 &cbAttrLen);
02397 }
02398
02399 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02400 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02401 {
02402 PROFILE_START
02403
02404 LONG rv;
02405 getset_struct scGetSetStruct;
02406 sharedSegmentMsg msgStruct;
02407 int i;
02408 DWORD dwContextIndex, dwChannelIndex;
02409
02410 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02411 return SCARD_E_NO_SERVICE;
02412
02413
02414
02415
02416 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02417
02418 if (rv == -1)
02419 return SCARD_E_INVALID_HANDLE;
02420
02421 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02422
02423 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02424 {
02425 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02426
02427
02428 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02429 break;
02430 }
02431
02432 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02433 {
02434 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02435 return SCARD_E_READER_UNAVAILABLE;
02436 }
02437
02438 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02439 {
02440 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02441 return SCARD_E_INSUFFICIENT_BUFFER;
02442 }
02443
02444 scGetSetStruct.hCard = hCard;
02445 scGetSetStruct.dwAttrId = dwAttrId;
02446 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02447 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02448 if (SCARD_SET_ATTRIB == command)
02449 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02450
02451 rv = WrapSHMWrite(command,
02452 psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
02453 PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
02454
02455 if (rv == -1)
02456 {
02457 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02458 return SCARD_E_NO_SERVICE;
02459 }
02460
02461
02462
02463
02464 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02465
02466 if (rv == -1)
02467 {
02468 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02469 return SCARD_F_COMM_ERROR;
02470 }
02471
02472 memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
02473
02474 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02475 {
02476
02477
02478
02479 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02480 {
02481 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02482 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02483 }
02484 else
02485 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02486
02487 if (pbAttr)
02488 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02489
02490 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02491 }
02492
02493 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02494
02495 PROFILE_END
02496
02497 return scGetSetStruct.rv;
02498 }
02499
02553 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02554 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02555 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02556 LPDWORD pcbRecvLength)
02557 {
02558 LONG rv;
02559 transmit_struct scTransmitStruct;
02560 sharedSegmentMsg msgStruct;
02561 int i;
02562 DWORD dwContextIndex, dwChannelIndex;
02563
02564 PROFILE_START
02565
02566 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02567 pcbRecvLength == NULL || pioSendPci == NULL)
02568 return SCARD_E_INVALID_PARAMETER;
02569
02570 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02571 return SCARD_E_NO_SERVICE;
02572
02573
02574
02575
02576 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02577
02578 if (rv == -1)
02579 {
02580 *pcbRecvLength = 0;
02581 return SCARD_E_INVALID_HANDLE;
02582 }
02583
02584 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02585
02586 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02587 {
02588 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02589
02590
02591 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02592 break;
02593 }
02594
02595 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02596 {
02597 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02598 return SCARD_E_READER_UNAVAILABLE;
02599 }
02600
02601 if (cbSendLength > MAX_BUFFER_SIZE)
02602 {
02603 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02604 return SCARD_E_INSUFFICIENT_BUFFER;
02605 }
02606
02607 scTransmitStruct.hCard = hCard;
02608 scTransmitStruct.cbSendLength = cbSendLength;
02609 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
02610 memcpy(&scTransmitStruct.pioSendPci, pioSendPci,
02611 sizeof(SCARD_IO_REQUEST));
02612 memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02613
02614 if (pioRecvPci)
02615 {
02616 memcpy(&scTransmitStruct.pioRecvPci, pioRecvPci,
02617 sizeof(SCARD_IO_REQUEST));
02618 }
02619 else
02620 scTransmitStruct.pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
02621
02622 rv = WrapSHMWrite(SCARD_TRANSMIT, psContextMap[dwContextIndex].dwClientID,
02623 sizeof(scTransmitStruct),
02624 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
02625
02626 if (rv == -1)
02627 {
02628 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02629 return SCARD_E_NO_SERVICE;
02630 }
02631
02632
02633
02634
02635 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02636
02637 memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
02638
02639 if (rv == -1)
02640 {
02641 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02642 return SCARD_F_COMM_ERROR;
02643 }
02644
02645
02646
02647
02648 memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
02649
02650 if (scTransmitStruct.rv == SCARD_S_SUCCESS)
02651 {
02652
02653
02654
02655 memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
02656 scTransmitStruct.pcbRecvLength);
02657 memset(scTransmitStruct.pbRecvBuffer, 0x00,
02658 scTransmitStruct.pcbRecvLength);
02659
02660 if (pioRecvPci)
02661 memcpy(pioRecvPci, &scTransmitStruct.pioRecvPci,
02662 sizeof(SCARD_IO_REQUEST));
02663 }
02664
02665 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
02666 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02667
02668 PROFILE_END
02669
02670 return scTransmitStruct.rv;
02671 }
02672
02702 LONG SCardListReaders(SCARDCONTEXT hContext, LPCTSTR mszGroups,
02703 LPTSTR mszReaders, LPDWORD pcchReaders)
02704 {
02705 DWORD dwReadersLen;
02706 int i, lastChrPtr;
02707 DWORD dwContextIndex;
02708
02709 PROFILE_START
02710
02711
02712
02713
02714 if (pcchReaders == NULL)
02715 return SCARD_E_INVALID_PARAMETER;
02716
02717 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02718 return SCARD_E_NO_SERVICE;
02719
02720
02721
02722
02723 dwContextIndex = SCardGetContextIndice(hContext);
02724 if (dwContextIndex == -1)
02725 return SCARD_E_INVALID_HANDLE;
02726
02727 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02728
02729 dwReadersLen = 0;
02730 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02731 if ((readerStates[i])->readerID != 0)
02732 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
02733
02734
02735 dwReadersLen += 1;
02736
02737 if ((mszReaders == NULL)
02738 || (*pcchReaders == 0))
02739 {
02740 *pcchReaders = dwReadersLen;
02741 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02742 return SCARD_S_SUCCESS;
02743 }
02744
02745 if (*pcchReaders < dwReadersLen)
02746 {
02747 *pcchReaders = dwReadersLen;
02748 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02749 return SCARD_E_INSUFFICIENT_BUFFER;
02750 }
02751
02752 lastChrPtr = 0;
02753 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02754 {
02755 if ((readerStates[i])->readerID != 0)
02756 {
02757
02758
02759
02760 strcpy(&mszReaders[lastChrPtr], (readerStates[i])->readerName);
02761 lastChrPtr += strlen((readerStates[i])->readerName)+1;
02762 }
02763 }
02764 mszReaders[lastChrPtr] = '\0';
02765
02766 *pcchReaders = dwReadersLen;
02767
02768 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02769
02770 PROFILE_END
02771
02772 return SCARD_S_SUCCESS;
02773 }
02774
02806 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPTSTR mszGroups,
02807 LPDWORD pcchGroups)
02808 {
02809 LONG rv = SCARD_S_SUCCESS;
02810 DWORD dwContextIndex;
02811
02812 PROFILE_START
02813
02814 const char ReaderGroup[] = "SCard$DefaultReaders";
02815 const int dwGroups = strlen(ReaderGroup) + 2;
02816
02817 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02818 return SCARD_E_NO_SERVICE;
02819
02820
02821
02822
02823 dwContextIndex = SCardGetContextIndice(hContext);
02824 if (dwContextIndex == -1)
02825 return SCARD_E_INVALID_HANDLE;
02826
02827 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02828
02829 if (mszGroups)
02830 {
02831
02832 if (*pcchGroups < dwGroups)
02833 rv = SCARD_E_INSUFFICIENT_BUFFER;
02834 else
02835 {
02836 memset(mszGroups, 0, dwGroups);
02837 memcpy(mszGroups, ReaderGroup, strlen(ReaderGroup));
02838 }
02839 }
02840
02841 *pcchGroups = dwGroups;
02842
02843 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02844
02845 PROFILE_END
02846
02847 return rv;
02848 }
02849
02877 LONG SCardCancel(SCARDCONTEXT hContext)
02878 {
02879 DWORD dwContextIndex;
02880
02881 PROFILE_START
02882
02883 dwContextIndex = SCardGetContextIndice(hContext);
02884
02885 if (dwContextIndex == -1)
02886 return SCARD_E_INVALID_HANDLE;
02887
02888
02889
02890
02891
02892 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
02893
02894 PROFILE_END
02895
02896 return SCARD_S_SUCCESS;
02897 }
02898
02915 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
02916 {
02917 int i;
02918
02919 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
02920 {
02921 if (psContextMap[i].hContext == 0)
02922 {
02923 psContextMap[i].hContext = hContext;
02924 psContextMap[i].dwClientID = dwClientID;
02925 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
02926 psContextMap[i].mMutex = (PCSCLITE_MUTEX_T) malloc(sizeof(PCSCLITE_MUTEX));
02927 SYS_MutexInit(psContextMap[i].mMutex);
02928 return SCARD_S_SUCCESS;
02929 }
02930 }
02931
02932 return SCARD_E_NO_MEMORY;
02933 }
02934
02947 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
02948 {
02949 LONG rv;
02950
02951 SCardLockThread();
02952 rv = SCardGetContextIndiceTH(hContext);
02953 SCardUnlockThread();
02954
02955 return rv;
02956 }
02957
02970 static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
02971 {
02972 int i;
02973
02974
02975
02976
02977 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
02978 {
02979 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
02980 return i;
02981 }
02982
02983 return -1;
02984 }
02985
02995 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
02996 {
02997 LONG retIndice;
02998
02999 retIndice = SCardGetContextIndiceTH(hContext);
03000
03001 if (retIndice == -1)
03002 return SCARD_E_INVALID_HANDLE;
03003 else
03004 {
03005 int i;
03006
03007 psContextMap[retIndice].hContext = 0;
03008 SHMClientCloseSession(psContextMap[retIndice].dwClientID);
03009 psContextMap[retIndice].dwClientID = 0;
03010 free(psContextMap[retIndice].mMutex);
03011 psContextMap[retIndice].mMutex = NULL;
03012 psContextMap[retIndice].contextBlockStatus = BLOCK_STATUS_RESUME;
03013
03014 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03015 {
03016
03017
03018
03019 psContextMap[retIndice].psChannelMap[i].hCard = 0;
03020 free(psContextMap[retIndice].psChannelMap[i].readerName);
03021 psContextMap[retIndice].psChannelMap[i].readerName = NULL;
03022 }
03023
03024 return SCARD_S_SUCCESS;
03025 }
03026 }
03027
03028
03029
03030
03031
03032 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
03033 LPTSTR readerName)
03034 {
03035 int i;
03036
03037 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03038 {
03039 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
03040 {
03041 psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
03042 psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
03043 return SCARD_S_SUCCESS;
03044 }
03045 }
03046
03047 return SCARD_E_NO_MEMORY;
03048 }
03049
03050 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03051 {
03052 DWORD dwContextIndice, dwChannelIndice;
03053 LONG rv;
03054
03055 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
03056
03057 if (rv == -1)
03058 return SCARD_E_INVALID_HANDLE;
03059 else
03060 {
03061 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
03062 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
03063 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
03064 return SCARD_S_SUCCESS;
03065 }
03066 }
03067
03068 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03069 {
03070 LONG rv;
03071
03072 SCardLockThread();
03073 rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
03074 SCardUnlockThread();
03075
03076 return rv;
03077 }
03078
03079 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03080 {
03081 int i;
03082
03083 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03084 {
03085 if (psContextMap[i].hContext != 0)
03086 {
03087 int j;
03088
03089 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
03090 {
03091 if (psContextMap[i].psChannelMap[j].hCard == hCard)
03092 {
03093 *pdwContextIndice = i;
03094 *pdwChannelIndice = j;
03095 return SCARD_S_SUCCESS;
03096 }
03097 }
03098
03099 }
03100 }
03101
03102 return -1;
03103 }
03104
03111 inline static LONG SCardLockThread(void)
03112 {
03113 return SYS_MutexLock(&clientMutex);
03114 }
03115
03121 inline static LONG SCardUnlockThread(void)
03122 {
03123 return SYS_MutexUnLock(&clientMutex);
03124 }
03125
03133 static LONG SCardCheckDaemonAvailability(void)
03134 {
03135 LONG rv;
03136 struct stat statBuffer;
03137
03138 rv = SYS_Stat(PCSCLITE_IPC_DIR, &statBuffer);
03139
03140 if (rv != 0)
03141 {
03142 Log1(PCSC_LOG_ERROR, "PCSC Not Running");
03143 return SCARD_E_NO_SERVICE;
03144 }
03145
03146 return SCARD_S_SUCCESS;
03147 }
03148
03154 #ifdef __SUNPRO_C
03155 #pragma fini (SCardUnload)
03156 #endif
03157
03158 void DESTRUCTOR SCardUnload(void)
03159 {
03160 if (!isExecuted)
03161 return;
03162
03163 SYS_CloseFile(mapAddr);
03164 isExecuted = 0;
03165 }
03166