学习windows驱动(队列)

来源:互联网 发布:米开朗基罗传 知乎 编辑:程序博客网 时间:2024/06/06 08:57

WDF驱动里的队列类型种类有如下定义:

typedef enum _WDF_IO_QUEUE_DISPATCH_TYPE {    WdfIoQueueDispatchInvalid = 0,    WdfIoQueueDispatchSequential,    WdfIoQueueDispatchParallel,    WdfIoQueueDispatchManual,    WdfIoQueueDispatchMax,} WDF_IO_QUEUE_DISPATCH_TYPE;

在上面枚举类型里,WdfIoQueueDispatchInvalid和WdfIoQueueDispatchMax是无效的,其他的是有效的。
WdfIoQueueDispatchSequential是串行队列,队列里的IO请求是挨个处理的,串行队列实现了序列化。

WdfIoQueueDispatchParallel是并行队列,IO请求入队后,只要有可能就会以最快的速度被处理,不需要等待前面的对象处理完。

WdfIoQueueDispatchManual是手动队列,IO请求入队后,框架就不管它了,WDF驱动在需要时,自己从队列里提取IO请求并处理。

WDF的一个主要特点是把所有东西封装成一个对象,把所有操作定义成一个事件(Event)或回调(Callback)。WDF对每个框架对象维护一个引用计数,能有效地控制对象的生命周期。

WDF的一个优点是把I/O进行了封装,使程序员不需要直接面对IRP,只管处理WDFREQUEST对象即可。处理也变得异常简单。I/O对象不再是设备对象,而是一个新的I/O target对象。I/O target对象比DEVICE_OBJECT使用更广,它不仅可以代表设备,也可以代表驱动、队列等。队列对象是一个全新事务,WDM编程里涉及队列的地方不多,但WDF却让它成为不可避免的部件。队列是专门用来管理WDFREQUEST对象的,因为WDFREQUEST对象是对IRP的封装,所以队列归根到底是对IRP的管理。队列允许WDFREQUEST对象以3种方式发送给驱动处理:并行、串行和手动。由于对IRP的管理、使用失策而导致的驱动问题,是WDM程序的一大难点。现在队列的引入,让IRP从野马变成驯良的坐骑。

假设一个用户线程X用同步方式向内核发送一个命令,内核框架收到命令后,判断出命令归于队列1。这个时候队列1里已经有3个排队命令。

每个设备对象都有一个默认队列,一般为了将效率最大化,把默认队列设置为并行队列。只把部分需要特别处理保证安全的对象放到串行队列。把特殊请求放到手动队列里,这些请求往往是为了等待某个条件被满足以达到同步的目的,或等待所需的数据到来,如从USB的中断端口读取数据。

队列间可以互相交流。在很多情况下要用到队列转移,比如IRP_MJ_DEVICE_IO_CONTROL类型请求,一般都是并行处理,但控制信号CTL_CODE是IOCTL_REQUEST_1的DEVICE_IO_CONTRO请求却必须被串行处理;这时可以把IRP_MJ_DEVICE_IO_CONTROL请求请求设置为在并行队列里排队,这样绝大部分的控制请求都被并行处理,当并行队列的处理函数遇到控制码为IOCTL_REQUEST_1时,放弃处理,重新将它送到串行队列里排队等待。

0 0