学习驱动开发也有大半年时间了,刚好国庆也过完了,今天逛了下csdn博客,发现自己好久没写博客了,一时兴起想写点什么关于驱动的,因为我刚学驱动开发时对一些概念不清楚,可能是文档没讲清楚或是我理解错了,我觉得有必要把我自己理解的讲出来。这里我以文件过滤驱动为例。
(我认为大家都看过楚狂人的驱动编程基础文档,有一定的基础,这里只为加深理解,如有分析错误的或不明白的地方,请在回复中指出)。
先来了解下驱动对象和设备对象
驱动对象(DRIVER_OBJECT)
驱动对象和驱动程序唯一对应,IO管理器使用它来管理驱动程序,这个在系统加载该驱动程序时分配。
它拥 有一组分发函数指针,并管理该驱动创建的所有设备对象。(它使用DeviceObject域指向一个设
备对象链表,这里要和设备栈区别)
设备对象(DEVICE_OBJECT)主要有CDO(控制设备对象)、FDO(功能设备对象)、PDO(物理设备对象)。
控制设备对象:主要处理一些控制请求,过滤驱动一般用它和应用层通信。
物理设备对象:比如文件系统卷,理论上一个分区对应一个系统卷,文件系统会为其创建卷设备对象,
这样的卷设备对象就属于物理设备对象,它位于设备栈最底层。
功能设备对象:要了解功能设备对象,必须先知道设备栈。这个先看下面的设备栈解释。
设备栈(DEVICE STACK)
一组有关联的设备对象,任何来自应用程序的请求,都被IO管理器解释为IRP,并发送到设备栈顶端的那个设备对象上。
IRP从设备栈的顶端开始,逐步往下发送。 我 们只要在这个设备栈顶端绑定一个设备对象,那么发送给底层Volume的
请求,就会先发送到我们这个设备上。要理解这段话的含义,举个文件过滤驱动的例子,要拦截对磁盘C的所有文件操
作,比如有3个驱动程序,驱动A生成一个卷过滤设备绑定到卷1(对应磁盘C)上,驱 动B和驱动C同样生成一个卷过滤
设备绑定到卷1上,绑定的先后顺序是A->B->C , 那么形成的设备栈是过滤设备C在最上层,其次是B和A,最后是文件系
统卷设备对象 ,发往文件系统卷设备对象的irp会依次给驱动C、驱动B、驱动A,这样生成的过滤设备对象称为功能设备
对象,只为实现过滤功能。
IRP处理
irp的处理建议直接看微软的文档Handling IRPS:What Every Drivers Writer Need to Know,里面对于同步异步irp处理
讲解的非常详细。
内存分配
驱动里面的内存非常宝贵,分配时尽量节约。大体和应用层一样,局部变量存放于栈区,需要从堆上分配的(一般申请大
小较栈上大)可以使用以下函数:ExAllocatePool、ExAllocatePoolWithTag、ExAllocatePoolWithQuota和
ExAllocatePoolWithQuotaTag。四个函数功能都是一样,WithQuota是按配额分配。第一参数都是分配内存类型,
即分页还是非分页。非分页内存是不允许发生页错误的,一般在高中断级函数中使用。另外函数多个tag是可以调试时
根据标签查看内存是否释放。释放函数是ExFreePool和ExFreePoolWithTag。驱动里面还有一种高效的内存申请方
式,即Lookaside旁视链表,一般用于固定大小的内存申请并且申请释放较频繁,类似于固定内存池。初始化使用
ExInitializeLookasideListEx,申请释放使用ExAllocateFromLookasideListEx、
ExFreeToLookasideListEx、
回收则用ExDeleteLookasideListEx。
好了就说这些了。