📄 tlp3cb.c
字号:
} else if (SmartcardExtension->CardCapabilities.Protocol.Selected &
SCARD_PROTOCOL_T0) {
// set timeouts
pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=
(SmartcardExtension->CardCapabilities.T0.WT +
MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
}
// Now make some adjustments depending on the system speed
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.LowPart/=1000; // Frequncy in Milli Second.
minWaitTime = (DWORD) ((5000L*5+liProcessClock.QuadPart/2)/(liProcessClock.QuadPart));
pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
max(pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant,minWaitTime);
pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=
max(pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout,minWaitTime);
status = TLP3ConfigureSerialPort(SmartcardExtension);
ASSERT(status == STATUS_SUCCESS);
// We're done anyway, so leave
leave;
}
if (!NT_SUCCESS(status)) {
leave;
}
//convert MicroSecond to Millisecond
if (waitTime) {
waitTime=(waitTime+MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
Sleep(waitTime);
}
}
}
_finally {
if (status == STATUS_TIMEOUT) {
status = STATUS_UNRECOGNIZED_MEDIA;
}
SmartcardExtension->ReaderExtension->PowerRequest = FALSE;
}
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3ReaderPower: Exit (%lx)\n"),
szDriverName,
status)
);
return status;
}
NTSTATUS
TLP3SetProtocol(
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
The smart card lib requires to have this function. It is called
to set a the transmission protocol and parameters. If this function
is called with a protocol mask (which means the caller doesn't card
about a particular protocol to be set) we first look if we can
set T=1 and the T=0
Arguments:
SmartcardExtension - Pointer to smart card data struct.
Return Value:
NTSTATUS
--*/
{
NTSTATUS status;
LARGE_INTEGER liProcessClock;
PREADER_EXTENSION pReaderExtension=SmartcardExtension->ReaderExtension;
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3SetProtocol: Enter\n"),
szDriverName)
);
try {
PUCHAR ptsRequest = SmartcardExtension->SmartcardRequest.Buffer;
PUCHAR ptsReply = SmartcardExtension->SmartcardReply.Buffer;
PSERIAL_READER_CONFIG serialConfigData =
&SmartcardExtension->ReaderExtension->SerialConfigData;
ULONG minWaitTime, newProtocol;
//
// Check if the card is already in specific state
// and if the caller wants to have the already selected protocol.
// We return success if this is the case.
//
if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC &&
(SmartcardExtension->CardCapabilities.Protocol.Selected &
SmartcardExtension->MinorIoControlCode)) {
status = STATUS_SUCCESS;
leave;
}
// set normal timeout
serialConfigData->Timeouts.ReadIntervalTimeout =
READ_INTERVAL_TIMEOUT_DEFAULT;
serialConfigData->Timeouts.ReadTotalTimeoutConstant =
READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;
status = TLP3ConfigureSerialPort(SmartcardExtension);
ASSERT(status == STATUS_SUCCESS);
if (status != STATUS_SUCCESS) {
leave;
}
//
// Assemble and send a pts selection
//
newProtocol = SmartcardExtension->MinorIoControlCode;
while(TRUE) {
// set initial character of PTS
ptsRequest[0] = 0xff;
// set the format character
if (SmartcardExtension->CardCapabilities.Protocol.Supported &
newProtocol &
SCARD_PROTOCOL_T1) {
// select T=1 and indicate that pts1 follows
ptsRequest[1] = 0x11;
SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;
} else if (SmartcardExtension->CardCapabilities.Protocol.Supported &
newProtocol &
SCARD_PROTOCOL_T0) {
// select T=0 and indicate that pts1 follows
ptsRequest[1] = 0x10;
SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
} else {
status = STATUS_INVALID_DEVICE_REQUEST;
leave;
}
// set pts1 which codes Fl and Dl
ptsRequest[2] =
SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
SmartcardExtension->CardCapabilities.PtsData.Dl;
// set pck (check character)
ptsRequest[3] = ptsRequest[0] ^ ptsRequest[1] ^ ptsRequest[2];
SmartcardExtension->SmartcardRequest.BufferLength = 4;
SmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_WRITE;
status = TLP3SerialIo(SmartcardExtension);
if (status != STATUS_SUCCESS) {
leave;
}
// read back the echo of the reader
SmartcardExtension->SmartcardReply.BufferLength = 4;
SmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_READ;
status = TLP3SerialIo(SmartcardExtension);
if (status != STATUS_SUCCESS) {
leave;
}
// read back the pts data
status = TLP3SerialIo(SmartcardExtension);
if (status != STATUS_SUCCESS &&
status != STATUS_TIMEOUT) {
leave;
}
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;
}
//
// The card replied correctly to the pts request
// Set the appropriate parameters for the port
//
if (SmartcardExtension->CardCapabilities.Protocol.Selected &
SCARD_PROTOCOL_T1) {
// set timeouts
serialConfigData->Timeouts.ReadTotalTimeoutConstant =
(SmartcardExtension->CardCapabilities.T1.BWT
+MICROSECONDS_PER_MILLISECOND/2)/ MICROSECONDS_PER_MILLISECOND;
serialConfigData->Timeouts.ReadIntervalTimeout =
(SmartcardExtension->CardCapabilities.T1.CWT
+MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
} else if (SmartcardExtension->CardCapabilities.Protocol.Selected &
SCARD_PROTOCOL_T0) {
// set timeouts
serialConfigData->Timeouts.ReadTotalTimeoutConstant =
serialConfigData->Timeouts.ReadIntervalTimeout =
(SmartcardExtension->CardCapabilities.T0.WT
+MICROSECONDS_PER_MILLISECOND/2)/ MICROSECONDS_PER_MILLISECOND;
}
// Now make some adjustments depending on the system speed
// minWaitTime = (KeQueryTimeIncrement() / 10000) * 5;
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));
pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
max(pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant,minWaitTime);
pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=
max(pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout,minWaitTime);
// Change data rate according to the new settings
pReaderExtension->SerialConfigData.SerialControlBlock.BaudRate =
SmartcardExtension->CardCapabilities.PtsData.DataRate;
SmartcardDebug( DEBUG_TRACE,
(TEXT("%s!TLP3SetProtocol :TimeOut Interval=%d,Totol%d\n"),
szDriverName,
pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout,
pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant
)
);
status = TLP3ConfigureSerialPort(SmartcardExtension);
ASSERT(status == STATUS_SUCCESS);
// 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;
RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3TransmitT0 begin\r\n")));
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!TLP3TransmitT0: Enter\n"),
szDriverName)
);
// try {
status=(PurgeComm(SmartcardExtension->ReaderExtension->hSerialPort,
PURGE_RXCLEAR | PURGE_TXCLEAR))?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;
if (status != STATUS_SUCCESS)
return status;
// Let the lib build a T=0 packet
status = SmartcardT0Request(
SmartcardExtension
);
if (status != STATUS_SUCCESS)
return status;
//
// The number of bytes we expect from the card
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -