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