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 (SCARD_SHARE_EXCLUSIVE == dwShareMode)
01264 {
01265 psChannelMap[i].haveLock = TRUE;
01266 psReaderMap[ReaderIndice].SharedRefCount = -1;
01267 }
01268 else
01269 {
01270 psReaderMap[ReaderIndice].SharedRefCount++;
01271 psReaderMap[ReaderIndice].dwCurrentState |= SCARD_STATE_INUSE;
01272 }
01273 PCSC_SCF_getATR(SCF_hCard, psReaderMap[ReaderIndice].bAtr,
01274 &psReaderMap[ReaderIndice].dwAtrLength);
01275 SCardEventUnlock();
01276 return SCARD_S_SUCCESS;
01277 }
01278 }
01279 return SCARD_E_NO_MEMORY;
01280 }
01281
01282 static LONG PCSC_SCF_getATR(SCF_Card_t hCard, LPBYTE pcbAtr,
01283 LPDWORD pcbAtrLen)
01284 {
01285 SCF_Status_t status;
01286
01287 struct SCF_BinaryData_t *pAtr;
01288
01289 status = SCF_Card_getInfo(hCard, "atr", &pAtr);
01290 if (SCF_STATUS_SUCCESS != status)
01291 return SCARD_F_COMM_ERROR;
01292
01293 if ((NULL == pcbAtr) || (NULL == pcbAtrLen) ||
01294 (MAX_ATR_SIZE < pAtr->length))
01295 {
01296 if (NULL != pcbAtrLen)
01297 *pcbAtrLen = pAtr->length;
01298 SCF_Card_freeInfo(hCard, pAtr);
01299 return SCARD_E_INSUFFICIENT_BUFFER;
01300 }
01301
01302 *pcbAtrLen = pAtr->length;
01303
01304 memcpy(pcbAtr, pAtr->data, pAtr->length);
01305
01306 SCF_Card_freeInfo(hCard, pAtr);
01307 return SCARD_S_SUCCESS;
01308 }
01309
01310 static LONG SCardRemoveHandle(SCARDHANDLE hCard)
01311 {
01312 LONG retIndice = 0;
01313
01314 retIndice = SCardGetHandleIndice(hCard);
01315
01316 if (retIndice == -1)
01317 {
01318 return SCARD_E_INVALID_HANDLE;
01319 }
01320 SCardEventLock();
01321 SCF_Session_close(psChannelMap[retIndice].hSession);
01322 psChannelMap[retIndice].PCSC_hCard = 0;
01323 psChannelMap[retIndice].hContext = 0;
01324 psChannelMap[retIndice].hSession = NULL;
01325 psChannelMap[retIndice].hTerminal = NULL;
01326 psChannelMap[retIndice].SCF_hCard = NULL;
01327 psChannelMap[retIndice].isReset = 0;
01328 if (psChannelMap[retIndice].haveLock)
01329 {
01330 psChannelMap[retIndice].haveLock = FALSE;
01331 psReaderMap[psChannelMap[retIndice].ReaderIndice].SharedRefCount = 0;
01332 }
01333 else
01334 {
01335 psReaderMap[psChannelMap[retIndice].ReaderIndice].SharedRefCount--;
01336 if (0 >=
01337 psReaderMap[psChannelMap[retIndice].ReaderIndice].SharedRefCount)
01338 {
01339 psReaderMap[psChannelMap[retIndice].ReaderIndice].SharedRefCount =
01340 0;
01341 psReaderMap[psChannelMap[retIndice].ReaderIndice].
01342 dwCurrentState &=
01343 (~(SCARD_STATE_EXCLUSIVE | SCARD_STATE_INUSE));
01344 }
01345 }
01346
01347 psChannelMap[retIndice].ReaderIndice = 0;
01348 SCardEventUnlock();
01349 return SCARD_S_SUCCESS;
01350 }
01351
01352
01353 static LONG getCardForHandle(SCARDHANDLE PCSC_hCard, SCF_Card_t * SCF_hCard)
01354 {
01355 int retIndice = 0;
01356
01357 retIndice = SCardGetHandleIndice(PCSC_hCard);
01358 if (0 > retIndice)
01359 return SCARD_E_INVALID_HANDLE;
01360
01361 *SCF_hCard = psChannelMap[retIndice].SCF_hCard;
01362 if (NULL == *SCF_hCard)
01363 return SCARD_E_INVALID_HANDLE;
01364 SCardEventLock();
01365 if (psChannelMap[retIndice].isReset)
01366 {
01367 SCardEventUnlock();
01368 return SCARD_W_RESET_CARD;
01369 }
01370 SCardEventUnlock();
01371
01372 return SCARD_S_SUCCESS;
01373
01374 }
01375
01376 static LONG getNewHandle(SCARDCONTEXT hContext, LPCSTR szReader,
01377 SCARDHANDLE * phCard, DWORD dwShareMode)
01378 {
01379 long rv = 0, ReaderIndice;
01380 SCF_Status_t status;
01381 SCF_Session_t hSession;
01382 SCF_Terminal_t hTerminal;
01383 SCF_Card_t SCF_hCard;
01384
01385 ReaderIndice = SCardGetReaderIndice(szReader);
01386 if (-1 == ReaderIndice)
01387 return SCARD_E_UNKNOWN_READER;
01388
01389 SCardEventLock();
01390 if ((psReaderMap[ReaderIndice].SharedRefCount == -1) ||
01391 ((SCARD_SHARE_EXCLUSIVE == dwShareMode) &&
01392 psReaderMap[ReaderIndice].SharedRefCount))
01393 {
01394 SCardEventUnlock();
01395 return SCARD_E_SHARING_VIOLATION;
01396 }
01397 SCardEventUnlock();
01398
01399 status = SCF_Session_getSession(&hSession);
01400 if (SCF_STATUS_SUCCESS != status)
01401 {
01402 return ConvertStatus(status);
01403 }
01404 status = SCF_Session_getTerminal(hSession, szReader, &hTerminal);
01405 if (SCF_STATUS_SUCCESS != status)
01406 {
01407 SCF_Session_close(hSession);
01408 return ConvertStatus(status);
01409 }
01410 status = SCF_Terminal_getCard(hTerminal, &SCF_hCard);
01411 if (SCF_STATUS_SUCCESS != status)
01412 {
01413 SCF_Session_close(hSession);
01414 return ConvertStatus(status);
01415 }
01416
01417 if (SCARD_SHARE_EXCLUSIVE == dwShareMode)
01418 {
01419 status = SCF_Card_lock(SCF_hCard, 0);
01420 if (status != SCF_STATUS_SUCCESS)
01421 {
01422 SCF_Session_close(hSession);
01423 return SCARD_E_SHARING_VIOLATION;
01424 }
01425 }
01426
01427 while (1)
01428 {
01429 *phCard = (PCSCLITE_SVC_IDENTITY + SYS_RandomInt(1, 65535));
01430 if (SCardGetHandleIndice(*phCard) == -1)
01431 break;
01432 }
01433 rv = SCardAddHandle(*phCard, hContext, hSession,
01434 hTerminal, SCF_hCard, ReaderIndice, dwShareMode);
01435 if (SCARD_S_SUCCESS != rv)
01436 {
01437 SCF_Session_close(hSession);
01438 return rv;
01439 }
01440
01441 return SCARD_S_SUCCESS;
01442 }
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457 static LONG getNewContext(SCARDCONTEXT * phContext)
01458 {
01459 LONG rv;
01460 SCF_Session_t hSession = NULL;
01461 SCF_Status_t status;
01462
01463 status = SCF_Session_getSession(&hSession);
01464 if (status != SCF_STATUS_SUCCESS)
01465 return SCARD_E_NO_SERVICE;
01466
01467 while (1)
01468 {
01469 *phContext = (PCSCLITE_SVC_IDENTITY + SYS_RandomInt(1, 65535));
01470 if (-1 == SCardGetContextIndice(*phContext))
01471 break;
01472 }
01473
01474 rv = SCardAddContext(*phContext, hSession);
01475 if (SCARD_S_SUCCESS != rv)
01476 {
01477 SCF_Session_close(hSession);
01478 }
01479
01480 return rv;
01481 }
01482
01483 static LONG SCardAddContext(SCARDCONTEXT hContext, SCF_Session_t hSession)
01484 {
01485 int i;
01486
01487 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01488 {
01489 if (psContextMap[i].hContext == 0)
01490 {
01491 psContextMap[i].hContext = hContext;
01492 psContextMap[i].hSession = hSession;
01493 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
01494 return SCARD_S_SUCCESS;
01495 }
01496 }
01497
01498 return SCARD_E_NO_MEMORY;
01499 }
01500
01501 static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
01502 {
01503 int i;
01504
01505
01506 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01507 {
01508 if ((hContext == psContextMap[i].hContext) && (hContext != 0))
01509 {
01510 return i;
01511 }
01512 }
01513
01514 return -1;
01515 }
01516
01517 static LONG SCardRemoveContext(SCARDCONTEXT hContext)
01518 {
01519 LONG retIndice;
01520 int i = 0;
01521 retIndice = 0;
01522
01523 retIndice = SCardGetContextIndice(hContext);
01524
01525 if (retIndice == -1)
01526 {
01527 return SCARD_E_INVALID_HANDLE;
01528 }
01529 else
01530 {
01531
01532 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01533 {
01534 if (psChannelMap[i].hContext == hContext)
01535 {
01536 SCardRemoveHandle(psChannelMap[i].PCSC_hCard);
01537 }
01538 }
01539 SCF_Session_close(psContextMap[retIndice].hSession);
01540 psContextMap[retIndice].hContext = 0;
01541 psContextMap[retIndice].hSession = NULL;
01542 psContextMap[retIndice].contextBlockStatus = BLOCK_STATUS_RESUME;
01543 }
01544
01545 return SCARD_S_SUCCESS;
01546 }
01547
01548 static SCF_Session_t getSessionForContext(SCARDCONTEXT hContext)
01549 {
01550 LONG retIndice;
01551 retIndice = 0;
01552
01553 retIndice = SCardGetContextIndice(hContext);
01554
01555 if (retIndice == -1)
01556 return NULL;
01557
01558 return (psContextMap[retIndice].hSession);
01559 }
01560
01561
01562
01563
01564
01565
01566 LONG SCardLockThread(void)
01567 {
01568 return SYS_MutexLock(&clientMutex);
01569 }
01570
01571 LONG SCardEventLock(void)
01572 {
01573 return SYS_MutexLock(&EventMutex);
01574 }
01575
01576
01577
01578
01579
01580 LONG SCardUnlockThread(void)
01581 {
01582 return SYS_MutexUnLock(&clientMutex);
01583 }
01584
01585 LONG SCardEventUnlock(void)
01586 {
01587 return SYS_MutexUnLock(&EventMutex);
01588 }
01589
01590 static LONG isActiveContextPresent(void)
01591 {
01592 long fActiveContext = FALSE;
01593 int i;
01594
01595 for (i=0; i<PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01596 {
01597 if (psContextMap[i].hContext != 0)
01598 {
01599 fActiveContext = TRUE;
01600 break;
01601 }
01602 }
01603 return fActiveContext;
01604 }
01605
01606 static void EventCallback(SCF_Event_t eventType, SCF_Terminal_t hTerm,
01607 void *cbdata)
01608 {
01609 static char bInitialized = 0;
01610 int i = 0;
01611 int ReaderIndice = 0;
01612 SCF_Card_t hCard;
01613
01614 SCF_Status_t status;
01615
01616 #if 0
01617 struct _psReaderMap *readerMap;
01618 readerMap = (struct _psReaderMap *) cbdata;
01619 #endif
01620
01621 ReaderIndice = (int) cbdata;
01622 SCardEventLock();
01623 switch (eventType)
01624 {
01625 case SCF_EVENT_CARDINSERTED:
01626 case SCF_EVENT_CARDPRESENT:
01627 #if 0
01628 printf("card present dwState = %x\n",
01629 psReaderMap[ReaderIndice].dwCurrentState);
01630 #endif
01631 psReaderMap[ReaderIndice].dwCurrentState &=
01632 (~(SCARD_STATE_UNKNOWN | SCARD_STATE_UNAVAILABLE |
01633 SCARD_STATE_EMPTY));
01634 psReaderMap[ReaderIndice].dwCurrentState |= SCARD_STATE_PRESENT;
01635 #if 0
01636 printf("card present post dwState = %x\n",
01637 psReaderMap[ReaderIndice].dwCurrentState);
01638 #endif
01639
01640 status = SCF_Terminal_getCard(psReaderMap[ReaderIndice].hTerminal,
01641 &hCard);
01642 if (SCF_STATUS_SUCCESS == status)
01643 {
01644 #if 0
01645 printf("Setting ATR...\n");
01646 #endif
01647 PCSC_SCF_getATR(hCard, psReaderMap[ReaderIndice].bAtr,
01648 &psReaderMap[ReaderIndice].dwAtrLength);
01649 #if 0
01650 printf("Atrlen = %d\n", psReaderMap[ReaderIndice].dwAtrLength);
01651 #endif
01652 }
01653 SCF_Card_close(hCard);
01654 break;
01655 case SCF_EVENT_CARDREMOVED:
01656 case SCF_EVENT_CARDABSENT:
01657 #if 0
01658 printf("card absent dwState = %x\n",
01659 psReaderMap[ReaderIndice].dwCurrentState);
01660 #endif
01661 psReaderMap[ReaderIndice].dwCurrentState &= (~(SCARD_STATE_PRESENT |
01662 SCARD_STATE_EXCLUSIVE |
01663 SCARD_STATE_INUSE |
01664 SCARD_STATE_MUTE | SCARD_STATE_UNAVAILABLE));
01665 psReaderMap[ReaderIndice].dwCurrentState |= SCARD_STATE_EMPTY;
01666 psReaderMap[ReaderIndice].SharedRefCount = 0;
01667 psReaderMap[ReaderIndice].dwAtrLength = 0;
01668 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01669 {
01670 if ((0 != psChannelMap[i].PCSC_hCard) &&
01671 (psChannelMap[i].ReaderIndice == ReaderIndice))
01672 {
01673 psChannelMap[i].haveLock = FALSE;
01674 }
01675 }
01676 #if 0
01677 printf("card absent dwState = %x\n",
01678 psReaderMap[ReaderIndice].dwCurrentState);
01679 #endif
01680 break;
01681 case SCF_EVENT_TERMINALCLOSED:
01682
01683 break;
01684 case SCF_EVENT_CARDRESET:
01685 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01686 {
01687 if ((0 != psChannelMap[i].PCSC_hCard) &&
01688 (psChannelMap[i].ReaderIndice == ReaderIndice))
01689 {
01690 psChannelMap[i].isReset = TRUE;
01691 }
01692 }
01693 break;
01694 default:
01695 break;
01696 }
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707 if (bInitialized < 2)
01708 {
01709 bInitialized++;
01710 if (2 == bInitialized)
01711 pthread_cond_signal(&EventCondition);
01712 }
01713
01714 SCardEventUnlock();
01715 }
01716
01717
01718 static LONG isOCFServerRunning(void)
01719 {
01720 static int isRunning = TRUE;
01721 SCF_Status_t status;
01722 SCF_Session_t hSession;
01723
01724 if (FALSE == isRunning)
01725 return SCARD_E_NO_SERVICE;
01726
01727 status = SCF_Session_getSession(&hSession);
01728 if (SCF_STATUS_SUCCESS != status)
01729 {
01730 isRunning = FALSE;
01731 return SCARD_E_NO_SERVICE;
01732 }
01733 SCF_Session_close(hSession);
01734
01735 return SCARD_S_SUCCESS;
01736 }
01737
01738 static LONG PCSC_SCF_Initialize(void)
01739 {
01740 SCF_Status_t status;
01741 char **tList = NULL;
01742 int i;
01743
01744 if (PCSC_Initialized)
01745 return SCARD_S_SUCCESS;
01746 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01747 {
01748 psContextMap[i].hContext = 0;
01749 psContextMap[i].hSession = 0;
01750 psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
01751 psChannelMap[i].PCSC_hCard = 0;
01752 psChannelMap[i].SCF_hCard = 0;
01753 psChannelMap[i].hTerminal = 0;
01754 psChannelMap[i].hContext = 0;
01755 psChannelMap[i].hSession = 0;
01756 psChannelMap[i].haveLock = 0;
01757 psChannelMap[i].isReset = 0;
01758 psChannelMap[i].ReaderIndice = 0;
01759 psTransmitMap[i].isResponseCached = 0;
01760 psTransmitMap[i].bufferLength = 0;
01761 }
01762 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01763 {
01764 psReaderMap[i].ReaderName = NULL;
01765 psReaderMap[i].hTerminal = 0;
01766 psReaderMap[i].SharedRefCount = 0;
01767 psReaderMap[i].dwCurrentState |= SCARD_STATE_UNAVAILABLE;
01768 psReaderMap[i].dwAtrLength = 0;
01769 memset(psReaderMap[i].bAtr, 0, MAX_ATR_SIZE);
01770 psReaderMap[i].lHandle = NULL;
01771 }
01772
01773 status = SCF_Session_getSession(&g_hSession);
01774 if (status != SCF_STATUS_SUCCESS)
01775 return SCARD_E_NO_SERVICE;
01776 status = SCF_Session_getInfo(g_hSession, "terminalnames", &tList);
01777 if (status != SCF_STATUS_SUCCESS)
01778 return SCARD_E_NO_SERVICE;
01779
01780 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01781 {
01782 if (NULL == tList[i])
01783 break;
01784 psReaderMap[i].ReaderName = strdup(tList[i]);
01785 status =
01786 SCF_Session_getTerminal(g_hSession, psReaderMap[i].ReaderName,
01787 &psReaderMap[i].hTerminal);
01788 if (status != SCF_STATUS_SUCCESS)
01789 continue;
01790 status =
01791 SCF_Terminal_addEventListener(psReaderMap[i].hTerminal,
01792 SCF_EVENT_ALL, EventCallback, (void *) i,
01793 &psReaderMap[i].lHandle);
01794 if (status != SCF_STATUS_SUCCESS)
01795 {
01796 SCF_Terminal_close(psReaderMap[i].hTerminal);
01797 psReaderMap[i].hTerminal = NULL;
01798 }
01799 }
01800 SCF_Session_freeInfo(g_hSession, tList);
01801
01802 SYS_MutexLock(&SCFInitMutex);
01803
01804 {
01805 struct timeval currTime;
01806 struct timespec absTime;
01807
01808 gettimeofday(&currTime, NULL);
01809
01810
01811 absTime.tv_sec = currTime.tv_sec + 2;
01812 absTime.tv_nsec = currTime.tv_usec*1000;
01813
01814 pthread_cond_timedwait(&EventCondition, &SCFInitMutex, &absTime);
01815 }
01816 SYS_MutexUnLock(&SCFInitMutex);
01817
01818 PCSC_Initialized = 1;
01819 return SCARD_S_SUCCESS;
01820 }
01821
01822 static LONG ConvertStatus(SCF_Status_t status)
01823 {
01824 switch (status)
01825 {
01826 case SCF_STATUS_COMMERROR:
01827 return SCARD_F_COMM_ERROR;
01828 case SCF_STATUS_FAILED:
01829 return SCARD_F_INTERNAL_ERROR;
01830 case SCF_STATUS_BADHANDLE:
01831 return SCARD_E_INVALID_HANDLE;
01832 case SCF_STATUS_UNKNOWNPROPERTY:
01833 return SCARD_F_UNKNOWN_ERROR;
01834 case SCF_STATUS_BADARGS:
01835 return SCARD_E_INVALID_VALUE;
01836 case SCF_STATUS_BADTERMINAL:
01837 return SCARD_E_READER_UNAVAILABLE;
01838 case SCF_STATUS_NOCARD:
01839 return SCARD_E_NO_SMARTCARD;
01840 case SCF_STATUS_CARDREMOVED:
01841 return SCARD_W_REMOVED_CARD;
01842 case SCF_STATUS_TIMEOUT:
01843 return SCARD_E_TIMEOUT;
01844 #if 0
01845 case SCF_STATUS_DOUBLELOCK:
01846
01847 break;
01848 #endif
01849 case SCF_STATUS_CARDLOCKED:
01850 return SCARD_E_SHARING_VIOLATION;
01851 case SCF_STATUS_NOSPACE:
01852 return SCARD_E_NO_MEMORY;
01853 case SCF_STATUS_SUCCESS:
01854 return SCARD_S_SUCCESS;
01855 }
01856 return SCARD_F_UNKNOWN_ERROR;
01857 }
01858
01859
01860
01861
01862 LONG SCardCheckReaderAvailability(LPSTR readerName, LONG errorCode)
01863 {
01864 #if 0
01865 LONG retIndice;
01866 int i;
01867
01868 retIndice = 0;
01869 i = 0;
01870 if (errorCode != SCARD_S_SUCCESS)
01871 {
01872 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
01873 {
01874 if (strcmp(psChannelMap[i].readerName, readerName) == 0)
01875 {
01876 return errorCode;
01877 }
01878 }
01879
01880 return SCARD_E_READER_UNAVAILABLE;
01881
01882 }
01883 else
01884 {
01885 return SCARD_S_SUCCESS;
01886 }
01887 #endif
01888 return 0;
01889 }
01890
01891
01892
01893
01894
01895
01896 void SCardUnload(void)
01897 {
01898 int i=0;
01899 #if 0
01900 if (!isExecuted)
01901 return;
01902
01903 SHMClientCloseSession();
01904 SYS_CloseFile(mapAddr);
01905 isExecuted = 0;
01906 #endif
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921 if((!PCSC_Initialized) || isActiveContextPresent())
01922 return;
01923
01924 for(i=0; i<PCSCLITE_MAX_READERS_CONTEXTS; i++)
01925 if (psReaderMap[i].hTerminal)
01926 {
01927 SCF_Terminal_removeEventListener(psReaderMap[i].hTerminal,
01928 psReaderMap[i].lHandle);
01929
01930 SCF_Terminal_close(psReaderMap[i].hTerminal);
01931
01932 if (psReaderMap[i].ReaderName)
01933 free(psReaderMap[i].ReaderName);
01934 }
01935
01936 SCF_Session_close(g_hSession);
01937 PCSC_Initialized = 0;
01938 }
01939
01940
01941
01942
01943 LONG SCardCheckDaemonAvailability(void)
01944 {
01945 LONG rv = 1;
01946
01947 if (rv == 0)
01948 return SCARD_E_NO_SERVICE;
01949 else
01950 return SCARD_S_SUCCESS;
01951 }
01952