阅读:2918回复:14
关于DISKPERF中直接读写磁盘
我想在DISKPERF中读写磁盘,比如在IRP_MJ_READ中读写磁盘的物理扇区呢??大家给我一个提示吧.谢谢.......................
为这个问题想了好多天了... |
|
沙发#
发布于:2007-07-07 11:29
那位老大进来帮我一下吧.我搜完了这里的贴子.也没有发现解决方法..谢谢
|
|
板凳#
发布于:2007-07-07 12:52
有那么难吗?你需要提示什么?读写?
|
|
|
地板#
发布于:2007-07-08 01:07
运行一会就蓝了
NTSTATUSDiskPerfReadWrite( 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;返回这里有点不对.. 或者说其它地方..请指点一下.谢谢 |
|
地下室#
发布于: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; } 请高手帮我看一下那里不对..谢谢.....搞了一个晚上了....累死我了... |
|
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值写出来,代码好乱,看得我头都晕了 |
|
|
6楼#
发布于:2007-07-09 17:47
//这里是有问题的,不能填0啊,如果你正确读写到了数据,Information那里,
//应该是读写到的数据量. Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; |
|
|
7楼#
发布于:2007-07-09 19:55
哦..好的..我马上整理一下,弄一个出来.谢谢
|
|
8楼#
发布于:2007-07-09 20:37
F9D90DCC
Status是:F9D90DCC |
|
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); 就不动了..这段代码是抄的别人的,他说是可以读逻辑盘的..我不明白在这里有什么分别.高手指点一条路呀...谢谢 |
|
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; } |
|
11楼#
发布于:2007-07-10 16:11
tooflat ,,我应该怎么说你呢....5555555555,,我想不到..还是简单点吧......
谢谢你..非常谢谢你...我一会回家试一下.... 谢谢...... |
|
12楼#
发布于:2007-07-10 19:48
谢谢.....
|
|
13楼#
发布于:2007-07-13 18:25
,光谢Tooflat? 那下次你就只找Tooflat帮忙好了! ......我越来越像小孩子了......唉!
|
|
|
14楼#
发布于:2007-07-14 15:57
呵..也多谢proplayboy
再请问一下..在DISKPERF中,我怎么分得清那些扇区或者说簇被占用了呢? |
|