wdm设备驱动程序入门
设备对象与设备驱动程序关系
每个功能设备对应一个设备对象(设备对象栈为设备对象内部属性), 相同型号的多个功能设备对应多个设备对象。每个设备对象具有不同的私 有属性值(如设备ID)。
相同型号的多个功能设备共用一个过滤驱动程序和功能驱动程序,
即只有一个驱动程序对象。
设备驱动程序与设备关系:
同类中成员函数与类实例关系。
显示驱动程序是用于显示和打印设备的内核模式驱动程 序。 文件系统驱动程序在本地磁盘或网络上实现标准PC文件 系统模型(含多层次目录结构和命名文件概念)。 保留设备驱动程序主要包括Windows NT早期版本的驱动 程序,它直接控制一个硬设备而不用其他驱动程序帮助 ,可以不做修改地在Windows 2000中运行。
驱动程序的AddDevice函数示例:
NTSTATUS AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo) { NTSTATUS status; PDEVICE_OBJECT fdo; status=IoCreateDevice(DriveObject, sizeof(WDM_DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo); //在fdo中产生我们的功能设备对象 if (NT_ERROR(status)) return status; ……}
PnP管理器根据需要给设备发送各种PnP IRP
PnP管理器给设备发送“启动设备”PnP IRP,驱动程序将分 配的资源信息向下传送到设备配置头区域中,并启动设备
驱动程序处于等待状态,等待IRP的到来
WDM驱动程序的结构
WDM驱动程序包含许多例程,操作系统调用这些例程来执
行对IRP的各种操作。
基本驱动程序例程 I/O控制例程 StartIO AdapterControl OnInterrupt DpcForIsr StartIO处理请求队列、 AdapterControl处理DMA 操作、OnInterrupt处理中断。 分发例程
已装 入?
执行DriverEntry(),设置各例程 入口地址,将对象指针装入I/O 管理器中
PnP管理器装入最底层过滤驱动程序,调用其 AddDevice函数,该函数创建一个FiDO,实现FiDO与 同级驱动程序的连接
AddDevice函数把PDO连接到FiDO上
PnP管理器依次装入各级驱动程序,完成整个设备对象栈
IRP的设置与派遣:
I/O管理器在创建完IRP后,将I/O请求信息设置到IRP中, 并将IRP发送到设备驱动程序中。 已知参数信息: PDEVICE_OBJECT DeviceObject; //设备对象结构 IRP_MJ_Xxx; //I/O请求对应的功能码 I/O管理器的处理流程: PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp); //获得该IRP第一个堆栈单元的指针(堆栈初始为空) stack->MajorFunction = IRP_MJ_Xxx; //填充MajorFunction代码 …… //对栈做其他初始化的工作 //如StartIo() NTSTATUS status = IoCallDriver(DeviceObject,Irp); //把IRP发送到设备驱动程序
驱动程序处理:每层驱动程序都可决定如何处理IRP,既可直接处理 完该IRP就不再向下传,也可处理完后继续向下传递,还可只做向下 传递工作。下层处理完的返回信息又通过该包的结构逐层向上传递。
系统重启
硬件接入
添加新设备 指定 检测 安装向导指定新的硬件类 型
总线驱动程序检测到新的 硬件
取配置头区域信息 由指定得到信息 取得厂商、设备类型、版本、资源需求等信息
文件系统 驱动程序
保留设备 驱动程序
PnP 驱动程序 WDM驱动程序
显示 驱动程序
类驱动程序
小驱动程序
Windows2000/XP设备驱动程序的种类
虚拟设备驱动程序(Virtual Device Driver,VDD)可 使DOS应用程序访问x86平台上的硬件,也可支持 Windows 9x下的对端口访问。 WDM驱动程序 是一种遵循电源管理协议并能在Win98 和Win2000上实现源代码级兼容的PnP驱动程序。WDM 驱动程序又可分为类驱动程序(管理已定义类的设备) 和小驱动程序(提供厂商专有的支持)。
Windows2000/XP设备驱动程序设计
Windows 2000/XP的设备驱动程序
什么是驱动程序 OS patch 学习Windows驱动程序的难点 技术壁垒,资料少 内核编程 user-api-内核
Windows 2000/XP的设备驱动程序
虚拟设备 驱动程序(VDD) 内核模式 驱动程序
;
I/O请求包(IRP)
定义:I/O请求包(IRP)是驱动程序操作的中心,它是一个内核“对象”, 是预先定义的数据结构。 应用:I/O管理器通过IRP对设备对象进行操作。 I/O管理器接收到一个I/O请求后,分配并初始化一个IRP,再把它传递 到合适的设备驱动程序中的最高驱动程序中。 设备对象属性为设备驱动程序处理的数据。
Parameters成员的几个常见的类型:
IRP_MJ_CREATE请求,创建设备映射; IRP_MJ_CLOSE请求,关闭设备映射; IRP_MJ_READ请求,读取设备对象的信息; IRP_MJ_WRITE请求,对设备对象写信息; IRP_MJ_PNP请求,实现PnP管理,如 IRP_MN_START_DEVICE请求,启动设备; IRP_MJ_IOCTL请求,I/O控制。
2、IRP创建与处理
创建者:I/O管理器,或其他的驱动程序。
创建IRP的函数: IoBuildAsynchronousFsdRequest();//创建异步IRP IoBuildSynchronousFsdRequest();//创建同步IRP IoBuildDeviceIoControlRequest(); //创建同步IRP_MJ_DEVICE_CONTROL或 // IRP_MJ_INTERNAL_DEVICE_CONTROL 请求 IoAllocateIrp();//创建其他种类IRP IoMakeAssociatedIrp();//创建某些IRP的子IRP
1.IRP组成
由一个固定的首部和一个可变数目的I/O栈组成。
IRP首部组成
IRP中的I/O栈组成
I/O栈:通过IO_STACK_LOCATION结构数组实现。 一次I/O请求可能对应多个I/O操作 实现方法: 较多个IRP实现; 一个IRP实现+I/O栈实现。(较优)
IO_STACK_LOCATION结构成员: MajorFunction(该IRP的主功能码) MinorFunction(该IRP的副功能码) Parameters(IRP参数) DeviceObject(与该栈单元对应的设备对象地址) FileObject(内核文件对象地址) CompletionRoutine(I/O完成程序地址) Context(任意的与上下文相关的值)。
WDM的基本结构
1、设备对象
设备对象:系统为帮助软件管理硬件而创建的一个数据 结构(包括 PDO、FDO、FiDO)。 PDO(物理设备对象):设备对象中的物理型对象。 FDO(功能设备对象):设备对象中的功能型对象。 FiDO(过滤器设备对象):在I/O管理器、FDO和PDO间的监视、修改 IRP流的过滤型对象,分上层过滤和下层过滤对象。
驱动程序的DriverEntry函数示例:
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { // 初始化例程的入口地址 DriverObject->DriverUnload = DriverUnload; DriverObject->DriverExtension->AddDevice = AddDevice; DriverObject->DriverStartIo = StartIo; DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER]= DispatchPower; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DispatchWmi; …… // 这里可加入其他MajorFunction处理例程的入口地址
驱动程序的IRP派遣函数示例:
NTSTATUS DispatchXxx(PDEVICE_OBJECT device, PIRP Irp) { PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获得栈单元指针 PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)device->DeviceExtension //获得设备扩展 …… //其他IRP处理操作 return STATUS_Xxx; //返回状态码 }
DriverEntry
AddDevice
DispatchPnp DispatchPower
DispatchWmi DispatchRead DispatchWrite
WDM驱动程序包含例程
• DriverEntry例程:这个例程是每一个设备驱动程序的入口。完成 某些全局初始化(如将驱动程序对象指针装入到I/O管理器中)工 作,设置响应各种用户请求的分发例程与I/O控制例程的入口。 • AddDevice例程:对于功能驱动程序,其AddDevice函数的基本职责 是创建一个设备对象并把它连接到以PDO为底的设备堆栈中。 • DispatchPnp例程:用于处理IRP_MJ_PNP消息,以便能实现即插即 用的功能。 • DispatchPower例程:用于实现对电源管理的支持。 • DispatchWmi例程:WMI是微软实现的基于Web的企业管理工业标准 ,该例程用于处理有关的消息。