📄 tlp3cb.c
字号:
} else if (SmartcardExtension->CardCapabilities.Protocol.Selected &
SCARD_PROTOCOL_T0) {
// set timeouts
serialConfigData->Timeouts.ReadTotalTimeoutConstant =
serialConfigData->Timeouts.ReadIntervalTimeout =
SmartcardExtension->CardCapabilities.T0.WT / 1000;
}
// Now make some adjustments depending on the system speed
minWaitTime = (KeQueryTimeIncrement() / 10000) * 5;
if (serialConfigData->Timeouts.ReadTotalTimeoutConstant <
minWaitTime) {
serialConfigData->Timeouts.ReadTotalTimeoutConstant =
minWaitTime;
}
if (serialConfigData->Timeouts.ReadIntervalTimeout <
minWaitTime) {
serialConfigData->Timeouts.ReadIntervalTimeout =
minWaitTime;
}
status = TLP3ConfigureSerialPort(SmartcardExtension);
ASSERT(status == STATUS_SUCCESS);
// We're done anyway, so leave
leave;
}
status = TLP3SerialIo(SmartcardExtension);
if (!NT_SUCCESS(status)) {
leave;
}
if (waitTime) {
LARGE_INTEGER delayPeriod;
delayPeriod.HighPart = -1;
delayPeriod.LowPart = waitTime * (-10);
KeDelayExecutionThread(
KernelMode,
FALSE,
&delayPeriod
);
}
}
}
_finally {
if (status == STATUS_TIMEOUT) {
status = STATUS_UNRECOGNIZED_MEDIA;
}
SmartcardExtension->ReaderExtension->PowerRequest = FALSE;
#ifdef SIMULATION
if (SmartcardExtension->ReaderExtension->SimulationLevel &
SIM_WRONG_STATE) {
// inject a wrong state after warm/cold reset
SmartcardExtension->ReaderCapabilities.CurrentState =
SCARD_PRESENT;
SmartcardDebug(
DEBUG_SIMULATION,
("%s!TLP3ReaderPower: SIM wrong state\n",
DRIVER_NAME)
);
} else if (SmartcardExtension->ReaderExtension->SimulationLevel &
SIM_INVALID_STATE) {
// inject completely invalid state after reset.
LARGE_INTEGER tickCount;
KeQueryTickCount(
&tickCount
);
SmartcardExtension->ReaderCapabilities.CurrentState =
(UCHAR) tickCount.LowPart;
SmartcardDebug(
DEBUG_SIMULATION,
("%s!TLP3ReaderPower: SIM invalid state %ls\n",
DRIVER_NAME,
SmartcardExtension->ReaderCapabilities.CurrentState)
);
}
if (SmartcardExtension->ReaderExtension->SimulationLevel &
SIM_LONG_RESET_TIMEOUT) {
// inject a random timeout of max 60 sec.
LARGE_INTEGER tickCount;
KeQueryTickCount(
&tickCount
);
tickCount.LowPart %= 60;
SmartcardDebug(
DEBUG_SIMULATION,
("%s!TLP3ReaderPower: SIM reset wait %ld\n",
DRIVER_NAME,
tickCount.LowPart)
);
tickCount.QuadPart *= -10000000;
KeDelayExecutionThread(
KernelMode,
FALSE,
&tickCount
);
}
#endif
}
SmartcardDebug(
DEBUG_TRACE,
("%s!TLP3ReaderPower: Exit (%lx)\n",
DRIVER_NAME,
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;
PAGED_CODE();
SmartcardDebug(
DEBUG_TRACE,
("%s!TLP3SetProtocol: Enter\n",
DRIVER_NAME)
);
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,
("%s!TLP3SetProtocol: PTS failed. Trying default parameters...\n",
DRIVER_NAME,
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 / 1000;
serialConfigData->Timeouts.ReadIntervalTimeout =
SmartcardExtension->CardCapabilities.T1.CWT / 1000;
} else if (SmartcardExtension->CardCapabilities.Protocol.Selected &
SCARD_PROTOCOL_T0) {
// set timeouts
serialConfigData->Timeouts.ReadTotalTimeoutConstant =
serialConfigData->Timeouts.ReadIntervalTimeout =
SmartcardExtension->CardCapabilities.T0.WT / 1000;
}
// Now make some adjustments depending on the system speed
minWaitTime = (KeQueryTimeIncrement() / 10000) * 5;
if (serialConfigData->Timeouts.ReadTotalTimeoutConstant < minWaitTime) {
serialConfigData->Timeouts.ReadTotalTimeoutConstant = minWaitTime;
}
if (serialConfigData->Timeouts.ReadIntervalTimeout < minWaitTime) {
serialConfigData->Timeouts.ReadIntervalTimeout = minWaitTime;
}
// Change data rate according to the new settings
serialConfigData->BaudRate.BaudRate =
SmartcardExtension->CardCapabilities.PtsData.DataRate;
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,
("%s!TLP3SetProtocol: Exit(%lx)\n",
DRIVER_NAME,
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -