📄 tlp3cb.c
字号:
}
if (status != STATUS_TIMEOUT &&
memcmp(ptsRequest, ptsReply, 4) == 0) {
// the card replied correctly to our pts-request
break;
}
if (SmartcardExtension->CardCapabilities.PtsData.Type !=
PTS_TYPE_DEFAULT) {
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3SetProtocol: PTS failed. Trying default parameters...\n"),
szDriverName,
status)
);
//
// The card did either NOT reply or it replied incorrectly
// so try default values
//
SmartcardExtension->CardCapabilities.PtsData.Type =
PTS_TYPE_DEFAULT;
SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
status = TLP3ReaderPower(SmartcardExtension);
continue;
}
// the card failed the pts-request
status = STATUS_DEVICE_PROTOCOL_ERROR;
leave;
}
if (!QueryPerformanceFrequency(&liProcessClock)) { // not supported
// ASSUME it is 66 Mhz CPU Clock
liProcessClock.HighPart=0;
liProcessClock.LowPart=66*1000000L;
};
// Minimum wait set to 5k instruction in Milli Second.
liProcessClock.QuadPart/=1000; // Frequncy in Milli Second.
minWaitTime = (DWORD) ((5000L*5+liProcessClock.QuadPart/2)/(liProcessClock.QuadPart));
// now indicate that we're in specific mode
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_SPECIFIC;
// return the selected protocol to the caller
*(PULONG) SmartcardExtension->IoRequest.ReplyBuffer =
SmartcardExtension->CardCapabilities.Protocol.Selected;
*SmartcardExtension->IoRequest.Information =
sizeof(SmartcardExtension->CardCapabilities.Protocol.Selected);
}
finally {
if (status == STATUS_TIMEOUT) {
// STATUS_TIMEOUT is not mapped to a Win32 error code
status = STATUS_IO_TIMEOUT;
*SmartcardExtension->IoRequest.Information = 0;
} else if (status != STATUS_SUCCESS) {
SmartcardExtension->CardCapabilities.Protocol.Selected =
SCARD_PROTOCOL_UNDEFINED;
*SmartcardExtension->IoRequest.Information = 0;
}
}
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3SetProtocol: Exit(%lx)\n"),
szDriverName,
status)
);
return status;
}
NTSTATUS
TLP3TransmitT0(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
This function performs a T=0 transmission.
Arguments:
SmartcardExtension - Pointer to smart card data struct.
Return Value:
NTSTATUS
--*/
{
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;
ULONG bytesToSend, bytesToRead, currentByte = 0;
BOOLEAN restartWorkWaitingTime = FALSE;
DWORD dwMilliSecond;
NTSTATUS status;
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3TransmitT0: Enter\n"),
szDriverName)
);
try {
// Let the lib build a T=0 packet
status = SmartcardT0Request(
SmartcardExtension
);
if (status != STATUS_SUCCESS)
leave;
//
// The number of bytes we expect from the card
// is Le + 2 status bytes
//
bytesToSend = *requestLength;
bytesToRead = SmartcardExtension->T0.Le + 3;
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3TransmitT0: Send %d and Received %d \n"),
szDriverName,bytesToSend,bytesToRead)
);
//
// Send the first 5 bytes to the card
//
*requestLength = 5;
do {
UCHAR procByte;
//
// According to ISO 7816 a procedure byte of
// 60 should be treated as a request for a one time wait.
// In this case we do not write anything to the card
//
if (restartWorkWaitingTime == FALSE) {
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: -> Sending %s (%ld bytes)\n"),
szDriverName,
(currentByte == 0 ? TEXT("header") : TEXT("data")),
*requestLength)
);
//
// Write to the card
//
*serialIoControlCode = SMARTCARD_WRITE;
SmartcardExtension->SmartcardRequest.Buffer = &requestBuffer[currentByte];
status = TLP3SerialIo(
SmartcardExtension
);
if (status != STATUS_SUCCESS)
{
DEBUGMSG(1,(TEXT("status != STATUS_SUCCESS, leave====>>>\r\n")));
leave;
}
currentByte += *requestLength;
bytesToSend -= *requestLength;
}
if((*requestLength ==5)&&(bytesToSend==0)){
*serialIoControlCode = SMARTCARD_READ;
*replyLength = bytesToRead;
status = TLP3SerialIo(
SmartcardExtension
);
if (status != STATUS_SUCCESS)
leave;
SmartcardExtension->SmartcardReply.BufferLength = bytesToRead;
restartWorkWaitingTime = TRUE;
bytesToSend = 0;
bytesToRead = 0;
break;
}else{
// Read the 'Procedure byte'.
SmartcardExtension->SmartcardReply.Buffer = &procByte;
*serialIoControlCode = SMARTCARD_READ;
*replyLength = 1;
status = TLP3SerialIo(
SmartcardExtension
);
if (status != STATUS_SUCCESS)
leave;
restartWorkWaitingTime = FALSE;
}
//
// Check the procedure byte.
// Please take a look at ISO 7816 Part 3 Section 8.2.2
//
if (procByte == requestBuffer[1] ||
procByte == requestBuffer[1] + 1) {
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- ACK (send all)\n"),
szDriverName)
);
// All remaining data bytes can be sent at once
*requestLength = bytesToSend;
} else if (procByte == (UCHAR) ~requestBuffer[1] ||
procByte == (UCHAR) ~(requestBuffer[1] + 1)) {
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- ACK (send single)\n"),
szDriverName)
);
// We can send only one byte
*requestLength = 1;
} else if (procByte == 0x60 ||
SmartcardExtension->CardCapabilities.InversConvention &&
procByte == 0xf9) {
//
// We have to reset the wait time and try again to read
//
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- NULL (%ldms)\n"),
szDriverName,
SmartcardExtension->CardCapabilities.T0.WT / 1000)
);
dwMilliSecond=(SmartcardExtension->CardCapabilities.T0.WT+MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
if (dwMilliSecond) {
Sleep(dwMilliSecond);
}
//
// Set flag that we only should read the proc byte
// without writing data to the card
//
restartWorkWaitingTime = TRUE;
} else {
//
// The card returned a status byte.
// Status bytes are always two bytes long.
// Store this byte first and then read the next
//
replyBuffer[0] = procByte;
*serialIoControlCode = SMARTCARD_READ;
*replyLength = 1;
bytesToSend = 0;
bytesToRead = 0;
replyBuffer[1] = *(SmartcardExtension->SmartcardReply.Buffer + 1) ;
SmartcardExtension->SmartcardReply.BufferLength = 2;
//DEBUGMSG(1,(TEXT("*replyBuffer = 0x%x\r\n"),*SmartcardExtension->SmartcardReply.Buffer));
//DEBUGMSG(1,(TEXT("*replyBuffer+1 = 0x%x\r\n"),*(SmartcardExtension->SmartcardReply.Buffer+1)));
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!TLP3TransmitT0: <- SW1=%02x SW2=%02x\n"),
szDriverName,
replyBuffer[0],
replyBuffer[1])
);
}
} while(bytesToSend || restartWorkWaitingTime);
if (status != STATUS_SUCCESS)
leave;
if (bytesToRead != 0) {
*serialIoControlCode = SMARTCARD_READ;
*replyLength = bytesToRead;
SmartcardExtension->SmartcardReply.Buffer =
replyBuffer;
status = TLP3SerialIo(
SmartcardExtension
);
#if DBG || DEBUG
if (status == STATUS_SUCCESS) {
SmartcardDebug(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -