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

Generated on Wed Apr 30 17:11:41 2008 for pcsc-lite by  doxygen 1.5.5