⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diskperf.cpp

📁 实现USB存储设备的只读操作,可以实现所有USB设备
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		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 + -