DontKissBossAss
驱动牛犊
驱动牛犊
  • 注册日期2011-12-06
  • 最后登录2012-12-24
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望21点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1629回复:2

求助关于完成挂起的IRP蓝屏问题, 跟了一天啦。

楼主#
更多 发布于:2012-01-11 22:58
我要在应用层开buffer供内核使用。当采集数据时,应用层开辟足够的空间,然后传递给内核,驱动程序挂起该IRP。
当停止采集时,内核关闭挂起IRP(开始采集时的IRP)时,程序崩溃。
 
错误的原因是 IRQL LESS THAN OR EQUAL  
给我的感觉是 挂起的IRP在分页内存中,我也粗略的检查了引入的buffer在崩溃1处,没有消除。
(如代码所示,经过各种测试,有3种情况会发生上述错误。)
 
代码如下
NTSTATUS
SfDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
    switch( ioControlCode)
    {
        //...该IRP仅仅传递来了一个BUFFER,供内核输出。
        case IOCTL_DRIVER_REF_BUFFER:
            Irp->IoStatus.Status = STATUS_PENDING;
            Irp->IoStatus.Information = 0;
            
            IoMarkIrpPending(Irp);
            IoSetCancelRoutine(Irp, OnCancelIrp);
 
            deviceExtension->rbBufferIrp = Irp;
            return STATUS_PENDING;
...
        //buffer使用完成后,完成挂起的rbBufferIrp,其他问题不会处理rbBufferIrp
        //应用程序也不会主动cancelIO
        case IOCTL_DRIVER_DEREF_BUFFER:
            Irp->IoStatus.Status = STATUS_CANCELLED;
            Irp->IoStatus.Information = 0;
            IoCompleteRequest(Irp,IO_NO_INCREMENT);    // 1: [backcolor=#ff0000][color=#000000]蓝屏,IRQL NOT LESS THAN OR EQUAL 
[/color][/backcolor]            break;
        default:
           //.....
           break
     }
    //......
    IoCompleteRequest(Irp,IO_NO_INCREMENT);
}
OnCancelIrp(PDEVICE_OBJECT DeviceObject, PIRP pirp)
{
    PDEVICE_EXTENSION deviceExtension = ;
    deviceExtension = (PDEVICE_EXTENSION)
    DeviceObject->DeviceExtension;
    IoReleaseCancelSpinLock(Irp->CancelIrql);  // 2: [backcolor=#ff0000]强制结束进程时,调用此处也蓝屏。同1是一样的错误[/backcolor]
    if( Irp==deviceExtension->UserMessageIrp)
    {
        deviceExtension->UserMessageIrp = NULL;
    }
    Irp->IoStatus.Status = STATUS_CANCELLED;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp,IO_NO_INCREMENT); //3: 注释2,[backcolor=#ff0000]强制结束进程时,调用此处也蓝屏。同1是一样的错误[/backcolor]
}
jzxsasch@126.co
驱动牛犊
驱动牛犊
  • 注册日期2011-07-08
  • 最后登录2012-01-18
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望171点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2012-01-17 23:18
// 1:请求到来要么完成IRP 要么悬挂IRP STATUS_CANCELLED实在异步取消时才能设置
if(irp == device->CurrentIrp)
    {
        KIRQL oldirql = irp -> CancelIrql;
        IoReleaseCancelSpinLock(irp->CancelIrql);
        KeLowerIrql(oldirql);        
    }else
    {
        
        IoReleaseCancelSpinLock(irp->CancelIrql);
    }
jzxsasch@126.co
驱动牛犊
驱动牛犊
  • 注册日期2011-07-08
  • 最后登录2012-01-18
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望171点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2012-01-18 20:33
2 3 先要以取消的方式完成IRP 之后再释放自旋锁
游客

返回顶部