IRP 的创建
来源:互联网 发布:淘宝卖家怎么截图上新 编辑:程序博客网 时间:2024/05/24 06:34
1. 有四种方法来创建IRP
Ø IoBuildAsynchronousFsdRequest
创建异步IRP,不需要等待其完成;
Ø IoBuildSynchronousFsdRequest
创建同步IRP, 需要等待其完成,这种方法和上面的只能创建某些特定类型IRP
Ø IoBuildDeviceIoCtontrolRequest
创建一个类型为 IRP_MJ_DEVICE_CONTROL 或者
IRP_MJ_DEVICE_CONTROL 的同步IRP.
Ø IoAllocateIrp
创建任何类型的异步IRP
2. 创建同步IRP
I/O管理器认为新创建的IRP是属于创建IRP时所处的那个线程,这样,如果这个线程结束了,I/O管理器会自动取消属于它的还处在PENDING状态的IRP.所以,不要在任意上下文状态创建一个IRP,否则,IRP可能被意外的取消了。创建同步IRP时,需要用户提供一个事件对象,要保证在I/O管理器设置该事件对象的信号时,该事件对象还在内存中。只能在PASSIVE_LEVEL 上调用创建同步IRP的函数,因为当IRP完成时,系统派遣一个APC来置位提供的那个事件,以下的code有问题:
PIRP irp = IoBuildSynchronousFsdRequest(...);
ExAcquireFastMutex(...);
NTSTATUS status = IoCallDriver(...);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(...);
}
ExReleaseFastMutex(...);
红色部分会导致死锁,当IRP被完成时,IoCompleteRequest会派遣一个该线程的APC,这个APC会设置用户等待的事件,但是由于开始调用了ExAcquireFastMutex,从而使得该段code处在APC_LEVEL上,这样APC就没法执行了。
有三种方案解决这个问题:
Ø 使用常规互斥对象代替快速互斥对象;
Ø 使用KeEnterCriticalRegion,它不会阻止APC的运行,然后使用ExAcquireFastMutexUnsafe 来获得互斥对象
Ø 创建异步IRP来代替
3.创建异步IRP
可以在非任意上下文和任意上下文中创建异步IRP, 需要提供一个完成回调例程做IRP
的清理工作和调用IoFreeIrp.可以在IRQL <= DISPATCH_LEVEL 的级别来创建
4 派遣IRP
创建完IRP后,使用IoGetNextIrpStackLocation函数来获得第一个堆栈单元的指针,然后初始化这个IRP。
5. 不要以STATUS_PENDING 的状态完成一个IRP, 调用 IoCompleteRequest之前要保证IRP的取消例程为空。把IRP向下层驱动传递的时候,也要保证IRP的取消例程为空。
- IRP 的创建
- IRP的创建
- IRP的创建
- 创建IRP的相关内容
- 创建IRP的四种不同方式
- 创建IRP的四种不同方式
- 创建IRP_MJ_WRITE IRP参数的困惑
- 用IoAllocateIrp创建IRP
- 创建 IRP 给底层驱动
- 对IRP的理解
- 对IRP的理解
- IRP的完成例程
- IRP的同步
- IRP 的结构
- 驱动程序的取消IRP
- 驱动程序的取消IRP
- IRP的同步问题
- IRP的同步
- 说说MP3 (三)
- 网格中合并(Merge)功能的多种技术方案
- 大学最值钱的东西...
- 灰度差分统计分类效果
- 说说MP3 (四)
- IRP 的创建
- 中国程序员的汽车梦
- 转帖:三个关键命令找出ASP.NET程序内存分片的原因
- 在VC++中生成伪随机数祥解(转帖)
- sql server行转列
- 说说MP3 (五)
- 在JAVA应用按钮实现超链接......
- 柑橘溃疡病实验的下一步安排
- 说说MP3 (六)