FsRtlCheckOplockEx2 函数 (ntifs.h)

FsRtlCheckOplockEx2 将文件 I/O 操作的 IRP 与当前机会锁同步 (oplock) 状态。

语法

NTSTATUS FsRtlCheckOplockEx2(
  [in]           POPLOCK                       Oplock,
  [in]           PIRP                          Irp,
  [in]           ULONG                         Flags,
  [in]           ULONG                         FlagsEx2,
  [in, optional] PVOID                         CompletionRoutineContext,
  [in, optional] POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine,
  [in, optional] POPLOCK_FS_PREPOST_IRP        PostIrpRoutine,
  [in]           ULONGLONG                     Timeout,
  [in, optional] PVOID                         NotifyContext,
  [in, optional] POPLOCK_NOTIFY_ROUTINE        NotifyRoutine
);

参数

[in] Oplock

指向文件的不透明不锁定结构的指针。 此指针必须已通过先前对 FsRtlInitializeOplock 的调用进行初始化。

[in] Irp

指向声明所请求 I/O 操作的 IRP 的指针。

[in] Flags

关联文件 I/O 操作的位掩码。 文件系统或筛选器驱动程序设置位以指定 FsRtlCheckOplockEx2 的行为。 标志 具有以下选项:

标志值 含义
OPLOCK_FLAG_COMPLETE_IF_OPLOCKED (0x00000001) 指定允许 oplock 中断继续,而不会阻止或挂起导致 oplock 中断的操作。
OPLOCK_FLAG_OPLOCK_KEY_CHECK_ONLY (0x00000002) 指定 FsRtlCheckOplockEx2 应仅为与 Irp 参数指向的 IRP 关联的FILE_OBJECT上的 oplock 键检查。 如果 IRP 中提供了密钥,则 FsRtlCheckOplockEx2 必须添加密钥。 不会发生其他 oplock 处理;也就是说,不会发生 oplock 中断。 从 Windows 7 开始受支持。
OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK (0x00000004) 指定 FsRtlCheckOplockEx2 应还原之前通过调用 FsRtlOplockFsctrl 例程设置的任何状态。 FsRtlOplockFsctrl 是在处理IRP_MJ_CREATE请求期间调用的,该请求在 create options 参数中指定FILE_OPEN_REQUIRING_OPLOCK标志。 OPLOCK_FLAG_BACK_OUT_ATOMIC_OPLOCK标志通常在之前失败时用于此类创建请求的最终处理中。 从 Windows 7 开始受支持。
OPLOCK_FLAG_IGNORE_OPLOCK_KEYS (0x00000008) 指定允许所有 oplock 中断继续进行,而不考虑 oplock 键。 从 Windows 7 开始受支持。
OPLOCK_FLAG_PARENT_OBJECT (0x00000010) 指定 Oplock 与 Irp参数中的 IRP 定向到的文件或目录的父 (目录) 相关联。 从 Windows 8 开始支持。
OPLOCK_FLAG_CLOSING_DELETE_ON_CLOSE (0x00000020) 指定 Irp 中指定的 I/O 操作是最初使用创建选项中设置FILE_DELETE_ON_CLOSE标志打开的句柄的IRP_MJ_CLEANUP。 如果 Irp 不是IRP_MJ_CLEANUP操作,则此标志无效。 指定此标志可能会导致 oplock 中断。 从 Windows 8 开始支持。
OPLOCK_FLAG_REMOVING_FILE_OR_LINK (0x00000040) 指定在删除父目录的文件或链接时处理父目录上的 oplock 中断。 如果指定,则必须将此标志与 OPLOCK_FLAG_PARENT_OBJECT 组合在一起。 当文件系统正在处理导致删除链接或文件的操作时,必须指定此标志。 从 Windows 8 开始支持。

[in] FlagsEx2

保留;必须设置为零。

[in, optional] CompletionRoutineContext

指向要传递给 CompletionRoutine 参数指向的回调例程的调用方定义的上下文信息的指针。 此参数是可选的,可以为 NULL

[in, optional] CompletionRoutine

指向调用方提供的回调例程的指针。 如果正在进行 oplock 中断,则此例程在中断完成时调用。 此参数是可选的,可以为 NULL。 如果为 NULL,FsRtlCheckOpLockEx2 将同步运行,使调用方进入等待状态,直到操作锁中断完成。

CompletionRoutine 声明如下:

typedef VOID
(*POPLOCK_WAIT_COMPLETE_ROUTINE) (
      IN PVOID Context,
      IN PIRP Irp
      );

CompletionRoutine 具有以下参数:

  • Context:在 Context 参数中传递给 FsRtlCheckOplockEx2上下文信息指针。
  • Irp:指向 I/O 操作的 IRP 的指针。

[in, optional] PostIrpRoutine

指向调用方提供的回调例程的指针,在 I/O 操作发布到工作队列时要调用。 此参数是可选的,可以为 NULL

PostIrpRoutine 的声明如下:

typedef VOID
(*POPLOCK_FS_PREPOST_IRP) (
      IN PVOID Context,
      IN PIRP Irp
      );

PostIrpRoutine 具有以下参数:

  • Context,它是在 Context 参数中传递给 FsRtlCheckOplockEx2上下文信息指针。
  • Irp:指向 I/O 操作的 IRP 的指针。

[in] Timeout

如果为非零,则指定超时 (以毫秒为单位,) 等待用于阻止调用方线程的事件,以便等待 oplock 中断完成。 除非满足以下两个条件,否则将忽略此值: CompletionRoutineNULL,NotifyRoutine 不为 NULL。

[in, optional] NotifyContext

指向要传递给 NotifyRoutine 参数指向的回调例程的OPLOCK_NOTIFY_PARAMS结构的指针。 此参数是可选的,可以为 NULL

[in, optional] NotifyRoutine

指向调用方提供的回调例程的指针,该例程要为 oplock 状态通知调用。 此参数是可选的,可以为 NULL

NotifyRoutine 的声明如下:

typedef NTSTATUS
(*POPLOCK_NOTIFY_ROUTINE) (
      IN POPLOCK_NOTIFY_PARAMS NotifyParams
      );

NotifyRoutine 具有以下参数:

  • NotifyParams,设置为传递给 FsRtlCheckOplockEx2NotifyContext 参数。

返回值

FsRtlCheckOplockEx2 返回STATUS_SUCCESS或相应的 NTSTATUS 代码,如下所示:

返回代码 说明
STATUS_CANCELLED IRP 已取消。 STATUS_CANCELLED是错误代码。
STATUS_CANNOT_BREAK_OPLOCK 无法实现 oplock 中断。 IRP 是一个IRP_MJ_CREATE请求。 FILE_OPEN_REQUIRING_OPLOCK是在操作的 create options 参数中指定的,并且有一个已授予的 oplock。
STATUS_OPLOCK_BREAK_IN_PROGRESS 正在中断 oplock。 IRP 是一个IRP_MJ_CREATE请求,FILE_COMPLETE_IF_OPLOCKED是在操作的 create options 参数中指定的。 STATUS_OPLOCK_BREAK_IN_PROGRESS是一个成功代码,如果设置了OPLOCK_FLAG_COMPLETE_IF_OPLOCKED,并且 oplock 已中断,则返回该代码。
STATUS_PENDING 正在中断 oplock,并且 IRP 的控制权已传递给 oplock 包。 如果 CompletionRoutineNULL,则 FsRtlCheckOplockEx2 将在处理 oplock 中断时阻止,而不是返回STATUS_PENDING。 STATUS_PENDING是一个成功的代码。

注解

微筛选器应调用 FltCheckOplockEx 而不是 FsRtlCheckOplockEx2

FsRtlCheckOplockEx2 根据以下条件将 I/O 操作的 IRP 与文件的当前 oplock 状态同步:

  • 如果 I/O 操作会导致 oplock 中断,则会启动 oplock 中断。

  • 如果 I/O 操作在 oplock 中断完成并且指定 CompletionRoutine 中的完成例程之前无法继续, 则 FsRtlCheckOplockEx2 将返回STATUS_PENDING并调用 PostIrpRoutine 中指定的回调例程。 确认 oplock 中断后,将调用 CompletionRoutine 中的回调例程。

  • 如果 I/O 操作在 oplock 中断完成且未指定 CompletionRoutine 之前无法继续,则调用方线程将被阻止,并且 FsRtlCheckOplockEx2 仅在 oplock 中断完成时返回。

如果调用方线程被阻止且 NotifyRoutine 不为 NULL,则将出于 NotifyParams 中设置的以下任何或所有原因调用 NotifyRoutine

  • OPLOCK_NOTIFY_BREAK_WAIT_INTERIM_TIMEOUT
  • OPLOCK_NOTIFY_BREAK_WAIT_TERMINATED

仅当 CompletionRoutine 为 NULL 并且需要阻止调用方的线程以等待中断完成时,才会出于上述任何原因调用 NotifyRoutine

如果出于OPLOCK_NOTIFY_BREAK_WAIT_INTERIM_TIMEOUT原因调用 NotifyRoutine ,则始终会出于原因OPLOCK_NOTIFY_BREAK_WAIT_TERMINATED如果等待因任何原因终止/完成, (可能永远不会) 。

FsRtlCheckOplockEx2 忽略 notifyRoutine 返回的OPLOCK_NOTIFY_BREAK_WAIT_INTERIM_TIMEOUT和OPLOCK_NOTIFY_BREAK_WAIT_TERMINATED状态代码。

仅当指定 CompletionRoutine 时,才应指定 PostIrpRoutine。 如果 PostIrpRoutine 不为 NULL,则会在将任何内容排队到等待的 Irp 队列之前调用它。

如果在 Flags 中指定了 OPLOCK_FLAG_PARENT_OBJECT 标志, FsRtlCheckOplockEx2 将无条件地中断任何现有的父 oplock;也就是说,不考虑 Irp 中的主代码。

如果文件系统使用 oplock,则必须从任何可能导致 oplock 中断的 I/O 操作调度例程调用 FsRtlCheckOplockEx2 。 此规则适用于以下类型的 I/O 操作,因为这些操作可能会导致 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

有关 oplock 的详细信息,请参阅 机会锁

要求

要求
最低受支持的客户端 Windows 10 版本 2004
标头 ntifs.h

另请参阅

FSCTL_OPBATCH_ACK_CLOSE_PENDING

FSCTL_OPLOCK_BREAK_ACKNOWLEDGE

FSCTL_OPLOCK_BREAK_ACK_NO_2

FSCTL_OPLOCK_BREAK_NOTIFY

FSCTL_REQUEST_BATCH_OPLOCK

FSCTL_REQUEST_FILTER_OPLOCK

FSCTL_REQUEST_OPLOCK_LEVEL_1

FSCTL_REQUEST_OPLOCK_LEVEL_2

FltCheckOplockEx

FsRtlCurrentBatchOplock

FsRtlInitializeOplock

FsRtlOplockFsctrl

FsRtlOplockIsFastIoPossible

FsRtlUninitializeOplock

OPLOCK_NOTIFY_PARAMS