📄 filedisk.c
字号:
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
partition_information_ex = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer;
length = device_extension->file_information.AllocationSize.QuadPart;
partition_information_ex->PartitionStyle = PARTITION_STYLE_MBR;
partition_information_ex->StartingOffset.QuadPart = SECTOR_SIZE;
partition_information_ex->PartitionLength.QuadPart = length - SECTOR_SIZE;
partition_information_ex->PartitionNumber = 0;
partition_information_ex->RewritePartition = FALSE;
partition_information_ex->Mbr.PartitionType = 0;
partition_information_ex->Mbr.BootIndicator = FALSE;
partition_information_ex->Mbr.RecognizedPartition = FALSE;
partition_information_ex->Mbr.HiddenSectors = 1;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);
break;
}
case IOCTL_DISK_IS_WRITABLE:
{
if (!device_extension->read_only)
{
status = STATUS_SUCCESS;
}
else
{
status = STATUS_MEDIA_WRITE_PROTECTED;
}
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_CDROM_READ_TOC:
{
PCDROM_TOC cdrom_toc;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(CDROM_TOC))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
cdrom_toc = (PCDROM_TOC) Irp->AssociatedIrp.SystemBuffer;
RtlZeroMemory(cdrom_toc, sizeof(CDROM_TOC));
cdrom_toc->FirstTrack = 1;
cdrom_toc->LastTrack = 1;
cdrom_toc->TrackData[0].Control = TOC_DATA_TRACK;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(CDROM_TOC);
break;
}
case IOCTL_DISK_SET_PARTITION_INFO:
{
if (device_extension->read_only)
{
status = STATUS_MEDIA_WRITE_PROTECTED;
Irp->IoStatus.Information = 0;
break;
}
if (io_stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(SET_PARTITION_INFORMATION))
{
status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
}
case IOCTL_DISK_VERIFY:
{
PVERIFY_INFORMATION verify_information;
if (io_stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(VERIFY_INFORMATION))
{
status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
verify_information = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = verify_information->Length;
break;
}
default:
{
KdPrint((
"FileDisk: Unknown IoControlCode %#x\n",
io_stack->Parameters.DeviceIoControl.IoControlCode
));
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
}
}
if (status != STATUS_PENDING)
{
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return status;
}
VOID
FileDiskThread (
IN PVOID Context
)
{
PDEVICE_OBJECT device_object;
PDEVICE_EXTENSION device_extension;
PLIST_ENTRY request;
PIRP irp;
PIO_STACK_LOCATION io_stack;
ASSERT(Context != NULL);
device_object = (PDEVICE_OBJECT) Context;
device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;
KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
for (;;)
{
KeWaitForSingleObject(
&device_extension->request_event,
Executive,
KernelMode,
FALSE,
NULL
);
if (device_extension->terminate_thread)
{
PsTerminateSystemThread(STATUS_SUCCESS);
}
while (request = ExInterlockedRemoveHeadList(
&device_extension->list_head,
&device_extension->list_lock
))
{
irp = CONTAINING_RECORD(request, IRP, Tail.Overlay.ListEntry);
io_stack = IoGetCurrentIrpStackLocation(irp);
switch (io_stack->MajorFunction)
{
case IRP_MJ_READ:
ZwReadFile(
device_extension->file_handle,
NULL,
NULL,
NULL,
&irp->IoStatus,
MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority),
io_stack->Parameters.Read.Length,
&io_stack->Parameters.Read.ByteOffset,
NULL
);
break;
case IRP_MJ_WRITE:
if ((io_stack->Parameters.Write.ByteOffset.QuadPart +
io_stack->Parameters.Write.Length) >
device_extension->file_information.AllocationSize.QuadPart)
{
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
irp->IoStatus.Information = 0;
}
ZwWriteFile(
device_extension->file_handle,
NULL,
NULL,
NULL,
&irp->IoStatus,
MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority),
io_stack->Parameters.Write.Length,
&io_stack->Parameters.Write.ByteOffset,
NULL
);
break;
case IRP_MJ_DEVICE_CONTROL:
switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_FILE_DISK_OPEN_FILE:
SeImpersonateClient(device_extension->security_client_context, NULL);
FileDiskOpenFile(device_object, irp);
PsRevertToSelf();
break;
case IOCTL_FILE_DISK_CLOSE_FILE:
FileDiskCloseFile(device_object, irp);
break;
default:
irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
irp->IoStatus.Information = 0;
}
break;
default:
irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
irp->IoStatus.Information = 0;
}
IoCompleteRequest(
irp,
(CCHAR) (NT_SUCCESS(irp->IoStatus.Status) ?
IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
}
}
}
#pragma code_seg("PAGE")
NTSTATUS
FileDiskOpenFile (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
POPEN_FILE_INFORMATION open_file_information;
ANSI_STRING file_name;
UNICODE_STRING ufile_name;
NTSTATUS status;
OBJECT_ATTRIBUTES object_attributes;
FILE_END_OF_FILE_INFORMATION file_eof;
FILE_ALIGNMENT_INFORMATION file_alignment;
PAGED_CODE();
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
open_file_information = (POPEN_FILE_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
device_extension->read_only = open_file_information->ReadOnly;
if (open_file_information->DeviceType == FILE_DEVICE_CD_ROM)
{
device_extension->read_only = TRUE;
}
file_name.Length = open_file_information->FileNameLength;
file_name.MaximumLength = open_file_information->FileNameLength;
file_name.Buffer = open_file_information->FileName;
status = RtlAnsiStringToUnicodeString(
&ufile_name,
&file_name,
TRUE
);
if (!NT_SUCCESS(status))
{
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
return status;
}
InitializeObjectAttributes(
&object_attributes,
&ufile_name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
status = ZwCreateFile(
&device_extension->file_handle,
device_extension->read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
&object_attributes,
&Irp->IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE |
FILE_RANDOM_ACCESS |
FILE_NO_INTERMEDIATE_BUFFERING |
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
if (status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_NO_SUCH_FILE)
{
if (device_extension->read_only || open_file_information->FileSize.QuadPart == 0)
{
RtlFreeUnicodeString(&ufile_name);
Irp->IoStatus.Status = STATUS_NO_SUCH_FILE;
Irp->IoStatus.Information = 0;
return STATUS_NO_SUCH_FILE;
}
else
{
status = ZwCreateFile(
&device_extension->file_handle,
GENERIC_READ | GENERIC_WRITE,
&object_attributes,
&Irp->IoStatus,
&open_file_information->FileSize,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE |
FILE_RANDOM_ACCESS |
FILE_NO_INTERMEDIATE_BUFFERING |
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
if (!NT_SUCCESS(status))
{
RtlFreeUnicodeString(&ufile_name);
return status;
}
if (Irp->IoStatus.Information == FILE_CREATED)
{
file_eof.EndOfFile.QuadPart = open_file_information->FileSize.QuadPart;
status = ZwSetInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_eof,
sizeof(FILE_END_OF_FILE_INFORMATION),
FileEndOfFileInformation
);
if (!NT_SUCCESS(status))
{
RtlFreeUnicodeString(&ufile_name);
ZwClose(device_extension->file_handle);
return status;
}
}
}
}
else if (!NT_SUCCESS(status))
{
RtlFreeUnicodeString(&ufile_name);
return status;
}
RtlFreeUnicodeString(&ufile_name);
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&device_extension->file_information,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation
);
if (!NT_SUCCESS(status))
{
ZwClose(device_extension->file_handle);
return status;
}
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_alignment,
sizeof(FILE_ALIGNMENT_INFORMATION),
FileAlignmentInformation
);
if (!NT_SUCCESS(status))
{
ZwClose(device_extension->file_handle);
return status;
}
DeviceObject->AlignmentRequirement = file_alignment.AlignmentRequirement;
if (open_file_information->DeviceType != 0)
{
DeviceObject->DeviceType = open_file_information->DeviceType;
}
else
{
DeviceObject->DeviceType = FILE_DEVICE_DISK;
}
if (device_extension->read_only)
{
DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
}
else
{
DeviceObject->Characteristics &= ~FILE_READ_ONLY_DEVICE;
}
device_extension->media_in_device = TRUE;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
NTSTATUS
FileDiskCloseFile (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
PAGED_CODE();
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
device_extension->media_in_device = FALSE;
ZwClose(device_extension->file_handle);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -