00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00018 #include "config.h"
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <sys/types.h>
00022 #include <fcntl.h>
00023 #include <unistd.h>
00024 #include <sys/un.h>
00025 #include <smartcard/scf.h>
00026 #include <time.h>
00027
00028 #include "pcsclite.h"
00029 #include "winscard.h"
00030 #include "debug.h"
00031
00032 #include "thread_generic.h"
00033
00034 #include "readerfactory.h"
00035 #include "eventhandler.h"
00036 #include "sys_generic.h"
00037
00038 #define TRUE 1
00039 #define FALSE 0
00040
00041 #undef PCSCLITE_MAX_READERS_CONTEXTS
00042 #define PCSCLITE_MAX_READERS_CONTEXTS 2
00043
00045 static SCF_Session_t g_hSession = NULL;
00046
00048 SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, g_rgSCardRawPci;
00049
00050 static struct _psTransmitMap
00051 {
00052 BYTE Buffer[266];
00053 int isResponseCached;
00054 LONG bufferLength;
00055 } psTransmitMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
00056
00058 static struct _psChannelMap
00059 {
00060 SCARDHANDLE PCSC_hCard;
00061 SCARDCONTEXT hContext;
00062 SCF_Session_t hSession;
00063 SCF_Terminal_t hTerminal;
00064 SCF_Card_t SCF_hCard;
00065 short haveLock;
00066 short isReset;
00067 int ReaderIndice;
00068 } psChannelMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
00069
00071 static struct _psContextMap
00072 {
00073 SCARDCONTEXT hContext;
00074 SCF_Session_t hSession;
00075 DWORD contextBlockStatus;
00076 } psContextMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
00077
00079 static struct _psReaderMap
00080 {
00081 SCF_Terminal_t hTerminal;
00082 LPSTR ReaderName;
00083 short SharedRefCount;
00084 DWORD dwCurrentState;
00085 BYTE bAtr[MAX_ATR_SIZE];
00086 DWORD dwAtrLength;
00087 SCF_ListenerHandle_t lHandle;
00088 } psReaderMap[PCSCLITE_MAX_READERS_CONTEXTS];
00089
00090 static PCSCLITE_MUTEX clientMutex = PTHREAD_MUTEX_INITIALIZER;
00091
00097 static PCSCLITE_MUTEX EventMutex = PTHREAD_MUTEX_INITIALIZER;
00098 static PCSCLITE_MUTEX SCFInitMutex = PTHREAD_MUTEX_INITIALIZER;
00099 static pthread_cond_t EventCondition = PTHREAD_COND_INITIALIZER;
00100 static char PCSC_Initialized = 0;
00101
00102 static LONG isOCFServerRunning(void);
00103 LONG SCardLockThread(void);
00104 LONG SCardUnlockThread(void);
00105 LONG SCardEventLock(void);
00106 LONG SCardEventUnlock(void);
00107 static LONG PCSC_SCF_Initialize(void);
00108 static void EventCallback(SCF_Event_t eventType, SCF_Terminal_t hTerm,
00109 void *cbdata);
00110 static LONG PCSC_SCF_getATR(SCF_Card_t hCard, LPBYTE pcbAtr,
00111 LPDWORD pcbAtrLen);
00112
00113 static LONG ConvertStatus(SCF_Status_t status);
00114 static LONG SCardGetReaderIndice(LPCSTR ReaderName);
00115 static LONG getNewContext(SCARDCONTEXT * phContext);
00116 static LONG SCardAddContext(SCARDCONTEXT hContext, SCF_Session_t hSession);
00117 static SCF_Session_t getSessionForContext(SCARDCONTEXT hContext);
00118 static LONG SCardRemoveContext(SCARDCONTEXT hContext);
00119 static LONG SCardGetContextIndice(SCARDCONTEXT hContext);
00120
00121 static LONG getNewHandle(SCARDCONTEXT hContext, LPCSTR szReader,
00122 SCARDHANDLE * phCard, DWORD);
00123 static LONG getCardForHandle(SCARDHANDLE PSCS_hCard, SCF_Card_t * SCF_hCard);
00124 static LONG SCardRemoveHandle(SCARDHANDLE hCard);
00125 static LONG SCardAddHandle(SCARDHANDLE PCSC_hCard, SCARDCONTEXT hContext,
00126 SCF_Session_t hSession, SCF_Terminal_t hTerminal,
00127 SCF_Card_t SCF_hCard, int, DWORD);
00128 static LONG SCardGetHandleIndice(SCARDHANDLE hCard);
00129 static LONG isActiveContextPresent(void);
00130
00131
00132 static LONG SCardEstablishContextTH(DWORD dwScope, LPCVOID pvReserved1,
00133 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00134 {
00135 LONG rv = 0;
00136
00137 if (SCARD_S_SUCCESS != isOCFServerRunning())
00138 return SCARD_E_NO_SERVICE;
00139
00140 rv = PCSC_SCF_Initialize();
00141
00142 if (SCARD_S_SUCCESS != rv)
00143 return rv;
00144
00145 if (NULL == phContext)
00146 return SCARD_E_INVALID_PARAMETER;
00147 else
00148 *phContext = 0;
00149
00150 if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
00151 dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
00152 {
00153 *phContext = 0;
00154 return SCARD_E_INVALID_VALUE;
00155 }
00156 rv = getNewContext(phContext);
00157 return rv;
00158 }
00159
00160 LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
00161 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00162 {
00163 long rv;
00164
00165 SCardLockThread();
00166 rv = SCardEstablishContextTH(dwScope, pvReserved1,
00167 pvReserved2, phContext);
00168 SCardUnlockThread();
00169
00170 return rv;
00171 }
00172
00173 static LONG SCardReleaseContextTH(SCARDCONTEXT hContext)
00174 {
00175 LONG rv;
00176
00177
00178 if (SCARD_S_SUCCESS != isOCFServerRunning())
00179 return SCARD_E_NO_SERVICE;
00180
00181 rv = 0;
00182
00183
00184 rv = SCardRemoveContext(hContext);
00185
00186 return rv;
00187 }
00188
00189 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00190 {
00191 long rv;
00192
00193 SCardLockThread();
00194 rv = SCardReleaseContextTH(hContext);
00195 SCardUnlockThread();
00196
00197 return rv;
00198 }
00199
00200
00201 static LONG SCardListReadersTH(SCARDCONTEXT hContext, LPCSTR mszGroups,
00202 LPSTR mszReaders, LPDWORD pcchReaders)
00203 {
00204 static int first_time = 1;
00205 int i = 0;
00206 static DWORD dwReadersLen = 0;
00207 LONG retIndice = 0;
00208 char *tempPtr;
00209
00210 if (SCARD_S_SUCCESS != isOCFServerRunning())
00211 return SCARD_E_NO_SERVICE;
00212
00213
00214 if (pcchReaders == NULL)
00215 {
00216 return SCARD_E_INVALID_PARAMETER;
00217 }
00218
00219 retIndice = SCardGetContextIndice(hContext);
00220 if (0 > retIndice)
00221 return SCARD_E_INVALID_HANDLE;
00222
00223
00224
00225 if (first_time)
00226 {
00227 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00228 {
00229 if (NULL != psReaderMap[i].ReaderName)
00230 dwReadersLen += strlen(psReaderMap[i].ReaderName) + 1;
00231 }
00232 dwReadersLen++;
00233 first_time = 0;
00234 }
00235
00236 if (1 >= dwReadersLen)
00237 return SCARD_E_READER_UNAVAILABLE;
00238
00239 if (mszReaders == NULL)
00240 {
00241 *pcchReaders = dwReadersLen;
00242 return SCARD_S_SUCCESS;
00243 }
00244 else if (*pcchReaders == 0)
00245 {
00246 *pcchReaders = dwReadersLen;
00247 return SCARD_S_SUCCESS;
00248 }
00249 else if (*pcchReaders < dwReadersLen)
00250 {
00251 *pcchReaders = dwReadersLen;
00252 return SCARD_E_INSUFFICIENT_BUFFER;
00253 }
00254
00255 tempPtr = mszReaders;
00256 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00257 {
00258 if (NULL != psReaderMap[i].ReaderName)
00259 {
00260 memcpy(tempPtr, psReaderMap[i].ReaderName,
00261 strlen(psReaderMap[i].ReaderName) + 1);
00262 tempPtr += (strlen(psReaderMap[i].ReaderName) + 1);
00263 }
00264 }
00265
00266 tempPtr[0] = '\0';
00267 *pcchReaders = dwReadersLen;
00268
00269 return SCARD_S_SUCCESS;
00270 }
00271
00272
00273 LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
00274 LPSTR mszReaders, LPDWORD pcchReaders)
00275 {
00276 long rv;
00277
00278 SCardLockThread();
00279 rv = SCardListReadersTH(hContext, mszGroups, mszReaders, pcchReaders);
00280 SCardUnlockThread();
00281
00282 return rv;
00283 }
00284
00285
00286
00287
00288 static LONG SCardConnectTH(SCARDCONTEXT hContext, LPCSTR szReader,
00289 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00290 LPDWORD pdwActiveProtocol)
00291 {
00292 LONG rv;
00293
00294 if (SCARD_S_SUCCESS != isOCFServerRunning())
00295 return SCARD_E_NO_SERVICE;
00296
00297
00298 rv = 0;
00299
00300
00301 if (phCard == NULL || pdwActiveProtocol == NULL)
00302 return SCARD_E_INVALID_PARAMETER;
00303 else
00304 *phCard = 0;
00305
00306
00307 if (SCardGetContextIndice(hContext) == -1)
00308 return SCARD_E_INVALID_HANDLE;
00309
00310 if (szReader == NULL)
00311 return SCARD_E_UNKNOWN_READER;
00312
00313
00314 if (strlen(szReader) > MAX_READERNAME)
00315 return SCARD_E_INVALID_VALUE;
00316
00317 if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00318 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00319 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00320 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY))
00321 {
00322 return SCARD_E_INVALID_VALUE;
00323 }
00324
00325 if ((SCARD_SHARE_SHARED != dwShareMode) &&
00326 (SCARD_SHARE_EXCLUSIVE != dwShareMode) &&
00327 (SCARD_SHARE_DIRECT != dwShareMode))
00328 {
00329 return SCARD_E_INVALID_VALUE;
00330 }
00331
00332
00333
00334
00335 rv = getNewHandle(hContext, szReader, phCard, dwShareMode);
00336
00337 if (SCARD_S_SUCCESS != rv)
00338 return rv;
00339
00340 *pdwActiveProtocol = SCARD_PROTOCOL_T0;
00341 return SCARD_S_SUCCESS;
00342 }
00343
00344 LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
00345 DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00346 LPDWORD pdwActiveProtocol)
00347 {
00348 long rv;
00349
00350 SCardLockThread();
00351 rv = SCardConnectTH(hContext, szReader, dwShareMode,
00352 dwPreferredProtocols, phCard, pdwActiveProtocol);
00353 SCardUnlockThread();
00354 return rv;
00355 }
00356
00357 static LONG SCardDisconnectTH(SCARDHANDLE hCard, DWORD dwDisposition)
00358 {
00359 long rv;
00360 LONG retIndice = 0;
00361
00362 SCF_Status_t status;
00363
00364
00365 if (SCARD_S_SUCCESS != isOCFServerRunning())
00366 return SCARD_E_NO_SERVICE;
00367
00368 if (dwDisposition != SCARD_LEAVE_CARD &&
00369 dwDisposition != SCARD_RESET_CARD &&
00370 dwDisposition != SCARD_UNPOWER_CARD &&
00371 dwDisposition != SCARD_EJECT_CARD)
00372 {
00373 return SCARD_E_INVALID_VALUE;
00374 }
00375
00376 retIndice = SCardGetHandleIndice(hCard);
00377 if ((retIndice == -1) || (NULL == psChannelMap[retIndice].SCF_hCard))
00378 return SCARD_E_INVALID_HANDLE;
00379
00380
00381
00382
00383 if (SCARD_LEAVE_CARD != dwDisposition)
00384 {
00385
00386 status = SCF_Card_lock(psChannelMap[retIndice].SCF_hCard, 0);
00387 if ((SCF_STATUS_SUCCESS == status)
00388 || (SCF_STATUS_DOUBLELOCK == status))
00389 {
00390 status = SCF_Card_reset(psChannelMap[retIndice].SCF_hCard);
00391 SCF_Card_unlock(psChannelMap[retIndice].SCF_hCard);
00392
00393
00394 SYS_USleep(10);
00395 }
00396 }
00397
00398 rv = SCardRemoveHandle(hCard);
00399
00400 return rv;
00401 }
00402
00403 static LONG SCardReconnectTH(SCARDHANDLE hCard, DWORD dwShareMode,
00404 DWORD dwPreferredProtocols, DWORD dwInitialization,
00405 LPDWORD pdwActiveProtocol)
00406 {
00407 SCARDCONTEXT hContext;
00408 LPSTR ReaderName;
00409 SCARDHANDLE tempHandle;
00410 LONG rv;
00411
00412 int retIndice = 0;
00413 if (SCARD_S_SUCCESS != isOCFServerRunning())
00414 return SCARD_E_NO_SERVICE;
00415 if (pdwActiveProtocol == NULL)
00416 return SCARD_E_INVALID_PARAMETER;
00417
00418 if (dwInitialization != SCARD_LEAVE_CARD &&
00419 dwInitialization != SCARD_RESET_CARD &&
00420 dwInitialization != SCARD_UNPOWER_CARD &&
00421 dwInitialization != SCARD_EJECT_CARD)
00422 {
00423 return SCARD_E_INVALID_VALUE;
00424 }
00425
00426 retIndice = SCardGetHandleIndice(hCard);
00427
00428 if (-1 == retIndice)
00429 return SCARD_E_INVALID_HANDLE;
00430
00431 hContext = psChannelMap[retIndice].hContext;
00432 ReaderName = psReaderMap[psChannelMap[retIndice].ReaderIndice].ReaderName;
00433
00434 SCardDisconnectTH(hCard, dwInitialization);
00435
00436
00437 rv = SCardConnectTH(hContext, ReaderName, dwShareMode,
00438 dwPreferredProtocols, &tempHandle, pdwActiveProtocol);
00439 if (SCARD_S_SUCCESS != rv)
00440 return rv;
00441
00442 retIndice = SCardGetHandleIndice(tempHandle);
00443 if (-1 == retIndice)
00444 return SCARD_E_NO_MEMORY;
00445
00446
00447 SCardEventLock();
00448 psChannelMap[retIndice].PCSC_hCard = hCard;
00449 SCardEventUnlock();
00450
00451 return SCARD_S_SUCCESS;
00452 }
00453
00454 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00455 DWORD dwPreferredProtocols, DWORD dwInitialization,
00456 LPDWORD pdwActiveProtocol)
00457 {
00458 long rv;
00459
00460 SCardLockThread();
00461 rv = SCardReconnectTH(hCard, dwShareMode, dwPreferredProtocols,
00462 dwInitialization, pdwActiveProtocol);
00463 SCardUnlockThread();
00464 return rv;
00465 }
00466
00467 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
00468 {
00469 long rv;
00470
00471 SCardLockThread();
00472 rv = SCardDisconnectTH(hCard, dwDisposition);
00473 SCardUnlockThread();
00474 return rv;
00475 }
00476
00477
00478 LONG SCardBeginTransaction(SCARDHANDLE hCard)
00479 {
00480 LONG rv;
00481
00482 SCF_Card_t SCF_hCard;
00483 SCF_Status_t status;
00484
00485 rv = 0;
00486
00487 SCardLockThread();
00488 if (SCARD_S_SUCCESS != isOCFServerRunning())
00489 {
00490 SCardUnlockThread();
00491 return SCARD_E_NO_SERVICE;
00492 }
00493 rv = getCardForHandle(hCard, &SCF_hCard);
00494 if (SCARD_S_SUCCESS != rv)
00495 {
00496 SCardUnlockThread();
00497 return rv;
00498 }
00499 SCardUnlockThread();
00500
00501 status = SCF_Card_lock(SCF_hCard, SCF_TIMEOUT_MAX);
00502
00503 if (SCF_STATUS_DOUBLELOCK == status)
00504 return SCARD_S_SUCCESS;
00505
00506 rv = ConvertStatus(status);
00507
00508 return rv;
00509 }
00510
00511 static LONG SCardEndTransactionTH(SCARDHANDLE hCard, DWORD dwDisposition)
00512 {
00513 LONG rv;
00514 LONG retIndice = 0;
00515 SCF_Card_t SCF_hCard;
00516 SCF_Status_t status;
00517
00518 if (SCARD_S_SUCCESS != isOCFServerRunning())
00519 return SCARD_E_NO_SERVICE;
00520
00521 rv = 0;
00522 if (dwDisposition != SCARD_LEAVE_CARD &&
00523 dwDisposition != SCARD_RESET_CARD &&
00524 dwDisposition != SCARD_UNPOWER_CARD &&
00525 dwDisposition != SCARD_EJECT_CARD)
00526 {
00527
00528 return SCARD_E_INVALID_VALUE;
00529 }
00530 retIndice = SCardGetHandleIndice(hCard);
00531 if (retIndice == -1)
00532 return SCARD_E_INVALID_HANDLE;
00533
00534 rv = getCardForHandle(hCard, &SCF_hCard);
00535 if (rv != SCARD_S_SUCCESS)
00536 return rv;
00537
00538
00539 if (SCARD_LEAVE_CARD != dwDisposition)
00540 {
00541 status = SCF_Card_reset(psChannelMap[retIndice].SCF_hCard);
00542 if (SCF_STATUS_SUCCESS == status)
00543 {
00544
00545 SYS_USleep(10);
00546 SCardEventLock();
00547 psChannelMap[retIndice].isReset = 0;
00548 SCardEventUnlock();
00549 }
00550 }
00551
00552 status = SCF_Card_unlock(SCF_hCard);
00553
00554 return ConvertStatus(status);
00555 }
00556
00557 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
00558 {
00559 long rv;
00560
00561 SCardLockThread();
00562 rv = SCardEndTransactionTH(hCard, dwDisposition);
00563 SCardUnlockThread();
00564 return rv;
00565 }
00566
00567 static LONG SCardCancelTransactionTH(SCARDHANDLE hCard)
00568 {
00569 if (SCARD_S_SUCCESS != isOCFServerRunning())
00570 return SCARD_E_NO_SERVICE;
00571
00572
00573 return SCARD_S_SUCCESS;
00574 }
00575
00576 LONG SCardCancelTransaction(SCARDHANDLE hCard)
00577 {
00578 long rv;
00579
00580 SCardLockThread();
00581 rv = SCardCancelTransactionTH(hCard);
00582 SCardUnlockThread();
00583 return rv;
00584 }
00585
00586 static LONG SCardStatusTH(SCARDHANDLE hCard, LPSTR mszReaderNames,
00587 LPDWORD pcchReaderLen, LPDWORD pdwState,
00588 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
00589 {
00590 LONG retIndice, rv;
00591 int i;
00592 DWORD dwReaderLen;
00593 SCF_Card_t SCF_hCard;
00594
00595 if (SCARD_S_SUCCESS != isOCFServerRunning())
00596 return SCARD_E_NO_SERVICE;
00597
00598 retIndice = 0;
00599 dwReaderLen = 0;
00600 rv = 0;
00601 i = 0;
00602
00603
00604 if (pcchReaderLen == NULL || pdwState == NULL ||
00605 pdwProtocol == NULL || pcbAtrLen == NULL)
00606 {
00607 return SCARD_E_INVALID_PARAMETER;
00608 }
00609
00610 retIndice = SCardGetHandleIndice(hCard);
00611
00612 rv = getCardForHandle(hCard, &SCF_hCard);
00613 if (SCARD_S_SUCCESS != rv)
00614 return rv;
00615
00616 dwReaderLen =
00617 strlen(psReaderMap[psChannelMap[retIndice].ReaderIndice].ReaderName);
00618
00619 if (mszReaderNames == NULL)
00620 {
00621 *pcchReaderLen = dwReaderLen;
00622 *pcbAtrLen = 0;
00623 *pdwState = 0;
00624 *pdwProtocol = 0;
00625 return SCARD_S_SUCCESS;
00626 }
00627
00628 if (*pcchReaderLen == 0)
00629 {
00630 *pcchReaderLen = dwReaderLen;
00631 *pcbAtrLen = 0;
00632 *pdwState = 0;
00633 *pdwProtocol = 0;
00634 return SCARD_S_SUCCESS;
00635 }
00636
00637 if (*pcchReaderLen < dwReaderLen)
00638 {
00639 *pcchReaderLen = dwReaderLen;
00640 *pcbAtrLen = 0;
00641 *pdwState = 0;
00642 *pdwProtocol = 0;
00643 return SCARD_E_INSUFFICIENT_BUFFER;
00644 }
00645
00646 *pcchReaderLen = dwReaderLen;
00647 strcpy(mszReaderNames,
00648 psReaderMap[psChannelMap[retIndice].ReaderIndice].ReaderName);
00649 *pdwProtocol = SCARD_PROTOCOL_T0;
00650
00651 SCardEventLock();
00652 if (!(psReaderMap[psChannelMap[retIndice].ReaderIndice].
00653 dwCurrentState & SCARD_STATE_PRESENT))
00654 {
00655 *pdwState = SCARD_ABSENT;
00656 SCardEventUnlock();
00657 return SCARD_S_SUCCESS;
00658 }
00659
00660 *pdwState = SCARD_NEGOTIABLE | SCARD_POWERED | SCARD_PRESENT;
00661 rv = PCSC_SCF_getATR(SCF_hCard, pbAtr, pcbAtrLen);
00662 if (SCARD_S_SUCCESS == rv)
00663 {
00664
00665 psReaderMap[psChannelMap[retIndice].ReaderIndice].dwAtrLength =
00666 *pcbAtrLen;
00667 memcpy(psReaderMap[psChannelMap[retIndice].ReaderIndice].bAtr, pbAtr,
00668 *pcbAtrLen);
00669 }
00670
00671 SCardEventUnlock();
00672 return SCARD_S_SUCCESS;
00673 }
00674
00675 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames,
00676 LPDWORD pcchReaderLen, LPDWORD pdwState,
00677 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
00678 {
00679 long rv;
00680
00681 SCardLockThread();
00682 rv = SCardStatusTH(hCard, mszReaderNames, pcchReaderLen, pdwState,
00683 pdwProtocol, pbAtr, pcbAtrLen);
00684 SCardUnlockThread();
00685 return rv;
00686 }
00687
00688 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
00689 LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
00690 {
00691
00692 LONG rv, retIndice, readerIndice;
00693 PSCARD_READERSTATE_A currReader;
00694 PREADER_STATE rContext;
00695 LPSTR lpcReaderName;
00696 DWORD dwTime;
00697 DWORD dwState;
00698 DWORD dwBreakFlag;
00699 int i, j;
00700
00701 if (SCARD_S_SUCCESS != isOCFServerRunning())
00702 return SCARD_E_NO_SERVICE;
00703
00704
00705 rv = 0;
00706 rContext = 0;
00707 lpcReaderName = 0;
00708 dwTime = 0;
00709 j = 0;
00710 dwState = 0;
00711 i = 0;
00712 currReader = 0;
00713 retIndice = 0;
00714 readerIndice = 0;
00715 dwBreakFlag = 0;
00716
00717 if (rgReaderStates == NULL && cReaders > 0)
00718 return SCARD_E_INVALID_PARAMETER;
00719
00720 if (cReaders < 0)
00721 return SCARD_E_INVALID_VALUE;
00722
00723
00724 SCardLockThread();
00725 retIndice = SCardGetContextIndice(hContext);
00726
00727 SCardUnlockThread();
00728 if (retIndice == -1)
00729 return SCARD_E_INVALID_HANDLE;
00730
00731
00732
00733
00734 if (cReaders == 0)
00735 {
00736 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00737 {
00738 if (psReaderMap[i].ReaderName)
00739 return SCARD_S_SUCCESS;
00740 }
00741 return SCARD_E_READER_UNAVAILABLE;
00742 }
00743 else if (cReaders > PCSCLITE_MAX_READERS_CONTEXTS)
00744 {
00745 return SCARD_E_INVALID_VALUE;
00746 }
00747
00748 for (j = 0; j < cReaders; j++)
00749 {
00750 currReader = &rgReaderStates[j];
00751 if (currReader->szReader == NULL)
00752 {
00753 return SCARD_E_INVALID_VALUE;
00754 }
00755 }
00756
00757
00758
00759 for (j = 0; j < cReaders; j++)
00760 {
00761 currReader = &rgReaderStates[j];
00762 currReader->dwEventState = 0;
00763 }
00764
00765
00766
00767 psContextMap[retIndice].contextBlockStatus = BLOCK_STATUS_BLOCKING;
00768 j = 0;
00769
00770 do
00771 {
00772 SYS_USleep(10);
00773 if (SCARD_S_SUCCESS != isOCFServerRunning())
00774 return SCARD_E_NO_SERVICE;
00775
00776 currReader = &rgReaderStates[j];
00777
00778
00779
00780 if (currReader->dwCurrentState & SCARD_STATE_IGNORE)
00781 {
00782 currReader->dwEventState = SCARD_STATE_IGNORE;
00783 }
00784 else
00785 {
00786
00787
00788 lpcReaderName = (char *) currReader->szReader;
00789
00790 readerIndice = SCardGetReaderIndice(lpcReaderName);
00791
00792 if (0 > readerIndice)
00793 {
00794 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
00795 {
00796 currReader->dwEventState = SCARD_STATE_UNKNOWN;
00797 }
00798 else
00799 {
00800 currReader->dwEventState =
00801 SCARD_STATE_UNKNOWN | SCARD_STATE_CHANGED;
00802
00803
00804 dwBreakFlag = 1;
00805 }
00806 }
00807 else
00808 {
00809
00810 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
00811 {
00812 currReader->dwEventState |= SCARD_STATE_CHANGED;
00813 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
00814 dwBreakFlag = 1;
00815 }
00816
00817
00818 SCardEventLock();
00819
00820 dwState = psReaderMap[readerIndice].dwCurrentState;
00821
00822
00823 if (dwState & SCARD_STATE_UNKNOWN)
00824 {
00825
00826 if (currReader->dwCurrentState & SCARD_STATE_UNAVAILABLE)
00827 {
00828 currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
00829 }
00830 else
00831 {
00832
00833 currReader->dwEventState = SCARD_STATE_CHANGED |
00834 SCARD_STATE_UNAVAILABLE;
00835 dwBreakFlag = 1;
00836 }
00837 }
00838 else
00839 {
00840
00841 if (currReader->dwCurrentState & SCARD_STATE_UNAVAILABLE)
00842 {
00843 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
00844 currReader->dwEventState |= SCARD_STATE_CHANGED;
00845 dwBreakFlag = 1;
00846 }
00847 }
00848
00849
00850
00851 if (dwState & SCARD_STATE_PRESENT)
00852 {
00853 currReader->cbAtr = psReaderMap[readerIndice].dwAtrLength;
00854 memcpy(currReader->rgbAtr, psReaderMap[readerIndice].bAtr,
00855 currReader->cbAtr);
00856 }
00857 else
00858 {
00859 currReader->cbAtr = 0;
00860 }
00861
00862 if (dwState & SCARD_STATE_EMPTY)
00863 {
00864 currReader->dwEventState |= SCARD_STATE_EMPTY;
00865 currReader->dwEventState &= ~SCARD_STATE_PRESENT;
00866 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
00867 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
00868 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
00869 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
00870 currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
00871 currReader->dwEventState &= ~SCARD_STATE_MUTE;
00872 currReader->dwEventState &= ~SCARD_STATE_INUSE;
00873
00874 if (currReader->dwCurrentState & SCARD_STATE_PRESENT ||
00875 currReader->dwCurrentState & SCARD_STATE_ATRMATCH ||
00876 currReader->dwCurrentState & SCARD_STATE_EXCLUSIVE ||
00877 currReader->dwCurrentState & SCARD_STATE_INUSE)
00878 {
00879 currReader->dwEventState |= SCARD_STATE_CHANGED;
00880 dwBreakFlag = 1;
00881 }
00882
00883 }
00884 else if (dwState & SCARD_STATE_PRESENT)
00885 {
00886 currReader->dwEventState |= SCARD_STATE_PRESENT;
00887 currReader->dwEventState &= ~SCARD_STATE_EMPTY;
00888 currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
00889 currReader->dwEventState &= ~SCARD_STATE_IGNORE;
00890 currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
00891 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
00892 currReader->dwEventState &= ~SCARD_STATE_MUTE;
00893
00894 if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
00895 {
00896 currReader->dwEventState |= SCARD_STATE_CHANGED;
00897 dwBreakFlag = 1;
00898 }
00899
00900 if (0 && dwState & SCARD_SWALLOWED)
00901 {
00902 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
00903 {
00904 currReader->dwEventState |= SCARD_STATE_MUTE;
00905 }
00906 else
00907 {
00908 currReader->dwEventState |= SCARD_STATE_MUTE;
00909 if (currReader->dwCurrentState !=
00910 SCARD_STATE_UNAWARE)
00911 {
00912 currReader->dwEventState |=
00913 SCARD_STATE_CHANGED;
00914 }
00915 dwBreakFlag = 1;
00916 }
00917 }
00918 else
00919 {
00920
00921 if (currReader->dwCurrentState & SCARD_STATE_MUTE)
00922 {
00923 currReader->dwEventState |= SCARD_STATE_CHANGED;
00924 dwBreakFlag = 1;
00925 }
00926 }
00927 }
00928
00929 if (-1 == psReaderMap[readerIndice].SharedRefCount)
00930 {
00931 currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
00932 currReader->dwEventState &= ~SCARD_STATE_INUSE;
00933 if (!currReader->dwCurrentState & SCARD_STATE_EXCLUSIVE)
00934 {
00935 currReader->dwEventState |= SCARD_STATE_CHANGED;
00936 dwBreakFlag = 1;
00937 }
00938 }
00939 else if (psReaderMap[readerIndice].SharedRefCount >= 1)
00940 {
00941
00942 if (dwState & SCARD_STATE_PRESENT)
00943 {
00944 currReader->dwEventState |= SCARD_STATE_INUSE;
00945 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
00946 if (!currReader->dwCurrentState & SCARD_STATE_INUSE)
00947 {
00948 currReader->dwEventState |= SCARD_STATE_CHANGED;
00949 dwBreakFlag = 1;
00950 }
00951 }
00952 }
00953 SCardEventUnlock();
00954 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
00955 {
00956
00957
00958 dwBreakFlag = 1;
00959 }
00960 SYS_USleep(PCSCLITE_STATUS_WAIT);
00961
00962 }
00963
00964 }
00965
00966
00967 j = j + 1;
00968 if (j == cReaders)
00969 j = 0;
00970
00971 if (dwTimeout != INFINITE && dwTimeout != 0)
00972 {
00973 dwTime += PCSCLITE_STATUS_WAIT;
00974
00975
00976
00977
00978 if ((dwTime >= (dwTimeout * 1000)) && (j == 0))
00979 {
00980 return SCARD_E_TIMEOUT;
00981 }
00982 }
00983
00984
00985
00986 if (psContextMap[retIndice].contextBlockStatus == BLOCK_STATUS_RESUME)
00987 break;
00988
00989
00990 if ((dwBreakFlag == 1) && (j == 0))
00991 break;
00992
00993
00994
00995
00996
00997
00998 if ((dwTimeout == 0) && (j == 0))
00999 break;
01000
01001 }
01002 while (1);
01003
01004 if (psContextMap[retIndice].contextBlockStatus == BLOCK_STATUS_RESUME)
01005 {
01006 return SCARD_E_CANCELLED;
01007 }
01008
01009 return SCARD_S_SUCCESS;
01010 }
01011
01012
01013 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
01014 DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
01015 LPDWORD lpBytesReturned)
01016 {
01017
01018 return SCARD_S_SUCCESS;
01019 }
01020
01021 static LONG SCardTransmitTH(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
01022 LPCBYTE pbSendBuffer, DWORD cbSendLength,
01023 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
01024 {
01025 BYTE Buffer[MAX_BUFFER_SIZE];
01026 LONG rv = 0;
01027 SCF_Card_t SCF_hCard;
01028 SCF_Status_t status;
01029 LONG retIndice;
01030 LONG localRecvLen = MAX_BUFFER_SIZE;
01031 if (SCARD_S_SUCCESS != isOCFServerRunning())
01032 return SCARD_E_NO_SERVICE;
01033 if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
01034 pcbRecvLength == NULL || pioSendPci == NULL)
01035 {
01036 return SCARD_E_INVALID_PARAMETER;
01037 }
01038
01039 rv = getCardForHandle(hCard, &SCF_hCard);
01040 if (rv != SCARD_S_SUCCESS)
01041 return rv;
01042
01043 if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength < 2))
01044 return SCARD_E_INSUFFICIENT_BUFFER;
01045
01046
01047
01048 retIndice = SCardGetHandleIndice(hCard);
01049 if ((pbSendBuffer[1] == 0xC0) &&
01050 psTransmitMap[retIndice].isResponseCached)
01051 {
01052 if (*pcbRecvLength < psTransmitMap[retIndice].bufferLength)
01053 {
01054 *pcbRecvLength = psTransmitMap[retIndice].bufferLength;
01055 return SCARD_E_INSUFFICIENT_BUFFER;
01056 }
01057 *pcbRecvLength = psTransmitMap[retIndice].bufferLength;
01058 memcpy(pbRecvBuffer, psTransmitMap[retIndice].Buffer,
01059 psTransmitMap[retIndice].bufferLength);
01060 if (pioRecvPci && pioSendPci)
01061 pioRecvPci->dwProtocol = pioSendPci->dwProtocol;
01062 return SCARD_S_SUCCESS;
01063 }
01064 else
01065 {
01066 psTransmitMap[retIndice].isResponseCached = 0;
01067 }
01068
01069 status = SCF_Card_exchangeAPDU(SCF_hCard,
01070 (const uint8_t *) pbSendBuffer, (size_t) cbSendLength,
01071 (uint8_t *) Buffer, (size_t *) & localRecvLen);
01072 if ((cbSendLength > 5) && (localRecvLen > 2))
01073 {
01074 if (SCF_STATUS_SUCCESS == status)
01075 {
01076 *pcbRecvLength = 2;
01077 pbRecvBuffer[0] = 0x61;
01078 pbRecvBuffer[1] = localRecvLen - 2;
01079 psTransmitMap[retIndice].isResponseCached = TRUE;
01080 psTransmitMap[retIndice].bufferLength = localRecvLen;
01081 memcpy(psTransmitMap[retIndice].Buffer, Buffer,
01082 psTransmitMap[retIndice].bufferLength);
01083 if (pioRecvPci && pioSendPci)
01084 pioRecvPci->dwProtocol = pioSendPci->dwProtocol;
01085 return SCARD_S_SUCCESS;
01086 }
01087 }
01088 else
01089 {
01090 if (SCF_STATUS_SUCCESS == status)
01091 {
01092 if (*pcbRecvLength < localRecvLen)
01093 {
01094 *pcbRecvLength = localRecvLen;
01095 return SCARD_E_INSUFFICIENT_BUFFER;
01096 }
01097 *pcbRecvLength = localRecvLen;
01098 memcpy(pbRecvBuffer, Buffer, *pcbRecvLength);
01099 }
01100 }
01101
01102
01103
01104 if (pioRecvPci && pioSendPci)
01105 pioRecvPci->dwProtocol = pioSendPci->dwProtocol;
01106
01107 rv = ConvertStatus(status);
01108 return rv;
01109 }
01110
01111 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
01112 LPCBYTE pbSendBuffer, DWORD cbSendLength,
01113 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
01114 {
01115 long rv;
01116
01117 SCardLockThread();
01118 rv = SCardTransmitTH(hCard, pioSendPci, pbSendBuffer, cbSendLength,
01119 pioRecvPci, pbRecvBuffer, pcbRecvLength);
01120 SCardUnlockThread();
01121
01122 return rv;
01123 }
01124
01125
01126 static LONG SCardListReaderGroupsTH(SCARDCONTEXT hContext, LPSTR mszGroups,
01127 LPDWORD pcchGroups)
01128 {
01129 LONG rv = SCARD_S_SUCCESS;
01130 const char ReaderGroup[] = "SCard$DefaultReaders";
01131 const int dwGroups = strlen(ReaderGroup) + 2;
01132 if (SCARD_S_SUCCESS != isOCFServerRunning())
01133 return SCARD_E_NO_SERVICE;
01134
01135 if (SCardGetContextIndice(hContext) == -1)
01136 {
01137 return SCARD_E_INVALID_HANDLE;
01138 }
01139 if (mszGroups)
01140 {
01141
01142 if (*pcchGroups < dwGroups)
01143 rv = SCARD_E_INSUFFICIENT_BUFFER;
01144 else
01145 {
01146 memset(mszGroups, 0, dwGroups);
01147 memcpy(mszGroups, ReaderGroup, strlen(ReaderGroup));
01148 }
01149 }
01150
01151 *pcchGroups = dwGroups;
01152
01153 return rv;
01154 }
01155
01156 LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
01157 LPDWORD pcchGroups)
01158 {
01159 long rv;
01160
01161 SCardLockThread();
01162 rv = SCardListReaderGroupsTH(hContext, mszGroups, pcchGroups);
01163 SCardUnlockThread();
01164
01165 return rv;
01166 }
01167
01168 static LONG SCardCancelTH(SCARDCONTEXT hContext)
01169 {
01170 LONG hContextIndice;
01171 if (SCARD_S_SUCCESS != isOCFServerRunning())
01172 return SCARD_E_NO_SERVICE;
01173
01174 hContextIndice = SCardGetContextIndice(hContext);
01175
01176 if (hContextIndice == -1)
01177 return SCARD_E_INVALID_HANDLE;
01178
01179
01180 psContextMap[hContextIndice].contextBlockStatus = BLOCK_STATUS_RESUME;
01181
01182 return SCARD_S_SUCCESS;
01183 }
01184
01185 LONG SCardCancel(SCARDCONTEXT hContext)
01186 {
01187 long rv;
01188
01189 SCardLockThread();
01190 rv = SCardCancelTH(hContext);
01191 SCardUnlockThread();
01192
01193 return rv;
01194 }
01195
01196 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
01197 LPDWORD pcbAttrLen)
01198 {
01199 return SCARD_E_NOT_TRANSACTED;
01200 }
01201
01202 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
01203 DWORD cbAttrLen)
01204 {
01205 return SCARD_E_NOT_TRANSACTED;
01206 }
01207
01208 static LONG SCardGetHandleIndice(SCARDHANDLE hCard)
01209 {
01210 int i = 0;
01211 static int LastIndex = 0;
01212
01213 if (hCard == 0)
01214 return -1;
01215 if (psChannelMap[LastIndex].PCSC_hCard == hCard)
01216 return LastIndex;
01217
01218 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01219 {
01220 if (hCard == psChannelMap[i].PCSC_hCard)
01221 return i;
01222 }
01223
01224 return -1;
01225 }
01226 static LONG SCardGetReaderIndice(LPCSTR ReaderName)
01227 {
01228 int i = 0;
01229
01230 if (NULL == ReaderName)
01231 return -1;
01232
01233 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01234 {
01235 if ((NULL != psReaderMap[i].ReaderName) &&
01236 (strncmp(psReaderMap[i].ReaderName, ReaderName,
01237 strlen(psReaderMap[i].ReaderName)) == 0))
01238 {
01239 return i;
01240 }
01241 }
01242
01243 return -1;
01244 }
01245
01246 static LONG SCardAddHandle(SCARDHANDLE PCSC_hCard, SCARDCONTEXT hContext,
01247 SCF_Session_t hSession, SCF_Terminal_t hTerminal,
01248 SCF_Card_t SCF_hCard, int ReaderIndice, DWORD dwShareMode)
01249 {
01250 int i = 0;
01251
01252 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01253 {
01254 if (psChannelMap[i].PCSC_hCard == 0)
01255 {
01256 psChannelMap[i].PCSC_hCard = PCSC_hCard;
01257 psChannelMap[i].hContext = hContext;
01258 psChannelMap[i].hSession = hSession;
01259 psChannelMap[i].hTerminal = hTerminal;
01260 psChannelMap[i].SCF_hCard = SCF_hCard;
01261 psChannelMap[i].ReaderIndice = ReaderIndice;
01262 SCardEventLock();
01263 if (SCA