阅读:1611回复:2
根据Diskperf简化的DiskMon出错,希望不吝赐教!
根据Diskperf简化的DiskMon出现
error:0x0000007B 0xF081B84C 0xC0000034 0x00000000 0x00000000 INACCESSIBLE_BOOT_DEVICE(0x7B) 用SoftIce调试出现 error:break due to page fault(0Eh) 我所作的简化仅是不支持多CPU和去掉WMI. 我加入的内容: 在IRP_MJ_READ中IoMarkIrpPending(Irp),用IoBuildAsynchronousFsdRequest 建造一个newirp,将Irp的参数赋给newirp, IoCallDriver(TargetDeviceObject,newirp),完成Irp. 我的错究竟在哪?希望不吝赐教! 操作系统: Win2000 Professional Ver 5.00.2195 Tools: VC6 WIN2000DDK SoftIce4.05 for NT 代码如下: #ifdef __cplusplus extern \"C\" { #endif #define INITGUID #include \"ntddk.h\" #include \"ntdddisk.h\" #include \"stdio.h\" #include <ntddvol.h> #include <mountdev.h> #define DiskMon_MAXSTR 64 // DMFlag #define INITFLAG (0X00000001) typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT TargetDeviceObject; ULONG DMFlag; // DiskMon Flag // Bit0: Initial Flag KEVENT PagingPathCountEvent; ULONG PagingPathCount; UNICODE_STRING PhysicalDeviceName; WCHAR PhysicalDeviceNameBuffer[DiskMon_MAXSTR]; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; // Function Prototype ... #ifdef ALLOC_PRAGMA #pragma alloc_text (INIT, DriverEntry) #pragma alloc_text (PAGE, DiskMonAddDevice) #pragma alloc_text (PAGE, DiskMonDispatchPnp) #pragma alloc_text (PAGE, DiskMonStartDevice) #pragma alloc_text (PAGE, DiskMonRemoveDevice) #pragma alloc_text (PAGE, DiskMonUnload) #pragma alloc_text (PAGE, DiskMonWmi) #pragma alloc_text (PAGE, DiskMonSyncFilterWithTarget) #endif UNICODE_STRING DiskMonRegistryPath; extern \"C\" NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { DiskMonRegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); DiskMonRegistryPath.Buffer = (unsigned short *)ExAllocatePool( PagedPool, DiskMonRegistryPath.MaximumLength); if (DiskMonRegistryPath.Buffer != NULL) { RtlCopyUnicodeString(&DiskMonRegistryPath, RegistryPath); } else { DiskMonRegistryPath.Length = 0; DiskMonRegistryPath.MaximumLength = 0; } ULONG ulIndex; PDRIVER_DISPATCH * dispatch; for (ulIndex = 0, dispatch = DriverObject->MajorFunction; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++, dispatch++) { *dispatch = DiskMonSendToNextDriver; } DriverObject->MajorFunction[IRP_MJ_CREATE] = DiskMonCreate; DriverObject->MajorFunction[IRP_MJ_READ] = DiskMonRead; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DiskMonWmi; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DiskMonShutdownFlush; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DiskMonShutdownFlush; DriverObject->MajorFunction[IRP_MJ_PNP] = DiskMonDispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = DiskMonDispatchPower; DriverObject->DriverExtension->AddDevice = DiskMonAddDevice; DriverObject->DriverUnload = DiskMonUnload; return(STATUS_SUCCESS); } #define FILTER_DEVICE_PROPOGATE_FLAGS 0 #define FILTER_DEVICE_PROPOGATE_CHARACTERISTICS (FILE_REMOVABLE_MEDIA | \\ FILE_READ_ONLY_DEVICE | FILE_FLOPPY_DISKETTE ) VOID DiskMonSyncFilterWithTarget( IN PDEVICE_OBJECT FilterDevice, IN PDEVICE_OBJECT TargetDevice ) { ULONG propFlags; // PAGED_CODE(); propFlags = TargetDevice->Flags & FILTER_DEVICE_PROPOGATE_FLAGS; FilterDevice->Flags |= propFlags; propFlags = TargetDevice->Characteristics & FILTER_DEVICE_PROPOGATE_CHARACTERISTICS; FilterDevice->Characteristics |= propFlags; } NTSTATUS DiskMonAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) { NTSTATUS status; PDEVICE_OBJECT filterDeviceObject; PDEVICE_EXTENSION deviceExtension; // PAGED_CODE(); status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_DISK, 0, FALSE, &filterDeviceObject); if (!NT_SUCCESS(status)) return status; filterDeviceObject->Flags |= DO_DIRECT_IO; deviceExtension = (PDEVICE_EXTENSION) filterDeviceObject->DeviceExtension; RtlZeroMemory(deviceExtension, sizeof(DEVICE_EXTENSION)); deviceExtension->TargetDeviceObject = IoAttachDeviceToDeviceStack(filterDeviceObject, PhysicalDeviceObject); if (deviceExtension->TargetDeviceObject == NULL) { IoDeleteDevice(filterDeviceObject); return STATUS_NO_SUCH_DEVICE; } deviceExtension->DeviceObject = filterDeviceObject; deviceExtension->PhysicalDeviceName.Buffer = deviceExtension->PhysicalDeviceNameBuffer; KeInitializeEvent(&deviceExtension->PagingPathCountEvent, NotificationEvent, TRUE); filterDeviceObject->Flags |= DO_POWER_PAGABLE; filterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; } NTSTATUS DiskMonDispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status; PDEVICE_EXTENSION deviceExtension; // PAGED_CODE(); deviceExtension = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension; switch(irpSp->MinorFunction) { case IRP_MN_START_DEVICE: status = DiskMonStartDevice(DeviceObject, Irp); break; case IRP_MN_REMOVE_DEVICE: status = DiskMonRemoveDevice(DeviceObject, Irp); break; case IRP_MN_DEVICE_USAGE_NOTIFICATION: PIO_STACK_LOCATION irpStack; ULONG count; BOOLEAN setPagable; irpStack = IoGetCurrentIrpStackLocation(Irp); if (irpStack->Parameters.UsageNotification.Type != DeviceUsageTypePaging) { status = DiskMonSendToNextDriver(DeviceObject, Irp); break; } status = KeWaitForSingleObject(&deviceExtension->PagingPathCountEvent, Executive, KernelMode, FALSE, NULL); setPagable = FALSE; if (!irpStack->Parameters.UsageNotification.InPath && deviceExtension->PagingPathCount == 1 ) { if (!(DeviceObject->Flags & DO_POWER_INRUSH)) { DeviceObject->Flags |= DO_POWER_PAGABLE; setPagable = TRUE; } } status = DiskMonForwardIrpSynchronous(DeviceObject, Irp); if (NT_SUCCESS(status)) { IoAdjustPagingPathCount( (long *)&deviceExtension->PagingPathCount, irpStack->Parameters.UsageNotification.InPath); if (irpStack->Parameters.UsageNotification.InPath) { if (deviceExtension->PagingPathCount == 1) { DeviceObject->Flags &= ~DO_POWER_PAGABLE; } } } else { if (setPagable == TRUE) { DeviceObject->Flags &= ~DO_POWER_PAGABLE; setPagable = FALSE; } } KeSetEvent(&deviceExtension->PagingPathCountEvent, IO_NO_INCREMENT, FALSE); IoCompleteRequest(Irp, IO_NO_INCREMENT); break; default: return DiskMonSendToNextDriver(DeviceObject, Irp); } return status; } NTSTATUS DiskMonIrpCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PKEVENT Event = (PKEVENT) Context; UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Irp); KeSetEvent(Event, IO_NO_INCREMENT, FALSE); return(STATUS_MORE_PROCESSING_REQUIRED); } NTSTATUS DiskMonStartDevice( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; // PAGED_CODE(); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; status = DiskMonForwardIrpSynchronous(DeviceObject, Irp); DiskMonSyncFilterWithTarget(DeviceObject,deviceExtension->TargetDeviceObject); DiskMonRegisterDevice(DeviceObject); Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DiskMonRemoveDevice( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { // NTSTATUS status; PDEVICE_EXTENSION deviceExtension; // PAGED_CODE(); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; // The following sentence maybe be no required, // and maybe be error indeed! // status = DiskMonForwardIrpSynchronous(DeviceObject, Irp); IoDetachDevice(deviceExtension->TargetDeviceObject); IoDeleteDevice(DeviceObject); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DiskMonSendToNextDriver( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; IoSkipCurrentIrpStackLocation(Irp); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; return IoCallDriver(deviceExtension->TargetDeviceObject, Irp); } NTSTATUS DiskMonDispatchPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; return PoCallDriver(deviceExtension->TargetDeviceObject, Irp); } NTSTATUS DiskMonForwardIrpSynchronous( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; KEVENT event; NTSTATUS status; KeInitializeEvent(&event, NotificationEvent, FALSE); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, DiskMonIrpCompletion, &event, TRUE, TRUE, TRUE); status = IoCallDriver(deviceExtension->TargetDeviceObject, Irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = Irp->IoStatus.Status; } return status; } NTSTATUS DiskMonCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { UNREFERENCED_PARAMETER(DeviceObject); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DiskMonRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; PIO_STACK_LOCATION curIrpStack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp); if( ((deviceExtension->DMFlag & INITFLAG)!=INITFLAG) ) { return DiskMonSendToNextDriver(DeviceObject, Irp); } IoMarkIrpPending(Irp); IO_STATUS_BLOCK ioStatus; PIRP pIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, deviceExtension->TargetDeviceObject, MmGetSystemAddressForMdlSafe(Irp->MdlAddress,HighPagePriority), curIrpStack->Parameters.Read.Length, &curIrpStack->Parameters.Read.ByteOffset, &ioStatus ); if (pIrp == NULL) return STATUS_INSUFFICIENT_RESOURCES ; IoSetCompletionRoutine(pIrp, (PIO_COMPLETION_ROUTINE)DiskMonIoCompletion, NULL, TRUE, TRUE, TRUE); IoCallDriver(deviceExtension->TargetDeviceObject,pIrp); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_DISK_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DiskMonIoCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { if(Irp->MdlAddress !=NULL) { IoFreeMdl(Irp->MdlAddress); } IoFreeIrp(Irp); return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS DiskMonWmi( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { IoSkipCurrentIrpStackLocation(Irp); PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; return IoCallDriver(deviceExtension->TargetDeviceObject, Irp); } NTSTATUS DiskMonShutdownFlush( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension; Irp->CurrentLocation++, Irp->Tail.Overlay.CurrentStackLocation++; return IoCallDriver(deviceExtension->TargetDeviceObject, Irp); } VOID DiskMonUnload( IN PDRIVER_OBJECT DriverObject ) { // PAGED_CODE(); ExFreePool(DiskMonRegistryPath.Buffer); } NTSTATUS DiskMonRegisterDevice( IN PDEVICE_OBJECT DeviceObject ) { NTSTATUS status; IO_STATUS_BLOCK ioStatus; KEVENT event; PDEVICE_EXTENSION deviceExtension; PIRP irp; STORAGE_DEVICE_NUMBER number; ULONG registrationFlag = 0; // PAGED_CODE(); deviceExtension = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension; KeInitializeEvent(&event, NotificationEvent, FALSE); irp = IoBuildDeviceIoControlRequest( IOCTL_STORAGE_GET_DEVICE_NUMBER, deviceExtension->TargetDeviceObject, NULL, 0, &number, sizeof(number), FALSE, &event, &ioStatus); if (!irp) { // error return STATUS_INSUFFICIENT_RESOURCES; } status = IoCallDriver(deviceExtension->TargetDeviceObject, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = ioStatus.Status; } if (NT_SUCCESS(status)) { swprintf( deviceExtension->PhysicalDeviceNameBuffer, L\"\\\\Device\\\\Harddisk%d\\\\Partition%d\", number.DeviceNumber, number.PartitionNumber); RtlInitUnicodeString( &deviceExtension->PhysicalDeviceName, &deviceExtension->PhysicalDeviceNameBuffer[0]); } else { ULONG outputSize = sizeof(MOUNTDEV_NAME); PMOUNTDEV_NAME output; VOLUME_NUMBER volumeNumber; output = (PMOUNTDEV_NAME)ExAllocatePool(PagedPool, outputSize); if (!output) { //error return STATUS_INSUFFICIENT_RESOURCES; } KeInitializeEvent(&event, NotificationEvent, FALSE); irp = IoBuildDeviceIoControlRequest( IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, deviceExtension->TargetDeviceObject, NULL, 0, output, outputSize, FALSE, &event, &ioStatus); if (!irp) { ExFreePool(output); return STATUS_INSUFFICIENT_RESOURCES; } status = IoCallDriver(deviceExtension->TargetDeviceObject, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = ioStatus.Status; } if (status == STATUS_BUFFER_OVERFLOW) { outputSize = sizeof(MOUNTDEV_NAME) + output->NameLength; ExFreePool(output); output = (PMOUNTDEV_NAME)ExAllocatePool(PagedPool, outputSize); if (!output) { // error return STATUS_INSUFFICIENT_RESOURCES; } KeInitializeEvent(&event, NotificationEvent, FALSE); irp = IoBuildDeviceIoControlRequest( IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, deviceExtension->TargetDeviceObject, NULL, 0, output, outputSize, FALSE, &event, &ioStatus); if (!irp) { ExFreePool(output); // error return STATUS_INSUFFICIENT_RESOURCES; } status = IoCallDriver(deviceExtension->TargetDeviceObject, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL ); status = ioStatus.Status; } } if (!NT_SUCCESS(status)) { ExFreePool(output); return status; } deviceExtension->PhysicalDeviceName.Length = output->NameLength; deviceExtension->PhysicalDeviceName.MaximumLength = output->NameLength + sizeof(WCHAR); RtlCopyMemory( deviceExtension->PhysicalDeviceName.Buffer, output->Name, output->NameLength); deviceExtension->PhysicalDeviceName.Buffer [deviceExtension->PhysicalDeviceName.Length/sizeof(WCHAR)] = 0; ExFreePool(output); outputSize = sizeof(VOLUME_NUMBER); RtlZeroMemory(&volumeNumber, sizeof(VOLUME_NUMBER)); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = IoBuildDeviceIoControlRequest( IOCTL_VOLUME_QUERY_VOLUME_NUMBER, deviceExtension->TargetDeviceObject, NULL, 0, &volumeNumber, sizeof(VOLUME_NUMBER), FALSE, &event, &ioStatus); if (!irp) { // error return STATUS_INSUFFICIENT_RESOURCES; } status = IoCallDriver(deviceExtension->TargetDeviceObject, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = ioStatus.Status; } } deviceExtension->DMFlag |= INITFLAG; return status; } |
|
沙发#
发布于:2002-10-12 12:27
帮帮我吧,各位大佬!
|
|
板凳#
发布于:2004-10-13 15:40
帮帮我吧,各位大佬! 读了一下您的代码,应该是IoCallDriver()返回false或是STATUS_PENDING后超时,导致系统缺页错误。 |
|