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

📄 tlp3cb.c

📁 SmardCard Windows驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/*++

Copyright (C) 1997, 98 Microsoft Corporation

Module Name:

    tlp3cb.c

Abstract:

    Callback functions for smart card library

Author:

    Klaus U. Schutz

Environment:                       

    Kernel mode

--*/
                                            
#include <stdio.h> 
#include "bulltlp3.h"

#pragma alloc_text(PAGEABLE, TLP3SetProtocol)
#pragma alloc_text(PAGEABLE, TLP3SetParameters)
#pragma alloc_text(PAGEABLE, TLP3TransmitT0)
#pragma alloc_text(PAGEABLE, TLP3Transmit)
#pragma alloc_text(PAGEABLE, TLP3VendorIoctl)

NTSTATUS
TLP3ReaderPower(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

Routine Description:

	The smart card lib requires to have this function. It is called 
	for certain power requests to the card. We do nothing here, because
	this action is performed in the StartIo function.

--*/
{
	ULONG step, waitTime, TdIndex, numTry = 0, minWaitTime;
	NTSTATUS status = STATUS_SUCCESS;
	PSERIAL_STATUS serialStatus;
	KIRQL oldIrql;
    PUCHAR requestBuffer;
    PSERIAL_READER_CONFIG serialConfigData = 
        &SmartcardExtension->ReaderExtension->SerialConfigData;

	SmartcardDebug(
		DEBUG_TRACE,
		("%s!TLP3ReaderPower: Enter (%lx)\n",
        DRIVER_NAME,
        SmartcardExtension->MinorIoControlCode)
		);

    _try {
     	
#if defined (DEBUG) && defined (DETECT_SERIAL_OVERRUNS)
        // we have to call GetCommStatus to reset the error condition
	    SmartcardExtension->ReaderExtension->SerialIoControlCode =
		    IOCTL_SERIAL_GET_COMMSTATUS;
	    SmartcardExtension->SmartcardRequest.BufferLength = 0;
	    SmartcardExtension->SmartcardReply.BufferLength = 
		    sizeof(SERIAL_STATUS);

	    status = TLP3SerialIo(SmartcardExtension);
        ASSERT(status == STATUS_SUCCESS);
#endif
        //
        // Set standard parameters for serial port
        // 
        serialConfigData->LineControl.Parity = EVEN_PARITY;
        serialConfigData->LineControl.StopBits = STOP_BITS_2;

        serialConfigData->BaudRate.BaudRate = 
            SmartcardExtension->ReaderCapabilities.DataRate.Default;

        // we set very short timeouts to get the ATR as fast as possible
        serialConfigData->Timeouts.ReadIntervalTimeout = 
            READ_INTERVAL_TIMEOUT_ATR;
        serialConfigData->Timeouts.ReadTotalTimeoutConstant =
            READ_TOTAL_TIMEOUT_CONSTANT_ATR;

        status = TLP3ConfigureSerialPort(SmartcardExtension);

        ASSERT(status == STATUS_SUCCESS);

        if (status != STATUS_SUCCESS) {

            leave;
        }                     

	    // We don't send data to the reader, so set Number of bytes to send = 0
	    SmartcardExtension->SmartcardRequest.BufferLength = 0;

	    // Default number of bytes we expect to get back
	    SmartcardExtension->SmartcardReply.BufferLength = 0;

	    //
	    // Since power down triggers the UpdateSerialStatus function, we have
	    // to inform it that we forced the change of the status and not the user
	    // (who might have removed and inserted a card)
	    //
	    // SmartcardExtension->ReaderExtension->PowerRequest = TRUE;

	    // purge the serial buffer (it can contain the pnp id of the reader)
	    SmartcardExtension->ReaderExtension->SerialIoControlCode =
		    IOCTL_SERIAL_PURGE;
	    *(PULONG) SmartcardExtension->SmartcardRequest.Buffer =
		    SERIAL_PURGE_RXCLEAR | SERIAL_PURGE_TXCLEAR;;
	    SmartcardExtension->SmartcardRequest.BufferLength =
		    sizeof(ULONG);

	    status = TLP3SerialIo(SmartcardExtension);

        ASSERT(status == STATUS_SUCCESS);

        if (status != STATUS_SUCCESS) {

            leave;
        }

        SmartcardExtension->CardCapabilities.ATR.Length = 0;

	    for (step = 0; NT_SUCCESS(status); step++) {

            if (SmartcardExtension->MinorIoControlCode == 
                SCARD_WARM_RESET && 
                step == 0) {

                step = 4;         	
            }

		    switch (step) {

		        case 0:
                    // RTS = 0 means reader is in command mode
			        SmartcardExtension->ReaderExtension->SerialIoControlCode =
				        IOCTL_SERIAL_CLR_RTS;
                    //
                    // This is the minimum wait time we have to wait before
                    // we can send commands to the microcontroller.
                    //
			        waitTime = 1000;
			        break;

		        case 1:
			        // write power down command to the reader
			        SmartcardExtension->ReaderExtension->SerialIoControlCode =
				        SMARTCARD_WRITE;
			        SmartcardExtension->SmartcardRequest.BufferLength =	1;

                    SmartcardExtension->SmartcardRequest.Buffer[0] = 
                        READER_CMD_POWER_DOWN;

			        waitTime = 100;
			        break;

		        case 2:
			        // Read back the echo of the reader
			        SmartcardExtension->ReaderExtension->SerialIoControlCode =
				        SMARTCARD_READ;
			        SmartcardExtension->SmartcardReply.BufferLength = 1;

                    // Wait the recovery time for the microcontroller 
			        waitTime = 1000;
			        break;

		        case 3:
                    // set RTS again so the microcontroller can execute the command
			        SmartcardExtension->ReaderExtension->SerialIoControlCode =
				        IOCTL_SERIAL_SET_RTS;
			        waitTime = 10000;
			        break;

		        case 4:
                    if (SmartcardExtension->MinorIoControlCode == SCARD_POWER_DOWN) {

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

				        SmartcardExtension->CardCapabilities.Protocol.Selected = 
					        SCARD_PROTOCOL_UNDEFINED;

                        status = STATUS_SUCCESS;             	
                        leave;
                    }

                    // clear RTS to switch to command mode
			        SmartcardExtension->ReaderExtension->SerialIoControlCode =
				        IOCTL_SERIAL_CLR_RTS;

                    // Wait the recovery time for the microcontroller 
			        waitTime = 1000;
			        break;

		        case 5:
			        // write the appropriate reset command to the reader
			        SmartcardExtension->ReaderExtension->SerialIoControlCode =
				        SMARTCARD_WRITE;
			        SmartcardExtension->SmartcardRequest.BufferLength =	1;
                    switch (SmartcardExtension->MinorIoControlCode) {

                    case SCARD_COLD_RESET:
                        SmartcardExtension->SmartcardRequest.Buffer[0] = 
                            READER_CMD_COLD_RESET;
                        break;

                    case SCARD_WARM_RESET:
                        SmartcardExtension->SmartcardRequest.Buffer[0] = 
                            READER_CMD_WARM_RESET;
                        break;
                    }
			        waitTime = 100;
			        break;

		        case 6:
			        // Read back the echo of the reader
			        SmartcardExtension->ReaderExtension->SerialIoControlCode =
				        SMARTCARD_READ;
			        SmartcardExtension->SmartcardReply.BufferLength = 1;

                    //
                    // This is the time we need to wait for the microcontroller
                    // to recover before we can set RTS again
                    //
			        waitTime = 1000;
			        break;

		        case 7:
                    // set RTS again so the microcontroller can execute the command
			        SmartcardExtension->ReaderExtension->SerialIoControlCode =
				        IOCTL_SERIAL_SET_RTS;
			        waitTime = 10000; 
			        break;

		        case 8:
                    //
                    // We now try to get the ATR as fast as possible.
                    // Therefor we prev. set a very short read timeout and
                    // 'hope' that the card delivered its ATR within this 
                    // short time. To verify the correctness of the ATR we call
                    // SmartcardUpdateCardCapabilities(). If this call returns
                    // with STATUS_SUCCESS we know that the ATR is complete.
                    // Otherwise we read again and append the new data to the 
                    // ATR buffer in the CardCapabilities and try again.
                    //
			        SmartcardExtension->ReaderExtension->SerialIoControlCode = 
				        SMARTCARD_READ;

			        SmartcardExtension->SmartcardReply.BufferLength = 
                        MAXIMUM_ATR_LENGTH - 
                        SmartcardExtension->CardCapabilities.ATR.Length;

			        waitTime = 0;                                     
			        break;

                case 9:
                    if (SmartcardExtension->SmartcardReply.BufferLength != 0) {

                        ASSERT(
                            SmartcardExtension->CardCapabilities.ATR.Length +
                            SmartcardExtension->SmartcardReply.BufferLength <
                            MAXIMUM_ATR_LENGTH
                            );

                        if( SmartcardExtension->CardCapabilities.ATR.Length +
                            SmartcardExtension->SmartcardReply.BufferLength >=
                            MAXIMUM_ATR_LENGTH) {

                            status = STATUS_UNRECOGNIZED_MEDIA;
                            leave;
                        }
                     
                        // we got some ATR bytes. 
				        RtlCopyMemory(
					        SmartcardExtension->CardCapabilities.ATR.Buffer + 
                                SmartcardExtension->CardCapabilities.ATR.Length,
					        SmartcardExtension->SmartcardReply.Buffer,
					        SmartcardExtension->SmartcardReply.BufferLength
					        );

				        SmartcardExtension->CardCapabilities.ATR.Length += 
                            (UCHAR) SmartcardExtension->SmartcardReply.BufferLength;

                        status = SmartcardUpdateCardCapabilities(
                            SmartcardExtension
                            );
                    }

                    if (status != STATUS_SUCCESS && numTry < 25) {

                        if (SmartcardExtension->SmartcardReply.BufferLength != 0) {
                         	
                            // Because we received some data, we reset our counter
                            numTry = 0;

                        } else {
                         	
                            // ATR is incomplete. Try again to get ATR bytes.
                            numTry += 1;
                        }

                        // continue with step 8
                        step = 7;
                        status = STATUS_TIMEOUT;
                        continue;                     	
                    }

                    if (status != STATUS_SUCCESS) {

                        leave;
                    }
                	// No break

		        case 10:
                    KeAcquireSpinLock(
				        &SmartcardExtension->OsData->SpinLock,
				        &oldIrql
				        );

			        if (SmartcardExtension->ReaderCapabilities.CurrentState <=
				        SCARD_ABSENT) {

				        status = STATUS_MEDIA_CHANGED;
			        } 

			        KeReleaseSpinLock(
				        &SmartcardExtension->OsData->SpinLock,
				        oldIrql
				        );

                    if (status != STATUS_SUCCESS) {

                        leave;                     	
                    }

#ifdef SIMULATION
					if (SmartcardExtension->ReaderExtension->SimulationLevel &
						SIM_ATR_TRASH) {

						ULONG index;
						LARGE_INTEGER tickCount;

						KeQueryTickCount(
							&tickCount
							);

						SmartcardExtension->CardCapabilities.ATR.Length = 
							(UCHAR) tickCount.LowPart % MAXIMUM_ATR_LENGTH;

						for (index = 0; 
							 index < SmartcardExtension->CardCapabilities.ATR.Length;
							 index++) {

							SmartcardExtension->CardCapabilities.ATR.Buffer[index] *= 
								(UCHAR) tickCount.LowPart;
						}

						SmartcardDebug(
							DEBUG_SIMULATION,
							("%s!TLP3ReaderPower: SIM ATR trash\n",
							DRIVER_NAME)
							);
					}
#endif

				    // Copy ATR to user space
                    if (SmartcardExtension->IoRequest.ReplyBuffer) {
                
					    RtlCopyMemory(
						    SmartcardExtension->IoRequest.ReplyBuffer,
						    SmartcardExtension->CardCapabilities.ATR.Buffer,
						    SmartcardExtension->CardCapabilities.ATR.Length
						    );

					    // Tell user length of ATR
					    *SmartcardExtension->IoRequest.Information =
						    SmartcardExtension->CardCapabilities.ATR.Length;
                    }

				    //
				    // If the card uses invers convention we need to switch
				    // the serial driver to odd paritiy
				    //
				    if (SmartcardExtension->CardCapabilities.InversConvention) {

					    serialConfigData->LineControl.Parity = ODD_PARITY;
				    }

                    //
                    // If the extra guard time is 255 it means that our
                    // frame we have to expect from the card has only
                    // 1 instead of 2 stop bits 
                    // 1start bit + 8data bits + 1parity + 1stop == 11 etu
                    // see iso 7816-3 6.1.4.4 Extra Guard Time N
                    //
                    if (SmartcardExtension->CardCapabilities.PtsData.StopBits == 1) {

                        serialConfigData->LineControl.StopBits = STOP_BIT_1;      
                    }

					// Change data rate according to the new settings
					serialConfigData->BaudRate.BaudRate = 
						SmartcardExtension->CardCapabilities.PtsData.DataRate;

                    // depending on the protocol set the timeout values
                    if (SmartcardExtension->CardCapabilities.Protocol.Selected &
                        SCARD_PROTOCOL_T1) {

                        // set timeouts
                        serialConfigData->Timeouts.ReadTotalTimeoutConstant =
                            SmartcardExtension->CardCapabilities.T1.BWT / 1000;

                        serialConfigData->Timeouts.ReadIntervalTimeout =  
                            SmartcardExtension->CardCapabilities.T1.CWT / 1000;

⌨️ 快捷键说明

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