📄 diskperf.cpp
字号:
CurSrb=irpStack->Parameters.Scsi.Srb;
cdb = (PCDB)CurSrb->Cdb;
opCode=cdb->CDB6GENERIC.OperationCode;
if (opCode==SCSIOP_MODE_SENSE)
{
DbgPrint("观察:进入U盘写保护\n");
modeData = (PMODE_PARAMETER_HEADER)CurSrb->DataBuffer;
//////////////////////////////////////////////////////////////////////////
//
StorExtension->edx->;
//
//////////////////////////////////////////////////////////////////////////
if( IsReadOnly )
{
DbgPrint("U盘写保护\n");
modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
}
}
}
if ( Irp->PendingReturned )
{
IoMarkIrpPending( Irp );
}
return Irp->IoStatus.Status ;
}
NTSTATUS
DiskPerfScsi(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
KIRQL IrqLevel;
PDEVICE_OBJECT pDeviceObject;
PDEVICE_EXTENSION StorExtension = ( PDEVICE_EXTENSION )
DeviceObject->DeviceExtension;
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine( Irp,
USBSCSICompletion,
DeviceObject,
TRUE,
TRUE,
TRUE );
return IoCallDriver( StorExtension->TargetDeviceObject, Irp );
}
// 此函数行为及其功能暂不知道 孙勇
VOID
DiskPerfSyncFilterWithTarget(
IN PDEVICE_OBJECT FilterDevice,
IN PDEVICE_OBJECT TargetDevice
)
{
ULONG propFlags;
PAGED_CODE();
// Propogate all useful flags from target to diskperf. MountMgr will look
// at the diskperf object capabilities to figure out if the disk is
// a removable and perhaps other things.
propFlags = TargetDevice->Flags & FILTER_DEVICE_PROPOGATE_FLAGS;
FilterDevice->Flags |= propFlags;
propFlags = TargetDevice->Characteristics & FILTER_DEVICE_PROPOGATE_CHARACTERISTICS;
FilterDevice->Characteristics |= propFlags;
}
/*++
Routine Description:
Creates and initializes a new filter device object FiDO for the
corresponding PDO. Then it attaches the device object to the device
stack of the drivers for the device.
Arguments:
DriverObject - Disk performance driver object.
PhysicalDeviceObject - Physical Device Object from the underlying layered driver
Return Value:
NTSTATUS
--*/
UNICODE_STRING string1;
UNICODE_STRING string2;
UNICODE_STRING devNameUnicd;
UNICODE_STRING devLinkUnicd;
NTSTATUS
DiskPerfAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
NTSTATUS status;
IO_STATUS_BLOCK ioStatus;
PDEVICE_OBJECT filterDeviceObject;
PDEVICE_EXTENSION deviceExtension;
PIRP irp;
STORAGE_DEVICE_NUMBER number;
ULONG registrationFlag = 0;
PWMILIB_CONTEXT wmilibContext;
PCHAR buffer;
ULONG buffersize;
//////////////////////////////////////////////////////////////////////////
WCHAR KeyName[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\diskperf";
WCHAR valueName[] = L"OnlyRead";
HANDLE hKeyHandle = NULL;
NTSTATUS status1;
OBJECT_ATTRIBUTES tmp;
UNICODE_STRING strKeyName;
UNICODE_STRING strvalueName;
PKEY_VALUE_PARTIAL_INFORMATION buffer1 = 0;
ULONG bufferlen = 0;
ULONG resultLength = 0;
//初始化可用下面的语句:
RtlInitUnicodeString(&string1, L"\\Driver\\USBSTOR");
RtlInitUnicodeString(&string2, L"\\Driver\\USBSTOR1");
//赋值可用下面的语句:
//
string2.MaximumLength = PhysicalDeviceObject->DriverObject->DriverName.MaximumLength;
RtlCopyUnicodeString(&string2,&PhysicalDeviceObject->DriverObject->DriverName);
if( !RtlEqualUnicodeString(&string1,&string2,TRUE) )
{
status = STATUS_OBJECT_NAME_EXISTS;
return status;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
RtlInitUnicodeString( &strKeyName, KeyName );
RtlInitUnicodeString( &strvalueName, valueName );
InitializeObjectAttributes(&tmp,&strKeyName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,NULL,NULL);
status1 = ZwOpenKey(&hKeyHandle,KEY_READ, &tmp);
if (NT_SUCCESS(status1))
{
DbgPrint(("ZwOpenKey success \n"));
bufferlen = sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof(ULONG);
buffer1 = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool( NonPagedPool,bufferlen );
status1 = ZwQueryValueKey( hKeyHandle,&strvalueName,
KeyValuePartialInformation,
buffer1,
bufferlen,
&resultLength );
if (NT_SUCCESS(status1))
{
if( buffer1->Data[0] == 1)
{
IsReadOnly = TRUE;
}
else
{
IsReadOnly = FALSE;
}
}
else
{
DbgPrint(("ZwQueryValueKey fail \n"));
}
ZwClose(hKeyHandle);
ExFreePool(buffer1);
}
else
{
DbgPrint(("ZwOpenKey success fail \n"));
}
//////////////////////////////////////////////////////////////////////////
PAGED_CODE();
// Create a filter device object for this device (partition).
DBGOUT((2, "DiskPerfAddDevice: Driver %X Device %X\n",
DriverObject, PhysicalDeviceObject));
DbgPrint(("DiskPerfAddDevice: in diskperf.c"));
status = IoCreateDevice(DriverObject,
DEVICE_EXTENSION_SIZE,
NULL,
FILE_DEVICE_DISK,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&filterDeviceObject);
if (!NT_SUCCESS(status)) {
DBGOUT((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);
DBGOUT((10, "DiskPerfAddDevice: LIC=%I64u\n",
deviceExtension->LastIdleClock));
// Allocate per processor counters. NOTE: To save some memory, it does
// allocate memory beyond QueryTime. Remember to expand size if there
// is a need to use anything beyond this
deviceExtension->Processors = KeNumberProcessors;
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);
}
// Attaches the device object to the highest device object in the chain and
// return the previously highest device object, which is passed to
// IoCallDriver when pass IRPs down the device stack
deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
deviceExtension->TargetDeviceObject =
IoAttachDeviceToDeviceStack(filterDeviceObject, PhysicalDeviceObject);
if (deviceExtension->TargetDeviceObject == NULL) {
IoDeleteDevice(filterDeviceObject);
DBGOUT((1, "DiskPerfAddDevice: Unable to attach %X to target %X\n",
filterDeviceObject, PhysicalDeviceObject));
return STATUS_NO_SUCH_DEVICE;
}
// Save the filter device object in the device extension
deviceExtension->DeviceObject = filterDeviceObject;
deviceExtension->PhysicalDeviceName.Buffer
= deviceExtension->PhysicalDeviceNameBuffer;
KeInitializeEvent(&deviceExtension->PagingPathCountEvent,
NotificationEvent, TRUE);
// Initialize WMI library context
wmilibContext = &deviceExtension->WmilibContext;
RtlZeroMemory(wmilibContext, sizeof(WMILIB_CONTEXT));
wmilibContext->GuidCount = DiskperfGuidCount;
wmilibContext->GuidList = DiskperfGuidList;
wmilibContext->QueryWmiRegInfo = DiskperfQueryWmiRegInfo;
wmilibContext->QueryWmiDataBlock = DiskperfQueryWmiDataBlock;
wmilibContext->WmiFunctionControl = DiskperfWmiFunctionControl;
// default to DO_POWER_PAGABLE
filterDeviceObject->Flags |= DO_POWER_PAGABLE;
// Clear the DO_DEVICE_INITIALIZING flag
filterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
//////////////////////////////////////////////////////////////////////////
// 用于关联设备栈
PDEVICE_OBJECT edo;
WCHAR namebuf[64];
static LONG numextra = -1;
_snwprintf(namebuf, sizeof(namebuf), L"\\Device\\MyExtra%d",
InterlockedIncrement(&numextra));
UNICODE_STRING edoname;
RtlInitUnicodeString(&edoname, namebuf);
status = IoCreateDevice(DriverObject, sizeof(EXTRA_DEVICE_EXTENSION),
&edoname, FILE_DEVICE_UNKNOWN, 0, FALSE, &edo);
if( !NT_SUCCESS(status) )
{
DbgPrint(("建立扩展设备对象失败! diskperf.c"));
}
_snwprintf(namebuf, sizeof(namebuf), L"\\DosDevices\\MyExtra%d",
&numextra);
UNICODE_STRING linkname;
RtlInitUnicodeString(&linkname, namebuf);
status = IoCreateSymbolicLink(&linkname, &edoname);
if( !NT_SUCCESS(status) )
{
DbgPrint(("扩展设备符号链接名联接失败 diskperf.c"));
}
PEXTRA_DEVICE_EXTENSION edx =
(PEXTRA_DEVICE_EXTENSION) edo->DeviceExtension;
edx->pdx = deviceExtension;
deviceExtension->edx = edx;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
return STATUS_SUCCESS;
} // end DiskPerfAddDevice()
NTSTATUS
DiskPerfDispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Dispatch for PNP
Arguments:
DeviceObject - Supplies the device object.
Irp - Supplies the I/O request packet.
Return Value:
NTSTATUS
--*/
{
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
PAGED_CODE();
DBGOUT((2, "DiskPerfDispatchPnp: Device %X Irp %X\n",
DeviceObject, Irp));
switch(irpSp->MinorFunction) {
case IRP_MN_START_DEVICE:
// Call the Start Routine handler to schedule a completion routine
DBGOUT((3,
"DiskPerfDispatchPnp: Schedule completion for START_DEVICE"));
status = DiskPerfStartDevice(DeviceObject, Irp);
break;
case IRP_MN_REMOVE_DEVICE:
{
// Call the Remove Routine handler to schedule a completion routine
DBGOUT((3,
"DiskPerfDispatchPnp: Schedule completion for REMOVE_DEVICE"));
status = DiskPerfRemoveDevice(DeviceObject, Irp);
break;
}
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
{
PIO_STACK_LOCATION irpStack;
ULONG count;
BOOLEAN setPagable;
DBGOUT((3,
"DiskPerfDispatchPnp: Processing DEVICE_USAGE_NOTIFICATION"));
irpStack = IoGetCurrentIrpStackLocation(Irp);
if (irpStack->Parameters.UsageNotification.Type != DeviceUsageTypePaging) {
status = DiskPerfSendToNextDriver(DeviceObject, Irp);
break; // out of case statement
}
deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
// wait on the paging path event
status = KeWaitForSingleObject(&deviceExtension->PagingPathCountEvent,
Executive, KernelMode,
FALSE, NULL);
// if removing last paging device, need to set DO_POWER_PAGABLE
// bit here, and possible re-set it below on failure.
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) {
DBGOUT((3, "DiskPerfDispatchPnp: last paging file "
"removed but DO_POWER_INRUSH set, so not "
"setting PAGABLE bit "
"for DO %p\n", DeviceObject));
} else {
DBGOUT((2, "DiskPerfDispatchPnp: Setting PAGABLE "
"bit for DO %p\n", DeviceObject));
DeviceObject->Flags |= DO_POWER_PAGABLE;
setPagable = TRUE;
}
}
// send the irp synchronously
status = DiskPerfForwardIrpSynchronous(DeviceObject, Irp);
// now deal with the failure and success cases.
// note that we are not allowed to fail the irp
// once it is sent to the lower drivers.
if (NT_SUCCESS(status)) {
IoAdjustPagingPathCount(
(LONG*)&deviceExtension->PagingPathCount,
irpStack->Parameters.UsageNotification.InPath);
if (irpStack->Parameters.UsageNotification.InPath) {
if (deviceExtension->PagingPathCount == 1) {
// first paging file addition
DBGOUT((3, "DiskPerfDispatchPnp: Clearing PAGABLE bit "
"for DO %p\n", DeviceObject));
DeviceObject->Flags &= ~DO_POWER_PAGABLE;
}
}
} else {
// cleanup the changes done above
if (setPagable == TRUE) {
DeviceObject->Flags &= ~DO_POWER_PAGABLE;
setPagable = FALSE;
}
}
// set the event so the next one can occur.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -