武安河另外讲WDM的书是《windows 2000/xp wdm设备驱动开发》
KDMF 构建在WDM之上,内核级,sys文件
UDMF 用户级,dll文件
第1章 Windows 2000和WDM驱动程序
1.中断优先级(IRQL): 32个中断级别,可打断
0 : PASSIVE_LEVEL, 常规线程
1:APC_LEVEL, 异步调用过程
2:DISPATCH_LEVEL, 延迟过程调用
3~26: DIRQL, 硬件中断
2. 在DISPATCH_LEVEL 运行代码时,访问非分页内存是一个根本原则
第2章 KMDF驱动程序框架
1. 环境变量结构
_DEVICE_CONTEXT{}
pDeviceContext = GetDeviceContext(Device);
2. 创建对象的方法
KMDF控制的对象生命周期:WDFDRIVER, WDFDEVICE, WDFFILEOBJECT, WDFREQUEST (IRP)
3. KMDF结构
1)DriverEntry:设置 EvtDeviceAdd (安装时调),WdfDriverCreate 创建驱动对象
2) EvtDriverDeviceAdd: 新设备被枚举时会调用,
职责:创建设备对象,I/O队列,GUID接口,事件回调例程,
WdfDeviceCreate, WdfDeviceCreateDeviceInterface,
WdfDeviceInitSetExclusive(DeviceInit,TRUE); // 独占,只允许一个应用打开
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchSequential); // IO为串行
WdfIoQueueCreate // io队列
WdfDeviceCreateDeviceInterface // guid接口
3)I/O处理例程
WDF_FILEOBJECT_CONFIG_INIT(&FileConfig,EvtDeviceFileCreate, EvtFileClose, EvtFileCleanup);
ioQueueConfig.EvtIoDeviceControl = PCI9056WDF_EvtIoDeviceControl; // DeviceIoControl 调用
ioQueueConfig.EvtIoRead = PCI9056WDF_EvtIoRead; // ReadFile
ioQueueConfig.EvtIoWrite = PCI9056WDF_EvtIoWrite; // WriteFile
第3章 基本对象
1. WDFREQUEST: I/O请求,即IRP
WdfRequestComplete : 完成请求
WdfRequestCompleteWithInformation : 完成请求, 完成的传输字节数
WdfRequestRetrieveInputBuffer: 获取输入缓冲器地址
WdfRequestRetrieveInputMemory: 获取输入缓冲器地址,形式为WDFMEMORY
WdfRequestRetrieveInputWdmMdl: 获取输入缓冲器地址,形式为MDL
WdfRequestGetIoQueue: 返回队列对象
WdfRequestGetFileObject: 返回文件对象
WdfRequestGetInformation: 完成的传输字节数
WdfRequestCreate: 创建IO请求
2. IO请求(IRP)基本操作
取消IO请求:编写取消例程
向下传递IO请求
3. WDFQUEUE 队列, WdfIoQueueDispatchSequential 串行
初始化默认队列 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE
WdfIoQueueCreate
WdfIoQueueStart : 启动接收和分发IRP
WdfIoQueueStop: 暂停分发,但还接收
WdfIoQueueDrain: 停止接收,但分发
WdfIoQueuePurge: 停止接收,取消队列中的IRP
4. WDFTIMER, WDFDPC, WDFWORKITEM, WDFMEMORY
5. 数据同步
1)自旋锁运行在DISPATCH_LEVEL(自动提升),因此不能访问分页内存
WdfSpinLockCreate, WdfSpinLockAcquire, WdfSpinLockRelease
2)WDFWAITLOCK 运行在PASSIVE_LEVEL, 同步锁
WdfWaitLockCreate, WdfWaitLockAcquire, WdfWaitLockRelease
6. 字符串
CHAR, WCHAR, STRING, UNICODE_STRING
WDFSTRING: WdfStringCreate
串处理函数:strlen之类
7. 队列编程 QueueSample
// 因为取消例程等要用环境变量, 所以用一个设备对象范围同步(重要)
deviceAttr.SynchronizationScope = WdfSynchronizationScopeDevice;
调用例程,取消例程,定时器回调例程,都用了设备对象范围同步,所以运行在DISPATCH_LEVEL, 不能用分页内存。不然要蓝屏