alan2u
驱动巨牛
驱动巨牛
  • 注册日期2001-12-11
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分5926分
  • 威望43813点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:2419回复:22

一个问题请教各位大佬

楼主#
更多 发布于:2002-10-16 09:42
用IoBuildSynchronousFsdRequest创建的Irp,如何释放它,在ddk中讲需要用IoCompleteRequest()而不能仅仅使用IoFreeIrp.但我在试验时不论使用IoCompleteRequest()还是使用IoFreeIrp都会使系统崩溃,相反这两个函数一个都不用反而能够运行.

这让我很迷茫,创建了Irp,不释放掉心里总是不踏实

最新喜欢:

luke_gemluke_g...
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-10-16 12:31
是不是在什么地方已经释放了?
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-10-16 12:35
两个都用呢?
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
VanCheer
驱动老牛
驱动老牛
  • 注册日期2002-02-21
  • 最后登录2003-08-28
  • 粉丝0
  • 关注0
  • 积分-20分
  • 威望-10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-10-16 12:35
用SoftIce跟进“IoCompleteRequest()还是使用IoFreeIrp”这两个东西去,看看传的参数对否
[img]http://www.driverdevelop.com/forum/upload/VanCheer/2003-03-21_mon.gif[/img][img]http://www.driverdevelop.com/forum/upload/VanCheer/2002-12-07_smallbaby.jpg[/img]
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2002-10-16 12:36
两个都用呢?

蓝屏
打pp
VanCheer
驱动老牛
驱动老牛
  • 注册日期2002-02-21
  • 最后登录2003-08-28
  • 粉丝0
  • 关注0
  • 积分-20分
  • 威望-10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-10-16 12:37
补充一下,不一定是你释放的原因,如果你把Buffer溢出了,也可能有这情况(起码应用里是这样)
[img]http://www.driverdevelop.com/forum/upload/VanCheer/2003-03-21_mon.gif[/img][img]http://www.driverdevelop.com/forum/upload/VanCheer/2002-12-07_smallbaby.jpg[/img]
guardee
驱动巨牛
驱动巨牛
  • 注册日期2002-11-08
  • 最后登录2010-05-29
  • 粉丝2
  • 关注1
  • 积分2分
  • 威望34点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-10-16 12:38
你要搞清楚,你建立的这个IRP是往什么地方发送!如果还是你自己的驱动程序来处理,那么你就要用IoCompleteRequest来完成了!如果是发给低层,那么你可以看WDM里面的例子
Tom_lyd
驱动大牛
驱动大牛
  • 注册日期2001-09-02
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-10-16 14:35
用IoBuildSynchronousFsdRequest创建的Irp,如何释放它,在ddk中讲需要用IoCompleteRequest()而不能仅仅使用IoFreeIrp.但我在试验时不论使用IoCompleteRequest()还是使用IoFreeIrp都会使系统崩溃,相反这两个函数一个都不用反而能够运行.

这让我很迷茫,创建了Irp,不释放掉心里总是不踏实

有几点需要提醒你:
1.自己分配的IRP需要自己在完成例程中释放
2.在完成中一般需要返回
STATUS_MORE_PROCESSING_REQUIRED,这样避免I/O Manager尝试释放你创建的IRP,如果返回成功,则I/O Manager会释放这个IRP,则肯定死翘翘。

在返回前根据下层驱动返回的相关参数设置事件,并调用IoFreeIrp释放IRP。
3.原分配IRP函数收到事件后不得再访问IRP,否则会引起异常。
Tom_lyd
alan2u
驱动巨牛
驱动巨牛
  • 注册日期2001-12-11
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分5926分
  • 威望43813点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
8楼#
发布于:2002-10-16 16:04
两个都用呢?


我试过了,不行
alan2u
驱动巨牛
驱动巨牛
  • 注册日期2001-12-11
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分5926分
  • 威望43813点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
9楼#
发布于:2002-10-16 16:32
[quote]用IoBuildSynchronousFsdRequest创建的Irp,如何释放它,在ddk中讲需要用IoCompleteRequest()而不能仅仅使用IoFreeIrp.但我在试验时不论使用IoCompleteRequest()还是使用IoFreeIrp都会使系统崩溃,相反这两个函数一个都不用反而能够运行.

这让我很迷茫,创建了Irp,不释放掉心里总是不踏实

有几点需要提醒你:
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


VanCheer
驱动老牛
驱动老牛
  • 注册日期2002-02-21
  • 最后登录2003-08-28
  • 粉丝0
  • 关注0
  • 积分-20分
  • 威望-10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-10-16 16:36
我创建的Irp是给下层驱动的.而且是同步的,所以它没有完成例程.

整个函数的流程是这样的:
1.创建irp
2.IoCallDriver
3.等待
4.返回

我这样理解对不对?
我在返回前判断一下Status,如果是成功的,就不要释放irp了,Iomanager已经释放了.如果是STATUS_MORE_PROCESSING_REQUIRED,就IoCompleteRequest一下,然后在iofreeirp


 

别管对不对,汝试验之
[img]http://www.driverdevelop.com/forum/upload/VanCheer/2003-03-21_mon.gif[/img][img]http://www.driverdevelop.com/forum/upload/VanCheer/2002-12-07_smallbaby.jpg[/img]
Tom_lyd
驱动大牛
驱动大牛
  • 注册日期2001-09-02
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
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。切记,切记!


Tom_lyd
alan2u
驱动巨牛
驱动巨牛
  • 注册日期2001-12-11
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分5926分
  • 威望43813点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
12楼#
发布于:2002-10-16 16:50
错矣,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。切记,切记!


 


老哥,这段话是说IoBuildAsynchronousFsdRequest这个函数,这是异步的,我调用的那个是同步的,中间少个A
alan2u
驱动巨牛
驱动巨牛
  • 注册日期2001-12-11
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分5926分
  • 威望43813点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
13楼#
发布于:2002-10-16 16:54
别管对不对,汝试验之


花猫,我试验过,两个函数都不调用是正确的,但不知道其原因,心里不踏实 :D
alan2u
驱动巨牛
驱动巨牛
  • 注册日期2001-12-11
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分5926分
  • 威望43813点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
14楼#
发布于:2002-10-16 17:06
错矣,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。切记,切记!


 


你的意思是在KeWaitForSingleObject等待事件被触发,不管是否Status,都不去处理irp?

那么irp是底层驱动释放的?还是iomanager释放的?
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-10-16 17:10
你自己申请的当然要你自己释放

[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
Tom_lyd
驱动大牛
驱动大牛
  • 注册日期2001-09-02
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
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等。
Tom_lyd
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2002-10-16 17:24
拜托你把相关代码贴一下,让大家在这里揣摩你的代码再回答真的很浪费时间和精力哦!
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
alan2u
驱动巨牛
驱动巨牛
  • 注册日期2001-12-11
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分5926分
  • 威望43813点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
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;
}
alan2u
驱动巨牛
驱动巨牛
  • 注册日期2001-12-11
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分5926分
  • 威望43813点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
19楼#
发布于:2002-10-16 18:21
谢谢大家给我回答问题

上一页
游客

返回顶部