00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00033
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
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
00112
00113
00114
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
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
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
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
00182
00183
00184 return rv;
00185 }
00186
00187
00188
00189
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
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
00227
00228
00229 return rv;
00230 }
00231
00232
00233
00234
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
00254
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
00276
00277
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
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
00321
00322
00323 return rv;
00324 }
00325
00326
00327
00328
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
00346
00347 rv = 0;
00348 dwStatus = 0;
00349 ucValue[0] = 0;
00350
00351
00352
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
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
00399
00400
00401
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
00418
00419 if (rContext->dwVersion == IFD_HVERSION_1_0)
00420 IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00421
00422 return rv;
00423 }
00424
00425
00426
00427
00428
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
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
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
00507
00508
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
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
00535
00536
00537
00538
00539
00540
00541
00542 rv = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);
00543
00544
00545
00546
00547 if (rv == 0)
00548 *pdwAtrLen = 0;
00549 else
00550 *pdwAtrLen = sSmartCard.ATR.Length;
00551 }
00552 else
00553 {
00554
00555
00556
00557 *pdwAtrLen = 0;
00558 }
00559
00560
00561
00562 }
00563
00564 *pdwStatus = dwCardStatus;
00565
00566 return SCARD_S_SUCCESS;
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576
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
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
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
00623
00624
00625
00626
00627
00628
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
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
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
00685
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
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
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
00750
00751
00752
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