eric.hee
驱动牛犊
驱动牛犊
  • 注册日期2002-05-21
  • 最后登录2002-10-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2285回复:19

关于IoSetCompletionRoutine,50分!

楼主#
更多 发布于:2002-05-23 20:00
小弟想做一个包过滤程序,
过滤函数如下:

NTSTATUS Pass( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
DbgPrint(\"get Package!!!\\n\");

PIO_STACK_LOCATION pIrpStack;

pIrpStack = IoGetCurrentIrpStackLocation( Irp );
IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine( Irp,
GenericCompletion,
0,
TRUE,
TRUE,
TRUE
);


return IoCallDriver( m_TcpgetDevice, Irp);

}

NTSTATUS GenericCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
{
if(Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}

return STATUS_SUCCESS;
}

但是发现一个问题,第一次调用IoSetCompletionRoutine没有问题,
当接到第二个irp时,再调用IoSetCompletionRoutine,就会蓝屏,
希望有经验的大虾多指教!
谢谢!




 

最新喜欢:

flyfoxflyfox
sprite_sy
驱动牛犊
驱动牛犊
  • 注册日期2002-05-20
  • 最后登录2002-12-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-05-23 22:46
猜想可能和IRP的排队有关系吧

不过就这些好像看不出什么问题
 看看IoStartNextPacket之类的调用有没有问题
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-05-24 08:42
前一个Irp没有完成,当然不能再处理Irp的例程。
在Completion中加入IoCompleteRequest的调用。
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-05-24 09:14
对呀,你自己的完成例程里怎么不调用IoCompleteRequest
你注册了一个回调的完成例程,最主要的就是调用IoCompleteRequest来完成irp的
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
eric.hee
驱动牛犊
驱动牛犊
  • 注册日期2002-05-21
  • 最后登录2002-10-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-05-24 09:51
首先非常感谢你们的回复。

但是我试了一下,
将GenericCompletion改成这样。

NTSTATUS GenericCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
{
  IoCompleteRequest(Irp,IO_NO_INCREMENT);  
  return STATUS_SUCCESS;
}

但结果还是一样的。。。。。。。。
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-05-24 10:07
完成一个IRP必须先填充IoStatus块的Status和Information成员,然后调用IoCompleteRequest例程。Status值就是NTSTATUS.H中定义的状态代码。表5-1简要地列出了常用的状态代码。而Information值要取决于你完成的是何种类型的IRP以及是成功还是失败。通常情况下,如果IRP完成失败(即,完成的结果是某种错误状态),你应把Information域置0。如果你成功地完成了一个数据传输IRP,通常应该把Information域设置成传输的字节量。

NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS status, ULONG_PTR Information)
{
  Irp->IoStatus.Status = status;
  Irp->IoStatus.Information = Information;
  IoCompleteRequest(Irp, IO_NO_INCREMENT);
  return status;
}
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
eric.hee
驱动牛犊
驱动牛犊
  • 注册日期2002-05-21
  • 最后登录2002-10-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-05-24 10:26
谢谢,这位大哥如此热心小弟感激涕零。。。。。

我按照你说的填充了information和status

NTSTATUS GenericCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
{
  Irp->IoStatus.Status = STATUS_SUCCESS;
  Irp->IoStatus.Information = 0;
  IoCompleteRequest(Irp, IO_NO_INCREMENT);

  return STATUS_SUCCESS;
}

但执行到IoSetCompletionRoutine还是出错。。。。。唉。。。苦
eric.hee
驱动牛犊
驱动牛犊
  • 注册日期2002-05-21
  • 最后登录2002-10-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-05-24 10:32
以下是全部代码,很短,可否请各位大哥帮忙分析一下IoSetCompletionRoutine出错的原因,小弟先行谢过了。


#include \"PassThrough.h\"

/////////////////////////////////////////////////////////////////////////////

PDEVICE_OBJECT phddo = NULL;
PDEVICE_OBJECT    m_TcpgetDevice;
PDEVICE_OBJECT  TcpDevice;
/////////////////////////////////////////////////////////////////////////////

#pragma code_seg(\"INIT\") // start INIT section

/////////////////////////////////////////////////////////////////////////////
// DriverEntry:
//
extern \"C\"
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{

    UNICODE_STRING    TcpDeviceName;
    PDRIVER_OBJECT    TcpDriver;
    PDEVICE_OBJECT    TcpgetDevice;
    PDRIVER_DISPATCH  Empty;
    NTSTATUS          status;
    PFILE_OBJECT      FileObject;
    int i = 0;

DriverObject->DriverUnload = PassThroughUnload;
Empty = DriverObject->MajorFunction[IRP_MJ_CREATE];
RtlInitUnicodeString( &TcpDeviceName, L\"\\\\Device\\\\Tcp\");

status = IoGetDeviceObjectPointer( &TcpDeviceName,
                                        FILE_ALL_ACCESS,
                               &FileObject,
                                        &TcpDevice
                                      );
    

    if(!NT_SUCCESS(status))
     {
        DbgPrint(\"IoGetDeviceObjectPointer error!\\n\");
        return status;
     }

   DbgPrint(\"IoGetDeviceObjectPointer ok!\\n\");

  
   status = IoCreateDevice( DriverObject,
                            sizeof(PHDIO_DEVICE_EXTENSION),
                            NULL,
                            FILE_DEVICE_UNKNOWN,
                            0,
                            FALSE,
                            &phddo
                           );
  
   if(!NT_SUCCESS(status))
    {
        return status;
    }

    
    TcpgetDevice = IoAttachDeviceToDeviceStack( phddo, TcpDevice);

    if(!TcpgetDevice)
    {
         IoDeleteDevice(phddo);
    DbgPrint(\"IoAttachDeviceToDeviceStack error!\\n\");
         return STATUS_SUCCESS;
    }
    
m_TcpgetDevice = TcpgetDevice;
    
    TcpDriver = TcpgetDevice->DriverObject;

    
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
    {
       if((TcpDriver->MajorFunction!=Empty)&&(DriverObject->MajorFunction==Empty))
       {
          DriverObject->MajorFunction = Pass;
       }
   }
  
   ObDereferenceObject(FileObject);



return status;
}

NTSTATUS Pass( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
  DbgPrint(\"get Package!!!\\n\");
  
  PIO_STACK_LOCATION          pIrpStack;
  
  pIrpStack = IoGetCurrentIrpStackLocation( Irp );
  IoCopyCurrentIrpStackLocationToNext(Irp);
  
  IoSetCompletionRoutine( Irp,
                          GenericCompletion,
                          NULL,
                          TRUE,
                     TRUE,
                     TRUE
                   );
  
  
  return IoCallDriver( m_TcpgetDevice, Irp);
  
}

NTSTATUS GenericCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
{
  //if(Irp->PendingReturned)
  //{
  //  IoMarkIrpPending(Irp);
  //}
  Irp->IoStatus.Status = STATUS_SUCCESS;
  Irp->IoStatus.Information = 0;
  IoCompleteRequest(Irp, IO_NO_INCREMENT);

  return STATUS_SUCCESS;
}



 

////////////////////////////////////////////////////////////////////////////
// PassThoughUnload
//
// Description:
// Unload the driver by removing any remaining objects, etc.
//
// Arguments:
// Pointer to the Driver object
//
// Return Value:
// None

#pragma code_seg(\"PAGE\") // start PAGE section

VOID PassThroughUnload(IN PDRIVER_OBJECT DriverObject)
{
IoDetachDevice(TcpDevice);
    IoDeleteDevice(phddo);
DbgPrint(\"Driver Unload Success completed\\n\");
}

//////////////////////////////////////////////////////////////////////////////

guardee
驱动巨牛
驱动巨牛
  • 注册日期2002-11-08
  • 最后登录2010-05-29
  • 粉丝2
  • 关注1
  • 积分2分
  • 威望34点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-05-24 10:36
呵呵!他们告诉你的是错误的,你的完成例程里面估计是因为你的返回值有错误,可能是下层驱动程序还没有完成该IRP,而你却返回成功,你应该返回的是Irp->IoStatus.Status,因为下层驱动程序对该IRP的处理状态放在这里了!对于不想下发该IRP的话,那么是可以这样完成该IRP的
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
该代码就是把该请求的IRP完成了,也不把IRP下发到下一层驱动程序了!
yxjoyce
驱动牛犊
驱动牛犊
  • 注册日期2002-04-15
  • 最后登录2003-04-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-05-24 10:39
我也写过filter driver,它的pass 和completion部分基本和你相同,没有什么问题,我估计可能是你其它部分有点问题:)
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-05-24 11:01
、、、、、、、、、、、、、、、、、
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
if((TcpDriver->MajorFunction!=Empty)&&(DriverObject->MajorFunction==Empty))
{
DriverObject->MajorFunction = Pass;
}
}
、、、、、、、、、、、、、、、、、、、、、
是不是有问题,显然是要对MajorFunction数组操作的
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
if((TcpDriver->MajorFunction!=Empty)&&(DriverObject->MajorFunction==Empty))
{
DriverObject->MajorFunction = Pass;
}
}
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
matt
驱动中牛
驱动中牛
  • 注册日期2001-07-24
  • 最后登录2016-02-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-05-24 11:02
首先非常感谢你们的回复。

但是我试了一下,
将GenericCompletion改成这样。

NTSTATUS GenericCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
{
  IoCompleteRequest(Irp,IO_NO_INCREMENT);  
  return STATUS_SUCCESS;
}

但结果还是一样的。。。。。。。。
 



在你的完成例程中不应该加入IoCompleteRequest。因为此IRP处理不是你来做的,IoCompleteRequest应该由下层来调用。

此外,将黑体部分改成FALSE。

IoSetCompletionRoutine( Irp,
GenericCompletion,
NULL,
TRUE,
TRUE,
TRUE );




System Internals http://sys.xiloo.com
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-05-24 11:04
糟糕,没改掉
应该是:
 
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
if((TcpDriver->MajorFunction!=Empty)&&(DriverObject->MajorFunction==Empty))
{
DriverObject->MajorFunction = Pass;
}
}
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-05-24 11:08
faint

怎么回事

非得让我敲进去

应该是MajorFuntion
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-05-24 11:10
明白了,数组下标显示不出来
算了。
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-05-24 11:51
 
在你的完成例程中不应该加入IoCompleteRequest。因为此IRP处理不是你来做的,IoCompleteRequest应该由下层来调用。

此外,将黑体部分改成FALSE。

IoSetCompletionRoutine( Irp,
GenericCompletion,
NULL,
TRUE,
TRUE,
TRUE );


这个irp又不是它自己创建的,也是由上层传下来的,当然要调用IoCompleteRequest
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
matt
驱动中牛
驱动中牛
  • 注册日期2001-07-24
  • 最后登录2016-02-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2002-05-24 12:36
[quote] 在你的完成例程中不应该加入IoCompleteRequest。因为此IRP处理不是你来做的,IoCompleteRequest应该由下层来调用。

此外,将黑体部分改成FALSE。

IoSetCompletionRoutine( Irp,
GenericCompletion,
NULL,
TRUE,
TRUE,
TRUE );


这个irp又不是它自己创建的,也是由上层传下来的,当然要调用IoCompleteRequest [/quote]

你的完成例程为什么会被调用?是因为下层driver将它完成了,因而你有必要再IoCompleteRequest吗?

System Internals http://sys.xiloo.com
tigerzd
驱动老牛
驱动老牛
  • 注册日期2001-08-25
  • 最后登录2004-12-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2002-05-24 12:44
返回值改为STATUS_MORE_PROCESSING_REQUIRED试试。
犯强汉者,虽远必诛! [img]http://www.driverdevelop.com/forum/upload/tigerzd/2002-12-13_sf10.JPG[/img]
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2002-05-24 12:50
 
引用:
--------------------------------------------------------------------------------
 
引用:
--------------------------------------------------------------------------------
 在你的完成例程中不应该加入IoCompleteRequest。因为此IRP处理不是你来做的,IoCompleteRequest应该由下层来调用。

此外,将黑体部分改成FALSE。

IoSetCompletionRoutine( Irp,
GenericCompletion,
NULL,
TRUE,
TRUE,
TRUE );

--------------------------------------------------------------------------------



这个irp又不是它自己创建的,也是由上层传下来的,当然要调用IoCompleteRequest
--------------------------------------------------------------------------------



你的完成例程为什么会被调用?是因为下层driver将它完成了,因而你有必要再IoCompleteRequest吗?
 


你如果不调用IoCompleteRequest,你的上层驱动程序怎么办,它什么时候调用他的完成例程
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
eric.hee
驱动牛犊
驱动牛犊
  • 注册日期2002-05-21
  • 最后登录2002-10-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2002-05-24 13:58
终于解决了,原来是#pragma code_seg(\"PAGE\")
的问题,删掉就没事了。。。。

多谢大家!

真想给你们每个人100分,可惜我分数没那么多:(
游客

返回顶部