winscard.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 1999-2004
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00007  *
00008  * $Id: winscard.c 3304 2009-02-06 08:46:19Z rousseau $
00009  */
00010 
00081 #include "config.h"
00082 #include <stdlib.h>
00083 #include <sys/time.h>
00084 #include <string.h>
00085 
00086 #include "pcscd.h"
00087 #include "winscard.h"
00088 #include "ifdhandler.h"
00089 #include "debuglog.h"
00090 #include "readerfactory.h"
00091 #include "prothandler.h"
00092 #include "ifdwrapper.h"
00093 #include "atrhandler.h"
00094 #include "sys_generic.h"
00095 #include "eventhandler.h"
00096 #include "utils.h"
00097 
00098 #undef DO_PROFILE
00099 #ifdef DO_PROFILE
00100 
00101 #ifndef FALSE
00102 #define FALSE 0
00103 #define TRUE 1
00104 #endif
00105 
00106 #define PROFILE_FILE "/tmp/pcscd_profile"
00107 #include <stdio.h>
00108 #include <sys/time.h>
00109 #include <errno.h>
00110 #include <unistd.h>
00111 
00112 struct timeval profile_time_start;
00113 FILE *fd;
00114 char profile_tty;
00115 
00116 #define PROFILE_START profile_start(__FUNCTION__);
00117 #define PROFILE_END profile_end(__FUNCTION__, __LINE__);
00118 
00119 static void profile_start(const char *f)
00120 {
00121     static char initialized = FALSE;
00122 
00123     if (!initialized)
00124     {
00125         initialized = TRUE;
00126         fd = fopen(PROFILE_FILE, "a+");
00127         if (NULL == fd)
00128         {
00129             fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n",
00130                 PROFILE_FILE, strerror(errno));
00131             exit(-1);
00132         }
00133         fprintf(fd, "\nStart a new profile\n");
00134         fflush(fd);
00135 
00136         if (isatty(fileno(stderr)))
00137             profile_tty = TRUE;
00138         else
00139             profile_tty = FALSE;
00140     }
00141 
00142     gettimeofday(&profile_time_start, NULL);
00143 } /* profile_start */
00144 
00145 /* r = a - b */
00146 static long int time_sub(struct timeval *a, struct timeval *b)
00147 {
00148     struct timeval r;
00149     r.tv_sec = a -> tv_sec - b -> tv_sec;
00150     r.tv_usec = a -> tv_usec - b -> tv_usec;
00151     if (r.tv_usec < 0)
00152     {
00153         r.tv_sec--;
00154         r.tv_usec += 1000000;
00155     }
00156 
00157     return r.tv_sec * 1000000 + r.tv_usec;
00158 } /* time_sub */
00159 
00160 
00161 static void profile_end(const char *f, int line)
00162 {
00163     struct timeval profile_time_end;
00164     long d;
00165 
00166     gettimeofday(&profile_time_end, NULL);
00167     d = time_sub(&profile_time_end, &profile_time_start);
00168 
00169     if (profile_tty)
00170         fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m (%d)\n", f, d,
00171             line);
00172     fprintf(fd, "%s %ld\n", f, d);
00173     fflush(fd);
00174 } /* profile_end */
00175 
00176 #else
00177 #define PROFILE_START
00178 #define PROFILE_END
00179 #endif
00180 
00182 #define SCARD_PROTOCOL_ANY_OLD   0x1000
00183 
00185 #define SCARD_LAST_CONTEXT       1
00186 
00187 #define SCARD_NO_CONTEXT         0
00188 
00189 #define SCARD_EXCLUSIVE_CONTEXT -1
00190 
00191 #define SCARD_NO_LOCK            0
00192 
00193 SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, sizeof(SCARD_IO_REQUEST) };
00194 SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(SCARD_IO_REQUEST) };
00195 SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, sizeof(SCARD_IO_REQUEST) };
00196 
00217 LONG SCardEstablishContext(DWORD dwScope, /*@unused@*/ LPCVOID pvReserved1,
00218     /*@unused@*/ LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
00219 {
00220     (void)pvReserved1;
00221     (void)pvReserved2;
00222     /*
00223      * Check for NULL pointer
00224      */
00225     if (phContext == 0)
00226         return SCARD_E_INVALID_PARAMETER;
00227 
00228     if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
00229         dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
00230     {
00231         *phContext = 0;
00232         return SCARD_E_INVALID_VALUE;
00233     }
00234 
00235     /*
00236      * Unique identifier for this server so that it can uniquely be
00237      * identified by clients and distinguished from others
00238      */
00239 
00240     *phContext = (PCSCLITE_SVC_IDENTITY + SYS_RandomInt(1, 65535));
00241 
00242     Log2(PCSC_LOG_DEBUG, "Establishing Context: %d", *phContext);
00243 
00244     return SCARD_S_SUCCESS;
00245 }
00246 
00247 LONG SCardReleaseContext(SCARDCONTEXT hContext)
00248 {
00249     /*
00250      * Nothing to do here RPC layer will handle this
00251      */
00252 
00253     Log2(PCSC_LOG_DEBUG, "Releasing Context: %d", hContext);
00254 
00255     return SCARD_S_SUCCESS;
00256 }
00257 
00258 LONG SCardSetTimeout(/*@unused@*/ SCARDCONTEXT hContext,
00259     /*@unused@*/ DWORD dwTimeout)
00260 {
00261     /*
00262      * This is only used at the client side of an RPC call but just in
00263      * case someone calls it here
00264      */
00265 
00266     (void)hContext;
00267     (void)dwTimeout;
00268     return SCARD_E_UNSUPPORTED_FEATURE;
00269 }
00270 
00271 LONG SCardConnect(/*@unused@*/ SCARDCONTEXT hContext, LPCSTR szReader,
00272     DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
00273     LPDWORD pdwActiveProtocol)
00274 {
00275     LONG rv;
00276     PREADER_CONTEXT rContext = NULL;
00277     DWORD dwStatus;
00278 
00279     (void)hContext;
00280     PROFILE_START
00281 
00282     /*
00283      * Check for NULL parameters
00284      */
00285     if (szReader == NULL || phCard == NULL || pdwActiveProtocol == NULL)
00286         return SCARD_E_INVALID_PARAMETER;
00287     else
00288         *phCard = 0;
00289 
00290     if ((dwShareMode != SCARD_SHARE_DIRECT) &&
00291             !(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00292             !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00293             !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00294             !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00295         return SCARD_E_PROTO_MISMATCH;
00296 
00297     if (dwShareMode != SCARD_SHARE_EXCLUSIVE &&
00298             dwShareMode != SCARD_SHARE_SHARED &&
00299             dwShareMode != SCARD_SHARE_DIRECT)
00300         return SCARD_E_INVALID_VALUE;
00301 
00302     Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %d",
00303         szReader, dwPreferredProtocols);
00304 
00305     rv = RFReaderInfo((LPSTR) szReader, &rContext);
00306 
00307     if (rv != SCARD_S_SUCCESS)
00308     {
00309         Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader);
00310         return rv;
00311     }
00312 
00313     /*
00314      * Make sure the reader is working properly
00315      */
00316     rv = RFCheckReaderStatus(rContext);
00317     if (rv != SCARD_S_SUCCESS)
00318         return rv;
00319 
00320     /*******************************************
00321      *
00322      * This section checks for simple errors
00323      *
00324      *******************************************/
00325 
00326     /*
00327      * Connect if not exclusive mode
00328      */
00329     if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
00330     {
00331         Log1(PCSC_LOG_ERROR, "Error Reader Exclusive");
00332         return SCARD_E_SHARING_VIOLATION;
00333     }
00334 
00335     /*
00336      * wait until a possible transaction is finished
00337      */
00338     if (rContext->dwLockId != 0)
00339     {
00340         Log1(PCSC_LOG_INFO, "Waiting for release of lock");
00341         while (rContext->dwLockId != 0)
00342             (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
00343         Log1(PCSC_LOG_INFO, "Lock released");
00344     }
00345 
00346     /* the reader has been removed while we were waiting */
00347     if (NULL == rContext->readerState)
00348         return SCARD_E_NO_SMARTCARD;
00349 
00350     /*******************************************
00351      *
00352      * This section tries to determine the
00353      * presence of a card or not
00354      *
00355      *******************************************/
00356     dwStatus = rContext->readerState->readerState;
00357 
00358     if (dwShareMode != SCARD_SHARE_DIRECT)
00359     {
00360         if (!(dwStatus & SCARD_PRESENT))
00361         {
00362             /* Coolkey does the card connect to see if the card
00363              * is here, don't fill up /var/log because if it */
00364             Log1(PCSC_LOG_DEBUG, "Card Not Inserted");
00365             return SCARD_E_NO_SMARTCARD;
00366         }
00367 
00368         if (dwStatus & SCARD_SWALLOWED)
00369         {
00370             Log1(PCSC_LOG_ERROR, "Card Not Powered");
00371             return SCARD_W_UNPOWERED_CARD;
00372         }
00373     }
00374 
00375 
00376     /*******************************************
00377      *
00378      * This section tries to decode the ATR
00379      * and set up which protocol to use
00380      *
00381      *******************************************/
00382     if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
00383         rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW;
00384     else
00385     {
00386         if (dwShareMode != SCARD_SHARE_DIRECT)
00387         {
00388             /* lock here instead in IFDSetPTS() to lock up to
00389              * setting rContext->readerState->cardProtocol */
00390             (void)SYS_MutexLock(rContext->mMutex);
00391 
00392             /* the protocol is not yet set (no PPS yet) */
00393             if (SCARD_PROTOCOL_UNDEFINED == rContext->readerState->cardProtocol)
00394             {
00395                 UCHAR ucAvailable, ucDefault;
00396                 int ret;
00397 
00398                 ucDefault = PHGetDefaultProtocol(rContext->readerState->cardAtr,
00399                     rContext->readerState->cardAtrLength);
00400                 ucAvailable =
00401                     PHGetAvailableProtocols(rContext->readerState->cardAtr,
00402                             rContext->readerState->cardAtrLength);
00403 
00404                 /*
00405                  * If it is set to ANY let it do any of the protocols
00406                  */
00407                 if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
00408                     dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
00409 
00410                 ret = PHSetProtocol(rContext, dwPreferredProtocols,
00411                     ucAvailable, ucDefault);
00412 
00413                 /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error  */
00414                 if (SET_PROTOCOL_PPS_FAILED == ret)
00415                 {
00416                     (void)SYS_MutexUnLock(rContext->mMutex);
00417                     return SCARD_W_UNRESPONSIVE_CARD;
00418                 }
00419 
00420                 if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
00421                 {
00422                     (void)SYS_MutexUnLock(rContext->mMutex);
00423                     return SCARD_E_PROTO_MISMATCH;
00424                 }
00425 
00426                 /* use negociated protocol */
00427                 rContext->readerState->cardProtocol = ret;
00428 
00429                 (void)SYS_MutexUnLock(rContext->mMutex);
00430             }
00431             else
00432             {
00433                 (void)SYS_MutexUnLock(rContext->mMutex);
00434 
00435                 if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
00436                     return SCARD_E_PROTO_MISMATCH;
00437             }
00438         }
00439     }
00440 
00441     *pdwActiveProtocol = rContext->readerState->cardProtocol;
00442 
00443     if (dwShareMode != SCARD_SHARE_DIRECT)
00444     {
00445         if ((*pdwActiveProtocol != SCARD_PROTOCOL_T0)
00446             && (*pdwActiveProtocol != SCARD_PROTOCOL_T1))
00447             Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %d",
00448                 *pdwActiveProtocol);
00449         else
00450             Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
00451                 (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
00452     }
00453     else
00454         Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected");
00455 
00456     /*
00457      * Prepare the SCARDHANDLE identity
00458      */
00459     *phCard = RFCreateReaderHandle(rContext);
00460 
00461     Log2(PCSC_LOG_DEBUG, "hCard Identity: %x", *phCard);
00462 
00463     /*******************************************
00464      *
00465      * This section tries to set up the
00466      * exclusivity modes. -1 is exclusive
00467      *
00468      *******************************************/
00469 
00470     if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
00471     {
00472         if (rContext->dwContexts == SCARD_NO_CONTEXT)
00473         {
00474             rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT;
00475             (void)RFLockSharing(*phCard);
00476         }
00477         else
00478         {
00479             (void)RFDestroyReaderHandle(*phCard);
00480             *phCard = 0;
00481             return SCARD_E_SHARING_VIOLATION;
00482         }
00483     }
00484     else
00485     {
00486         /*
00487          * Add a connection to the context stack
00488          */
00489         rContext->dwContexts += 1;
00490     }
00491 
00492     /*
00493      * Add this handle to the handle list
00494      */
00495     rv = RFAddReaderHandle(rContext, *phCard);
00496 
00497     if (rv != SCARD_S_SUCCESS)
00498     {
00499         /*
00500          * Clean up - there is no more room
00501          */
00502         (void)RFDestroyReaderHandle(*phCard);
00503         if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
00504             rContext->dwContexts = SCARD_NO_CONTEXT;
00505         else
00506             if (rContext->dwContexts > SCARD_NO_CONTEXT)
00507                 rContext->dwContexts -= 1;
00508 
00509         *phCard = 0;
00510 
00511         PROFILE_END
00512 
00513         return SCARD_F_INTERNAL_ERROR;
00514     }
00515 
00516     /*
00517      * Propagate new state to Shared Memory
00518      */
00519     rContext->readerState->readerSharing = rContext->dwContexts;
00520     (void)StatSynchronize(rContext->readerState);
00521 
00522     PROFILE_END
00523 
00524     return SCARD_S_SUCCESS;
00525 }
00526 
00527 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
00528     DWORD dwPreferredProtocols, DWORD dwInitialization,
00529     LPDWORD pdwActiveProtocol)
00530 {
00531     LONG rv;
00532     PREADER_CONTEXT rContext = NULL;
00533 
00534     Log1(PCSC_LOG_DEBUG, "Attempting reconnect to token.");
00535 
00536     if (hCard == 0)
00537         return SCARD_E_INVALID_HANDLE;
00538 
00539     /*
00540      * Handle the dwInitialization
00541      */
00542     if (dwInitialization != SCARD_LEAVE_CARD &&
00543             dwInitialization != SCARD_RESET_CARD &&
00544             dwInitialization != SCARD_UNPOWER_CARD)
00545         return SCARD_E_INVALID_VALUE;
00546 
00547     if (dwShareMode != SCARD_SHARE_SHARED &&
00548             dwShareMode != SCARD_SHARE_EXCLUSIVE &&
00549             dwShareMode != SCARD_SHARE_DIRECT)
00550         return SCARD_E_INVALID_VALUE;
00551 
00552     if ((dwShareMode != SCARD_SHARE_DIRECT) &&
00553             !(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
00554             !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
00555             !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
00556             !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
00557         return SCARD_E_PROTO_MISMATCH;
00558 
00559     if (pdwActiveProtocol == NULL)
00560         return SCARD_E_INVALID_PARAMETER;
00561 
00562     rv = RFReaderInfoById(hCard, &rContext);
00563     if (rv != SCARD_S_SUCCESS)
00564         return rv;
00565 
00566     /*
00567      * Make sure the reader is working properly
00568      */
00569     rv = RFCheckReaderStatus(rContext);
00570     if (rv != SCARD_S_SUCCESS)
00571         return rv;
00572 
00573     rv = RFFindReaderHandle(hCard);
00574     if (rv != SCARD_S_SUCCESS)
00575         return rv;
00576 
00577     /*
00578      * Make sure no one has a lock on this reader
00579      */
00580     rv = RFCheckSharing(hCard);
00581     if (rv != SCARD_S_SUCCESS)
00582         return rv;
00583 
00584     /*
00585      * RFUnblockReader( rContext ); FIX - this doesn't work
00586      */
00587 
00588     if (dwInitialization == SCARD_RESET_CARD ||
00589         dwInitialization == SCARD_UNPOWER_CARD)
00590     {
00591         DWORD dwAtrLen;
00592         /*
00593          * Currently pcsc-lite keeps the card powered constantly
00594          */
00595         dwAtrLen = rContext->readerState->cardAtrLength;
00596         if (SCARD_RESET_CARD == dwInitialization)
00597             rv = IFDPowerICC(rContext, IFD_RESET,
00598                 rContext->readerState->cardAtr,
00599                 &dwAtrLen);
00600         else
00601         {
00602             rv = IFDPowerICC(rContext, IFD_POWER_DOWN,
00603                 rContext->readerState->cardAtr,
00604                 &dwAtrLen);
00605             rv = IFDPowerICC(rContext, IFD_POWER_UP,
00606                 rContext->readerState->cardAtr,
00607                 &dwAtrLen);
00608         }
00609         rContext->readerState->cardAtrLength = dwAtrLen;
00610 
00611         /* the protocol is unset after a power on */
00612         rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00613 
00614         /*
00615          * Notify the card has been reset
00616          * Not doing this could result in deadlock
00617          */
00618         rv = RFCheckReaderEventState(rContext, hCard);
00619         switch(rv)
00620         {
00621             /* avoid deadlock */
00622             case SCARD_W_RESET_CARD:
00623                 break;
00624 
00625             case SCARD_W_REMOVED_CARD:
00626                 Log1(PCSC_LOG_ERROR, "card removed");
00627                 return SCARD_W_REMOVED_CARD;
00628 
00629             /* invalid EventStatus */
00630             case SCARD_E_INVALID_VALUE:
00631                 Log1(PCSC_LOG_ERROR, "invalid EventStatus");
00632                 return SCARD_F_INTERNAL_ERROR;
00633 
00634             /* invalid hCard, but hCard was widely used some lines above :( */
00635             case SCARD_E_INVALID_HANDLE:
00636                 Log1(PCSC_LOG_ERROR, "invalid handle");
00637                 return SCARD_F_INTERNAL_ERROR;
00638 
00639             case SCARD_S_SUCCESS:
00640                 /*
00641                  * Notify the card has been reset
00642                  */
00643                 (void)RFSetReaderEventState(rContext, SCARD_RESET);
00644 
00645                 /*
00646                  * Set up the status bit masks on dwStatus
00647                  */
00648                 if (rv == SCARD_S_SUCCESS)
00649                 {
00650                     rContext->readerState->readerState |= SCARD_PRESENT;
00651                     rContext->readerState->readerState &= ~SCARD_ABSENT;
00652                     rContext->readerState->readerState |= SCARD_POWERED;
00653                     rContext->readerState->readerState |= SCARD_NEGOTIABLE;
00654                     rContext->readerState->readerState &= ~SCARD_SPECIFIC;
00655                     rContext->readerState->readerState &= ~SCARD_SWALLOWED;
00656                     rContext->readerState->readerState &= ~SCARD_UNKNOWN;
00657                 }
00658                 else
00659                 {
00660                     rContext->readerState->readerState |= SCARD_PRESENT;
00661                     rContext->readerState->readerState &= ~SCARD_ABSENT;
00662                     rContext->readerState->readerState |= SCARD_SWALLOWED;
00663                     rContext->readerState->readerState &= ~SCARD_POWERED;
00664                     rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
00665                     rContext->readerState->readerState &= ~SCARD_SPECIFIC;
00666                     rContext->readerState->readerState &= ~SCARD_UNKNOWN;
00667                     rContext->readerState->cardAtrLength = 0;
00668                 }
00669 
00670                 if (rContext->readerState->cardAtrLength > 0)
00671                 {
00672                     Log1(PCSC_LOG_DEBUG, "Reset complete.");
00673                     LogXxd(PCSC_LOG_DEBUG, "Card ATR: ",
00674                         rContext->readerState->cardAtr,
00675                         rContext->readerState->cardAtrLength);
00676                 }
00677                 else
00678                 {
00679                     DWORD dwStatus, dwAtrLen2;
00680                     UCHAR ucAtr[MAX_ATR_SIZE];
00681 
00682                     Log1(PCSC_LOG_ERROR, "Error resetting card.");
00683                     (void)IFDStatusICC(rContext, &dwStatus, ucAtr, &dwAtrLen2);
00684                     if (dwStatus & SCARD_PRESENT)
00685                         return SCARD_W_UNRESPONSIVE_CARD;
00686                     else
00687                         return SCARD_E_NO_SMARTCARD;
00688                 }
00689                 break;
00690 
00691             default:
00692                 Log2(PCSC_LOG_ERROR,
00693                     "invalid retcode from RFCheckReaderEventState (%X)", rv);
00694                 return SCARD_F_INTERNAL_ERROR;
00695                 break;
00696         }
00697     }
00698     else
00699         if (dwInitialization == SCARD_LEAVE_CARD)
00700         {
00701             /*
00702              * Do nothing
00703              */
00704         }
00705 
00706     /*******************************************
00707      *
00708      * This section tries to decode the ATR
00709      * and set up which protocol to use
00710      *
00711      *******************************************/
00712     if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
00713         rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW;
00714     else
00715     {
00716         if (dwShareMode != SCARD_SHARE_DIRECT)
00717         {
00718             /* lock here instead in IFDSetPTS() to lock up to
00719              * setting rContext->readerState->cardProtocol */
00720             (void)SYS_MutexLock(rContext->mMutex);
00721 
00722             /* the protocol is not yet set (no PPS yet) */
00723             if (SCARD_PROTOCOL_UNDEFINED == rContext->readerState->cardProtocol)
00724             {
00725                 UCHAR ucAvailable, ucDefault;
00726                 int ret;
00727 
00728                 ucDefault = PHGetDefaultProtocol(rContext->readerState->cardAtr,
00729                     rContext->readerState->cardAtrLength);
00730                 ucAvailable =
00731                     PHGetAvailableProtocols(rContext->readerState->cardAtr,
00732                             rContext->readerState->cardAtrLength);
00733 
00734                 /* If it is set to ANY let it do any of the protocols */
00735                 if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
00736                     dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
00737 
00738                 ret = PHSetProtocol(rContext, dwPreferredProtocols,
00739                     ucAvailable, ucDefault);
00740 
00741                 /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error  */
00742                 if (SET_PROTOCOL_PPS_FAILED == ret)
00743                 {
00744                     (void)SYS_MutexUnLock(rContext->mMutex);
00745                     return SCARD_W_UNRESPONSIVE_CARD;
00746                 }
00747 
00748                 if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
00749                 {
00750                     (void)SYS_MutexUnLock(rContext->mMutex);
00751                     return SCARD_E_PROTO_MISMATCH;
00752                 }
00753 
00754                 /* use negociated protocol */
00755                 rContext->readerState->cardProtocol = ret;
00756 
00757                 (void)SYS_MutexUnLock(rContext->mMutex);
00758             }
00759             else
00760             {
00761                 (void)SYS_MutexUnLock(rContext->mMutex);
00762 
00763                 if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
00764                     return SCARD_E_PROTO_MISMATCH;
00765             }
00766         }
00767     }
00768 
00769     *pdwActiveProtocol = rContext->readerState->cardProtocol;
00770 
00771     if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
00772     {
00773         if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
00774         {
00775             /*
00776              * Do nothing - we are already exclusive
00777              */
00778         } else
00779         {
00780             if (rContext->dwContexts == SCARD_LAST_CONTEXT)
00781             {
00782                 rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT;
00783                 (void)RFLockSharing(hCard);
00784             } else
00785             {
00786                 return SCARD_E_SHARING_VIOLATION;
00787             }
00788         }
00789     } else if (dwShareMode == SCARD_SHARE_SHARED)
00790     {
00791         if (rContext->dwContexts != SCARD_EXCLUSIVE_CONTEXT)
00792         {
00793             /*
00794              * Do nothing - in sharing mode already
00795              */
00796         } else
00797         {
00798             /*
00799              * We are in exclusive mode but want to share now
00800              */
00801             (void)RFUnlockSharing(hCard);
00802             rContext->dwContexts = SCARD_LAST_CONTEXT;
00803         }
00804     } else if (dwShareMode == SCARD_SHARE_DIRECT)
00805     {
00806         if (rContext->dwContexts != SCARD_EXCLUSIVE_CONTEXT)
00807         {
00808             /*
00809              * Do nothing - in sharing mode already
00810              */
00811         } else
00812         {
00813             /*
00814              * We are in exclusive mode but want to share now
00815              */
00816             (void)RFUnlockSharing(hCard);
00817             rContext->dwContexts = SCARD_LAST_CONTEXT;
00818         }
00819     } else
00820         return SCARD_E_INVALID_VALUE;
00821 
00822     /*
00823      * Clear a previous event to the application
00824      */
00825     (void)RFClearReaderEventState(rContext, hCard);
00826 
00827     /*
00828      * Propagate new state to Shared Memory
00829      */
00830     rContext->readerState->readerSharing = rContext->dwContexts;
00831     (void)StatSynchronize(rContext->readerState);
00832 
00833     return SCARD_S_SUCCESS;
00834 }
00835 
00836 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
00837 {
00838     LONG rv;
00839     PREADER_CONTEXT rContext = NULL;
00840     DWORD dwAtrLen;
00841 
00842     if (hCard == 0)
00843         return SCARD_E_INVALID_HANDLE;
00844 
00845     rv = RFReaderInfoById(hCard, &rContext);
00846     if (rv != SCARD_S_SUCCESS)
00847         return rv;
00848 
00849     rv = RFFindReaderHandle(hCard);
00850     if (rv != SCARD_S_SUCCESS)
00851         return rv;
00852 
00853     if ((dwDisposition != SCARD_LEAVE_CARD)
00854         && (dwDisposition != SCARD_UNPOWER_CARD)
00855         && (dwDisposition != SCARD_RESET_CARD)
00856         && (dwDisposition != SCARD_EJECT_CARD))
00857         return SCARD_E_INVALID_VALUE;
00858 
00859     /*
00860      * wait until a possible transaction is finished
00861      */
00862     if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->dwLockId != 0)
00863         && (rContext->dwLockId != hCard))
00864     {
00865         Log1(PCSC_LOG_INFO, "Waiting for release of lock");
00866         while (rContext->dwLockId != 0)
00867             (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
00868         Log1(PCSC_LOG_INFO, "Lock released");
00869     }
00870 
00871     /* the reader has been removed while we were waiting */
00872     if (NULL == rContext->readerState)
00873         return SCARD_E_NO_SMARTCARD;
00874 
00875     /*
00876      * Unlock any blocks on this context
00877      */
00878     rv = RFUnlockAllSharing(hCard);
00879     if (rv != SCARD_S_SUCCESS)
00880         return rv;
00881 
00882     Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->dwContexts);
00883 
00884     if (dwDisposition == SCARD_RESET_CARD ||
00885         dwDisposition == SCARD_UNPOWER_CARD)
00886     {
00887         /*
00888          * Currently pcsc-lite keeps the card powered constantly
00889          */
00890         dwAtrLen = rContext->readerState->cardAtrLength;
00891         if (SCARD_RESET_CARD == dwDisposition)
00892             rv = IFDPowerICC(rContext, IFD_RESET,
00893                 rContext->readerState->cardAtr,
00894                 &dwAtrLen);
00895         else
00896         {
00897             rv = IFDPowerICC(rContext, IFD_POWER_DOWN,
00898                 rContext->readerState->cardAtr,
00899                 &dwAtrLen);
00900             rv = IFDPowerICC(rContext, IFD_POWER_UP,
00901                 rContext->readerState->cardAtr,
00902                 &dwAtrLen);
00903         }
00904         rContext->readerState->cardAtrLength = dwAtrLen;
00905 
00906         /* the protocol is unset after a power on */
00907         rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00908 
00909         /*
00910          * Notify the card has been reset
00911          */
00912         (void)RFSetReaderEventState(rContext, SCARD_RESET);
00913 
00914         /*
00915          * Set up the status bit masks on dwStatus
00916          */
00917         if (rv == SCARD_S_SUCCESS)
00918         {
00919             rContext->readerState->readerState |= SCARD_PRESENT;
00920             rContext->readerState->readerState &= ~SCARD_ABSENT;
00921             rContext->readerState->readerState |= SCARD_POWERED;
00922             rContext->readerState->readerState |= SCARD_NEGOTIABLE;
00923             rContext->readerState->readerState &= ~SCARD_SPECIFIC;
00924             rContext->readerState->readerState &= ~SCARD_SWALLOWED;
00925             rContext->readerState->readerState &= ~SCARD_UNKNOWN;
00926         }
00927         else
00928         {
00929             if (rContext->readerState->readerState & SCARD_ABSENT)
00930                 rContext->readerState->readerState &= ~SCARD_PRESENT;
00931             else
00932                 rContext->readerState->readerState |= SCARD_PRESENT;
00933             /* SCARD_ABSENT flag is already set */
00934             rContext->readerState->readerState |= SCARD_SWALLOWED;
00935             rContext->readerState->readerState &= ~SCARD_POWERED;
00936             rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
00937             rContext->readerState->readerState &= ~SCARD_SPECIFIC;
00938             rContext->readerState->readerState &= ~SCARD_UNKNOWN;
00939             rContext->readerState->cardAtrLength = 0;
00940         }
00941 
00942         if (rContext->readerState->cardAtrLength > 0)
00943             Log1(PCSC_LOG_DEBUG, "Reset complete.");
00944         else
00945             Log1(PCSC_LOG_ERROR, "Error resetting card.");
00946     }
00947     else if (dwDisposition == SCARD_EJECT_CARD)
00948     {
00949         UCHAR controlBuffer[5];
00950         UCHAR receiveBuffer[MAX_BUFFER_SIZE];
00951         DWORD receiveLength;
00952 
00953         /*
00954          * Set up the CTBCS command for Eject ICC
00955          */
00956         controlBuffer[0] = 0x20;
00957         controlBuffer[1] = 0x15;
00958         controlBuffer[2] = (rContext->dwSlot & 0x0000FFFF) + 1;
00959         controlBuffer[3] = 0x00;
00960         controlBuffer[4] = 0x00;
00961         receiveLength = 2;
00962         rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
00963             &receiveLength);
00964 
00965         if (rv == SCARD_S_SUCCESS)
00966         {
00967             if (receiveLength == 2 && receiveBuffer[0] == 0x90)
00968             {
00969                 Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
00970                 /*
00971                  * Successful
00972                  */
00973             }
00974             else
00975                 Log1(PCSC_LOG_ERROR, "Error ejecting card.");
00976         }
00977         else
00978             Log1(PCSC_LOG_ERROR, "Error ejecting card.");
00979 
00980     }
00981     else if (dwDisposition == SCARD_LEAVE_CARD)
00982     {
00983         /*
00984          * Do nothing
00985          */
00986     }
00987 
00988     /*
00989      * Remove and destroy this handle
00990      */
00991     (void)RFRemoveReaderHandle(rContext, hCard);
00992     (void)RFDestroyReaderHandle(hCard);
00993 
00994     /*
00995      * For exclusive connection reset it to no connections
00996      */
00997     if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
00998         rContext->dwContexts = SCARD_NO_CONTEXT;
00999     else
01000     {
01001         /*
01002          * Remove a connection from the context stack
01003          */
01004         rContext->dwContexts -= 1;
01005 
01006         if (rContext->dwContexts < 0)
01007             rContext->dwContexts = 0;
01008     }
01009 
01010     /*
01011      * Propagate new state to Shared Memory
01012      */
01013     rContext->readerState->readerSharing = rContext->dwContexts;
01014     (void)StatSynchronize(rContext->readerState);
01015 
01016     return SCARD_S_SUCCESS;
01017 }
01018 
01019 LONG SCardBeginTransaction(SCARDHANDLE hCard)
01020 {
01021     LONG rv;
01022     PREADER_CONTEXT rContext;
01023 
01024     if (hCard == 0)
01025         return SCARD_E_INVALID_HANDLE;
01026 
01027     rv = RFReaderInfoById(hCard, &rContext);
01028 
01029     /*
01030      * Cannot find the hCard in this context
01031      */
01032     if (rv != SCARD_S_SUCCESS)
01033         return rv;
01034 
01035     /*
01036      * Make sure the reader is working properly
01037      */
01038     rv = RFCheckReaderStatus(rContext);
01039     if (rv != SCARD_S_SUCCESS)
01040         return rv;
01041 
01042     rv = RFFindReaderHandle(hCard);
01043     if (rv != SCARD_S_SUCCESS)
01044         return rv;
01045 
01046     /*
01047      * Make sure some event has not occurred
01048      */
01049     if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
01050         return rv;
01051 
01052     rv = RFLockSharing(hCard);
01053 
01054     /* if the transaction is not yet ready we sleep a bit so the client
01055      * do not retry immediately */
01056     if (SCARD_E_SHARING_VIOLATION == rv)
01057         (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
01058 
01059     Log2(PCSC_LOG_DEBUG, "Status: 0x%08X", rv);
01060 
01061     return rv;
01062 }
01063 
01064 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
01065 {
01066     LONG rv;
01067     PREADER_CONTEXT rContext = NULL;
01068     DWORD dwAtrLen;
01069 
01070     /*
01071      * Ignoring dwDisposition for now
01072      */
01073     if (hCard == 0)
01074         return SCARD_E_INVALID_HANDLE;
01075 
01076     if ((dwDisposition != SCARD_LEAVE_CARD)
01077         && (dwDisposition != SCARD_UNPOWER_CARD)
01078         && (dwDisposition != SCARD_RESET_CARD)
01079         && (dwDisposition != SCARD_EJECT_CARD))
01080     return SCARD_E_INVALID_VALUE;
01081 
01082     rv = RFReaderInfoById(hCard, &rContext);
01083 
01084     /*
01085      * Cannot find the hCard in this context
01086      */
01087     if (rv != SCARD_S_SUCCESS)
01088         return rv;
01089 
01090     rv = RFFindReaderHandle(hCard);
01091     if (rv != SCARD_S_SUCCESS)
01092         return rv;
01093 
01094     /*
01095      * Make sure some event has not occurred
01096      */
01097     if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
01098         return rv;
01099 
01100     if (dwDisposition == SCARD_RESET_CARD ||
01101         dwDisposition == SCARD_UNPOWER_CARD)
01102     {
01103         /*
01104          * Currently pcsc-lite keeps the card always powered
01105          */
01106         dwAtrLen = rContext->readerState->cardAtrLength;
01107         if (SCARD_RESET_CARD == dwDisposition)
01108             rv = IFDPowerICC(rContext, IFD_RESET,
01109                 rContext->readerState->cardAtr,
01110                 &dwAtrLen);
01111         else
01112         {
01113             rv = IFDPowerICC(rContext, IFD_POWER_DOWN,
01114                 rContext->readerState->cardAtr,
01115                 &dwAtrLen);
01116             rv = IFDPowerICC(rContext, IFD_POWER_UP,
01117                 rContext->readerState->cardAtr,
01118                 &dwAtrLen);
01119         }
01120         rContext->readerState->cardAtrLength = dwAtrLen;
01121 
01122         /* the protocol is unset after a power on */
01123         rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
01124 
01125         /*
01126          * Notify the card has been reset
01127          */
01128         (void)RFSetReaderEventState(rContext, SCARD_RESET);
01129 
01130         /*
01131          * Set up the status bit masks on dwStatus
01132          */
01133         if (rv == SCARD_S_SUCCESS)
01134         {
01135             rContext->readerState->readerState |= SCARD_PRESENT;
01136             rContext->readerState->readerState &= ~SCARD_ABSENT;
01137             rContext->readerState->readerState |= SCARD_POWERED;
01138             rContext->readerState->readerState |= SCARD_NEGOTIABLE;
01139             rContext->readerState->readerState &= ~SCARD_SPECIFIC;
01140             rContext->readerState->readerState &= ~SCARD_SWALLOWED;
01141             rContext->readerState->readerState &= ~SCARD_UNKNOWN;
01142         }
01143         else
01144         {
01145             if (rContext->readerState->readerState & SCARD_ABSENT)
01146                 rContext->readerState->readerState &= ~SCARD_PRESENT;
01147             else
01148                 rContext->readerState->readerState |= SCARD_PRESENT;
01149             /* SCARD_ABSENT flag is already set */
01150             rContext->readerState->readerState |= SCARD_SWALLOWED;
01151             rContext->readerState->readerState &= ~SCARD_POWERED;
01152             rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
01153             rContext->readerState->readerState &= ~SCARD_SPECIFIC;
01154             rContext->readerState->readerState &= ~SCARD_UNKNOWN;
01155             rContext->readerState->cardAtrLength = 0;
01156         }
01157 
01158         if (rContext->readerState->cardAtrLength > 0)
01159             Log1(PCSC_LOG_DEBUG, "Reset complete.");
01160         else
01161             Log1(PCSC_LOG_ERROR, "Error resetting card.");
01162 
01163     }
01164     else if (dwDisposition == SCARD_EJECT_CARD)
01165     {
01166         UCHAR controlBuffer[5];
01167         UCHAR receiveBuffer[MAX_BUFFER_SIZE];
01168         DWORD receiveLength;
01169 
01170         /*
01171          * Set up the CTBCS command for Eject ICC
01172          */
01173         controlBuffer[0] = 0x20;
01174         controlBuffer[1] = 0x15;
01175         controlBuffer[2] = (rContext->dwSlot & 0x0000FFFF) + 1;
01176         controlBuffer[3] = 0x00;
01177         controlBuffer[4] = 0x00;
01178         receiveLength = 2;
01179         rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
01180             &receiveLength);
01181 
01182         if (rv == SCARD_S_SUCCESS)
01183         {
01184             if (receiveLength == 2 && receiveBuffer[0] == 0x90)
01185             {
01186                 Log1(PCSC_LOG_DEBUG, "Card ejected successfully.");
01187                 /*
01188                  * Successful
01189                  */
01190             }
01191             else
01192                 Log1(PCSC_LOG_ERROR, "Error ejecting card.");
01193         }
01194         else
01195             Log1(PCSC_LOG_ERROR, "Error ejecting card.");
01196 
01197     }
01198     else if (dwDisposition == SCARD_LEAVE_CARD)
01199     {
01200         /*
01201          * Do nothing
01202          */
01203     }
01204 
01205     /*
01206      * Unlock any blocks on this context
01207      */
01208     (void)RFUnlockSharing(hCard);
01209 
01210     Log2(PCSC_LOG_DEBUG, "Status: 0x%08X", rv);
01211 
01212     return rv;
01213 }
01214 
01215 LONG SCardCancelTransaction(SCARDHANDLE hCard)
01216 {
01217     LONG rv;
01218     PREADER_CONTEXT rContext = NULL;
01219 
01220     /*
01221      * Ignoring dwDisposition for now
01222      */
01223     if (hCard == 0)
01224         return SCARD_E_INVALID_HANDLE;
01225 
01226     rv = RFReaderInfoById(hCard, &rContext);
01227 
01228     /*
01229      * Cannot find the hCard in this context
01230      */
01231     if (rv != SCARD_S_SUCCESS)
01232         return rv;
01233 
01234     rv = RFFindReaderHandle(hCard);
01235     if (rv != SCARD_S_SUCCESS)
01236         return rv;
01237 
01238     /*
01239      * Make sure some event has not occurred
01240      */
01241     if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
01242         return rv;
01243 
01244     rv = RFUnlockSharing(hCard);
01245 
01246     Log2(PCSC_LOG_DEBUG, "Status: 0x%08X", rv);
01247 
01248     return rv;
01249 }
01250 
01251 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames,
01252     LPDWORD pcchReaderLen, LPDWORD pdwState,
01253     LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
01254 {
01255     LONG rv;
01256     PREADER_CONTEXT rContext = NULL;
01257 
01258     if (hCard == 0)
01259         return SCARD_E_INVALID_HANDLE;
01260 
01261     rv = RFReaderInfoById(hCard, &rContext);
01262 
01263     /*
01264      * Cannot find the hCard in this context
01265      */
01266     if (rv != SCARD_S_SUCCESS)
01267         return rv;
01268 
01269     if (strlen(rContext->lpcReader) > MAX_BUFFER_SIZE
01270             || rContext->readerState->cardAtrLength > MAX_ATR_SIZE)
01271         return SCARD_F_INTERNAL_ERROR;
01272 
01273     /*
01274      * This is a client side function however the server maintains the
01275      * list of events between applications so it must be passed through to
01276      * obtain this event if it has occurred
01277      */
01278 
01279     /*
01280      * Make sure some event has not occurred
01281      */
01282     if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
01283         return rv;
01284 
01285     /*
01286      * Make sure the reader is working properly
01287      */
01288     rv = RFCheckReaderStatus(rContext);
01289     if (rv != SCARD_S_SUCCESS)
01290         return rv;
01291 
01292     if (mszReaderNames)
01293     {  /* want reader name */
01294         if (pcchReaderLen)
01295         { /* & present reader name length */
01296             if (*pcchReaderLen >= strlen(rContext->lpcReader))
01297             { /* & enough room */
01298                 *pcchReaderLen = strlen(rContext->lpcReader);
01299                 strncpy(mszReaderNames, rContext->lpcReader, MAX_READERNAME);
01300             }
01301             else
01302             {        /* may report only reader name len */
01303                 *pcchReaderLen = strlen(rContext->lpcReader);
01304                 rv = SCARD_E_INSUFFICIENT_BUFFER;
01305             }
01306         }
01307         else
01308         {            /* present buf & no buflen */
01309             return SCARD_E_INVALID_PARAMETER;
01310         }
01311     }
01312     else
01313     {
01314         if (pcchReaderLen)
01315         { /* want reader len only */
01316             *pcchReaderLen = strlen(rContext->lpcReader);
01317         }
01318         else
01319         {
01320         /* nothing todo */
01321         }
01322     }
01323 
01324     if (pdwState)
01325         *pdwState = rContext->readerState->readerState;
01326 
01327     if (pdwProtocol)
01328         *pdwProtocol = rContext->readerState->cardProtocol;
01329 
01330     if (pbAtr)
01331     {  /* want ATR */
01332         if (pcbAtrLen)
01333         { /* & present ATR length */
01334             if (*pcbAtrLen >= rContext->readerState->cardAtrLength)
01335             { /* & enough room */
01336                 *pcbAtrLen = rContext->readerState->cardAtrLength;
01337                 memcpy(pbAtr, rContext->readerState->cardAtr,
01338                     rContext->readerState->cardAtrLength);
01339             }
01340             else
01341             { /* may report only ATR len */
01342                 *pcbAtrLen = rContext->readerState->cardAtrLength;
01343                 rv = SCARD_E_INSUFFICIENT_BUFFER;
01344             }
01345         }
01346         else
01347         { /* present buf & no buflen */
01348             return SCARD_E_INVALID_PARAMETER;
01349         }
01350     }
01351     else
01352     {
01353         if (pcbAtrLen)
01354         { /* want ATR len only */
01355             *pcbAtrLen = rContext->readerState->cardAtrLength;
01356         }
01357         else
01358         {
01359             /* nothing todo */
01360         }
01361     }
01362 
01363     return rv;
01364 }
01365 
01366 LONG SCardGetStatusChange(/*@unused@*/ SCARDCONTEXT hContext,
01367     /*@unused@*/ DWORD dwTimeout,
01368     /*@unused@*/ LPSCARD_READERSTATE_A rgReaderStates,
01369     /*@unused@*/ DWORD cReaders)
01370 {
01371     /*
01372      * Client side function
01373      */
01374     (void)hContext;
01375     (void)dwTimeout;
01376     (void)rgReaderStates;
01377     (void)cReaders;
01378     return SCARD_S_SUCCESS;
01379 }
01380 
01381 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
01382     LPCVOID pbSendBuffer, DWORD cbSendLength,
01383     LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
01384 {
01385     LONG rv;
01386     PREADER_CONTEXT rContext = NULL;
01387 
01388     /* 0 bytes returned by default */
01389     *lpBytesReturned = 0;
01390 
01391     if (0 == hCard)
01392         return SCARD_E_INVALID_HANDLE;
01393 
01394     /*
01395      * Make sure no one has a lock on this reader
01396      */
01397     if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
01398         return rv;
01399 
01400     rv = RFReaderInfoById(hCard, &rContext);
01401     if (rv != SCARD_S_SUCCESS)
01402         return rv;
01403 
01404     if (IFD_HVERSION_2_0 == rContext->dwVersion)
01405         if (NULL == pbSendBuffer || 0 == cbSendLength)
01406             return SCARD_E_INVALID_PARAMETER;
01407 
01408     /*
01409      * Make sure the reader is working properly
01410      */
01411     rv = RFCheckReaderStatus(rContext);
01412     if (rv != SCARD_S_SUCCESS)
01413         return rv;
01414 
01415     rv = RFFindReaderHandle(hCard);
01416     if (rv != SCARD_S_SUCCESS)
01417         return rv;
01418 
01419     /*
01420      * Make sure some event has not occurred
01421      */
01422     if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
01423         return rv;
01424 
01425     if (IFD_HVERSION_2_0 == rContext->dwVersion)
01426     {
01427         /* we must wrap a API 3.0 client in an API 2.0 driver */
01428         *lpBytesReturned = cbRecvLength;
01429         return IFDControl_v2(rContext, (PUCHAR)pbSendBuffer,
01430             cbSendLength, pbRecvBuffer, lpBytesReturned);
01431     }
01432     else
01433         if (IFD_HVERSION_3_0 == rContext->dwVersion)
01434             return IFDControl(rContext, dwControlCode, pbSendBuffer,
01435                 cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned);
01436         else
01437             return SCARD_E_UNSUPPORTED_FEATURE;
01438 }
01439 
01440 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
01441     LPBYTE pbAttr, LPDWORD pcbAttrLen)
01442 {
01443     LONG rv;
01444     PREADER_CONTEXT rContext = NULL;
01445 
01446     if (0 == hCard)
01447         return SCARD_E_INVALID_HANDLE;
01448 
01449     /*
01450      * Make sure no one has a lock on this reader
01451      */
01452     if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
01453         return rv;
01454 
01455     rv = RFReaderInfoById(hCard, &rContext);
01456     if (rv != SCARD_S_SUCCESS)
01457         return rv;
01458 
01459     /*
01460      * Make sure the reader is working properly
01461      */
01462     rv = RFCheckReaderStatus(rContext);
01463     if (rv != SCARD_S_SUCCESS)
01464         return rv;
01465 
01466     rv = RFFindReaderHandle(hCard);
01467     if (rv != SCARD_S_SUCCESS)
01468         return rv;
01469 
01470     /*
01471      * Make sure some event has not occurred
01472      */
01473     if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
01474         return rv;
01475 
01476     rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr);
01477     if (rv == IFD_SUCCESS)
01478         return SCARD_S_SUCCESS;
01479     else
01480         if (rv == IFD_ERROR_TAG)
01481             return SCARD_E_UNSUPPORTED_FEATURE;
01482         else
01483             return SCARD_E_NOT_TRANSACTED;
01484 }
01485 
01486 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
01487     LPCBYTE pbAttr, DWORD cbAttrLen)
01488 {
01489     LONG rv;
01490     PREADER_CONTEXT rContext = NULL;
01491 
01492     if (0 == hCard)
01493         return SCARD_E_INVALID_HANDLE;
01494 
01495     /*
01496      * Make sure no one has a lock on this reader
01497      */
01498     if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
01499         return rv;
01500 
01501     rv = RFReaderInfoById(hCard, &rContext);
01502     if (rv != SCARD_S_SUCCESS)
01503         return rv;
01504 
01505     /*
01506      * Make sure the reader is working properly
01507      */
01508     rv = RFCheckReaderStatus(rContext);
01509     if (rv != SCARD_S_SUCCESS)
01510         return rv;
01511 
01512     rv = RFFindReaderHandle(hCard);
01513     if (rv != SCARD_S_SUCCESS)
01514         return rv;
01515 
01516     /*
01517      * Make sure some event has not occurred
01518      */
01519     if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
01520         return rv;
01521 
01522     rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr);
01523     if (rv == IFD_SUCCESS)
01524         return SCARD_S_SUCCESS;
01525     else
01526         if (rv == IFD_ERROR_TAG)
01527             return SCARD_E_UNSUPPORTED_FEATURE;
01528         else
01529             return SCARD_E_NOT_TRANSACTED;
01530 }
01531 
01532 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
01533     LPCBYTE pbSendBuffer, DWORD cbSendLength,
01534     LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
01535     LPDWORD pcbRecvLength)
01536 {
01537     LONG rv;
01538     PREADER_CONTEXT rContext = NULL;
01539     SCARD_IO_HEADER sSendPci, sRecvPci;
01540     DWORD dwRxLength, tempRxLength;
01541 
01542     if (pcbRecvLength == 0)
01543         return SCARD_E_INVALID_PARAMETER;
01544 
01545     dwRxLength = *pcbRecvLength;
01546     *pcbRecvLength = 0;
01547 
01548     if (hCard == 0)
01549         return SCARD_E_INVALID_HANDLE;
01550 
01551     if (pbSendBuffer == NULL || pbRecvBuffer == NULL || pioSendPci == NULL)
01552         return SCARD_E_INVALID_PARAMETER;
01553 
01554     /*
01555      * Must at least send a 4 bytes APDU
01556      */
01557     if (cbSendLength < 4)
01558         return SCARD_E_INVALID_PARAMETER;
01559 
01560     /*
01561      * Must at least have 2 status words even for SCardControl
01562      */
01563     if (dwRxLength < 2)
01564         return SCARD_E_INSUFFICIENT_BUFFER;
01565 
01566     /*
01567      * Make sure no one has a lock on this reader
01568      */
01569     if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
01570         return rv;
01571 
01572     rv = RFReaderInfoById(hCard, &rContext);
01573     if (rv != SCARD_S_SUCCESS)
01574         return rv;
01575 
01576     /*
01577      * Make sure the reader is working properly
01578      */
01579     rv = RFCheckReaderStatus(rContext);
01580     if (rv != SCARD_S_SUCCESS)
01581         return rv;
01582 
01583     rv = RFFindReaderHandle(hCard);
01584     if (rv != SCARD_S_SUCCESS)
01585         return rv;
01586 
01587     /*
01588      * Make sure some event has not occurred
01589      */
01590     if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
01591         return rv;
01592 
01593     /*
01594      * Check for some common errors
01595      */
01596     if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
01597     {
01598         if (rContext->readerState->readerState & SCARD_ABSENT)
01599         {
01600             return SCARD_E_NO_SMARTCARD;
01601         }
01602     }
01603 
01604     if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
01605     {
01606         if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD)
01607         {
01608             if (pioSendPci->dwProtocol != rContext->readerState->cardProtocol)
01609             {
01610                 return SCARD_E_PROTO_MISMATCH;
01611             }
01612         }
01613     }
01614 
01615     /*
01616      * Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler
01617      * just wants 0 or 1
01618      */
01619 
01620     sSendPci.Protocol = 0; /* protocol T=0 by default */
01621 
01622     if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1)
01623     {
01624         sSendPci.Protocol = 1;
01625     } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
01626     {
01627         /*
01628          * This is temporary ......
01629          */
01630         sSendPci.Protocol = SCARD_PROTOCOL_RAW;
01631     } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD)
01632     {
01633       /* Fix by Amira (Athena) */
01634         unsigned long i;
01635         unsigned long prot = rContext->readerState->cardProtocol;
01636 
01637         for (i = 0 ; prot != 1 ; i++)
01638             prot >>= 1;
01639 
01640         sSendPci.Protocol = i;
01641     }
01642 
01643     sSendPci.Length = pioSendPci->cbPciLength;
01644 
01645     sRecvPci.Protocol = pioRecvPci->dwProtocol;
01646     sRecvPci.Length = pioRecvPci->cbPciLength;
01647 
01648     /* the protocol number is decoded a few lines above */
01649     Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%d", sSendPci.Protocol);
01650 
01651     tempRxLength = dwRxLength;
01652 
01653     if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
01654     {
01655         rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength,
01656             pbRecvBuffer, &dwRxLength);
01657     } else
01658     {
01659         rv = IFDTransmit(rContext, sSendPci, (PUCHAR) pbSendBuffer,
01660             cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci);
01661     }
01662 
01663     pioRecvPci->dwProtocol = sRecvPci.Protocol;
01664     pioRecvPci->cbPciLength = sRecvPci.Length;
01665 
01666     /*
01667      * Check for any errors that might have occurred
01668      */
01669 
01670     if (rv != SCARD_S_SUCCESS)
01671     {
01672         *pcbRecvLength = 0;
01673         Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv);
01674         return SCARD_E_NOT_TRANSACTED;
01675     }
01676 
01677     /*
01678      * Available is less than received
01679      */
01680     if (tempRxLength < dwRxLength)
01681     {
01682         *pcbRecvLength = 0;
01683         return SCARD_E_INSUFFICIENT_BUFFER;
01684     }
01685 
01686     /*
01687      * Successful return
01688      */
01689     *pcbRecvLength = dwRxLength;
01690     return SCARD_S_SUCCESS;
01691 }
01692 
01693 LONG SCardListReaders(/*@unused@*/ SCARDCONTEXT hContext,
01694     /*@unused@*/ LPCSTR mszGroups,
01695     /*@unused@*/ LPSTR mszReaders,
01696     /*@unused@*/ LPDWORD pcchReaders)
01697 {
01698     /*
01699      * Client side function
01700      */
01701     (void)hContext;
01702     (void)mszGroups;
01703     (void)mszReaders;
01704     (void)pcchReaders;
01705     return SCARD_S_SUCCESS;
01706 }
01707 
01708 LONG SCardCancel(/*@unused@*/ SCARDCONTEXT hContext)
01709 {
01710     /*
01711      * Client side function
01712      */
01713     (void)hContext;
01714     return SCARD_S_SUCCESS;
01715 }
01716 

Generated on 21 Mar 2017 for pcsc-lite by  doxygen 1.6.1