⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stccb.c

📁 Windows CE 5.0 下的SmartCard驱动。
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -