50、Windows驱动程序模型设计笔记(八),IRP

简介: 3、派遣例程的职责 •派遣函数立即完成该IRP。 •把该IRP传递到处于同一堆栈的下层驱动程序。 •排队该IRP以便由这个驱动程序中的其它例程来处理。     每个设备对象都自带一个请求队列对象,下面是使用这个队列的标准方法: NTSTATUS DispatchXxx(...) { ... IoMarkIrpPending(Irp); IoStartPacket(device, Irp, NULL, NULL); return STATUS_PENDING; } 一旦我们调用了IoStartPacket函数,就不要再碰IRP。

3、派遣例程的职责<?xml:namespace prefix = o />

•派遣函数立即完成该IRP。

•把该IRP传递到处于同一堆栈的下层驱动程序。

•排队该IRP以便由这个驱动程序中的其它例程来处理。

    每个设备对象都自带一个请求队列对象,下面是使用这个队列的标准方法:

NTSTATUS DispatchXxx(...)

{

...

IoMarkIrpPending(Irp);

IoStartPacket(device, Irp, NULL, NULL);

return STATUS_PENDING;

}

一旦我们调用了IoStartPacket函数,就不要再碰IRP。因为在该函数返回之前,IRP可能已经被完成并且其占用的内存可能被释放,而我们拥有的该IRP的指针也许是无效的

4、StartIo例程

每处理一个IRP,I/O管理器就调用一次StartIo例程。StartIo的工作是就着手处理IRP。

5、中断服务例程

用IoConnectInterrupt函数“钩住”一个中断,该函数的一个参数就是ISR的地址。一个ISR最可能做的事就是调度DPC例程(推迟过程调用)。而DPC的目的就是让你做某些事情,如调用IoCompleteRequest。

. IoCompleteRequest的优先级推进值

推进值常量

优先级推进值

IO_NO_INCREMENT

0

IO_CD_ROM_INCREMENT

1

IO_DISK_INCREMENT

1

IO_KEYBOARD_INCREMENT

6

IO_MAILSLOT_INCREMENT

2

IO_MOUSE_INCREMENT

6

IO_NAMED_PIPE_INCREMENT

2

IO_NETWORK_INCREMENT

2

IO_PARALLEL_INCREMENT

1

IO_SERIAL_INCREMENT

2

IO_SOUND_INCREMENT

8

IO_VIDEO_INCREMENT

1

    不要以专用状态代码STATUS_PENDING来完成一个IRP。派遣例程经常要使用STATUS_PENDING代码作为返回值,但你决不能在IoStatus.Status中设置这个值。

6、完成例程

    IoSetCompletionRoutine将把完成例程地址和上下文参数安装到下一个IO_STACK_LOCATION中,即下一层驱动程序将在那个堆栈单元中找到这些参数。因此,最底层的驱动程序不应该安装一个完成例程。

    完成例程通常在DISPATCH_LEVEL级和任意线程上下文中被调用,但有时也在PASSIVE_LEVEL或APC_LEVEL级被调用。为了适应大多数情况(DISPATCH_LEVEL),完成例程应存在于非分页内存中,并且仅使用可在DISPATCH_LEVEL级上调用的服务例程。然而,为了适应在低级IRQL上调用该例程的可能情况,完成例程不应调用像KeAcquireSpinLockAtDpcLevel这样的函数,因为这些函数假定开始执行于DISPATCH_LEVEL级上。

    在完成例程内部,一个IoGetCurrentIrpStackLocation调用将获得上一层堆栈单元的指针。上层堆栈单元的完成例程不应该依赖任何下层堆栈单元中的内容。为了加强这个规则,IoCompleteRequest在调用完成例程前清除了下一个堆栈单元中的大部分内容。

wps_clip_image-27419

if (Irp->PendingReturned)

IoMarkIrpPending(Irp);

    所有不返回STATUS_MORE_PROCESSING_REQUIRED状态的完成例程都需要这两行代码。

7、取消I/O请求

    为了在内核模式中取消一个请求,IRP的创建者需调用IoCancelIrp函数。如果某线程终止时,它发出的请求仍然未完成,则操作系统自动为每个IRP调用IoCancelIrp。用户模式应用程序调用CancelIo函数可以取消给定线程发出的所有未完成的异步操作。IoCancelIrp仅仅是简单地设置IRP的Cancel标志位然后调用IRP的取消例程。即:它并不知道你在是否修改过IRP指针,也不知道你是否正在处理这个IRP,所以它必须依靠一个你提供的取消例程来做大部分IRP取消工作。

关于取消IO更多的关于多CPU的讨论,见参考文献[1]。

[1] Windows驱动程序模型设计

目录
相关文章
|
1月前
|
监控 Ubuntu Linux
视频监控笔记(五):Ubuntu和windows时区同步问题-your clock is behind
这篇文章介绍了如何在Ubuntu和Windows系统中通过设置相同的时区并使用ntp服务来解决时间同步问题。
64 4
视频监控笔记(五):Ubuntu和windows时区同步问题-your clock is behind
|
4月前
|
Linux Apache C++
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt
该文介绍了如何在Windows环境下为FFmpeg集成SRT协议支持库libsrt。首先,需要安装Perl和Nasm,然后编译OpenSSL。接着,下载libsrt源码并使用CMake配置,生成VS工程并编译生成srt.dll和srt.lib。最后,将编译出的库文件和头文件按照特定目录结构放置,并更新环境变量,重新配置启用libsrt的FFmpeg并进行编译安装。该过程有助于优化直播推流的性能,减少卡顿问题。
123 2
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt
|
4月前
|
存储 安全 数据安全/隐私保护
Windows 32 汇编笔记(一):基础知识
Windows 32 汇编笔记(一):基础知识
|
3月前
|
Windows
Windows 映射网络驱动器及删除-此网格连接不存在
Windows 映射网络驱动器及删除-此网格连接不存在
422 0
|
3月前
|
存储 编译器 Linux
Windows 32 汇编笔记(二):使用 MASM
Windows 32 汇编笔记(二):使用 MASM
|
4月前
|
安全 测试技术 Windows
LabVIEW版本、硬件驱动和Windows版本之间兼容性
LabVIEW版本、硬件驱动和Windows版本之间兼容性
103 2
|
5月前
|
网络安全 C++ Windows
【Windows驱动开发】(主机)VS2017+(虚拟机)win10系统------双机调试
【Windows驱动开发】(主机)VS2017+(虚拟机)win10系统------双机调试
|
5月前
|
Windows
【Windows驱动开发】注册表的基本操作(创建、打开、修改、读取、枚举)(附源码)
【Windows驱动开发】注册表的基本操作(创建、打开、修改、读取、枚举)(附源码)
|
5月前
|
Windows
【Windows内核驱动函数(1)】IoCreateSymbolicLink()-----创建符号链接函数
【Windows内核驱动函数(1)】IoCreateSymbolicLink()-----创建符号链接函数
|
5月前
|
编解码 Windows
FFmpeg开发笔记(二十九)Windows环境给FFmpeg集成libxvid
XviD是开源MPEG-4视频编码器,与DivX相似但后者非开源。早期MP4常使用XviD或DivX编码,现已被H.264取代。在Windows上集成FFmpeg的XviD编解码库libxvid,需访问<https://labs.xvid.com/source/>下载源码,解压后在MSYS环境中配置、编译和安装。之后重新配置FFmpeg,启用libxvid并编译安装。详细步骤包括configure命令、make和make install。成功后,通过`ffmpeg -version`检查是否启用libxvid。更多音视频开发技术可参考《FFmpeg开发实战:从零基础到短视频上线》。
111 0
FFmpeg开发笔记(二十九)Windows环境给FFmpeg集成libxvid

热门文章

最新文章