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 #include <stddef.h>
00029
00030 #include "misc.h"
00031 #include "pcscd.h"
00032 #include "winscard.h"
00033 #include "debug.h"
00034 #include "thread_generic.h"
00035 #include "strlcpycat.h"
00036
00037 #include "readerfactory.h"
00038 #include "eventhandler.h"
00039 #include "sys_generic.h"
00040 #include "winscard_msg.h"
00041 #include "utils.h"
00042
00044 #define SCARD_PROTOCOL_ANY_OLD 0x1000
00045
00046 #ifndef TRUE
00047 #define TRUE 1
00048 #define FALSE 0
00049 #endif
00050
00051 #undef DO_PROFILE
00052 #ifdef DO_PROFILE
00053
00054 #define PROFILE_FILE "/tmp/pcsc_profile"
00055 #include <stdio.h>
00056 #include <sys/time.h>
00057
00058 struct timeval profile_time_start;
00059 FILE *fd;
00060 char profile_tty;
00061 char fct_name[100];
00062
00063 #define PROFILE_START profile_start(__FUNCTION__);
00064 #define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
00065
00066 static void profile_start(const char *f)
00067 {
00068 static char initialized = FALSE;
00069
00070 if (!initialized)
00071 {
00072 char filename[80];
00073
00074 initialized = TRUE;
00075 sprintf(filename, "%s-%d", PROFILE_FILE, getuid());
00076 fd = fopen(filename, "a+");
00077 if (NULL == fd)
00078 {
00079 fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n",
00080 PROFILE_FILE, strerror(errno));
00081 exit(-1);
00082 }
00083 fprintf(fd, "\nStart a new profile\n");
00084
00085 if (isatty(fileno(stderr)))
00086 profile_tty = TRUE;
00087 else
00088 profile_tty = FALSE;
00089 }
00090
00091
00092 if (profile_tty && fct_name[0])
00093 printf("\33[01;34m WARNING: %s starts before %s finishes\33[0m\n",
00094 f, fct_name);
00095
00096 strlcpy(fct_name, f, sizeof(fct_name));
00097
00098 gettimeofday(&profile_time_start, NULL);
00099 }
00100
00101
00102 static long int time_sub(struct timeval *a, struct timeval *b)
00103 {
00104 struct timeval r;
00105 r.tv_sec = a -> tv_sec - b -> tv_sec;
00106 r.tv_usec = a -> tv_usec - b -> tv_usec;
00107 if (r.tv_usec < 0)
00108 {
00109 r.tv_sec--;
00110 r.tv_usec += 1000000;
00111 }
00112
00113 return r.tv_sec * 1000000 + r.tv_usec;
00114 }
00115
00116
00117 static void profile_end(const char *f, LONG rv)
00118 {
00119 struct timeval profile_time_end;
00120 long d;
00121
00122 gettimeofday(&profile_time_end, NULL);
00123 d = time_sub(&profile_time_end, &profile_time_start);
00124
00125 if (profile_tty)
00126 {
00127 if (fct_name[0])
00128 {
00129 if (strncmp(fct_name, f, sizeof(fct_name)))
00130 printf("\33[01;34m WARNING: %s ends before %s\33[0m\n",
00131 f, fct_name);
00132 }
00133 else
00134 printf("\33[01;34m WARNING: %s ends but we lost its start\33[0m\n",
00135 f);
00136
00137
00138 fct_name[0] = '\0';
00139
00140 if (rv != SCARD_S_SUCCESS)
00141 fprintf(stderr,
00142 "\33[01;31mRESULT %s \33[35m%ld \33[34m0x%08lX %s\33[0m\n",
00143 f, d, rv, pcsc_stringify_error(rv));
00144 else
00145 fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m\n", f, d);
00146 }
00147 fprintf(fd, "%s %ld\n", f, d);
00148 fflush(fd);
00149 }
00150
00151 #else
00152 #define PROFILE_START
00153 #define PROFILE_END(rv)
00154 #endif
00155
00160 struct _psChannelMap
00161 {
00162 SCARDHANDLE hCard;
00163 LPSTR readerName;
00164 };
00165
00166 typedef struct _psChannelMap CHANNEL_MAP, *PCHANNEL_MAP;
00167
00173 static struct _psContextMap
00174 {
00175 DWORD dwClientID;
00176 SCARDCONTEXT hContext;
00177 DWORD contextBlockStatus;
00178 PCSCLITE_MUTEX_T mMutex;
00179 CHANNEL_MAP psChannelMap[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
00180 } psContextMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
00181
00185 static short isExecuted = 0;
00186
00187
00191 static time_t daemon_ctime = 0;
00192 static pid_t daemon_pid = 0;
00193
00199 static int mapAddr = 0;
00200
00205 static PCSCLITE_MUTEX clientMutex = PTHREAD_MUTEX_INITIALIZER;
00206
00213 static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
00214
00215 PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
00216 PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
00217 PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
00218
00219
00220 static LONG SCardAddContext(SCARDCONTEXT, DWORD);
00221 static LONG SCardGetContextIndice(SCARDCONTEXT);
00222 static LONG SCardGetContextIndiceTH(SCARDCONTEXT);
00223 static LONG SCardRemoveContext(SCARDCONTEXT);
00224 static LONG SCardCleanContext(LONG indice);
00225
00226 static LONG SCardAddHandle(SCARDHANDLE, DWORD, LPCSTR);
00227 static LONG SCardGetIndicesFromHandle(SCARDHANDLE, PDWORD, PDWORD);
00228 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE, PDWORD, PDWORD);
00229 static LONG SCardRemoveHandle(SCARDHANDLE);
00230
00231 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
00232 LPBYTE pbAttr, LPDWORD pcbAttrLen);
00233
00234 void DESTRUCTOR SCardUnload(void);
00235
00236
00237
00238
00245 inline static LONG SCardLockThread(void)
00246 {
00247 return SYS_MutexLock(&clientMutex);
00248 }
00249
00255 inline static LONG SCardUnlockThread(void)
00256 {
00257 return SYS_MutexUnLock(&clientMutex);
00258 }
00259
00260 static LONG SCardEstablishContextTH(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
00261
00294 LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
00295 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00296 {
00297 LONG rv;
00298
00299 PROFILE_START
00300
00301
00302 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00303 return SCARD_E_NO_SERVICE;
00304
00305 SCardLockThread();
00306 rv = SCardEstablishContextTH(dwScope, pvReserved1,
00307 pvReserved2, phContext);
00308 SCardUnlockThread();
00309
00310 PROFILE_END(rv)
00311
00312 return rv;
00313 }
00314
00340 static LONG SCardEstablishContextTH(DWORD dwScope, LPCVOID pvReserved1,
00341 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00342 {
00343 LONG rv;
00344 int i;
00345 establish_struct scEstablishStruct;
00346 sharedSegmentMsg msgStruct;
00347 DWORD dwClientID = 0;
00348
00349 if (phContext == NULL)
00350 return SCARD_E_INVALID_PARAMETER;
00351 else
00352 *phContext = 0;
00353
00354
00355
00356
00357
00358
00359
00360
00361 if (isExecuted == 0)
00362 {
00363 int pageSize;
00364
00365
00366
00367
00368 SYS_Initialize();
00369
00370
00371
00372
00373 mapAddr = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDONLY, 0);
00374 if (mapAddr < 0)
00375 {
00376 Log2(PCSC_LOG_CRITICAL, "Cannot open public shared file: %s",
00377 PCSCLITE_PUBSHM_FILE);
00378 return SCARD_E_NO_SERVICE;
00379 }
00380
00381
00382
00383
00384 fcntl(mapAddr, F_SETFD, FD_CLOEXEC);
00385
00386 pageSize = SYS_GetPageSize();
00387
00388
00389
00390
00391 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00392 {
00393 readerStates[i] =
00394 (PREADER_STATE)SYS_PublicMemoryMap(sizeof(READER_STATE),
00395 mapAddr, (i * pageSize));
00396 if (readerStates[i] == NULL)
00397 {
00398 Log1(PCSC_LOG_CRITICAL, "Cannot public memory map");
00399 SYS_CloseFile(mapAddr);
00400 return SCARD_F_INTERNAL_ERROR;
00401 }
00402 }
00403
00404
00405
00406
00407 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00408 {
00409 int j;
00410
00411
00412
00413
00414 psContextMap[i].dwClientID = 0;
00415 psContextMap[i].hContext = 0;
00416 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
00417 psContextMap[i].mMutex = NULL;
00418
00419 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
00420 {
00421
00422
00423
00424 psContextMap[i].psChannelMap[j].hCard = 0;
00425 psContextMap[i].psChannelMap[j].readerName = NULL;
00426 }
00427 }
00428
00429 }
00430
00431
00432
00433
00434
00435 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
00436 {
00437 if (psContextMap[i].dwClientID == 0)
00438 break;
00439 }
00440
00441 if (i == PCSCLITE_MAX_APPLICATION_CONTEXTS)
00442 {
00443 return SCARD_E_NO_MEMORY;
00444 }
00445
00446
00447 if (SHMClientSetupSession(&dwClientID) != 0)
00448 {
00449 SYS_CloseFile(mapAddr);
00450 return SCARD_E_NO_SERVICE;
00451 }
00452
00453 {
00454 version_struct *veStr;
00455
00456 memset(&msgStruct, 0, sizeof(msgStruct));
00457 msgStruct.mtype = CMD_VERSION;
00458 msgStruct.user_id = SYS_GetUID();
00459 msgStruct.group_id = SYS_GetGID();
00460 msgStruct.command = 0;
00461 msgStruct.date = time(NULL);
00462
00463 veStr = (version_struct *) msgStruct.data;
00464 veStr->major = PROTOCOL_VERSION_MAJOR;
00465 veStr->minor = PROTOCOL_VERSION_MINOR;
00466
00467 if (-1 == SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
00468 PCSCLITE_MCLIENT_ATTEMPTS))
00469 return SCARD_E_NO_SERVICE;
00470
00471
00472
00473
00474 if (-1 == SHMMessageReceive(&msgStruct, sizeof(msgStruct), dwClientID,
00475 PCSCLITE_CLIENT_ATTEMPTS))
00476 {
00477 Log1(PCSC_LOG_CRITICAL, "Your pcscd is too old and does not support CMD_VERSION");
00478 return SCARD_F_COMM_ERROR;
00479 }
00480
00481 Log3(PCSC_LOG_INFO, "Server is protocol version %d:%d",
00482 veStr->major, veStr->minor);
00483
00484 if (veStr->rv != SCARD_S_SUCCESS)
00485 return veStr->rv;
00486
00487 isExecuted = 1;
00488 }
00489
00490
00491 if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
00492 dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
00493 {
00494 return SCARD_E_INVALID_VALUE;
00495 }
00496
00497
00498
00499
00500 scEstablishStruct.dwScope = dwScope;
00501 scEstablishStruct.phContext = 0;
00502 scEstablishStruct.rv = SCARD_S_SUCCESS;
00503
00504 rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
00505 sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
00506 (void *) &scEstablishStruct);
00507
00508 if (rv == -1)
00509 return SCARD_E_NO_SERVICE;
00510
00511
00512
00513
00514 rv = SHMClientRead(&msgStruct, dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00515
00516 if (rv == -1)
00517 return SCARD_F_COMM_ERROR;
00518
00519 memcpy(&scEstablishStruct, &msgStruct.data, sizeof(scEstablishStruct));
00520
00521 if (scEstablishStruct.rv != SCARD_S_SUCCESS)
00522 return scEstablishStruct.rv;
00523
00524 *phContext = scEstablishStruct.phContext;
00525
00526
00527
00528
00529 rv = SCardAddContext(*phContext, dwClientID);
00530
00531 return rv;
00532 }
00533
00552 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00553 {
00554 LONG rv;
00555 release_struct scReleaseStruct;
00556 sharedSegmentMsg msgStruct;
00557 LONG dwContextIndex;
00558
00559 PROFILE_START
00560
00561 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00562 return SCARD_E_NO_SERVICE;
00563
00564
00565
00566
00567 dwContextIndex = SCardGetContextIndice(hContext);
00568 if (dwContextIndex == -1)
00569 return SCARD_E_INVALID_HANDLE;
00570
00571 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00572
00573 scReleaseStruct.hContext = hContext;
00574 scReleaseStruct.rv = SCARD_S_SUCCESS;
00575
00576 rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT, psContextMap[dwContextIndex].dwClientID,
00577 sizeof(scReleaseStruct),
00578 PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);
00579
00580 if (rv == -1)
00581 {
00582 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00583 return SCARD_E_NO_SERVICE;
00584 }
00585
00586
00587
00588
00589 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00590 memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));
00591
00592 if (rv == -1)
00593 {
00594 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00595 return SCARD_F_COMM_ERROR;
00596 }
00597
00598 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00599
00600
00601
00602
00603 SCardLockThread();
00604 SCardRemoveContext(hContext);
00605 SCardUnlockThread();
00606
00607 PROFILE_END(scReleaseStruct.rv)
00608
00609 return scReleaseStruct.rv;
00610 }
00611
00624 LONG SCardSetTimeout(SCARDCONTEXT hContext, DWORD dwTimeout)
00625 {
00626
00627
00628
00629
00630 return SCARD_S_SUCCESS;
00631 }
00632
00683 LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,
00684 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00685 LPDWORD pdwActiveProtocol)
00686 {
00687 LONG rv;
00688 connect_struct scConnectStruct;
00689 sharedSegmentMsg msgStruct;
00690 LONG dwContextIndex;
00691
00692 PROFILE_START
00693
00694
00695
00696
00697 if (phCard == NULL || pdwActiveProtocol == NULL)
00698 return SCARD_E_INVALID_PARAMETER;
00699 else
00700 *phCard = 0;
00701
00702 if (szReader == NULL)
00703 return SCARD_E_UNKNOWN_READER;
00704
00705
00706
00707
00708 if (strlen(szReader) > MAX_READERNAME)
00709 return SCARD_E_INVALID_VALUE;
00710
00711 if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00712 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00713 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00714 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00715 {
00716 return SCARD_E_INVALID_VALUE;
00717 }
00718
00719 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00720 return SCARD_E_NO_SERVICE;
00721
00722
00723
00724
00725 dwContextIndex = SCardGetContextIndice(hContext);
00726 if (dwContextIndex == -1)
00727 return SCARD_E_INVALID_HANDLE;
00728
00729 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00730
00731 strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);
00732
00733 scConnectStruct.hContext = hContext;
00734 scConnectStruct.dwShareMode = dwShareMode;
00735 scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00736 scConnectStruct.phCard = 0;
00737 scConnectStruct.pdwActiveProtocol = 0;
00738 scConnectStruct.rv = SCARD_S_SUCCESS;
00739
00740 rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
00741 sizeof(scConnectStruct),
00742 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);
00743
00744 if (rv == -1)
00745 {
00746 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00747 return SCARD_E_NO_SERVICE;
00748 }
00749
00750
00751
00752
00753 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00754
00755 memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));
00756
00757 if (rv == -1)
00758 {
00759 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00760 return SCARD_F_COMM_ERROR;
00761 }
00762
00763 *phCard = scConnectStruct.phCard;
00764 *pdwActiveProtocol = scConnectStruct.pdwActiveProtocol;
00765
00766 if (scConnectStruct.rv == SCARD_S_SUCCESS)
00767 {
00768
00769
00770
00771 rv = SCardAddHandle(*phCard, dwContextIndex, szReader);
00772 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00773
00774 PROFILE_END(rv)
00775
00776 return rv;
00777 }
00778
00779 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00780
00781 PROFILE_END(scConnectStruct.rv)
00782
00783 return scConnectStruct.rv;
00784 }
00785
00853 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00854 DWORD dwPreferredProtocols, DWORD dwInitialization,
00855 LPDWORD pdwActiveProtocol)
00856 {
00857 LONG rv;
00858 reconnect_struct scReconnectStruct;
00859 sharedSegmentMsg msgStruct;
00860 int i;
00861 DWORD dwContextIndex, dwChannelIndex;
00862
00863 PROFILE_START
00864
00865 if (dwInitialization != SCARD_LEAVE_CARD &&
00866 dwInitialization != SCARD_RESET_CARD &&
00867 dwInitialization != SCARD_UNPOWER_CARD &&
00868 dwInitialization != SCARD_EJECT_CARD)
00869 {
00870 return SCARD_E_INVALID_VALUE;
00871 }
00872
00873 if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00874 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00875 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00876 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00877 {
00878 return SCARD_E_INVALID_VALUE;
00879 }
00880
00881 if (pdwActiveProtocol == NULL)
00882 return SCARD_E_INVALID_PARAMETER;
00883
00884 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
00885 return SCARD_E_NO_SERVICE;
00886
00887
00888
00889
00890 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
00891
00892 if (rv == -1)
00893 return SCARD_E_INVALID_HANDLE;
00894
00895 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
00896
00897
00898 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00899 {
00900 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
00901
00902
00903 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
00904 break;
00905 }
00906
00907 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00908 {
00909 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00910 return SCARD_E_READER_UNAVAILABLE;
00911 }
00912
00913 do
00914 {
00915 scReconnectStruct.hCard = hCard;
00916 scReconnectStruct.dwShareMode = dwShareMode;
00917 scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
00918 scReconnectStruct.dwInitialization = dwInitialization;
00919 scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
00920 scReconnectStruct.rv = SCARD_S_SUCCESS;
00921
00922 rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
00923 sizeof(scReconnectStruct),
00924 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
00925
00926 if (rv == -1)
00927 {
00928 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00929 return SCARD_E_NO_SERVICE;
00930 }
00931
00932
00933
00934
00935 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
00936
00937 memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
00938
00939 if (rv == -1)
00940 {
00941 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00942 return SCARD_F_COMM_ERROR;
00943 }
00944 } while (SCARD_E_SHARING_VIOLATION == scReconnectStruct.rv);
00945
00946 *pdwActiveProtocol = scReconnectStruct.pdwActiveProtocol;
00947
00948 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
00949
00950 PROFILE_END(scReconnectStruct.rv)
00951
00952 return scReconnectStruct.rv;
00953 }
00954
00985 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
00986 {
00987 LONG rv;
00988 disconnect_struct scDisconnectStruct;
00989 sharedSegmentMsg msgStruct;
00990 DWORD dwContextIndex, dwChannelIndex;
00991
00992 PROFILE_START
00993
00994 if (dwDisposition != SCARD_LEAVE_CARD &&
00995 dwDisposition != SCARD_RESET_CARD &&
00996 dwDisposition != SCARD_UNPOWER_CARD &&
00997 dwDisposition != SCARD_EJECT_CARD)
00998 {
00999 return SCARD_E_INVALID_VALUE;
01000 }
01001
01002 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01003 return SCARD_E_NO_SERVICE;
01004
01005
01006
01007
01008 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01009
01010 if (rv == -1)
01011 return SCARD_E_INVALID_HANDLE;
01012
01013 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01014
01015 scDisconnectStruct.hCard = hCard;
01016 scDisconnectStruct.dwDisposition = dwDisposition;
01017 scDisconnectStruct.rv = SCARD_S_SUCCESS;
01018
01019 rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
01020 sizeof(scDisconnectStruct),
01021 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
01022
01023 if (rv == -1)
01024 {
01025 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01026 return SCARD_E_NO_SERVICE;
01027 }
01028
01029
01030
01031
01032 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01033
01034 memcpy(&scDisconnectStruct, &msgStruct.data,
01035 sizeof(scDisconnectStruct));
01036
01037 if (rv == -1)
01038 {
01039 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01040 return SCARD_F_COMM_ERROR;
01041 }
01042
01043 SCardRemoveHandle(hCard);
01044
01045 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01046
01047 PROFILE_END(scDisconnectStruct.rv)
01048
01049 return scDisconnectStruct.rv;
01050 }
01051
01084 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01085 {
01086
01087 LONG rv;
01088 begin_struct scBeginStruct;
01089 int i;
01090 sharedSegmentMsg msgStruct;
01091 DWORD dwContextIndex, dwChannelIndex;
01092
01093 PROFILE_START
01094
01095 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01096 return SCARD_E_NO_SERVICE;
01097
01098
01099
01100
01101 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01102
01103 if (rv == -1)
01104 return SCARD_E_INVALID_HANDLE;
01105
01106 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01107
01108 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01109 {
01110 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01111
01112
01113 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01114 break;
01115 }
01116
01117 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01118 {
01119 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01120 return SCARD_E_READER_UNAVAILABLE;
01121 }
01122
01123 scBeginStruct.hCard = hCard;
01124 scBeginStruct.rv = SCARD_S_SUCCESS;
01125
01126
01127
01128
01129
01130
01131 do
01132 {
01133 rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01134 sizeof(scBeginStruct),
01135 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);
01136
01137 if (rv == -1)
01138 {
01139
01140 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01141 return SCARD_E_NO_SERVICE;
01142 }
01143
01144
01145
01146
01147 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01148
01149
01150 memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));
01151
01152 if (rv == -1)
01153 {
01154
01155 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01156 return SCARD_F_COMM_ERROR;
01157 }
01158
01159 }
01160 while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
01161
01162 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01163
01164 PROFILE_END(scBeginStruct.rv);
01165
01166 return scBeginStruct.rv;
01167 }
01168
01207 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01208 {
01209 LONG rv;
01210 end_struct scEndStruct;
01211 sharedSegmentMsg msgStruct;
01212 int randnum, i;
01213 DWORD dwContextIndex, dwChannelIndex;
01214
01215 PROFILE_START
01216
01217
01218
01219
01220 randnum = 0;
01221
01222 if (dwDisposition != SCARD_LEAVE_CARD &&
01223 dwDisposition != SCARD_RESET_CARD &&
01224 dwDisposition != SCARD_UNPOWER_CARD &&
01225 dwDisposition != SCARD_EJECT_CARD)
01226 {
01227 return SCARD_E_INVALID_VALUE;
01228 }
01229
01230 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01231 return SCARD_E_NO_SERVICE;
01232
01233
01234
01235
01236 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01237
01238 if (rv == -1)
01239 return SCARD_E_INVALID_HANDLE;
01240
01241 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01242
01243 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01244 {
01245 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01246
01247
01248 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01249 break;
01250 }
01251
01252 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01253 {
01254 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01255 return SCARD_E_READER_UNAVAILABLE;
01256 }
01257
01258 scEndStruct.hCard = hCard;
01259 scEndStruct.dwDisposition = dwDisposition;
01260 scEndStruct.rv = SCARD_S_SUCCESS;
01261
01262 rv = WrapSHMWrite(SCARD_END_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01263 sizeof(scEndStruct),
01264 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
01265
01266 if (rv == -1)
01267 {
01268 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01269 return SCARD_E_NO_SERVICE;
01270 }
01271
01272
01273
01274
01275 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01276
01277 memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
01278
01279 if (rv == -1)
01280 {
01281 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01282 return SCARD_F_COMM_ERROR;
01283 }
01284
01285
01286
01287
01288 randnum = SYS_RandomInt(1000, 10000);
01289 SYS_USleep(randnum);
01290
01291 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01292
01293 PROFILE_END(scEndStruct.rv)
01294
01295 return scEndStruct.rv;
01296 }
01297
01303 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01304 {
01305 LONG rv;
01306 cancel_struct scCancelStruct;
01307 sharedSegmentMsg msgStruct;
01308 int i;
01309 DWORD dwContextIndex, dwChannelIndex;
01310
01311 PROFILE_START
01312
01313 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01314 return SCARD_E_NO_SERVICE;
01315
01316
01317
01318
01319 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01320
01321 if (rv == -1)
01322 return SCARD_E_INVALID_HANDLE;
01323
01324 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01325
01326 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01327 {
01328 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01329
01330
01331 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01332 break;
01333 }
01334
01335 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01336 {
01337 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01338 return SCARD_E_READER_UNAVAILABLE;
01339 }
01340
01341 scCancelStruct.hCard = hCard;
01342
01343 rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
01344 sizeof(scCancelStruct),
01345 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
01346
01347 if (rv == -1)
01348 {
01349 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01350 return SCARD_E_NO_SERVICE;
01351 }
01352
01353
01354
01355
01356 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01357
01358 memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
01359
01360 if (rv == -1)
01361 {
01362 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01363 return SCARD_F_COMM_ERROR;
01364 }
01365
01366 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01367
01368 PROFILE_END(scCancelStruct.rv)
01369
01370 return scCancelStruct.rv;
01371 }
01372
01430 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames,
01431 LPDWORD pcchReaderLen, LPDWORD pdwState,
01432 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
01433 {
01434 DWORD dwReaderLen, dwAtrLen;
01435 LONG rv;
01436 int i;
01437 status_struct scStatusStruct;
01438 sharedSegmentMsg msgStruct;
01439 DWORD dwContextIndex, dwChannelIndex;
01440 char *r;
01441
01442 PROFILE_START
01443
01444
01445
01446
01447
01448 if (pcchReaderLen == NULL || pcbAtrLen == NULL)
01449 return SCARD_E_INVALID_PARAMETER;
01450
01451
01452 dwReaderLen = *pcchReaderLen;
01453 dwAtrLen = *pcbAtrLen;
01454
01455
01456 if (pdwState)
01457 *pdwState = 0;
01458
01459 if (pdwProtocol)
01460 *pdwProtocol = 0;
01461
01462 *pcchReaderLen = 0;
01463 *pcbAtrLen = 0;
01464
01465 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01466 return SCARD_E_NO_SERVICE;
01467
01468
01469
01470
01471 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
01472
01473 if (rv == -1)
01474 return SCARD_E_INVALID_HANDLE;
01475
01476 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01477
01478 r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
01479 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01480 {
01481
01482 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
01483 break;
01484 }
01485
01486 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01487 {
01488 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01489 return SCARD_E_READER_UNAVAILABLE;
01490 }
01491
01492
01493 memset(&scStatusStruct, 0, sizeof(scStatusStruct));
01494 scStatusStruct.hCard = hCard;
01495
01496
01497 scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
01498 scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
01499
01500 rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
01501 sizeof(scStatusStruct),
01502 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
01503
01504 if (rv == -1)
01505 {
01506 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01507 return SCARD_E_NO_SERVICE;
01508 }
01509
01510
01511
01512
01513 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
01514
01515 memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
01516
01517 if (rv == -1)
01518 {
01519 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01520 return SCARD_F_COMM_ERROR;
01521 }
01522
01523 rv = scStatusStruct.rv;
01524 if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
01525 {
01526
01527
01528
01529 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01530 return rv;
01531 }
01532
01533
01534
01535
01536
01537 *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
01538 *pcbAtrLen = (readerStates[i])->cardAtrLength;
01539
01540 if (pdwState)
01541 *pdwState = (readerStates[i])->readerState;
01542
01543 if (pdwProtocol)
01544 *pdwProtocol = (readerStates[i])->cardProtocol;
01545
01546
01547 if (mszReaderNames)
01548 {
01549 if (*pcchReaderLen > dwReaderLen)
01550 rv = SCARD_E_INSUFFICIENT_BUFFER;
01551
01552 strncpy(mszReaderNames,
01553 psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
01554 dwReaderLen);
01555 }
01556
01557 if (pbAtr)
01558 {
01559 if (*pcbAtrLen > dwAtrLen)
01560 rv = SCARD_E_INSUFFICIENT_BUFFER;
01561
01562 memcpy(pbAtr, (readerStates[i])->cardAtr,
01563 min(*pcbAtrLen, dwAtrLen));
01564 }
01565
01566 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01567
01568 PROFILE_END(rv)
01569
01570 return rv;
01571 }
01572
01658 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
01659 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
01660 {
01661 PSCARD_READERSTATE_A currReader;
01662 PREADER_STATE rContext;
01663 DWORD dwTime = 0;
01664 DWORD dwState;
01665 DWORD dwBreakFlag = 0;
01666 int j;
01667 LONG dwContextIndex;
01668 int currentReaderCount = 0;
01669
01670 PROFILE_START
01671
01672 if (rgReaderStates == NULL && cReaders > 0)
01673 return SCARD_E_INVALID_PARAMETER;
01674
01675 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01676 return SCARD_E_NO_SERVICE;
01677
01678
01679
01680
01681
01682 dwContextIndex = SCardGetContextIndice(hContext);
01683 if (dwContextIndex == -1)
01684 return SCARD_E_INVALID_HANDLE;
01685
01686 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
01687
01688
01689
01690
01691
01692
01693 if (cReaders == 0)
01694 {
01695 while (1)
01696 {
01697 int i;
01698
01699 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01700 {
01701 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01702 return SCARD_E_NO_SERVICE;
01703 }
01704
01705 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01706 {
01707 if ((readerStates[i])->readerID != 0)
01708 {
01709
01710
01711
01712 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01713
01714 PROFILE_END(SCARD_S_SUCCESS)
01715
01716 return SCARD_S_SUCCESS;
01717 }
01718 }
01719
01720 if (dwTimeout == 0)
01721 {
01722
01723
01724
01725 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01726 return SCARD_E_READER_UNAVAILABLE;
01727 }
01728
01729 SYS_USleep(PCSCLITE_STATUS_WAIT);
01730
01731 if (dwTimeout != INFINITE)
01732 {
01733 dwTime += PCSCLITE_STATUS_WAIT;
01734
01735 if (dwTime >= (dwTimeout * 1000))
01736 {
01737 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01738
01739 PROFILE_END(SCARD_E_TIMEOUT)
01740
01741 return SCARD_E_TIMEOUT;
01742 }
01743 }
01744 }
01745 }
01746 else
01747 if (cReaders >= PCSCLITE_MAX_READERS_CONTEXTS)
01748 {
01749 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01750 return SCARD_E_INVALID_VALUE;
01751 }
01752
01753
01754
01755
01756
01757 for (j = 0; j < cReaders; j++)
01758 {
01759 currReader = &rgReaderStates[j];
01760
01761 if (currReader->szReader == NULL)
01762 {
01763 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01764 return SCARD_E_INVALID_VALUE;
01765 }
01766 }
01767
01768
01769
01770
01771
01772
01773
01774
01775 for (j = 0; j < cReaders; j++)
01776 {
01777 currReader = &rgReaderStates[j];
01778 currReader->dwEventState = 0;
01779 }
01780
01781
01782
01783
01784
01785 Log1(PCSC_LOG_DEBUG, "Event Loop Start");
01786
01787 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
01788
01789
01790 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
01791 if ((readerStates[j])->readerID != 0)
01792 currentReaderCount++;
01793
01794 j = 0;
01795
01796 do
01797 {
01798 int newReaderCount = 0;
01799 char ReaderCountChanged = FALSE;
01800
01801 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
01802 {
01803 if (psContextMap[dwContextIndex].mMutex)
01804 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
01805
01806 PROFILE_END(SCARD_E_NO_SERVICE)
01807
01808 return SCARD_E_NO_SERVICE;
01809 }
01810
01811 if (j == 0)
01812 {
01813 int i;
01814
01815 for (i=0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01816 if ((readerStates[i])->readerID != 0)
01817 newReaderCount++;
01818
01819 if (newReaderCount != currentReaderCount)
01820 {
01821 Log1(PCSC_LOG_INFO, "Reader list changed");
01822 ReaderCountChanged = TRUE;
01823 currentReaderCount = newReaderCount;
01824 }
01825 }
01826 currReader = &rgReaderStates[j];
01827
01828
01829
01830 if (currReader->dwCurrentState & SCARD_STATE_IGNORE)
01831 currReader->dwEventState = SCARD_STATE_IGNORE;
01832 else
01833 {
01834 LPSTR lpcReaderName;
01835 int i;
01836
01837
01838
01839 lpcReaderName = (char *) currReader->szReader;
01840
01841 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01842 {
01843 if (strcmp(lpcReaderName, (readerStates[i])->readerName) == 0)
01844 break;
01845 }
01846
01847
01848
01849
01850 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01851 {
01852 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01853 currReader->dwEventState = SCARD_STATE_UNKNOWN;
01854 else
01855 {
01856 currReader->dwEventState =
01857 SCARD_STATE_UNKNOWN | SCARD_STATE_CHANGED;
01858
01859
01860
01861
01862
01863 dwBreakFlag = 1;
01864 }
01865 }
01866 else
01867 {
01868
01869
01870
01871
01872 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
01873 {
01874 currReader->dwEventState |= SCARD_STATE_CHANGED;
01875 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01876 dwBreakFlag = 1;
01877 }
01878
01879
01880
01881
01882
01883
01884 rContext = readerStates[i];
01885
01886
01887
01888
01889 dwState = rContext->readerState;
01890 {
01891 int currentCounter, stateCounter;
01892
01893 stateCounter = (dwState >> 16) & 0xFFFF;
01894 currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
01895
01896
01897 if (stateCounter != currentCounter)
01898 currReader->dwEventState |= SCARD_STATE_CHANGED;
01899
01900
01901 currReader->dwEventState =
01902 ((currReader->dwEventState & 0xffff )
01903 | (stateCounter << 16));
01904 }
01905
01906
01907 if (dwState & SCARD_UNKNOWN)
01908 {
01909
01910
01911
01912 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
01913 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
01914 else
01915 {
01916
01917
01918
01919
01920 currReader->dwEventState = SCARD_STATE_CHANGED |
01921 SCARD_STATE_UNAVAILABLE;
01922 dwBreakFlag = 1;
01923 }
01924 }
01925 else
01926 {
01927
01928
01929
01930 if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
01931 {
01932 currReader->dwEventState &=
01933 ~SCARD_STATE_UNAVAILABLE;
01934 currReader->dwEventState |= SCARD_STATE_CHANGED;
01935 dwBreakFlag = 1;
01936 }
01937 }
01938
01939
01940
01941 if (dwState & SCARD_PRESENT)
01942 {
01943
01944 if (0 == rContext->cardAtrLength)
01945
01946 SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
01947
01948 currReader->cbAtr = rContext->cardAtrLength;
01949 memcpy(currReader->rgbAtr, rContext->cardAtr,
01950 currReader->cbAtr);
01951 }
01952 else
01953 currReader->cbAtr = 0;
01954
01955
01956
01957
01958 if (dwState & SCARD_ABSENT)
01959 {
01960 currReader->dwEventState |= SCARD_STATE_EMPTY;
01961 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
01962 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
01963 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
01964 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01965 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
01966 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
01967 currReader->dwEventState &= ~SCARD_STATE_MUTE;
01968 currReader->dwEventState &= ~SCARD_STATE_INUSE;
01969
01970
01971
01972
01973 if (currReader->dwCurrentState & SCARD_STATE_PRESENT)
01974 {
01975 currReader->dwEventState |= SCARD_STATE_CHANGED;
01976 dwBreakFlag = 1;
01977 }
01978
01979
01980
01981
01982 } else if (dwState & SCARD_PRESENT)
01983 {
01984 currReader->dwEventState |= SCARD_STATE_PRESENT;
01985 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
01986 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
01987 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
01988 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
01989 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
01990 currReader->dwEventState &= ~SCARD_STATE_MUTE;
01991
01992 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
01993 {
01994 currReader->dwEventState |= SCARD_STATE_CHANGED;
01995 dwBreakFlag = 1;
01996 }
01997
01998 if (dwState & SCARD_SWALLOWED)
01999 {
02000 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
02001 currReader->dwEventState |= SCARD_STATE_MUTE;
02002 else
02003 {
02004 currReader->dwEventState |= SCARD_STATE_MUTE;
02005 if (currReader->dwCurrentState
02006 != SCARD_STATE_UNAWARE)
02007 currReader->dwEventState |= SCARD_STATE_CHANGED;
02008 dwBreakFlag = 1;
02009 }
02010 }
02011 else
02012 {
02013
02014
02015
02016 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
02017 {
02018 currReader->dwEventState |=
02019 SCARD_STATE_CHANGED;
02020 dwBreakFlag = 1;
02021 }
02022 }
02023 }
02024
02025
02026
02027
02028 if (rContext->readerSharing == -1)
02029 {
02030 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
02031 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02032 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02033 {
02034 currReader->dwEventState |= SCARD_STATE_CHANGED;
02035 dwBreakFlag = 1;
02036 }
02037 }
02038 else if (rContext->readerSharing >= 1)
02039 {
02040
02041
02042
02043 if (dwState & SCARD_PRESENT)
02044 {
02045 currReader->dwEventState |= SCARD_STATE_INUSE;
02046 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02047 if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)
02048 {
02049 currReader->dwEventState |= SCARD_STATE_CHANGED;
02050 dwBreakFlag = 1;
02051 }
02052 }
02053 }
02054 else if (rContext->readerSharing == 0)
02055 {
02056 currReader->dwEventState &= ~SCARD_STATE_INUSE;
02057 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
02058
02059 if (currReader->dwCurrentState & SCARD_STATE_INUSE)
02060 {
02061 currReader->dwEventState |= SCARD_STATE_CHANGED;
02062 dwBreakFlag = 1;
02063 }
02064 else if (currReader-> dwCurrentState
02065 & SCARD_STATE_EXCLUSIVE)
02066 {
02067 currReader->dwEventState |= SCARD_STATE_CHANGED;
02068 dwBreakFlag = 1;
02069 }
02070 }
02071
02072 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
02073 {
02074
02075
02076
02077
02078 currReader->dwEventState |= SCARD_STATE_CHANGED;
02079 dwBreakFlag = 1;
02080 }
02081
02082 }
02083
02084 }
02085
02086
02087
02088
02089 j = j + 1;
02090 if (j == cReaders)
02091 {
02092 if (!dwBreakFlag)
02093 {
02094
02095
02096
02097
02098 if (ReaderCountChanged)
02099 break;
02100 }
02101 j = 0;
02102 }
02103
02104
02105
02106
02107
02108 if (psContextMap[dwContextIndex].contextBlockStatus
02109 == BLOCK_STATUS_RESUME)
02110 break;
02111
02112
02113
02114
02115 if ((dwBreakFlag == 1) && (j == 0))
02116 break;
02117
02118
02119
02120
02121 if ((dwTimeout == 0) && (j == 0))
02122 break;
02123
02124 if (dwTimeout != INFINITE && dwTimeout != 0)
02125 {
02126
02127
02128
02129
02130 if ((dwTime >= (dwTimeout * 1000)) && (j == 0))
02131 {
02132 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02133 PROFILE_END(SCARD_E_TIMEOUT)
02134 return SCARD_E_TIMEOUT;
02135 }
02136 }
02137
02138
02139
02140
02141 if (j == 0)
02142 {
02143 SYS_USleep(PCSCLITE_STATUS_WAIT);
02144 dwTime += PCSCLITE_STATUS_WAIT;
02145 }
02146 }
02147 while (1);
02148
02149 Log1(PCSC_LOG_DEBUG, "Event Loop End");
02150
02151 if (psContextMap[dwContextIndex].contextBlockStatus ==
02152 BLOCK_STATUS_RESUME)
02153 {
02154 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02155 PROFILE_END(SCARD_E_CANCELLED)
02156 return SCARD_E_CANCELLED;
02157 }
02158
02159 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02160
02161 PROFILE_END(SCARD_S_SUCCESS)
02162
02163 return SCARD_S_SUCCESS;
02164 }
02165
02212 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
02213 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
02214 LPDWORD lpBytesReturned)
02215 {
02216 LONG rv;
02217 control_struct scControlStruct;
02218 sharedSegmentMsg msgStruct;
02219 int i;
02220 DWORD dwContextIndex, dwChannelIndex;
02221
02222 PROFILE_START
02223
02224
02225 if (NULL != lpBytesReturned)
02226 *lpBytesReturned = 0;
02227
02228 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02229 return SCARD_E_NO_SERVICE;
02230
02231
02232
02233
02234 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02235
02236 if (rv == -1)
02237 return SCARD_E_INVALID_HANDLE;
02238
02239 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02240
02241 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02242 {
02243 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02244
02245
02246 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02247 break;
02248 }
02249
02250 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02251 {
02252 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02253 return SCARD_E_READER_UNAVAILABLE;
02254 }
02255
02256 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02257 || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02258 {
02259 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02260 return SCARD_E_INSUFFICIENT_BUFFER;
02261 }
02262
02263 if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
02264 {
02265
02266 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02267 control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
02268 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02269
02270 scControlStructExtended->hCard = hCard;
02271 scControlStructExtended->dwControlCode = dwControlCode;
02272 scControlStructExtended->cbSendLength = cbSendLength;
02273 scControlStructExtended->cbRecvLength = cbRecvLength;
02274 scControlStructExtended->pdwBytesReturned = 0;
02275 scControlStructExtended->rv = SCARD_S_SUCCESS;
02276
02277
02278
02279
02280 scControlStructExtended->size = sizeof(*scControlStructExtended)
02281 - (sizeof(control_struct_extended) - offsetof(control_struct_extended, data))
02282 + cbSendLength;
02283 memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
02284
02285 rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
02286 psContextMap[dwContextIndex].dwClientID,
02287 scControlStructExtended->size,
02288 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02289
02290 if (rv == -1)
02291 {
02292 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02293 return SCARD_E_NO_SERVICE;
02294 }
02295
02296
02297
02298
02299
02300 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02301 if (rv == -1)
02302 {
02303 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02304 return SCARD_F_COMM_ERROR;
02305 }
02306
02307
02308 scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
02309
02310
02311 if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02312 {
02313 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02314 scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02315 psContextMap[dwContextIndex].dwClientID,
02316 PCSCLITE_CLIENT_ATTEMPTS);
02317 if (rv == -1)
02318 {
02319 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02320 return SCARD_F_COMM_ERROR;
02321 }
02322 }
02323
02324 if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
02325 {
02326
02327
02328
02329 memcpy(pbRecvBuffer, scControlStructExtended -> data,
02330 scControlStructExtended -> pdwBytesReturned);
02331 memset(scControlStructExtended -> data, 0x00,
02332 scControlStructExtended -> pdwBytesReturned);
02333 }
02334
02335 if (NULL != lpBytesReturned)
02336 *lpBytesReturned = scControlStructExtended -> pdwBytesReturned;
02337
02338 rv = scControlStructExtended -> rv;
02339 }
02340 else
02341 {
02342 scControlStruct.hCard = hCard;
02343 scControlStruct.dwControlCode = dwControlCode;
02344 scControlStruct.cbSendLength = cbSendLength;
02345 scControlStruct.cbRecvLength = cbRecvLength;
02346 memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02347
02348 rv = WrapSHMWrite(SCARD_CONTROL, psContextMap[dwContextIndex].dwClientID,
02349 sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
02350
02351 if (rv == -1)
02352 {
02353 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02354 return SCARD_E_NO_SERVICE;
02355 }
02356
02357
02358
02359
02360 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02361
02362 if (rv == -1)
02363 {
02364 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02365 return SCARD_F_COMM_ERROR;
02366 }
02367
02368 memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
02369
02370 if (NULL != lpBytesReturned)
02371 *lpBytesReturned = scControlStruct.dwBytesReturned;
02372
02373 if (scControlStruct.rv == SCARD_S_SUCCESS)
02374 {
02375
02376
02377
02378 memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
02379 scControlStruct.cbRecvLength);
02380 memset(scControlStruct.pbRecvBuffer, 0x00,
02381 sizeof(scControlStruct.pbRecvBuffer));
02382 }
02383
02384 rv = scControlStruct.rv;
02385 }
02386
02387 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02388
02389 PROFILE_END(rv)
02390
02391 return rv;
02392 }
02393
02474 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
02475 LPDWORD pcbAttrLen)
02476 {
02477 LONG ret;
02478
02479 PROFILE_START
02480
02481 if (NULL == pcbAttrLen)
02482 return SCARD_E_INVALID_PARAMETER;
02483
02484
02485 if (NULL == pbAttr)
02486
02487 *pcbAttrLen = MAX_BUFFER_SIZE;
02488
02489 ret = SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, pbAttr,
02490 pcbAttrLen);
02491
02492 PROFILE_END(ret)
02493
02494 return ret;
02495 }
02496
02527 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
02528 DWORD cbAttrLen)
02529 {
02530 LONG ret;
02531
02532 PROFILE_START
02533
02534 if (NULL == pbAttr || 0 == cbAttrLen)
02535 return SCARD_E_INVALID_PARAMETER;
02536
02537 ret = SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
02538 &cbAttrLen);
02539
02540 PROFILE_END(ret)
02541
02542 return ret;
02543 }
02544
02545 static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
02546 LPBYTE pbAttr, LPDWORD pcbAttrLen)
02547 {
02548 LONG rv;
02549 getset_struct scGetSetStruct;
02550 sharedSegmentMsg msgStruct;
02551 int i;
02552 DWORD dwContextIndex, dwChannelIndex;
02553
02554 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02555 return SCARD_E_NO_SERVICE;
02556
02557
02558
02559
02560 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02561
02562 if (rv == -1)
02563 return SCARD_E_INVALID_HANDLE;
02564
02565 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02566
02567 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02568 {
02569 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02570
02571
02572 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02573 break;
02574 }
02575
02576 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02577 {
02578 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02579 return SCARD_E_READER_UNAVAILABLE;
02580 }
02581
02582 if (*pcbAttrLen > MAX_BUFFER_SIZE)
02583 {
02584 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02585 return SCARD_E_INSUFFICIENT_BUFFER;
02586 }
02587
02588 scGetSetStruct.hCard = hCard;
02589 scGetSetStruct.dwAttrId = dwAttrId;
02590 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02591 scGetSetStruct.rv = SCARD_E_NO_SERVICE;
02592 memset(scGetSetStruct.pbAttr, 0, sizeof(scGetSetStruct.pbAttr));
02593 if (SCARD_SET_ATTRIB == command)
02594 memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
02595
02596 rv = WrapSHMWrite(command,
02597 psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
02598 PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
02599
02600 if (rv == -1)
02601 {
02602 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02603 return SCARD_E_NO_SERVICE;
02604 }
02605
02606
02607
02608
02609 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02610
02611 if (rv == -1)
02612 {
02613 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02614 return SCARD_F_COMM_ERROR;
02615 }
02616
02617 memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
02618
02619 if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
02620 {
02621
02622
02623
02624 if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
02625 {
02626 scGetSetStruct.cbAttrLen = *pcbAttrLen;
02627 scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
02628 }
02629 else
02630 *pcbAttrLen = scGetSetStruct.cbAttrLen;
02631
02632 if (pbAttr)
02633 memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
02634
02635 memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
02636 }
02637
02638 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02639
02640 return scGetSetStruct.rv;
02641 }
02642
02696 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
02697 LPCBYTE pbSendBuffer, DWORD cbSendLength,
02698 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
02699 LPDWORD pcbRecvLength)
02700 {
02701 LONG rv;
02702 int i;
02703 DWORD dwContextIndex, dwChannelIndex;
02704
02705 PROFILE_START
02706
02707 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
02708 pcbRecvLength == NULL || pioSendPci == NULL)
02709 return SCARD_E_INVALID_PARAMETER;
02710
02711 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02712 return SCARD_E_NO_SERVICE;
02713
02714
02715
02716
02717 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
02718
02719 if (rv == -1)
02720 {
02721 *pcbRecvLength = 0;
02722 return SCARD_E_INVALID_HANDLE;
02723 }
02724
02725 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02726
02727 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02728 {
02729 char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
02730
02731
02732 if (r && strcmp(r, (readerStates[i])->readerName) == 0)
02733 break;
02734 }
02735
02736 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
02737 {
02738 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02739 return SCARD_E_READER_UNAVAILABLE;
02740 }
02741
02742 if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
02743 || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
02744 {
02745 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02746 return SCARD_E_INSUFFICIENT_BUFFER;
02747 }
02748
02749 if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
02750 {
02751
02752 unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
02753 transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
02754 sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
02755
02756 scTransmitStructExtended->hCard = hCard;
02757 scTransmitStructExtended->cbSendLength = cbSendLength;
02758 scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
02759
02760
02761
02762
02763 scTransmitStructExtended->size = sizeof(*scTransmitStructExtended)
02764 - (sizeof(transmit_struct_extended) - offsetof(transmit_struct_extended, data))
02765 + cbSendLength;
02766 memcpy(&scTransmitStructExtended->pioSendPci, pioSendPci,
02767 sizeof(SCARD_IO_REQUEST));
02768 memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
02769 scTransmitStructExtended->rv = SCARD_S_SUCCESS;
02770
02771 if (pioRecvPci)
02772 {
02773 memcpy(&scTransmitStructExtended->pioRecvPci, pioRecvPci,
02774 sizeof(SCARD_IO_REQUEST));
02775 }
02776 else
02777 {
02778 scTransmitStructExtended->pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
02779 scTransmitStructExtended->pioRecvPci.cbPciLength = sizeof(SCARD_IO_REQUEST);
02780 }
02781
02782 rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
02783 psContextMap[dwContextIndex].dwClientID,
02784 scTransmitStructExtended->size,
02785 PCSCLITE_CLIENT_ATTEMPTS, buffer);
02786
02787 if (rv == -1)
02788 {
02789 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02790 return SCARD_E_NO_SERVICE;
02791 }
02792
02793
02794
02795
02796
02797 rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02798 if (rv == -1)
02799 {
02800 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02801 return SCARD_F_COMM_ERROR;
02802 }
02803
02804
02805 scTransmitStructExtended = (transmit_struct_extended *)&(pmsgStruct -> data);
02806
02807
02808 if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
02809 {
02810 rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
02811 scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
02812 psContextMap[dwContextIndex].dwClientID,
02813 PCSCLITE_CLIENT_ATTEMPTS);
02814 if (rv == -1)
02815 {
02816 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02817 return SCARD_F_COMM_ERROR;
02818 }
02819 }
02820
02821 if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
02822 {
02823
02824
02825
02826 memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
02827 scTransmitStructExtended -> pcbRecvLength);
02828 memset(scTransmitStructExtended -> data, 0x00,
02829 scTransmitStructExtended -> pcbRecvLength);
02830
02831 if (pioRecvPci)
02832 memcpy(pioRecvPci, &scTransmitStructExtended -> pioRecvPci,
02833 sizeof(SCARD_IO_REQUEST));
02834 }
02835
02836 *pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
02837 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02838
02839 rv = scTransmitStructExtended -> rv;
02840 }
02841 else
02842 {
02843
02844 transmit_struct scTransmitStruct;
02845 sharedSegmentMsg msgStruct;
02846
02847 scTransmitStruct.hCard = hCard;
02848 scTransmitStruct.cbSendLength = cbSendLength;
02849 scTransmitStruct.pcbRecvLength = *pcbRecvLength;
02850 memcpy(&scTransmitStruct.pioSendPci, pioSendPci,
02851 sizeof(SCARD_IO_REQUEST));
02852 memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
02853 memset(scTransmitStruct.pbSendBuffer+cbSendLength, 0, sizeof(scTransmitStruct.pbSendBuffer)-cbSendLength);
02854 memset(scTransmitStruct.pbRecvBuffer, 0, sizeof(scTransmitStruct.pbRecvBuffer));
02855 scTransmitStruct.rv = SCARD_S_SUCCESS;
02856
02857 scTransmitStruct.pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
02858 scTransmitStruct.pioRecvPci.cbPciLength = sizeof(scTransmitStruct.pioRecvPci);
02859
02860 rv = WrapSHMWrite(SCARD_TRANSMIT,
02861 psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
02862 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
02863
02864 if (rv == -1)
02865 {
02866 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02867 return SCARD_E_NO_SERVICE;
02868 }
02869
02870
02871
02872
02873 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
02874
02875 memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
02876
02877 if (rv == -1)
02878 {
02879 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02880 return SCARD_F_COMM_ERROR;
02881 }
02882
02883
02884
02885
02886 memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
02887
02888 if (scTransmitStruct.rv == SCARD_S_SUCCESS)
02889 {
02890
02891
02892
02893 memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
02894 scTransmitStruct.pcbRecvLength);
02895 memset(scTransmitStruct.pbRecvBuffer, 0x00,
02896 scTransmitStruct.pcbRecvLength);
02897
02898 if (pioRecvPci)
02899 memcpy(pioRecvPci, &scTransmitStruct.pioRecvPci,
02900 sizeof(SCARD_IO_REQUEST));
02901 }
02902
02903 *pcbRecvLength = scTransmitStruct.pcbRecvLength;
02904 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02905
02906 rv = scTransmitStruct.rv;
02907 }
02908
02909 PROFILE_END(rv)
02910
02911 return rv;
02912 }
02913
02943 LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
02944 LPSTR mszReaders, LPDWORD pcchReaders)
02945 {
02946 DWORD dwReadersLen;
02947 int i, lastChrPtr;
02948 LONG dwContextIndex;
02949
02950 PROFILE_START
02951
02952
02953
02954
02955 if (pcchReaders == NULL)
02956 return SCARD_E_INVALID_PARAMETER;
02957
02958 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
02959 return SCARD_E_NO_SERVICE;
02960
02961
02962
02963
02964 dwContextIndex = SCardGetContextIndice(hContext);
02965 if (dwContextIndex == -1)
02966 return SCARD_E_INVALID_HANDLE;
02967
02968 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
02969
02970 dwReadersLen = 0;
02971 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02972 if ((readerStates[i])->readerID != 0)
02973 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
02974
02975
02976 dwReadersLen += 1;
02977
02978 if ((mszReaders == NULL)
02979 || (*pcchReaders == 0))
02980 {
02981 *pcchReaders = dwReadersLen;
02982 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02983 PROFILE_END(SCARD_S_SUCCESS)
02984 return SCARD_S_SUCCESS;
02985 }
02986
02987 if (*pcchReaders < dwReadersLen)
02988 {
02989 *pcchReaders = dwReadersLen;
02990 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
02991 PROFILE_END(SCARD_E_INSUFFICIENT_BUFFER)
02992 return SCARD_E_INSUFFICIENT_BUFFER;
02993 }
02994
02995 lastChrPtr = 0;
02996 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
02997 {
02998 if ((readerStates[i])->readerID != 0)
02999 {
03000
03001
03002
03003 strcpy(&mszReaders[lastChrPtr], (readerStates[i])->readerName);
03004 lastChrPtr += strlen((readerStates[i])->readerName)+1;
03005 }
03006 }
03007 mszReaders[lastChrPtr] = '\0';
03008
03009 *pcchReaders = dwReadersLen;
03010
03011 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03012
03013 PROFILE_END(SCARD_S_SUCCESS)
03014
03015 return SCARD_S_SUCCESS;
03016 }
03017
03049 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
03050 LPDWORD pcchGroups)
03051 {
03052 LONG rv = SCARD_S_SUCCESS;
03053 LONG dwContextIndex;
03054
03055 PROFILE_START
03056
03057 const char ReaderGroup[] = "SCard$DefaultReaders";
03058 const int dwGroups = strlen(ReaderGroup) + 2;
03059
03060 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
03061 return SCARD_E_NO_SERVICE;
03062
03063
03064
03065
03066 dwContextIndex = SCardGetContextIndice(hContext);
03067 if (dwContextIndex == -1)
03068 return SCARD_E_INVALID_HANDLE;
03069
03070 SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
03071
03072 if (mszGroups)
03073 {
03074
03075 if (*pcchGroups < dwGroups)
03076 rv = SCARD_E_INSUFFICIENT_BUFFER;
03077 else
03078 {
03079 memset(mszGroups, 0, dwGroups);
03080 memcpy(mszGroups, ReaderGroup, strlen(ReaderGroup));
03081 }
03082 }
03083
03084 *pcchGroups = dwGroups;
03085
03086 SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
03087
03088 PROFILE_END(rv)
03089
03090 return rv;
03091 }
03092
03120 LONG SCardCancel(SCARDCONTEXT hContext)
03121 {
03122 LONG dwContextIndex;
03123
03124 PROFILE_START
03125
03126 dwContextIndex = SCardGetContextIndice(hContext);
03127
03128 if (dwContextIndex == -1)
03129 return SCARD_E_INVALID_HANDLE;
03130
03131
03132
03133
03134
03135 psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
03136
03137 PROFILE_END(SCARD_S_SUCCESS)
03138
03139 return SCARD_S_SUCCESS;
03140 }
03141
03165 LONG SCardIsValidContext(SCARDCONTEXT hContext)
03166 {
03167 LONG rv;
03168 LONG dwContextIndex;
03169
03170 PROFILE_START
03171
03172 rv = SCARD_S_SUCCESS;
03173
03174
03175 if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
03176 return SCARD_E_INVALID_HANDLE;
03177
03178
03179
03180
03181 dwContextIndex = SCardGetContextIndice(hContext);
03182 if (dwContextIndex == -1)
03183 rv = SCARD_E_INVALID_HANDLE;
03184
03185 PROFILE_END(rv)
03186
03187 return rv;
03188 }
03189
03206 static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
03207 {
03208 int i;
03209
03210 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03211 {
03212 if (psContextMap[i].hContext == 0)
03213 {
03214 psContextMap[i].hContext = hContext;
03215 psContextMap[i].dwClientID = dwClientID;
03216 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
03217 psContextMap[i].mMutex = malloc(sizeof(PCSCLITE_MUTEX));
03218 SYS_MutexInit(psContextMap[i].mMutex);
03219 return SCARD_S_SUCCESS;
03220 }
03221 }
03222
03223 return SCARD_E_NO_MEMORY;
03224 }
03225
03238 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
03239 {
03240 LONG rv;
03241
03242 SCardLockThread();
03243 rv = SCardGetContextIndiceTH(hContext);
03244 SCardUnlockThread();
03245
03246 return rv;
03247 }
03248
03261 static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
03262 {
03263 int i;
03264
03265
03266
03267
03268 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03269 {
03270 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
03271 return i;
03272 }
03273
03274 return -1;
03275 }
03276
03286 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
03287 {
03288 LONG retIndice;
03289
03290 retIndice = SCardGetContextIndiceTH(hContext);
03291
03292 if (retIndice == -1)
03293 return SCARD_E_INVALID_HANDLE;
03294 else
03295 return SCardCleanContext(retIndice);
03296 }
03297
03298 static LONG SCardCleanContext(LONG indice)
03299 {
03300 int i;
03301
03302 psContextMap[indice].hContext = 0;
03303 SHMClientCloseSession(psContextMap[indice].dwClientID);
03304 psContextMap[indice].dwClientID = 0;
03305 free(psContextMap[indice].mMutex);
03306 psContextMap[indice].mMutex = NULL;
03307 psContextMap[indice].contextBlockStatus = BLOCK_STATUS_RESUME;
03308
03309 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03310 {
03311
03312
03313
03314 psContextMap[indice].psChannelMap[i].hCard = 0;
03315 free(psContextMap[indice].psChannelMap[i].readerName);
03316 psContextMap[indice].psChannelMap[i].readerName = NULL;
03317 }
03318
03319 return SCARD_S_SUCCESS;
03320 }
03321
03322
03323
03324
03325
03326 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
03327 LPCSTR readerName)
03328 {
03329 int i;
03330
03331 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03332 {
03333 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
03334 {
03335 psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
03336 psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
03337 return SCARD_S_SUCCESS;
03338 }
03339 }
03340
03341 return SCARD_E_NO_MEMORY;
03342 }
03343
03344 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
03345 {
03346 DWORD dwContextIndice, dwChannelIndice;
03347 LONG rv;
03348
03349 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
03350
03351 if (rv == -1)
03352 return SCARD_E_INVALID_HANDLE;
03353 else
03354 {
03355 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
03356 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
03357 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
03358 return SCARD_S_SUCCESS;
03359 }
03360 }
03361
03362 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03363 {
03364 LONG rv;
03365
03366 if (0 == hCard)
03367 return -1;
03368
03369 SCardLockThread();
03370 rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
03371 SCardUnlockThread();
03372
03373 return rv;
03374 }
03375
03376 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
03377 {
03378 int i;
03379
03380 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03381 {
03382 if (psContextMap[i].hContext != 0)
03383 {
03384 int j;
03385
03386 for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
03387 {
03388 if (psContextMap[i].psChannelMap[j].hCard == hCard)
03389 {
03390 *pdwContextIndice = i;
03391 *pdwChannelIndice = j;
03392 return SCARD_S_SUCCESS;
03393 }
03394 }
03395
03396 }
03397 }
03398
03399 return -1;
03400 }
03401
03409 LONG SCardCheckDaemonAvailability(void)
03410 {
03411 LONG rv;
03412 struct stat statBuffer;
03413
03414 rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &statBuffer);
03415
03416 if (rv != 0)
03417 {
03418 Log1(PCSC_LOG_INFO, "PCSC Not Running");
03419 return SCARD_E_NO_SERVICE;
03420 }
03421
03422 if (daemon_ctime)
03423 {
03424
03425
03426 if (statBuffer.st_ctime > daemon_ctime)
03427 {
03428 pid_t new_pid;
03429
03430 new_pid = GetDaemonPid();
03431
03432
03433 if (new_pid != daemon_pid)
03434 {
03435 int i;
03436
03437 Log1(PCSC_LOG_INFO, "PCSC restarted");
03438
03439
03440 SCardLockThread();
03441
03442 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
03443 if (psContextMap[i].hContext)
03444 SCardCleanContext(i);
03445
03446 SCardUnlockThread();
03447
03448
03449 daemon_ctime = 0;
03450
03451
03452 SCardUnload();
03453
03454 return SCARD_E_NO_SERVICE;
03455 }
03456
03457 daemon_ctime = statBuffer.st_ctime;
03458 }
03459 }
03460 else
03461 {
03462 daemon_ctime = statBuffer.st_ctime;
03463 daemon_pid = GetDaemonPid();
03464 }
03465
03466 return SCARD_S_SUCCESS;
03467 }
03468
03474 #ifdef __SUNPRO_C
03475 #pragma fini (SCardUnload)
03476 #endif
03477
03478 void DESTRUCTOR SCardUnload(void)
03479 {
03480 int i;
03481
03482 if (!isExecuted)
03483 return;
03484
03485
03486 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
03487 {
03488 if (readerStates[i] != NULL)
03489 {
03490 SYS_PublicMemoryUnmap(readerStates[i], sizeof(READER_STATE));
03491 readerStates[i] = NULL;
03492 }
03493 }
03494
03495 SYS_CloseFile(mapAddr);
03496 isExecuted = 0;
03497 }
03498