📄 tlp3cb.c
字号:
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- Data %ld bytes, SW1=%02x SW2=%02x\n"),
szDriverName,
bytesToRead,
replyBuffer[bytesToRead - 2],
replyBuffer[bytesToRead - 1])
);
}
#endif
}
}
finally {
// Restore pointers to their original location
SmartcardExtension->SmartcardRequest.Buffer =
requestBuffer;
SmartcardExtension->SmartcardReply.Buffer =
replyBuffer;
if (status == STATUS_TIMEOUT) {
// STATUS_TIMEOUT is not mapped to a Win32 error code
status = STATUS_IO_TIMEOUT;
}
if (status == STATUS_SUCCESS) {
status = SmartcardT0Reply(
SmartcardExtension
);
}
}
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3TransmitT0: Exit(%lx)\n"),
szDriverName,
status)
);
return status;
}
NTSTATUS
TLP3Transmit(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
This function is called by the smart card library whenever a transmission
is required.
Arguments:
SmartcardExtension - Pointer to smart card data struct.
Return Value:
NTSTATUS
--*/
{
NTSTATUS status;
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3Transmit: Enter\n"),
szDriverName)
);
_try {
do {
PUCHAR requestBuffer = SmartcardExtension->SmartcardRequest.Buffer;
PUCHAR replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
PULONG replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
PULONG serialIoControlCode = &SmartcardExtension->ReaderExtension->SerialIoControlCode;
//
// Tell the lib function how many bytes I need for the prologue
//
*requestLength = 0;
switch (SmartcardExtension->CardCapabilities.Protocol.Selected) {
case SCARD_PROTOCOL_RAW:
status = SmartcardRawRequest(SmartcardExtension);
break;
case SCARD_PROTOCOL_T0:
//
// T=0 requires a bit more work.
// So we do this in a seperate function.
//
status = TLP3TransmitT0(SmartcardExtension);
leave;
case SCARD_PROTOCOL_T1:
status = SmartcardT1Request(SmartcardExtension);
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
leave;
}
if (status != STATUS_SUCCESS) {
leave;
}
//
// Write the command to the card
//
*replyLength = 0;
*serialIoControlCode = SMARTCARD_WRITE;
status = TLP3SerialIo(SmartcardExtension);
if (status != STATUS_SUCCESS) {
leave;
}
switch (SmartcardExtension->CardCapabilities.Protocol.Selected) {
case SCARD_PROTOCOL_RAW:
status = SmartcardRawReply(SmartcardExtension);
break;
case SCARD_PROTOCOL_T1:
//
// Check if the card requested a waiting time extension
//
if (SmartcardExtension->T1.Wtx) {
DWORD dwMilliSecond=
(SmartcardExtension->T1.Wtx * SmartcardExtension->CardCapabilities.T1.BWT)
/MICROSECONDS_PER_MILLISECOND;
Sleep(dwMilliSecond);
}
//
// Read NAD, PCB and LEN fields
//
*replyLength = 3;
status = TLP3SerialIo(SmartcardExtension);
//
// Check for timeout first. If the card did not reply
// we need to send a resend request
//
if (status != STATUS_TIMEOUT) {
if (status != STATUS_SUCCESS) {
leave;
}
//
// The third byte contains the length of the data in the packet
// and we additinally want to have the EDC bytes which
// is one for LRC and 2 for CRC
//
*replyLength =
replyBuffer[2] +
(SmartcardExtension->CardCapabilities.T1.EDC & 0x01 ? 2 : 1);
// We want to have the remaining bytes just after the first 3
SmartcardExtension->SmartcardReply.Buffer += 3;
status = TLP3SerialIo(SmartcardExtension);
SmartcardExtension->SmartcardReply.Buffer -= 3;
SmartcardExtension->SmartcardReply.BufferLength += 3;
if (status != STATUS_SUCCESS && status != STATUS_TIMEOUT) {
leave;
}
}
if (status == STATUS_TIMEOUT) {
//
// Since the card did not reply we set the number of
// bytes received to 0. This will trigger a resend
// request
//
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT1: Timeout\n"),
szDriverName)
);
SmartcardExtension->SmartcardReply.BufferLength = 0;
}
status = SmartcardT1Reply(SmartcardExtension);
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
leave;
}
} while (status == STATUS_MORE_PROCESSING_REQUIRED);
}
_finally {
if (status == STATUS_TIMEOUT) {
// STATUS_TIMEOUT is not mapped to a Win32 error code
status = STATUS_IO_TIMEOUT;
}
}
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3Transmit: Exit(%lx)\n"),
szDriverName,
status)
);
return status;
}
NTSTATUS
TLP3CardTracking(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
The smart card lib requires to have this function. It is called
to setup event tracking for card insertion and removal events.
Arguments:
SmartcardExtension - pointer to the smart card data struct.
Return Value:
NTSTATUS
--*/
{
SmartcardDebug(
DEBUG_TRACE,
( TEXT("%s!CBCardTracking: Exit \n"),szDriverName )
);
return STATUS_PENDING;
}
NTSTATUS
TLP3VendorIoctl(
PSMARTCARD_EXTENSION SmartcardExtension
)
{
NTSTATUS status;
static TCHAR answer[] = _T("Vendor IOCTL");
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3VendorIoctl: Enter\n"),
szDriverName)
);
#if BEFORECEDAR
if (SmartcardExtension->MajorIoControlCode==IOCTL_INIT_COMPLETE) {
TCHAR szDeviceName[DEVNAME_LEN];
TCHAR szFriendlyName[MAXIMUM_ATTR_STRING_LENGTH+DEVNAME_LEN+5];
//
// Called by the device manager after PSC_Init (assuming the "Ioctl" registry value has been set)
//
// The device name should now be available
status = GetDeviceName(SmartcardExtension->ReaderExtension->d_ActivePath,szDeviceName);
if (NT_SUCCESS(status)) {
PTCHAR pch = szDeviceName;
while (*pch && (*pch < '0' || *pch > '9'))
++pch;
if (*pch)
SmartcardExtension->VendorAttr.UnitNo = *pch - '0';
// Attempt to register a friendly name for this device
// for the benefit of the resource manager.
// The friendly name has the format "PRODUCTNAME [UNITNO]"
// For example, "SCM SwapSmart [1]"
//
MakeFriendlyName(SmartcardExtension, szFriendlyName);
SmartcardCreateLink(szFriendlyName,szDeviceName);
status=STATUS_SUCCESS;
}
}
else
#endif
if (SmartcardExtension->IoRequest.ReplyBuffer != NULL &&
SmartcardExtension->IoRequest.ReplyBufferLength >=
(_tcslen(answer) + 1)*sizeof(TCHAR)) {
_tcscpy((TCHAR *)SmartcardExtension->IoRequest.ReplyBuffer, answer);
*SmartcardExtension->IoRequest.Information = _tcslen(answer);
status = STATUS_SUCCESS;
} else {
status = STATUS_BUFFER_TOO_SMALL;
}
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3VendorIoctl: Exit(%lx)\n"),
szDriverName,
status)
);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -