  
- 帖子
- 1065
- 积分
- 2031
- 注册时间
- 2011-5-23

|
/*
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;
} |
|