funny
驱动小牛
驱动小牛
  • 注册日期2003-04-17
  • 最后登录2021-07-30
  • 粉丝0
  • 关注0
  • 积分1012分
  • 威望178点
  • 贡献值0点
  • 好评度123点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1752回复:8

过滤驱动间 Irp传递问题?请指点!

楼主#
更多 发布于:2007-03-20 16:48
我创建了一个过滤驱动,在IRP_MJ_WRITE的dispatchwrite例程中,捕获Irp中systembuffer的数据,  将数据发送到串口(串口在驱动初始时已进行通信设置)。

具体步骤:
1.创建一个新的同步IRP,通过IoCallDriver将此Irp传递到串口过滤设备对象中。
2.而原来的Irp继续往下传递。
出现的现象,发向串口的数据很慢,并且第二次请求死过去了。
如果IoCompleteRequest原来的Irp,那么发往串口的Irp正常,并且数据能及时传递到串口,不会死锁。可是我目的是不想提前完成原来的Irp,即仍然IoCallDriver向下传递。

是什么导致死锁的发生呢?欢迎讨论!

最新喜欢:

LeopardLeopar...
驱动现在,成就未来
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-03-21 06:28
你的过滤驱动是过滤什么的?
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
liyunch
驱动小牛
驱动小牛
  • 注册日期2001-06-28
  • 最后登录2014-09-05
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望134点
  • 贡献值0点
  • 好评度94点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-03-21 08:48
用异步的irp.记着给分呀
funny
驱动小牛
驱动小牛
  • 注册日期2003-04-17
  • 最后登录2021-07-30
  • 粉丝0
  • 关注0
  • 积分1012分
  • 威望178点
  • 贡献值0点
  • 好评度123点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2007-03-21 08:59
我是创建的并口过滤驱动,将WriteFile并口的数据截获发向串口。
我一直有个疑惑关于Irp分支给不同设备对象,并口的Irp_MJ_Write与新创建的串口Irp_MJ_WIite的完成例程之间关于Irp的堆栈释放是否有冲突。  

请rayyang2000给个解释。thanks in advance。

To:liyunch还有从网站的哪个地方给分,没找到。
驱动现在,成就未来
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-03-22 08:26
听起来没有什么原因会造成延迟,Windows对串、并口有不同的driver,貌似不会内部产生什么同步问题。

可以试试看,先将并口的IRP做pending,然后传送新的IRP给串口,串口返回后再将旧的传给并口。

另外,并口Irp->SystemBuffer貌似不能直接设置给新的Irp,最好把数据复制一份
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
funny
驱动小牛
驱动小牛
  • 注册日期2003-04-17
  • 最后登录2021-07-30
  • 粉丝0
  • 关注0
  • 积分1012分
  • 威望178点
  • 贡献值0点
  • 好评度123点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2007-03-22 13:44
OK, o 正是使用了并口Irp->AssociatedIrp.systembuffer,传递给了IoBuildSynchronousFsdRequest的Inbuffer参数,  但如果对并口Irp做Pending (IoMarkIrpPending), 是不是应该在串口的完成例程里,在传递旧的Irp给并口? 正 looking  DDK关于对Irp的章节,搞不懂。
驱动现在,成就未来
funny
驱动小牛
驱动小牛
  • 注册日期2003-04-17
  • 最后登录2021-07-30
  • 粉丝0
  • 关注0
  • 积分1012分
  • 威望178点
  • 贡献值0点
  • 好评度123点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2007-03-22 13:54
偶写有以上问题的部分代码:
请各路高手讨论分析:
我也曾试过把ComhookIoSyncWrite放在ComhookDispatchWrite的完成例程中,但是还是出现死锁。
以下是在把ComhookIoSyncWrite放在ComhookDispatchWrite的例程中调用的。

//并口部分
ComhookDispatchWrite(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    PIO_STACK_LOCATION        IrpStack;
    PDEVICE_EXTENSION       deviceExtension;

    NTSTATUS ntStatus = STATUS_NOT_SUPPORTED;

    KEVENT event;
    IO_STATUS_BLOCK iosb;

    IrpStack = IoGetCurrentIrpStackLocation(Irp);
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    //IoSkipCurrentIrpStackLocation(Irp);

    IoCopyCurrentIrpStackLocationToNext(Irp);
    
                 ntStatus = IoCallDriver(deviceExtension->NextLowerDeviceObject, Irp);

    //ExAcquireFastMutex(&fastmutex);    
    
    //初始事件
    KeInitializeEvent( &event, NotificationEvent, FALSE);

    ntStatus = CommhookIoSyncWrite(IRP_MJ_WRITE,
                        deviceExtension->TgtDeviceObject,    
                        &event,
                        &iosb,
                           Irp->AssociatedIrp.SystemBuffer,        // input buffer
                        IrpStack->Parameters.DeviceIoControl.OutputBufferLength);     // input buffer length
    
    //ExReleaseFastMutex(&fastmutex);

    //Irp->IoStatus.Status = ntStatus;
    //Irp->IoStatus.Information = 0;
    //IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DbgPrint("[COMHOOK] DispatchWrite Exit 0x%0x \r\n", ntStatus);

    return ntStatus;
}
///串口部分
NTSTATUS
ComhookIoSyncWrite(
    IN        ULONG            Ioctl,                     // io control code
    IN        PDEVICE_OBJECT   DeviceObject,              // object to call
    IN        PKEVENT          Event,                     // event to wait on
    OUT        PIO_STATUS_BLOCK Iosb,                      // used inside IRP
    IN OUT  PVOID            InBuffer,    OPTIONAL        // input buffer
    IN        ULONG            InBufferLen)  OPTIONAL     // input buffer length

{
    NTSTATUS status;
    PIRP Irp;
    LARGE_INTEGER   startingOffset;
    startingOffset.QuadPart = (LONGLONG) 0;
    
    KeClearEvent(Event);

    Irp = IoBuildSynchronousFsdRequest(Ioctl,
                                        DeviceObject,
                                        InBuffer,
                                        InBufferLen,
                                        &startingOffset,
                                        Event,
                                        Iosb);
                                            
    if(Irp == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = IoCallDriver( DeviceObject, Irp);
    if (status == STATUS_PENDING)
            {
                   status = KeWaitForSingleObject(Event, Executive, KernelMode, FALSE, NULL);
    }

    return status;
}
驱动现在,成就未来
funny
驱动小牛
驱动小牛
  • 注册日期2003-04-17
  • 最后登录2021-07-30
  • 粉丝0
  • 关注0
  • 积分1012分
  • 威望178点
  • 贡献值0点
  • 好评度123点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2007-03-29 20:58
i find sth that:
IoBuildSynchronousFsdRequest can be called only in the following circumstances:
1.By a driver-created thread to build IRPs for read or write requests, because such a thread can wait in a nonarbitrary thread context (its own) on a dispatcher object, such as a driver-initialized Event passed to IoBuildSynchronousFsdRequest
2.In the system thread context during initialization or while unloading
3.To build IRPs for inherently synchronous operations, such as create, flush, shutdown, close, and device control requests .
驱动现在,成就未来
liumaliang
驱动牛犊
驱动牛犊
  • 注册日期2006-07-14
  • 最后登录2010-05-28
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望33点
  • 贡献值0点
  • 好评度31点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-04-08 10:52
为什么是先调用IoCallDriver将IRP往下发送,然后才写到串口呢?
先写到串口然后在往下发送应该才好吧?
   IoCopyCurrentIrpStackLocationToNext(Irp);
  
          ntStatus = IoCallDriver(deviceExtension->NextLowerDeviceObject, Irp);

   //ExAcquireFastMutex(&fastmutex);    
  
   //初始事件
   KeInitializeEvent( &event, NotificationEvent, FALSE);

   ntStatus = CommhookIoSyncWrite(IRP_MJ_WRITE,
                      deviceExtension->TgtDeviceObject,    
                       &event,
                       &iosb,
                         Irp->AssociatedIrp.SystemBuffer,        // input buffer
                       IrpStack->Parameters.DeviceIoControl.OutputBufferLength);   // input buffer length
游客

返回顶部