NT驱动程序和WDM驱动程序
NT驱动程序是最基本的内核驱动程序,WDM驱动程序由NT封装而来。
NT驱动程序
Windows内核驱动开发中,NT驱动程序是最基础的类型。所谓NT驱动,指的是遵循Windows NT内核模型的驱动程序,它们是操作系统与硬件设备之间的桥梁。
基本概念
NT驱动程序运行在内核模式,权限最高,可以直接访问硬件和系统内存。它们被组织成.sys文件,由I/O管理器加载和管理。每个NT驱动本质上是一个动态链接库,有标准的入口点和回调函数。
驱动加载后,会创建一个驱动对象,代表驱动本身。通过这个驱动对象,可以创建一个或多个设备对象,每个设备对象对应一个用户可以访问的逻辑设备。
驱动结构
典型的NT驱动包含几个核心部分。首先是DriverEntry函数,这是驱动的入口点,相当于main函数。在这里,驱动进行初始化,创建设备对象,设置分发函数。
分发函数是驱动的核心逻辑。当用户程序调用DeviceIoControl、ReadFile、WriteFile等API时,I/O管理器会把请求转化为IRP(I/O请求包),然后调用相应的分发函数处理。
驱动的卸载函数也很重要。当驱动被卸载时,这个函数负责释放所有资源,删除设备对象,确保系统稳定。
通信机制
用户程序与驱动通信主要通过几种方式。最常用的是DeviceIoControl,通过控制码传递自定义命令和数据。ReadFile和WriteFile用于简单的读写操作,适合文件式接口。
驱动也可以主动通知用户程序,通过异步I/O完成、事件、APC等机制。比如设备状态变化时,驱动可以通知等待的用户程序。
设备栈
Windows的设备管理基于栈模型。一个I/O请求从上层设备对象传递到底层,每个设备对象有机会处理请求。这允许多个驱动协同工作,比如功能驱动上面加过滤驱动。
即插即用驱动是NT驱动的扩展。它们支持设备的热插拔,能响应系统发出的PNP IRP,动态加载和卸载。
WDM驱动程序
对于WDM驱动程序来说,一般都是基于分层的。也就是说,完成一个设备的操作,至少要由两个驱动设备共同完成。
在WDM模型中,完成一个设备的操作,至少有两个设备对象共同完成。其中,一个是物理设备对象(Physical Device Object,以下简称PDO),另一个是功能设备对象(Function Device Object,以下简称FDO)。其关系是"附加"与"被附加"的关系。

当有新的设备插入PC时,总线驱动程序就会自动创建一个PDO对象,PDO不能单独操作设备,需要配合FDO一起使用。系统会提示检测到新设备。需要安装的驱动程序指的就是WDM程序,此驱动程序负责创建FDO,并且附加到PDO之上。
如何将FDO设备附加到PDO对象上呢?答案是通过IoAttachDeviceToDeviceStack函数实现。
有时候,PDO和FDO之间还会存在过滤驱动。在FDO上面的过滤驱动被称作上层过滤驱动。在FDO的下层的驱动,被称作下层过滤驱动。每个设备对象中,有个StackSize子域,表明操作这个设备对象需要几层才能到达最下层的物理设备。
