00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00069
00070
00071
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
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
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
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
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
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);
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
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
00250
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, PUCHAR) = NULL;
00282 RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, 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
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
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
00334
00335 rv = IFD_SUCCESS;
00336 dwStatus = 0;
00337 ucValue[0] = 0;
00338
00339
00340
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
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
00382 (void)SYS_MutexUnLock(rContext->mMutex);
00383
00384
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
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, 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
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
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
00483
00484
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
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
00508 (void)SYS_MutexUnLock(rContext->mMutex);
00509
00510
00511
00512
00513
00514
00515 ret = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);
00516
00517
00518
00519
00520 if (ret == 0)
00521 *pdwAtrLen = 0;
00522 else
00523 *pdwAtrLen = sSmartCard.ATR.Length;
00524 }
00525 else
00526 {
00527
00528
00529
00530 *pdwAtrLen = 0;
00531 }
00532
00533
00534
00535 }
00536
00537 *pdwStatus = dwCardStatus;
00538
00539 return SCARD_S_SUCCESS;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
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, 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
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
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
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
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
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 PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00667 RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
00668 DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00669 #endif
00670
00671
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
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
00713 (void)SYS_MutexUnLock(rContext->mMutex);
00714
00715
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