ifdwrapper.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  *  Damien Sauveron <damien.sauveron@labri.fr>
00007  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00008  *
00009  * $Id: ifdwrapper.c 2944 2008-05-12 08:36:21Z rousseau $
00010  */
00011 
00017 #include <errno.h>
00018 #include "config.h"
00019 #include "misc.h"
00020 #include "pcscd.h"
00021 #include "ifdhandler.h"
00022 #include "debuglog.h"
00023 #include "readerfactory.h"
00024 #include "ifdwrapper.h"
00025 #include "atrhandler.h"
00026 #include "dyn_generic.h"
00027 #include "sys_generic.h"
00028 #include "utils.h"
00029 
00030 #undef PCSCLITE_STATIC_DRIVER
00031 
00036 LONG IFDSetPTS(PREADER_CONTEXT rContext, DWORD dwProtocol, UCHAR ucFlags,
00037     UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
00038 {
00039     RESPONSECODE rv = IFD_SUCCESS;
00040     UCHAR ucValue[1];
00041 
00042 #ifndef PCSCLITE_STATIC_DRIVER
00043     RESPONSECODE(*IFD_set_protocol_parameters) (DWORD, UCHAR, UCHAR,
00044         UCHAR, UCHAR) = NULL;
00045     RESPONSECODE(*IFDH_set_protocol_parameters) (DWORD, DWORD, UCHAR,
00046         UCHAR, UCHAR, UCHAR) = NULL;
00047 
00048     if (rContext->dwVersion == IFD_HVERSION_1_0)
00049     {
00050         IFD_set_protocol_parameters = (RESPONSECODE(*)(DWORD, UCHAR, UCHAR,
00051             UCHAR, UCHAR)) rContext->psFunctions.psFunctions_v1.pvfSetProtocolParameters;
00052 
00053         if (NULL == IFD_set_protocol_parameters)
00054             return SCARD_E_UNSUPPORTED_FEATURE;
00055     }
00056     else
00057     {
00058         IFDH_set_protocol_parameters = (RESPONSECODE(*)(DWORD, DWORD, UCHAR,
00059             UCHAR, UCHAR, UCHAR))
00060             rContext->psFunctions.psFunctions_v2.pvfSetProtocolParameters;
00061 
00062         if (NULL == IFDH_set_protocol_parameters)
00063             return SCARD_E_UNSUPPORTED_FEATURE;
00064     }
00065 #endif
00066 
00067     /*
00068      * LOCK THIS CODE REGION
00069      */
00070     SYS_MutexLock(rContext->mMutex);
00071 
00072     ucValue[0] = rContext->dwSlot;
00073 
00074 #ifndef PCSCLITE_STATIC_DRIVER
00075     if (rContext->dwVersion == IFD_HVERSION_1_0)
00076     {
00077             ucValue[0] = rContext->dwSlot;
00078             IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00079             rv = (*IFD_set_protocol_parameters) (dwProtocol,
00080             ucFlags, ucPTS1, ucPTS2, ucPTS3);
00081     }
00082     else
00083     {
00084         rv = (*IFDH_set_protocol_parameters) (rContext->dwSlot,
00085                               dwProtocol,
00086                               ucFlags, ucPTS1,
00087                               ucPTS2, ucPTS3);
00088     }
00089 #else
00090     if (rContext->dwVersion == IFD_HVERSION_1_0)
00091     {
00092             ucValue[0] = rContext->dwSlot;
00093             IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00094         rv = IFD_Set_Protocol_Parameters(dwProtocol, ucFlags, ucPTS1,
00095             ucPTS2, ucPTS3);
00096     }
00097     else
00098     {
00099         rv = IFDHSetProtocolParameters(rContext->dwSlot, dwProtocol,
00100             ucFlags, ucPTS1, ucPTS2, ucPTS3);
00101     }
00102 #endif
00103 
00104     SYS_MutexUnLock(rContext->mMutex);
00105     /*
00106      * END OF LOCKED REGION
00107      */
00108 
00109     return rv;
00110 }
00111 
00115 LONG IFDOpenIFD(PREADER_CONTEXT rContext)
00116 {
00117     RESPONSECODE rv = 0;
00118 
00119 #ifndef PCSCLITE_STATIC_DRIVER
00120     RESPONSECODE(*IO_create_channel) (DWORD) = NULL;
00121     RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
00122     RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPSTR) = NULL;
00123 
00124     if (rContext->dwVersion == IFD_HVERSION_1_0)
00125         IO_create_channel =
00126             rContext->psFunctions.psFunctions_v1.pvfCreateChannel;
00127     else
00128         if (rContext->dwVersion == IFD_HVERSION_2_0)
00129             IFDH_create_channel =
00130                 rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
00131         else
00132         {
00133             IFDH_create_channel =
00134                 rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
00135             IFDH_create_channel_by_name =
00136                 rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
00137         }
00138 #endif
00139 
00140     /*
00141      * LOCK THIS CODE REGION
00142      */
00143 
00144     SYS_MutexLock(rContext->mMutex);
00145 #ifndef PCSCLITE_STATIC_DRIVER
00146     if (rContext->dwVersion == IFD_HVERSION_1_0)
00147     {
00148         rv = (*IO_create_channel) (rContext->dwPort);
00149     } else if (rContext->dwVersion == IFD_HVERSION_2_0)
00150     {
00151         rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
00152     } else
00153     {
00154         /* use device name only if defined */
00155         if (rContext->lpcDevice[0] != '\0')
00156             rv = (*IFDH_create_channel_by_name) (rContext->dwSlot, rContext->lpcDevice);
00157         else
00158             rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
00159     }
00160 #else
00161     if (rContext->dwVersion == IFD_HVERSION_1_0)
00162     {
00163         rv = IO_Create_Channel(rContext->dwPort);
00164     } else if (rContext->dwVersion == IFD_HVERSION_2_0)
00165     {
00166         rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
00167     } else
00168     {
00169         /* Use device name only if defined */
00170         if (rContext->lpcDevice[0] != '\0')
00171             rv = IFDHCreateChannelByName(rContext->dwSlot, rContext->lpcDevice);
00172         else
00173             rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
00174     }
00175 #endif
00176     SYS_MutexUnLock(rContext->mMutex);
00177 
00178     /*
00179      * END OF LOCKED REGION
00180      */
00181 
00182     return rv;
00183 }
00184 
00188 LONG IFDCloseIFD(PREADER_CONTEXT rContext)
00189 {
00190     RESPONSECODE rv = IFD_SUCCESS;
00191 
00192 #ifndef PCSCLITE_STATIC_DRIVER
00193     RESPONSECODE(*IO_close_channel) (void) = NULL;
00194     RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;
00195 
00196     if (rContext->dwVersion == IFD_HVERSION_1_0)
00197         IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel;
00198     else
00199         IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
00200 #endif
00201 
00202     /*
00203      * LOCK THIS CODE REGION
00204      */
00205 
00206     rv = SYS_MutexTryLock(rContext->mMutex);
00207     if (EBUSY == rv)
00208         Log1(PCSC_LOG_ERROR, "Locking failed");
00209 #ifndef PCSCLITE_STATIC_DRIVER
00210     if (rContext->dwVersion == IFD_HVERSION_1_0)
00211 
00212         rv = (*IO_close_channel) ();
00213     else
00214         rv = (*IFDH_close_channel) (rContext->dwSlot);
00215 #else
00216     if (rContext->dwVersion == IFD_HVERSION_1_0)
00217         rv = IO_Close_Channel();
00218     else
00219         rv = IFDHCloseChannel(rContext->dwSlot);
00220 #endif
00221     SYS_MutexUnLock(rContext->mMutex);
00222 
00223     /*
00224      * END OF LOCKED REGION
00225      */
00226 
00227     return rv;
00228 }
00229 
00233 LONG IFDSetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
00234             DWORD dwLength, PUCHAR pucValue)
00235 {
00236     RESPONSECODE rv = IFD_SUCCESS;
00237 
00238 #ifndef PCSCLITE_STATIC_DRIVER
00239     RESPONSECODE(*IFD_set_capabilities) (DWORD, PUCHAR) = NULL;
00240     RESPONSECODE(*IFDH_set_capabilities) (DWORD, DWORD, DWORD, PUCHAR) = NULL;
00241 
00242     if (rContext->dwVersion == IFD_HVERSION_1_0)
00243         IFD_set_capabilities = rContext->psFunctions.psFunctions_v1.pvfSetCapabilities;
00244     else
00245         IFDH_set_capabilities = rContext->psFunctions.psFunctions_v2.pvfSetCapabilities;
00246 #endif
00247 
00248     /*
00249      * Let the calling function lock this otherwise a deadlock will
00250      * result
00251      */
00252 
00253 #ifndef PCSCLITE_STATIC_DRIVER
00254     if (rContext->dwVersion == IFD_HVERSION_1_0)
00255         rv = (*IFD_set_capabilities) (dwTag, pucValue);
00256     else
00257         rv = (*IFDH_set_capabilities) (rContext->dwSlot, dwTag,
00258             dwLength, pucValue);
00259 #else
00260     if (rContext->dwVersion == IFD_HVERSION_1_0)
00261         rv = IFD_Set_Capabilities(dwTag, pucValue);
00262     else
00263         rv = IFDHSetCapabilities(rContext->dwSlot, dwTag, dwLength,
00264             pucValue);
00265 #endif
00266 
00267     return rv;
00268 }
00269 
00275 LONG IFDGetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
00276     PDWORD pdwLength, PUCHAR pucValue)
00277 {
00278     RESPONSECODE rv = IFD_SUCCESS;
00279 
00280 #ifndef PCSCLITE_STATIC_DRIVER
00281     RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
00282     RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, PUCHAR) = NULL;
00283 
00284     if (rContext->dwVersion == IFD_HVERSION_1_0)
00285         IFD_get_capabilities =
00286             rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
00287     else
00288         IFDH_get_capabilities =
00289             rContext->psFunctions.psFunctions_v2.pvfGetCapabilities;
00290 #endif
00291 
00292     /*
00293      * LOCK THIS CODE REGION
00294      */
00295 
00296     SYS_MutexLock(rContext->mMutex);
00297 
00298 #ifndef PCSCLITE_STATIC_DRIVER
00299     if (rContext->dwVersion == IFD_HVERSION_1_0)
00300         rv = (*IFD_get_capabilities) (dwTag, pucValue);
00301     else
00302         rv = (*IFDH_get_capabilities) (rContext->dwSlot, dwTag,
00303             pdwLength, pucValue);
00304 #else
00305     if (rContext->dwVersion == IFD_HVERSION_1_0)
00306         rv = IFD_Get_Capabilities(dwTag, pucValue);
00307     else
00308         rv = IFDHGetCapabilities(rContext->dwSlot, dwTag, pdwLength,
00309             pucValue);
00310 #endif
00311 
00312     SYS_MutexUnLock(rContext->mMutex);
00313 
00314     /*
00315      * END OF LOCKED REGION
00316      */
00317 
00318     return rv;
00319 }
00320 
00324 LONG IFDPowerICC(PREADER_CONTEXT rContext, DWORD dwAction,
00325     PUCHAR pucAtr, PDWORD pdwAtrLen)
00326 {
00327     RESPONSECODE rv;
00328     short ret;
00329     SMARTCARD_EXTENSION sSmartCard;
00330     DWORD dwStatus;
00331     UCHAR ucValue[1];
00332 
00333 #ifndef PCSCLITE_STATIC_DRIVER
00334     RESPONSECODE(*IFD_power_icc) (DWORD) = NULL;
00335     RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL;
00336 #endif
00337 
00338     /*
00339      * Zero out everything
00340      */
00341     rv = IFD_SUCCESS;
00342     dwStatus = 0;
00343     ucValue[0] = 0;
00344 
00345     /*
00346      * Check that the card is inserted first
00347      */
00348     IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00349 
00350     if (dwStatus & SCARD_ABSENT)
00351         return SCARD_W_REMOVED_CARD;
00352 #ifndef PCSCLITE_STATIC_DRIVER
00353     if (rContext->dwVersion == IFD_HVERSION_1_0)
00354         IFD_power_icc = rContext->psFunctions.psFunctions_v1.pvfPowerICC;
00355     else
00356         IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC;
00357 #endif
00358 
00359     /*
00360      * LOCK THIS CODE REGION
00361      */
00362 
00363     SYS_MutexLock(rContext->mMutex);
00364 
00365 #ifndef PCSCLITE_STATIC_DRIVER
00366     if (rContext->dwVersion == IFD_HVERSION_1_0)
00367     {
00368         ucValue[0] = rContext->dwSlot;
00369         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00370         rv = (*IFD_power_icc) (dwAction);
00371     }
00372     else
00373     {
00374         rv = (*IFDH_power_icc) (rContext->dwSlot, dwAction,
00375             pucAtr, pdwAtrLen);
00376 
00377         ret = ATRDecodeAtr(&sSmartCard, pucAtr, *pdwAtrLen);
00378     }
00379 #else
00380     if (rContext->dwVersion == IFD_HVERSION_1_0)
00381     {
00382         ucValue[0] = rContext->dwSlot;
00383         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00384         rv = IFD_Power_ICC(dwAction);
00385     }
00386     else
00387         rv = IFDHPowerICC(rContext->dwSlot, dwAction, pucAtr, pdwAtrLen);
00388 #endif
00389     SYS_MutexUnLock(rContext->mMutex);
00390 
00391     /*
00392      * END OF LOCKED REGION
00393      */
00394 
00395     /* use clean values in case of error */
00396     if (rv != IFD_SUCCESS)
00397     {
00398         *pdwAtrLen = 0;
00399         pucAtr[0] = '\0';
00400 
00401         if (rv == IFD_NO_SUCH_DEVICE)
00402         {
00403             SendHotplugSignal();
00404             return SCARD_E_READER_UNAVAILABLE;
00405         }
00406 
00407         return SCARD_E_NOT_TRANSACTED;
00408     }
00409 
00410     /*
00411      * Get the ATR and it's length
00412      */
00413     if (rContext->dwVersion == IFD_HVERSION_1_0)
00414         IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00415 
00416     return rv;
00417 }
00418 
00423 LONG IFDStatusICC(PREADER_CONTEXT rContext, PDWORD pdwStatus,
00424     PUCHAR pucAtr, PDWORD pdwAtrLen)
00425 {
00426     RESPONSECODE rv = IFD_SUCCESS;
00427     DWORD dwTag = 0, dwCardStatus = 0;
00428     SMARTCARD_EXTENSION sSmartCard;
00429     UCHAR ucValue[1] = "\x00";
00430 
00431 #ifndef PCSCLITE_STATIC_DRIVER
00432     RESPONSECODE(*IFD_is_icc_present) (void) = NULL;
00433     RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;
00434     RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
00435 
00436     if (rContext->dwVersion == IFD_HVERSION_1_0)
00437     {
00438         IFD_is_icc_present =
00439             rContext->psFunctions.psFunctions_v1.pvfICCPresence;
00440         IFD_get_capabilities =
00441             rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
00442     }
00443     else
00444         IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
00445 #endif
00446 
00447     /*
00448      * LOCK THIS CODE REGION
00449      */
00450 
00451     SYS_MutexLock(rContext->mMutex);
00452 
00453 #ifndef PCSCLITE_STATIC_DRIVER
00454     if (rContext->dwVersion == IFD_HVERSION_1_0)
00455     {
00456         ucValue[0] = rContext->dwSlot;
00457         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00458         rv = (*IFD_is_icc_present) ();
00459     }
00460     else
00461         rv = (*IFDH_icc_presence) (rContext->dwSlot);
00462 #else
00463     if (rContext->dwVersion == IFD_HVERSION_1_0)
00464     {
00465         ucValue[0] = rContext->dwSlot;
00466         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00467         rv = IFD_Is_ICC_Present();
00468     }
00469     else
00470         rv = IFDHICCPresence(rContext->dwSlot);
00471 #endif
00472     SYS_MutexUnLock(rContext->mMutex);
00473 
00474     /*
00475      * END OF LOCKED REGION
00476      */
00477 
00478     if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00479         dwCardStatus |= SCARD_PRESENT;
00480     else
00481         if (rv == IFD_ICC_NOT_PRESENT)
00482             dwCardStatus |= SCARD_ABSENT;
00483         else
00484         {
00485             Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00486             *pdwStatus = SCARD_UNKNOWN;
00487 
00488             if (rv == IFD_NO_SUCH_DEVICE)
00489             {
00490                 SendHotplugSignal();
00491                 return SCARD_E_READER_UNAVAILABLE;
00492             }
00493 
00494             return SCARD_E_NOT_TRANSACTED;
00495         }
00496 
00497     /*
00498      * Now lets get the ATR and process it if IFD Handler version 1.0.
00499      * IFD Handler version 2.0 does this immediately after reset/power up
00500      * to conserve resources
00501      */
00502 
00503     if (rContext->dwVersion == IFD_HVERSION_1_0)
00504     {
00505         if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00506         {
00507             short ret;
00508 
00509             dwTag = TAG_IFD_ATR;
00510 
00511             /*
00512              * LOCK THIS CODE REGION
00513              */
00514 
00515             SYS_MutexLock(rContext->mMutex);
00516 
00517             ucValue[0] = rContext->dwSlot;
00518             IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00519 
00520 #ifndef PCSCLITE_STATIC_DRIVER
00521             rv = (*IFD_get_capabilities) (dwTag, pucAtr);
00522 #else
00523             rv = IFD_Get_Capabilities(dwTag, pucAtr);
00524 #endif
00525             SYS_MutexUnLock(rContext->mMutex);
00526 
00527             /*
00528              * END OF LOCKED REGION
00529              */
00530 
00531             /*
00532              * FIX :: This is a temporary way to return the correct size
00533              * of the ATR since most of the drivers return MAX_ATR_SIZE
00534              */
00535 
00536             ret = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);
00537 
00538             /*
00539              * Might be a memory card without an ATR
00540              */
00541             if (ret == 0)
00542                 *pdwAtrLen = 0;
00543             else
00544                 *pdwAtrLen = sSmartCard.ATR.Length;
00545         }
00546         else
00547         {
00548             /*
00549              * No card is inserted - Atr length is 0
00550              */
00551             *pdwAtrLen = 0;
00552         }
00553         /*
00554          * End of FIX
00555          */
00556     }
00557 
00558     *pdwStatus = dwCardStatus;
00559 
00560     return SCARD_S_SUCCESS;
00561 }
00562 
00563 /*
00564  * Function: IFDControl Purpose : This function provides a means for
00565  * toggling a specific action on the reader such as swallow, eject,
00566  * biometric.
00567  */
00568 
00569 /*
00570  * Valid only for IFDHandler version 2.0
00571  */
00572 
00573 LONG IFDControl_v2(PREADER_CONTEXT rContext, PUCHAR TxBuffer,
00574     DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
00575 {
00576     RESPONSECODE rv = IFD_SUCCESS;
00577 
00578 #ifndef PCSCLITE_STATIC_DRIVER
00579     RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, PUCHAR, PDWORD);
00580 #endif
00581 
00582     if (rContext->dwVersion != IFD_HVERSION_2_0)
00583         return SCARD_E_UNSUPPORTED_FEATURE;
00584 
00585 #ifndef PCSCLITE_STATIC_DRIVER
00586     IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
00587 #endif
00588 
00589     /*
00590      * LOCK THIS CODE REGION
00591      */
00592     SYS_MutexLock(rContext->mMutex);
00593 
00594 #ifndef PCSCLITE_STATIC_DRIVER
00595     rv = (*IFDH_control_v2) (rContext->dwSlot, TxBuffer, TxLength,
00596         RxBuffer, RxLength);
00597 #else
00598     rv = IFDHControl_v2(rContext->dwSlot, TxBuffer, TxLength,
00599         RxBuffer, RxLength);
00600 #endif
00601     SYS_MutexUnLock(rContext->mMutex);
00602     /*
00603      * END OF LOCKED REGION
00604      */
00605 
00606     if (rv == IFD_SUCCESS)
00607         return SCARD_S_SUCCESS;
00608     else
00609     {
00610         Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00611         return SCARD_E_NOT_TRANSACTED;
00612     }
00613 }
00614 
00620 /*
00621  * Valid only for IFDHandler version 3.0 and up
00622  */
00623 
00624 LONG IFDControl(PREADER_CONTEXT rContext, DWORD ControlCode,
00625     LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
00626     LPDWORD BytesReturned)
00627 {
00628     RESPONSECODE rv = IFD_SUCCESS;
00629 
00630 #ifndef PCSCLITE_STATIC_DRIVER
00631     RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
00632 #endif
00633 
00634     if (rContext->dwVersion < IFD_HVERSION_3_0)
00635         return SCARD_E_UNSUPPORTED_FEATURE;
00636 
00637 #ifndef PCSCLITE_STATIC_DRIVER
00638     IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
00639 #endif
00640 
00641     /*
00642      * LOCK THIS CODE REGION
00643      */
00644 
00645     SYS_MutexLock(rContext->mMutex);
00646 
00647 #ifndef PCSCLITE_STATIC_DRIVER
00648     rv = (*IFDH_control) (rContext->dwSlot, ControlCode, TxBuffer,
00649         TxLength, RxBuffer, RxLength, BytesReturned);
00650 #else
00651     rv = IFDHControl(rContext->dwSlot, ControlCode, TxBuffer,
00652         TxLength, RxBuffer, RxLength, BytesReturned);
00653 #endif
00654     SYS_MutexUnLock(rContext->mMutex);
00655 
00656     /*
00657      * END OF LOCKED REGION
00658      */
00659 
00660     if (rv == IFD_SUCCESS)
00661         return SCARD_S_SUCCESS;
00662     else
00663     {
00664         Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00665 
00666         if (rv == IFD_NO_SUCH_DEVICE)
00667         {
00668             SendHotplugSignal();
00669             return SCARD_E_READER_UNAVAILABLE;
00670         }
00671 
00672         return SCARD_E_NOT_TRANSACTED;
00673     }
00674 }
00675 
00679 LONG IFDTransmit(PREADER_CONTEXT rContext, SCARD_IO_HEADER pioTxPci,
00680     PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
00681     PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
00682 {
00683     RESPONSECODE rv = IFD_SUCCESS;
00684     UCHAR ucValue[1] = "\x00";
00685 
00686 #ifndef PCSCLITE_STATIC_DRIVER
00687     RESPONSECODE(*IFD_transmit_to_icc) (SCARD_IO_HEADER, PUCHAR, DWORD,
00688         PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00689     RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
00690         DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00691 #endif
00692 
00693     /* log the APDU */
00694     DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);
00695 
00696 #ifndef PCSCLITE_STATIC_DRIVER
00697     if (rContext->dwVersion == IFD_HVERSION_1_0)
00698         IFD_transmit_to_icc =
00699             rContext->psFunctions.psFunctions_v1.pvfTransmitToICC;
00700     else
00701         IFDH_transmit_to_icc =
00702             rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
00703 #endif
00704 
00705     /*
00706      * LOCK THIS CODE REGION
00707      */
00708 
00709     SYS_MutexLock(rContext->mMutex);
00710 
00711 
00712 #ifndef PCSCLITE_STATIC_DRIVER
00713     if (rContext->dwVersion == IFD_HVERSION_1_0)
00714     {
00715         ucValue[0] = rContext->dwSlot;
00716         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00717         rv = (*IFD_transmit_to_icc) (pioTxPci, (LPBYTE) pucTxBuffer,
00718             dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
00719     }
00720     else
00721         rv = (*IFDH_transmit_to_icc) (rContext->dwSlot, pioTxPci,
00722             (LPBYTE) pucTxBuffer, dwTxLength,
00723             pucRxBuffer, pdwRxLength, pioRxPci);
00724 #else
00725     if (rContext->dwVersion == IFD_HVERSION_1_0)
00726     {
00727         ucValue[0] = rContext->dwSlot;
00728         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00729         rv = IFD_Transmit_to_ICC(pioTxPci, (LPBYTE) pucTxBuffer,
00730             dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
00731     }
00732     else
00733         rv = IFDHTransmitToICC(rContext->dwSlot, pioTxPci,
00734             (LPBYTE) pucTxBuffer, dwTxLength,
00735             pucRxBuffer, pdwRxLength, pioRxPci);
00736 #endif
00737     SYS_MutexUnLock(rContext->mMutex);
00738 
00739     /*
00740      * END OF LOCKED REGION
00741      */
00742 
00743     /* log the returned status word */
00744     DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);
00745 
00746     if (rv == IFD_SUCCESS)
00747         return SCARD_S_SUCCESS;
00748     else
00749     {
00750         Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00751 
00752         if (rv == IFD_NO_SUCH_DEVICE)
00753         {
00754             SendHotplugSignal();
00755             return SCARD_E_READER_UNAVAILABLE;
00756         }
00757 
00758         return SCARD_E_NOT_TRANSACTED;
00759     }
00760 }
00761 

Generated on Thu Aug 28 20:14:58 2008 for pcsc-lite by  doxygen 1.5.6