IRP_MJ_CREATE (FS 和 FS 筛选器)

发送时

I/O 管理器在以下情况下发送IRP_MJ_CREATE请求:

  • 正在创建新文件或目录。
  • 正在打开现有文件、设备、目录或卷。

通常,此 IRP 是代表已调用 Microsoft Win32 函数(例如 CreateFile )的用户模式应用程序发送的,或者代表调用 了 IoCreateFileIoCreateFileSpecifyDeviceObjectHintZwCreateFileZwOpenFile 等函数的内核模式组件发送。

如果创建请求成功完成,应用程序或内核模式组件将收到文件对象的句柄。

操作:文件系统驱动程序

如果目标设备对象是文件系统的控制设备对象,则文件系统驱动程序的调度例程必须在将 Irp-IoStatus.Status 和 Irp-IoStatus.Information>> 设置为适当的值后完成 IRP 并返回相应的 NTSTATUS 值。

否则,文件系统驱动程序应处理创建请求。

操作:旧版文件系统筛选器驱动程序

如果目标设备对象是筛选器驱动程序的控制设备对象,则筛选器驱动程序的调度例程必须在将Irp-IoStatus.Status 和 Irp-IoStatus.Information>> 设置为适当的值后完成 IRP 并返回相应的 NTSTATUS 值。

否则,筛选器驱动程序应执行任何所需的处理。 然后,根据筛选器的性质,它应完成 IRP 或将其向下传递给堆栈上下一个较低的驱动程序。

通常,筛选器驱动程序不应返回 STATUS_PENDING 以响应 IRP_MJ_CREATE。 但是,如果较低级别的驱动程序返回 STATUS_PENDING,则筛选器驱动程序应将此状态值传递到驱动程序链上。

文件系统筛选器驱动程序编写者应注意 IoCreateStreamFileObject 会导致 将IRP_MJ_CLEANUP 请求发送到卷的文件系统驱动程序堆栈。 由于文件系统通常会创建流文件对象作为 IRP_MJ_CREATE以外的操作的副作用,因此筛选器驱动程序很难可靠地检测流文件对象的创建。 因此,筛选器驱动程序应接收 IRP_MJ_CLEANUP ,并 IRP_MJ_CLOSE 以前看不见的文件对象请求。 对于 IoCreateStreamFileObjectLite,不会发送 IRP_MJ_CLEANUP 请求。

当旧筛选器驱动程序在创建后回调中重新发出创建请求时,它们必须释放并设置与其重分析点关联的缓冲区, (辅助缓冲区) 为 NULL。 如果旧版筛选器驱动程序未释放此缓冲区并将其设置为 NULL,则该驱动程序将泄漏内存。 微筛选器驱动程序不必执行此操作,因为筛选器管理器会为它们执行此操作。

参数

文件系统或旧筛选器驱动程序使用给定的 IRP 调用 IoGetCurrentIrpStackLocation ,以获取指向 IRP 中自己的堆栈位置的指针。 在以下参数中, Irp 指向 IRP而 IrpSp 指向 IO_STACK_LOCATION。 驱动程序可以使用 IRP 和 IRP 堆栈位置的以下成员中设置的信息来处理创建请求。

  • DeviceObject 是指向目标设备对象的指针。

  • Irp->如果文件对象表示具有扩展属性的文件,则 AssociatedIrp.SystemBuffer 指向 FILE_FULL_EA_INFORMATION结构化缓冲区。 否则,此成员将设置为 NULL

  • Irp->标志 设置为此请求的以下标志:

    • IRP_CREATE_OPERATION
    • IRP_DEFER_IO_COMPLETION
    • IRP_SYNCHRONOUS_API
  • Irp->RequestorMode 指示请求操作的进程( KernelMode 或 UserMode )的执行 模式。 如果设置了SL_FORCE_ACCESS_CHECK标志,则必须执行访问检查,即使 Irp-RequestorMode>KernelMode 也是如此。

  • Irp->IoStatus 指向一个 IO_STATUS_BLOCK 结构,该结构接收最终完成状态和有关所请求操作的信息。 文件系统将此结构的 Information 成员设置为以下值之一:

    • FILE_CREATED
    • FILE_DOES_NOT_EXIST
    • FILE_EXISTS
    • FILE_OPENED
    • FILE_OVERWRITTEN
    • FILE_SUPERSEDED
  • Irp->Overlay.AllocationSize 是文件的初始分配大小(以字节为单位)。 除非正在创建、覆盖或取代文件,否则非零值不起作用。

  • IrpSp->FileObject 指向 I/O 管理器为表示要创建或打开的文件而创建的文件对象。 当文件系统处理IRP_MJ_CREATE请求时,它将此文件对象中的 FsContext 和可能为 FsContext2 字段设置为特定于文件系统的值。 因此,在文件系统处理创建请求之前, FsContextFsContext2 字段的值不能被视为有效。 有关详细信息,请参阅 文件流、流上下文和 Per-Stream 上下文

    FltCancelFileOpenIoCancelFileOpen 在文件对象的 Flags 字段中设置FO_FILE_OPEN_CANCELLED标志。 设置此标志表示已取消IRP_MJ_CREATE请求,并将为此文件对象发出 IRP_MJ_CLOSE 请求。 取消创建请求后,无法重新发出该请求。

    IrpSp-FileObject> 参数包含指向 RelatedFileObject 字段的指针,该字段也是FILE_OBJECT结构。 FILE_OBJECT 结构的 RelatedFileObject 字段用于指示给定文件已相对于已打开的文件对象打开。 这通常表示相对文件是目录,但基于流的文件可能相对于已存在的文件流打开。 FILE_OBJECT 结构的 RelatedFileObject 字段仅在处理IRP_MJ_CREATE期间有效。

  • IrpSp->标志 可以设置为以下一个或多个值:

    标志 含义
    SL_FORCE_ACCESS_CHECK 0x01 如果设置了此标志,则即使 IRP-RequestorMode> 的值为 KernelMode,也必须执行访问检查。
    SL_OPEN_PAGING_FILE 0x02 如果设置了此标志,则该文件是分页文件。
    SL_OPEN_TARGET_DIRECTORY 0x04 如果设置了此标志,则应打开文件的父目录。
    SL_STOP_ON_SYMLINK 0x08 如果设置了此标志,I/O 管理器对交汇点和符号链接的自动遍历将被禁止,从而导致打开交汇点和符号链接返回STATUS_REPARSE。
    SL_IGNORE_READONLY_ATTRIBUTE 0x40 如果设置了此标志,则允许使用 FILE_DELETE_ON_CLOSE 选项创建只读文件。 此选项会导致在关闭句柄时删除文件。
    SL_CASE_SENSITIVE 0x80 如果已设置,文件名比较应区分大小写。
  • IrpSp->MajorFunction 设置为 IRP_MJ_CREATE。

  • IrpSp->Parameters.Create.EaLengthIrp-AssociatedIrp.SystemBuffer> 中缓冲区的大小(以字节为单位)。 如果 Irp*->AssociatedIrp.SystemBuffer 的值为 NULL,则此成员必须为零。

  • IrpSp->Parameters.Create.FileAttributes 是创建或打开文件时要应用的属性标志的位掩码。 仅当创建、取代文件或在某些情况下被覆盖时,才会应用显式指定的属性。 默认情况下,此值为FILE_ATTRIBUTE_NORMAL,任何其他标志或兼容标志的 OR 组合都可以替代此值。 此成员对应于 IoCreateFileSpecifyDeviceObjectHint的 FileAttributes 参数。

  • IrpSp->Parameters.Create.Options 是标志的位掩码,指定创建或打开文件时要应用的选项,以及文件已存在时要执行的操作。

    此参数的高 8 位对应于 IoCreateFileSpecifyDeviceObjectHintDisposition 参数。

    此成员的低 24 位对应于 IoCreateFileSpecifyDeviceObjectHintCreateOptions 参数。 执行文件扫描 ((如防病毒程序) )的文件系统筛选器和微筛选器驱动程序应特别注意FILE_COMPLETE_IF_OPLOCKED标志。 如果设置了此标志,则筛选器不得阻止或以其他方式延迟IRP_MJ_CREATE操作。

    如果在预创建 (创建调度) 路径中设置了FILE_COMPLETE_IF_OPLOCKED标志,则筛选器不得启动以下任何类型的操作,因为它们可能会导致 oplock 中断:

    • IRP_MJ_CLEANUP
    • IRP_MJ_CREATE
    • IRP_MJ_FILE_SYSTEM_CONTROL
    • IRP_MJ_FLUSH_BUFFERS
    • IRP_MJ_LOCK_CONTROL
    • IRP_MJ_READ
    • IRP_MJ_SET_INFORMATION
    • IRP_MJ_WRITE

    如果筛选器或微筛选器无法遵循FILE_COMPLETE_IF_OPLOCKED标志,则必须使用 STATUS_SHARING_VIOLATION 完成IRP_MJ_CREATE请求。

    如果在完成 (创建后) 路径中设置了FILE_COMPLETE_IF_OPLOCKED标志,则筛选器应检查文件系统是否已将 Irp-IoStatus.Status> 设置为STATUS_OPLOCK_BREAK_IN_PROGRESS状态值。 如果未设置此状态值,筛选器可以安全地对文件启动上述操作之一。 如果设置了此状态值,则表明操作锁尚未中断,并且筛选器不得启动任何可能导致 oplock 中断的操作。 因此,筛选器必须推迟对文件执行上述所有操作,直到满足以下条件之一:

    • oplock 的所有者向文件系统发送FSCTL_OPLOCK_BREAK_ACKNOWLEDGE请求。
    • 筛选器或微筛选器以外的系统组件向文件系统发送 I/O 请求,该请求必须等待操作锁中断完成, (例如IRP_MJ_READ或IRP_MJ_WRITE) 。 筛选器或微筛选器可以从此新操作的调度 (或预操作回调) 例程启动上述操作之一,因为调度或预操作回调例程将进入等待状态,直到操作锁中断完成。
  • *IrpSp->Parameters.Create.SecurityContext-AccessState> 指向包含对象的主题上下文、授予的访问权限类型和剩余所需访问类型的ACCESS_STATE结构。

  • IrpSp->Parameters.Create.SecurityContext-DesiredAccess> 是一个ACCESS_MASK结构,用于指定为文件请求的访问权限。 有关详细信息,请参阅 IoCreateFileSpecifyDeviceObjectHint的 DesiredAccess 参数的说明。

  • IrpSp->Parameters.Create.ShareAccess 是为文件请求的共享访问权限的位掩码。 如果此成员为零,则请求独占访问权限。 有关详细信息,请参阅 IoCreateFileSpecifyDeviceObjectHintShareAccess 参数的说明。

另请参阅

ACCESS_MASK

ACCESS_STATE

FILE_FULL_EA_INFORMATION

FltCancelFileOpen

FltReissueSynchronousIo

IO_STACK_LOCATION

IO_STATUS_BLOCK

IoCancelFileOpen

IoCheckEaBufferValidity

IoCreateFile

IoCreateFileSpecifyDeviceObjectHint

IoCreateStreamFileObject

IoCreateStreamFileObjectLite

IoGetCurrentIrpStackLocation

IRP

IRP_MJ_CLEANUP

IRP_MJ_CLOSE

IRP_MJ_CREATE (WDK 内核参考)

ZwCreateFile

ZwOpenFile