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

📄 diskperf.c

📁 U盘过滤驱动,仿DDK例子diskperf改写,实现U盘的只读操作,供初学者参考
💻 C
📖 第 1 页 / 共 5 页
字号:

	irpStack = IoGetCurrentIrpStackLocation( Irp );

	CurSrb = (PSCSI_REQUEST_BLOCK)ExAllocatePoolWithTag(NonPagedPool,
		sizeof(SCSI_REQUEST_BLOCK),
		'brs');
	if (CurSrb == NULL) 
	{
		//DbgPrint("观察:CurSrb==NULL\n");
	}
	else
	{
		//DbgPrint("观察:CurSrb!=NULL\n");
	}

	RtlZeroMemory(CurSrb, SCSI_REQUEST_BLOCK_SIZE); 

	if (irpStack->MajorFunction==IRP_MJ_INTERNAL_DEVICE_CONTROL)
	{
		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;
			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");

//	RtlInitUnicodeString(&devNameUnicd,L"\\Device\\diskperf");
//	RtlInitUnicodeString(&devLinkUnicd,L"\\??\\diskperf");


//赋值可用下面的语句:   
//
	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;

    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 = 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(
                    &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.
            //

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

            //
            // and complete the irp
            //

            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return status;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -