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

📄 stccb.c

📁 Windows CE 5.0 下的SmartCard驱动。
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++

Copyright (c) 1998 SCM Microsystems, Inc.


--*/


// Include

#include "common.h"
#include "stccmd.h"
#include "stccb.h"
#include "stcusbce.h"
#include "usbcom.h"


NTSTATUS
CBCardPower(
    PSMARTCARD_EXTENSION SmartcardExtension)
/*++

CBCardPower:
    callback handler for SMCLIB RDF_CARD_POWER

Arguments:
    SmartcardExtension    context of call

Return Value:
    STATUS_SUCCESS
    STATUS_NO_MEDIA
    STATUS_TIMEOUT
    STATUS_BUFFER_TOO_SMALL

--*/
{
    NTSTATUS            NTStatus = STATUS_SUCCESS;
    UCHAR                ATRBuffer[ ATR_SIZE ];
    ULONG                Command,
                        ATRLength;
    PREADER_EXTENSION    ReaderExtension;

    SmartcardDebug( DEBUG_TRACE, (TEXT("%s!CBCardPower Enter\n"),DRIVER_NAME ));


    ReaderExtension = SmartcardExtension->ReaderExtension;


    //    discard old ATR
    SysFillMemory( SmartcardExtension->CardCapabilities.ATR.Buffer, 0x00, 0x40 );

    SmartcardExtension->CardCapabilities.ATR.Length = 0;
    SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;

    Command = SmartcardExtension->MinorIoControlCode;


    switch ( Command )
    {
        case SCARD_WARM_RESET:

            //    if the card was not powered, fall through to cold reset
            if( SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_SWALLOWED )
            {
                //    reset the card
                ATRLength = ATR_SIZE;
                NTStatus = STCReset(
                    ReaderExtension,
                    0,                    // not used: ReaderExtension->Device,
                    TRUE,                // warm reset
                    ATRBuffer,
                    &ATRLength);

                break;
            }
            //    warm reset not possible because card was not powered

        case SCARD_COLD_RESET:
            //    reset the card
            ATRLength = ATR_SIZE;
            NTStatus = STCReset(
                ReaderExtension,
                0,                        // not used: ReaderExtension->Device,
                FALSE,                    // cold reset
                ATRBuffer,
                &ATRLength);
            break;

        case SCARD_POWER_DOWN:

            //    discard old card status
            ATRLength = 0;
            NTStatus = STCPowerOff(    ReaderExtension );

            if(NTStatus == STATUS_SUCCESS)
            {
                SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_PRESENT;
            }
            break;
    }

    //    finish the request
    if( NTStatus == STATUS_SUCCESS )
    {

        //    update all neccessary data if an ATR was received
        if( ATRLength > 2 )
        {
            //    copy ATR to user buffer 
            if( ATRLength <= SmartcardExtension->IoRequest.ReplyBufferLength )
            {
                SysCopyMemory(
                    SmartcardExtension->IoRequest.ReplyBuffer,
                    ATRBuffer,
                    ATRLength);
                *SmartcardExtension->IoRequest.Information = ATRLength;
            }
            else
            {
                NTStatus = STATUS_BUFFER_TOO_SMALL;
            }

            //    copy ATR to card capability buffer
            if( ATRLength <= 64 )
            {    
                SysCopyMemory(
                    SmartcardExtension->CardCapabilities.ATR.Buffer,
                    ATRBuffer,
                    ATRLength);

                SmartcardExtension->CardCapabilities.ATR.Length = ( UCHAR )ATRLength;


                //    let the lib update the card capabilities
                NTStatus = SmartcardUpdateCardCapabilities( SmartcardExtension );

            }
            else
            {
                NTStatus = STATUS_BUFFER_TOO_SMALL;
            }
            if( NTStatus == STATUS_SUCCESS )
            {
                //    set the stc registers
                CBSynchronizeSTC( SmartcardExtension );

                // set read timeout
                if( SmartcardExtension->CardCapabilities.Protocol.Selected == SCARD_PROTOCOL_T1 )
                {
                    ReaderExtension->ReadTimeout = 
                        (ULONG) (SmartcardExtension->CardCapabilities.T1.BWT  / 1000);


                }
                else 
                {
                    ReaderExtension->ReadTimeout = 
                        (ULONG) (SmartcardExtension->CardCapabilities.T0.WT / 1000);
                    if(ReaderExtension->ReadTimeout < 50)
                    {
                        ReaderExtension->ReadTimeout = 50; //  50 ms minimum timeout
                    }
                }
            }
        }
    }


    SmartcardDebug( DEBUG_TRACE,( TEXT("%s!CBCardPower Exit: %X\n"), DRIVER_NAME,NTStatus ));
    return( NTStatus );
}

NTSTATUS
CBSetProtocol(        
    PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

CBSetProtocol:
    callback handler for SMCLIB RDF_SET_PROTOCOL

Arguments:
    SmartcardExtension    context of call

Return Value:
    STATUS_SUCCESS
    STATUS_NO_MEDIA
    STATUS_TIMEOUT
    STATUS_BUFFER_TOO_SMALL
    STATUS_INVALID_DEVICE_STATE
    STATUS_INVALID_DEVICE_REQUEST

--*/
{
    NTSTATUS            NTStatus = STATUS_PENDING;
    UCHAR                PTSRequest[64],
                        PTSReply[64];
    ULONG                NewProtocol;
    PREADER_EXTENSION    ReaderExtension;

    SmartcardDebug( DEBUG_TRACE, (TEXT("%s!CBSetProtocol Enter\n"),DRIVER_NAME ));

    ReaderExtension = SmartcardExtension->ReaderExtension;
    NewProtocol        = SmartcardExtension->MinorIoControlCode;

    //    check if the card is already in specific state
    if( ( SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC )  &&
        ( SmartcardExtension->CardCapabilities.Protocol.Selected & NewProtocol ))
    {
        NTStatus = STATUS_SUCCESS;    
    }

    //    protocol supported?
    if( !( SmartcardExtension->CardCapabilities.Protocol.Supported & NewProtocol ) || 
        !( SmartcardExtension->ReaderCapabilities.SupportedProtocols & NewProtocol ))
    {
        NTStatus = STATUS_INVALID_DEVICE_REQUEST;    
    }

    //    send PTS
    while( NTStatus == STATUS_PENDING )
    {
        // set initial character of PTS
        PTSRequest[0] = 0xFF;

        // set the format character
        if(( NewProtocol & SCARD_PROTOCOL_T1 )&&
            (SmartcardExtension->CardCapabilities.Protocol.Supported & SCARD_PROTOCOL_T1 ))
        {
            PTSRequest[1] = 0x11;
            SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;
        }
        else
        {
            PTSRequest[1] = 0x10;
            SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;
        }

        //    PTS1 codes Fl and Dl
        PTSRequest[2] = 
            SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
            SmartcardExtension->CardCapabilities.PtsData.Dl;

        //    check character
        PTSRequest[3] = PTSRequest[0] ^ PTSRequest[1] ^ PTSRequest[2];   

        //    write PTSRequest
        NTStatus = IFWriteSTCData( ReaderExtension, PTSRequest, 4 );

        //    get response
        if( NTStatus == STATUS_SUCCESS )
        {
            NTStatus = IFReadSTCData( ReaderExtension, PTSReply, 4 );

            if(( NTStatus == STATUS_SUCCESS ) && !SysCompareMemory( PTSRequest, PTSReply, 4))
            {
                //    set the stc registers
                SmartcardExtension->CardCapabilities.Dl =
                    SmartcardExtension->CardCapabilities.PtsData.Dl;
                SmartcardExtension->CardCapabilities.Fl = 
                    SmartcardExtension->CardCapabilities.PtsData.Fl;

                CBSynchronizeSTC( SmartcardExtension );

                // the card replied correctly to the PTS-request
                break;
            }
        }

        //
        //    The card did either NOT reply or it replied incorrectly
        //    so try default values
        //
        if( SmartcardExtension->CardCapabilities.PtsData.Type != PTS_TYPE_DEFAULT )
        {
            SmartcardExtension->CardCapabilities.PtsData.Type    = PTS_TYPE_DEFAULT;
            SmartcardExtension->MinorIoControlCode                = SCARD_COLD_RESET;
            NTStatus = CBCardPower( SmartcardExtension );

            if( NTStatus == STATUS_SUCCESS )
            {
                NTStatus = STATUS_PENDING;
            }
            else
            {
                NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
            }
        }
    }

    if( NTStatus == STATUS_TIMEOUT )
    {
        NTStatus = STATUS_IO_TIMEOUT;             
    }

    if( NTStatus == STATUS_SUCCESS )
    {
        //    card replied correctly to the PTS request
        if( SmartcardExtension->CardCapabilities.Protocol.Selected & SCARD_PROTOCOL_T1 )
        {
            ReaderExtension->ReadTimeout = SmartcardExtension->CardCapabilities.T1.BWT / 1000;
        }
        else
        {
            ReaderExtension->ReadTimeout = SmartcardExtension->CardCapabilities.T0.WT / 1000;
            // We need to have a minimum timeout anyway
            if(ReaderExtension->ReadTimeout <50)
            {
                ReaderExtension->ReadTimeout =50; // 50 ms minimum timeout
            }
        }


        //    indicate that the card is 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);
    }
    else
    {
        SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
        *(PULONG) SmartcardExtension->IoRequest.ReplyBuffer = 0;
        *SmartcardExtension->IoRequest.Information = 0;
    }

    SmartcardDebug( DEBUG_TRACE, (TEXT("%d!CBSetProtocol: Exit %X\n"),DRIVER_NAME, NTStatus ));

    return( NTStatus ); 
}
NTSTATUS
CBGenericIOCTL(
    PSMARTCARD_EXTENSION SmartcardExtension)
/*++

Description:
    Performs generic callbacks to the reader

Arguments:
    SmartcardExtension    context of the call

Return Value:
    STATUS_SUCCESS

--*/
{
    NTSTATUS                NTStatus;
    SmartcardDebug( 
        DEBUG_TRACE, 
        ( TEXT("%s!CBGenericIOCTL: Enter\n"),
        DRIVER_NAME));

    //
    //    get pointer to current IRP stack location
    //
    //
    // assume error
    //
    NTStatus = STATUS_INVALID_DEVICE_REQUEST;


    //
    //    dispatch IOCTL
    //
    switch( SmartcardExtension->MajorIoControlCode )
    {

    
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -