winscard_scf.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 2002
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  *  Najam Siddiqui
00007  * Copyright (C) 2005
00008  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00009  *
00010  * $Id: winscard_scf.c 2896 2008-04-22 09:20:00Z rousseau $
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     /* Zero out everything */
00177 
00178     if (SCARD_S_SUCCESS != isOCFServerRunning())
00179         return SCARD_E_NO_SERVICE;
00180 
00181     rv = 0;
00182 
00183     /* Remove the local context from the stack */
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 /* Check for NULL parameters */
00214     if (pcchReaders == NULL)
00215     {
00216         return SCARD_E_INVALID_PARAMETER;
00217     }
00218     /*Check for Context validity */
00219     retIndice = SCardGetContextIndice(hContext);
00220     if (0 > retIndice)
00221         return SCARD_E_INVALID_HANDLE;
00222 
00223     /*Calculate the the buffer length reuired only once.
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     /*There are no readers available */
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     /*the extra NULL character as per the PCSC specs. */
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 /* by najam */
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     /* Zero out everything   */
00298     rv = 0;
00299 
00300     /* Check for NULL parameters */
00301     if (phCard == NULL || pdwActiveProtocol == NULL)
00302         return SCARD_E_INVALID_PARAMETER;
00303     else
00304         *phCard = 0;
00305 
00306     /* Make sure this context has been opened */
00307     if (SCardGetContextIndice(hContext) == -1)
00308         return SCARD_E_INVALID_HANDLE;
00309 
00310     if (szReader == NULL)
00311         return SCARD_E_UNKNOWN_READER;
00312 
00313     /* Check for uninitialized strings */
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     /* TODO Which Protocols have to be supported */
00332     /* Ignoring protocols for now */
00333     /* Make sure this handle has been opened */
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     /*check ocfserver availibility */
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     /*CHECK HANDLE VALIDITY */
00376     retIndice = SCardGetHandleIndice(hCard);
00377     if ((retIndice == -1) || (NULL == psChannelMap[retIndice].SCF_hCard))
00378         return SCARD_E_INVALID_HANDLE;
00379 
00380     /* TODO Take Care of the Disposition...  */
00381     /* Resetting the card for SCARD_RESET_CARD |
00382        SCARD_UNPOWER_CARD | SCARD_EJECT_CARD */
00383     if (SCARD_LEAVE_CARD != dwDisposition)
00384     {
00385         /*must acquire the lock to reset card */
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             /*a usleep here will allow the RESET_EVENT to be reported and
00393                the Maps to be updated */
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     /* get a new handle */
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     /*set PCSC hCard to old Handle */
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     /* Zero out everything   */
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     /* Zero out everything   */
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     /* TODO Take Care of the Disposition... */
00539     if (SCARD_LEAVE_CARD != dwDisposition)
00540     {
00541         status = SCF_Card_reset(psChannelMap[retIndice].SCF_hCard);
00542         if (SCF_STATUS_SUCCESS == status)
00543         {
00544             /* reset the isReset for this card */
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     /* TODO */
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     /* Zero out everything   */
00598     retIndice = 0;
00599     dwReaderLen = 0;
00600     rv = 0;
00601     i = 0;
00602     /* Check for NULL parameters */
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         /*referesh the Atr in the reader Map */
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     /* Zero out everything */
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     /* change by najam */
00724     SCardLockThread();
00725     retIndice = SCardGetContextIndice(hContext);
00726     /* change by najam */
00727     SCardUnlockThread();
00728     if (retIndice == -1)
00729         return SCARD_E_INVALID_HANDLE;
00730 
00731     /* Application is waiting for a reader -
00732        return the first available reader
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     /* Check the integrity of the reader states structures */
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     /* End of search for readers */
00757 
00758     /* Clear the event state for all readers */
00759     for (j = 0; j < cReaders; j++)
00760     {
00761         currReader = &rgReaderStates[j];
00762         currReader->dwEventState = 0;
00763     }
00764 
00765     /* Now is where we start our event checking loop */
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     /************ Look for IGNORED readers ****************************/
00779 
00780         if (currReader->dwCurrentState & SCARD_STATE_IGNORE)
00781         {
00782             currReader->dwEventState = SCARD_STATE_IGNORE;
00783         }
00784         else
00785         {
00786       /************ Looks for correct readernames *********************/
00787 
00788             lpcReaderName = (char *) currReader->szReader;
00789 
00790             readerIndice = SCardGetReaderIndice(lpcReaderName);
00791             /* The requested reader name is not recognized */
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                     /* Spec says use SCARD_STATE_IGNORE but a removed USB reader
00803                        with eventState fed into currentState will be ignored forever */
00804                     dwBreakFlag = 1;
00805                 }
00806             }
00807             else
00808             {
00809                 /* The reader has come back after being away */
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                 /* Now we check all the Reader States */
00820                 dwState = psReaderMap[readerIndice].dwCurrentState;
00821 
00822     /*********** Check if the reader is in the correct state ********/
00823                 if (dwState & SCARD_STATE_UNKNOWN)
00824                 {
00825                     /* App thinks reader is in bad state and it is */
00826                     if (currReader->dwCurrentState & SCARD_STATE_UNAVAILABLE)
00827                     {
00828                         currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
00829                     }
00830                     else
00831                     {
00832                         /* App thinks reader is in good state and it is not */
00833                         currReader->dwEventState = SCARD_STATE_CHANGED |
00834                             SCARD_STATE_UNAVAILABLE;
00835                         dwBreakFlag = 1;
00836                     }
00837                 }
00838                 else
00839                 {
00840                     /* App thinks reader in bad state but it is not */
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     /********** Check for card presence in the reader **************/
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                 /* Card is now absent                   */
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                     /* After present the rest are assumed */
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                     /* Card is now present              */
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                     /* TODO */
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                         /* App thinks card is mute but it is not */
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                     /* A card must be inserted for it to be INUSE */
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                     /* Break out of the while .. loop and return status
00957                        once all the status's for all readers is met */
00958                     dwBreakFlag = 1;
00959                 }
00960                 SYS_USleep(PCSCLITE_STATUS_WAIT);
00961 
00962             }                   /* End of SCARD_STATE_UNKNOWN */
00963 
00964         }                       /* End of SCARD_STATE_IGNORE */
00965 
00966         /* Counter and resetter */
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             /* If time is greater than timeout and all readers have been
00976                checked
00977              */
00978             if ((dwTime >= (dwTimeout * 1000)) && (j == 0))
00979             {
00980                 return SCARD_E_TIMEOUT;
00981             }
00982         }
00983 
00984         /* Declare all the break conditions */
00985         /* TODO think about this */
00986         if (psContextMap[retIndice].contextBlockStatus == BLOCK_STATUS_RESUME)
00987             break;
00988 
00989         /* Break if UNAWARE is set and all readers have been checked */
00990         if ((dwBreakFlag == 1) && (j == 0))
00991             break;
00992 
00993         /*
00994          * Solve the problem of never exiting the loop when a smartcard is
00995          * already inserted in the reader, thus blocking the application
00996          * (patch proposed by Serge Koganovitsch)
00997          */
00998         if ((dwTimeout == 0) && (j == 0))
00999             break;
01000 
01001     }
01002     while (1);                  /* end of do */
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     /* TODO */
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     /* TODO which protocols to support */
01047     /* if(pioSendPci && pioSendPci->dwProtocol) { */
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     /* TODO fill the received Pci ... */
01103     /* For now  just filling the send pci protocol. */
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     /* Make sure this context has been opened */
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     /* Set the block status for this Context so blocking calls will complete */
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