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