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 1827 2006-01-24 14:49:52Z rousseau $
00010  */
00011 
00017 #include "config.h"
00018 #include "misc.h"
00019 #include "pcsclite.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 
00028 #undef PCSCLITE_STATIC_DRIVER
00029 
00030 /*
00031  * Function: IFDSetPTS Purpose : To set the protocol type selection (PTS). 
00032  * This function sets the appropriate protocol to be used on the card. 
00033  */
00034 
00035 LONG IFDSetPTS(PREADER_CONTEXT rContext, DWORD dwProtocol, UCHAR ucFlags,
00036     UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
00037 {
00038     RESPONSECODE rv = 0;
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 
00111 /*
00112  * Function: IFDOpenIFD Purpose : This function opens a communication
00113  * channel to the IFD. 
00114  */
00115 
00116 LONG IFDOpenIFD(PREADER_CONTEXT rContext)
00117 {
00118     RESPONSECODE rv = 0;
00119 
00120 #ifndef PCSCLITE_STATIC_DRIVER
00121     RESPONSECODE(*IO_create_channel) (DWORD) = NULL;
00122     RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
00123     RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPTSTR) = NULL;
00124 
00125     if (rContext->dwVersion == IFD_HVERSION_1_0)
00126         IO_create_channel =
00127             rContext->psFunctions.psFunctions_v1.pvfCreateChannel;
00128     else
00129         if (rContext->dwVersion == IFD_HVERSION_2_0)
00130             IFDH_create_channel =
00131                 rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
00132         else
00133         {
00134             IFDH_create_channel =
00135                 rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
00136             IFDH_create_channel_by_name =
00137                 rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
00138         }
00139 #endif
00140 
00141     /*
00142      * LOCK THIS CODE REGION 
00143      */
00144 
00145     SYS_MutexLock(rContext->mMutex);
00146 #ifndef PCSCLITE_STATIC_DRIVER
00147     if (rContext->dwVersion == IFD_HVERSION_1_0)
00148     {
00149         rv = (*IO_create_channel) (rContext->dwPort);
00150     } else if (rContext->dwVersion == IFD_HVERSION_2_0)
00151     {
00152         rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
00153     } else
00154     {
00155         /* use device name only if defined */
00156         if (rContext->lpcDevice[0] != '\0')
00157             rv = (*IFDH_create_channel_by_name) (rContext->dwSlot, rContext->lpcDevice);
00158         else
00159             rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
00160     }
00161 #else
00162     if (rContext->dwVersion == IFD_HVERSION_1_0)
00163     {
00164         rv = IO_Create_Channel(rContext->dwPort);
00165     } else if (rContext->dwVersion == IFD_HVERSION_2_0)
00166     { 
00167         rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
00168     } else
00169     {
00170         /* Use device name only if defined */
00171         if (rContext->lpcDevice[0] != '\0')
00172             rv = IFDHCreateChannelByName(rContext->dwSlot, rContext->lpcDevice);
00173         else
00174             rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
00175     }
00176 #endif
00177     SYS_MutexUnLock(rContext->mMutex);
00178 
00179     /*
00180      * END OF LOCKED REGION 
00181      */
00182 
00183     return rv;
00184 }
00185 
00186 /*
00187  * Function: IFDCloseIFD Purpose : This function closes a communication
00188  * channel to the IFD. 
00189  */
00190 
00191 LONG IFDCloseIFD(PREADER_CONTEXT rContext)
00192 {
00193     RESPONSECODE rv = 0;
00194 
00195 #ifndef PCSCLITE_STATIC_DRIVER
00196     RESPONSECODE(*IO_close_channel) () = NULL;
00197     RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;
00198 
00199     if (rContext->dwVersion == IFD_HVERSION_1_0)
00200         IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel;
00201     else
00202         IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
00203 #endif
00204 
00205     /*
00206      * LOCK THIS CODE REGION 
00207      */
00208 
00209     SYS_MutexLock(rContext->mMutex);
00210 #ifndef PCSCLITE_STATIC_DRIVER
00211     if (rContext->dwVersion == IFD_HVERSION_1_0)
00212     
00213         rv = (*IO_close_channel) ();
00214     else
00215         rv = (*IFDH_close_channel) (rContext->dwSlot);
00216 #else
00217     if (rContext->dwVersion == IFD_HVERSION_1_0)
00218         rv = IO_Close_Channel();
00219     else
00220         rv = IFDHCloseChannel(rContext->dwSlot);
00221 #endif
00222     SYS_MutexUnLock(rContext->mMutex);
00223 
00224     /*
00225      * END OF LOCKED REGION 
00226      */
00227 
00228     return rv;
00229 }
00230 
00231 /*
00232  * Function: IFDSetCapabilites Purpose : This function set's capabilities
00233  * in the reader. 
00234  */
00235 
00236 LONG IFDSetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
00237             DWORD dwLength, PUCHAR pucValue)
00238 {
00239     LONG rv = 0;
00240 
00241 #ifndef PCSCLITE_STATIC_DRIVER
00242     RESPONSECODE(*IFD_set_capabilities) (DWORD, PUCHAR) = NULL;
00243     RESPONSECODE(*IFDH_set_capabilities) (DWORD, DWORD, DWORD, PUCHAR) = NULL;
00244 
00245     if (rContext->dwVersion == IFD_HVERSION_1_0)
00246         IFD_set_capabilities = rContext->psFunctions.psFunctions_v1.pvfSetCapabilities;
00247     else
00248         IFDH_set_capabilities = rContext->psFunctions.psFunctions_v2.pvfSetCapabilities;
00249 #endif
00250 
00251     /*
00252      * Let the calling function lock this otherwise a deadlock will
00253      * result 
00254      */
00255 
00256 #ifndef PCSCLITE_STATIC_DRIVER
00257     if (rContext->dwVersion == IFD_HVERSION_1_0)
00258         rv = (*IFD_set_capabilities) (dwTag, pucValue);
00259     else
00260         rv = (*IFDH_set_capabilities) (rContext->dwSlot, dwTag,
00261             dwLength, pucValue);
00262 #else
00263     if (rContext->dwVersion == IFD_HVERSION_1_0)
00264         rv = IFD_Set_Capabilities(dwTag, pucValue);
00265     else
00266         rv = IFDHSetCapabilities(rContext->dwSlot, dwTag, dwLength,
00267             pucValue);
00268 #endif
00269 
00270     return rv;
00271 }
00272 
00273 /*
00274  * Function: IFDGetCapabilites Purpose : This function get's capabilities
00275  * in the reader. Other functions int this file will call the driver
00276  * directly to not cause a deadlock. 
00277  */
00278 
00279 LONG IFDGetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
00280     PDWORD pdwLength, PUCHAR pucValue)
00281 {
00282     LONG rv = 0;
00283 
00284 #ifndef PCSCLITE_STATIC_DRIVER
00285     RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
00286     RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, PUCHAR) = NULL;
00287 
00288     if (rContext->dwVersion == IFD_HVERSION_1_0)
00289         IFD_get_capabilities =
00290             rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
00291     else
00292         IFDH_get_capabilities =
00293             rContext->psFunctions.psFunctions_v2.pvfGetCapabilities;
00294 #endif
00295 
00296     /*
00297      * LOCK THIS CODE REGION 
00298      */
00299 
00300     SYS_MutexLock(rContext->mMutex);
00301 
00302 #ifndef PCSCLITE_STATIC_DRIVER
00303     if (rContext->dwVersion == IFD_HVERSION_1_0)
00304         rv = (*IFD_get_capabilities) (dwTag, pucValue);
00305     else
00306         rv = (*IFDH_get_capabilities) (rContext->dwSlot, dwTag,
00307             pdwLength, pucValue);
00308 #else
00309     if (rContext->dwVersion == IFD_HVERSION_1_0)
00310         rv = IFD_Get_Capabilities(dwTag, pucValue);
00311     else
00312         rv = IFDHGetCapabilities(rContext->dwSlot, dwTag, pdwLength,
00313             pucValue);
00314 #endif
00315 
00316     SYS_MutexUnLock(rContext->mMutex);
00317 
00318     /*
00319      * END OF LOCKED REGION 
00320      */
00321 
00322     return rv;
00323 }
00324 
00325 /*
00326  * Function: IFDPowerICC Purpose : This function powers up/down or reset's 
00327  * an ICC located in the IFD. 
00328  */
00329 
00330 LONG IFDPowerICC(PREADER_CONTEXT rContext, DWORD dwAction,
00331     PUCHAR pucAtr, PDWORD pdwAtrLen)
00332 {
00333     RESPONSECODE rv, ret;
00334     SMARTCARD_EXTENSION sSmartCard;
00335     DWORD dwStatus;
00336     UCHAR ucValue[1];
00337 
00338 #ifndef PCSCLITE_STATIC_DRIVER
00339     RESPONSECODE(*IFD_power_icc) (DWORD) = NULL;
00340     RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL;
00341 #endif
00342 
00343     /*
00344      * Zero out everything 
00345      */
00346     rv = 0;
00347     dwStatus = 0;
00348     ucValue[0] = 0;
00349 
00350     /*
00351      * Check that the card is inserted first 
00352      */
00353     IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00354 
00355     if (dwStatus & SCARD_ABSENT)
00356         return SCARD_W_REMOVED_CARD;
00357 #ifndef PCSCLITE_STATIC_DRIVER
00358     if (rContext->dwVersion == IFD_HVERSION_1_0)
00359         IFD_power_icc = rContext->psFunctions.psFunctions_v1.pvfPowerICC;
00360     else
00361         IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC;
00362 #endif
00363 
00364     /*
00365      * LOCK THIS CODE REGION 
00366      */
00367 
00368     SYS_MutexLock(rContext->mMutex);
00369 
00370 #ifndef PCSCLITE_STATIC_DRIVER
00371     if (rContext->dwVersion == IFD_HVERSION_1_0)
00372     {
00373         ucValue[0] = rContext->dwSlot;
00374         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00375         rv = (*IFD_power_icc) (dwAction);
00376     }
00377     else
00378     {
00379         rv = (*IFDH_power_icc) (rContext->dwSlot, dwAction,
00380             pucAtr, pdwAtrLen);
00381 
00382         ret = ATRDecodeAtr(&sSmartCard, pucAtr, *pdwAtrLen);
00383     }
00384 #else
00385     if (rContext->dwVersion == IFD_HVERSION_1_0)
00386     {
00387         ucValue[0] = rContext->dwSlot;
00388         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00389         rv = IFD_Power_ICC(dwAction);
00390     }
00391     else
00392         rv = IFDHPowerICC(rContext->dwSlot, dwAction, pucAtr, pdwAtrLen);
00393 #endif
00394     SYS_MutexUnLock(rContext->mMutex);
00395 
00396     /*
00397      * END OF LOCKED REGION 
00398      */
00399 
00400     /* use clean values in case of error */
00401     if (rv != IFD_SUCCESS)
00402     {
00403         *pdwAtrLen = 0;
00404         pucAtr[0] = '\0';
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 
00416 /*
00417  * Function: IFDStatusICC Purpose : This function provides statistical
00418  * information about the IFD and ICC including insertions, atr, powering
00419  * status/etc. 
00420  */
00421 
00422 LONG IFDStatusICC(PREADER_CONTEXT rContext, PDWORD pdwStatus,
00423     PUCHAR pucAtr, PDWORD pdwAtrLen)
00424 {
00425     RESPONSECODE rv = 0;
00426     DWORD dwTag = 0, dwCardStatus = 0;
00427     SMARTCARD_EXTENSION sSmartCard;
00428     UCHAR ucValue[1] = "\x00";
00429 
00430 #ifndef PCSCLITE_STATIC_DRIVER
00431     RESPONSECODE(*IFD_is_icc_present) () = NULL;
00432     RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;
00433     RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
00434 
00435     if (rContext->dwVersion == IFD_HVERSION_1_0)
00436     {
00437         IFD_is_icc_present =
00438             rContext->psFunctions.psFunctions_v1.pvfICCPresence;
00439         IFD_get_capabilities =
00440             rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
00441     }
00442     else
00443         IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
00444 #endif
00445 
00446     /*
00447      * LOCK THIS CODE REGION 
00448      */
00449 
00450     SYS_MutexLock(rContext->mMutex);
00451 
00452 #ifndef PCSCLITE_STATIC_DRIVER
00453     if (rContext->dwVersion == IFD_HVERSION_1_0)
00454     {
00455         ucValue[0] = rContext->dwSlot;
00456         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00457         rv = (*IFD_is_icc_present) ();
00458     }
00459     else
00460         rv = (*IFDH_icc_presence) (rContext->dwSlot);
00461 #else
00462     if (rContext->dwVersion == IFD_HVERSION_1_0)
00463     {
00464         ucValue[0] = rContext->dwSlot;
00465         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00466         rv = IFD_Is_ICC_Present();
00467     }
00468     else
00469         rv = IFDHICCPresence(rContext->dwSlot);
00470 #endif
00471     SYS_MutexUnLock(rContext->mMutex);
00472 
00473     /*
00474      * END OF LOCKED REGION 
00475      */
00476 
00477     if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00478         dwCardStatus |= SCARD_PRESENT;
00479     else
00480         if (rv == IFD_ICC_NOT_PRESENT)
00481             dwCardStatus |= SCARD_ABSENT;
00482         else
00483         {
00484             Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00485             return SCARD_E_NOT_TRANSACTED;
00486         }
00487 
00488     /*
00489      * Now lets get the ATR and process it if IFD Handler version 1.0.
00490      * IFD Handler version 2.0 does this immediately after reset/power up
00491      * to conserve resources 
00492      */
00493 
00494     if (rContext->dwVersion == IFD_HVERSION_1_0)
00495     {
00496         if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00497         {
00498             dwTag = TAG_IFD_ATR;
00499 
00500             /*
00501              * LOCK THIS CODE REGION 
00502              */
00503 
00504             SYS_MutexLock(rContext->mMutex);
00505 
00506             ucValue[0] = rContext->dwSlot;
00507             IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00508 
00509 #ifndef PCSCLITE_STATIC_DRIVER
00510             rv = (*IFD_get_capabilities) (dwTag, pucAtr);
00511 #else
00512             rv = IFD_Get_Capabilities(dwTag, pucAtr);
00513 #endif
00514             SYS_MutexUnLock(rContext->mMutex);
00515 
00516             /*
00517              * END OF LOCKED REGION 
00518              */
00519 
00520             /*
00521              * FIX :: This is a temporary way to return the correct size
00522              * of the ATR since most of the drivers return MAX_ATR_SIZE 
00523              */
00524 
00525             rv = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);
00526 
00527             /*
00528              * Might be a memory card without an ATR 
00529              */
00530             if (rv == 0)
00531                 *pdwAtrLen = 0;
00532             else
00533                 *pdwAtrLen = sSmartCard.ATR.Length;
00534         }
00535         else
00536         {
00537             /*
00538              * No card is inserted - Atr length is 0 
00539              */
00540             *pdwAtrLen = 0;
00541         }
00542         /*
00543          * End of FIX 
00544          */
00545     }
00546 
00547     *pdwStatus = dwCardStatus;
00548 
00549     return SCARD_S_SUCCESS;
00550 }
00551 
00552 /*
00553  * Function: IFDControl Purpose : This function provides a means for
00554  * toggling a specific action on the reader such as swallow, eject,
00555  * biometric. 
00556  */
00557 
00558 /*
00559  * Valid only for IFDHandler version 2.0
00560  */
00561 
00562 LONG IFDControl_v2(PREADER_CONTEXT rContext, PUCHAR TxBuffer,
00563     DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
00564 {
00565     RESPONSECODE rv = 0;
00566 
00567 #ifndef PCSCLITE_STATIC_DRIVER
00568     RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, PUCHAR, PDWORD);
00569 #endif
00570 
00571     if (rContext->dwVersion != IFD_HVERSION_2_0)
00572         return SCARD_E_UNSUPPORTED_FEATURE;
00573 
00574 #ifndef PCSCLITE_STATIC_DRIVER
00575     IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
00576 #endif
00577 
00578     /*
00579      * LOCK THIS CODE REGION 
00580      */
00581     SYS_MutexLock(rContext->mMutex);
00582 
00583 #ifndef PCSCLITE_STATIC_DRIVER
00584     rv = (*IFDH_control_v2) (rContext->dwSlot, TxBuffer, TxLength,
00585         RxBuffer, RxLength);
00586 #else
00587     rv = IFDHControl_v2(rContext->dwSlot, TxBuffer, TxLength,
00588         RxBuffer, RxLength);
00589 #endif
00590     SYS_MutexUnLock(rContext->mMutex);
00591     /*
00592      * END OF LOCKED REGION 
00593      */
00594 
00595     if (rv == IFD_SUCCESS)
00596         return SCARD_S_SUCCESS;
00597     else
00598     {
00599         Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00600         return SCARD_E_NOT_TRANSACTED;
00601     }
00602 }
00603 
00604 /*
00605  * Function: IFDControl Purpose : This function provides a means for
00606  * toggling a specific action on the reader such as swallow, eject,
00607  * biometric. 
00608  */
00609 
00610 /*
00611  * Valid only for IFDHandler version 3.0 and up
00612  */
00613 
00614 LONG IFDControl(PREADER_CONTEXT rContext, DWORD ControlCode,
00615     LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
00616     LPDWORD BytesReturned)
00617 {
00618     RESPONSECODE rv = 0;
00619 
00620 #ifndef PCSCLITE_STATIC_DRIVER
00621     RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
00622 #endif
00623 
00624     if (rContext->dwVersion < IFD_HVERSION_3_0)
00625         return SCARD_E_UNSUPPORTED_FEATURE;
00626 
00627 #ifndef PCSCLITE_STATIC_DRIVER
00628     IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
00629 #endif
00630 
00631     /*
00632      * LOCK THIS CODE REGION 
00633      */
00634 
00635     SYS_MutexLock(rContext->mMutex);
00636 
00637 #ifndef PCSCLITE_STATIC_DRIVER
00638     rv = (*IFDH_control) (rContext->dwSlot, ControlCode, TxBuffer,
00639         TxLength, RxBuffer, RxLength, BytesReturned);
00640 #else
00641     rv = IFDHControl(rContext->dwSlot, ControlCode, TxBuffer,
00642         TxLength, RxBuffer, RxLength, BytesReturned);
00643 #endif
00644     SYS_MutexUnLock(rContext->mMutex);
00645 
00646     /*
00647      * END OF LOCKED REGION 
00648      */
00649 
00650     if (rv == IFD_SUCCESS)
00651         return SCARD_S_SUCCESS;
00652     else
00653     {
00654         Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00655         return SCARD_E_NOT_TRANSACTED;
00656     }
00657 }
00658 
00659 /*
00660  * Function: IFDTransmit Purpose : This function transmits an APDU to the
00661  * ICC. 
00662  */
00663 
00664 LONG IFDTransmit(PREADER_CONTEXT rContext, SCARD_IO_HEADER pioTxPci,
00665     PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
00666     PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
00667 {
00668     RESPONSECODE rv = 0;
00669     UCHAR ucValue[1] = "\x00";
00670 
00671 #ifndef PCSCLITE_STATIC_DRIVER
00672     RESPONSECODE(*IFD_transmit_to_icc) (SCARD_IO_HEADER, PUCHAR, DWORD,
00673         PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00674     RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
00675         DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00676 #endif
00677 
00678     /* log the APDU */
00679     DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);
00680 
00681 #ifndef PCSCLITE_STATIC_DRIVER
00682     if (rContext->dwVersion == IFD_HVERSION_1_0)
00683         IFD_transmit_to_icc =
00684             rContext->psFunctions.psFunctions_v1.pvfTransmitToICC;
00685     else
00686         IFDH_transmit_to_icc =
00687             rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
00688 #endif
00689 
00690     /*
00691      * LOCK THIS CODE REGION 
00692      */
00693 
00694     SYS_MutexLock(rContext->mMutex);
00695 
00696 
00697 #ifndef PCSCLITE_STATIC_DRIVER
00698     if (rContext->dwVersion == IFD_HVERSION_1_0)
00699     {
00700         ucValue[0] = rContext->dwSlot;
00701         IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00702         rv = (*IFD_transmit_to_icc) (pioTxPci, (LPBYTE) pucTxBuffer,
00703             dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
00704     }
00705     else
00706         rv = (*IFDH_transmit_to_icc) (rContext->dwSlot, pioTxPci,
00707             (LPBYTE) pucTxBuffer, dwTxLength,
00708             pucRxBuffer, pdwRxLength, pioRxPci);
00709 #else
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 = IFDHTransmitToICC(rContext->dwSlot, pioTxPci,
00719             (LPBYTE) pucTxBuffer, dwTxLength,
00720             pucRxBuffer, pdwRxLength, pioRxPci);
00721 #endif
00722     SYS_MutexUnLock(rContext->mMutex);
00723 
00724     /*
00725      * END OF LOCKED REGION 
00726      */
00727 
00728     /* log the returned status word */
00729     DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);
00730 
00731     if (rv == IFD_SUCCESS)
00732         return SCARD_S_SUCCESS;
00733     else
00734     {
00735         Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00736         return SCARD_E_NOT_TRANSACTED;
00737     }
00738 }
00739 

Generated on Sat Apr 22 16:37:47 2006 for pcsc-lite by  doxygen 1.4.6