📄 smcprot.c
字号:
} else {
SmartcardExtension->T1.State = T1_I_BLOCK;
}
// No break here !!
case T1_I_BLOCK:
SmartcardExtension->T1.State = T1_I_BLOCK;
//
// Set the number of bytes we will transmit to the card.
// This is the lesser of IFSD and IFSC
//
SmartcardExtension->T1.InfBytesSent = SmartcardExtension->T1.IFSC;
if (SmartcardExtension->T1.InfBytesSent > SmartcardExtension->T1.IFSD) {
SmartcardExtension->T1.InfBytesSent = SmartcardExtension->T1.IFSD;
}
// Send either max frame size or remaining bytes
if (SmartcardExtension->T1.BytesToSend > SmartcardExtension->T1.InfBytesSent) {
SmartcardExtension->T1.MoreData = TRUE;
t1SendFrame.Len = SmartcardExtension->T1.InfBytesSent;
} else {
SmartcardExtension->T1.MoreData = FALSE;
t1SendFrame.Len = (UCHAR) SmartcardExtension->T1.BytesToSend;
}
t1SendFrame.Nad = SmartcardExtension->T1.NAD;
//
// ProtocolControlByte:
// b7 - SendSequenceNumber
// b6 - MoreDatatBit
//
t1SendFrame.Pcb =
(SmartcardExtension->T1.SSN) << 6 |
(SmartcardExtension->T1.MoreData ? T1_MORE_DATA : 0);
t1SendFrame.Inf =
SmartcardExtension->IoRequest.RequestBuffer +
IoHeader->ScardIoRequest.cbPciLength +
SmartcardExtension->T1.BytesSent;
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Request: I(%d.%d) ->\n"),
DRIVER_NAME,
SmartcardExtension->T1.SSN,
(SmartcardExtension->T1.MoreData ? 1 : 0))
);
break;
case T1_R_BLOCK:
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Request: R(%d) ->\n"),
DRIVER_NAME,
SmartcardExtension->T1.RSN)
);
t1SendFrame.Nad = SmartcardExtension->T1.NAD;
//
// ProtocolControlByte:
// b5 - SequenceNumber
// b1-4 - ErrorCode
//
t1SendFrame.Pcb =
0x80 |
(SmartcardExtension->T1.RSN) << 4 |
(SmartcardExtension->T1.LastError);
//
// If this R-Block is a response to an error
// we have to restore to the original state we had before
//
if (SmartcardExtension->T1.LastError) {
SmartcardExtension->T1.LastError = 0;
//
// We must have a defined original state here
//
ASSERT(SmartcardExtension->T1.OriginalState != 0);
if (SmartcardExtension->T1.OriginalState == 0) {
SmartcardExtension->T1.State = T1_START;
return STATUS_INTERNAL_ERROR;
}
SmartcardExtension->T1.State =
SmartcardExtension->T1.OriginalState;
}
t1SendFrame.Len = 0;
t1SendFrame.Inf = NULL;
break;
case T1_IFS_RESPONSE:
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Request: T1_IFS_RESPONSE\n"),
DRIVER_NAME)
);
// Restore to the original state we had before
ASSERT(SmartcardExtension->T1.OriginalState != 0);
if (SmartcardExtension->T1.OriginalState == 0) {
SmartcardExtension->T1.State =
SmartcardExtension->T1.OriginalState;
}
t1SendFrame.Nad = SmartcardExtension->T1.NAD;
// Send IFS response
t1SendFrame.Pcb = 0xE1;
t1SendFrame.Len = 1;
// New length of INF-Field
t1SendFrame.Inf = &SmartcardExtension->T1.IFSC;
break;
case T1_RESYNCH_REQUEST:
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Request: T1_RESYNCH_REQUEST\n"),
DRIVER_NAME)
);
t1SendFrame.Nad = SmartcardExtension->T1.NAD;
// Resynch request
t1SendFrame.Pcb = 0xC0;
t1SendFrame.Len = 0;
t1SendFrame.Inf = NULL;
// Set the send sequence number to 0
SmartcardExtension->T1.SSN = 0;
break;
case T1_ABORT_REQUEST:
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Request: T1_ABORT_REQUEST\n"),
DRIVER_NAME)
);
t1SendFrame.Nad = SmartcardExtension->T1.NAD;
// Send ABORT request
t1SendFrame.Pcb = 0xC2;
t1SendFrame.Len = 0;
t1SendFrame.Inf = NULL;
break;
case T1_ABORT_RESPONSE:
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Request: T1_ABORT_RESPONSE\n"),
DRIVER_NAME)
);
SmartcardExtension->T1.State = T1_START;
t1SendFrame.Nad = SmartcardExtension->T1.NAD;
// Send ABORT response
t1SendFrame.Pcb = 0xE2;
t1SendFrame.Len = 0;
t1SendFrame.Inf = NULL;
break;
case T1_WTX_RESPONSE:
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Request: T1_WTX_RESPONSE\n"),
DRIVER_NAME)
);
// Restore to the original state we had before
ASSERT(SmartcardExtension->T1.OriginalState != 0);
SmartcardExtension->T1.State =
SmartcardExtension->T1.OriginalState;
t1SendFrame.Nad = SmartcardExtension->T1.NAD;
// Send WTX response
t1SendFrame.Pcb = 0xE3;
t1SendFrame.Len = 1;
t1SendFrame.Inf = &SmartcardExtension->T1.Wtx;
break;
default:
SmartcardDebug(
DEBUG_ERROR,
(TEXT("%s!SmartcardT1Request: Invalid State %d\n"),
DRIVER_NAME, SmartcardExtension->T1.State)
);
return STATUS_INVALID_DEVICE_STATE;
}
// Insert Node Address byte
smartcardRequest->Buffer[smartcardRequest->BufferLength] =
t1SendFrame.Nad;
// Insert ProtocolControlByte
smartcardRequest->Buffer[smartcardRequest->BufferLength + 1] =
t1SendFrame.Pcb;
// Length of INF field
smartcardRequest->Buffer[smartcardRequest->BufferLength + 2] =
t1SendFrame.Len;
// Insert INF field data
if (t1SendFrame.Len > 0) {
RtlCopyMemory(
&smartcardRequest->Buffer[smartcardRequest->BufferLength + 3],
t1SendFrame.Inf,
t1SendFrame.Len
);
}
// Compute checksum
SmartcardT1Chksum(
&smartcardRequest->Buffer[smartcardRequest->BufferLength],
SmartcardExtension->CardCapabilities.T1.EDC,
FALSE
);
#if (DBG || DEBUG)
#if !defined(SMCLIB_VXD) && !defined(SMCLIB_CE)
if (SmartcardGetDebugLevel() & DEBUG_T1_TEST) {
LARGE_INTEGER Ticks;
UCHAR RandomVal;
KeQueryTickCount(&Ticks);
RandomVal = (UCHAR) Ticks.LowPart % 4;
if (RandomVal == 0) {
smartcardRequest->Buffer[smartcardRequest->BufferLength - 1] += 1;
SmartcardDebug(
DEBUG_ERROR,
(TEXT("%s!SmartcardT1Request: Simulating bad checksum\n"),
DRIVER_NAME)
);
}
}
#endif
DumpT1Block(
smartcardRequest->Buffer + headerSize,
SmartcardExtension->CardCapabilities.T1.EDC
);
#endif
//
// If the card uses invers convention invert the data
// NOTE: do not invert any header data the reader may use
//
if (SmartcardExtension->CardCapabilities.InversConvention) {
SmartcardInvertData(
&smartcardRequest->Buffer[smartcardRequest->BufferLength],
(SmartcardExtension->CardCapabilities.T1.EDC & T1_CRC_CHECK ? 5 : 4) +
t1SendFrame.Len
);
}
//
// Update the number of bytes that are in the buffer
// A T1 block is at least 4 bytes long with LRC check and 5 bytes with CRC check
//
smartcardRequest->BufferLength +=
(SmartcardExtension->CardCapabilities.T1.EDC & T1_CRC_CHECK ? 5 : 4) +
t1SendFrame.Len;
return STATUS_SUCCESS;
}
NTSTATUS
#ifdef SMCLIB_VXD
SMCLIB_SmartcardT1Reply(
#else
SmartcardT1Reply(
#endif
PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
Arguments:
DeviceObject - Supplies a pointer to the device object for this request.
Return Value:
--*/
{
T1_BLOCK_FRAME t1RecFrame;
NTSTATUS status = STATUS_MORE_PROCESSING_REQUIRED;
PIO_HEADER IoHeader = (PIO_HEADER) SmartcardExtension->T1.ReplyData;
BOOLEAN packetOk = TRUE, chksumOk = TRUE;
// signal that we received an answer
SmartcardExtension->T1.WaitForReply = FALSE;
// Invert the data of an inverse convention card
if (SmartcardExtension->CardCapabilities.InversConvention) {
SmartcardInvertData(
SmartcardExtension->SmartcardReply.Buffer,
SmartcardExtension->SmartcardReply.BufferLength
);
}
// Clear waiting time extension
SmartcardExtension->T1.Wtx = 0;
try {
ULONG expectedLength =
SCARD_T1_PROLOGUE_LENGTH +
SmartcardExtension->SmartcardReply.Buffer[2] +
(SmartcardExtension->CardCapabilities.T1.EDC & T1_CRC_CHECK ? 2 : 1);
if (SmartcardExtension->SmartcardReply.BufferLength < 4 ||
SmartcardExtension->SmartcardReply.BufferLength != expectedLength) {
SmartcardDebug(
DEBUG_ERROR,
(TEXT("%s!SmartcardT1Reply: Packet length incorrect\n"),
DRIVER_NAME)
);
packetOk = FALSE;
} else {
// calculate the checksum
chksumOk = SmartcardT1Chksum(
SmartcardExtension->SmartcardReply.Buffer,
SmartcardExtension->CardCapabilities.T1.EDC,
TRUE
);
#if DBG
#ifndef SMCLIB_VXD
if (SmartcardGetDebugLevel() & DEBUG_T1_TEST) {
// inject some checksum errors
LARGE_INTEGER Ticks;
UCHAR RandomVal;
KeQueryTickCount(&Ticks);
RandomVal = (UCHAR) Ticks.LowPart % 4;
if (RandomVal == 0) {
chksumOk = FALSE;
SmartcardDebug(
DEBUG_ERROR,
(TEXT("%s!SmartcardT1Reply: Simulating bad checksum\n"),
DRIVER_NAME)
);
}
}
#endif
#endif
}
if (chksumOk == FALSE) {
SmartcardDebug(
DEBUG_ERROR,
(TEXT("%s!SmartcardT1Reply: Bad checksum\n"),
DRIVER_NAME)
);
}
if (packetOk == FALSE || chksumOk == FALSE) {
SmartcardExtension->T1.LastError =
(chksumOk ? T1_ERROR_OTHER : T1_ERROR_CHKSUM);
if (SmartcardExtension->T1.OriginalState == 0) {
SmartcardExtension->T1.OriginalState =
SmartcardExtension->T1.State;
}
if (SmartcardExtension->T1.Resend++ == T1_MAX_RETRIES) {
SmartcardExtension->T1.Resend = 0;
// Try to resynchronize since the resend requests have failed
SmartcardExtension->T1.State = T1_RESYNCH_REQUEST;
leave;
}
// If the last request was a resynch we try again to resynch
if (SmartcardExtension->T1.State != T1_RESYNCH_REQUEST) {
// Chksum not OK; request resend of last block
SmartcardExtension->T1.State = T1_R_BLOCK;
}
leave;
}
//
// The checksum of the packet is ok.
// Now check the rest of the packet
//
// Clear the last error
SmartcardExtension->T1.LastError = 0;
t1RecFrame.Nad = SmartcardExtension->SmartcardReply.Buffer[0];
t1RecFrame.Pcb = SmartcardExtension->SmartcardReply.Buffer[1];
t1RecFrame.Len = SmartcardExtension->SmartcardReply.Buffer[2];
t1RecFrame.Inf = &SmartcardExtension->SmartcardReply.Buffer[3];
//
// If the last block we sent was a ifs request,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -