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 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
00107
00108
00109 return rv;
00110 }
00111
00115 LONG IFDOpenIFD(PREADER_CONTEXT rContext)
00116 {
00117 RESPONSECODE rv = 0;
00118
00119 #ifndef PCSCLITE_STATIC_DRIVER
00120 RESPONSECODE(*IO_create_channel) (DWORD) = NULL;
00121 RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
00122 RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPSTR) = NULL;
00123
00124 if (rContext->dwVersion == IFD_HVERSION_1_0)
00125 IO_create_channel =
00126 rContext->psFunctions.psFunctions_v1.pvfCreateChannel;
00127 else
00128 if (rContext->dwVersion == IFD_HVERSION_2_0)
00129 IFDH_create_channel =
00130 rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
00131 else
00132 {
00133 IFDH_create_channel =
00134 rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
00135 IFDH_create_channel_by_name =
00136 rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
00137 }
00138 #endif
00139
00140
00141
00142
00143
00144 SYS_MutexLock(rContext->mMutex);
00145 #ifndef PCSCLITE_STATIC_DRIVER
00146 if (rContext->dwVersion == IFD_HVERSION_1_0)
00147 {
00148 rv = (*IO_create_channel) (rContext->dwPort);
00149 } else if (rContext->dwVersion == IFD_HVERSION_2_0)
00150 {
00151 rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
00152 } else
00153 {
00154
00155 if (rContext->lpcDevice[0] != '\0')
00156 rv = (*IFDH_create_channel_by_name) (rContext->dwSlot, rContext->lpcDevice);
00157 else
00158 rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
00159 }
00160 #else
00161 if (rContext->dwVersion == IFD_HVERSION_1_0)
00162 {
00163 rv = IO_Create_Channel(rContext->dwPort);
00164 } else if (rContext->dwVersion == IFD_HVERSION_2_0)
00165 {
00166 rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
00167 } else
00168 {
00169
00170 if (rContext->lpcDevice[0] != '\0')
00171 rv = IFDHCreateChannelByName(rContext->dwSlot, rContext->lpcDevice);
00172 else
00173 rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
00174 }
00175 #endif
00176 SYS_MutexUnLock(rContext->mMutex);
00177
00178
00179
00180
00181
00182 return rv;
00183 }
00184
00188 LONG IFDCloseIFD(PREADER_CONTEXT rContext)
00189 {
00190 RESPONSECODE rv = IFD_SUCCESS;
00191
00192 #ifndef PCSCLITE_STATIC_DRIVER
00193 RESPONSECODE(*IO_close_channel) (void) = NULL;
00194 RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;
00195
00196 if (rContext->dwVersion == IFD_HVERSION_1_0)
00197 IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel;
00198 else
00199 IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
00200 #endif
00201
00202
00203
00204
00205
00206 rv = SYS_MutexTryLock(rContext->mMutex);
00207 if (EBUSY == rv)
00208 Log1(PCSC_LOG_ERROR, "Locking failed");
00209 #ifndef PCSCLITE_STATIC_DRIVER
00210 if (rContext->dwVersion == IFD_HVERSION_1_0)
00211
00212 rv = (*IO_close_channel) ();
00213 else
00214 rv = (*IFDH_close_channel) (rContext->dwSlot);
00215 #else
00216 if (rContext->dwVersion == IFD_HVERSION_1_0)
00217 rv = IO_Close_Channel();
00218 else
00219 rv = IFDHCloseChannel(rContext->dwSlot);
00220 #endif
00221 SYS_MutexUnLock(rContext->mMutex);
00222
00223
00224
00225
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
00294
00295
00296 SYS_MutexLock(rContext->mMutex);
00297
00298 #ifndef PCSCLITE_STATIC_DRIVER
00299 if (rContext->dwVersion == IFD_HVERSION_1_0)
00300 rv = (*IFD_get_capabilities) (dwTag, pucValue);
00301 else
00302 rv = (*IFDH_get_capabilities) (rContext->dwSlot, dwTag,
00303 pdwLength, pucValue);
00304 #else
00305 if (rContext->dwVersion == IFD_HVERSION_1_0)
00306 rv = IFD_Get_Capabilities(dwTag, pucValue);
00307 else
00308 rv = IFDHGetCapabilities(rContext->dwSlot, dwTag, pdwLength,
00309 pucValue);
00310 #endif
00311
00312 SYS_MutexUnLock(rContext->mMutex);
00313
00314
00315
00316
00317
00318 return rv;
00319 }
00320
00324 LONG IFDPowerICC(PREADER_CONTEXT rContext, DWORD dwAction,
00325 PUCHAR pucAtr, PDWORD pdwAtrLen)
00326 {
00327 RESPONSECODE rv;
00328 short ret;
00329 SMARTCARD_EXTENSION sSmartCard;
00330 DWORD dwStatus;
00331 UCHAR ucValue[1];
00332
00333 #ifndef PCSCLITE_STATIC_DRIVER
00334 RESPONSECODE(*IFD_power_icc) (DWORD) = NULL;
00335 RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL;
00336 #endif
00337
00338
00339
00340
00341 rv = IFD_SUCCESS;
00342 dwStatus = 0;
00343 ucValue[0] = 0;
00344
00345
00346
00347
00348 IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00349
00350 if (dwStatus & SCARD_ABSENT)
00351 return SCARD_W_REMOVED_CARD;
00352 #ifndef PCSCLITE_STATIC_DRIVER
00353 if (rContext->dwVersion == IFD_HVERSION_1_0)
00354 IFD_power_icc = rContext->psFunctions.psFunctions_v1.pvfPowerICC;
00355 else
00356 IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC;
00357 #endif
00358
00359
00360
00361
00362
00363 SYS_MutexLock(rContext->mMutex);
00364
00365 #ifndef PCSCLITE_STATIC_DRIVER
00366 if (rContext->dwVersion == IFD_HVERSION_1_0)
00367 {
00368 ucValue[0] = rContext->dwSlot;
00369 IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00370 rv = (*IFD_power_icc) (dwAction);
00371 }
00372 else
00373 {
00374 rv = (*IFDH_power_icc) (rContext->dwSlot, dwAction,
00375 pucAtr, pdwAtrLen);
00376
00377 ret = ATRDecodeAtr(&sSmartCard, pucAtr, *pdwAtrLen);
00378 }
00379 #else
00380 if (rContext->dwVersion == IFD_HVERSION_1_0)
00381 {
00382 ucValue[0] = rContext->dwSlot;
00383 IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00384 rv = IFD_Power_ICC(dwAction);
00385 }
00386 else
00387 rv = IFDHPowerICC(rContext->dwSlot, dwAction, pucAtr, pdwAtrLen);
00388 #endif
00389 SYS_MutexUnLock(rContext->mMutex);
00390
00391
00392
00393
00394
00395
00396 if (rv != IFD_SUCCESS)
00397 {
00398 *pdwAtrLen = 0;
00399 pucAtr[0] = '\0';
00400
00401 if (rv == IFD_NO_SUCH_DEVICE)
00402 {
00403 SendHotplugSignal();
00404 return SCARD_E_READER_UNAVAILABLE;
00405 }
00406
00407 return SCARD_E_NOT_TRANSACTED;
00408 }
00409
00410
00411
00412
00413 if (rContext->dwVersion == IFD_HVERSION_1_0)
00414 IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00415
00416 return rv;
00417 }
00418
00423 LONG IFDStatusICC(PREADER_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, PUCHAR) = NULL;
00435
00436 if (rContext->dwVersion == 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
00448
00449
00450
00451 SYS_MutexLock(rContext->mMutex);
00452
00453 #ifndef PCSCLITE_STATIC_DRIVER
00454 if (rContext->dwVersion == IFD_HVERSION_1_0)
00455 {
00456 ucValue[0] = rContext->dwSlot;
00457 IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00458 rv = (*IFD_is_icc_present) ();
00459 }
00460 else
00461 rv = (*IFDH_icc_presence) (rContext->dwSlot);
00462 #else
00463 if (rContext->dwVersion == IFD_HVERSION_1_0)
00464 {
00465 ucValue[0] = rContext->dwSlot;
00466 IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00467 rv = IFD_Is_ICC_Present();
00468 }
00469 else
00470 rv = IFDHICCPresence(rContext->dwSlot);
00471 #endif
00472 SYS_MutexUnLock(rContext->mMutex);
00473
00474
00475
00476
00477
00478 if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00479 dwCardStatus |= SCARD_PRESENT;
00480 else
00481 if (rv == IFD_ICC_NOT_PRESENT)
00482 dwCardStatus |= SCARD_ABSENT;
00483 else
00484 {
00485 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00486 *pdwStatus = SCARD_UNKNOWN;
00487
00488 if (rv == IFD_NO_SUCH_DEVICE)
00489 {
00490 SendHotplugSignal();
00491 return SCARD_E_READER_UNAVAILABLE;
00492 }
00493
00494 return SCARD_E_NOT_TRANSACTED;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503 if (rContext->dwVersion == IFD_HVERSION_1_0)
00504 {
00505 if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00506 {
00507 short ret;
00508
00509 dwTag = TAG_IFD_ATR;
00510
00511
00512
00513
00514
00515 SYS_MutexLock(rContext->mMutex);
00516
00517 ucValue[0] = rContext->dwSlot;
00518 IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00519
00520 #ifndef PCSCLITE_STATIC_DRIVER
00521 rv = (*IFD_get_capabilities) (dwTag, pucAtr);
00522 #else
00523 rv = IFD_Get_Capabilities(dwTag, pucAtr);
00524 #endif
00525 SYS_MutexUnLock(rContext->mMutex);
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 ret = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);
00537
00538
00539
00540
00541 if (ret == 0)
00542 *pdwAtrLen = 0;
00543 else
00544 *pdwAtrLen = sSmartCard.ATR.Length;
00545 }
00546 else
00547 {
00548
00549
00550
00551 *pdwAtrLen = 0;
00552 }
00553
00554
00555
00556 }
00557
00558 *pdwStatus = dwCardStatus;
00559
00560 return SCARD_S_SUCCESS;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 LONG IFDControl_v2(PREADER_CONTEXT rContext, PUCHAR TxBuffer,
00574 DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
00575 {
00576 RESPONSECODE rv = IFD_SUCCESS;
00577
00578 #ifndef PCSCLITE_STATIC_DRIVER
00579 RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, PUCHAR, PDWORD);
00580 #endif
00581
00582 if (rContext->dwVersion != IFD_HVERSION_2_0)
00583 return SCARD_E_UNSUPPORTED_FEATURE;
00584
00585 #ifndef PCSCLITE_STATIC_DRIVER
00586 IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
00587 #endif
00588
00589
00590
00591
00592 SYS_MutexLock(rContext->mMutex);
00593
00594 #ifndef PCSCLITE_STATIC_DRIVER
00595 rv = (*IFDH_control_v2) (rContext->dwSlot, TxBuffer, TxLength,
00596 RxBuffer, RxLength);
00597 #else
00598 rv = IFDHControl_v2(rContext->dwSlot, TxBuffer, TxLength,
00599 RxBuffer, RxLength);
00600 #endif
00601 SYS_MutexUnLock(rContext->mMutex);
00602
00603
00604
00605
00606 if (rv == IFD_SUCCESS)
00607 return SCARD_S_SUCCESS;
00608 else
00609 {
00610 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00611 return SCARD_E_NOT_TRANSACTED;
00612 }
00613 }
00614
00620
00621
00622
00623
00624 LONG IFDControl(PREADER_CONTEXT rContext, DWORD ControlCode,
00625 LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
00626 LPDWORD BytesReturned)
00627 {
00628 RESPONSECODE rv = IFD_SUCCESS;
00629
00630 #ifndef PCSCLITE_STATIC_DRIVER
00631 RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
00632 #endif
00633
00634 if (rContext->dwVersion < IFD_HVERSION_3_0)
00635 return SCARD_E_UNSUPPORTED_FEATURE;
00636
00637 #ifndef PCSCLITE_STATIC_DRIVER
00638 IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
00639 #endif
00640
00641
00642
00643
00644
00645 SYS_MutexLock(rContext->mMutex);
00646
00647 #ifndef PCSCLITE_STATIC_DRIVER
00648 rv = (*IFDH_control) (rContext->dwSlot, ControlCode, TxBuffer,
00649 TxLength, RxBuffer, RxLength, BytesReturned);
00650 #else
00651 rv = IFDHControl(rContext->dwSlot, ControlCode, TxBuffer,
00652 TxLength, RxBuffer, RxLength, BytesReturned);
00653 #endif
00654 SYS_MutexUnLock(rContext->mMutex);
00655
00656
00657
00658
00659
00660 if (rv == IFD_SUCCESS)
00661 return SCARD_S_SUCCESS;
00662 else
00663 {
00664 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00665
00666 if (rv == IFD_NO_SUCH_DEVICE)
00667 {
00668 SendHotplugSignal();
00669 return SCARD_E_READER_UNAVAILABLE;
00670 }
00671
00672 return SCARD_E_NOT_TRANSACTED;
00673 }
00674 }
00675
00679 LONG IFDTransmit(PREADER_CONTEXT rContext, SCARD_IO_HEADER pioTxPci,
00680 PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
00681 PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
00682 {
00683 RESPONSECODE rv = IFD_SUCCESS;
00684 UCHAR ucValue[1] = "\x00";
00685
00686 #ifndef PCSCLITE_STATIC_DRIVER
00687 RESPONSECODE(*IFD_transmit_to_icc) (SCARD_IO_HEADER, PUCHAR, DWORD,
00688 PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00689 RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
00690 DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00691 #endif
00692
00693
00694 DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);
00695
00696 #ifndef PCSCLITE_STATIC_DRIVER
00697 if (rContext->dwVersion == IFD_HVERSION_1_0)
00698 IFD_transmit_to_icc =
00699 rContext->psFunctions.psFunctions_v1.pvfTransmitToICC;
00700 else
00701 IFDH_transmit_to_icc =
00702 rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
00703 #endif
00704
00705
00706
00707
00708
00709 SYS_MutexLock(rContext->mMutex);
00710
00711
00712 #ifndef PCSCLITE_STATIC_DRIVER
00713 if (rContext->dwVersion == IFD_HVERSION_1_0)
00714 {
00715 ucValue[0] = rContext->dwSlot;
00716 IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00717 rv = (*IFD_transmit_to_icc) (pioTxPci, (LPBYTE) pucTxBuffer,
00718 dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
00719 }
00720 else
00721 rv = (*IFDH_transmit_to_icc) (rContext->dwSlot, pioTxPci,
00722 (LPBYTE) pucTxBuffer, dwTxLength,
00723 pucRxBuffer, pdwRxLength, pioRxPci);
00724 #else
00725 if (rContext->dwVersion == IFD_HVERSION_1_0)
00726 {
00727 ucValue[0] = rContext->dwSlot;
00728 IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00729 rv = IFD_Transmit_to_ICC(pioTxPci, (LPBYTE) pucTxBuffer,
00730 dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
00731 }
00732 else
00733 rv = IFDHTransmitToICC(rContext->dwSlot, pioTxPci,
00734 (LPBYTE) pucTxBuffer, dwTxLength,
00735 pucRxBuffer, pdwRxLength, pioRxPci);
00736 #endif
00737 SYS_MutexUnLock(rContext->mMutex);
00738
00739
00740
00741
00742
00743
00744 DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);
00745
00746 if (rv == IFD_SUCCESS)
00747 return SCARD_S_SUCCESS;
00748 else
00749 {
00750 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00751
00752 if (rv == IFD_NO_SUCH_DEVICE)
00753 {
00754 SendHotplugSignal();
00755 return SCARD_E_READER_UNAVAILABLE;
00756 }
00757
00758 return SCARD_E_NOT_TRANSACTED;
00759 }
00760 }
00761