Windows驱动无法再安装

最近准备写一个驱动与应用Win32程序通信的功能,调研后发现可以通过缓冲区IO的方式工作,于是写出个demo(代码放置文末)测试,但是很奇怪,驱动卸载一次后就再也无法安装成功,
DriverMonitor提示:

The imagepath specified in the driver's service database entry is incorrect,or the file is missing.

除非重启电脑才能再次安装。

经过排查发现是一行代码导致:

 gDeviceObject->Flags = DO_BUFFERED_IO;

将其注释后程序卸载安装恢复正常。

这行代码是设置缓冲区IO的必要代码,所以肯定是要保留的,目前还没有找到具体原因和解决方法。

有懂行的朋友还请不吝赐教。

#include <ntddk.h>

// 定义设备名和符号名
UNICODE_STRING gDeviceName = RTL_CONSTANT_STRING(L"\\DosDevices\\PROCMON");
UNICODE_STRING gSymbolicLinkName = RTL_CONSTANT_STRING(L"\\Device\\PROCMON");

PDEVICE_OBJECT gDeviceObject = NULL;

// 设备创建函数
NTSTATUS DeviceCreate(PDEVICE_OBJECT Device, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	// I/O请求处理完毕
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	DbgPrint("Create Device Success\n");
	return STATUS_SUCCESS;
}

// 设备读操作函数
NTSTATUS DeviceRead(PDEVICE_OBJECT Device, PIRP pIrp)
{
	// 获取指向IRP的堆栈的指针
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
	// 获取堆栈长度
	ULONG length = stack->Parameters.Read.Length;
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = length;
	// 将堆栈上的数据全设置为0xAA
	memset(pIrp->AssociatedIrp.SystemBuffer, 0xAA, length);
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	DbgPrint("Read Device Success\n");
	return STATUS_SUCCESS;
}

// 设备关闭函数
NTSTATUS DeviceClose(PDEVICE_OBJECT Device, PIRP pIrp)
{
	// 跟设备创建函数相同
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	DbgPrint("Close Device Success\n");
	return STATUS_SUCCESS;
}

// 驱动卸载函数
NTSTATUS DriverUnload(PDRIVER_OBJECT Driver)
{
	NTSTATUS status;

	// 删除符号和设备
	IoDeleteSymbolicLink(&gSymbolicLinkName);
	IoDeleteDevice(gDeviceObject);
	DbgPrint("This Driver Is Unloading...\n");
	return STATUS_SUCCESS;
}

// 驱动入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT Driver, PUNICODE_STRING RegPath)
{
	NTSTATUS status;

	// 注册设备创建函数、设备读函数、设备关闭函数、驱动卸载函数
	Driver->MajorFunction[IRP_MJ_CREATE] = DeviceCreate;
	Driver->MajorFunction[IRP_MJ_READ] = DeviceRead;
	Driver->MajorFunction[IRP_MJ_CLOSE] = DeviceClose;
	Driver->DriverUnload = DriverUnload;

	// 创建设备对象
	status = IoCreateDevice(Driver, 0, &gDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &gDeviceObject);
	if (!NT_SUCCESS(status))
	{
		DbgPrint("Create Device Faild!\n");
		return STATUS_UNSUCCESSFUL;
	}

	// 将符号与设备关联
	status = IoCreateSymbolicLink(&gSymbolicLinkName, &gDeviceName);
	if (!NT_SUCCESS(status))
	{
		DbgPrint("Create SymLink Faild!\n");
		IoDeleteSymbolicLink(&gSymbolicLinkName);
		IoDeleteDevice(gDeviceObject);
		return STATUS_UNSUCCESSFUL;
	}

	DbgPrint("Initialize Success\n");

	// 设置pDevice以缓冲区方式读取
	gDeviceObject->Flags = DO_BUFFERED_IO;

	return STATUS_SUCCESS;
}
posted @ 2021-03-17 17:23  涌竹  阅读(324)  评论(1)    收藏  举报