📄 filedisk.c
字号:
NULL,
NULL,
FileDiskThread,
device_object
);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(device_object);
return status;
}
status = ObReferenceObjectByHandle(
thread_handle,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&device_extension->thread_pointer,
NULL
);
if (!NT_SUCCESS(status))
{
ZwClose(thread_handle);
device_extension->terminate_thread = TRUE;
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
IoDeleteDevice(device_object);
return status;
}
ZwClose(thread_handle);
return STATUS_SUCCESS;
}
#pragma code_seg("PAGE")
VOID
FileDiskUnload (
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT device_object;
/*
* 宏 用来确认是否该页在主存中
* 防止将其换出
* 如果换出 则是致命性错误
*/
PAGED_CODE();
device_object = DriverObject->DeviceObject;
while (device_object)
{
device_object = FileDiskDeleteDevice(device_object);
}
ZwClose(dir_handle);
}
PDEVICE_OBJECT
FileDiskDeleteDevice (
IN PDEVICE_OBJECT DeviceObject
)
{
PDEVICE_EXTENSION device_extension;
PDEVICE_OBJECT next_device_object;
PAGED_CODE();
ASSERT(DeviceObject != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
device_extension->terminate_thread = TRUE;
/*
* 使能
* 使线程进行操作
* 功能同 SetEvent
*/
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
/*
* 等待线程执行完毕
* 功能同 WaitForSingleObject
*/
KeWaitForSingleObject(
device_extension->thread_pointer,
Executive,
KernelMode,
FALSE,
NULL
);
/*
* 销毁设备的例行处理
*/
ObDereferenceObject(device_extension->thread_pointer);
if (device_extension->security_client_context != NULL)
{
SeDeleteClientSecurity(device_extension->security_client_context);
ExFreePool(device_extension->security_client_context);
}
next_device_object = DeviceObject->NextDevice;
IoDeleteDevice(DeviceObject);
return next_device_object;
}
NTSTATUS
FileDiskCreateClose (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PAGED_CODE();
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
#pragma code_seg()
NTSTATUS
FileDiskReadWrite (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
PIO_STACK_LOCATION io_stack;
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
/*
* 如果设备没有对应文件
* 返回对应错误
*/
if (!device_extension->media_in_device)
{
Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEDIA_IN_DEVICE;
}
io_stack = IoGetCurrentIrpStackLocation(Irp);
/*
* 如果读取的长度为0
* 直接成功
*/
if (io_stack->Parameters.Read.Length == 0)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
IoMarkIrpPending(Irp);
/*
* 将操作放入到队列中
* 然后让线程进行其他操作
*/
ExInterlockedInsertTailList(
&device_extension->list_head,
&Irp->Tail.Overlay.ListEntry,
&device_extension->list_lock
);
/*
* 使能线程
*/
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
return STATUS_PENDING;
}
NTSTATUS
FileDiskDeviceControl (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
PIO_STACK_LOCATION io_stack;
NTSTATUS status;
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (!device_extension->media_in_device &&
io_stack->Parameters.DeviceIoControl.IoControlCode !=
IOCTL_FILE_DISK_OPEN_FILE)
{
Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_MEDIA_IN_DEVICE;
}
switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
{
/*
* 这里我们主要使用的以下三个:
* IOCTL_FILE_DISK_OPEN_FILE
* IOCTL_FILE_DISK_CLOSE_FILE
* IOCTL_FILE_DISK_QUERY_FILE
*/
case IOCTL_FILE_DISK_OPEN_FILE:
{// 打开
SECURITY_QUALITY_OF_SERVICE security_quality_of_service;
// 设备已经打开
if (device_extension->media_in_device)
{
KdPrint(("FileDisk: IOCTL_FILE_DISK_OPEN_FILE: Media already opened\n"));
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
break;
}
// 传入的参数长度错误
if (io_stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(OPEN_FILE_INFORMATION))
{
status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
// 传入的参数长度错误
if (io_stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(OPEN_FILE_INFORMATION) +
((POPEN_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer)->FileNameLength -
sizeof(UCHAR))
{
status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (device_extension->security_client_context != NULL)
{
SeDeleteClientSecurity(device_extension->security_client_context);
}
else
{
device_extension->security_client_context =
ExAllocatePool(NonPagedPool, sizeof(SECURITY_CLIENT_CONTEXT));
}
RtlZeroMemory(&security_quality_of_service, sizeof(SECURITY_QUALITY_OF_SERVICE));
security_quality_of_service.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
security_quality_of_service.ImpersonationLevel = SecurityImpersonation;
security_quality_of_service.ContextTrackingMode = SECURITY_STATIC_TRACKING;
security_quality_of_service.EffectiveOnly = FALSE;
SeCreateClientSecurity(
PsGetCurrentThread(),
&security_quality_of_service,
FALSE,
device_extension->security_client_context
);
IoMarkIrpPending(Irp);
ExInterlockedInsertTailList(
&device_extension->list_head,
&Irp->Tail.Overlay.ListEntry,
&device_extension->list_lock
);
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
status = STATUS_PENDING;
break;
}
case IOCTL_FILE_DISK_CLOSE_FILE:
{// 关闭
IoMarkIrpPending(Irp);
ExInterlockedInsertTailList(
&device_extension->list_head,
&Irp->Tail.Overlay.ListEntry,
&device_extension->list_lock
);
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
status = STATUS_PENDING;
break;
}
case IOCTL_FILE_DISK_QUERY_FILE:
{
POPEN_FILE_INFORMATION open_file_information;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(OPEN_FILE_INFORMATION) + device_extension->file_name.Length - sizeof(UCHAR))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
open_file_information = (POPEN_FILE_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
open_file_information->FileSize.QuadPart = device_extension->file_size.QuadPart;
open_file_information->ReadOnly = device_extension->read_only;
open_file_information->FileNameLength = device_extension->file_name.Length;
RtlCopyMemory(
open_file_information->FileName,
device_extension->file_name.Buffer,
device_extension->file_name.Length
);
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(OPEN_FILE_INFORMATION) +
open_file_information->FileNameLength - sizeof(UCHAR);
break;
}
case IOCTL_DISK_CHECK_VERIFY:
case IOCTL_CDROM_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:
case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
{
PDISK_GEOMETRY disk_geometry;
ULONGLONG length;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(DISK_GEOMETRY))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
disk_geometry = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
length = device_extension->file_size.QuadPart;
disk_geometry->Cylinders.QuadPart = length / SECTOR_SIZE / 32 / 2;
disk_geometry->MediaType = FixedMedia;
disk_geometry->TracksPerCylinder = 2;
disk_geometry->SectorsPerTrack = 32;
disk_geometry->BytesPerSector = SECTOR_SIZE;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
break;
}
case IOCTL_DISK_GET_LENGTH_INFO:
{
PGET_LENGTH_INFORMATION get_length_information;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(GET_LENGTH_INFORMATION))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
get_length_information = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
get_length_information->Length.QuadPart = device_extension->file_size.QuadPart;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
break;
}
case IOCTL_DISK_GET_PARTITION_INFO:
{
PPARTITION_INFORMATION partition_information;
ULONGLONG length;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(PARTITION_INFORMATION))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
partition_information = (PPARTITION_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
length = device_extension->file_size.QuadPart;
partition_information->StartingOffset.QuadPart = 0;
partition_information->PartitionLength.QuadPart = length;
partition_information->HiddenSectors = 1;
partition_information->PartitionNumber = 0;
partition_information->PartitionType = 0;
partition_information->BootIndicator = FALSE;
partition_information->RecognizedPartition = FALSE;
partition_information->RewritePartition = FALSE;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
break;
}
case IOCTL_DISK_GET_PARTITION_INFO_EX:
{
PPARTITION_INFORMATION_EX partition_information_ex;
ULONGLONG length;
if (io_stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(PARTITION_INFORMATION_EX))
{
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}
partition_information_ex = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer;
length = device_extension->file_size.QuadPart;
partition_information_ex->PartitionStyle = PARTITION_STYLE_MBR;
partition_information_ex->StartingOffset.QuadPart = 0;
partition_information_ex->PartitionLength.QuadPart = length;
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -