📄 stccb.c
字号:
CBT1Transmit:
finishes the callback RDF_TRANSMIT for the T1 protocol
Arguments:
SmartcardExtension context of call
Return Value:
STATUS_SUCCESS
STATUS_NO_MEDIA
STATUS_TIMEOUT
STATUS_INVALID_DEVICE_REQUEST
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
SmartcardDebug( DEBUG_TRACE, (TEXT("%s!CBT1Transmit Enter\n"),DRIVER_NAME ));
// smclib workaround
*(PULONG)&SmartcardExtension->IoRequest.ReplyBuffer[0] = 0x02;
*(PULONG)&SmartcardExtension->IoRequest.ReplyBuffer[4] = sizeof( SCARD_IO_REQUEST );
// use the lib support to construct the T=1 packets
do {
// no header for the T=1 protocol
SmartcardExtension->SmartcardRequest.BufferLength = 0;
SmartcardExtension->T1.NAD = 0;
// let the lib setup the T=1 APDU & check for errors
NTStatus = SmartcardT1Request( SmartcardExtension );
if( NTStatus == STATUS_SUCCESS )
{
// send command (don't calculate LRC because CRC may be used!)
NTStatus = IFWriteSTCData(
SmartcardExtension->ReaderExtension,
SmartcardExtension->SmartcardRequest.Buffer,
SmartcardExtension->SmartcardRequest.BufferLength);
//
// extend the timeout if a Wtx request was sent by the card. if the
// card responds before the waiting time extension expires, the data are
// buffered in the reader. A delay without polling the reader status
// slows down the performance of the driver, but wtx is an exeption,
// not the rule.
//
if (SmartcardExtension->T1.Wtx)
{
SysDelay(
(( SmartcardExtension->T1.Wtx *
SmartcardExtension->CardCapabilities.T1.BWT + 999L )/
1000L));
}
// get response
SmartcardExtension->SmartcardReply.BufferLength = 0;
if( NTStatus == STATUS_SUCCESS )
{
NTStatus = IFReadSTCData(
SmartcardExtension->ReaderExtension,
SmartcardExtension->SmartcardReply.Buffer,
3);
if( NTStatus == STATUS_SUCCESS )
{
ULONG Length;
Length = (ULONG)SmartcardExtension->SmartcardReply.Buffer[ LEN_IDX ] + 1;
if( Length + 3 < MIN_BUFFER_SIZE )
{
NTStatus = IFReadSTCData(
SmartcardExtension->ReaderExtension,
&SmartcardExtension->SmartcardReply.Buffer[ DATA_IDX ],
Length);
SmartcardExtension->SmartcardReply.BufferLength = Length + 3;
}
else
{
NTStatus = STATUS_BUFFER_TOO_SMALL;
}
}
//
// if STCRead detects an LRC error, ignore it (maybe CRC used). Timeouts will
// be detected by the lib if len=0
//
if(( NTStatus == STATUS_CRC_ERROR ) || ( NTStatus == STATUS_IO_TIMEOUT ))
{
NTStatus = STATUS_SUCCESS;
}
if( NTStatus == STATUS_SUCCESS )
{
// let the lib evaluate the result & setup the next APDU
NTStatus = SmartcardT1Reply( SmartcardExtension );
}
}
}
// continue if the lib wants to send the next packet
} while( NTStatus == STATUS_MORE_PROCESSING_REQUIRED );
if( NTStatus == STATUS_IO_TIMEOUT )
{
NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
}
SmartcardDebug( DEBUG_TRACE,(TEXT( "%s!CBT1Transmit Exit: %X\n"),DRIVER_NAME, NTStatus ));
return ( NTStatus );
}
NTSTATUS
CBRawTransmit(
PSMARTCARD_EXTENSION SmartcardExtension)
/*++
CBRawTransmit:
finishes the callback RDF_TRANSMIT for the RAW protocol
Arguments:
SmartcardExtension context of call
Return Value:
STATUS_UNSUCCESSFUL
--*/
{
NTSTATUS NTStatus = STATUS_UNSUCCESSFUL;
SmartcardDebug( DEBUG_TRACE, (TEXT("%s!CBRawTransmit Exit: %X\n"),DRIVER_NAME, NTStatus ));
return ( NTStatus );
}
NTSTATUS
CBCardTracking(
PSMARTCARD_EXTENSION SmartcardExtension)
/*++
CBCardTracking:
callback handler for SMCLIB RDF_CARD_TRACKING. the requested event was
validated by the smclib (i.e. a card removal request will only be passed
if a card is present).
for a win95 build STATUS_PENDING will be returned without any other action.
for NT the cancel routine for the irp will be set to the drivers cancel
routine.
Arguments:
SmartcardExtension context of call
Return Value:
STATUS_PENDING
--*/
{
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!CBCardTracking Enter\n"),
DRIVER_NAME));
SmartcardExtension->ReaderExtension->IoctlPending=TRUE;
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!CBCardTracking Exit\n"),
DRIVER_NAME));
return( STATUS_PENDING );
}
NTSTATUS
CBUpdateCardState(
PSMARTCARD_EXTENSION SmartcardExtension )
/*++
CBUpdateCardState:
updates the variable CurrentState in SmartcardExtension
Arguments:
SmartcardExtension context of call
Return Value:
STATUS_SUCCESS
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
UCHAR Status;
//
// read card state
//
SmartcardLockDevice(SmartcardExtension);
NTStatus = IFReadSTCRegister(
SmartcardExtension->ReaderExtension,
ADR_IO_CONFIG,
1,
&Status);
switch(NTStatus)
{
case STATUS_NO_MEDIA:
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
break;
case STATUS_MEDIA_CHANGED:
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_PRESENT;
break;
case STATUS_SUCCESS:
Status &= M_SD;
if( Status == 0 )
{
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_ABSENT;
}
else
{
// first insertion?
if( SmartcardExtension->ReaderCapabilities.CurrentState <= SCARD_ABSENT )
{
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_PRESENT;
}
}
break;
default:
SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_UNKNOWN;
break;
}
SmartcardUnlockDevice(SmartcardExtension);
return(NTStatus);
}
NTSTATUS
CBSynchronizeSTC(
PSMARTCARD_EXTENSION SmartcardExtension )
/*++
CBSynchronizeSTC:
updates the card dependend data of the stc (wait times, ETU...)
Arguments:
SmartcardExtension context of call
Return Value:
STATUS_SUCCESS
--*/
{
NTSTATUS NTStatus = STATUS_SUCCESS;
PREADER_EXTENSION ReaderExtension;
ULONG CWT,
BWT,
CGT,
ETU;
UCHAR Dl,
Fl,
N;
#define MHZ * 1000000l
//
// The clock rate conversion table itself.
// All R(eserved)F(or Future)U(se) fields MUST be 0
//
static CLOCK_RATE_CONVERSION MyClockRateConversion[] = {
{ 1, 9600 },
{ 372, 5 MHZ },
{ 558, 6 MHZ },
{ 744, 8 MHZ },
{ 1116, 12 MHZ },
{ 1488, 16 MHZ },
{ 1860, 20 MHZ },
{ 0, 0 },
{ 0, 0 },
{ 512, 5 MHZ },
{ 768, 7500000 },
{ 1024, 10 MHZ },
{ 1536, 15 MHZ },
{ 2048, 20 MHZ },
{ 0, 0 },
{ 0, 0 }
};
#undef MHZ
//
// The bit rate adjustment table itself.
// All R(eserved)F(or)U(se) fields MUST be 0
//
static BIT_RATE_ADJUSTMENT MyBitRateAdjustment[] = {
{ 0, 0 },
{ 1, 1 },
{ 2, 1 },
{ 4, 1 },
{ 8, 1 },
{ 16, 1 },
{ 32, 1 },
{ 0, 0 },
{ 12, 1 },
{ 20, 1 },
{ 1, 2 },
{ 1, 4 },
{ 1, 8 },
{ 1, 16 },
{ 1, 32 },
{ 1, 64 }
};
ReaderExtension = SmartcardExtension->ReaderExtension;
// ClockRateConversion = SmartcardExtension->CardCapabilities.ClockRateConversion;
// BitRateAdjustment = SmartcardExtension->CardCapabilities.BitRateAdjustment;
// cycle length
Dl = SmartcardExtension->CardCapabilities.Dl;
Fl = SmartcardExtension->CardCapabilities.Fl;
ETU = MyClockRateConversion[Fl & 0x0F].F;
ETU /= MyBitRateAdjustment[ Dl & 0x0F ].DNumerator;
ETU *= MyBitRateAdjustment[ Dl & 0x0F ].DDivisor;
// ETU += (ETU % 2 == 0) ? 0 : 1;
// a extra guard time of 0xFF means minimum delay in both directions
N = SmartcardExtension->CardCapabilities.N;
if( N == 0xFF )
{
N = 0;
}
// set character waiting & guard time
switch ( SmartcardExtension->CardCapabilities.Protocol.Selected )
{
case SCARD_PROTOCOL_T0:
CWT = 960 * SmartcardExtension->CardCapabilities.T0.WI;
CGT = 14 + N; // 13 + N; cryptoflex error
break;
case SCARD_PROTOCOL_T1:
CWT = 11 + ( 0x01 << SmartcardExtension->CardCapabilities.T1.CWI );
BWT = 11 + ( 0x01 << SmartcardExtension->CardCapabilities.T1.BWI ) * 960;
CGT = 15 + N ;//13 + N; // 12 + N; sicrypt error
NTStatus = STCSetBWT( ReaderExtension, BWT * ETU );
break;
default:
NTStatus = STATUS_UNSUCCESSFUL;
break;
}
if(( NTStatus == STATUS_SUCCESS ) && ETU )
{
NTStatus = STCSetETU( ReaderExtension, ETU );
if( NTStatus == STATUS_SUCCESS )
{
NTStatus = STCSetCGT( ReaderExtension, CGT );
if( NTStatus == STATUS_SUCCESS )
{
NTStatus = STCSetCWT( ReaderExtension, CWT * ETU );
}
}
}
return( NTStatus );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -