📄 diskperf.c
字号:
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);
}
//
// Complete request.
//
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
else {
//
// Set current stack back one.
//
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
)
/*++
Routine Description:
This routine handles any WMI requests for information. Since the disk
information is read-only, is always collected and does not have any
events only QueryAllData, QuerySingleInstance and GetRegInfo requests
are supported.
Arguments:
DeviceObject - Context for the activity.
Irp - The device control argument block.
Return Value:
Status is returned.
--*/
{
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
)
/*++
Routine Description:
This routine is called for a shutdown and flush IRPs. These are sent by the
system before it actually shuts down or when the file system does a flush.
Arguments:
DriverObject - Pointer to device object to being shutdown by system.
Irp - IRP involved.
Return Value:
NT Status
--*/
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
//
// Set current stack back one.
//
DebugPrint((2, "DiskPerfShutdownFlush: DeviceObject %X Irp %X\n",
DeviceObject, Irp));
Irp->CurrentLocation++,
Irp->Tail.Overlay.CurrentStackLocation++;
return IoCallDriver(deviceExtension->TargetDeviceObject, Irp);
} // end DiskPerfShutdownFlush()
VOID
DiskPerfUnload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Free all the allocated resources, etc.
Arguments:
DriverObject - pointer to a driver object.
Return Value:
VOID.
--*/
{
PAGED_CODE();
return;
}
NTSTATUS
DiskPerfRegisterDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Routine to initialize a proper name for the device object, and
register it with WMI
Arguments:
DeviceObject - pointer to a device object to be initialized.
Return Value:
Status of the initialization. NOTE: If the registration fails,
the device name in the DeviceExtension will be left as empty.
--*/
{
NTSTATUS status;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
PDEVICE_EXTENSION deviceExtension;
PIRP irp;
STORAGE_DEVICE_NUMBER number;
ULONG registrationFlag = 0;
WCHAR ntNameBuffer[DISKPERF_MAXSTR];
STRING ntNameString;
UNICODE_STRING ntUnicodeString;
PAGED_CODE();
DebugPrint((2, "DiskPerfRegisterDevice: DeviceObject %X\n",
DeviceObject));
deviceExtension = DeviceObject->DeviceExtension;
KeInitializeEvent(&event, NotificationEvent, FALSE);
//
// Request for the device number
//
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)) {
//
// Remember the disk number for use as parameter in DiskIoNotifyRoutine
//
deviceExtension->DiskNumber = number.DeviceNumber;
//
// Create device name for each partition
//
swprintf(
deviceExtension->PhysicalDeviceNameBuffer,
L"\\Device\\Harddisk%d\\Partition%d",
number.DeviceNumber, number.PartitionNumber);
RtlInitUnicodeString(
&deviceExtension->PhysicalDeviceName,
&deviceExtension->PhysicalDeviceNameBuffer[0]);
//
// Set default name for physical disk
//
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;
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(
DeviceObject,
258,
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, 259,
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 (!NT_SUCCESS(status)) {
ExFreePool(output);
DiskPerfLogError(
DeviceObject,
260,
STATUS_SUCCESS,
IO_ERR_CONFIGURATION_ERROR);
return status;
}
//
// Since we get the volume name instead of the disk number,
// set it to a dummy value
// Todo: Instead of passing the disk number back to the user app.
// for tracing, pass the STORAGE_DEVICE_NUMBER structure instead.
deviceExtension->DiskNumber = -1;
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);
//
// Now, get the VOLUME_NUMBER information
//
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) {
DiskPerfLogError(
DeviceObject,
265,
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 (!NT_SUCCESS(status) ||
volumeNumber.VolumeManagerName[0] == (WCHAR) UNICODE_NULL) {
RtlCopyMemory(
&deviceExtension->StorageManagerName[0],
L"LogiDisk",
8 * sizeof(WCHAR));
if (NT_SUCCESS(status))
deviceExtension->DiskNumber = volumeNumber.VolumeNumber;
}
else {
RtlCopyMemory(
&deviceExtension->StorageManagerName[0],
&volumeNumber.VolumeManagerName[0],
8 * sizeof(WCHAR));
deviceExtension->DiskNumber = volumeNumber.VolumeNumber;
}
DebugPrint((3, "DiskPerfRegisterDevice: Device name %ws\n",
deviceExtension->PhysicalDeviceNameBuffer));
}
status = IoWMIRegistrationControl(DeviceObject,
WMIREG_ACTION_REGISTER | registrationFlag );
if (! NT_SUCCESS(status)) {
DiskPerfLogError(
DeviceObject,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -