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

📄 tlp3cb.c

📁 基于windows ce环境下对smart card 基于pc/sc架构下驱动例程
💻 C
📖 第 1 页 / 共 4 页
字号:
                    } else if (SmartcardExtension->CardCapabilities.Protocol.Selected &
                               SCARD_PROTOCOL_T0) {
                        // set timeouts
                        pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
                            pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=
                            (SmartcardExtension->CardCapabilities.T0.WT +
                            MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
                    }

                    // Now make some adjustments depending on the system speed
                    if (!QueryPerformanceFrequency(&liProcessClock)) { // not supported
                        // ASSUME it is 66 Mhz CPU Clock
                        liProcessClock.HighPart=0;
                        liProcessClock.LowPart=66*1000000L;
                    };
                    // Minimum wait set to 5k instruction in Milli Second.
                    liProcessClock.LowPart/=1000; // Frequncy in Milli Second.
                    minWaitTime = (DWORD) ((5000L*5+liProcessClock.QuadPart/2)/(liProcessClock.QuadPart));

                    pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
                        max(pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant,minWaitTime);
                    pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=
                        max(pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout,minWaitTime);

                    status = TLP3ConfigureSerialPort(SmartcardExtension);
                    ASSERT(status == STATUS_SUCCESS);
                    // We're done anyway, so leave
                    leave;                             
            }

            if (!NT_SUCCESS(status)) {
                leave;                 
            }
            //convert MicroSecond to Millisecond
            if (waitTime) {
                waitTime=(waitTime+MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;
                Sleep(waitTime);
            }
        } 
    }
    _finally {

        if (status == STATUS_TIMEOUT) {

            status = STATUS_UNRECOGNIZED_MEDIA;             
        }

        SmartcardExtension->ReaderExtension->PowerRequest = FALSE;         
    }

    SmartcardDebug(
        DEBUG_TRACE,
        (TEXT("%s!TLP3ReaderPower: Exit (%lx)\n"),
        szDriverName,
        status)
        );

    return status;
}

NTSTATUS
TLP3SetProtocol(
       PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

Routine Description:

    The smart card lib requires to have this function. It is called 
    to set a the transmission protocol and parameters. If this function 
    is called with a protocol mask (which means the caller doesn't card 
    about a particular protocol to be set) we first look if we can 
    set T=1 and the T=0

Arguments:

    SmartcardExtension - Pointer to smart card data struct.

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS status;
    LARGE_INTEGER liProcessClock;
    PREADER_EXTENSION pReaderExtension=SmartcardExtension->ReaderExtension;

    SmartcardDebug(
        DEBUG_TRACE,
        (TEXT("%s!TLP3SetProtocol: Enter\n"),
        szDriverName)
        );


    try {
          
        PUCHAR ptsRequest = SmartcardExtension->SmartcardRequest.Buffer;
        PUCHAR ptsReply = SmartcardExtension->SmartcardReply.Buffer;
        PSERIAL_READER_CONFIG serialConfigData = 
            &SmartcardExtension->ReaderExtension->SerialConfigData;
        ULONG minWaitTime, newProtocol;

        //
        // Check if the card is already in specific state
        // and if the caller wants to have the already selected protocol.
        // We return success if this is the case.
        //
        if (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_SPECIFIC &&
            (SmartcardExtension->CardCapabilities.Protocol.Selected & 
             SmartcardExtension->MinorIoControlCode)) {

            status = STATUS_SUCCESS;    
            leave;
        }

        // set normal timeout
        serialConfigData->Timeouts.ReadIntervalTimeout = 
            READ_INTERVAL_TIMEOUT_DEFAULT;
        serialConfigData->Timeouts.ReadTotalTimeoutConstant = 
            READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;

        status = TLP3ConfigureSerialPort(SmartcardExtension);

        ASSERT(status == STATUS_SUCCESS);

        if (status != STATUS_SUCCESS) {

            leave;
        }         
        
        //
        // Assemble and send a pts selection
        //

        newProtocol = SmartcardExtension->MinorIoControlCode;

        while(TRUE) {

            // set initial character of PTS
            ptsRequest[0] = 0xff;

            // set the format character
            if (SmartcardExtension->CardCapabilities.Protocol.Supported &
                newProtocol & 
                SCARD_PROTOCOL_T1) {

                // select T=1 and indicate that pts1 follows
                ptsRequest[1] = 0x11;
                SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T1;

            } else if (SmartcardExtension->CardCapabilities.Protocol.Supported & 
                       newProtocol & 
                       SCARD_PROTOCOL_T0) {

                // select T=0 and indicate that pts1 follows
                ptsRequest[1] = 0x10;
                SmartcardExtension->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_T0;

            } else {
                
                status = STATUS_INVALID_DEVICE_REQUEST;
                leave;
            }

            // set pts1 which codes Fl and Dl
            ptsRequest[2] = 
                SmartcardExtension->CardCapabilities.PtsData.Fl << 4 |
                SmartcardExtension->CardCapabilities.PtsData.Dl;

            // set pck (check character)
            ptsRequest[3] = ptsRequest[0] ^ ptsRequest[1] ^ ptsRequest[2];   

            SmartcardExtension->SmartcardRequest.BufferLength = 4;
            SmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_WRITE;

            status = TLP3SerialIo(SmartcardExtension);

            if (status != STATUS_SUCCESS) {
                 
                leave;
            }

            // read back the echo of the reader
            SmartcardExtension->SmartcardReply.BufferLength = 4;
            SmartcardExtension->ReaderExtension->SerialIoControlCode = SMARTCARD_READ;

            status = TLP3SerialIo(SmartcardExtension);

            if (status != STATUS_SUCCESS) {
                 
                leave;
            }

            // read back the pts data
            status = TLP3SerialIo(SmartcardExtension);

            if (status != STATUS_SUCCESS && 
                status != STATUS_TIMEOUT) {
                
                leave;       
            }

            if (status != STATUS_TIMEOUT && 
                memcmp(ptsRequest, ptsReply, 4) == 0) {

                // the card replied correctly to our pts-request
                break;
            }

            if (SmartcardExtension->CardCapabilities.PtsData.Type !=
                PTS_TYPE_DEFAULT) {

                SmartcardDebug(
                    DEBUG_TRACE,
                    (TEXT("%s!TLP3SetProtocol: PTS failed. Trying default parameters...\n"),
                    szDriverName,
                    status)
                    );
                //
                // The card did either NOT reply or it replied incorrectly
                // so try default values
                //
                SmartcardExtension->CardCapabilities.PtsData.Type = 
                    PTS_TYPE_DEFAULT;

                SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;

                status = TLP3ReaderPower(SmartcardExtension);

                continue;
            } 
            
            // the card failed the pts-request
            status = STATUS_DEVICE_PROTOCOL_ERROR;
            leave;
        } 

        //
        // The card replied correctly to the pts request
        // Set the appropriate parameters for the port
        //
        if (SmartcardExtension->CardCapabilities.Protocol.Selected &
            SCARD_PROTOCOL_T1) {

            // set timeouts
            serialConfigData->Timeouts.ReadTotalTimeoutConstant =
                (SmartcardExtension->CardCapabilities.T1.BWT
                +MICROSECONDS_PER_MILLISECOND/2)/ MICROSECONDS_PER_MILLISECOND;
                
            serialConfigData->Timeouts.ReadIntervalTimeout =    
                (SmartcardExtension->CardCapabilities.T1.CWT 
                +MICROSECONDS_PER_MILLISECOND/2)/MICROSECONDS_PER_MILLISECOND;

        } else if (SmartcardExtension->CardCapabilities.Protocol.Selected &
                   SCARD_PROTOCOL_T0) {

            // set timeouts
            serialConfigData->Timeouts.ReadTotalTimeoutConstant =
            serialConfigData->Timeouts.ReadIntervalTimeout =  
                (SmartcardExtension->CardCapabilities.T0.WT
                +MICROSECONDS_PER_MILLISECOND/2)/ MICROSECONDS_PER_MILLISECOND;
        }

        // Now make some adjustments depending on the system speed
//        minWaitTime = (KeQueryTimeIncrement() / 10000) * 5;
        if (!QueryPerformanceFrequency(&liProcessClock)) { // not supported
            // ASSUME it is 66 Mhz CPU Clock
            liProcessClock.HighPart=0;
            liProcessClock.LowPart=66*1000000L;
        };
        // Minimum wait set to 5k instruction in Milli Second.
        liProcessClock.QuadPart/=1000; // Frequncy in Milli Second.
        minWaitTime = (DWORD) ((5000L*5+liProcessClock.QuadPart/2)/(liProcessClock.QuadPart));

        pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
            max(pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant,minWaitTime);
        pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=
            max(pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout,minWaitTime);

        // Change data rate according to the new settings
        pReaderExtension->SerialConfigData.SerialControlBlock.BaudRate = 
            SmartcardExtension->CardCapabilities.PtsData.DataRate;
        SmartcardDebug(    DEBUG_TRACE,
            (TEXT("%s!TLP3SetProtocol :TimeOut Interval=%d,Totol%d\n"),
            szDriverName,
            pReaderExtension->SerialConfigData.Timeouts.ReadIntervalTimeout,
            pReaderExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant
            )
        );


        status = TLP3ConfigureSerialPort(SmartcardExtension);          

        ASSERT(status == STATUS_SUCCESS);

        // now indicate that we're 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);
    } 
    finally {

        if (status == STATUS_TIMEOUT) {

            // STATUS_TIMEOUT is not mapped to a Win32 error code
            status = STATUS_IO_TIMEOUT;             

            *SmartcardExtension->IoRequest.Information = 0;

        } else if (status != STATUS_SUCCESS) {
            
            SmartcardExtension->CardCapabilities.Protocol.Selected = 
                SCARD_PROTOCOL_UNDEFINED;

            *SmartcardExtension->IoRequest.Information = 0;
        } 
    }

    SmartcardDebug(
        DEBUG_TRACE,
        (TEXT("%s!TLP3SetProtocol: Exit(%lx)\n"),
        szDriverName,
        status)
        );

   return status;
}

NTSTATUS
TLP3TransmitT0(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

Routine Description:

    This function performs a T=0 transmission.

Arguments:

    SmartcardExtension - Pointer to smart card data struct.

Return Value:

    NTSTATUS

--*/
{
    PUCHAR requestBuffer = SmartcardExtension->SmartcardRequest.Buffer;
    PUCHAR replyBuffer = SmartcardExtension->SmartcardReply.Buffer;
    PULONG requestLength = &SmartcardExtension->SmartcardRequest.BufferLength;
    PULONG replyLength = &SmartcardExtension->SmartcardReply.BufferLength;
    PULONG serialIoControlCode = &SmartcardExtension->ReaderExtension->SerialIoControlCode;
    ULONG bytesToSend, bytesToRead, currentByte = 0;
    BOOLEAN restartWorkWaitingTime = FALSE;
//    DWORD dwMilliSecond;
    NTSTATUS status;

	RETAILMSG(1,(TEXT("\r\n@@@@@@TLP3TransmitT0   begin\r\n")));
    SmartcardDebug(
        DEBUG_TRACE,
        (TEXT("%s!TLP3TransmitT0: Enter\n"),
        szDriverName)
        );

//    try {
        status=(PurgeComm(SmartcardExtension->ReaderExtension->hSerialPort,
            PURGE_RXCLEAR | PURGE_TXCLEAR))?STATUS_SUCCESS:STATUS_UNSUCCESSFUL;

        if (status != STATUS_SUCCESS) 
			return status;    
        // Let the lib build a T=0 packet
        status = SmartcardT0Request(
            SmartcardExtension
            );

        if (status != STATUS_SUCCESS) 
			return status;    

        //
        // The number of bytes we expect from the card

⌨️ 快捷键说明

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