zdygis
驱动牛犊
驱动牛犊
  • 注册日期2007-10-30
  • 最后登录2008-05-06
  • 粉丝0
  • 关注0
  • 积分120分
  • 威望13点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
阅读:1315回复:2

磁盘过滤驱动读系统盘死锁的问题,那位大侠给看看(有代码)

楼主#
更多 发布于:2008-01-05 10:09
我做了一个简单的磁盘过滤驱动,只是用我自己新创建的Irp替换原来的Irp。读系统盘时死锁,系统起不来,如果把系统盘除外,其他盘可以正常工作。那位大侠给看看:

NTSTATUS
DiorWorkStatusRead(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PDEVICE_EXTENSION  deviceExtension = DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
    PVOID              buffer = NULL;
    ULONG              length = currentIrpStack->Parameters.Read.Length;
    LARGE_INTEGER      byteOffset = currentIrpStack->Parameters.Read.ByteOffset;

    if (deviceExtension->TargetDeviceObject->Flags & DO_BUFFERED_IO) {
     buffer = Irp->AssociatedIrp.SystemBuffer;
    } else if (deviceExtension->TargetDeviceObject->Flags & DO_DIRECT_IO) {
     buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
    } else {
     buffer = Irp->UserBuffer;
    }

   return DiorAsynchronousReadSectors(
             deviceExtension->TargetDeviceObject,
             buffer,    
             length,
             byteOffset,
             Irp);

}

NTSTATUS
DiorAsynchronousReadSectors(
    IN PDEVICE_OBJECT DeviceObject,
    OUT PVOID Buffer,
    IN ULONG Length,
    IN LARGE_INTEGER ByteOffset,
    IN PVOID Context
    )
{
    PIRP                irp;
    IO_STATUS_BLOCK        iosb;

    irp = IoBuildAsynchronousFsdRequest(
        IRP_MJ_READ,
        DeviceObject,
                                           Buffer,
        Length,
        &ByteOffset,
        &iosb);
    
    if (!irp) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    IoSetCompletionRoutine(irp, DiorReadSectorsCompletion,
         Context, TRUE, TRUE, TRUE);
    
    irp->UserIosb = NULL;
    
    return IoCallDriver(DeviceObject, irp);
}

NTSTATUS
DiorReadSectorsCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    )
{
    PMDL     mdl;
    PIRP irp = (PIRP)Context;
    
    UNREFERENCED_PARAMETER(DeviceObject);

    irp->IoStatus.Information = Irp->IoStatus.Information;
    irp->IoStatus.Status = Irp->IoStatus.Status;
    IoCompleteRequest(irp, IO_NO_INCREMENT);

    //
    // Free resources
    //

    if (Irp->AssociatedIrp.SystemBuffer && (Irp->Flags & IRP_DEALLOCATE_BUFFER)) {
        ExFreePool(Irp->AssociatedIrp.SystemBuffer);
    }

    while (Irp->MdlAddress) {
        mdl = Irp->MdlAddress;
        Irp->MdlAddress = mdl->Next;
        MmUnlockPages(mdl);
        IoFreeMdl(mdl);
    }

    IoFreeIrp(Irp);

    //
    // Don't touch irp any more
    //
    return STATUS_MORE_PROCESSING_REQUIRED;

}
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-01-06 23:11
有些处理上的问题,比如分配irp失败,不应该直接返回错误,而应该先IoCompleteRequest,
至于为什么会死锁,可能和return IoCallDriver(DeviceObject, irp);这句代码有关,比如IoCallDriver返回STATUS_PENDING,那么随后的完成例程可能会在其它线程里调用,而对于原始的irp,却没有被调用IoMarkIrpPending,所以该原始irp的完成例程可能无法正确工作。
以上仅是我的猜测。
zdygis
驱动牛犊
驱动牛犊
  • 注册日期2007-10-30
  • 最后登录2008-05-06
  • 粉丝0
  • 关注0
  • 积分120分
  • 威望13点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-01-07 10:08
楼上的,谢了。 问题已经解决了
游客

返回顶部