sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
阅读:2918回复:14

关于DISKPERF中直接读写磁盘

楼主#
更多 发布于:2007-07-06 11:37
我想在DISKPERF中读写磁盘,比如在IRP_MJ_READ中读写磁盘的物理扇区呢??大家给我一个提示吧.谢谢.......................

为这个问题想了好多天了...


sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-07-07 11:29
那位老大进来帮我一下吧.我搜完了这里的贴子.也没有发现解决方法..谢谢
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2007-07-07 12:52
有那么难吗?你需要提示什么?读写?
人不靓仔心灵美,版头不正红花仔!
sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-07-08 01:07
运行一会就蓝了
NTSTATUS
DiskPerfReadWrite(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
/////////省略系统的
    if(currentIrpStack->MajorFunction == IRP_MJ_READ)
    {
        systembuffer= (PUCHAR) MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
        //ExAllocatePool( NonPagedPoolCacheAligned, currentIrpStack->Parameters.Read.Length );
        if(systembuffer==NULL)
        {
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = IO_NO_INCREMENT;
IoCompleteRequest(
                Irp,
                 IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
        }
        if(!ReadDiskSector(deviceExtension->TargetDeviceObject,
            currentIrpStack->MajorFunction,
            currentIrpStack->Parameters.Read.ByteOffset,
            currentIrpStack->Parameters.Read.Length,
            systembuffer))
        {
Irp->IoStatus.Information = 0;
            Irp->IoStatus.Status = IO_NO_INCREMENT;
IoCompleteRequest(
                Irp,
                 IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
        }

    

        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = STATUS_SUCCESS;
        
        IoCompleteRequest(Irp,IO_DISK_INCREMENT);
        return STATUS_SUCCESS;
    }
IoSetCompletionRoutine(Irp,
                           DiskPerfIoCompletion,
                           DeviceObject,
                           TRUE,
                           TRUE,
                           TRUE);

    //
    // Return the results of the call to the disk driver.
    //

    return IoCallDriver(deviceExtension->TargetDeviceObject,
                        Irp);
}

///////////////////////////////////////////ReadDiskSector
BOOLEAN
ReadDiskSector (
  IN PDEVICE_OBJECT pDeviceObject,
  IN ULONG   MajorFunction,
  IN LARGE_INTEGER startingOffset,
  IN ULONG m_length,
  IN UCHAR * Buffer ) // must be DEVICE_LOGICAL_BLOCKSIZE = 512 bytes long.
  {  
  PIRP irp;
  IO_STATUS_BLOCK ioStatus;
  KEVENT event;
  NTSTATUS status;
  
  PUCHAR mbr;

  PAGED_CODE();

  //创建一个用于检查是否完成通知事件对象
  KeInitializeEvent( &event, NotificationEvent, FALSE );
  // 分配内存.
  mbr = ExAllocatePool( NonPagedPoolCacheAligned, m_length );
  if ( !mbr ) {
    return FALSE;
  }
  // 创建读MBR的IRP
  irp = IoBuildSynchronousFsdRequest( MajorFunction,
                          pDeviceObject,
                          mbr,
                          m_length,
                          &startingOffset,
                          &event,
                          &ioStatus );
  if ( irp == NULL ) {
    ExFreePool( mbr );
    return FALSE;
  }
  
  // 把IRP传送给端口驱动程序
  status = IoCallDriver( pDeviceObject, irp );
  
  if ( status == STATUS_PENDING ) {
    KeWaitForSingleObject( &event,
                    //Executive,
                    Suspended,
                    KernelMode,
                    FALSE,
                    NULL);
    status = ioStatus.Status;
  }
  if ( !NT_SUCCESS( status ) ) {
    ExFreePool( mbr );
    return FALSE;
  }
  // 返回读取的扇区信息
  RtlCopyMemory( Buffer, mbr, m_length );
  ExFreePool( mbr );
  return TRUE;
}

代码就是这样的,读取磁盘的函数是我找的别人的.可是总是运行一会就死了,每次都在重新启动后到桌面时....蓝屏后的错误号为:0x000000f4
麻烦ProPlayboy
帮我看一下,是不是我Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = STATUS_SUCCESS;
        
        IoCompleteRequest(Irp,IO_DISK_INCREMENT);
        return STATUS_SUCCESS;返回这里有点不对..
或者说其它地方..请指点一下.谢谢
sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-07-08 02:24
BOOLEAN
ReadDiskSector (
  IN PDEVICE_OBJECT pDeviceObject,
  IN ULONG   MajorFunction,
  IN LARGE_INTEGER startingOffset,
  IN ULONG m_length,
  IN UCHAR * Buffer )
  {  
  PIRP irp;
  IO_STATUS_BLOCK ioStatus;
  KEVENT event;
  NTSTATUS status;
  
  PUCHAR mbr;

  PAGED_CODE();

  //创建一个用于检查是否完成通知事件对象
  KeInitializeEvent( &event, NotificationEvent, FALSE );

  // 分配内存.
  mbr = ExAllocatePool( NonPagedPoolCacheAligned, m_length );
  if (mbr==NULL) {
DbgPrint("ExAllocatePool == NULL %d !\r\n",m_length);
    return FALSE;
  }
  // 创建读MBR的IRP
  irp = IoBuildSynchronousFsdRequest( MajorFunction,
                          pDeviceObject,
                          mbr,
                          m_length,
                          &startingOffset,
                          &event,
                          &ioStatus );
  if ( irp == NULL ) {
      DbgPrint("irp == NULL !\r\n");
    ExFreePool( mbr );
    return FALSE;
  }///设置处理
  IoSetCompletionRoutine(
               irp,
               SfReadWriteCompletion,
               &event,
               TRUE,
               TRUE,
               TRUE );
  // 把IRP传送给端口驱动程序
  status = IoCallDriver( pDeviceObject, irp );
  
  if ( status == STATUS_PENDING ) {
      DbgPrint("STATUS_PENDING !\r\n");
    KeWaitForSingleObject( &event,
                    Executive,
                   // Suspended,
                    KernelMode,
                    FALSE,
                    NULL);
    status = ioStatus.Status;
  }
  if ( !NT_SUCCESS( status ) ) {
      ///每次都从这里退出了.也就是上面没有成功吧
    ExFreePool( mbr );
    return FALSE;
  }
  // 返回读取的扇区信息
  DbgPrint("copy buffer!\r\n");
  RtlCopyMemory( Buffer, mbr, m_length );
  ExFreePool( mbr );
  return TRUE;
}

NTSTATUS
SfReadWriteCompletion (IN PDEVICE_OBJECT DeviceObject,
                    IN PIRP Irp,
                    IN PVOID Context
                    )
{
    PKEVENT event = Context;
    
    PIO_STACK_LOCATION     irpSp = IoGetCurrentIrpStackLocation(Irp);
    UNREFERENCED_PARAMETER( DeviceObject );
    UNREFERENCED_PARAMETER( Irp );
    
    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
if (Irp->PendingReturned)
    KeSetEvent(event, IO_NO_INCREMENT, FALSE);
    
    return STATUS_MORE_PROCESSING_REQUIRED;
}

请高手帮我看一下那里不对..谢谢.....搞了一个晚上了....累死我了...
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2007-07-09 17:37
if ( status == STATUS_PENDING ) {
     DbgPrint("STATUS_PENDING !\r\n");
    KeWaitForSingleObject( &event,
                    Executive,
                  // Suspended,
                    KernelMode,
                    FALSE,
                    NULL);
    status = ioStatus.Status;
  }
  if ( !NT_SUCCESS( status ) ) {
     ///每次都从这里退出了.也就是上面没有成功吧
    ExFreePool( mbr );
    return FALSE;
  }

把你的Status值写出来,把你的Status值写出来,代码好乱,看得我头都晕了
人不靓仔心灵美,版头不正红花仔!
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2007-07-09 17:47
        //这里是有问题的,不能填0啊,如果你正确读写到了数据,Information那里,
    //应该是读写到的数据量.
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = STATUS_SUCCESS;
人不靓仔心灵美,版头不正红花仔!
sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-07-09 19:55
哦..好的..我马上整理一下,弄一个出来.谢谢
sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-07-09 20:37
F9D90DCC


Status是:F9D90DCC
sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-07-09 23:08
BOOLEAN
ReadDiskSector (
                IN PDEVICE_OBJECT pDeviceObject,
                IN ULONG   MajorFunction,
                IN LARGE_INTEGER startingOffset,
                IN ULONG m_length,
                OUT UCHAR * Buffer ) // must be DEVICE_LOGICAL_BLOCKSIZE = 512 bytes long.
{  
    PIRP m_irp;
    IO_STATUS_BLOCK ioStatus;
    KEVENT event;
    NTSTATUS status;
    
    PUCHAR mbr;
    
    PAGED_CODE();
    
    //创建一个用于检查是否完成通知事件对象
    KeInitializeEvent( &event, NotificationEvent, FALSE );
    
    // 分配内存.
    mbr = ExAllocatePool( NonPagedPoolCacheAligned, m_length );
    if (mbr==NULL) {
        DbgPrint("ExAllocatePool == NULL %d !\r\n",m_length);
        return FALSE;
    }
    // 创建读的IRP
    m_irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
        pDeviceObject,
        mbr,
        m_length,
        &startingOffset,
        &event,
        &ioStatus );
    if ( m_irp == NULL )
    {
        DbgPrint("irp == NULL !\r\n");
        ExFreePool( mbr );
        return FALSE;
    }
    status = IoCallDriver( pDeviceObject, m_irp );
    
    if ( status == STATUS_PENDING ) {
        DbgPrint("STATUS_PENDING !\r\n");
        KeWaitForSingleObject( &event,
        //    Executive,
             Suspended,
            KernelMode,
            FALSE,
            NULL);/////大约十多次吧,就在这里不向下运行了
        status = ioStatus.Status;
    }
    if ( !NT_SUCCESS( status ) ) {
                ExFreePool( mbr );
        return FALSE;
    }
    // 返回读取的扇区信息
    RtlCopyMemory( Buffer, mbr, m_length );
    ExFreePool( mbr );
    return TRUE;
}
我弄成这样的.结果可以读到大约十多个左右.然后就不行了..就一动也不动了, 我调试时发现.是在KeWaitForSingleObject( &event,
        //    Executive,
             Suspended,
            KernelMode,
            FALSE,
            NULL);
就不动了..这段代码是抄的别人的,他说是可以读逻辑盘的..我不明白在这里有什么分别.高手指点一条路呀...谢谢
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-07-10 14:30
不要使用IoBuildSynchronousFsdRequest!!!!!!原因参考DDK的说明。


NTSTATUS
FltReadSectors(
    IN PDEVICE_OBJECT DeviceObject,
    OUT PVOID Buffer,
    IN ULONG Length,
    IN LONGLONG ByteOffset,
    IN BOOLEAN Wait
    )
/*++

Routine Description:

    This routine tries to read the data from the disk.

Arguments:

    DeviceObject - the lower device in the stack
    Buffer       - the buffer which hold the data
    Length       - the data length want to read
    ByteOffset   - the data offset on the disk
        
Return Value:

    NT Status is returned.

--*/
{
    PIRP                irp;
    IO_STATUS_BLOCK        iosb;
    KEVENT                event;
    NTSTATUS            status;

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

    if (Wait) {
        KeInitializeEvent(&event, NotificationEvent, FALSE);
        IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
            &event, TRUE, TRUE, TRUE);

        status = IoCallDriver(DeviceObject, irp);
        if (STATUS_PENDING == status) {
            KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
            status = iosb.Status;
        }
    } else {
        IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
            NULL, TRUE, TRUE, TRUE);
        irp->UserIosb = NULL;
        status = IoCallDriver(DeviceObject, irp);
    }

    return status;
}

NTSTATUS
FltWriteSectors(
    IN PDEVICE_OBJECT DeviceObject,
    IN PVOID Buffer,
    IN ULONG Length,
    IN LONGLONG ByteOffset,
    IN BOOLEAN Wait
    )
/*++

Routine Description:

    This routine tries to write the data to the disk.

Arguments:

    DeviceObject - the lower device in the stack
    Buffer       - the buffer which hold the data
    Length       - the data length want to read
    ByteOffset   - the data offset on the disk
        
Return Value:

    NT Status is returned.

--*/
{
    PIRP                irp;
    IO_STATUS_BLOCK        iosb;
    KEVENT                event;
    NTSTATUS            status;

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

    if (Wait) {
        KeInitializeEvent(&event, NotificationEvent, FALSE);
        IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
            &event, TRUE, TRUE, TRUE);

        status = IoCallDriver(DeviceObject, irp);
        if (STATUS_PENDING == status) {
            KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
            status = iosb.Status;
        }
    } else {
        IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
            NULL, TRUE, TRUE, TRUE);
        irp->UserIosb = NULL;
        status = IoCallDriver(DeviceObject, irp);
    }

    return status;
}

NTSTATUS
FltReadWriteSectorsCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    )
/*++
Routine Description:
    A completion routine for use when calling the lower device objects to
    which our filter deviceobject is attached.

Arguments:

    DeviceObject - Pointer to deviceobject
    Irp          - Pointer to a PnP Irp.
    Context      - NULL or PKEVENT
Return Value:

    NT Status is returned.

--*/
{
    PMDL     mdl;
    
    UNREFERENCED_PARAMETER(DeviceObject);

    //
    // 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);
    }

    if (Irp->PendingReturned && (Context != NULL)) {
        *Irp->UserIosb = Irp->IoStatus;
        KeSetEvent((PKEVENT) Context, IO_DISK_INCREMENT, FALSE);
    }

    IoFreeIrp(Irp);

    //
    // Don't touch irp any more
    //
    return STATUS_MORE_PROCESSING_REQUIRED;
}
sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-07-10 16:11
tooflat ,,我应该怎么说你呢....5555555555,,我想不到..还是简单点吧......

谢谢你..非常谢谢你...我一会回家试一下....

谢谢......
sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-07-10 19:48
谢谢.....
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
13楼#
发布于:2007-07-13 18:25
,光谢Tooflat? 那下次你就只找Tooflat帮忙好了! ......我越来越像小孩子了......唉!
人不靓仔心灵美,版头不正红花仔!
sc_wolf
驱动小牛
驱动小牛
  • 注册日期2006-09-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望278点
  • 贡献值1点
  • 好评度150点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2007-07-14 15:57
呵..也多谢proplayboy

再请问一下..在DISKPERF中,我怎么分得清那些扇区或者说簇被占用了呢?
游客

返回顶部