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

📄 tlp3nt.c

📁 bull tlp3智能卡读卡器的驱动程序示例
💻 C
📖 第 1 页 / 共 5 页
字号:
        irpStack->Parameters.Create.EaLength = 0;

        status = TLP3CallSerialDriver(
            ATTACHED_DEVICE_OBJECT, 
            irp
            );   
	    if (status != STATUS_SUCCESS) {

            leave;
        }

        KeClearEvent(&READER_EXTENSION_L(SerialCloseDone));

        status = TLP3ConfigureSerialPort(&deviceExtension->SmartcardExtension);
	    if (status != STATUS_SUCCESS) {
        
            leave;
        }

	    status = TLP3StartSerialEventTracking(
            &deviceExtension->SmartcardExtension
            );

	    if (status != STATUS_SUCCESS) {

            leave;
        }

        status = IoSetDeviceInterfaceState(
            &deviceExtension->PnPDeviceName,
            TRUE
            );

        if (status != STATUS_SUCCESS) {

            leave;
        }

        KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
    }
    _finally {

        if (status == STATUS_SHARED_IRQ_BUSY) {

	        SmartcardLogError(
		        DeviceObject,
		        TLP3_IRQ_BUSY,
		        NULL,
		        status
		        );
        }

        if (status != STATUS_SUCCESS) {

            TLP3StopDevice(DeviceObject);         	
        }

        IoFreeIrp(irp);
    }

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "%s!TLP3StartDevice: Exit %lx\n",
        DRIVER_NAME, 
        status)
		);

    return status;
}

VOID
TLP3StopDevice(
    IN PDEVICE_OBJECT DeviceObject
    )
/*++

Routine Description:
    Finishes card tracking requests and closes the connection to the 
    serial driver.
	
--*/
{
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "%s!TLP3StopDevice: Enter\n",
        DRIVER_NAME)
		);

    if (KeReadStateEvent(&READER_EXTENSION_L(SerialCloseDone)) == 0l) {

        NTSTATUS status;
        PUCHAR requestBuffer;
        PSMARTCARD_EXTENSION smartcardExtension = 
            &deviceExtension->SmartcardExtension;

        // test if we ever started event tracking
        if (smartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask == 0) {

            // no, we did not
            // We 'only' need to close the serial port
            TLP3CloseSerialPort(DeviceObject, NULL);       	

        } else {

            //
            // We now inform the serial driver that we're not longer
            // interested in serial events. This will also free the irp
            // we use for those io-completions
            //
	        smartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask = 0;

            // save the pointer
            requestBuffer = smartcardExtension->SmartcardRequest.Buffer;

	        *(PULONG) smartcardExtension->SmartcardRequest.Buffer = 
		        smartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask;

	        smartcardExtension->SmartcardRequest.BufferLength = sizeof(ULONG);

	        smartcardExtension->ReaderExtension->SerialIoControlCode = 
		        IOCTL_SERIAL_SET_WAIT_MASK;

	        // We don't expect to get bytes back
	        smartcardExtension->SmartcardReply.BufferLength = 0;

	        TLP3SerialIo(smartcardExtension);

            // restore the pointer
            smartcardExtension->SmartcardRequest.Buffer = requestBuffer;     	

            // now wait until the connetion to serial is closed
            status = KeWaitForSingleObject(
                &READER_EXTENSION_L(SerialCloseDone),
                Executive,
                KernelMode,
                FALSE,
                NULL
                );
            ASSERT(status == STATUS_SUCCESS);
        }
    } 	

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "%s!TLP3StopDevice: Exit\n",
        DRIVER_NAME)
		);
}

NTSTATUS
TLP3DeviceControl(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp
    )
/*++

Routine Description:
    This is our IOCTL dispatch function

--*/
{
	PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
    NTSTATUS status = STATUS_SUCCESS;
    KIRQL irql;
#ifdef SIMULATION
	RTL_QUERY_REGISTRY_TABLE parameters[2];
#endif

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "%s!TLP3DeviceControl: Enter\n",
        DRIVER_NAME)
		);

	if (smartcardExtension->ReaderExtension->SerialConfigData.SerialWaitMask == 0) {

		//
		// the wait mask is set to 0 whenever the device was either
		// surprise-removed or politely removed
		//
		status = STATUS_DEVICE_REMOVED;
	}

	if (status == STATUS_SUCCESS) {

		KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
		if (deviceExtension->IoCount == 0) {
 
			KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
			status = KeWaitForSingleObject(
				&deviceExtension->ReaderStarted,
				Executive,
				KernelMode,
				FALSE,
				NULL
				);
			ASSERT(status == STATUS_SUCCESS);

			KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
		} 
		ASSERT(deviceExtension->IoCount >= 0);
		deviceExtension->IoCount++;
		KeReleaseSpinLock(&deviceExtension->SpinLock, irql);

		status = SmartcardAcquireRemoveLockWithTag(smartcardExtension, 'tcoI');
	}

    if (status != STATUS_SUCCESS) {

        // the device has been removed. Fail the call
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_DEVICE_REMOVED;
    }

#ifdef SIMULATION
	if (DriverKey) {

		ULONG oldLevel = 
			smartcardExtension->ReaderExtension->SimulationLevel;

		RtlZeroMemory(parameters, sizeof(parameters));

		parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
		parameters[0].Name = L"SimulationLevel";
		parameters[0].EntryContext = 
			&smartcardExtension->ReaderExtension->SimulationLevel;
		parameters[0].DefaultType = REG_DWORD;
		parameters[0].DefaultData = 
			&smartcardExtension->ReaderExtension->SimulationLevel;
		parameters[0].DefaultLength = sizeof(ULONG);

		if (RtlQueryRegistryValues(
			 RTL_REGISTRY_ABSOLUTE,
			 DriverKey, 
			 parameters,
			 NULL,
			 NULL
			 ) == STATUS_SUCCESS) {

			SmartcardDebug( 
				smartcardExtension->ReaderExtension->SimulationLevel == oldLevel ? 0 : DEBUG_SIMULATION, 
				( "%s!TLP3AddDevice: SimulationLevel set to %lx\n",
				DRIVER_NAME,
				smartcardExtension->ReaderExtension->SimulationLevel)
				);
		}
	}
#endif

    ASSERT(smartcardExtension->ReaderExtension->ReaderPowerState == 
        PowerReaderWorking);

	status = SmartcardDeviceControl(
		smartcardExtension,
		Irp
		);

    SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'tcoI');

    KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
    deviceExtension->IoCount--;
    ASSERT(deviceExtension->IoCount >= 0);
    KeReleaseSpinLock(&deviceExtension->SpinLock, irql);

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "%s!TLP3DeviceControl: Exit %lx\n",
        DRIVER_NAME,
        status)
		);

    return status;
}

VOID 
TLP3CloseSerialPort(
    IN PDEVICE_OBJECT DeviceObject,
    IN PVOID Context
    )
/*++

Routine Description:
    This function closes the connection to the serial driver when the reader 
    has been removed (unplugged). This function runs as a system thread at 
    IRQL == PASSIVE_LEVEL. It waits for the remove event that is set by
    the IoCompletionRoutine
	
--*/
{
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
	PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
    NTSTATUS status;
    PIRP irp;
    PIO_STACK_LOCATION irpStack;
    IO_STATUS_BLOCK ioStatusBlock;

    UNREFERENCED_PARAMETER(Context);

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "%s!TLP3CloseSerialPort: Enter\n",
        DRIVER_NAME)
		);

    //
    // first mark this device as 'gone'.
    // This will prevent that someone can re-open the device
    // We intentionally ignore possible errors
    //
    IoSetDeviceInterfaceState(
        &deviceExtension->PnPDeviceName,
        FALSE
        );

    irp = IoAllocateIrp(
        (CCHAR) (DeviceObject->StackSize + 1),
        FALSE
        );

    ASSERT(irp != NULL);

    if (irp) {

	    SmartcardDebug( 
		    DEBUG_DRIVER, 
		    ( "%s!TLP3CloseSerialPort: Sending IRP_MJ_CLOSE\n",
            DRIVER_NAME)
		    );

        IoSetNextIrpStackLocation(irp);

        //
        // We send down a close to the serial driver. This close goes 
        // through serenum first which will trigger it to start looking
        // for changes on the com-port. Since our device is gone it will
        // call the device removal event of our PnP dispatch.
        //
        irp->UserIosb = &ioStatusBlock;
        irpStack = IoGetCurrentIrpStackLocation( irp );
        irpStack->MajorFunction = IRP_MJ_CLOSE;

        status = TLP3CallSerialDriver(
            ATTACHED_DEVICE_OBJECT,
            irp
            );   

        ASSERT(status == STATUS_SUCCESS);
    
        IoFreeIrp(irp);
    }

    // now 'signal' that we closed the serial driver
    KeSetEvent(
		&READER_EXTENSION_L(SerialCloseDone),
		0, 
		FALSE
		);

	SmartcardDebug( 
		DEBUG_INFO, 
		( "%s!TLP3CloseSerialPort: Exit\n",
        DRIVER_NAME)
		);
}
    
NTSTATUS
TLP3IoCompletion (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PKEVENT Event
    )
{
    UNREFERENCED_PARAMETER (DeviceObject);

    if (Irp->Cancel) {

        Irp->IoStatus.Status = STATUS_CANCELLED;

    } else {
     	
        Irp->IoStatus.Status = STATUS_MORE_PROCESSING_REQUIRED;
    }

    KeSetEvent (Event, 0, FALSE);

    return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS 
TLP3CallSerialDriver(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp
    )
/*++

Routine Description:
	Send an Irp to the serial driver.

--*/
{
 	
	NTSTATUS status = STATUS_SUCCESS;
    KEVENT Event;

    // Copy our stack location to the next.
    IoCopyCurrentIrpStackLocationToNext(Irp);

	//
	// initialize an event for process synchronization. The event is passed
	// to our completion routine and will be set when the serial driver is done
	//
    KeInitializeEvent(
        &Event,
        NotificationEvent,
        FALSE
        );   
    
    // Our IoCompletionRoutine sets only our event
    IoSetCompletionRoutine (
        Irp,
        TLP3IoCompletion,
        &Event,
        TRUE,
        TRUE,
        TRUE
        );

    if (IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_POWER) {
     	
        status = PoCallDriver(DeviceObject, Irp);

    } else {
     	
        // Call the serial driver
        status = IoCallDriver(DeviceObject, Irp);
    }

	// Wait until the serial driver has processed the Irp
    if (status == STATUS_PENDING) {

        status = KeWaitForSingleObject(
            &Event,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

        ASSERT (STATUS_SUCCESS == status);
        status = Irp->IoStatus.Status;
    } 

    return status;
}

NTSTATUS
TLP3PnP(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp
    )
/*++

Routine Description:

--*/
{
 	
    PUCHAR requestBuffer;
	NTSTATUS status = STATUS_SUCCESS;
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
    PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
    PREADER_EXTENSION readerExtension = smartcardExtension->ReaderExtension;
    PDEVICE_OBJECT AttachedDeviceObject;
	PIO_STACK_LOCATION irpStack;
    IO_STATUS_BLOCK ioStatusBlock;
    BOOLEAN deviceRemoved = FALSE, irpSkipped = FALSE;
    KIRQL irql;

	SmartcardDebug( 
		DEBUG_TRACE, 
		( "%s!TLP3PnPDeviceControl: Enter\n",
        DRIVER_NAME)
		);

    status = SmartcardAcquireRemoveLockWithTag(smartcardExtension, ' PnP');
    ASSERT(status == STATUS_SUCCESS);

    if (status != STATUS_SUCCESS) {

        Irp->IoStatus.Information = 0;

⌨️ 快捷键说明

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