Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

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

Generated on Mon Nov 24 18:20:33 2008 for pcsc-lite by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002