Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
阅读:1611回复:2

根据Diskperf简化的DiskMon出错,希望不吝赐教!

楼主#
更多 发布于:2002-10-12 11:17
根据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;
}
Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
沙发#
发布于:2002-10-12 12:27
帮帮我吧,各位大佬!
ygwelcome
驱动牛犊
驱动牛犊
  • 注册日期2004-10-10
  • 最后登录2004-10-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-10-13 15:40
帮帮我吧,各位大佬!

读了一下您的代码,应该是IoCallDriver()返回false或是STATUS_PENDING后超时,导致系统缺页错误。
游客

返回顶部