内核文件管理-IRP 源代码

IRP_FSD.h 头文件

#pragma once
#include <ntifs.h>

// 使用后需要调用ObRedeference函数关闭文件句柄
NTSTATUS IrpCreateFile(
	OUT PFILE_OBJECT* ppFileObject,					// 用于返回文件句柄的指针
	IN	ACCESS_MASK DesiredAccess,					// 指定访问权限
	IN	PUNICODE_STRING pustrFilePath,				// 文件路径
	OUT PIO_STATUS_BLOCK pIoStatusBlock,			// 用于返回最终完成的状态和其他请求操作的信息
	IN	PLARGE_INTEGER AllocationSize OPTIONAL,		// 包含初始分配大小的LARGE_INTEGER指针(用于文件创建或覆盖, NULL为不分配, 可选)
	IN	ULONG FileAttributes,						// 文件属性
	IN	ULONG ShareAccess,							// 共享访问类型
	IN	ULONG CreateDisposition,					// 指定在文件存在/不存在时要执行的操作
	IN	ULONG CreateOptions,						// 指定创建或打开文件时要应用的选项
	IN	PVOID EaBuffer OPTIONAL,					// 对于设备和中间驱动程序, 此参数必须是NULL指针。
	IN	ULONG EaLength);							//

NTSTATUS IrpQueryInformationFile(
	IN	PFILE_OBJECT pFileObject,						// 文件句柄
	OUT PIO_STATUS_BLOCK IoStatusBlock,					// 用于返回最终完成的状态和其他请求操作的信息
	OUT	PVOID FileInformation,							// 返回的文件信息
	IN	ULONG Length,									// FileInformation结构的长度
	IN	FILE_INFORMATION_CLASS FileInformationClass);	// FileInformatino的类型

NTSTATUS IrpSetInformationFile(
	IN	PFILE_OBJECT pFileObject,						// 文件句柄
	OUT PIO_STATUS_BLOCK IoStatusBlock,					// 用于返回最终完成的状态和其他请求操作的信息
	IN	PVOID FileInformation,							// 设置的文件信息
	IN	ULONG Length,									// FileInformation结构的长度
	IN	FILE_INFORMATION_CLASS FileInformationClass);	// FileInformatino的类型

NTSTATUS IrpReadFile(
	IN	PFILE_OBJECT pFileObject,						// 文件句柄
	OUT PIO_STATUS_BLOCK IoStatusBlock,					// 用于返回最终完成的状态和其他请求操作的信息
	OUT PVOID Buffer,									// 输出缓冲区
	IN	ULONG BufferLength,								// 缓冲区长度
	IN	PLARGE_INTEGER ByteOffset OPTIONAL);			// 读取偏移位置

NTSTATUS IrpWriteFile(
	IN	PFILE_OBJECT pFileObject,						// 文件句柄
	OUT PIO_STATUS_BLOCK IoStatusBlock,					// 用于返回最终完成的状态和其他请求操作的信息
	IN	PVOID Buffer,									// 输入缓冲区
	IN	ULONG BufferLength,								// 缓冲区长度
	IN	PLARGE_INTEGER ByteOffset OPTIONAL);			// 写入偏移位置

NTSTATUS IrpQueryDirectoryFile(
	IN	PFILE_OBJECT pFileObject,						// 文件句柄
	OUT PIO_STATUS_BLOCK IoStatusBlock,					// 用于返回最终完成的状态和其他请求操作的信息
	OUT PVOID FileInformation,							// 输出信息
	IN	ULONG Length,									// FileInformation分配的内存大小
	IN	FILE_INFORMATION_CLASS FileInformationClass,	// FileInformation类型
	IN	PUNICODE_STRING FileName OPTIONAL);				// 用作搜索(可选)

IRP_FSD.c 源文件

#include "IRP_FSD.h"

#define MAX_FILE_NAME_SIZE 512

typedef struct _AUX_ACCESS_DATA {
	PPRIVILEGE_SET PrivilegesUsed;
	GENERIC_MAPPING GenericMapping;
	ACCESS_MASK AccessesToAudit;
	ACCESS_MASK MaximumAuditMask;
	ULONG Unknown[256];
} AUX_ACCESS_DATA, * PAUX_ACCESS_DATA;

NTSTATUS ObCreateObject(
	__in KPROCESSOR_MODE ProbeMode,				// 决定是否要验证参数
	__in POBJECT_TYPE ObjectType,				// 对象类型指针
	__in POBJECT_ATTRIBUTES ObjectAttributes,	// 对象的属性, 最终会转化成ObAllocateObject需要的OBJECT_CREATE_INFORMATION结构
	__in KPROCESSOR_MODE OwnershipMode,			// 指定内核对象还是用户对象, 同上
	__inout_opt PVOID ParseContext,				// 这参数没用
	__in ULONG ObjectBodySize,					// 对象体大小
	__in ULONG PagedPoolCharge,					// ...
	__in ULONG NonPagedPoolCharge,				// ...
	__out PVOID* Object							// 接收对象体的指针
);

NTSTATUS SeCreateAccessState(
	PACCESS_STATE AccessState,
	PVOID AuxData,
	ACCESS_MASK DesiredAccess,
	PGENERIC_MAPPING GenericMapping
);


// 完成实例, 设置事件信号量, 并释放IRP
NTSTATUS CompleteRoutine(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP pIRP,
	IN PVOID Context)
{
	*pIRP->UserIosb = pIRP->IoStatus;
	// 设置事件信号
	if (pIRP->UserEvent)
	{
		KeSetEvent(pIRP->UserEvent, IO_NO_INCREMENT, FALSE);
	}
	// 释放IRP
	IoFreeIrp(pIRP);
	pIRP = NULL;

	return STATUS_MORE_PROCESSING_REQUIRED;
}

// 创建或打开文件
NTSTATUS IrpCreateFile(
	OUT PFILE_OBJECT* ppFileObject,
	IN ACCESS_MASK DesiredAccess,
	IN PUNICODE_STRING pustrFilePath,
	OUT PIO_STATUS_BLOCK pIoStatusBlock,
	IN PLARGE_INTEGER AllocationSize OPTIONAL,
	IN ULONG FileAttributes,
	IN ULONG ShareAccess,
	IN ULONG CreateDisposition,
	IN ULONG CreateOptions,
	IN PVOID EaBuffer OPTIONAL,
	IN ULONG EaLength)
{
	NTSTATUS status = STATUS_SUCCESS;
	UNICODE_STRING ustrRootPath;
	WCHAR wszRootPath[10] = { 0 };
	OBJECT_ATTRIBUTES objectAttributes = { 0 };
	HANDLE hDriver;
	PFILE_OBJECT pDriverFileObject = NULL, pFileObject = NULL;
	KEVENT kEvent = { 0 };
	PDEVICE_OBJECT pDeviceObject = NULL, pRealDevice = NULL;
	PIRP pIRP = NULL;
	AUX_ACCESS_DATA auxAccessData = { 0 };
	ACCESS_STATE accessData = { 0 };
	IO_SECURITY_CONTEXT ioSecurityContext = { 0 };
	PIO_STACK_LOCATION pIoStackLocation = NULL;
	*ppFileObject = NULL;
	
	// 根据文件路径打开文件所在的驱动器,并获得驱动器句柄hDriver
	wcscpy(wszRootPath, L"\\??\\A:\\");
	wszRootPath[4] = pustrFilePath->Buffer[0];
	RtlInitUnicodeString(&ustrRootPath, wszRootPath);
	InitializeObjectAttributes(&objectAttributes, &ustrRootPath, OBJ_KERNEL_HANDLE, NULL, NULL);
	status = IoCreateFile(&hDriver, GENERIC_READ | SYNCHRONIZE, &objectAttributes,
		pIoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 
		FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
		FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone,
		NULL, IO_NO_PARAMETER_CHECKING);
	if (!NT_SUCCESS(status))
	{
		return status;
	}
	// 根据驱动器句柄获取驱动器中的文件对象pDriverFileObject
	status = ObReferenceObjectByHandle(hDriver, FILE_READ_ACCESS, *IoFileObjectType, KernelMode, &pDriverFileObject, NULL);
	if (!NT_SUCCESS(status))
	{
		ZwClose(hDriver);
		return status;
	}
	// 利用文件对象中的VPB获取文件系统逻辑卷对象和物理卷设备, 然后关闭驱动器句柄和文件对象
	pDeviceObject = pDriverFileObject->Vpb->DeviceObject;
	pRealDevice = pDriverFileObject->Vpb->RealDevice;
	ObDereferenceObject(pDriverFileObject);
	ZwClose(hDriver);
	// 根据物理卷设备栈大小创建IRP
	pIRP = IoAllocateIrp(pDeviceObject->StackSize, FALSE);
	if (NULL == pIRP)
	{
		return STATUS_UNSUCCESSFUL;
	}
	// 创建事件
	KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
	// 创建空文件对象pFileObject并设置
	InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE, NULL, NULL);
	status = ObCreateObject(KernelMode, *IoFileObjectType, &objectAttributes, KernelMode, NULL, sizeof(FILE_OBJECT), 0, 0, &pFileObject);
	if (!NT_SUCCESS(status))
	{
		IoFreeIrp(pIRP);
		return status;
	}
	RtlZeroMemory(pFileObject, sizeof(FILE_OBJECT));
	pFileObject->Type = IO_TYPE_FILE;
	pFileObject->Size = sizeof(FILE_OBJECT);
	pFileObject->DeviceObject = pRealDevice;
	pFileObject->Flags = FO_SYNCHRONOUS_IO;
	pFileObject->FileName.Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, MAX_FILE_NAME_SIZE);
	if (pFileObject->FileName.Buffer == NULL)
	{
		IoFreeIrp(pIRP);
		ObDereferenceObject(pFileObject);
		return STATUS_UNSUCCESSFUL;
	}
	pFileObject->FileName.MaximumLength = MAX_FILE_NAME_SIZE;
	pFileObject->FileName.Length = pustrFilePath->Length - 4;
	RtlZeroMemory(pFileObject->FileName.Buffer, MAX_FILE_NAME_SIZE);
	RtlCopyMemory(pFileObject->FileName.Buffer, &pustrFilePath->Buffer[2], pFileObject->FileName.Length);
	KeInitializeEvent(&pFileObject->Lock, SynchronizationEvent, FALSE);
	KeInitializeEvent(&pFileObject->Event, NotificationEvent, FALSE);
	// 创建权限状态设置访问文件的权限
	RtlZeroMemory(&auxAccessData, sizeof(auxAccessData));
	status = SeCreateAccessState(&accessData, &auxAccessData, DesiredAccess, IoGetFileObjectGenericMapping());
	if (!NT_SUCCESS(status))
	{
		IoFreeIrp(pIRP);
		ObDereferenceObject(pFileObject);
		return status;
	}
	// 设置安全内容 IO_SECURITY_CONTEXT
	ioSecurityContext.SecurityQos = NULL;
	ioSecurityContext.AccessState = &accessData;
	ioSecurityContext.DesiredAccess = DesiredAccess;
	ioSecurityContext.FullCreateOptions = 0;
	// 设置IRP
	RtlZeroMemory(pIoStatusBlock, sizeof(IO_STATUS_BLOCK));
	pIRP->MdlAddress = NULL;
	pIRP->AssociatedIrp.SystemBuffer = EaBuffer;
	pIRP->Flags = IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
	pIRP->RequestorMode = KernelMode;
	pIRP->UserIosb = pIoStatusBlock;
	pIRP->UserEvent = &kEvent;
	pIRP->PendingReturned = FALSE;
	pIRP->Cancel = FALSE;
	pIRP->CancelRoutine = NULL;
	pIRP->Tail.Overlay.Thread = PsGetCurrentThread();
	pIRP->Tail.Overlay.AuxiliaryBuffer = NULL;
	pIRP->Tail.Overlay.OriginalFileObject = pFileObject;
	// 获取下一个IRP的IO_STACK_LOCATION并设置
	pIoStackLocation = IoGetNextIrpStackLocation(pIRP);
	pIoStackLocation->MajorFunction = IRP_MJ_CREATE;
	pIoStackLocation->DeviceObject = pDeviceObject;
	pIoStackLocation->FileObject = pFileObject;
	pIoStackLocation->Parameters.Create.SecurityContext = &ioSecurityContext;
	pIoStackLocation->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
	pIoStackLocation->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
	pIoStackLocation->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
	pIoStackLocation->Parameters.Create.EaLength = EaLength;
	// 设置完成实例, 以便通知IRP处理完成, 释放资源
	IoSetCompletionRoutine(pIRP, CompleteRoutine, NULL, TRUE, TRUE, TRUE);
	// 发送IRP
	status = IoCallDriver(pDeviceObject, pIRP);
	// 等待IRP处理完成
	if (STATUS_PENDING == status)
	{
		KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, NULL);
	}
	// 判断IRP处理结果
	status = pIoStatusBlock->Status;
	if (!NT_SUCCESS(status))
	{
		ObDereferenceObject(pFileObject);
		return status;
	}
	InterlockedIncrement(&pFileObject->DeviceObject->ReferenceCount);
	if (pFileObject->Vpb)
	{
		InterlockedIncrement(&pFileObject->Vpb->ReferenceCount);
	}
	// 返回文件对象
	*ppFileObject = pFileObject;
	
	return status;
}

// 获取文件的信息
NTSTATUS IrpQueryInformationFile(
	IN	PFILE_OBJECT pFileObject,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	OUT	PVOID FileInformation,
	IN	ULONG Length,
	IN	FILE_INFORMATION_CLASS FileInformationClass)
{
	NTSTATUS status = STATUS_SUCCESS;
	PDEVICE_OBJECT pDevObj = NULL;
	PIRP pIRP = NULL;
	KEVENT kEvent = { 0 };
	PIO_STACK_LOCATION pIoStackLocation = NULL;

	// 判断参数, 并获得设备对象
	if (NULL == pFileObject)
	{
		return STATUS_UNSUCCESSFUL;
	}
	if (NULL == pFileObject->Vpb)
	{
		return STATUS_UNSUCCESSFUL;
	}
	pDevObj = pFileObject->Vpb->DeviceObject;
	if (NULL == pDevObj)
	{
		return STATUS_UNSUCCESSFUL;
	}
	// 创建IRP和等待IRP处理完成的事件
	pIRP = IoAllocateIrp(pDevObj->StackSize, FALSE);
	if (NULL == pIRP)
	{
		return STATUS_UNSUCCESSFUL;
	}
	KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
	// 设置IRP
	RtlZeroMemory(FileInformation, Length);
	pIRP->UserEvent = &kEvent;
	pIRP->UserIosb = IoStatusBlock;
	pIRP->AssociatedIrp.SystemBuffer = FileInformation;
	pIRP->RequestorMode = KernelMode;
	pIRP->Tail.Overlay.Thread = PsGetCurrentThread();
	pIRP->Tail.Overlay.OriginalFileObject = pFileObject;
	// 获取下一个IRP的IO_STACK_LOCATION并设置
	pIoStackLocation = IoGetNextIrpStackLocation(pIRP);
	pIoStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
	pIoStackLocation->DeviceObject = pDevObj;
	pIoStackLocation->FileObject = pFileObject;
	pIoStackLocation->Parameters.QueryFile.Length = Length;
	pIoStackLocation->Parameters.QueryFile.FileInformationClass = FileInformationClass;
	// 设置完成实例, 以便通知IRP处理完成, 释放资源
	IoSetCompletionRoutine(pIRP, CompleteRoutine, NULL, TRUE, TRUE, TRUE);
	// 发送IRP
	status = IoCallDriver(pDevObj, pIRP);
	// 等待IRP处理完成
	if (STATUS_PENDING == status)
	{
		KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
	}
	// 返回结果
	return IoStatusBlock->Status;
}

// 设置文件信息
NTSTATUS IrpSetInformationFile(
	IN	PFILE_OBJECT pFileObject,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	IN	PVOID FileInformation,
	IN	ULONG Length,
	IN	FILE_INFORMATION_CLASS FileInformationClass
)
{
	NTSTATUS status = STATUS_SUCCESS;
	PDEVICE_OBJECT pDevObj = NULL;
	PIRP pIRP = NULL;
	KEVENT kEvent = { 0 };
	PIO_STACK_LOCATION pIoStackLocation = NULL;

	// 判断参数, 并获得设备对象
	if (NULL == pFileObject)
	{
		return STATUS_UNSUCCESSFUL;
	}
	if (NULL == pFileObject->Vpb)
	{
		return STATUS_UNSUCCESSFUL;
	}
	pDevObj = pFileObject->Vpb->DeviceObject;
	if (NULL == pDevObj)
	{
		return STATUS_UNSUCCESSFUL;
	}
	// 创建IRP和等待IRP处理完成的事件
	pIRP = IoAllocateIrp(pDevObj->StackSize, FALSE);
	if (NULL == pIRP)
	{
		return STATUS_UNSUCCESSFUL;
	}
	KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
	// 设置IRP
	pIRP->UserEvent = &kEvent;
	pIRP->UserIosb = IoStatusBlock;
	pIRP->AssociatedIrp.SystemBuffer = FileInformation;
	pIRP->RequestorMode = KernelMode;
	pIRP->Tail.Overlay.Thread = PsGetCurrentThread();
	pIRP->Tail.Overlay.OriginalFileObject = pFileObject;
	// 获取下一个IRP的IO_STACK_LOCATION并设置
	pIoStackLocation = IoGetNextIrpStackLocation(pIRP);
	pIoStackLocation->MajorFunction = IRP_MJ_SET_INFORMATION;
	pIoStackLocation->DeviceObject = pDevObj;
	pIoStackLocation->FileObject = pFileObject;
	pIoStackLocation->Parameters.SetFile.Length = Length;
	pIoStackLocation->Parameters.SetFile.FileInformationClass = FileInformationClass;
	// 设置完成实例, 以便通知IRP处理完成, 释放资源
	IoSetCompletionRoutine(pIRP, CompleteRoutine, NULL, TRUE, TRUE, TRUE);
	// 发送IRP
	status = IoCallDriver(pDevObj, pIRP);
	// 等待IRP的处理
	if (STATUS_PENDING == status)
	{
		KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
	}
	// 返回结果
	return IoStatusBlock->Status;
}

// 读取文件
NTSTATUS IrpReadFile(
	IN	PFILE_OBJECT pFileObject,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	OUT PVOID Buffer,
	IN	ULONG BufferLength,
	IN	PLARGE_INTEGER ByteOffset OPTIONAL)
{
	NTSTATUS status = STATUS_SUCCESS;
	PDEVICE_OBJECT pDevObj = NULL;
	PIRP pIRP = NULL;
	KEVENT kEvent = { 0 };
	PIO_STACK_LOCATION pIoStackLocation = NULL;

	// 判断参数, 并获得设备对象
	if (NULL == pFileObject)
	{
		return STATUS_UNSUCCESSFUL;
	}
	if (NULL == pFileObject->Vpb)
	{
		return STATUS_UNSUCCESSFUL;
	}
	pDevObj = pFileObject->Vpb->DeviceObject;
	if (NULL == pDevObj)
	{
		return STATUS_UNSUCCESSFUL;
	}
	// 调整参数
	if (NULL == ByteOffset)
	{
		if (0 == (FO_SYNCHRONOUS_IO & pFileObject->Flags))
		{
			return STATUS_INVALID_PARAMETER;
		}
		ByteOffset = &pFileObject->CurrentByteOffset;
	}
	// 创建IRP和等待IRP处理完成的事件
	pIRP = IoAllocateIrp(pDevObj->StackSize, FALSE);
	if (NULL == pIRP)
	{
		return STATUS_UNSUCCESSFUL;
	}
	KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
	// 设置IRP
	RtlZeroMemory(Buffer, BufferLength);
	pIRP->MdlAddress = MmCreateMdl(NULL, Buffer, BufferLength);	// 通过MDL修改内存
	if (NULL == pIRP->MdlAddress)
	{
		IoFreeIrp(pIRP);
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	MmBuildMdlForNonPagedPool(pIRP->MdlAddress);
	pIRP->UserEvent = &kEvent;
	pIRP->UserIosb = IoStatusBlock;
	pIRP->Flags = IRP_READ_OPERATION;
	pIRP->RequestorMode = KernelMode;
	pIRP->Tail.Overlay.Thread = PsGetCurrentThread();
	pIRP->Tail.Overlay.OriginalFileObject = pFileObject;
	// 获取下一个IRP的IO_STACK_LOCATION并设置
	pIoStackLocation = IoGetNextIrpStackLocation(pIRP);
	pIoStackLocation->MajorFunction = IRP_MJ_READ;
	pIoStackLocation->MinorFunction = IRP_MN_NORMAL;
	pIoStackLocation->DeviceObject = pDevObj;
	pIoStackLocation->FileObject = pFileObject;
	pIoStackLocation->Parameters.Read.Length = BufferLength;
	pIoStackLocation->Parameters.Read.ByteOffset = *ByteOffset;
	// 设置完成实例, 以便通知IRP处理完成, 释放资源
	IoSetCompletionRoutine(pIRP, CompleteRoutine, NULL, TRUE, TRUE, TRUE);
	// 发送IRP
	status = IoCallDriver(pDevObj, pIRP);
	// 等待IRP的处理
	if (STATUS_PENDING == status)
	{
		KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
	}
	// 返回结果
	return IoStatusBlock->Status;
}

// 写入文件
NTSTATUS IrpWriteFile(
	IN	PFILE_OBJECT pFileObject,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	IN	PVOID Buffer,
	IN	ULONG BufferLength,
	IN	PLARGE_INTEGER ByteOffset OPTIONAL)
{
	NTSTATUS status = STATUS_SUCCESS;
	PDEVICE_OBJECT pDevObj = NULL;
	PIRP pIRP = NULL;
	KEVENT kEvent = { 0 };
	PIO_STACK_LOCATION pIoStackLocation = NULL;

	// 判断参数, 并获得设备对象
	if (NULL == pFileObject)
	{
		return STATUS_UNSUCCESSFUL;
	}
	if (NULL == pFileObject->Vpb)
	{
		return STATUS_UNSUCCESSFUL;
	}
	pDevObj = pFileObject->Vpb->DeviceObject;
	if (NULL == pDevObj)
	{
		return STATUS_UNSUCCESSFUL;
	}
	// 调整参数
	if (NULL == ByteOffset)
	{
		if (0 == (FO_SYNCHRONOUS_IO & pFileObject->Flags))
		{
			return STATUS_INVALID_PARAMETER;
		}
		ByteOffset = &pFileObject->CurrentByteOffset;
	}
	// 创建IRP和等待IRP处理完成的事件
	pIRP = IoAllocateIrp(pDevObj->StackSize, FALSE);
	if (NULL == pIRP)
	{
		return STATUS_UNSUCCESSFUL;
	}
	KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
	// 设置IRP
	pIRP->MdlAddress = MmCreateMdl(NULL, Buffer, BufferLength);
	if (NULL == pIRP->MdlAddress)
	{
		IoFreeIrp(pIRP);
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	MmBuildMdlForNonPagedPool(pIRP->MdlAddress);
	pIRP->UserEvent = &kEvent;
	pIRP->UserIosb = IoStatusBlock;
	pIRP->Flags = IRP_WRITE_OPERATION;
	pIRP->RequestorMode = KernelMode;
	pIRP->Tail.Overlay.Thread = PsGetCurrentThread();
	pIRP->Tail.Overlay.OriginalFileObject = pFileObject;
	// 获取下一个IRP的IO_STACK_LOCATION并设置
	pIoStackLocation = IoGetNextIrpStackLocation(pIRP);
	pIoStackLocation->MajorFunction = IRP_MJ_WRITE;
	pIoStackLocation->MinorFunction = IRP_MN_NORMAL;
	pIoStackLocation->DeviceObject = pDevObj;
	pIoStackLocation->FileObject = pFileObject;
	pIoStackLocation->Parameters.Write.Length = BufferLength;
	pIoStackLocation->Parameters.Write.ByteOffset = *ByteOffset;
	// 设置完成实例, 以便通知IRP处理完成, 释放资源
	IoSetCompletionRoutine(pIRP, CompleteRoutine, NULL, TRUE, TRUE, TRUE);
	// 发送IRP
	status = IoCallDriver(pDevObj, pIRP);
	// 等待IRP的处理
	if (STATUS_PENDING == status)
	{
		KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
	}
	// 返回结果
	return IoStatusBlock->Status;
}

// 文件遍历
NTSTATUS IrpQueryDirectoryFile(
	IN	PFILE_OBJECT pFileObject,
	OUT PIO_STATUS_BLOCK IoStatusBlock,
	OUT PVOID FileInformation,
	IN	ULONG Length,
	IN	FILE_INFORMATION_CLASS FileInformationClass,
	IN	PUNICODE_STRING FileName OPTIONAL)
{
	NTSTATUS status = STATUS_SUCCESS;
	PIRP pIRP = NULL;
	KEVENT kEvent = { 0 };
	PIO_STACK_LOCATION pIoStackLocation = NULL;
	PDEVICE_OBJECT pDevObj = NULL;

	// 判断参数, 并获得设备对象
	if (NULL == pFileObject)
	{
		return STATUS_UNSUCCESSFUL;
	}
	if (NULL == pFileObject->Vpb)
	{
		return STATUS_UNSUCCESSFUL;
	}
	pDevObj = pFileObject->Vpb->DeviceObject;
	if (NULL == pDevObj)
	{
		return STATUS_UNSUCCESSFUL;
	}
	// 创建IRP和等待IRP处理完成的事件
	pIRP = IoAllocateIrp(pDevObj->StackSize, FALSE);
	if (NULL == pIRP)
	{
		return STATUS_UNSUCCESSFUL;
	}
	KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);
	// 设置IRP
	RtlZeroMemory(FileInformation, Length);
	pIRP->UserEvent = &kEvent;
	pIRP->UserIosb = IoStatusBlock;
	pIRP->UserBuffer = FileInformation;
	pIRP->Tail.Overlay.Thread = PsGetCurrentThread();
	pIRP->Tail.Overlay.OriginalFileObject = pFileObject;
	pIRP->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
	// 获取下一个IRP的IO_STACK_LOCATION并设置
	pIoStackLocation = IoGetNextIrpStackLocation(pIRP);
	pIoStackLocation->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
	pIoStackLocation->MinorFunction = IRP_MN_QUERY_DIRECTORY;
	pIoStackLocation->FileObject = pFileObject;
	pIoStackLocation->Flags = SL_RESTART_SCAN;
	pIoStackLocation->Parameters.QueryDirectory.Length = Length;
	pIoStackLocation->Parameters.QueryDirectory.FileName = FileName;
	pIoStackLocation->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;
	// 设置完成实例, 以便通知IRP处理完成, 释放资源
	IoSetCompletionRoutine(pIRP, CompleteRoutine, NULL, TRUE, TRUE, TRUE);
	// 发送IRP
	status = IoCallDriver(pDevObj, pIRP);
	// 等待IRP的处理
	if (STATUS_PENDING == status)
	{
		KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE, NULL);
	}
	// 返回结果
	return IoStatusBlock->Status;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值