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

Generated on Mon Aug 27 13:45:36 2007 for pcsc-lite by  doxygen 1.5.2