WDM驱动程序

来源:互联网 发布:mac pro 抹掉磁盘 编辑:程序博客网 时间:2024/05/18 14:11

先说下关于WDM驱动程序一些原理。Windows2000后,微软加入了新的驱动程序模型,就是WDM。在WDM中,完成一个设备的操作,至少有两个设备共同完成。其中,一个是物理设备对象PDO,另一个是功能设备对象FDO。两者的关系是"附加"和"被附加"的关系。当PC插入某个设备时,总线驱动程序创建PDO,而设备的驱动程序创建FDO,并附加到PDO上。当FDO附加到PDO上时,PDO设备对象的子域AttachedDevice会记录FDO的位置,而FDO可以通过定义设备扩展来记录FDO下层设备,如PDO。在FDO和PDO之间还会存在过滤驱动,在FDO上的过滤驱动被称为上层过滤驱动High FiDO,而在FDO的下层过滤驱动则称为下层过滤驱动Low FiDO。下面是一个基本的WDM驱动程序结构:

 

#include "HelloWDM.h"

#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
        IN PUNICODE_STRING pRegistryPath)
{
  pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;
 pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;
 pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
 pDriverObject->MajorFunction[IRP_MJ_CREATE] =
 pDriverObject->MajorFunction[IRP_MJ_READ] =
 pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;
 pDriverObject->DriverUnload = HelloWDMUnload;

 
 return STATUS_SUCCESS;
}

 

#pragma PAGEDCODE
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject)
{

......

}

 

#pragma PAGEDCODE
NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)
{

......

}

 

#pragma PAGEDCODE
NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{

......

}

 

#pragma PAGEDCODE
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
                        IN PIRP Irp)
{

......

}

 

#pragma PAGEDCODE
NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,
         IN PIRP Irp)
{

......

}

 

#pragma PAGEDCODE
void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject)
{

......

}

 

 

简单解释下:和NT式驱动程序一样,WDM的入口函数也是DriverEntry,但是程序的初始化工作放到了AddDevice例程中,这是和NT式驱动程序不同的地方。同时,在DriverEntry中,需要设置对IRP_MJ_PNP处理的派遣函数。设置AddDevice的方式是驱动对象中有个DriverExtension子域,DriverExtension中有个AddDevice子域,该子域指向AddDevice例程的函数地址。AddDevice函数有两个输入参数,一个是驱动对象DriverObject,另一个是设备对象的PhysicalDeviceObject,驱动对象是I/O管理器创建的驱动对象,设备对象是总线驱动创建的PDO。AddDevice函数分为下面几个步骤:

1、通过IoCreateDevice等函数,创建设备对象,即FDO。

2、创建完FDO后,在设备扩展中可以将FDO的地址保存下来。

3、驱动程序将创建的FDO附加到PDO上,附加的动作依靠IoAttachDeviceToDeviceStack函数实现的。

4、设置fdo的Flags子域。

在WDM驱动中,删除设备和取消符号链接被IRP_MN_REMOVE_DEVICE IRP函数HandleRemoveDevice所负责,这个例程在HelloWDMPnp函数中设置。