DiskPerf代码解读

来源:互联网 发布:sql select 不等于 编辑:程序博客网 时间:2024/05/21 20:26

水平有限,欢迎大家多批评。有什么意见请跟贴,我尽量回复,谢谢大家。 

Diskperf代码分析 



/*++ 
Copyright (C) Microsoft Corporation, 1991 - 1999 

Module Name: 

    diskperf.c 

Abstract: 

    This driver monitors disk accesses capturing performance data. 

Environment: 

    kernel mode only 

Notes: 

--*/ 


#define INITGUID 

#include "ntddk.h" 
#include "ntdddisk.h" 
#include "stdarg.h" 
#include "stdio.h" 
#include <ntddvol.h> 

#include <mountdev.h> 
#include "wmistr.h" 
#include "wmidata.h" 
#include "wmiguid.h" 
#include "wmilib.h" 

#include "ntstrsafe.h" 

// 下面这个宏用来把ExAllocatePool替换成ExAllocatePoolWithTag,MS的文档中推荐用后 
// 者,以便调试,所以做了这个替换 
#ifdef POOL_TAGGING 
#ifdef ExAllocatePool 
#undef ExAllocatePool 
#endif 
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'frPD') 
#endif 

#define DISKPERF_MAXSTR        64 

// 
// Device Extension 
// 

typedef struct _DEVICE_EXTENSION { 

    // 
    // Back pointer to device object 
    // 

    PDEVICE_OBJECT DeviceObject; 

    // 
    // 目标设备对象 
    // 

    PDEVICE_OBJECT TargetDeviceObject; 

    // 
    // 物理设备对象 
    // 
    PDEVICE_OBJECT PhysicalDeviceObject; 

    // 
    // Disk number for reference in WMI 
    // 

    ULONG      DiskNumber; 

    // 
    // If device is enabled for counting always 
    // 

    LONG        EnabledAlways; 

    // 
    // Use to keep track of Volume info from ntddvol.h 
    // 

    WCHAR StorageManagerName[8]; 

    // 
    // Disk performance counters 
    // and locals used to compute counters 
    // 

    ULONG  Processors; 
    PDISK_PERFORMANCE DiskCounters;    // per processor counters 
    LARGE_INTEGER LastIdleClock; 
    LONG QueueDepth; 
    LONG CountersEnabled; 

    // 
    // 同步分页路径通知用 
    // 
    KEVENT PagingPathCountEvent; 
    LONG  PagingPathCount; 

    // 
    //  物理设备名或者WMI 实例名字 
    // 

    UNICODE_STRING PhysicalDeviceName; 
    WCHAR PhysicalDeviceNameBuffer[DISKPERF_MAXSTR]; 

    // 
    // Private context for using WmiLib 
    // 
    WMILIB_CONTEXT WmilibContext; 

} DEVICE_EXTENSION, *PDEVICE_EXTENSION; 

#define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION) 
#define PROCESSOR_COUNTERS_SIZE FIELD_OFFSET(DISK_PERFORMANCE, QueryTime) 

/* 
每个处理器的计数器的布局,是一个连续的内存块: 

    处理器1 
+-----------------------+    +-----------------------+ 
|PROCESSOR_COUNTERS_SIZE| ... |PROCESSOR_COUNTERS_SIZE| 
+-----------------------+    +-----------------------+ 
这里PROCESSOR_COUNTERS_SIZE比DISK_PERFORMANCE的尺寸要小,因为我们只统计实际使用的。 
*/ 

UNICODE_STRING DiskPerfRegistryPath; 



// 
// 函数定义 
// 

DRIVER_INITIALIZE DriverEntry; 

DRIVER_ADD_DEVICE DiskPerfAddDevice; 

DRIVER_DISPATCH DiskPerfForwardIrpSynchronous; 

__drv_dispatchType(IRP_MJ_PNP) 
DRIVER_DISPATCH DiskPerfDispatchPnp; 

__drv_dispatchType(IRP_MJ_POWER) 
DRIVER_DISPATCH DiskPerfDispatchPower; 

DRIVER_DISPATCH DiskPerfSendToNextDriver; 

__drv_dispatchType(IRP_MJ_CREATE) 
DRIVER_DISPATCH DiskPerfCreate; 

__drv_dispatchType(IRP_MJ_READ) 
__drv_dispatchType(IRP_MJ_WRITE) 
DRIVER_DISPATCH DiskPerfReadWrite; 

__drv_dispatchType(IRP_MJ_DEVICE_CONTROL) 
DRIVER_DISPATCH DiskPerfDeviceControl; 

__drv_dispatchType(IRP_MJ_SYSTEM_CONTROL) 
DRIVER_DISPATCH DiskPerfWmi; 

__drv_dispatchType(IRP_MJ_FLUSH_BUFFERS) 
__drv_dispatchType(IRP_MJ_SHUTDOWN) 
DRIVER_DISPATCH DiskPerfShutdownFlush; 

DRIVER_DISPATCH DiskPerfStartDevice; 
DRIVER_DISPATCH DiskPerfRemoveDevice; 

IO_COMPLETION_ROUTINE DiskPerfIoCompletion; 
IO_COMPLETION_ROUTINE DiskPerfIrpCompletion; 

DRIVER_UNLOAD DiskPerfUnload; 


VOID 
DiskPerfLogError( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN ULONG UniqueId, 
    IN NTSTATUS ErrorCode, 
    IN NTSTATUS Status 
    ); 

NTSTATUS 
DiskPerfRegisterDevice( 
    IN PDEVICE_OBJECT DeviceObject 
    ); 

WMI_QUERY_REGINFO_CALLBACK DiskperfQueryWmiRegInfo; 

WMI_QUERY_DATABLOCK_CALLBACK DiskperfQueryWmiDataBlock; 

VOID 
DiskPerfSyncFilterWithTarget( 
    IN PDEVICE_OBJECT FilterDevice, 
    IN PDEVICE_OBJECT TargetDevice 
    ); 

WMI_FUNCTION_CONTROL_CALLBACK DiskperfWmiFunctionControl; 

VOID 
DiskPerfAddCounters( 
    IN OUT PDISK_PERFORMANCE TotalCounters, 
    IN PDISK_PERFORMANCE NewCounters, 
    IN LARGE_INTEGER Frequency 
    ); 

#if DBG 

ULONG DiskPerfDebug = 0; 

VOID 
DiskPerfDebugPrint( 
    ULONG DebugPrintLevel, 
    PCCHAR DebugMessage, 
    ... 
    ); 

#define DebugPrint(x)  DiskPerfDebugPrint x 

#else 

#define DebugPrint(x) 

#endif 

// 
// 下面的宏定义用来优化编译器,取消一些无关代码(比如分页代码)。 
// 
// 

#ifdef ALLOC_PRAGMA 
#pragma alloc_text (INIT, DriverEntry) 
#pragma alloc_text (PAGE, DiskPerfCreate) 
#pragma alloc_text (PAGE, DiskPerfAddDevice) 
#pragma alloc_text (PAGE, DiskPerfDispatchPnp) 
#pragma alloc_text (PAGE, DiskPerfStartDevice) 
#pragma alloc_text (PAGE, DiskPerfRemoveDevice) 
#pragma alloc_text (PAGE, DiskPerfUnload) 
#pragma alloc_text (PAGE, DiskPerfWmi) 
#pragma alloc_text (PAGE, DiskperfQueryWmiRegInfo) 
#pragma alloc_text (PAGE, DiskperfQueryWmiDataBlock) 
#pragma alloc_text (PAGE, DiskPerfRegisterDevice) 
#pragma alloc_text (PAGE, DiskPerfSyncFilterWithTarget) 
#endif 

WMIGUIDREGINFO DiskperfGuidList[] = 

    { &DiskPerfGuid, 
      1, 
      0 
    } 
}; 

#define DiskperfGuidCount (sizeof(DiskperfGuidList) / sizeof(WMIGUIDREGINFO)) 

#define USE_PERF_CTR 

#ifdef USE_PERF_CTR 
#define DiskPerfGetClock(a, b) (a) = KeQueryPerformanceCounter((b)) 
#else 
#define DiskPerfGetClock(a, b) KeQuerySystemTime(&(a)) 
#endif 



NTSTATUS 
DriverEntry( 
    IN PDRIVER_OBJECT DriverObject, 
    IN PUNICODE_STRING RegistryPath 
    ) 

/*++ 

函数说明: 

    可安装驱动的初始化入口点。 
    这个方法直接被I/O管理器调用,用来创建磁盘性能驱动。这里的driver对象创建好, 
    然后Pnp管理器调用DiskPerfAddDevice来把它附加到启动设备上。 


参数: 

    DriverObject – 磁盘性能驱动对象。 

RegistryPath – 指向一个unicode的字符串,表示路径。 
也就是注册表中,驱动特定的键。 


返回值: 

    STATUS_SUCCESS 如果成功的话 

--*/ 



    ULONG              ulIndex; 
    PDRIVER_DISPATCH  * dispatch; 

    // 
    // 保存注册表路径 
    // 

    DiskPerfRegistryPath.MaximumLength = RegistryPath->Length 
                                            + sizeof(UNICODE_NULL); 
    DiskPerfRegistryPath.Buffer = ExAllocatePool( 
                                    PagedPool, 
                                    DiskPerfRegistryPath.MaximumLength); 
    if (DiskPerfRegistryPath.Buffer != NULL) 
    { 
        RtlCopyUnicodeString(&DiskPerfRegistryPath, RegistryPath); 
    } else { 
        DiskPerfRegistryPath.Length = 0; 
        DiskPerfRegistryPath.MaximumLength = 0; 
    } 

    // 
    // 创建分派函数 
    // 
    for (ulIndex = 0, dispatch = DriverObject->MajorFunction; 
        ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; 
        ulIndex++, dispatch++) { 

        *dispatch = DiskPerfSendToNextDriver; 
    } 

    // 
    // 创建设备驱动入口点 
    // 

    DriverObject->MajorFunction[IRP_MJ_CREATE]          = DiskPerfCreate; 
    DriverObject->MajorFunction[IRP_MJ_READ]            = DiskPerfReadWrite; 
    DriverObject->MajorFunction[IRP_MJ_WRITE]          = DiskPerfReadWrite; 
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = DiskPerfDeviceControl; 
    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]  = DiskPerfWmi; 

    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]        = DiskPerfShutdownFlush; 
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]  = DiskPerfShutdownFlush; 
    DriverObject->MajorFunction[IRP_MJ_PNP]            = DiskPerfDispatchPnp; 
    DriverObject->MajorFunction[IRP_MJ_POWER]          = DiskPerfDispatchPower; 


    // 下面这行代码请尤其注意:这行代码是确保本驱动被装载的时候会执行 
// DiskPerfAddDevice的关键 

    DriverObject->DriverExtension->AddDevice            = DiskPerfAddDevice; 
    DriverObject->DriverUnload                          = DiskPerfUnload; 

    return(STATUS_SUCCESS); 

} // end DriverEntry() 

#define FILTER_DEVICE_PROPOGATE_FLAGS            0 
#define FILTER_DEVICE_PROPOGATE_CHARACTERISTICS (FILE_REMOVABLE_MEDIA |  / 
                                                FILE_READ_ONLY_DEVICE | / 
                                                FILE_FLOPPY_DISKETTE    / 
                                                ) 

VOID 
DiskPerfSyncFilterWithTarget( 
    IN PDEVICE_OBJECT FilterDevice, 
    IN PDEVICE_OBJECT TargetDevice 
    ) 

    ULONG                  propFlags; 

    PAGED_CODE(); 

// 
// 把目标设备的一些有用标记复制到diskperf中。挂载管理器将查找 
// diskperf对象的功能点,并且表明磁盘是可移动设备还是其他的 
// 设备 
    // 
    propFlags = TargetDevice->Flags & FILTER_DEVICE_PROPOGATE_FLAGS; 
    FilterDevice->Flags |= propFlags; 

    propFlags = TargetDevice->Characteristics & FILTER_DEVICE_PROPOGATE_CHARACTERISTICS; 
    FilterDevice->Characteristics |= propFlags; 




NTSTATUS 
DiskPerfAddDevice( 
    IN PDRIVER_OBJECT DriverObject, 
    IN PDEVICE_OBJECT PhysicalDeviceObject 
    ) 
/*++ 
方法说明: 

    为对应得物理设备对象(PDO=Physical Device Object)创建一个新的过滤设备对 
象(FiDO)。然后把这个设备对象“粘”到驱动的堆栈上去。 
    


参数: 

    DriverObject – 磁盘性能驱动对象。 
    PhysicalDeviceObject – 下层驱动的物理设备对象。 

返回值: 

    NTSTATUS 
--*/ 


    NTSTATUS                status; 
    PDEVICE_OBJECT          filterDeviceObject; 
    PDEVICE_EXTENSION      deviceExtension; 
    PWMILIB_CONTEXT        wmilibContext; 
    PCHAR                  buffer; 
    ULONG                  buffersize; 

    PAGED_CODE(); 

    // 
    //  为本设备创建一个过滤设备对象(分离)。 
    // 

    DebugPrint((2, "DiskPerfAddDevice: Driver %X Device %X/n", 
            DriverObject, PhysicalDeviceObject)); 

    // 这里尤其要注意FILE_DEVICE_DISK这个参数,这个用来表示你创建的 
    // 设备需要“粘”到磁盘设备对象,如果这个参数弄错了,你可能就“粘” 
    // 到其他地方去了。 
    status = IoCreateDevice(DriverObject, 
                            DEVICE_EXTENSION_SIZE, 
                            NULL, 
                            FILE_DEVICE_DISK, 
                            FILE_DEVICE_SECURE_OPEN, 
                            FALSE, 
                            &filterDeviceObject); 

    if (!NT_SUCCESS(status)) { 
      DebugPrint((1, "DiskPerfAddDevice: Cannot create filterDeviceObject/n")); 
      return status; 
    } 

    filterDeviceObject->Flags |= DO_DIRECT_IO; 

    deviceExtension = (PDEVICE_EXTENSION) filterDeviceObject->DeviceExtension; 

    RtlZeroMemory(deviceExtension, DEVICE_EXTENSION_SIZE); 
    DiskPerfGetClock(deviceExtension->LastIdleClock, NULL); 
    DebugPrint((10, "DiskPerfAddDevice: LIC=%I64u/n", 
                    deviceExtension->LastIdleClock)); 

    // 
//  为每个处理器分配计数器 
// 
    // 注意:为了节省内存,我们不必为QueryTime分配额外的内存。 
    //  如果有额外需要的话,记录需要的额外的内存大小。 
    // 

#if (NTDDI_VERSION >= NTDDI_WIN7) 
    deviceExtension->Processors = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); 
#elif (NTDDI_VERSION >= NTDDI_VISTA) 
    deviceExtension->Processors = KeQueryActiveProcessorCount(NULL);    
#else 
    deviceExtension->Processors = KeNumberProcessors; 
#endif 

    buffersize= PROCESSOR_COUNTERS_SIZE * deviceExtension->Processors; 
    buffer = (PCHAR) ExAllocatePool(NonPagedPool, buffersize); 
    if (buffer != NULL) { 
        RtlZeroMemory(buffer, buffersize); 
        deviceExtension->DiskCounters = (PDISK_PERFORMANCE) buffer; 
    } 
    else { 
        DiskPerfLogError( 
            filterDeviceObject, 
            513, 
            STATUS_SUCCESS, 
            IO_ERR_INSUFFICIENT_RESOURCES); 
    } 

// 
// 把设备对象“粘”到设备链中最高层的设备对象中 
// 同时返回上次的最高层设备对象,这个用来在调用IoCallDriver 
// 把IRP下发的时候用。 
    // 

    deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; 

    deviceExtension->TargetDeviceObject = 
        IoAttachDeviceToDeviceStack(filterDeviceObject, PhysicalDeviceObject); 

    if (deviceExtension->TargetDeviceObject == NULL) { 
        ExFreePool(deviceExtension->DiskCounters); 
        deviceExtension->DiskCounters = NULL; 
        IoDeleteDevice(filterDeviceObject); 
        DebugPrint((1, "DiskPerfAddDevice: Unable to attach %X to target %X/n", 
            filterDeviceObject, PhysicalDeviceObject)); 
        return STATUS_NO_SUCH_DEVICE; 
    } 

    // 
//  在device extension中保存过滤设备对象。 
// 
    deviceExtension->DeviceObject = filterDeviceObject; 

    deviceExtension->PhysicalDeviceName.Buffer 
            = deviceExtension->PhysicalDeviceNameBuffer; 

    KeInitializeEvent(&deviceExtension->PagingPathCountEvent, 
                      NotificationEvent, TRUE); 


    // 
    //  初始化WMI库上下文 
    // 
    wmilibContext = &deviceExtension->WmilibContext; 
    RtlZeroMemory(wmilibContext, sizeof(WMILIB_CONTEXT)); 
    wmilibContext->GuidCount = DiskperfGuidCount; 
    wmilibContext->GuidList = DiskperfGuidList; 
    wmilibContext->QueryWmiRegInfo = DiskperfQueryWmiRegInfo; 
    wmilibContext->QueryWmiDataBlock = DiskperfQueryWmiDataBlock; 
    wmilibContext->WmiFunctionControl = DiskperfWmiFunctionControl; 

    // 
    // 默认DO_POWER_PAGABLE 
    // 

    filterDeviceObject->Flags |=  DO_POWER_PAGABLE; 

    // 
    //  清除DO_DEVICE_INITIALIZING标记 
    // 

    filterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 

    return STATUS_SUCCESS; 

} // end DiskPerfAddDevice() 


NTSTATUS 
DiskPerfDispatchPnp( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 
/*++ 

方法说明: 

    PNP分派 

参数: 

    DeviceObject    - 设备对象 

    Irp            - I/O请求包 

返回值: 

    NTSTATUS 

--*/ 


    PIO_STACK_LOCATION  irpSp = IoGetCurrentIrpStackLocation(Irp); 
    NTSTATUS            status; 
    PDEVICE_EXTENSION  deviceExtension; 

    PAGED_CODE(); 

    DebugPrint((2, "DiskPerfDispatchPnp: Device %X Irp %X/n", 
        DeviceObject, Irp)); 

    switch(irpSp->MinorFunction) { 

        case IRP_MN_START_DEVICE: 
            // 
            // 调用StartRoutine 
            // 
            DebugPrint((3, 
              "DiskPerfDispatchPnp: Schedule completion for START_DEVICE")); 
            status = DiskPerfStartDevice(DeviceObject, Irp); 
            break; 

        case IRP_MN_REMOVE_DEVICE: 
        { 
            // 
            // 调用移除方法 
            // 
            DebugPrint((3, 
              "DiskPerfDispatchPnp: Schedule completion for REMOVE_DEVICE")); 
            status = DiskPerfRemoveDevice(DeviceObject, Irp); 
            break; 
        } 
        case IRP_MN_DEVICE_USAGE_NOTIFICATION: 
        { 
            PIO_STACK_LOCATION irpStack; 
            BOOLEAN setPagable; 

            DebugPrint((3, 
              "DiskPerfDispatchPnp: Processing DEVICE_USAGE_NOTIFICATION")); 
            irpStack = IoGetCurrentIrpStackLocation(Irp); 

            if (irpStack->Parameters.UsageNotification.Type != DeviceUsageTypePaging) { 
                status = DiskPerfSendToNextDriver(DeviceObject, Irp); 
                break; // 跳出 case 语句 
            } 

            deviceExtension = DeviceObject->DeviceExtension; 

            // 
            // 等待分页路径事件 
            // 

            status = KeWaitForSingleObject(&deviceExtension->PagingPathCountEvent, 
                                          Executive, KernelMode, 
                                          FALSE, NULL); 

            // 
            // 如果移除上一次分页的设备,需要设置DO_POWER_PAGABLE 
            // 如果失败,则清除这个标志 
            // 

            setPagable = FALSE; 
            if (!irpStack->Parameters.UsageNotification.InPath && 
                deviceExtension->PagingPathCount == 1 ) { 

                // 
                // removing the last paging file 
                // must have DO_POWER_PAGABLE bits set 
                // 

                if (DeviceObject->Flags & DO_POWER_INRUSH) { 
                    DebugPrint((3, "DiskPerfDispatchPnp: last paging file " 
                                "removed but DO_POWER_INRUSH set, so not " 
                                "setting PAGABLE bit " 
                                "for DO %p/n", DeviceObject)); 
                } else { 
                    DebugPrint((2, "DiskPerfDispatchPnp: Setting  PAGABLE " 
                                "bit for DO %p/n", DeviceObject)); 
                    DeviceObject->Flags |= DO_POWER_PAGABLE; 
                    setPagable = TRUE; 
                } 

            } 

            // 
            // 同步发送irp 
            // 

            status = DiskPerfForwardIrpSynchronous(DeviceObject, Irp); 

            // 
            // 处理成功,失败的情况。now deal with the failure and success cases. 
            // 注意,发送到下层驱动后,irp不允许失败。 
            // 
            // 

            if (NT_SUCCESS(status)) { 

                IoAdjustPagingPathCount( 
                    &deviceExtension->PagingPathCount, 
                    irpStack->Parameters.UsageNotification.InPath); 

                if (irpStack->Parameters.UsageNotification.InPath) { 
                    if (deviceExtension->PagingPathCount == 1) { 

                        // 
                        // 分页文件第1条件 
                        // 

                        DebugPrint((3, "DiskPerfDispatchPnp: Clearing PAGABLE bit " 
                                    "for DO %p/n", DeviceObject)); 
                        DeviceObject->Flags &= ~DO_POWER_PAGABLE; 
                    } 
                } 

            } else { 

                // 
                // 清除上文的改变 
                // 

                if (setPagable == TRUE) { 
                    DeviceObject->Flags &= ~DO_POWER_PAGABLE; 
                    setPagable = FALSE; 
                } 

            } 

            // 
            // 设置事件,以便下一个事件可以触发 
            // 

            KeSetEvent(&deviceExtension->PagingPathCountEvent, 
                      IO_NO_INCREMENT, FALSE); 

            // 
            //  并且完成irp 
            // 

            IoCompleteRequest(Irp, IO_NO_INCREMENT); 
            return status; 
            break; 

        } 

        default: 
            DebugPrint((3, 
              "DiskPerfDispatchPnp: Forwarding irp")); 
            // 
            //  简单的转发所有其他的Irp 
            // 
            return DiskPerfSendToNextDriver(DeviceObject, Irp); 

    } 

    return status; 

} // end DiskPerfDispatchPnp() 



NTSTATUS 
DiskPerfIrpCompletion( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp, 
    IN PVOID Context 
    ) 

/*++ 

函数说明: 

    转发IRP 完成方法。设置一个事件并且返回 
STATUS_MORE_PROCESSING_REQUIRED,这样Irp转发的时候会等待这个事件, 
然后在清理工作完成后再次完成。 


参数: 

    DeviceObject 是WMI驱动的设备对象。 
    Irp 就是WMI的irp 
    Context 是转发器等待的事件句柄 PKEVENT。 

返回值: 

    STATUS_MORE_PORCESSING_REQUIRED 

--*/ 


    PKEVENT Event = (PKEVENT) Context; 

    UNREFERENCED_PARAMETER(DeviceObject); 
    UNREFERENCED_PARAMETER(Irp); 

    KeSetEvent(Event, IO_NO_INCREMENT, FALSE); 

    return(STATUS_MORE_PROCESSING_REQUIRED); 

} // end DiskPerfIrpCompletion() 



NTSTATUS 
DiskPerfStartDevice( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 
/*++ 

函数说明: 

    当收到Pnp启动Irp时调用本函数。 
    它将调用完成函数,初始化和注册WMI。 

参数: 

    DeviceObject - 指向设备对象的指针 

    Irp – 指向irp的指针 


返回值: 

    处理开始Irp的状态 

--*/ 

    PDEVICE_EXTENSION  deviceExtension; 
    NTSTATUS            status; 

    PAGED_CODE(); 

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 

    status = DiskPerfForwardIrpSynchronous(DeviceObject, Irp); 

    DiskPerfSyncFilterWithTarget(DeviceObject, 
                                deviceExtension->TargetDeviceObject); 

    // 
    //  完成WMI注册 
    // 
    DiskPerfRegisterDevice(DeviceObject); 

    // 
    //  完成Irp 
    // 
    Irp->IoStatus.Status = status; 
    IoCompleteRequest(Irp, IO_NO_INCREMENT); 

    return status; 




NTSTATUS 
DiskPerfRemoveDevice( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 
/*++ 

函数说明: 

    当设备被移除时调用此函数。 
    首先将把自身从WMI反注册,删除自身前把自己从 
    设备栈上移除。 


参数: 

    DeviceObject – 指向设备对象的指针 

    Irp – 指向irp的指针 


返回值: 

    移除设备后的状态 

--*/ 

    NTSTATUS            status; 
    PDEVICE_EXTENSION  deviceExtension; 
    PWMILIB_CONTEXT    wmilibContext; 

    PAGED_CODE(); 

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 

    // 
    // 首先从WMI中反注册 
    // 
    IoWMIRegistrationControl(DeviceObject, WMIREG_ACTION_DEREGISTER); 

    // 
//  尽快把计数器清零,来把结构置为不可用 
// 
    wmilibContext = &deviceExtension->WmilibContext; 
    InterlockedExchange( 
        (PLONG) &(wmilibContext->GuidCount), 
        (LONG) 0); 
    RtlZeroMemory(wmilibContext, sizeof(WMILIB_CONTEXT)); 

    status = DiskPerfForwardIrpSynchronous(DeviceObject, Irp); 

    if (deviceExtension->DiskCounters) { 
        ExFreePool(deviceExtension->DiskCounters); 
    } 

    IoDetachDevice(deviceExtension->TargetDeviceObject); 
    IoDeleteDevice(DeviceObject); 

    // 
    // 完成Irp 
    // 
    Irp->IoStatus.Status = status; 
    IoCompleteRequest(Irp, IO_NO_INCREMENT); 

    return status; 




NTSTATUS 
DiskPerfSendToNextDriver( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 

/*++ 

函数说明: 

    当本驱动不处理某个Irp时 
这个函数发送Irp 到队列的下一个驱动 


参数: 

    DeviceObject 
    Irp 

返回值: 

    NTSTATUS 

--*/ 


    PDEVICE_EXTENSION  deviceExtension; 

    IoSkipCurrentIrpStackLocation(Irp); 
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 

    return IoCallDriver(deviceExtension->TargetDeviceObject, Irp); 

} // end DiskPerfSendToNextDriver() 


NTSTATUS 
DiskPerfDispatchPower( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 

    PDEVICE_EXTENSION deviceExtension; 


#if (NTDDI_VERSION < NTDDI_VISTA) 
    PoStartNextPowerIrp(Irp); 
    IoSkipCurrentIrpStackLocation(Irp); 

    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 
    return PoCallDriver(deviceExtension->TargetDeviceObject, Irp); 
#else 
    IoSkipCurrentIrpStackLocation(Irp); 

    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 
    return IoCallDriver(deviceExtension->TargetDeviceObject, Irp); 
#endif 

} // end DiskPerfDispatchPower 


NTSTATUS 
DiskPerfForwardIrpSynchronous( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 

/*++ 

函数说明: 

    当Irp 需要底层驱动优先处理的时候,把 
    本Irp发送到下一个驱动处理。 

参数: 

    DeviceObject 
    Irp 

返回值: 

    NTSTATUS 

--*/ 


    PDEVICE_EXTENSION  deviceExtension; 
    KEVENT event; 
    NTSTATUS status; 

    KeInitializeEvent(&event, NotificationEvent, FALSE); 
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 

    // 
    // 把irp堆栈拷贝到下一个设备 
    // 

    IoCopyCurrentIrpStackLocationToNext(Irp); 

    // 
    // 设置完成方法 
    // 

    IoSetCompletionRoutine(Irp, DiskPerfIrpCompletion, 
                            &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; 

} // end DiskPerfForwardIrpSynchronous() 



NTSTATUS 
DiskPerfCreate( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 

/*++ 

函数说明: 

    这个函数接受打开命令。通过状态返回建立驱动。 


参数: 

    DeviceObject – 活动的上下文 
    Irp          - 设备控制参数块 

返回值: 

    NT 状态 

--*/ 


    PAGED_CODE(); 

    UNREFERENCED_PARAMETER(DeviceObject); 

    Irp->IoStatus.Status = STATUS_SUCCESS; 

    IoCompleteRequest(Irp, IO_NO_INCREMENT); 
    return STATUS_SUCCESS; 

} // end DiskPerfCreate() 


NTSTATUS 
DiskPerfReadWrite( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 

/*++ 

方法说明: 

    这是diskperf驱动粘帖到的磁盘的读写入口点。 
    这个驱动收集统计信息并且设置完成方法,这样当 
    请求完成时可以收集额外的信息。然后调用下层的 
    驱动。 


参数: 

    DeviceObject 
    Irp 

返回值: 

    NTSTATUS 

--*/ 


    PDEVICE_EXTENSION  deviceExtension  = DeviceObject->DeviceExtension; 
    PIO_STACK_LOCATION currentIrpStack  = IoGetCurrentIrpStackLocation(Irp); 
#if (NTDDI_VERSION >= NTDDI_WIN7) 
    ULONG              processor        = KeGetCurrentProcessorNumberEx(NULL); 
#else 
    ULONG              processor        = KeGetCurrentProcessorNumber(); 
#endif 
    PDISK_PERFORMANCE  partitionCounters = NULL; 
    LONG              queueLen; 
    PLARGE_INTEGER    timeStamp; 

// 
// 因为处理器可能动态添加,确保 
// 这里有当前处理器的上下文环境。 
    // 

    if (deviceExtension->DiskCounters != NULL && 
        processor < deviceExtension->Processors) { 

        partitionCounters = (PDISK_PERFORMANCE) 
                            ((PCHAR) deviceExtension->DiskCounters 
                                + (processor*PROCESSOR_COUNTERS_SIZE)); 
    } 

// 
// 设备没有合适的初始化。只能盲目的传递irp 
    // 
    if (deviceExtension->CountersEnabled <= 0 || 
        deviceExtension->PhysicalDeviceNameBuffer[0] == 0 || 
        partitionCounters == NULL) { 
        return DiskPerfSendToNextDriver(DeviceObject, Irp); 
    } 

    // 
    // 增加队列深度计数 
    // 

    queueLen = InterlockedIncrement(&deviceExtension->QueueDepth); 

    // 
// 把当前的堆栈拷贝到下一个堆栈 
// 

    IoCopyCurrentIrpStackLocationToNext(Irp); 

    // 
    // 当前请求开始的事件戳 
    // 

    timeStamp = (PLARGE_INTEGER) &currentIrpStack->Parameters.Read; 
    DiskPerfGetClock(*timeStamp, NULL); 
    DebugPrint((10, "DiskPerfReadWrite: TS=%I64u/n", *timeStamp)); 

    if (queueLen == 1) { 
        partitionCounters->IdleTime.QuadPart 
            += timeStamp->QuadPart - 
                deviceExtension->LastIdleClock.QuadPart; 
        deviceExtension->LastIdleClock.QuadPart = timeStamp->QuadPart; 
    } 

    // 
    // 设置回调完成方法 
    // 

    IoSetCompletionRoutine(Irp, 
                          DiskPerfIoCompletion, 
                          DeviceObject, 
                          TRUE, 
                          TRUE, 
                          TRUE); 

    // 
    // 返回所有调用磁盘驱动的结果 
    // 

    return IoCallDriver(deviceExtension->TargetDeviceObject, 
                        Irp); 

} // end DiskPerfReadWrite() 


NTSTATUS 
DiskPerfIoCompletion( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP          Irp, 
    IN PVOID          Context 
    ) 

/*++ 

函数说明: 

    完成一个IRP后,本方法从系统获取控制。 
    它将计算IRP开始时间和当前时间的差异, 
    然后减小队列深度 


参数: 

    DeviceObject –为IRP准备 
    Irp          - 刚完成的I/O请求。 
    Context      - 未使用 

返回值: 

    IRP 的状态 

--*/ 


    PDEVICE_EXTENSION  deviceExtension  = DeviceObject->DeviceExtension; 
    PIO_STACK_LOCATION irpStack          = IoGetCurrentIrpStackLocation(Irp); 
#if (NTDDI_VERSION >= NTDDI_WIN7) 
    ULONG              processor        = KeGetCurrentProcessorNumberEx(NULL); 
#else 
    ULONG              processor        = KeGetCurrentProcessorNumber(); 
#endif 
    PDISK_PERFORMANCE  partitionCounters = NULL; 
    LARGE_INTEGER      timeStampComplete; 
    PLARGE_INTEGER    difference; 
    LONG              queueLen; 

    UNREFERENCED_PARAMETER(Context); 

    if (Irp->PendingReturned) { 
        IoMarkIrpPending(Irp); 
    } 

    // 
    //  当前请求完成的事件戳 
    // 

    difference = (PLARGE_INTEGER) &irpStack->Parameters.Read; 
    DiskPerfGetClock(timeStampComplete, NULL); 
    difference->QuadPart = timeStampComplete.QuadPart - difference->QuadPart; 
    DebugPrint((10, "DiskPerfIoCompletion: TS=%I64u diff %I64u/n", 
                    timeStampComplete, difference->QuadPart)); 

// 
// 减少卷的队列深度计数。 
// 这个不需要自旋锁,使用Interlocked函数完成即可。 
// 这是唯一合法的方法。 
    // 

    queueLen = InterlockedDecrement(&deviceExtension->QueueDepth); 

    if (queueLen < 0) { // do not over-decrement. Only happens at start 
        queueLen = InterlockedIncrement(&deviceExtension->QueueDepth); 
    } 
    if (queueLen == 0) { 
        deviceExtension->LastIdleClock = timeStampComplete; 
    } 

// 
// 更新计数器,但是,仅当在单处理器具有预分配上下 
// 文时才使用。 
    // 

    if (deviceExtension->DiskCounters != NULL && 
        processor < deviceExtension->Processors) { 

        partitionCounters = (PDISK_PERFORMANCE) 
                            ((PCHAR) deviceExtension->DiskCounters 
                                + (processor*PROCESSOR_COUNTERS_SIZE)); 
    } 

    if (partitionCounters == NULL) { 
        return STATUS_SUCCESS; 
    }; 

    if (irpStack->MajorFunction == IRP_MJ_READ) { 

        // 
        // 增加这个请求的字节数。用字节来表示读取计数器。 
        // 

        partitionCounters->BytesRead.QuadPart += Irp->IoStatus.Information; 

        // 
        // 增加读取请求的处理计数器。 
        // 

        partitionCounters->ReadCount++; 

        // 
        // 计算请求处理时间。 
        // 

        partitionCounters->ReadTime.QuadPart += difference->QuadPart; 
        DebugPrint((11, "Added RT delta %I64u total %I64u qlen=%d/n", 
            difference->QuadPart, partitionCounters->ReadTime.QuadPart, 
            queueLen)); 
    } 

    else { 

        // 
        //增加这个请求的字节数。用字节来表示写入计数器。 
        // 

        partitionCounters->BytesWritten.QuadPart += Irp->IoStatus.Information; 

        // 
        //增加写入请求的处理计数器。 
        // 

        partitionCounters->WriteCount++; 

        // 
        //计算请求处理时间。 
        // 

        partitionCounters->WriteTime.QuadPart += difference->QuadPart; 
        DebugPrint((11, "Added WT delta %I64u total %I64u qlen=%d/n", 
            difference->QuadPart, partitionCounters->WriteTime.QuadPart, 
            queueLen)); 
    } 

    if (Irp->Flags & IRP_ASSOCIATED_IRP) { 
        partitionCounters->SplitCount++; 
    } 

    return STATUS_SUCCESS; 

} // DiskPerfIoCompletion 


NTSTATUS 
DiskPerfDeviceControl( 
    PDEVICE_OBJECT DeviceObject, 
    PIRP Irp 
    ) 

/*++ 

函数说明: 

    设备控制分派函数,只处理磁盘性能设备控制。 
    所有其他的控制命令都直接发送给下层磁盘驱动。 
    磁盘性能驱动返回当前的性能数据快照。 


参数: 

    DeviceObject – 活动上下文 
    Irp          -设备控制参数快 

返回值: 

    返回状态。 

--*/ 


    PDEVICE_EXTENSION  deviceExtension = DeviceObject->DeviceExtension; 
    PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp); 

    DebugPrint((2, "DiskPerfDeviceControl: DeviceObject %X Irp %X/n", 
                    DeviceObject, Irp)); 

    if (currentIrpStack->Parameters.DeviceIoControl.IoControlCode == 
        IOCTL_DISK_PERFORMANCE) { 

        NTSTATUS        status; 

        // 
        //  校验对于性能数据来说用户缓冲区是否够大。 
        // 

        if (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength < 
                sizeof(DISK_PERFORMANCE)) { 

        // 
        // 表示非成功状态,没有数据传输。 
        // 

        status = STATUS_BUFFER_TOO_SMALL; 
        Irp->IoStatus.Information = 0; 

        } 

        else { 
            ULONG i; 
            PDISK_PERFORMANCE totalCounters; 
            PDISK_PERFORMANCE diskCounters = deviceExtension->DiskCounters; 
            LARGE_INTEGER frequency, perfctr; 

            if (diskCounters == NULL) { 
                Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 
                IoCompleteRequest(Irp, IO_NO_INCREMENT); 
                return STATUS_UNSUCCESSFUL; 
            } 

            if (InterlockedCompareExchange(&deviceExtension->EnabledAlways, 1, 0) == 0) 
            { 
                InterlockedIncrement(&deviceExtension->CountersEnabled); 

                // 
                // reset per processor counters only 
                // 
                if (deviceExtension->DiskCounters != NULL) 
                { 
                    RtlZeroMemory(deviceExtension->DiskCounters, PROCESSOR_COUNTERS_SIZE * deviceExtension->Processors); 
                } 

                DiskPerfGetClock(deviceExtension->LastIdleClock, NULL); 

                deviceExtension->QueueDepth = 0; 

                DebugPrint((10, "DiskPerfDeviceControl: LIC=%I64u/n", deviceExtension->LastIdleClock)); 
                DebugPrint((3, "DiskPerfDeviceControl: Counters enabled %d/n", deviceExtension->CountersEnabled)); 
            } 

            totalCounters = (PDISK_PERFORMANCE) Irp->AssociatedIrp.SystemBuffer; 
            RtlZeroMemory(totalCounters, sizeof(DISK_PERFORMANCE)); 
#ifdef USE_PERF_CTR 
            perfctr = KeQueryPerformanceCounter(&frequency); 
#endif 
            KeQuerySystemTime(&totalCounters->QueryTime); 

            for (i=0; i<deviceExtension->Processors; i++) { 
                DiskPerfAddCounters(totalCounters, diskCounters, frequency); 
                diskCounters = (PDISK_PERFORMANCE) 
                              ((PCHAR) diskCounters + PROCESSOR_COUNTERS_SIZE); 
            } 
            totalCounters->QueueDepth = deviceExtension->QueueDepth; 

            if (totalCounters->QueueDepth == 0) { 
                LARGE_INTEGER difference; 

                difference.QuadPart = 
#ifdef USE_PERF_CTR 
                    perfctr.QuadPart 
#else 
                  totalCounters->QueryTime.QuadPart 
#endif 
                        - deviceExtension->LastIdleClock.QuadPart; 
                if (difference.QuadPart > 0) { 
                    totalCounters->IdleTime.QuadPart += 
#ifdef USE_PERF_CTR 
                        10000000 * difference.QuadPart / frequency.QuadPart; 
#else 
                        difference.QuadPart; 
#endif 
                } 
            } 
            totalCounters->StorageDeviceNumber 
                = deviceExtension->DiskNumber; 
            RtlCopyMemory( 
                &totalCounters->StorageManagerName[0], 
                &deviceExtension->StorageManagerName[0], 
                8 * sizeof(WCHAR)); 
            status = STATUS_SUCCESS; 
            Irp->IoStatus.Information = sizeof(DISK_PERFORMANCE); 
        } 

        // 
        // 完成请求。 
        // 

        Irp->IoStatus.Status = status; 
        IoCompleteRequest(Irp, IO_NO_INCREMENT); 
        return status; 

    } 

    else { 

        // 
        // 将当前的堆栈回退1。 
        // 

        Irp->CurrentLocation++, 
        Irp->Tail.Overlay.CurrentStackLocation++; 

        // 
        // Pass unrecognized device control requests 
        // down to next driver layer. 
        // 

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




NTSTATUS DiskPerfWmi( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 

/*++ 

函数说明: 

    这个函数处理WMI的信息请求。由于磁盘性能信息是只读的, 
    所以总是收集数据,没有任何的事件,除非是QueryAllData,QuerySingleInstance和 
    GetRegInfo请求支持的事件。 


参数: 

    DeviceObject – 活动的上下文 
    Irp          - 设备控制参数块 

返回值: 

    返回的状态 

--*/ 


    PIO_STACK_LOCATION      irpSp; 
    NTSTATUS status; 
    PWMILIB_CONTEXT wmilibContext; 
    SYSCTL_IRP_DISPOSITION disposition; 
    PDEVICE_EXTENSION  deviceExtension = DeviceObject->DeviceExtension; 

    PAGED_CODE(); 

    DebugPrint((2, "DiskPerfWmi: DeviceObject %X Irp %X/n", 
                    DeviceObject, Irp)); 
    wmilibContext = &deviceExtension->WmilibContext; 
    if (wmilibContext->GuidCount == 0)  // wmilibContext is not valid 
    { 
        DebugPrint((3, "DiskPerfWmi: WmilibContext invalid")); 
        return DiskPerfSendToNextDriver(DeviceObject, Irp); 
    } 

    irpSp = IoGetCurrentIrpStackLocation(Irp); 

        DebugPrint((3, "DiskPerfWmi: Calling WmiSystemControl/n")); 
        status = WmiSystemControl(wmilibContext, 
                                    DeviceObject, 
                                    Irp, 
                                    &disposition); 
        switch (disposition) 
        { 
            case IrpProcessed: 
            { 
                break; 
            } 

            case IrpNotCompleted: 
            { 
                IoCompleteRequest(Irp, IO_NO_INCREMENT); 
                break; 
            } 

//          case IrpForward: 
//          case IrpNotWmi: 
            default: 
            { 
                status = DiskPerfSendToNextDriver(DeviceObject, Irp); 
                break; 
            } 
        } 
    return(status); 




NTSTATUS 
DiskPerfShutdownFlush( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp 
    ) 

/*++ 

函数说明: 


    关闭或者刷新IRP时候调用本函数。在系统真正关闭之前或者系统刷新时 
    发送这些IRP。 


参数: 

DriverObject –指向将被系统关闭的设备对象。 
    Irp          -包含的Irp 

返回值: 

    NT 状态 

--*/ 


    PDEVICE_EXTENSION  deviceExtension = DeviceObject->DeviceExtension; 

    DebugPrint((2, "DiskPerfShutdownFlush: DeviceObject %X Irp %X/n", 
                    DeviceObject, Irp)); 

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

} // end DiskPerfShutdownFlush() 


VOID 
DiskPerfUnload( 
    IN PDRIVER_OBJECT DriverObject 
    ) 

/*++ 

函数说明: 

    释放所有分配的资源.。 

参数: 

    DriverObject -  指向驱动对象。 

返回值: 

    VOID. 

--*/ 

    PAGED_CODE(); 

    UNREFERENCED_PARAMETER(DriverObject); 

    return; 




NTSTATUS 
DiskPerfRegisterDevice( 
    IN PDEVICE_OBJECT DeviceObject 
    ) 

/*++ 

函数说明: 

    为设备初始化合适的名字, 
    并且向WMI注册。 


参数: 

    DeviceObject – 指向需要初始化的设备对象。 

返回值: 

    初始化的状态。注意:如果注册失败, 
    DeviceExtension中的设备名称将为空。 


--*/ 


    NTSTATUS                status; 
    IO_STATUS_BLOCK        ioStatus; 
    KEVENT                  event; 
    PDEVICE_EXTENSION      deviceExtension; 
    PIRP                    irp; 
    STORAGE_DEVICE_NUMBER  number; 
    ULONG                  registrationFlag = 0; 

    PAGED_CODE(); 

    DebugPrint((2, "DiskPerfRegisterDevice: DeviceObject %X/n", 
                    DeviceObject)); 
    deviceExtension = 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) { 
        DiskPerfLogError( 
            DeviceObject, 
            256, 
            STATUS_SUCCESS, 
            IO_ERR_INSUFFICIENT_RESOURCES); 
        DebugPrint((3, "DiskPerfRegisterDevice: Fail to build irp/n")); 
        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)) { 

        // 
        // 保存设备号,作为DiskIoNotifyRoutine的参数使用。 
        // 
        deviceExtension->DiskNumber = number.DeviceNumber; 

        // 
        // 为每个分区创建设备名字 
        // 

        RtlStringCbPrintfW( 
            deviceExtension->PhysicalDeviceNameBuffer, 
            sizeof(deviceExtension->PhysicalDeviceNameBuffer), 
            L"//Device//Harddisk%d//Partition%d", 
            number.DeviceNumber, number.PartitionNumber); 

        RtlInitUnicodeString(&deviceExtension->PhysicalDeviceName, &deviceExtension->PhysicalDeviceNameBuffer[0]); 

        // 
        // 为物理磁盘设置默认名字 
        // 
        RtlCopyMemory( 
            &(deviceExtension->StorageManagerName[0]), 
            L"PhysDisk", 
            8 * sizeof(WCHAR)); 
        DebugPrint((3, "DiskPerfRegisterDevice: Device name %ws/n", 
                      deviceExtension->PhysicalDeviceNameBuffer)); 
    } 
    else { 

        // request for partition's information failed, try volume 

        ULONG          outputSize = sizeof(MOUNTDEV_NAME); 
        PMOUNTDEV_NAME  output; 
        VOLUME_NUMBER  volumeNumber; 
        ULONG          nameSize; 

        output = ExAllocatePool(PagedPool, outputSize); 
        if (!output) { 
            DiskPerfLogError( 
                DeviceObject, 
                257, 
                STATUS_SUCCESS, 
                IO_ERR_INSUFFICIENT_RESOURCES); 
            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); 
            DiskPerfLogError( 
                DeviceObject, 
                258, 
                STATUS_SUCCESS, 
                IO_ERR_INSUFFICIENT_RESOURCES); 
            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 = ExAllocatePool(PagedPool, outputSize); 

            if (!output) { 
                DiskPerfLogError( 

原创粉丝点击