📄 smcprot.c
字号:
// we expect the card to reply with an ifs response.
//
if (SmartcardExtension->T1.State == T1_IFS_REQUEST) {
// Check if the card properly responded to an ifs request
if (t1RecFrame.Pcb == T1_IFS_RESPONSE) {
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: T1_IFS_RESPONSE\n"),
DRIVER_NAME)
);
// The smart card acked our ifsd size
SmartcardExtension->T1.State = T1_I_BLOCK;
leave;
}
if ((t1RecFrame.Pcb & 0x82) == 0x82) {
//
// The card does not support ifs request, so we stop
// sending this and continue with a data block
// (the card is NOT ISO conform)
//
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: Card does not support IFS REQUEST\n"),
DRIVER_NAME)
);
SmartcardExtension->T1.State = T1_I_BLOCK;
leave;
}
//
// The card replied with junk to our ifs request.
// It doesn't make sense to continue.
//
status = STATUS_DEVICE_PROTOCOL_ERROR;
leave;
}
//
// If the last block was a resync. request,
// we expect the card to answer with a resynch response.
//
if (SmartcardExtension->T1.State == T1_RESYNCH_REQUEST) {
// Check if the card properly responded to an resynch request
if (t1RecFrame.Pcb != T1_RESYNCH_RESPONSE) {
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: Card response is not ISO conform! Aborting...\n"),
DRIVER_NAME)
);
status = STATUS_DEVICE_PROTOCOL_ERROR;
leave;
}
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: T1_RESYNCH_RESPONSE\n"),
DRIVER_NAME)
);
// Reset error counter
SmartcardExtension->T1.Resend = 0;
// The smart card has successfully responded to a resynch request
SmartcardExtension->T1.RSN = 0;
SmartcardExtension->T1.SSN = 0;
//
// Do a complete restart of the whole transmission
// but without resetting the resynch counter
//
SmartcardExtension->T1.State = T1_RESTART;
leave;
}
//
// Now check for other protocol states...
//
//
// Copy NAD value back to user buffer if this is an extended io-header
// containing the nad
//
if (IoHeader->ScardIoRequest.cbPciLength > sizeof(SCARD_IO_REQUEST) &&
IoHeader->Asn1Data[0] == 0x81 &&
IoHeader->Asn1Data[1] == 0x01 &&
IoHeader->Asn1Data[3] == 0x00) {
IoHeader->Asn1Data[2] = t1RecFrame.Nad;
}
if ((t1RecFrame.Pcb & 0x80) == 0) {
// This is an I-block
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: I(%d.%d) <-\n"),
DRIVER_NAME,
(t1RecFrame.Pcb & 0x40) >> 6,
(t1RecFrame.Pcb & 0x20) >> 5)
);
if (((t1RecFrame.Pcb & 0x40) >> 6) == SmartcardExtension->T1.RSN) {
// I-Block with correct sequence number
PUCHAR data;
ULONG minBufferSize;
// Reset error counter and error indicator
SmartcardExtension->T1.Resend = 0;
SmartcardExtension->T1.OriginalState = 0;
// We can 'increase' the number of correctly received I-Blocks
SmartcardExtension->T1.RSN ^= 1;
if (SmartcardExtension->T1.State == T1_I_BLOCK) {
// This I-Block is also an acknowledge for the I-Block we sent
SmartcardExtension->T1.SSN ^= 1;
}
// Check size of user buffer
minBufferSize =
IoHeader->ScardIoRequest.cbPciLength +
SmartcardExtension->T1.BytesReceived +
t1RecFrame.Len;
if (SmartcardExtension->IoRequest.ReplyBufferLength < minBufferSize) {
status = STATUS_BUFFER_TOO_SMALL;
leave;
}
ASSERT(SmartcardExtension->T1.ReplyData);
//
// Let data pointer point behind struct.
// All reply data will be stored there.
//
data =
SmartcardExtension->T1.ReplyData +
IoHeader->ScardIoRequest.cbPciLength +
SmartcardExtension->T1.BytesReceived;
// Copy data to user buffer
RtlCopyMemory(
data,
t1RecFrame.Inf,
t1RecFrame.Len
);
SmartcardExtension->T1.BytesReceived += t1RecFrame.Len;
if (t1RecFrame.Pcb & T1_MORE_DATA) {
// Ack this block and request the next block
SmartcardExtension->T1.State = T1_R_BLOCK;
} else {
//
// This was the last block of the transmission
// Set number of bytes returned by this transmission
//
*SmartcardExtension->IoRequest.Information =
IoHeader->ScardIoRequest.cbPciLength +
SmartcardExtension->T1.BytesReceived;
// Copy the result back to the user buffer
ASSERT(SmartcardExtension->IoRequest.ReplyBuffer != NULL);
RtlCopyMemory(
SmartcardExtension->IoRequest.ReplyBuffer,
SmartcardExtension->T1.ReplyData,
IoHeader->ScardIoRequest.cbPciLength +
SmartcardExtension->T1.BytesReceived
);
status = STATUS_SUCCESS;
}
leave;
}
//
// I-Block with wrong sequence number
// We try T1_MAX_RETRIES times to resend the last block.
// If this is unsuccessfull, we try to resynch.
// If resynch is unsuccessfull we abort the transmission.
//
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: Block number incorrect\n"),
DRIVER_NAME)
);
SmartcardExtension->T1.LastError = T1_ERROR_OTHER;
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
SmartcardExtension->T1.State = T1_RESYNCH_REQUEST;
leave;
}
// request the block again.
SmartcardExtension->T1.State = T1_R_BLOCK;
leave;
}
if ((t1RecFrame.Pcb & 0xC0) == 0x80) {
// This is an R-block
UCHAR RSN = (t1RecFrame.Pcb & 0x10) >> 4;
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: R(%d) <-\n"),
DRIVER_NAME,
RSN)
);
if (RSN != SmartcardExtension->T1.SSN &&
SmartcardExtension->T1.MoreData) {
// The ICC has acked the last block
SmartcardExtension->T1.Resend = 0;
SmartcardExtension->T1.BytesSent += SmartcardExtension->T1.InfBytesSent;
SmartcardExtension->T1.BytesToSend -= SmartcardExtension->T1.InfBytesSent;
SmartcardExtension->T1.SSN ^= 1;
SmartcardExtension->T1.State = T1_I_BLOCK;
leave;
}
//
// We have an error condition...
//
ASSERT(t1RecFrame.Pcb & 0x0f);
if ((t1RecFrame.Pcb & 0x02) &&
SmartcardExtension->T1.State == T1_IFS_REQUEST) {
//
// The card does not support ifs request, so
// we stop sending this and continue with a data block
// (the card is NOT ISO conform)
//
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: Card does not support IFS REQUEST\n"),
DRIVER_NAME)
);
SmartcardExtension->T1.State = T1_I_BLOCK;
leave;
}
// We have to resend the last block
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: Card reports error\n"),
DRIVER_NAME)
);
if (SmartcardExtension->T1.Resend++ == T1_MAX_RETRIES) {
SmartcardExtension->T1.Resend = 0;
if (SmartcardExtension->T1.OriginalState == 0) {
// Save current state
SmartcardExtension->T1.OriginalState =
SmartcardExtension->T1.State;
}
// Try to resynchronize
SmartcardExtension->T1.State = T1_RESYNCH_REQUEST;
}
leave;
}
//
// This is an S-block
//
switch (t1RecFrame.Pcb) {
case T1_IFS_REQUEST:
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: T1_IFS_REQUEST\n"),
DRIVER_NAME)
);
// The smart card wants to exend the IFS - size
SmartcardExtension->T1.IFSC =
SmartcardExtension->SmartcardReply.Buffer[3];
// Save current state
ASSERT(SmartcardExtension->T1.OriginalState == 0);
SmartcardExtension->T1.OriginalState =
SmartcardExtension->T1.State;
SmartcardExtension->T1.State = T1_IFS_RESPONSE;
break;
case T1_ABORT_REQUEST:
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: T1_ABORT_REQUEST\n"),
DRIVER_NAME)
);
SmartcardExtension->T1.State = T1_ABORT_RESPONSE;
break;
case T1_WTX_REQUEST:
SmartcardDebug(
DEBUG_PROTOCOL,
(TEXT("%s!SmartcardT1Reply: T1_WTX_REQUEST\n"),
DRIVER_NAME)
);
// Smart card needs longer wait time
SmartcardExtension->T1.Wtx =
SmartcardExtension->SmartcardReply.Buffer[3];
// Save current state
ASSERT(SmartcardExtension->T1.OriginalState == 0);
SmartcardExtension->T1.OriginalState =
SmartcardExtension->T1.State;
SmartcardExtension->T1.State = T1_WTX_RESPONSE;
break;
case T1_VPP_ERROR:
SmartcardDebug(
DEBUG_ERROR,
(TEXT("%s!SmartcardT1Reply: T1_VPP_ERROR\n"),
DRIVER_NAME)
);
status = STATUS_DEVICE_POWER_FAILURE;
break;
default:
ASSERTMSG(
TEXT("SmartcardT1Reply: Invalid Pcb "),
FALSE
);
status = STATUS_DEVICE_PROTOCOL_ERROR;
break;
}
}
finally {
#if DBG
if (packetOk && chksumOk) {
DumpT1Block(
SmartcardExtension->SmartcardReply.Buffer,
SmartcardExtension->CardCapabilities.T1.EDC
);
}
#endif
if (SmartcardExtension->T1.State == T1_RESYNCH_REQUEST &&
SmartcardExtension->T1.Resynch++ == T1_MAX_RETRIES) {
SmartcardDebug(
DEBUG_ERROR,
(TEXT("%s!SmartcardT1Reply: Too many errors! Aborting...\n"),
DRIVER_NAME)
);
status = STATUS_DEVICE_PROTOCOL_ERROR;
}
if (status != STATUS_MORE_PROCESSING_REQUIRED) {
if (SmartcardExtension->T1.OriginalState == T1_IFS_REQUEST) {
SmartcardExtension->T1.State = T1_IFS_REQUEST;
} else {
SmartcardExtension->T1.State = T1_START;
}
if (SmartcardExtension->T1.ReplyData) {
// free the reply data buffer
#ifdef SMCLIB_VXD
_HeapFree(SmartcardExtension->T1.ReplyData, 0);
#elif defined(SMCLIB_CE)
LocalFree(SmartcardExtension->T1.ReplyData);
#else
ExFreePool(SmartcardExtension->T1.ReplyData);
#endif
SmartcardExtension->T1.ReplyData = NULL;
}
SmartcardExtension->T1.OriginalState = 0;
SmartcardExtension->T1.NAD = 0;
}
}
return status;
}
#if DBG
#pragma optimize( "", on )
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -