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 3294 2009-01-28 13:34:28Z 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      * Locking is done in winscard.c SCardConnect() and SCardReconnect()
00069      *
00070      * This avoids to renegociate the protocol and confuse the card
00071      * Error returned by CCID driver is: CCID_Receive Procedure byte conflict
00072      */
00073 
00074     ucValue[0] = rContext->dwSlot;
00075 
00076 #ifndef PCSCLITE_STATIC_DRIVER
00077     if (rContext->dwVersion == IFD_HVERSION_1_0)
00078     {
00079             ucValue[0] = rContext->dwSlot;
00080             (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00081             rv = (*IFD_set_protocol_parameters) (dwProtocol,
00082             ucFlags, ucPTS1, ucPTS2, ucPTS3);
00083     }
00084     else
00085     {
00086         rv = (*IFDH_set_protocol_parameters) (rContext->dwSlot,
00087                               dwProtocol,
00088                               ucFlags, ucPTS1,
00089                               ucPTS2, ucPTS3);
00090     }
00091 #else
00092     if (rContext->dwVersion == IFD_HVERSION_1_0)
00093     {
00094             ucValue[0] = rContext->dwSlot;
00095             (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00096         rv = IFD_Set_Protocol_Parameters(dwProtocol, ucFlags, ucPTS1,
00097             ucPTS2, ucPTS3);
00098     }
00099     else
00100     {
00101         rv = IFDHSetProtocolParameters(rContext->dwSlot, dwProtocol,
00102             ucFlags, ucPTS1, ucPTS2, ucPTS3);
00103     }
00104 #endif
00105 
00106     return rv;
00107 }
00108 
00112 LONG IFDOpenIFD(PREADER_CONTEXT rContext)
00113 {
00114     RESPONSECODE rv = 0;
00115 
00116 #ifndef PCSCLITE_STATIC_DRIVER
00117     RESPONSECODE(*IO_create_channel) (DWORD) = NULL;
00118     RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
00119     RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPSTR) = NULL;
00120 
00121     if (rContext->dwVersion == IFD_HVERSION_1_0)
00122         IO_create_channel =
00123             rContext->psFunctions.psFunctions_v1.pvfCreateChannel;
00124     else
00125         if (rContext->dwVersion == IFD_HVERSION_2_0)
00126             IFDH_create_channel =
00127                 rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
00128         else
00129         {
00130             IFDH_create_channel =
00131                 rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
00132             IFDH_create_channel_by_name =
00133                 rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
00134         }
00135 #endif
00136 
00137     /* LOCK THIS CODE REGION */
00138     (void)SYS_MutexLock(rContext->mMutex);
00139 
00140 #ifndef PCSCLITE_STATIC_DRIVER
00141     if (rContext->dwVersion == IFD_HVERSION_1_0)
00142     {
00143         rv = (*IO_create_channel) (rContext->dwPort);
00144     } else if (rContext->dwVersion == IFD_HVERSION_2_0)
00145     {
00146         rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
00147     } else
00148     {
00149         /* use device name only if defined */
00150         if (rContext->lpcDevice[0] != '\0')
00151             rv = (*IFDH_create_channel_by_name) (rContext->dwSlot, rContext->lpcDevice);
00152         else
00153             rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
00154     }
00155 #else
00156     if (rContext->dwVersion == IFD_HVERSION_1_0)
00157     {
00158         rv = IO_Create_Channel(rContext->dwPort);
00159     } else if (rContext->dwVersion == IFD_HVERSION_2_0)
00160     {
00161         rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
00162     } else
00163     {
00164         /* Use device name only if defined */
00165         if (rContext->lpcDevice[0] != '\0')
00166             rv = IFDHCreateChannelByName(rContext->dwSlot, rContext->lpcDevice);
00167         else
00168             rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
00169     }
00170 #endif
00171 
00172     /* END OF LOCKED REGION */
00173     (void)SYS_MutexUnLock(rContext->mMutex);
00174 
00175     return rv;
00176 }
00177 
00181 LONG IFDCloseIFD(PREADER_CONTEXT rContext)
00182 {
00183     RESPONSECODE rv = IFD_SUCCESS;
00184     int repeat;
00185 
00186 #ifndef PCSCLITE_STATIC_DRIVER
00187     RESPONSECODE(*IO_close_channel) (void) = NULL;
00188     RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;
00189 
00190     if (rContext->dwVersion == IFD_HVERSION_1_0)
00191         IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel;
00192     else
00193         IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
00194 #endif
00195 
00196     /* TRY TO LOCK THIS CODE REGION */
00197     repeat = 5;
00198 again:
00199     rv = SYS_MutexTryLock(rContext->mMutex);
00200     if (EBUSY == rv)
00201     {
00202         Log1(PCSC_LOG_ERROR, "Locking failed");
00203         repeat--;
00204         if (repeat)
00205         {
00206             (void)SYS_USleep(100*1000); /* 100 ms */
00207             goto again;
00208         }
00209     }
00210 
00211 #ifndef PCSCLITE_STATIC_DRIVER
00212     if (rContext->dwVersion == IFD_HVERSION_1_0)
00213 
00214         rv = (*IO_close_channel) ();
00215     else
00216         rv = (*IFDH_close_channel) (rContext->dwSlot);
00217 #else
00218     if (rContext->dwVersion == IFD_HVERSION_1_0)
00219         rv = IO_Close_Channel();
00220     else
00221         rv = IFDHCloseChannel(rContext->dwSlot);
00222 #endif
00223 
00224     /* END OF LOCKED REGION */
00225     (void)SYS_MutexUnLock(rContext->mMutex);
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, /*@out@*/ PUCHAR) = NULL;
00282     RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, /*@out@*/ 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     /* LOCK THIS CODE REGION */
00293     (void)SYS_MutexLock(rContext->mMutex);
00294 
00295 #ifndef PCSCLITE_STATIC_DRIVER
00296     if (rContext->dwVersion == IFD_HVERSION_1_0)
00297         rv = (*IFD_get_capabilities) (dwTag, pucValue);
00298     else
00299         rv = (*IFDH_get_capabilities) (rContext->dwSlot, dwTag,
00300             pdwLength, pucValue);
00301 #else
00302     if (rContext->dwVersion == IFD_HVERSION_1_0)
00303         rv = IFD_Get_Capabilities(dwTag, pucValue);
00304     else
00305         rv = IFDHGetCapabilities(rContext->dwSlot, dwTag, pdwLength,
00306             pucValue);
00307 #endif
00308 
00309     /* END OF LOCKED REGION */
00310     (void)SYS_MutexUnLock(rContext->mMutex);
00311 
00312     return rv;
00313 }
00314 
00318 LONG IFDPowerICC(PREADER_CONTEXT rContext, DWORD dwAction,
00319     PUCHAR pucAtr, PDWORD pdwAtrLen)
00320 {
00321     RESPONSECODE rv;
00322     short ret;
00323     SMARTCARD_EXTENSION sSmartCard;
00324     DWORD dwStatus;
00325     UCHAR ucValue[1];
00326 
00327 #ifndef PCSCLITE_STATIC_DRIVER
00328     RESPONSECODE(*IFD_power_icc) (DWORD) = NULL;
00329     RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL;
00330 #endif
00331 
00332     /*
00333      * Zero out everything
00334      */
00335     rv = IFD_SUCCESS;
00336     dwStatus = 0;
00337     ucValue[0] = 0;
00338 
00339     /*
00340      * Check that the card is inserted first
00341      */
00342     (void)IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00343 
00344     if (dwStatus & SCARD_ABSENT)
00345         return SCARD_W_REMOVED_CARD;
00346 #ifndef PCSCLITE_STATIC_DRIVER
00347     if (rContext->dwVersion == IFD_HVERSION_1_0)
00348         IFD_power_icc = rContext->psFunctions.psFunctions_v1.pvfPowerICC;
00349     else
00350         IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC;
00351 #endif
00352 
00353     /* LOCK THIS CODE REGION */
00354     (void)SYS_MutexLock(rContext->mMutex);
00355 
00356 #ifndef PCSCLITE_STATIC_DRIVER
00357     if (rContext->dwVersion == IFD_HVERSION_1_0)
00358     {
00359         ucValue[0] = rContext->dwSlot;
00360         (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00361         rv = (*IFD_power_icc) (dwAction);
00362     }
00363     else
00364     {
00365         rv = (*IFDH_power_icc) (rContext->dwSlot, dwAction,
00366             pucAtr, pdwAtrLen);
00367 
00368         ret = ATRDecodeAtr(&sSmartCard, pucAtr, *pdwAtrLen);
00369     }
00370 #else
00371     if (rContext->dwVersion == IFD_HVERSION_1_0)
00372     {
00373         ucValue[0] = rContext->dwSlot;
00374         (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00375         rv = IFD_Power_ICC(dwAction);
00376     }
00377     else
00378         rv = IFDHPowerICC(rContext->dwSlot, dwAction, pucAtr, pdwAtrLen);
00379 #endif
00380 
00381     /* END OF LOCKED REGION */
00382     (void)SYS_MutexUnLock(rContext->mMutex);
00383 
00384     /* use clean values in case of error */
00385     if (rv != IFD_SUCCESS)
00386     {
00387         *pdwAtrLen = 0;
00388         pucAtr[0] = '\0';
00389 
00390         if (rv == IFD_NO_SUCH_DEVICE)
00391         {
00392             (void)SendHotplugSignal();
00393             return SCARD_E_READER_UNAVAILABLE;
00394         }
00395 
00396         return SCARD_E_NOT_TRANSACTED;
00397     }
00398 
00399     /*
00400      * Get the ATR and it's length
00401      */
00402     if (rContext->dwVersion == IFD_HVERSION_1_0)
00403         (void)IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00404 
00405     return rv;
00406 }
00407 
00412 LONG IFDStatusICC(PREADER_CONTEXT rContext, PDWORD pdwStatus,
00413     PUCHAR pucAtr, PDWORD pdwAtrLen)
00414 {
00415     RESPONSECODE rv = IFD_SUCCESS;
00416     DWORD dwTag = 0, dwCardStatus = 0;
00417     SMARTCARD_EXTENSION sSmartCard;
00418     UCHAR ucValue[1] = "\x00";
00419 
00420 #ifndef PCSCLITE_STATIC_DRIVER
00421     RESPONSECODE(*IFD_is_icc_present) (void) = NULL;
00422     RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;
00423     RESPONSECODE(*IFD_get_capabilities) (DWORD, /*@out@*/ PUCHAR) = NULL;
00424 
00425     if (rContext->dwVersion == IFD_HVERSION_1_0)
00426     {
00427         IFD_is_icc_present =
00428             rContext->psFunctions.psFunctions_v1.pvfICCPresence;
00429         IFD_get_capabilities =
00430             rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
00431     }
00432     else
00433         IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
00434 #endif
00435 
00436     /* LOCK THIS CODE REGION */ 
00437     (void)SYS_MutexLock(rContext->mMutex);
00438 
00439 #ifndef PCSCLITE_STATIC_DRIVER
00440     if (rContext->dwVersion == IFD_HVERSION_1_0)
00441     {
00442         ucValue[0] = rContext->dwSlot;
00443         (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00444         rv = (*IFD_is_icc_present) ();
00445     }
00446     else
00447         rv = (*IFDH_icc_presence) (rContext->dwSlot);
00448 #else
00449     if (rContext->dwVersion == IFD_HVERSION_1_0)
00450     {
00451         ucValue[0] = rContext->dwSlot;
00452         (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00453         rv = IFD_Is_ICC_Present();
00454     }
00455     else
00456         rv = IFDHICCPresence(rContext->dwSlot);
00457 #endif
00458 
00459     /* END OF LOCKED REGION */
00460     (void)SYS_MutexUnLock(rContext->mMutex);
00461 
00462     if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00463         dwCardStatus |= SCARD_PRESENT;
00464     else
00465         if (rv == IFD_ICC_NOT_PRESENT)
00466             dwCardStatus |= SCARD_ABSENT;
00467         else
00468         {
00469             Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00470             *pdwStatus = SCARD_UNKNOWN;
00471 
00472             if (rv == IFD_NO_SUCH_DEVICE)
00473             {
00474                 (void)SendHotplugSignal();
00475                 return SCARD_E_READER_UNAVAILABLE;
00476             }
00477 
00478             return SCARD_E_NOT_TRANSACTED;
00479         }
00480 
00481     /*
00482      * Now lets get the ATR and process it if IFD Handler version 1.0.
00483      * IFD Handler version 2.0 does this immediately after reset/power up
00484      * to conserve resources
00485      */
00486 
00487     if (rContext->dwVersion == IFD_HVERSION_1_0)
00488     {
00489         if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00490         {
00491             short ret;
00492 
00493             dwTag = TAG_IFD_ATR;
00494 
00495             /* LOCK THIS CODE REGION */ 
00496             (void)SYS_MutexLock(rContext->mMutex);
00497 
00498             ucValue[0] = rContext->dwSlot;
00499             (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00500 
00501 #ifndef PCSCLITE_STATIC_DRIVER
00502             rv = (*IFD_get_capabilities) (dwTag, pucAtr);
00503 #else
00504             rv = IFD_Get_Capabilities(dwTag, pucAtr);
00505 #endif
00506 
00507             /* END OF LOCKED REGION */
00508             (void)SYS_MutexUnLock(rContext->mMutex);
00509 
00510             /*
00511              * FIX :: This is a temporary way to return the correct size
00512              * of the ATR since most of the drivers return MAX_ATR_SIZE
00513              */
00514 
00515             ret = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);
00516 
00517             /*
00518              * Might be a memory card without an ATR
00519              */
00520             if (ret == 0)
00521                 *pdwAtrLen = 0;
00522             else
00523                 *pdwAtrLen = sSmartCard.ATR.Length;
00524         }
00525         else
00526         {
00527             /*
00528              * No card is inserted - Atr length is 0
00529              */
00530             *pdwAtrLen = 0;
00531         }
00532         /*
00533          * End of FIX
00534          */
00535     }
00536 
00537     *pdwStatus = dwCardStatus;
00538 
00539     return SCARD_S_SUCCESS;
00540 }
00541 
00542 /*
00543  * Function: IFDControl Purpose : This function provides a means for
00544  * toggling a specific action on the reader such as swallow, eject,
00545  * biometric.
00546  */
00547 
00548 /*
00549  * Valid only for IFDHandler version 2.0
00550  */
00551 
00552 LONG IFDControl_v2(PREADER_CONTEXT rContext, PUCHAR TxBuffer,
00553     DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
00554 {
00555     RESPONSECODE rv = IFD_SUCCESS;
00556 
00557 #ifndef PCSCLITE_STATIC_DRIVER
00558     RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, /*@out@*/ PUCHAR,
00559         PDWORD);
00560 #endif
00561 
00562     if (rContext->dwVersion != IFD_HVERSION_2_0)
00563         return SCARD_E_UNSUPPORTED_FEATURE;
00564 
00565 #ifndef PCSCLITE_STATIC_DRIVER
00566     IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
00567 #endif
00568 
00569     /* LOCK THIS CODE REGION */
00570     (void)SYS_MutexLock(rContext->mMutex);
00571 
00572 #ifndef PCSCLITE_STATIC_DRIVER
00573     rv = (*IFDH_control_v2) (rContext->dwSlot, TxBuffer, TxLength,
00574         RxBuffer, RxLength);
00575 #else
00576     rv = IFDHControl_v2(rContext->dwSlot, TxBuffer, TxLength,
00577         RxBuffer, RxLength);
00578 #endif
00579 
00580     /* END OF LOCKED REGION */
00581     (void)SYS_MutexUnLock(rContext->mMutex);
00582 
00583     if (rv == IFD_SUCCESS)
00584         return SCARD_S_SUCCESS;
00585     else
00586     {
00587         Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00588         LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
00589         LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *RxLength);
00590         return SCARD_E_NOT_TRANSACTED;
00591     }
00592 }
00593 
00599 /*
00600  * Valid only for IFDHandler version 3.0 and up
00601  */
00602 
00603 LONG IFDControl(PREADER_CONTEXT rContext, DWORD ControlCode,
00604     LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
00605     LPDWORD BytesReturned)
00606 {
00607     RESPONSECODE rv = IFD_SUCCESS;
00608 
00609 #ifndef PCSCLITE_STATIC_DRIVER
00610     RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
00611 #endif
00612 
00613     if (rContext->dwVersion < IFD_HVERSION_3_0)
00614         return SCARD_E_UNSUPPORTED_FEATURE;
00615 
00616 #ifndef PCSCLITE_STATIC_DRIVER
00617     IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
00618 #endif
00619 
00620     /* LOCK THIS CODE REGION */ 
00621     (void)SYS_MutexLock(rContext->mMutex);
00622 
00623 #ifndef PCSCLITE_STATIC_DRIVER
00624     rv = (*IFDH_control) (rContext->dwSlot, ControlCode, TxBuffer,
00625         TxLength, RxBuffer, RxLength, BytesReturned);
00626 #else
00627     rv = IFDHControl(rContext->dwSlot, ControlCode, TxBuffer,
00628         TxLength, RxBuffer, RxLength, BytesReturned);
00629 #endif
00630 
00631     /* END OF LOCKED REGION */
00632     (void)SYS_MutexUnLock(rContext->mMutex);
00633 
00634     if (rv == IFD_SUCCESS)
00635         return SCARD_S_SUCCESS;
00636     else
00637     {
00638         Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00639         Log3(PCSC_LOG_DEBUG, "ControlCode: 0x%.8Lx BytesReturned: %ld",
00640             ControlCode, *BytesReturned);
00641         LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
00642         LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *BytesReturned);
00643 
00644         if (rv == IFD_NO_SUCH_DEVICE)
00645         {
00646             (void)SendHotplugSignal();
00647             return SCARD_E_READER_UNAVAILABLE;
00648         }
00649 
00650         return SCARD_E_NOT_TRANSACTED;
00651     }
00652 }
00653 
00657 LONG IFDTransmit(PREADER_CONTEXT rContext, SCARD_IO_HEADER pioTxPci,
00658     PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
00659     PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
00660 {
00661     RESPONSECODE rv = IFD_SUCCESS;
00662     UCHAR ucValue[1] = "\x00";
00663 
00664 #ifndef PCSCLITE_STATIC_DRIVER
00665     RESPONSECODE(*IFD_transmit_to_icc) (SCARD_IO_HEADER, PUCHAR, DWORD,
00666         /*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00667     RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
00668         DWORD, /*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00669 #endif
00670 
00671     /* log the APDU */
00672     DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);
00673 
00674 #ifndef PCSCLITE_STATIC_DRIVER
00675     if (rContext->dwVersion == IFD_HVERSION_1_0)
00676         IFD_transmit_to_icc =
00677             rContext->psFunctions.psFunctions_v1.pvfTransmitToICC;
00678     else
00679         IFDH_transmit_to_icc =
00680             rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
00681 #endif
00682 
00683     /* LOCK THIS CODE REGION */ 
00684     (void)SYS_MutexLock(rContext->mMutex);
00685 
00686 #ifndef PCSCLITE_STATIC_DRIVER
00687     if (rContext->dwVersion == IFD_HVERSION_1_0)
00688     {
00689         ucValue[0] = rContext->dwSlot;
00690         (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00691         rv = (*IFD_transmit_to_icc) (pioTxPci, (LPBYTE) pucTxBuffer,
00692             dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
00693     }
00694     else
00695         rv = (*IFDH_transmit_to_icc) (rContext->dwSlot, pioTxPci,
00696             (LPBYTE) pucTxBuffer, dwTxLength,
00697             pucRxBuffer, pdwRxLength, pioRxPci);
00698 #else
00699     if (rContext->dwVersion == IFD_HVERSION_1_0)
00700     {
00701         ucValue[0] = rContext->dwSlot;
00702         (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00703         rv = IFD_Transmit_to_ICC(pioTxPci, (LPBYTE) pucTxBuffer,
00704             dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
00705     }
00706     else
00707         rv = IFDHTransmitToICC(rContext->dwSlot, pioTxPci,
00708             (LPBYTE) pucTxBuffer, dwTxLength,
00709             pucRxBuffer, pdwRxLength, pioRxPci);
00710 #endif
00711 
00712     /* END OF LOCKED REGION */
00713     (void)SYS_MutexUnLock(rContext->mMutex);
00714 
00715     /* log the returned status word */
00716     DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);
00717 
00718     if (rv == IFD_SUCCESS)
00719         return SCARD_S_SUCCESS;
00720     else
00721     {
00722         Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00723 
00724         if (rv == IFD_NO_SUCH_DEVICE)
00725         {
00726             (void)SendHotplugSignal();
00727             return SCARD_E_READER_UNAVAILABLE;
00728         }
00729 
00730         return SCARD_E_NOT_TRANSACTED;
00731     }
00732 }
00733 

Generated on Mon Aug 17 01:00:09 2009 for pcsc-lite by  doxygen 1.5.9