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

📄 hellowdm.cpp

📁 windows WDM驱动开发实例
💻 CPP
字号:
//: HelloWDM.cpp
/***************************************************************
程序名称:Hello World for WDM
文件名称:HelloWDM.cpp
作者:KEVIN
日期:2008-03-05
***************************************************************/
#include "HelloWDM.h"

/***************************************************************
函数名称:DriverEntry()
功能描述:WDM程序入口
***************************************************************/
//extern "C"是必须的,表示"用C链接"。如果你的文件名是HelloWDM.c的话,这句可以省略
extern "C"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
					 IN PUNICODE_STRING RegistryPath)
{
	DbgPrint("DriverEntry Loading...\n");

	//指定“添加设备”消息由函数“HelloWDMAddDevice()”来处理:
	DriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;

	//指定“即插即用”消息由函数“HelloWDMPnp()”来处理:
	DriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;

	//返回一个NTSTATUS值STATUS_SUCCESS。几乎所有的驱动程序例程都必须返回一个NTSTATUS值,
	//这些值在NTSTATUS.H DDK头文件中有详细的定义。
	return STATUS_SUCCESS;
}

/***************************************************************
函数名称:HelloWDMAddDevice()
功能描述:处理“添加设备”消息
***************************************************************/
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
						   IN PDEVICE_OBJECT PhysicalDeviceObject)
{
	NTSTATUS status;
	//定义一个功能设备对象
	PDEVICE_OBJECT fdo;
	//创建我们的功能设备对象,并储存到fdo中
	status = IoCreateDevice(DriverObject,	//驱动程序对象
		sizeof(DEVICE_EXTENSION),			//要求的设备扩展的大小
		NULL,								//设备名称,这里为NULL
		FILE_DEVICE_UNKNOWN,				//设备的类型,在标准头文件WDM.h或NTDDK.h中列出的FILE_DEVICE_XXX值之一
		0,									//各种常量用OR组合在一起,指示可删除介质、只读等。
		FALSE,								//如果一次只有一个线程可以访问该设备,为TRUE,否则为FALSE
		&fdo								//返回的设备对象
		);
	//NT_SUCCESS宏用于测试IoCreateDevice内核是否成功完成。
	//不要忘记检查对内核的所有调用是否成功。NT_ERROR宏不等
	//同于!NT_SUCCESS,最好使用!NT_SUCCESS,因为除了错误外,它还截获警告信息。
	if (!NT_SUCCESS(status))
	{
		return status;
	}
	//创建一个设备扩展对象dx,用于存储指向fdo的指针;
	PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
	dx->fdo = fdo;
	
	//用IoAttachDeviceToDeviceStack函数把HelloWDM设备挂接到设备栈:
	dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);

	//设置fdo的flags。有两个“位”是必须改变的,一个是必须清除DO_DEVICE_INITIALIZING标志,
	//如果在DriverEntry例程中调用IoCreateDevice(),就不需要清除这个标志位。还有一个是必须
	//设置DO_BUFFER_IO标志位:
	fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
	fdo->Flags &= ~DO_DEVICE_INITIALIZING;
	
	return STATUS_SUCCESS;
}

/***************************************************************
函数名称:HelloWDMPnp()
功能描述:处理“即插即用”消息
***************************************************************/
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
					 IN PIRP Irp)
{
	//创建一个设备扩展对象dx,用于存储指向fdo的指针:
	PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
	
	//首先要通过函数IoGetCurrentIrpStackLocation()得到当前的IRP,并由此得到Minor Function:
	PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
	ULONG MinorFunction = IrpStack->MinorFunction;

	//然后把这个Minor Function传递给下一个设备栈:
	IoSkipCurrentIrpStackLocation(Irp);
	NTSTATUS status = IoCallDriver(dx->NextStackDevice, Irp);

	// add by kevin [1/7/2009]
	// 这个地方应该对返回的status处理
	// add by kevin [1/7/2009]

	////处理“即插即用”次功能代码:
    //当Minor Function等于IRP_MN_REMOVE_DEVICE时,说明有设备被拔出或卸下,这时要取消资源分配并删除设备:
	if (MinorFunction == IRP_MN_REMOVE_DEVICE)
	{
		//取消设备接口:
		IoSetDeviceInterfaceState(&dx->ifSymLinkName, FALSE);
		RtlFreeUnicodeString(&dx->ifSymLinkName);
		
		//调用IoDetachDevice()把fdo从设备栈中脱开:
		if (dx->NextStackDevice)
		{
			IoDetachDevice(dx->NextStackDevice);
		}

		//删除fdo:
		IoDeleteDevice(fdo);
	}
	return status;
}

⌨️ 快捷键说明

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