派遣函数 - 对派遣函数的简单处理

        大部分的IRP都源于文件I/O处理Win32 API,如CreateFile、ReadFile等。处理这些IRP最简单的就是是在相应的派造函数中,将IRP的状态设置为成功,然后结束IRP的请求,并让派遣函数返回成功。结束IRP的请求使用函数IoCompleteRequest。下面的代码演示了一种最简单的处理IRP请求的派遣函数。

NTSTATUS HelloDDKDispatchRouthin(IN PDEVICE_OBJECT pDevoBJ, IN PIRP pIrp)
{

	KdPrint(("Enter HelloDDKDispatchRouthin!\n"));

	// 对一般IRP的简单操作,后面会介绍对IRP更复杂的操作
	NTSTATUS status = STATUS_SUCCESS;

	// 设置IRP完成状态
	pIrp->IoStatus.Information = 0; 

	// 处理IRP
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	KdPrint(("Leave HelloDDKDispatchRouthin!\n"));

	return status;
}

        在本例中,派遣函数设置了IRP的完成状态为STATUS_SUCCESS。这样,发起I/O请求的Win32 API(如 WriteFile)将会返回 TRUE。相反,如果将IRP的完成状态设置为不成功,这时发起I/O请求的Win32 API(如 WriteFile)将会返回 FALSE。这种情况时,可以使用GetLastErmor Win32 API得到错误代码。所得的错误代码会和 IRP 设置的状态相一致。

        除了设置IRP的完成状态,派遣函数还要设置这个IRP请求操作了多少字节。在本例中,将操作字节数简单地设置成了0。如果是ReadFile产生的IRP,这个字节数代表从设备读了多少字节。如果是WriteFile产生的IRP,这个字节数代表对设备写了多少字节。最后,派遣函数将 IRP 请求结束,这是通过 IoCompleteRequest函数完成的,loCompleteRequest的声明如下:

VOID IoCompleteRequest(
    IN PIRP Irp,
    IN CCHAR PriorityBoost
    );
	
// Irp:代表需要被结束的IRP。
// PriorityBoost:代表线程恢复时的优先级别。

        为了解释优先级的概念,需要了解一下与文件I/O相关的 Win32 API的内部操作过程。
这里以ReadFile为例,ReadFile 的内部操作大体是这样的:

            a. ReadFile 调用 ntdll 中的 NtReadFile。 其中 ReadFile 函数是 Win32 API,
而 NtReadFile函数是 Native API。

            b. ntdll中的 NtReadFile 进入到内核模式,并调用系统服务中的 NtReadFile 函数。

            c. 系统服务函数 NReadFile 创建 IRP_MJ_WRITE 类型的IRP,
然后它将这个IRP发送到某个驱动程序的派遭函数中。NtReadFile 然后去等待一个事件,
这时当前线程进入“睡眼”,状态,也可以说当前线程被阻塞住或者线程处于“pending”状态。

            d. 在派遣函数中一般会将IRP 请求结束,结束IRP是通过IoCompleteRequest函数,
在IoCompleteRequest函数内部会设置刚才等待的事件,“睡眠”的线程被恢复运行。

        例如,在读一个很大的文件(或者设备)时,ReadFile不会立刻返回,而是等待一段时间。这段时间就是当前线程“睡眠”的那段时间。IRP请求被结束,标志这个操作执行完毕,这时“睡眠”的线程被唤醒。

        IocompleteReguct函数中第二个参数PriorityBoost代表一种优先级,指的是被阻塞的线程以何种优先级恢复运行。一般情况下,优先级设置为IO_NO_INCREMENT。对某些特殊情况,需要将阻塞的线程以“优先”的身份恢复运行。如键盘、鼠标等输入设备,它们需要更快地反应。

优先级说明
IO_NO_INCREMENT不增加优先级
IO_CD_ROM_INCREMENT光驱设备增加的优先级
IO_DISK_INCREMENT磁盘设备增加的优先级
IO_KEYBOARD_INCREMENT键盘设备增加的优先级
IO_MOUSE_INCREMENT鼠标设备增加的优先级
IO_NAMED_PIPE_INCREMENT命名管道增加的优先级
IO_NETWORK_INCREMENT网络设备增加的优先级
IO_PARALLEL_INCREMENT并口设备增加的优先级
IO_SERIAL_INCREMENT串口设备增加的优先级
IO_SOUND_INCREMENT声卡设备增加的优先级
IO_VIDEO_INCREMENT视频设备增加的优先级
SEMAPHORE_JNCREMENT信号灯增加的优先级

        本节只讨论了派遣函数中最简单的处理IRP的方法,在实际应用中往往要比这个复杂的多。

  • 19
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WendyWJGu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值