您的位置:首页 > 其它

驱动杂记1:对驱动对象,设备对象,设备栈的理解

2012-04-16 18:18 162 查看
Windows内核采用的是面向对象的编程方式,但使用的确是C语言。Windows内核认为许多东西都是“对象”,

比如一个驱动一个文件一个设备,“对象”相当于一个基类。

一个驱动对象代表了一个驱动程序,或者说一个内核模块。驱动对象结构如下:

typedef struct _DRIVER_OBJECT{

//结构的类型和大小

CSHORT Type;

CSHORT Size;

......

//设备对象,该驱动创建的设备对象链表的开始

PDEVICE_OBJECT DeviceObject;

......

//该内核模块在内核空间中的开始地址和大小

PVOID DriverStart;

ULONG DriverSize;

......

//驱动的名字

UNICODE_STRING DriverName;

......

//FastIO例程

PFAST_IO_DISPATCH FastIoDispath;

......

//StartIO例程

PDRIVER_STARTIO DriverStartIo;

......

//卸载例程

PDRIVER_UNLOAD DriverUnload;

......

//普通分发函数,派遣例程

PDRIVER_DISPATH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1];

}DRIVER_OBJECT;

在驱动对象中我们可以看到其中有一个设备对象成员

PDEVICE_OBJECT DeviceObject 它指向一个设备对象链表的第一个对象,因为每个驱动对象可以创建若干个设备对象,

这些设备对象正是用链表形式链接起来(最后一个设备对象指向NULL)。设备对象即DEVICE_OBJECT ,简称DO。

在内核中,信息主要以IRP(I/O请求包)方式传递,而设备对象是唯一可以接受请求的实体。

那么说到这里我们再来看看设备对象这个数据结构。

typedef struct _DEVICE_OBJECT{

......

//该设备对象所属的驱动对象

struct _DRIVER_OBJECT *DriverObject;

//水平层次上的下一个设备对象,即和该设备对象同属一个驱动对象

struct _DEVICE_OBJECT *NextDevice;

//垂直层次的上一个设备对象,和该设备对象不属于同一个驱动对象

struct _DEVICE_OBJECT *AttachedDevice;

//使用StartIO例程的时时候,此域指向的是当前IRP结构

struct _IRP *CurrentIrp;

ULONG Flags;

//设备扩展对象,又程序员自己定义的结构体记录一些设备信息,

//为避免使用全局变量,可以将全局变量存在设备扩展里面

struct _DEVOBJ_EXTENSION *DeviceObjectExtension;

}DEVICE_OBJECT;

从驱动对象和设备对象的结构定义来看,设备对象通过struct _DEVICE_OBJECT *NextDevice;

这个域将该驱动中的设备对象链接起来。

驱动对象可以找到它创建的设备链表头,而设备对象可以找到它所属的驱动对象。

我们看到设备对象中有一个struct _DEVICE_OBJECT *AttachedDevice成员,它是跟设备栈相关联的。

设备的创建顺序是,先创建底层PDO(物理设备对象),再创建FDO(功能设备对象),PDO和FDO之间可能还有一些过滤驱动

(称为FiDO Filter Device Object)。

每一层设备对象由不同的驱动对象创建,这些驱动对象共同完成一个物理设备的驱动任务。

这由下而上生长的设备便形成了设备栈。*AttachedDevice就指向上一层的设备对象,如果为NULL表示已经是最顶层。

从底层向高层可以通过*AttachedDevice来寻找,从高层到底层,设备对象没有提供相关子域。这里就可以通过设备扩展

这个成员来自定义,在_DEVOBJ_EXTENSION 结构中定义一个指向低一层设备的域。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: