IRP_MJ_CLEANUP
保持进程定义上下文信息的驱动器,必须在DispatchCleanup中包含cleanup请求。
何时发送: 收到IRP_MJ_CLEANUP意味着请求的目标设备与目标文件的句柄相关(也可能因为io请求后没有释放)
入参: 无
出参: 无
操作: 该IRP在关闭 file object 句柄的进程上下文中发送。因此,驱动器应该释放进程上下文中所指定的资源,比如之前驱动器锁定或映射的user memory等。 如果驱动器的 device objects 状态是exclusive,则该device是独占性的,一次只能为一个线程服务。驱动器必须结束当前目标 device object 队列中的所有IRP,并设置其I/O status block为STATUS_CANCELLED。 另外,驱动器只是需要取消并结束与待释放的file object句柄相关的IRP队列成员。(指向file object的指针位于驱动器IRP IO_STACK_LOCATION的FileObject成员中。)取消队列中的IRP后,驱动器结束了clear up IRP操作,并将自身的I/O status block置为STATUS_SUCCESS。 //------------------------------------------------------------------------------------------
IRP_MJ_CLOSE
驱动器必须在DispatchClose中包含关闭请求和驱动器的可能发生的异常,因为该驱动器只能通过关闭系统来卸载设备,保持了系统分页文件的的磁盘驱动器就属于这类驱动器。具有该类特性驱动器支持动态卸载。
何时发送: 收到IRP_MJ_CLOSE请求意味着与目标device object相关的file object句柄已经关闭或释放。所有的外部I/O请求都已结束或取消。
入参: 无
出参: 无
操作: 很少有设备会设置IRP的status block为STATUS_SUCCESS结束关闭请求。驱动器如何处理关闭请求取决于其设计。通常,驱动器在收到IRP_MJ_CREATE后会 undo自己的操作结果。device object为exclusive的驱动器,比如串行驱动器,在收到该请求后也可能会reset硬件。 IRP_MJ_CLOSE不是在关闭了file object句柄的进程上下文中发送的。如果驱动器必须释放进程指定的资源,比如驱动器之前锁定或映射的user memeory等,就会对IRP_MJ_CLEANUP请求做同样的响应。 //------------------------------------------------------------------------------------------
IRP_MJ_CREATE
kernel-mode驱动器必须在DispatchCreate或DispatchCreateClose中提出创建请求。
何时发送: 收到该请求意味着user-mode保护的子系统(可能代表的是某个应用程序),请求一个file object句柄,该局并代表特定的目标device object,或者是较高级别的驱动器正在连接器device object到目标device object。
入参: 无
出参: 无
操作: 与IRP_MJ_CLOSE类似,对IRP_MJ_CREATE的相应取决与驱动器的设计,很少有驱动器会设置IRP的I/O status block为STATUS_SUCCESS。带有pageable-image单元的驱动器,像系统串行驱动器,会通过映射自身的page-out代码, 来为那些尝试打开设备进行I/O操作的user-mode线程提供资源。
//------------------------------------------------------------------------------------------
IRP_MJ_DIRECTORY_CONTROL
何时发送: IRP_MJ_DIRECTORY_CONTROL请求是由I/O管理器和其他操作系统组件(比如kernel-mode驱动器)发送的。当user- mode程序调用ReadDirectoryChangesW、FindNextVolumeMountPoint或者kernal-mode componenet调用ZwQueryDirectoryFile时,会发送该请求。
操作:文件系统驱动器 文件系统驱动器通过检查监控程序code来判断判断执行哪一个目录控制操作。有效的监控程序codes: IRP_MN_NOTIFY_CHANGE_DIRECTORY 请求告知目录变更。通常文件系统驱动器会将此IRP放到私有的队列中,而不是立即进行满足该请求。 当目录发生变更时,文件系统驱动器执行通知目录变更操作,出队,结束该IRP。 IRP_MN_QUERY_DIRECTORY 目录查询请求。消息类型因文件系统而异,通常包括以下几种: FileBothDirectoryInformation FileDirectoryInformation FileFullDirectoryInformation FileIdBothDirectoryInformation FileIdFullDirectoryInformation FileNamesInformation FileObjectIdInformation FileReparsePointInformation
注意:FileQuotaInformation类已不再使用,用IRP_MJ_QUERY_QUOTA代替。 执行之后,结束IRP。
操作:文件系统过滤驱动器 过滤驱动器将该IRP向栈上的下一层驱动器传递。 //------------------------------------------------------------------------------------------
IRP_MJ_QUERY_INFORMATION
何时发送: IRP_MJ_QUERY_INFORMATION请求的发送和IRP_MJ_DIRECTORY_CONTROL类似,是由I/O管理器和其他操作系统 组件(比如kernel-mode驱动器)发送的。调用GetFileInformationByHandle或 ZwQueryInformationFile时发送。
操作:文件系统驱动器 文件系统驱动器提取file object信息并进行解析,由此判断用户是打开一个文件还是打开一个目录,这样,驱动器处理查询并结束IRP。如果不能对信息进行提取解析,驱动器结束IRP,不处理查询。 可供查询的文件和目录信息因文件系统而异,通常包括如下几种:
FileAllInformation
FileAttributeTagInformation
FileBasicInformation
FileCompressionInformation
FileEaInformation
FileInternalInformation
FileNameInformation
FileNetworkOpenInformation
FilePositionInformation
FileStandardInformation
FileStreamInformation
ZwQueryInformationFile支持FileAccessInformation, FileAlignmentInformation, 和 FileModeInformation 类型,而无需向文件系统发送IRP_MJ_QUERY_INFORMATION请求,因为他们与文件系统无关。
操作:文件系统过滤驱动器 过滤驱动器将该IRP向栈上的下一层驱动器传递。 //------------------------------------------------------------------------------------------ IRP_MJ_QUERY_VOLUME_INFORMATION
何时发送: IRP_MJ_QUERY_VOLUME_INFORMATION请求由I/O管理器发送。当user-mode程序调用GetDiskFreeSpace或GetFileType时会发送该请求。
操作:文件系统驱动器 文件系统驱动器通过对file object进行提取和解码,判断目标device object是不是该文件系统的control device object。如果是,并且请求的是打开volume(或者打开volume上的object),文件系统驱动器会处理请求并结束IRP。如果不是,文件 系统驱动器查询失败,结束IRP。 可供查询的volume信息类型因文件系统而异,通常有如下几种类型: FileFsAttributeInformation FileFsDeviceInformation FileFsSizeInformation FileFsVolumeInformation
操作:文件系统过滤驱动器 过滤驱动器将该IRP向栈上的下一层驱动器传递。 //------------------------------------------------------------------------------------------
IRP_MJ_READ
向系统传递数据的驱动器必须在DispatchRead或DispatchReadWrite中包含read请求,在此类驱动器上分层的higher-level驱动器也必须这样做。
何时发送: 在完成create请求的之后的时间域内发送。 可能由包含file object句柄(代表请求过从从该device传递数据的目标device object)的user-mode程序或win32组件发送。也可能由创建和设置read IRP的higher-level驱动器发送。
入参: IRP中的驱动器I/O stack位置指示Parameters.Read.Length.传送多少byte数据。 有些驱动器通过Parameters.Read.Key对在device queue或驱动器管理的IRP内部队列中对read请求进行排序。有的驱动器通过Parameters.Read.ByteOffset(指示传送操作的offset)进行排序。
出参: 根据驱动器对device object Flag的是DO_BUFFERED_IO还是DO_DIRECT_IO,采用不同的方法传递数据: The buffer at Irp->AssociatedIrp.SystemBuffer if the driver uses buffered I/O The buffer described by the MDL at Irp->MdlAddress if the underlying device driver uses direct I/O (DMA or PIO)
操作: 接收到read请求之后,higher-level驱动器会通过为next-lower驱动器设置IRP中的I/O stack位置,或者为lower驱动器创建并设置附加的IRP。可以调用IoSetCompletionRoutine设置 IoCompletion(在IRP输入中是可选的,但在driver-created IRP是必须的)。 接收到该请求之后,驱动器将器device传送给系统memory。结束IRP的过程中,驱动器将设置I/O stack block为传递的byte数量。 //------------------------------------------------------------------------------------------
IRP_MJ_SET_INFORMATION
何时发送: IRP_MJ_SET_INFORMATION请求的发送和IRP_MJ_QUERY_INFORMATION、 IRP_MJ_DIRECTORY_CONTROL类似,是由I/O管理器和其他操作系统组件(比如kernel-mode驱动器)发送的。调用 SetEndOfFile或ZwSetInformationFile时发送。
操作:文件系统驱动器 文件系统驱动器提取file object信息并进行解析,由此判断用户是打开一个文件还是打开一个目录,这样,驱动器处理查询并结束IRP。
可供设置的文件、目录属性信息如下:
FileBasicInformation
FileDispositionInformation
FileLinkInformation (for file systems that allow cycles to be created in the directory hierarchy) FilePositionInformation
FileRenameInformation
文件专有属性:
FileAllocationInformation
FileEndOfFileInformation
FileLinkInformation (for file systems, such as NTFS, that do not allow cycles to be created in the directory hierarchy)
FileValidDataLengthInformation
操作:文件系统过滤驱动器 过滤驱动器将该IRP向栈上的下一层驱动器传递。 //------------------------------------------------------------------------------------------
IRP_MJ_SET_INFORMATION* IRP_MJ_SET_INFORMATION (Serial)
何时发送: client通过set information请求改变串行设备上打开的文件结尾位置时发送。
//------------------------------------------------------------------------------------------
IRP_MJ_WRITE
向系统传递数据的驱动器必须在DispatchWrite或DispatchReadWrite中包含write请求,在此类驱动器上分层的higher-level驱动器也必须这样做。
何时发送: 成功结束creat请求的时间域内。 可能由包含file object句柄(代表请求过从从该device传递数据的目标device object)的user-mode程序或win32组件发送。也可能由创建和设置write IRP的higher-level驱动器发送。
入参: IRP中的驱动器I/O stack位置指示Parameters.Write.Length.传送多少byte数据。 有些驱动器通过Parameters.Write.Key对在device queue或驱动器管理的IRP内部队列中对write请求进行排序。有的驱动器通过Parameters.write.ByteOffset(指示传送操作的offset)进行排序。 根据驱动器对device object Flag的是DO_BUFFERED_IO还是DO_DIRECT_IO,采用不同的方法传递数据: The buffer at Irp->AssociatedIrp.SystemBuffer, if the driver uses buffered I/O The buffer described by the MDL at Irp->MdlAddress, if the underlying device driver uses direct I/O (DMA or PIO)
出参: 无
操作: 接收到write请求之后,higher-level驱动器会通过为next-lower驱动器设置IRP中的I/O stack位置,或者为lower驱动器创建并设置附加的IRP。可以调用IoSetCompletionRoutine设置 IoCompletion(在IRP输入中是可选的,但在driver-created IRP是必须的)。之后,驱动器通过IoCallDriver传递请求给next-lower驱动器。 接收到该请求之后,驱动器将数据从系统memory传递到自身的device。结束IRP的过程中,驱动器将设置I/O stack block为传递的byte数量。
//------------------------------------------------------------------------------------------
IRP_MJ_WRITE* 分段写入,提供Offset,每次写入65536字节。