pcsc-lite 1.5.5
|
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 4222 2009-05-22 11:39:14Z 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