📄 diskperf.cpp
字号:
KeSetEvent(&deviceExtension->PagingPathCountEvent,
IO_NO_INCREMENT, FALSE);
// and complete the irp
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
break;
}
default:
DBGOUT((3,
"DiskPerfDispatchPnp: Forwarding irp"));
// Simply forward all other Irps
return DiskPerfSendToNextDriver(DeviceObject, Irp);
}
return status;
} // end DiskPerfDispatchPnp()
NTSTATUS
DiskPerfIrpCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
Forwarded IRP completion routine. Set an event and return
STATUS_MORE_PROCESSING_REQUIRED. Irp forwarder will wait on this
event and then re-complete the irp after cleaning up.
Arguments:
DeviceObject is the device object of the WMI driver
Irp is the WMI irp that was just completed
Context is a PKEVENT that forwarder will wait on
Return Value:
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
)
/*++
Routine Description:
This routine is called when a Pnp Start Irp is received.
It will schedule a completion routine to initialize and register with WMI.
Arguments:
DeviceObject - a pointer to the device object
Irp - a pointer to the irp
Return Value:
Status of processing the Start Irp
--*/
{
PDEVICE_EXTENSION deviceExtension;
KEVENT event;
NTSTATUS status;
PAGED_CODE();
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
status = DiskPerfForwardIrpSynchronous(DeviceObject, Irp);
DiskPerfSyncFilterWithTarget(DeviceObject,
deviceExtension->TargetDeviceObject);
// Complete WMI registration
DiskPerfRegisterDevice(DeviceObject);
// Complete the Irp
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS
DiskPerfRemoveDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called when the device is to be removed.
It will de-register itself from WMI first, detach itself from the
stack before deleting itself.
Arguments:
DeviceObject - a pointer to the device object
Irp - a pointer to the irp
Return Value:
Status of removing the device
--*/
{
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
PWMILIB_CONTEXT wmilibContext;
PAGED_CODE();
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
// Remove registration with WMI first
IoWMIRegistrationControl(DeviceObject, WMIREG_ACTION_DEREGISTER);
// quickly zero out the count first to invalid the structure
wmilibContext = &deviceExtension->WmilibContext;
InterlockedExchange(
(PLONG) &(wmilibContext->GuidCount),
(LONG) 0);
RtlZeroMemory(wmilibContext, sizeof(WMILIB_CONTEXT));
status = DiskPerfForwardIrpSynchronous(DeviceObject, Irp);
IoDetachDevice(deviceExtension->TargetDeviceObject);
IoDeleteDevice(DeviceObject);
// Complete the Irp
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS
DiskPerfSendToNextDriver(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine sends the Irp to the next driver in line
when the Irp is not processed by this driver.
Arguments:
DeviceObject
Irp
Return Value:
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;
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
return PoCallDriver(deviceExtension->TargetDeviceObject, Irp);
} // end DiskPerfDispatchPower
NTSTATUS
DiskPerfForwardIrpSynchronous(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine sends the Irp to the next driver in line
when the Irp needs to be processed by the lower drivers
prior to being processed by this one.
Arguments:
DeviceObject
Irp
Return Value:
NTSTATUS
--*/
{
PDEVICE_EXTENSION deviceExtension;
KEVENT event;
NTSTATUS status;
KeInitializeEvent(&event, NotificationEvent, FALSE);
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
// copy the irpstack for the next device
IoCopyCurrentIrpStackLocationToNext(Irp);
// set a completion routine
IoSetCompletionRoutine(Irp, DiskPerfIrpCompletion,
&event, TRUE, TRUE, TRUE);
// call the next lower device
status = IoCallDriver(deviceExtension->TargetDeviceObject, Irp);
// wait for the actual completion
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
)
/*++
Routine Description:
This routine services open commands. It establishes
the driver's existance by returning status success.
Arguments:
DeviceObject - Context for the activity.
Irp - The device control argument block.
Return Value:
NT Status
--*/
{
PAGED_CODE();
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
} // end DiskPerfCreate()
/*++
Routine Description:
This is the driver entry point for read and write requests
to disks to which the diskperf driver has attached.
This driver collects statistics and then sets a completion
routine so that it can collect additional information when
the request completes. Then it calls the next driver below
it.
Arguments:
DeviceObject
Irp
Return Value:
NTSTATUS
--*/
NTSTATUS
DiskPerfReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
//完成一个IRP必须先填充IoStatus块的Status和Information成员,
//然后调用IoCompleteRequest例程。Status值就是NTSTATUS.H中定义的状态代码
//而Information值要取决于你完成的是何种类型的IRP以及是成功还是失败。
//通常情况下,如果IRP完成失败(即,完成的结果是某种错误状态),你应把Information域置0。
//返回STATUS_MEDIA_WRITE_PROTECTED不会出现延缓写入失败。
{
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
ULONG processor = (ULONG) KeGetCurrentProcessorNumber();
PDISK_PERFORMANCE partitionCounters = NULL;
LONG queueLen;
PLARGE_INTEGER timeStamp;
NTSTATUS status; // by sun define;
ULONG BytesTxd = 0;// by sun define
if (deviceExtension->DiskCounters != NULL) {
partitionCounters = (PDISK_PERFORMANCE)
((PCHAR) deviceExtension->DiskCounters
+ (processor*PROCESSOR_COUNTERS_SIZE));
}
// Device is not initialized properly. Blindly pass the irp along
if (deviceExtension->CountersEnabled <= 0 ||
deviceExtension->PhysicalDeviceNameBuffer[0] == 0 ||
partitionCounters == NULL) {
return DiskPerfSendToNextDriver(DeviceObject, Irp);
}
//////////////////////////////////////////////////////////////////////////
//if( ( currentIrpStack->MajorFunction == IRP_MJ_WRITE ) && IsReadOnly )
//{
// DbgPrint(("Read only by sun \n"));
// status = STATUS_MEDIA_WRITE_PROTECTED;
// Irp->IoStatus.Status = status;
// Irp->IoStatus.Information = BytesTxd;
// IoCompleteRequest(Irp,IO_NO_INCREMENT );// IO_NO_INCREMENT
// return status;
//}
//////////////////////////////////////////////////////////////////////////
// Increment queue depth counter.
queueLen = InterlockedIncrement(&deviceExtension->QueueDepth);
// Copy current stack to next stack.
*nextIrpStack = *currentIrpStack;
// Time stamp current request start.
timeStamp = (PLARGE_INTEGER) ¤tIrpStack->Parameters.Read;
DiskPerfGetClock(*timeStamp, NULL);
DBGOUT((10, "DiskPerfReadWrite: TS=%I64u\n", *timeStamp));
if (queueLen == 1) {
partitionCounters->IdleTime.QuadPart
+= timeStamp->QuadPart -
deviceExtension->LastIdleClock.QuadPart;
deviceExtension->LastIdleClock.QuadPart = timeStamp->QuadPart;
}
// Set completion routine callback.
IoSetCompletionRoutine(Irp,
DiskPerfIoCompletion,
DeviceObject,
TRUE,
TRUE,
TRUE);
// Return the results of the call to the disk driver.
return IoCallDriver(deviceExtension->TargetDeviceObject,
Irp);
} // end DiskPerfReadWrite()
NTSTATUS
DiskPerfIoCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
This routine will get control from the system at the completion of an IRP.
It will calculate the difference between the time the IRP was started
and the current time, and decrement the queue depth.
Arguments:
DeviceObject - for the IRP.
Irp - The I/O request that just completed.
Context - Not used.
Return Value:
The IRP status.
--*/
{
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PDISK_PERFORMANCE partitionCounters;
LARGE_INTEGER timeStampComplete;
PLARGE_INTEGER difference;
KIRQL currentIrql;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -