阅读:2419回复:22
一个问题请教各位大佬
用IoBuildSynchronousFsdRequest创建的Irp,如何释放它,在ddk中讲需要用IoCompleteRequest()而不能仅仅使用IoFreeIrp.但我在试验时不论使用IoCompleteRequest()还是使用IoFreeIrp都会使系统崩溃,相反这两个函数一个都不用反而能够运行.
这让我很迷茫,创建了Irp,不释放掉心里总是不踏实 |
|
最新喜欢:![]() |
沙发#
发布于:2002-10-16 12:31
是不是在什么地方已经释放了?
|
|
板凳#
发布于:2002-10-16 12:35
两个都用呢?
|
|
|
地板#
发布于:2002-10-16 12:35
用SoftIce跟进“IoCompleteRequest()还是使用IoFreeIrp”这两个东西去,看看传的参数对否
|
|
|
地下室#
发布于:2002-10-16 12:36
两个都用呢? 蓝屏 打pp |
|
5楼#
发布于:2002-10-16 12:37
补充一下,不一定是你释放的原因,如果你把Buffer溢出了,也可能有这情况(起码应用里是这样)
|
|
|
6楼#
发布于:2002-10-16 12:38
你要搞清楚,你建立的这个IRP是往什么地方发送!如果还是你自己的驱动程序来处理,那么你就要用IoCompleteRequest来完成了!如果是发给低层,那么你可以看WDM里面的例子
|
|
7楼#
发布于:2002-10-16 14:35
用IoBuildSynchronousFsdRequest创建的Irp,如何释放它,在ddk中讲需要用IoCompleteRequest()而不能仅仅使用IoFreeIrp.但我在试验时不论使用IoCompleteRequest()还是使用IoFreeIrp都会使系统崩溃,相反这两个函数一个都不用反而能够运行. 有几点需要提醒你: 1.自己分配的IRP需要自己在完成例程中释放 2.在完成中一般需要返回 STATUS_MORE_PROCESSING_REQUIRED,这样避免I/O Manager尝试释放你创建的IRP,如果返回成功,则I/O Manager会释放这个IRP,则肯定死翘翘。 在返回前根据下层驱动返回的相关参数设置事件,并调用IoFreeIrp释放IRP。 3.原分配IRP函数收到事件后不得再访问IRP,否则会引起异常。 |
|
|
8楼#
发布于:2002-10-16 16:04
两个都用呢? 我试过了,不行 |
|
9楼#
发布于:2002-10-16 16:32
[quote]用IoBuildSynchronousFsdRequest创建的Irp,如何释放它,在ddk中讲需要用IoCompleteRequest()而不能仅仅使用IoFreeIrp.但我在试验时不论使用IoCompleteRequest()还是使用IoFreeIrp都会使系统崩溃,相反这两个函数一个都不用反而能够运行. 有几点需要提醒你: 1.自己分配的IRP需要自己在完成例程中释放 2.在完成中一般需要返回 STATUS_MORE_PROCESSING_REQUIRED,这样避免I/O Manager尝试释放你创建的IRP,如果返回成功,则I/O Manager会释放这个IRP,则肯定死翘翘。 在返回前根据下层驱动返回的相关参数设置事件,并调用IoFreeIrp释放IRP。 3.原分配IRP函数收到事件后不得再访问IRP,否则会引起异常。 [/quote] 我创建的Irp是给下层驱动的.而且是同步的,所以它没有完成例程. 整个函数的流程是这样的: 1.创建irp 2.IoCallDriver 3.等待 4.返回 我这样理解对不对? 我在返回前判断一下Status,如果是成功的,就不要释放irp了,Iomanager已经释放了.如果是STATUS_MORE_PROCESSING_REQUIRED,就IoCompleteRequest一下,然后在iofreeirp |
|
10楼#
发布于:2002-10-16 16:36
我创建的Irp是给下层驱动的.而且是同步的,所以它没有完成例程. 别管对不对,汝试验之 |
|
|
11楼#
发布于:2002-10-16 16:40
错矣,IoBuildSynchronousFsdRequest创建的IRP来请求低层驱程序的服务必须设置完成例程。下面是从DDK文档中摘来的一段:
Intermediate or highest-level drivers can call IoBuildAsynchronousFsdRequest to set up IRPs for requests sent to lower-level drivers. Such a driver must set its IoCompletion routine in the IRP so the IRP can be deallocated with IoFreeIrp. IoFreeIrp必须在完成例程中调用,调用者在IoCallDriver后,用KeWaitForSingleObject等待事件被触发,不得再触及IRP。切记,切记! |
|
|
12楼#
发布于:2002-10-16 16:50
错矣,IoBuildSynchronousFsdRequest创建的IRP来请求低层驱程序的服务必须设置完成例程。下面是从DDK文档中摘来的一段: 老哥,这段话是说IoBuildAsynchronousFsdRequest这个函数,这是异步的,我调用的那个是同步的,中间少个A |
|
13楼#
发布于:2002-10-16 16:54
别管对不对,汝试验之 花猫,我试验过,两个函数都不调用是正确的,但不知道其原因,心里不踏实 :D |
|
14楼#
发布于:2002-10-16 17:06
错矣,IoBuildSynchronousFsdRequest创建的IRP来请求低层驱程序的服务必须设置完成例程。下面是从DDK文档中摘来的一段: 你的意思是在KeWaitForSingleObject等待事件被触发,不管是否Status,都不去处理irp? 那么irp是底层驱动释放的?还是iomanager释放的? |
|
15楼#
发布于:2002-10-16 17:10
你自己申请的当然要你自己释放
|
|
|
16楼#
发布于:2002-10-16 17:17
自己创建的IRP当然是自己释放,不应该让I/O Manager去管这个事件。在完成例程中返回STATUS_MORE_PROCESSING_REQUIRED就是为了不让I/O Manager去管这个IRP,I/O Manager甚至根本不知道你还自己创建过一个IRP:)。
是的,创建IRP的例程只要调用了IoCallDriver,就不应该再访问这个IRP,至于释放IRP已经不是它的事。在IoCallDriver之前有两件必须做的事就是: 调用IoSetCompletionRoutine设置完成例程; 调用KeInitializeEvent初始化一个事件对象; 另外,创建好了IRP后,IRP的一些字段必须正确初始化,如IRP_STACK_LOCATION等。 |
|
|
17楼#
发布于:2002-10-16 17:24
拜托你把相关代码贴一下,让大家在这里揣摩你的代码再回答真的很浪费时间和精力哦!
|
|
|
18楼#
发布于:2002-10-16 17:56
NTSTATUS
NCFSWriteSync( IN PDEVICE_OBJECT DeviceObject, IN LONGLONG Offset, IN ULONG Length, IN PVOID Buffer ) { KEVENT Event; PIRP Irp; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; ASSERT(DeviceObject != NULL); ASSERT(Buffer != NULL); KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildSynchronousFsdRequest( IRP_MJ_WRITE, DeviceObject, Buffer, Length, (PLARGE_INTEGER)(&Offset), &Event, &IoStatus ); if (!Irp) { return STATUS_INSUFFICIENT_RESOURCES; } Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject( &Event, Suspended, KernelMode, FALSE, NULL ); Status = IoStatus.Status; } //我项在这里释放irp return Status; } |
|
19楼#
发布于:2002-10-16 18:21
谢谢大家给我回答问题
|
|
上一页
下一页