在开发Windows下文件系统过滤驱动程序时,我们经常需要先查询一下文件的属性信息,为了实现这个小目标,可以调用Windows Native API函数ZwQueryInformationFile并提供希望查询的文件信息类的名字及结构即可。不过如果我们在驱动程序当中自己处理信息查询请求,可以避免IRP重入的问题。
1.自己创建文件信息查询IRP
NTSTATUS
QueryFileInformation(
PDEVICE_OBJECT DeviceObject,
PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass,
PVOID FileInfo,
ULONG FileInfoLength
)
{
PIRP Irp;
KEVENT event;
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION IoStackLocation;
//
// Initialize the event
//
KeInitializeEvent(&event, NotificationEvent, FALSE);
//
// 分配一个IRP,用目标设备对象的StackSize作为新创建IRP的堆栈大小,这是
// 标准的提供堆栈大小的方法。
//
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!Irp)
return FALSE;
//
// 设置IRP头的相关参数,由于我们采用IoAllocateIrp创建的IRP,因此很多
// 域要自己设置,包括安装输入缓冲区,同步事件以及IRP标志字段,这个字段
// 对文件信息查询没有太大的用处,对文件读写十分关键。
//
Irp->AssociatedIrp.SystemBuffer = FileInfo;
Irp->UserEvent = &event;
Irp->UserIosb = &IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->Flags = 0;
//
// 设置IRP堆栈位置中的相关参数,最重要的是MajorFunction,它决定了这个
// IRP的主要功能,另外Parameters.QueryFile.FileInformationClass定义了
// 希望查询哪种文件信息。
//
IoStackLocation = IoGetN