📄 devicethread.c
字号:
#include <ntddk.h>
#include <ntdef.h>
#include <ntdddisk.h>
#include <ntddcdrm.h>
#include <ntverp.h>
#include <ntifs.h>
#include <stdio.h>
#include <DeviceThread.h>
#include <VCD.h>
//////////////////////////////////////////////////////////////////////////
NTSTATUS
VCDOpenFile (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
PCHAR filename;
UCHAR afile_name[MAX_PATH] = {0};
UNICODE_STRING ufile_name;
NTSTATUS status;
OBJECT_ATTRIBUTES object_attributes;
FILE_END_OF_FILE_INFORMATION file_eof;
FILE_BASIC_INFORMATION file_basic;
FILE_STANDARD_INFORMATION file_standard;
FILE_ALIGNMENT_INFORMATION file_alignment;
DbgPrint("VCDOpenFile\n");
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
filename = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
RtlCopyMemory(device_extension->oldfile_name,
filename,
MAX_PATH);
if (filename[0] == '\\')
{
if (filename[1] == '\\')
// \\server\share\path\XXX.iso ->\??\UNC\\server\share\path\XXX.iso
{
strcpy(afile_name, "\\??\\UNC");
strcat(afile_name, filename);
}
else
// \Device\Harddisk0\Partition1\path\XXX.iso 不变
{
strcpy(afile_name, filename);
}
}
else
// c:\path\XXX.iso ->\??\c:\path\XXX.iso
{
strcpy(afile_name, "\\??\\");
strcat(afile_name, filename);
}
device_extension->file_name.Length = (USHORT)strlen(afile_name);
device_extension->file_name.MaximumLength = device_extension->file_name.Length;
device_extension->file_name.Buffer = ExAllocatePool(NonPagedPool, device_extension->file_name.Length);
RtlCopyMemory(
device_extension->file_name.Buffer,
afile_name,
device_extension->file_name.Length
);
status = RtlAnsiStringToUnicodeString(
&ufile_name,
&device_extension->file_name,
TRUE
);
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
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,
GENERIC_READ,
&object_attributes,
&Irp->IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
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)
{
//如果长度是0
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
Irp->IoStatus.Status = STATUS_NO_SUCH_FILE;
Irp->IoStatus.Information = 0;
DbgPrint("文件不存在!\n");
return STATUS_NO_SUCH_FILE;
}
else if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
DbgPrint("打开文件失败!\n");
return status;
}
RtlFreeUnicodeString(&ufile_name);
//获取虚拟光盘文件基础信息
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_basic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation
);
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
DbgPrint("1获取文件信息失败!\n");
return status;
}
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_standard,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation
);
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
DbgPrint("2获取文件信息失败!\n");
return status;
}
device_extension->file_size.QuadPart = file_standard.EndOfFile.QuadPart;
DbgPrint("文件长度[%d]!\n",device_extension->file_size.QuadPart);
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_alignment,
sizeof(FILE_ALIGNMENT_INFORMATION),
FileAlignmentInformation
);
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
DbgPrint("3获取文件信息失败!\n");
return status;
}
DeviceObject->AlignmentRequirement = file_alignment.AlignmentRequirement;
//只读
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
VCDCloseFile(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
DbgPrint("VCDCloseFile\n");
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
device_extension->media_in_device = FALSE;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////
VOID
DeviceThread (
IN PVOID Context
)
{
PDEVICE_OBJECT device_object;
PDEVICE_EXTENSION device_extension;
PLIST_ENTRY request;
PIRP irp;
PIO_STACK_LOCATION io_stack;
PUCHAR system_buffer;
PUCHAR buffer;
DbgPrint("DeviceThread\n");
device_object = (PDEVICE_OBJECT) Context;
device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;
//把线程自身优先级设置较低-----必须如此才能保证对文件读写正常.否则内核模式优先级别高的话写文件会失败
KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
for (;;)
{
//等待事件被触发
KeWaitForSingleObject(
&device_extension->k_event,
Executive,
KernelMode,
FALSE,
NULL
);
DbgPrint("KeWaitForSingleObject被触发\n");
//如果线程结束标志被设置了,就结束自身
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);
DbgPrint("io_stack->MajorFunction=[%u]\n",io_stack->MajorFunction);
switch (io_stack->MajorFunction)
{
//读
case IRP_MJ_READ:
system_buffer = (PUCHAR) MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
if (system_buffer == NULL)
{
irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
irp->IoStatus.Information = 0;
break;
}
buffer = (PUCHAR) ExAllocatePool(PagedPool, io_stack->Parameters.Read.Length);
if (buffer == NULL)
{
irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
irp->IoStatus.Information = 0;
break;
}
ZwReadFile(
device_extension->file_handle,
NULL,
NULL,
NULL,
&irp->IoStatus,
buffer,
io_stack->Parameters.Read.Length,
&io_stack->Parameters.Read.ByteOffset,
NULL
);
RtlCopyMemory(system_buffer, buffer, io_stack->Parameters.Read.Length);
ExFreePool(buffer);
break;
//写,直接返回写保护
case IRP_MJ_WRITE:
irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
break;
//设备控制
case IRP_MJ_DEVICE_CONTROL:
switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
{
//我们定义的打开文件
case IOCTL_VCD_OPEN_FILE:
SeImpersonateClient(device_extension->security_client_context, NULL);
irp->IoStatus.Status = VCDOpenFile(device_object, irp);
DbgPrint("VCDOpenFile=[%u]\n",irp->IoStatus.Status) ;
PsRevertToSelf();
DbgPrint("PsRevertToSelf\n") ;
break;
//我们定义的关闭文件
case IOCTL_VCD_CLOSE_FILE:
irp->IoStatus.Status = VCDCloseFile(device_object, irp);
break;
default:
irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
}
break;
default:
irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
}
IoCompleteRequest(
irp,
(CCHAR) (NT_SUCCESS(irp->IoStatus.Status) ?IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -