返回列表 发帖

[分享] 虚拟磁盘

/*

DiskDispatch.c

Author: NewbieCoder[0GiNr]

http://0ginr.com
*/

NTSTATUS
AllocateUnicodeString(
                                          PUNICODE_STRING AllocatedString,
                                          USHORT StringLengthInByte
                                          )
{
        BOOLEAN Result;
        AllocatedString->Buffer=ExAllocatePool(NonPagedPool,StringLengthInByte+sizeof(UNICODE_NULL));
        Result=(AllocatedString->Buffer!=NULL);
        if (Result)
        {
                RtlZeroMemory(AllocatedString->Buffer,StringLengthInByte+sizeof(UNICODE_NULL));
                AllocatedString->Length=0;
                AllocatedString->MaximumLength=StringLengthInByte+sizeof(UNICODE_NULL);
        }
        return (Result?STATUS_SUCCESS:STATUS_NO_MEMORY);
}

VOID
FreeUnicodeString(
                                  PUNICODE_STRING UnicodeString
                                         )
{
        if (UnicodeString->Buffer)
        {
                ExFreePool(UnicodeString->Buffer);
        }
        return;
}

NTSTATUS
VirtualDiskWorkThread(
                                          PDEVICE_OBJECT DeviceObject
                                          )
{
        PVIRTUAL_DISK_DEVICE_EXTENSION DeviceExtension;
        NTSTATUS Status=STATUS_INVALID_DEVICE_REQUEST;
        PLIST_ENTRY Request=NULL;
        PIRP Irp=NULL;
        PIO_STACK_LOCATION IrpSp=NULL;
        PVOID SystemBuffer=NULL;
        PVOID DeviceBuffer=NULL;

        DeviceExtension=(PVIRTUAL_DISK_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        while (!DeviceExtension->WorkThreadInformation.TerminateWorkThread)
        {
                (VOID)KeWaitForSingleObject(&DeviceExtension->WorkThreadInformation.NotifyEvent,Executive,KernelMode,FALSE,NULL);

                while (Request = ExInterlockedRemoveHeadList(&DeviceExtension->WorkThreadInformation.List,&DeviceExtension->WorkThreadInformation.SpinLock))
                {
                        Irp=CONTAINING_RECORD(Request, IRP, Tail.Overlay.ListEntry);
                        IrpSp=IoGetCurrentIrpStackLocation(Irp);

                        switch (IrpSp->MajorFunction)
                        {
                        case IRP_MJ_READ:
                                {
                                        SystemBuffer=MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);
                                        if (SystemBuffer == NULL)
                                        {
                                                dprintf("[VirtualDisk VirtualDiskWorkThread: IRP_MJ_READ failes of SystemBuffer is null.\n");
                                                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                                                Irp->IoStatus.Information = 0;
                                                break;
                                        }
                                        //DeviceBuffer=ExAllocatePool(PagedPool,IrpSp->Parameters.Read.Length);
                                        //if (DeviceBuffer == NULL)
                                        //{
                                        //        dprintf("[VirtualDisk VirtualDiskWorkThread: IRP_MJ_READ failes of ExAllocatePool failed.\n");
                                        //        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                                        //        Irp->IoStatus.Information = 0;
                                        //        break;
                                        //}
                                        Status=ZwReadFile(
                                                DeviceExtension->FileHandle,
                                                NULL,
                                                NULL,
                                                NULL,
                                                &Irp->IoStatus,
                                                SystemBuffer,//DeviceBuffer,
                                                IrpSp->Parameters.Read.Length,
                                                &IrpSp->Parameters.Read.ByteOffset,
                                                NULL
                                                );
                                        //if (NT_SUCCESS(Status))
                                        //{
                                        //        RtlCopyMemory(SystemBuffer, DeviceBuffer, IrpSp->Parameters.Read.Length);
                                        //}
#if DBG
                                        if (!NT_SUCCESS(Status))
                                        {
                                                dprintf("[VirtualDisk VirtualDiskWorkThread: ZwReadFile failed, status = 0x%X.\n",Status);
                                        }
#endif
                                        //ExFreePool(DeviceBuffer);
                                        break;
                                }

                        case IRP_MJ_WRITE:
                                {
                                        if ((IrpSp->Parameters.Write.ByteOffset.QuadPart +
                                                IrpSp->Parameters.Write.Length) >
                                                DeviceExtension->EndOfFile.QuadPart)
                                        {
                                                Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                                                Irp->IoStatus.Information = 0;

                                                dprintf("[VirtualDisk VirtualDiskWorkThread: IRP_MJ_WRITE failes of STATUS_INVALID_PARAMETER.\n");
                                                break;
                                        }
                                        if (DeviceExtension->IsReadOnly)
                                        {
                                                //Status=STATUS_MEDIA_WRITE_PROTECTED;
                                                Status=STATUS_ACCESS_DENIED;
                                                Irp->IoStatus.Information = 0;

                                                dprintf("[VirtualDisk VirtualDiskWorkThread: IRP_MJ_WRITE failes of STATUS_MEDIA_WRITE_PROTECTED.\n");
                                                break;
                                        }
                                        else
                                        {
                                                Status=ZwWriteFile(
                                                        DeviceExtension->FileHandle,
                                                        NULL,
                                                        NULL,
                                                        NULL,
                                                        &Irp->IoStatus, // we've processed IoStatus here
                                                        MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority),
                                                        IrpSp->Parameters.Write.Length,
                                                        &IrpSp->Parameters.Write.ByteOffset,
                                                        NULL
                                                        );
#if DBG
                                                if (!NT_SUCCESS(Status))
                                                {
                                                        dprintf("[VirtualDisk VirtualDiskWorkThread: ZwReadFile failed, status = 0x%X.\n",Status);
                                                }
#endif
                                        }
                                        break;
                                }

                        case IRP_MJ_DEVICE_CONTROL:
                                {
                                        switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
                                        {
                                                // ????
                                                //case IOCTL_FILE_DISK_OPEN_FILE:

                                                //    SeImpersonateClient(device_extension->security_client_context, NULL);

                                                //    irp->IoStatus.Status = FileDiskOpenFile(device_object, irp);

                                                //    PsRevertToSelf();

                                                //    break;

                                                //case IOCTL_FILE_DISK_CLOSE_FILE:
                                                //    Irp->IoStatus.Status = FileDiskCloseFile(device_object, irp);
                                                //    break;

                                        default:
                                                {
                                                        DbgBreakPoint();
                                                        Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
                                                        Irp->IoStatus.Information = 0;
                                                        break;
                                                }
                                        }
                                }

                        default:
                                {
                                        dprintf("[VirtualDisk] VirtualDiskWorkThread: unknown io ctl code.\n");
                                        Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
                                        Irp->IoStatus.Information = 0;
                                }
                        }

                        IoCompleteRequest(Irp,(NT_SUCCESS(Irp->IoStatus.Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
                }
                (VOID)KeResetEvent(&DeviceExtension->WorkThreadInformation.NotifyEvent);
        }
        return PsTerminateSystemThread(STATUS_SUCCESS);
}

NTSTATUS
InstallNewVirtualDisk(
                                          WCHAR DriverLetter,
                                          BOOLEAN ReadOnlyDisk
                                          )
{
        NTSTATUS Status;
        PVIRTUAL_DISK_DEVICE_EXTENSION DeviceExtension;
        UNICODE_STRING DeviceName={0};
        UNICODE_STRING SuffixName={0};
        WCHAR DriveName[]=L"\x00:";
        PDEVICE_OBJECT DeviceObject=NULL;
        HANDLE WorkThreadHandle;

        Status=AllocateUnicodeString(
                &SuffixName,
                MAX_NAME_LENGTH
                );
        if (!NT_SUCCESS(Status))
        {
                goto __exit;
        }

        Status=AllocateUnicodeString(
                &DeviceName,
                MAX_NAME_LENGTH
                );
        if (!NT_SUCCESS(Status))
        {
                goto __exit1;
        }

        Status=RtlIntegerToUnicodeString(g_NumberOfVirtualDisks,0,&SuffixName);
        if (!NT_SUCCESS(Status))
        {
                goto __exit2;
        }

        Status=RtlAppendUnicodeToString(&DeviceName,VIRTUALDISK_DEVICE_NAME_W);
        if (!NT_SUCCESS(Status))
        {
                goto __exit2;
        }

        Status=RtlAppendUnicodeStringToString(&DeviceName,&SuffixName);
        if (!NT_SUCCESS(Status))
        {
                goto __exit2;
        }

        dprintf("[VirtualDisk] InstallNewVirtualDisk: DeviceName: %S.\n",DeviceName.Buffer);

        Status=IoCreateDevice(
                g_DriverObject,
                sizeof(VIRTUAL_DISK_DEVICE_EXTENSION),
                &DeviceName,
                FILE_DEVICE_DISK,
                FILE_DEVICE_SECURE_OPEN,
                FALSE,
                &DeviceObject
                );
        if (!NT_SUCCESS(Status))
        {
                goto __exit2;
        }

        DeviceExtension=(PVIRTUAL_DISK_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

        DeviceObject->Flags |= DO_DIRECT_IO;
        if (ReadOnlyDisk)
        {
                DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
                DeviceExtension->IsReadOnly=ReadOnlyDisk;
        }

        IoInitializeRemoveLock(&DeviceExtension->RemoveLock,GENERIC_TAG,0,0);

        Status=AllocateUnicodeString(&DeviceExtension->SymbolicLink,MAX_NAME_LENGTH);
        if (!NT_SUCCESS(Status))
        {
                goto __exit3;
        }

        DriveName[0]=DriverLetter;
        Status=RtlAppendUnicodeToString(&DeviceExtension->SymbolicLink,L"\\??\\");
        if (!NT_SUCCESS(Status))
        {
                goto __exit4;
        }

        Status=RtlAppendUnicodeToString(&DeviceExtension->SymbolicLink,DriveName);
        if (!NT_SUCCESS(Status))
        {
                goto __exit4;
        }

        dprintf("[VirtualDisk] InstallNewVirtualDisk: SymbolicLink: %S.\n",DeviceExtension->SymbolicLink.Buffer);

        // FIXME: open first to check if there's already one.
        Status=IoCreateSymbolicLink(&DeviceExtension->SymbolicLink,&DeviceName);
        if (!NT_SUCCESS(Status))
        {
                goto __exit4;
        }

        InitializeListHead(&DeviceExtension->WorkThreadInformation.List);
        KeInitializeSpinLock(&DeviceExtension->WorkThreadInformation.SpinLock);
        KeInitializeEvent(&DeviceExtension->WorkThreadInformation.NotifyEvent,NotificationEvent,FALSE);
        DeviceExtension->WorkThreadInformation.TerminateWorkThread=FALSE;
        Status=PsCreateSystemThread(&WorkThreadHandle,THREAD_ALL_ACCESS,NULL,NULL,NULL,VirtualDiskWorkThread,DeviceObject);
        if (!NT_SUCCESS(Status))
        {
                goto __exit5;
        }
        Status=ObReferenceObjectByHandle(WorkThreadHandle,THREAD_ALL_ACCESS,NULL,KernelMode,&DeviceExtension->WorkThreadInformation.WorkThread,NULL);
        ZwClose(WorkThreadHandle);
        if (1)
        {
                OBJECT_ATTRIBUTES ObjectAttributes;
                IO_STATUS_BLOCK IoSb;
                UNICODE_STRING DiskFile;
                FILE_STANDARD_INFORMATION FileStandardInfo;
                RtlInitUnicodeString(&DiskFile,L"\\??\\F:\\DISKFORMY");
                InitializeObjectAttributes(&ObjectAttributes,&DiskFile,OBJ_CASE_INSENSITIVE,(HANDLE)0,NULL);
                ZwCreateFile(&DeviceExtension->FileHandle,GENERIC_READ|GENERIC_WRITE,&ObjectAttributes,&IoSb,&DeviceExtension->EndOfFile,FILE_ATTRIBUTE_NORMAL,0,FILE_OPEN_IF,
                        FILE_NON_DIRECTORY_FILE |
                        FILE_RANDOM_ACCESS |
                        FILE_NO_INTERMEDIATE_BUFFERING |
                        FILE_SYNCHRONOUS_IO_NONALERT,
                        NULL,0);
                ZwQueryInformationFile(DeviceExtension->FileHandle,&IoSb,&FileStandardInfo,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);
                DeviceExtension->EndOfFile.QuadPart=FileStandardInfo.EndOfFile.QuadPart;
                dprintf("FileHandle  = 0x%X, size = 0x%X,0x%X.\n",DeviceExtension->FileHandle,DeviceExtension->EndOfFile.LowPart,DeviceExtension->EndOfFile.HighPart);
                // file size is error.
                //DbgBreakPoint();
        }
        if (!NT_SUCCESS(Status))
        {
                goto __exit6;
        }
        goto __exit2;
        goto __exit6;
__exit6:
        KeSetEvent(&DeviceExtension->WorkThreadInformation.NotifyEvent,IO_NO_INCREMENT,FALSE);
        DeviceExtension->WorkThreadInformation.TerminateWorkThread=TRUE;
__exit5:
        IoDeleteSymbolicLink(&DeviceExtension->SymbolicLink);
__exit4:
        FreeUnicodeString(&DeviceExtension->SymbolicLink);
__exit3:
        IoDeleteDevice(DeviceObject);
__exit2:
        FreeUnicodeString(&DeviceName);
__exit1:
        FreeUnicodeString(&SuffixName);
__exit:
        return Status;
}

VOID
DeleteVirtualDisk(
                                  PDEVICE_OBJECT DeviceObject
                                  )
{
        PVIRTUAL_DISK_DEVICE_EXTENSION DeviceExtension;
        DeviceExtension=(PVIRTUAL_DISK_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        dprintf("[VirtualDisk] attempt to DeleteVirtualDisk: 0x%X.\n",DeviceObject);
        if (!DeviceExtension)
        {
                dprintf("[VirtualDisk] DeleteVirtualDisk 0x%X failed.\n",DeviceObject);
                return; // main device will be deleted in OnUnload
        }
        DeviceExtension->WorkThreadInformation.TerminateWorkThread=TRUE;
        KeSetEvent(&DeviceExtension->WorkThreadInformation.NotifyEvent,IO_NO_INCREMENT,FALSE);
        KeWaitForSingleObject(DeviceExtension->WorkThreadInformation.WorkThread,Executive,KernelMode,FALSE,NULL);
        ObDereferenceObject(DeviceExtension->WorkThreadInformation.WorkThread);
        IoDeleteSymbolicLink(&DeviceExtension->SymbolicLink);
        FreeUnicodeString(&DeviceExtension->SymbolicLink);
        ZwClose(DeviceExtension->FileHandle);

        IoDeleteDevice(DeviceObject);
        return;
}

NTSTATUS
DoVirtualDiskReadWrite(
                                           PDEVICE_OBJECT DeviceObject,
                                           PIRP Irp
                                           )
{        
        NTSTATUS Status=STATUS_SUCCESS;
        PVIRTUAL_DISK_DEVICE_EXTENSION DeviceExtension;
        PIO_STACK_LOCATION IrpSp;
        DeviceExtension=(PVIRTUAL_DISK_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        IrpSp=IoGetCurrentIrpStackLocation(Irp);

        if (IrpSp->Parameters.Read.Length==0) // equal to IrpSp->Parameters.Write.Length
        {
                Status=STATUS_SUCCESS;
                Irp->IoStatus.Status = Status;
                Irp->IoStatus.Information = 0;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
        }
        else
        {
                Status=STATUS_PENDING;
                IoMarkIrpPending(Irp);
                ExInterlockedInsertTailList(
                        &DeviceExtension->WorkThreadInformation.List,
                        &Irp->Tail.Overlay.ListEntry,
                        &DeviceExtension->WorkThreadInformation.SpinLock
                        );
                KeSetEvent(
                        &DeviceExtension->WorkThreadInformation.NotifyEvent,
                        IO_NO_INCREMENT,
                        FALSE
                        );
        }

        return Status;
}

NTSTATUS
DoVirtualDiskCreateClose(
                                                 PDEVICE_OBJECT DeviceObject,
                                                 PIRP Irp
                                                 )
{
        NTSTATUS Status=STATUS_SUCCESS;
        Irp->IoStatus.Information = 0; // FILE_OPENED
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return Status;
}

NTSTATUS
DoVirtualDiskUnsupporttedRequest(
                                                                 PDEVICE_OBJECT DeviceObject,
                                                                 PIRP Irp
                                                                 )
{
        NTSTATUS Status=STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return Status;
}

NTSTATUS
DoVirtualDiskDeviceControl(
                                                   PDEVICE_OBJECT DeviceObject,
                                                   PIRP Irp
                                                   )
{
        NTSTATUS Status=STATUS_DEVICE_NOT_READY;
        PVIRTUAL_DISK_DEVICE_EXTENSION DeviceExtension;
        PIO_STACK_LOCATION IrpSp;
        ULONG OutputBufferLength,InputBufferLength;
        PVOID IoBuffer;
        DeviceExtension=(PVIRTUAL_DISK_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        IrpSp=IoGetCurrentIrpStackLocation(Irp);
        OutputBufferLength=IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
        InputBufferLength=IrpSp->Parameters.DeviceIoControl.InputBufferLength;
        IoBuffer=Irp->AssociatedIrp.SystemBuffer;
        switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
        {
        case IOCTL_DISK_CHECK_VERIFY:
        case IOCTL_STORAGE_CHECK_VERIFY:
        case IOCTL_STORAGE_CHECK_VERIFY2:
                {
                        Status = STATUS_SUCCESS;
                        Irp->IoStatus.Information = 0;
                        break;
                }
        case IOCTL_DISK_GET_DRIVE_GEOMETRY:
                {
                        PDISK_GEOMETRY DiskGeometry;

                        if (OutputBufferLength<sizeof(DISK_GEOMETRY))
                        {
                                Status=STATUS_BUFFER_OVERFLOW;
                                Irp->IoStatus.Information=0;
                                dprintf("[VirtualDisk] DoVirtualDiskDeviceControl: IOCTL_DISK_GET_DRIVE_GEOMETRY fails.\n");
                                break;
                        }

                        DiskGeometry=(PDISK_GEOMETRY)IoBuffer;
                        RtlZeroMemory(DiskGeometry,sizeof(DISK_GEOMETRY));

                        DiskGeometry->BytesPerSector=SECTOR_SIZE;
                        DiskGeometry->Cylinders.QuadPart=DeviceExtension->EndOfFile.QuadPart/SECTOR_SIZE/32/2;
                        DiskGeometry->TracksPerCylinder=2;
                        DiskGeometry->SectorsPerTrack=32;
                        DiskGeometry->MediaType=FixedMedia;

                        Status = STATUS_SUCCESS;
                        Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);

                        break;
                }
        case IOCTL_DISK_GET_LENGTH_INFO:
                {
                        PGET_LENGTH_INFORMATION LengthInformation;

                        if (OutputBufferLength<sizeof(GET_LENGTH_INFORMATION))
                        {
                                Status=STATUS_BUFFER_OVERFLOW;
                                Irp->IoStatus.Information=0;
                                dprintf("[VirtualDisk] DoVirtualDiskDeviceControl: IOCTL_DISK_GET_LENGTH_INFO fails.\n");
                                break;
                        }

                        LengthInformation=(PGET_LENGTH_INFORMATION) IoBuffer;
                        RtlZeroMemory(LengthInformation,sizeof(GET_LENGTH_INFORMATION));

                        LengthInformation->Length.QuadPart=DeviceExtension->EndOfFile.QuadPart;

                        Status = STATUS_SUCCESS;
                        Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);

                        break;
                }

        case IOCTL_DISK_GET_PARTITION_INFO:
                {
                        PPARTITION_INFORMATION PartitionInformation;

                        dprintf("IOCTL_DISK_GET_PARTITION_INFO .\n");
                        if (OutputBufferLength<sizeof(PARTITION_INFORMATION))
                        {
                                Status=STATUS_BUFFER_OVERFLOW;
                                Irp->IoStatus.Information=0;
                                dprintf("[VirtualDisk] DoVirtualDiskDeviceControl: IOCTL_DISK_GET_PARTITION_INFO fails.\n");
                                break;
                        }

                        PartitionInformation=(PPARTITION_INFORMATION)IoBuffer;
                        RtlZeroMemory(PartitionInformation,sizeof(PARTITION_INFORMATION));

                        PartitionInformation->BootIndicator=FALSE; // not bootable
                        PartitionInformation->HiddenSectors=0; // no hidden sectors
                        PartitionInformation->PartitionLength.QuadPart=DeviceExtension->EndOfFile.QuadPart;
                        PartitionInformation->PartitionNumber=0; // ???? ( 1 based )
                        PartitionInformation->PartitionType=PARTITION_ENTRY_UNUSED; // an unused entry partition
                        PartitionInformation->RecognizedPartition=FALSE;
                        PartitionInformation->RewritePartition=FALSE;
                        PartitionInformation->StartingOffset.QuadPart=0;

                        Status = STATUS_SUCCESS;
                        Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);

                        break;
                }

        case IOCTL_DISK_GET_PARTITION_INFO_EX:
                {
                        PPARTITION_INFORMATION_EX PartitionInformationEx;

                        if (OutputBufferLength<sizeof(PARTITION_INFORMATION_EX))
                        {
                                Status=STATUS_BUFFER_OVERFLOW;
                                Irp->IoStatus.Information=0;
                                dprintf("[VirtualDisk] DoVirtualDiskDeviceControl: IOCTL_DISK_GET_PARTITION_INFO_EX fails.\n");
                                break;
                        }
                        PartitionInformationEx = (PPARTITION_INFORMATION_EX) IoBuffer;
                        RtlZeroMemory(PartitionInformationEx,sizeof(PARTITION_INFORMATION_EX));

                        PartitionInformationEx->PartitionStyle=PARTITION_STYLE_MBR;
                        PartitionInformationEx->StartingOffset.QuadPart=0;
                        PartitionInformationEx->PartitionLength.QuadPart=DeviceExtension->EndOfFile.QuadPart;
                        PartitionInformationEx->PartitionNumber=0;
                        PartitionInformationEx->RewritePartition=FALSE;
                        PartitionInformationEx->Mbr.BootIndicator=FALSE;
                        PartitionInformationEx->Mbr.HiddenSectors=0;
                        PartitionInformationEx->Mbr.PartitionType=PARTITION_ENTRY_UNUSED;
                        PartitionInformationEx->Mbr.RecognizedPartition=FALSE; // ????

                        Status = STATUS_SUCCESS;
                        Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);

                        break;
                }

        case IOCTL_DISK_IS_WRITABLE:
                {
                        //Status=DeviceExtension->IsReadOnly?STATUS_MEDIA_WRITE_PROTECTED:STATUS_SUCCESS;
                        Status=DeviceExtension->IsReadOnly?STATUS_ACCESS_DENIED:STATUS_SUCCESS;
                        Irp->IoStatus.Information = 0;
                        break;
                }

        case IOCTL_DISK_MEDIA_REMOVAL:
        case IOCTL_STORAGE_MEDIA_REMOVAL:
                {
                        Status = STATUS_SUCCESS;
                        Irp->IoStatus.Information = 0;
                        break;
                }

        case IOCTL_DISK_SET_PARTITION_INFO:
                {
                        // in fact, we do nothing
                        if (DeviceExtension->IsReadOnly)
                        {
                                //Status=STATUS_MEDIA_WRITE_PROTECTED;
                                Status=STATUS_ACCESS_DENIED;
                                Irp->IoStatus.Information=0;
                                dprintf("[VirtualDisk] DoVirtualDiskDeviceControl: IOCTL_DISK_SET_PARTITION_INFO fails of read only.\n");
                                break;
                        }
                        if (InputBufferLength<sizeof(SET_PARTITION_INFORMATION))
                        {
                                Status=STATUS_INVALID_PARAMETER;
                                Irp->IoStatus.Information=0;
                                dprintf("[VirtualDisk] DoVirtualDiskDeviceControl: IOCTL_DISK_SET_PARTITION_INFO fails of too small buffer.\n");
                                break;
                        }

                        Status = STATUS_SUCCESS;
                        Irp->IoStatus.Information = 0;

                        break;
                }

        case IOCTL_DISK_VERIFY:
                {
                        PVERIFY_INFORMATION VerifyInformation;

                        if (InputBufferLength<sizeof(VERIFY_INFORMATION))
                        {
                                Status=STATUS_INVALID_PARAMETER;
                                Irp->IoStatus.Information=0;
                                dprintf("[VirtualDisk] DoVirtualDiskDeviceControl: IOCTL_DISK_VERIFY fails.\n");
                                break;
                        }
                        VerifyInformation=(PVERIFY_INFORMATION)IoBuffer;

                        Status = STATUS_SUCCESS;
                        Irp->IoStatus.Information = VerifyInformation->Length;

                        break;
                }

        case IOCTL_STORAGE_GET_DEVICE_NUMBER:
        case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
        case IOCTL_STORAGE_GET_HOTPLUG_INFO:
        case 0x66001B:// FT_BALANCED_READ_MODE
                {
                        Status = STATUS_INVALID_DEVICE_REQUEST;
                        Irp->IoStatus.Information = 0;

                        break;
                }

        default:
                {
                        dprintf("[VirtualDisk] DoVirtualDiskDeviceControl: unexcepted ioctl code: 0x%X.\n",IrpSp->Parameters.DeviceIoControl.IoControlCode);
                        Status=STATUS_INVALID_DEVICE_REQUEST;
                        Irp->IoStatus.Information = 0;
                        break;
                }
        }
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return Status;
}

东西,谢谢共享

TOP

返回列表