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

📄 tlp3nt.c

📁 bull tlp3智能卡读卡器的驱动程序示例
💻 C
📖 第 1 页 / 共 5 页
字号:
	            break;

	        case 2:
	            //
	            // Set serial special characters
	            //
				SmartcardExtension->ReaderExtension->SerialIoControlCode =
			        IOCTL_SERIAL_SET_CHARS;

		    	SmartcardExtension->SmartcardRequest.Buffer = 
	            	(PUCHAR) &configData->SerialChars;

				SmartcardExtension->SmartcardRequest.BufferLength =
	            	sizeof(SERIAL_CHARS);
	            break;

	        case 3:
	            //
	            // Set up timeouts
	            //
				SmartcardExtension->ReaderExtension->SerialIoControlCode =
		     	   IOCTL_SERIAL_SET_TIMEOUTS;

			    SmartcardExtension->SmartcardRequest.Buffer =
	            	(PUCHAR) &configData->Timeouts;

				SmartcardExtension->SmartcardRequest.BufferLength =
	            	sizeof(SERIAL_TIMEOUTS);
	            break;

	        case 4:
	            // Set flowcontrol and handshaking
				SmartcardExtension->ReaderExtension->SerialIoControlCode =
			        IOCTL_SERIAL_SET_HANDFLOW;

			    SmartcardExtension->SmartcardRequest.Buffer =
	            	(PUCHAR) &configData->HandFlow;

				SmartcardExtension->SmartcardRequest.BufferLength =
	            	sizeof(SERIAL_HANDFLOW);
	            break;

	        case 5:
	            // Set break off
				SmartcardExtension->ReaderExtension->SerialIoControlCode =
			        IOCTL_SERIAL_SET_BREAK_OFF;
	            break;

			case 6:
                // set DTR for the reader
		        SmartcardExtension->ReaderExtension->SerialIoControlCode = 
		        	IOCTL_SERIAL_SET_DTR;
				break;

			case 7:
		        SmartcardExtension->ReaderExtension->SerialIoControlCode =
		        	IOCTL_SERIAL_SET_RTS;
				break;

			case 8:
			    return STATUS_SUCCESS;
        }

	    status = TLP3SerialIo(SmartcardExtension);

		// restore pointer to original request buffer
		SmartcardExtension->SmartcardRequest.Buffer = request;
    }

    return status;
}

NTSTATUS 
TLP3StartSerialEventTracking(
    PSMARTCARD_EXTENSION SmartcardExtension
	)
/*++

Routine Description:

    This routine initializes serial event tracking. 
    It calls the serial driver to set a wait mask for CTS and DSR tracking. 

--*/
{
    NTSTATUS status;
    PREADER_EXTENSION readerExtension = SmartcardExtension->ReaderExtension;
	IO_STATUS_BLOCK ioStatus;
	KEVENT event;

    PAGED_CODE();

    readerExtension->SerialConfigData.SerialWaitMask = 
        SERIAL_EV_CTS | SERIAL_EV_DSR;

    KeInitializeEvent(
        &event,
        NotificationEvent,
        FALSE
        );   

	//
	// Send a wait mask to the serial driver. This call only sets the 
    // wait mask. We want to be informed when CTS or DSR changes its state
	//
    readerExtension->SerialStatusIrp = IoBuildDeviceIoControlRequest(
    	IOCTL_SERIAL_SET_WAIT_MASK,
    	readerExtension->AttachedDeviceObject, 
        &readerExtension->SerialConfigData.SerialWaitMask,
        sizeof(readerExtension->SerialConfigData.SerialWaitMask),
        NULL,
		0,
        FALSE,
        &event,
        &ioStatus
        );

    if (readerExtension->SerialStatusIrp == NULL) {

        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = IoCallDriver(
    	readerExtension->AttachedDeviceObject, 
		readerExtension->SerialStatusIrp,
    	);

	if (status == STATUS_PENDING) {

        status = KeWaitForSingleObject(
            &event,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );
        ASSERT(status == STATUS_SUCCESS);

		status = ioStatus.Status;
	}

	if (status == STATUS_SUCCESS) {

		KIRQL oldIrql;
		LARGE_INTEGER delayPeriod;
		PIO_STACK_LOCATION irpSp;

		//
		// Now tell the serial driver that we want to be informed
		// when CTS or DSR changes its state.
		//
		readerExtension->SerialStatusIrp = IoAllocateIrp(
			(CCHAR) (SmartcardExtension->OsData->DeviceObject->StackSize + 1),
			FALSE
			);

	    if (readerExtension->SerialStatusIrp == NULL) {

	        return STATUS_INSUFFICIENT_RESOURCES;
	    }

	    irpSp = IoGetNextIrpStackLocation( readerExtension->SerialStatusIrp );
		irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;

		irpSp->Parameters.DeviceIoControl.InputBufferLength = 0;
		irpSp->Parameters.DeviceIoControl.OutputBufferLength = 
			sizeof(readerExtension->SerialConfigData.SerialWaitMask);
		irpSp->Parameters.DeviceIoControl.IoControlCode = 
			IOCTL_SERIAL_WAIT_ON_MASK;
		
		readerExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer = 
			&readerExtension->SerialConfigData.SerialWaitMask;

		//
		// this artificial delay is necessary to make this driver work
		// with digi board cards
		//
     	delayPeriod.HighPart = -1;
		delayPeriod.LowPart = 100l * 1000 * (-10);

        KeDelayExecutionThread(
            KernelMode,
            FALSE,
            &delayPeriod
            );
        
        // We simulate a callback now that triggers the card supervision
        TLP3SerialEvent(
            SmartcardExtension->OsData->DeviceObject,
            readerExtension->SerialStatusIrp,
            SmartcardExtension
            );

		status = STATUS_SUCCESS;
	}

    return status;                                        
}	

VOID
TLP3CompleteCardTracking(
    IN PSMARTCARD_EXTENSION SmartcardExtension
    )
{
    KIRQL ioIrql, keIrql;
    PIRP notificationIrp;

    IoAcquireCancelSpinLock(&ioIrql);
    KeAcquireSpinLock(
        &SmartcardExtension->OsData->SpinLock, 
        &keIrql
        );

    notificationIrp = SmartcardExtension->OsData->NotificationIrp;
    SmartcardExtension->OsData->NotificationIrp = NULL;

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

    if (notificationIrp) {

        IoSetCancelRoutine(
            notificationIrp, 
            NULL
            );
    }

    IoReleaseCancelSpinLock(ioIrql);

    if (notificationIrp) {
     	
		SmartcardDebug(
			DEBUG_INFO,
			("%s!TLP3CompleteCardTracking: Completing NotificationIrp %lxh\n",
            DRIVER_NAME,
            notificationIrp)
			);

	    //	finish the request
        if (notificationIrp->Cancel) {
         	
	        notificationIrp->IoStatus.Status = STATUS_CANCELLED;

        } else {
         	
	        notificationIrp->IoStatus.Status = STATUS_SUCCESS;
        }
	    notificationIrp->IoStatus.Information = 0;

	    IoCompleteRequest(
            notificationIrp, 
            IO_NO_INCREMENT 
            );
    }
}

NTSTATUS 
TLP3SerialEvent(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

Routine Description:

    This routine is called in two cases:
    a) CTS changed (card inserted or removed) or
    b) DSR changed (reader has been removed)
	
    For a) we update the card status and complete outstanding 
    card tracking requests.
    For b) we start to unload the driver

    NOTE: This function calls itself using IoCompletion. In the 'first'
    callback the serial driver only tells us that something has changed.
    We set up a call for 'what has changed' (GetModemStatus) which then
    call this function again.
    When we updated everything and we don't unload the driver card
    tracking is started again.

--*/
{
	NTSTATUS status;
    KIRQL irql;

    KeAcquireSpinLock(
        &SmartcardExtension->OsData->SpinLock,
        &irql
        );

	if (SmartcardExtension->ReaderExtension->GetModemStatus) {

		//
		// This function requested the modem status previously.
        // As part of the io-completion, this function is then
        // called again. When we're here we can read the actual 
        // modem-status to figure out if the card is in the reader
		//
		if ((SmartcardExtension->ReaderExtension->ModemStatus & SERIAL_DSR_STATE) == 0) {

			SmartcardDebug(
				DEBUG_INFO,
				("%s!TLP3SerialEvent: Reader removed\n",
                DRIVER_NAME)
				);

            //
            // We set the mask to zero to signal that we can 
            // release the irp that we use for the serial events
            //
            SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask = 0;
			SmartcardExtension->ReaderCapabilities.CurrentState = SCARD_UNKNOWN;

        } else {

		    if (SmartcardExtension->ReaderExtension->ModemStatus & SERIAL_CTS_STATE) {

			    // Card is inserted
	            SmartcardExtension->ReaderCapabilities.CurrentState = 
                    SCARD_SWALLOWED;

			    SmartcardExtension->CardCapabilities.Protocol.Selected = 
				    SCARD_PROTOCOL_UNDEFINED;

			    SmartcardDebug(
				    DEBUG_INFO,
				    ("%s!TLP3SerialEvent: Smart card inserted\n",
                    DRIVER_NAME)
				    );

		    } else {
			    
			    // Card is removed
                SmartcardExtension->CardCapabilities.ATR.Length = 0;

	            SmartcardExtension->ReaderCapabilities.CurrentState = 
	        	    SCARD_ABSENT;

			    SmartcardExtension->CardCapabilities.Protocol.Selected = 
				    SCARD_PROTOCOL_UNDEFINED;

			    SmartcardDebug(
				    DEBUG_INFO,
				    ("%s!TLP3SerialEvent: Smart card removed\n",
                    DRIVER_NAME)
				    );
		    }
        }
    }

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

	//
	// Only inform the user of a card insertion/removal event 
	// if this function isn't called due to a power down - power up cycle
	//
	if (SmartcardExtension->ReaderExtension->PowerRequest == FALSE) {

        TLP3CompleteCardTracking(SmartcardExtension);
	}

    // The wait mask is set to 0 when the driver unloads
	if (SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask == 0) {

        // The reader has been unplugged.
        PDEVICE_EXTENSION deviceExtension = 
            SmartcardExtension->OsData->DeviceObject->DeviceExtension;

        // schedule our remove thread
		IoQueueWorkItem(
			deviceExtension->CloseSerial,
            (PIO_WORKITEM_ROUTINE) TLP3CloseSerialPort,
			DelayedWorkQueue,
            NULL
			);

        SmartcardDebug(
            DEBUG_TRACE,
            ("%s!TLP3SerialEvent: Exit (Release IRP)\n",
            DRIVER_NAME)
            );

		//
        // We don't need the IRP anymore, so free it and tell the 
		// io subsystem not to touch it anymore by returning the value below
		//
		IoFreeIrp(Irp);
		return STATUS_MORE_PROCESSING_REQUIRED;
    }

	if (SmartcardExtension->ReaderExtension->GetModemStatus == FALSE) {

		//
		// Setup call for device control to get modem status.
		// The CTS signal tells us if the card is inserted or removed. 
		// CTS is high if the card is inserted.
		//
		PIO_STACK_LOCATION irpStack;

		irpStack = IoGetNextIrpStackLocation(
			SmartcardExtension->ReaderExtension->SerialStatusIrp
			);

		irpStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
	    irpStack->MinorFunction = 0UL;
	    irpStack->Parameters.DeviceIoControl.OutputBufferLength = 
	    	sizeof(SmartcardExtension->ReaderExtension->ModemStatus);
	    irpStack->Parameters.DeviceIoControl.IoControlCode = 
	    	IOCTL_SERIAL_GET_MODEMSTATUS;

		SmartcardExtension->ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer = 
			&SmartcardExtension->ReaderExtension->ModemStatus;

		SmartcardExtension->ReaderExtension->GetModemStatus = TRUE;

	} else {
     	
        PIO_STACK_LOCATION irpStack;

		// Setup call for device control to wait for a serial event
		irpStack = IoGetNextIrpStackLocation(
			SmartcardExtension->ReaderExtension->SerialStatusIrp
			);

#if defined (DEBUG) && defined (DETECT_SERIAL_OVERRUNS)
        if (Irp->IoStatus.Status != STATUS_SUCCESS) {

            //
            // we need to call the serial driver to reset the internal 
            // error counters, otherwise the serial driver refuses to work
            //

            static SERIAL_STATUS serialStatus;

			SmartcardDebug( 
				DEBUG_ERROR, 
				( "%s!TLP3SerialEvent: Reset of serial error condition...\n",
				DRIVER_NAME)
				);

		    irpStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
	        irpStack->MinorFunction = 0UL;
	        irpStack->Parameters.DeviceIoControl.OutputBufferLength = 
	            sizeof(serialStatus);
	        irpStack->Parameters.DeviceIoControl.IoControlCode = 
	    	    IOCTL_SERIAL_GET_COMMSTATUS;

		    SmartcardExtension->ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer = 
	            &serialStatus;
        } else
#endif
        { 	
		    irpStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
	        irpStack->MinorFunction = 0UL;
	        irpStack->Parameters.DeviceIoControl.OutputBufferLength = 
	            sizeof(SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask);
	        irpStack->Parameters.DeviceIoControl.IoControlCode = 
	    	    IOCTL_SERIAL_WAIT_ON_MASK;

		    SmartcardExtension->ReaderExtension->SerialStatusIrp->AssociatedIrp.SystemBuffer = 
	            &SmartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask;

        }

		SmartcardExtension->ReaderExtension->GetModemStatus = FALSE;
    }

	IoSetCompletionRoutine(
		SmartcardExtension->ReaderExtension->SerialStatusIrp,
		TLP3SerialEvent,
		SmartcardExtension,
		TRUE,
		TRUE,
		TRUE
		);

    status = IoCallDriver(
    	SmartcardExtension->ReaderExtension->AttachedDeviceObject, 
    	SmartcardExtension->ReaderExtension->SerialStatusIrp
    	);

    return STATUS_MORE_PROCESSING_REQUIRED;
}	


⌨️ 快捷键说明

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