📄 irpfile.c
字号:
//分配一个IRP
Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
if(Irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );
RtlZeroMemory(FileInformation, Length);
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock; //输出参数
Irp->UserBuffer = FileInformation; //I/O缓冲区的用户空间地址
Irp->Tail.Overlay.Thread = PsGetCurrentThread(); //获取当前线程
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
IrpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
IrpSp->FileObject = FileObject;
IrpSp->Flags = SL_RESTART_SCAN;
IrpSp->Parameters.QueryDirectory.Length = Length; //输入参数
IrpSp->Parameters.QueryDirectory.FileName = FileName; //输入参数
IrpSp->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;//输入参数
IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(FileObject->Vpb->DeviceObject, Irp); //IoCallDriver最好自己实现
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
return IoStatusBlock->Status;
}
/*
NTSTATUS
IrpDirectoryQuery(
IN PFILE_OBJECT FileObject,
IN FILE_INFORMATION_CLASS FileInformationClass,
OUT PVOID Buffer,
IN ULONG Length
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION irpSp;
PDEVICE_OBJECT deviceObject;
PQUERY_DIRECTORY queryDirectory;
if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
return STATUS_UNSUCCESSFUL;
deviceObject = FileObject->Vpb->DeviceObject;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->Flags = IRP_INPUT_OPERATION | IRP_BUFFERED_IO;
irp->RequestorMode = KernelMode;
irp->UserEvent = &event;
irp->UserIosb = &ioStatus;
irp->UserBuffer = Buffer;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
//irp->Pointer = FileObject;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
irpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
irpSp->DeviceObject = deviceObject;
irpSp->FileObject = FileObject;
queryDirectory = (PQUERY_DIRECTORY)&irpSp->Parameters; //PQUERY_DIRECTORY
queryDirectory->Length = Length; //ULONG Length
queryDirectory->FileName = NULL; //PUNICODE_STRING FileName;
queryDirectory->FileInformationClass = FileInformationClass; //FILE_INFORMATION_CLASS FileInformationClass;
queryDirectory->FileIndex = 0; //ULONG
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(deviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
status = ioStatus.Status;
}
return status;
}
*/
//IRP_MJ_QUERY_INFORMATION
//NtQueryInformationFile
//取得文件信息
NTSTATUS
IrpQueryInformationFile(
IN PFILE_OBJECT FileObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass )
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
if ( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
return STATUS_UNSUCCESSFUL;
Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
if( Irp == NULL )
return STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );
RtlZeroMemory( FileInformation, Length );
Irp->AssociatedIrp.SystemBuffer = FileInformation; //输出参数
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.QueryFile.Length = Length; //输入参数
IrpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass; //输入参数
IoSetCompletionRoutine( Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE );
ntStatus = IoCallDriver( FileObject->Vpb->DeviceObject, Irp );
if ( ntStatus == STATUS_PENDING )
KeWaitForSingleObject( &kEvent, Executive, KernelMode, TRUE, 0 );
return IoStatusBlock->Status;
}
NTSTATUS
IRPQueryInformationFile(
IN PFILE_OBJECT FileObject,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION irpSp;
PDEVICE_OBJECT deviceObject;
if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
return STATUS_UNSUCCESSFUL;
deviceObject = FileObject->Vpb->DeviceObject;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->Flags = IRP_BUFFERED_IO;
irp->AssociatedIrp.SystemBuffer = FileInformation;
irp->RequestorMode = KernelMode;
irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)NULL;
irp->UserEvent = &event;
irp->UserIosb = &ioStatus;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
irpSp->DeviceObject = deviceObject;
irpSp->FileObject = FileObject;
irpSp->Parameters.QueryFile.Length = Length;
irpSp->Parameters.QueryFile.FileInformationClass = FileInformationClass;
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(deviceObject, irp);
if (status == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
return ioStatus.Status;
}
//IRP_MJ_SET_INFORMATION
//NtSetInformationFile
//设置文件信息:删除,改名,改属性
NTSTATUS
IrpSetInformationFile(
IN PFILE_OBJECT FileObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReplaceIfExists)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
if ( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
return STATUS_UNSUCCESSFUL;
Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
if( Irp == NULL )
return STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );
Irp->AssociatedIrp.SystemBuffer = FileInformation;
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.SetFile.ReplaceIfExists = ReplaceIfExists;
IrpSp->Parameters.SetFile.FileObject = FileObject;
IrpSp->Parameters.SetFile.AdvanceOnly = FALSE;
IrpSp->Parameters.SetFile.Length = Length;
IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;
IoSetCompletionRoutine( Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE );
ntStatus = IoCallDriver( FileObject->Vpb->DeviceObject, Irp );
if (ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);
return IoStatusBlock->Status;
}
//IRP_MJ_READ
//NtReadFile
//读文件
NTSTATUS IrpReadFile(
IN PFILE_OBJECT FileObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
if( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
return STATUS_UNSUCCESSFUL;
if( ByteOffset == NULL )
{
if( !(FileObject->Flags & FO_SYNCHRONOUS_IO) )
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
if( Irp == NULL )
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory( Buffer, Length );
//FileObject->DeviceObject->Flags指定这个设备的缓冲区策略DO_BUFFER_IO、DO_DIRECT_IO
if( FileObject->DeviceObject->Flags & DO_BUFFERED_IO )
{
//如果驱动程序执行缓冲I/O,指向系统空间缓冲区的指针
Irp->AssociatedIrp.SystemBuffer = Buffer;
}
else if( FileObject->DeviceObject->Flags & DO_DIRECT_IO )
{
//如果设备执行直接I/O,指向用户空间缓冲区的内存描述符列表的指针
Irp->MdlAddress = IoAllocateMdl( Buffer, Length, 0, 0, 0 );
if ( Irp->MdlAddress == NULL )
{
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
MmBuildMdlForNonPagedPool( Irp->MdlAddress );
}
else
{
Irp->UserBuffer = Buffer;
}
KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_READ_OPERATION;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject; //输入的文件对象
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_READ;
IrpSp->MinorFunction = IRP_MN_NORMAL;
IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.Read.Length = Length;
IrpSp->Parameters.Read.ByteOffset = *ByteOffset;
//接着要考虑如果IRP不能及时完成,会异步的返回的情况,我们安装一个CompletionRoutine,
//在CompletionRoutine里面设置一个事件为已激活,
//通知我们的主线程读取或者写入操作已经完成。
IoSetCompletionRoutine( Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE );
ntStatus = IoCallDriver( FileObject->Vpb->DeviceObject, Irp );
if ( ntStatus == STATUS_PENDING )
KeWaitForSingleObject( &kEvent, Executive, KernelMode, TRUE, 0 );
return IoStatusBlock->Status;
}
NTSTATUS
IRPReadFile(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN ULONG Length,
OUT PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatusBlock
)
{
NTSTATUS status;
KEVENT event;
PIRP irp;
PIO_STACK_LOCATION irpSp;
PDEVICE_OBJECT deviceObject;
if (ByteOffset == NULL)
{
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
return STATUS_UNSUCCESSFUL;
deviceObject = FileObject->Vpb->DeviceObject;
irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, TRUE, NULL);
if (irp->MdlAddress == NULL)
{
IoFreeIrp(irp);
return STATUS_INSUFFICIENT_RESOURCES;;
}
MmBuildMdlForNonPagedPool(irp->MdlAddress);
irp->Flags = IRP_READ_OPERATION;
irp->RequestorMode = KernelMode;
irp->UserIosb = IoStatusBlock;
irp->UserEvent = &event;
irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_READ;
irpSp->MinorFunction = IRP_MN_NORMAL;
irpSp->DeviceObject = deviceObject;
irpSp->FileObject = FileObject;
irpSp->Parameters.Read.Length = Length;
irpSp->Parameters.Read.ByteOffset = *ByteOffset;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(deviceObject, irp);
if (status == STATUS_PENDING)
status = KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
return status;
}
//IRP_MJ_WRITE
//NtWriteFile
//写文件
NTSTATUS
IrpWriteFile(
IN PFILE_OBJECT FileObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL)
{
NTSTATUS ntStatus;
PIRP Irp;
KEVENT kEvent;
PIO_STACK_LOCATION IrpSp;
if ( FileObject->Vpb == 0 || FileObject->Vpb->DeviceObject == NULL )
return STATUS_UNSUCCESSFUL;
if ( ByteOffset == NULL )
{
if ( !(FileObject->Flags & FO_SYNCHRONOUS_IO) )
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
Irp = IoAllocateIrp( FileObject->Vpb->DeviceObject->StackSize, FALSE );
if ( Irp == NULL )
return STATUS_INSUFFICIENT_RESOURCES;
if( FileObject->DeviceObject->Flags & DO_BUFFERED_IO )
{
Irp->AssociatedIrp.SystemBuffer = Buffer;
}
else
{
Irp->MdlAddress = IoAllocateMdl( Buffer, Length, 0, 0, 0 );
if (Irp->MdlAddress == NULL)
{
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
MmBuildMdlForNonPagedPool( Irp->MdlAddress );
}
KeInitializeEvent( &kEvent, SynchronizationEvent, FALSE );
Irp->UserEvent = &kEvent;
Irp->UserIosb = IoStatusBlock;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_WRITE_OPERATION;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MajorFunction = IRP_MJ_WRITE;
IrpSp->MinorFunction = IRP_MN_NORMAL;
IrpSp->DeviceObject = FileObject->Vpb->DeviceObject;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.Write.Length = Length;
IrpSp->Parameters.Write.ByteOffset = *ByteOffset;
IoSetCompletionRoutine(Irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver( FileObject->Vpb->DeviceObject, Irp );
if ( ntStatus == STATUS_PENDING )
KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, NULL);
return IoStatusBlock->Status;
}
NTSTATUS
IRPWriteFile(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN ULONG Length,
IN PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatusBlock )
{
NTSTATUS status;
KEVENT event;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
PDEVICE_OBJECT deviceObject;
if (ByteOffset == NULL)
{
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
return STATUS_INVALID_PARAMETER;
ByteOffset = &FileObject->CurrentByteOffset;
}
if (FileObject->Vpb == 0 || FileObject->Vpb->RealDevice == NULL)
return STATUS_UNSUCCESSFUL;
deviceObject = FileObject->Vpb->DeviceObject;
Irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (Irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Irp->MdlAddress = IoAllocateMdl(Buffer, Length, FALSE, TRUE, NULL);
if (Irp->MdlAddress == NULL)
{
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;;
}
MmBuildMdlForNonPagedPool(Irp->MdlAddress);
Irp->Flags = IRP_WRITE_OPERATION;
Irp->RequestorMode = KernelMode;
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = &event;
Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
IrpSp = IoGetNextIrpStackLocation(Irp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -