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

Generated on Mon Mar 26 20:50:45 2007 for pcsc-lite by  doxygen 1.4.7