IoCreateFileSpecifyDeviceObjectHint 函数 (ntddk.h)

文件系统筛选器驱动程序使用 IoCreateFileSpecifyDeviceObjectHint 例程,仅向指定设备对象下面的筛选器和文件系统发送创建请求。

语法

NTSTATUS IoCreateFileSpecifyDeviceObjectHint(
  [out]          PHANDLE            FileHandle,
  [in]           ACCESS_MASK        DesiredAccess,
  [in]           POBJECT_ATTRIBUTES ObjectAttributes,
  [out]          PIO_STATUS_BLOCK   IoStatusBlock,
  [in, optional] PLARGE_INTEGER     AllocationSize,
  [in]           ULONG              FileAttributes,
  [in]           ULONG              ShareAccess,
  [in]           ULONG              Disposition,
  [in]           ULONG              CreateOptions,
  [in, optional] PVOID              EaBuffer,
  [in]           ULONG              EaLength,
  [in]           CREATE_FILE_TYPE   CreateFileType,
  [in, optional] PVOID              InternalParameters,
  [in]           ULONG              Options,
  [in, optional] PVOID              DeviceObject
);

参数

[out] FileHandle

指向变量的指针,如果此调用成功,该变量接收文件对象的句柄。

[in] DesiredAccess

标志的位掩码,指定调用方需要对文件或目录的访问类型。 系统定义的 DesiredAccess 标志集确定文件对象的以下特定访问权限。

DesiredAccess 标志 含义
DELETE 可以删除该文件。
FILE_READ_DATA 可从文件中读取数据。
FILE_READ_ATTRIBUTES 可以读取稍后介绍的 FileAttributes 标志。
FILE_READ_EA 可以读取与文件关联的扩展属性 (EA) 。
READ_CONTROL 可以读取与文件关联的 (ACL) 和所有权信息的访问控制列表。
FILE_WRITE_DATA 可将数据写入文件。
FILE_WRITE_ATTRIBUTES 可以写入 FileAttributes 标志。
FILE_WRITE_EA 可以写入与文件关联的扩展属性。
FILE_APPEND_DATA 可将数据追加到文件。
WRITE_DAC 可以编写与该文件关联的 DACL) (任意访问控制列表。
WRITE_OWNER 可以写入与文件关联的所有权信息。
SYNCHRONIZE 调用方可以通过等待返回的 FileHandle 设置为“已信号”状态来同步 I/O 操作的完成。 如果设置了 CreateOptions FILE_SYNCHRONOUS_IO_ALERT 或 FILE_SYNCHRONOUS_IO_NONALERT 标志,则必须设置此标志。
FILE_EXECUTE 可以使用系统分页 I/O 将数据从文件读取到内存中。

IoCreateFileSpecifyDeviceObjectHint 的调用方可以为不表示目录文件的任何文件对象指定以下一个或组合,可能为 ORed 以及前面DesiredAccess 标志列表中的其他兼容标志:

DesiredAccess 到文件值 映射到 DesiredAccess 标志
GENERIC_READ STANDARD_RIGHTS_READ、FILE_READ_DATA、FILE_READ_ATTRIBUTES、FILE_READ_EA和 SYNCHRONIZE。
GENERIC_WRITE STANDARD_RIGHTS_WRITE、FILE_WRITE_DATA、FILE_WRITE_ATTRIBUTES、FILE_WRITE_EA、FILE_APPEND_DATA和 SYNCHRONIZE。
GENERIC_EXECUTE STANDARD_RIGHTS_EXECUTE、SYNCHRONIZE、FILE_READ_ATTRIBUTES 和 FILE_EXECUTE。

STANDARD_RIGHTS_XXX 是预定义的系统值,用于对系统对象强制实施安全性。

如果设置了 FILE_DIRECTORY_FILE CreateOptions 标志, IoCreateFileSpecifyDeviceObjectHint 的调用方可以指定以下一种或组合,可能为 ORed,其中包含前面DesiredAccess 标志列表中的一个或多个兼容标志。

DesiredAccess 到目录值 含义
FILE_LIST_DIRECTORY 可以列出目录中的文件。
FILE_TRAVERSE 可以遍历目录:也就是说,它可以是文件路径名的一部分。

FILE_READ_DATA、FILE_WRITE_DATA、FILE_EXECUTE 和 FILE_APPEND_DATA DesiredAccess 标志与创建或打开目录文件不兼容。

[in] ObjectAttributes

指向已由 InitializeObjectAttributes 例程初始化的OBJECT_ATTRIBUTES结构的指针。 如果调用方在系统进程上下文中运行,则此参数 (ObjectAttributes) 可以为 NULL。 否则,调用方必须在对 InitializeObjectAttributes 例程的调用中设置 OBJ_KERNEL_HANDLE 属性。 文件对象的OBJECT_ATTRIBUTES结构的成员包括以下内容。

成员 Value
ULONGLength 指定提供的 ObjectAttributes 数据的字节数。 此值必须至少 为大小 (OBJECT_ATTRIBUTES)
PUNICODE_STRING ObjectName 指向命名要创建或打开的文件的缓冲 Unicode 字符串的指针。 此值必须是完全限定的文件规范,除非它是相对于 RootDirectory 指定的目录的文件的名称。 例如,\Device\Floppy1\myfile.dat 或 \??\B:\myfile.dat 可能是完全限定的文件规范,前提是已加载软盘驱动程序和过度文件系统。 (注意 \??将 \DosDevices 替换为 Win32 对象命名空间的名称。\DosDevices 仍然有效,但 \??由对象管理器更快地转换。)
HANDLERootDirectory (可选)指定由之前调用 IoCreateFileSpecifyDeviceObjectHint 获取的目录的句柄。 如果此值为 NULL则 ObjectName 成员必须是包含目标文件的完整路径的完全限定文件规范。 如果此值为非 NULL则 ObjectName 成员指定相对于此目录的文件名。
PSECURITY_DESCRIPTOR SecurityDescriptor (可选)指定要应用于文件的安全描述符。 由此类安全描述符指定的 ACL 仅在创建文件时应用于该文件。 如果创建文件时的值为 NULL ,则文件上放置的 ACL 依赖于文件系统;大多数文件系统从父目录文件传播此类 ACL 的某一部分,同时传播调用方的默认 ACL。
ULONGAttributes 一组控制文件对象属性的标志。 如果调用方在系统进程上下文中运行,则此参数可以为零。 否则,调用方必须设置OBJ_KERNEL_HANDLE标志。 调用方还可以选择性地设置OBJ_CASE_INSENSITIVE标志,该标志指示名称查找代码应忽略 ObjectName 的事例,而不是执行完全匹配的搜索。

[out] IoStatusBlock

指向 IO_STATUS_BLOCK 结构的指针,该结构接收最终完成状态和有关所请求操作的信息。 从 IoCreateFileSpecifyDeviceObjectHint 返回时, Information 成员包含以下值之一:

  • FILE_CREATED

  • FILE_OPENED

  • FILE_OVERWRITTEN

  • FILE_SUPERSEDED

  • FILE_EXISTS

  • FILE_DOES_NOT_EXIST

[in, optional] AllocationSize

(可选)指定文件的初始分配大小(以字节为单位)。 除非正在创建、覆盖或取代文件,否则非零值不起作用。

[in] FileAttributes

仅当创建、取代文件或在某些情况下被覆盖时,才会应用显式指定的属性。 默认情况下,此值为FILE_ATTRIBUTE_NORMAL,可由任何其他标志或兼容标志的 ORed 组合重写。 可能的 FileAttributes 标志包括以下内容。

FileAttributes 标志 含义
FILE_ATTRIBUTE_NORMAL 应创建具有标准属性的文件。
FILE_ATTRIBUTE_READONLY 应创建只读文件。
FILE_ATTRIBUTE_HIDDEN 应创建隐藏文件。
FILE_ATTRIBUTE_SYSTEM 应创建系统文件。
FILE_ATTRIBUTE_ARCHIVE 应标记文件,以便将其存档。
FILE_ATTRIBUTE_TEMPORARY 应创建一个临时文件。

[in] ShareAccess

指定调用方希望的对文件的共享访问类型(为零或 1,或以下标志的组合)。 若要请求独占访问权限,请将此参数设置为零。 如果在 Options 参数中指定了 IO_IGNORE_SHARE_ACCESS_CHECK 标志,则 I/O 管理器将忽略此参数。 但是,文件系统可能仍会执行访问检查。 因此,为此参数指定所需的共享模式非常重要,即使使用 IO_IGNORE_SHARE_ACCESS_CHECK 标志也是如此。 为尽量避免共享冲突错误,请指定以下所有共享访问标志。

ShareAccess 标志 含义
FILE_SHARE_READ 文件可以打开以供其他线程读取访问。
FILE_SHARE_WRITE 文件可以打开以供其他线程进行写入访问。
FILE_SHARE_DELETE 文件可以打开以供其他线程删除访问。

[in] Disposition

指定一个值,该值确定要执行的操作,具体取决于文件是否已存在。 该值可以是下面所述的任意值。

处置值 含义
FILE_SUPERSEDE 如果文件已存在,请将它替换为给定的文件。 如果没有,请创建给定的文件。
FILE_CREATE 如果文件已存在,请失败请求,并且不要创建或打开给定的文件。 如果没有,请创建给定的文件。
FILE_OPEN 如果文件已存在,请打开它,而不是创建新文件。 如果没有,则失败请求,并且不创建新文件。
FILE_OPEN_IF 如果文件已存在,请将其打开。 如果没有,请创建给定的文件。
FILE_OVERWRITE 如果文件已存在,请打开它并覆盖它。 否则,请求失败。
FILE_OVERWRITE_IF 如果文件已存在,请打开它并覆盖它。 如果没有,请创建给定的文件。

[in] CreateOptions

指定要在创建或打开文件时应用的选项。 这些选项指定为以下标志的兼容组合。

CreateOptions 标志 含义
FILE_DIRECTORY_FILE 正在创建或打开的文件是目录文件。 如果设置了此标志,则必须将 Disposition 参数设置为FILE_CREATE、FILE_OPEN或FILE_OPEN_IF之一。 此标志与以下 CreateOptions 标志兼容:FILE_SYNCHRONOUS_IO_ALERT、FILE_SYNCHRONOUS_IO_NONALERT、FILE_WRITE_THROUGH、FILE_OPEN_FOR_BACKUP_INTENT和FILE_OPEN_BY_FILE_ID。
FILE_NON_DIRECTORY_FILE 打开的文件不能是目录文件,否则此调用将失败。 要打开的文件对象必须表示数据文件。
FILE_WRITE_THROUGH 将数据写入文件的系统服务、FSD 和驱动程序必须实际将数据传输到文件中,然后才能将请求的任何写入操作视为完成。
FILE_SEQUENTIAL_ONLY 对文件的所有访问都是按顺序进行的。
FILE_RANDOM_ACCESS 对文件的访问可以是随机的,因此 FSD 或系统不应对文件执行顺序预读操作。
FILE_NO_INTERMEDIATE_BUFFERING 文件不能在驱动程序的内部缓冲区中缓存或缓冲。 此标志与 DesiredAccess FILE_APPEND_DATA 标志不兼容。
FILE_SYNCHRONOUS_IO_ALERT 对文件执行的所有操作都是同步执行的。 代表调用方的任何等待都可能提前终止警报。 此标志还会导致 I/O 系统维护文件位置上下文。 如果设置了此标志,还必须设置 DesiredAccess SYNCHRONIZE 标志。
FILE_SYNCHRONOUS_IO_NONALERT 对文件执行的所有操作都是同步执行的。 系统中存在的同步 I/O 排队和完成的等待不受警报约束。 此标志还会导致 I/O 系统维护文件位置上下文。 如果设置了此标志,还必须设置 DesiredAccess SYNCHRONIZE 标志。
FILE_CREATE_TREE_CONNECTION 为此文件创建树连接,以便通过网络打开它。
FILE_COMPLETE_IF_OPLOCKED 如果目标文件已锁定,则立即使用备用成功代码完成此操作,而不是阻止调用方线程。 如果文件已锁定,则另一个调用方已通过网络访问该文件。
FILE_NO_EA_KNOWLEDGE 如果打开的现有文件上的扩展属性指示调用方必须理解 EA 才能正确解释文件,则失败此请求,因为调用方不了解如何处理 EA。
FILE_OPEN_REPARSE_POINT 使用重新分析点打开文件,并绕过文件的正常重新分析点处理。 有关详细信息,请参阅下面的 “备注 ”部分。
FILE_DELETE_ON_CLOSE 在文件的最后一个句柄传递到 ZwClose 时删除该文件。
FILE_OPEN_BY_FILE_ID ObjectAttributes 参数中指定的文件名包括文件的 8 字节文件引用号。 此数字由文件系统分配,特定于文件系统。 如果文件是重分析点,则文件名还包括设备的名称。 注意:FAT 文件系统不支持FILE_OPEN_BY_FILE_ID。
FILE_OPEN_FOR_BACKUP_INTENT 正在为备份意向打开该文件,因此,系统应检查某些访问权限,并在根据文件的安全描述符检查输入 DesiredAccess 之前,向调用方授予对该文件的适当访问权限。
FILE_OPEN_REQUIRING_OPLOCK 正在打开该文件,并且正在请求将文件 (oplock) 的机会锁作为单个原子操作请求。 文件系统在执行创建操作之前会检查 oplock,如果创建操作会中断现有 oplock,则创建操作将失败并返回STATUS_CANNOT_BREAK_OPLOCK代码。
FILE_RESERVE_OPFILTER 此标志允许应用程序请求筛选器机会锁 (oplock) ,以防止其他应用程序获取共享冲突。 如果已有打开的句柄,则创建请求会失败并STATUS_OPLOCK_NOT_GRANTED。 有关更多信息,请参见下面的“备注”部分。

[in, optional] EaBuffer

指向调用方提供的 FILE_FULL_EA_INFORMATION结构化缓冲区的指针,其中包含要应用于文件的扩展属性 (EA) 信息。

[in] EaLength

EaBuffer 的长度(以字节为单位)。

[in] CreateFileType

驱动程序必须将此参数设置为 CreateFileTypeNone。

[in, optional] InternalParameters

驱动程序必须将此参数设置为 NULL

[in] Options

指定要在创建请求期间使用的选项。 下表列出了可用的选项。

选项标志 含义
IO_FORCE_ACCESS_CHECK 指示 I/O 管理器必须针对文件的安全描述符检查创建请求。
IO_IGNORE_SHARE_ACCESS_CHECK 指示 I/O 管理器在创建文件对象后不应对其执行共享访问检查。 但是,文件系统可能仍会执行这些检查。

[in, optional] DeviceObject

指向要向其发送创建请求的设备对象的指针。 设备对象必须是文件或目录所在的卷的文件系统驱动程序堆栈中的筛选器或文件系统设备对象。 此参数是可选的,可以为 NULL。 如果此参数为 NULL,则请求将发送到驱动程序堆栈顶部的设备对象。

返回值

IoCreateFileSpecifyDeviceObjectHint 返回STATUS_SUCCESS或相应的 NTSTATUS 值,例如以下值之一:

返回代码 说明
STATUS_INVALID_DEVICE_OBJECT_PARAMETER 指定的 DeviceObject 不会附加到文件或目录名称中指定的卷的文件系统驱动程序堆栈。 如果名称包含非装入点的重新分析点,也可能发生此错误。
STATUS_MOUNT_POINT_NOT_RESOLVED 文件或目录名称包含一个装入点,该装入点解析为指定的 DeviceObject 所附加到的卷以外的卷。
STATUS_OBJECT_PATH_SYNTAX_BAD

IoCreateFileSpecifyDeviceObjectHint 可能会返回STATUS_FILE_LOCK_CONFLICT作为返回值,或者在 IoStatusBlock 参数指向的 IO_STATUS_BLOCK 结构的 Status 成员中返回。 仅当 NTFS 日志文件已满并且 IoCreateFileSpecifyDeviceObjectHint 尝试处理这种情况时,才会发生此错误。

注解

文件系统筛选器驱动程序使用此例程将创建请求仅发送到指定设备对象下面的筛选器和文件系统。 附加到驱动程序堆栈中指定设备对象上方的筛选器不会收到创建请求。

Windows Vista IoCreateFileEx 例程类似于 IoCreateFileSpecifyDeviceObjectHint 例程,但提供的功能比 IoCreateFileSpecifyDeviceObjectHint 例程更强大,包括访问额外的创建参数 (ECP) 和事务信息。

如果使用 IoCreateFileEx 例程而不是 IoCreateFileSpecifyDeviceObjectHint 例程,请注意,IoCreateFileSpecifyDeviceObjectHint 例程的 DriverContext 参数已移动到 IO_DRIVER_CREATE_CONTEXT 结构的 DeviceObjectHint 成员。 IO_DRIVER_CREATE_CONTEXT 结构通过其 DriverContext 参数传递到 IoCreateFileEx 例程中。

文件系统筛选器驱动程序调用 IoCreateFileSpecifyDeviceObjectHint ,以便仅将创建请求发送到指定的设备对象、其下方附加的筛选器以及文件系统。 驱动程序堆栈中指定设备对象上方附加的筛选器不会接收创建请求。 对于由 IoCreateFileSpecifyDeviceObjectHint 创建的文件对象上的任何清理或关闭请求也是如此。

有两种备用方法来指定要使用 IoCreateFileSpecifyDeviceObjectHint 创建或打开的文件的名称:

  1. 作为完全限定的路径名,在输入 ObjectAttributesObjectName 成员中提供

  2. 作为相对于由输入 ObjectAttributesRootDirectory 成员中的句柄表示的目录文件的路径名

最终必须通过调用 ZwClose 释放从 IoCreateFileSpecifyDeviceObjectHint 获取的任何句柄。

在非系统进程上下文中运行的驱动程序例程必须为 IoCreateFileSpecifyDeviceObjectHintObjectAttributes 参数设置 OBJ_KERNEL_HANDLE 属性。 这会将 IoCreateFileSpecifyDeviceObjectHint 返回的句柄的使用限制为在内核模式下运行的进程。 否则,运行驱动程序的上下文的进程可以访问句柄。

某些 DesiredAccess 标志和标志组合具有以下效果:

  • 对于通过等待返回 的 FileHandle 设置为“已信号”状态来同步 I/O 完成的调用方,必须设置 SYNCHRONIZE 标志。

  • 如果只设置了FILE_APPEND_DATA和 SYNCHRONIZE 标志,则调用方只能写入文件末尾,并且有关写入文件的任何偏移量信息将被忽略。 但是,对于这种类型的写入操作,文件将自动扩展。

  • 为文件设置FILE_WRITE_DATA标志还允许写入文件末尾以外的操作。 文件也会自动扩展为此类写入。

  • 如果只设置了FILE_EXECUTE和 SYNCHRONIZE 标志,则调用方无法使用返回的 FileHandle 直接读取或写入文件中的任何数据;也就是说,对文件的所有操作都通过系统寻呼器进行,以响应指令和数据访问。

ShareAccess 参数确定单独的线程是否可以同时访问同一文件。 如果两个文件打开程序都具有以指定方式访问文件的权限,则可以成功打开和共享该文件。 如果 IoCreateFileSpecifyDeviceObjectHint 的原始调用方未指定FILE_SHARE_READ、FILE_SHARE_WRITE或FILE_SHARE_DELETE,则无法对文件执行其他打开操作:即向原始调用方授予对该文件的独占访问权限。

若要成功打开共享文件,文件请求的 DesiredAccess 必须与之前尚未使用 ZwClose 发布的所有打开的 DesiredAccessShareAccess 规范兼容。 也就是说,为给定文件指定的 IoCreateFileSpecifyDeviceObjectHintDesiredAccess 不得与该文件的其他打开程序已禁止的访问发生冲突。

如果在 Options 参数中指定了IO_IGNORE_SHARE_ACCESS_CHECK,则 I/O 管理器将忽略 ShareAccess 参数。 但是,文件系统可能仍会执行访问检查。 因此,请务必为 ShareAccess 参数指定所需的共享模式,即使使用 IO_IGNORE_SHARE_ACCESS_CHECK 标志也是如此。

处置值FILE_SUPERSEDE要求调用方对现有文件对象具有 DELETE 访问权限。 如果是这样,如果成功调用 IoCreateFileSpecifyDeviceObjectHint 并FILE_SUPERSEDE现有文件,则会有效地删除该文件,然后重新创建该文件。 这意味着,如果文件已被另一个线程打开,则它通过指定一个 ShareAccess 参数来打开文件,并设置了FILE_SHARE_DELETE标志。 请注意,这种类型的处置与覆盖文件的 POSIX 样式一致。

处置值FILE_OVERWRITE_IF和FILE_SUPERSEDE相似。 如果使用现有文件调用 IoCreateFileSpecifyDeviceObjectHint ,并且其中任一 处置 值,则将替换该文件。

覆盖文件在语义上等效于取代操作,但以下情况除外:

  • 调用方必须对文件具有写入访问权限,而不是删除访问权限。 这意味着,如果文件已由另一个线程打开,它将在输入 ShareAccess 中设置FILE_SHARE_WRITE标志打开文件。

  • 指定的文件属性在逻辑上与文件上已有的属性一起为 ORed。 这意味着,如果文件已由另一个线程打开, 则 IoCreateFileSpecifyDeviceObjectHint 的后续调用方无法禁用现有的 FileAttributes 标志,但可以为同一文件启用其他标志。

CreateOptions FILE_DIRECTORY_FILE 值指定要创建或打开的文件是目录文件。 创建目录文件时,文件系统会在磁盘上创建适当的结构,以表示该特定文件系统的磁盘上结构的空目录。 如果指定了此选项,并且要打开的给定文件不是目录文件,或者调用方指定了不一致的 CreateOptionsDisposition 值,则对 IoCreateFileSpecifyDeviceObjectHint 的调用将失败。

CreateOptions FILE_NO_INTERMEDIATE_BUFFERING 标志阻止文件系统代表调用方执行任何中间缓冲。 指定此值对其他 Zw 的调用方参数存在某些限制 。文件 例程,包括以下内容:

  • 传递给 ZwReadFile 或 ZwWriteFile 的任何字节 Offset 值必须是基础设备的扇区大小的倍数。

  • 传递给 ZwReadFileZwWriteFileLength 必须是扇区大小的倍数。 请注意,如果在传输过程中到达文件的末尾,则指定对长度正好为扇区大小的缓冲区的读取操作可能会导致传输到该缓冲区的重要字节数减少。

  • 缓冲区必须根据基础设备的对齐要求进行对齐。 可以通过调用 IoCreateFileSpecifyDeviceObjectHint 获取表示物理设备的文件对象的句柄,然后使用该句柄调用 ZwQueryInformationFile 来获取此信息。 有关系统FILE_XXX_ALIGNMENT值的列表,请参阅 DEVICE_OBJECT

  • 调用 FileInformationClass 参数设置为 FilePositionInformation 的 ZwSetInformationFile 时,必须指定扇区大小的倍数的偏移量。

互斥 的 CreateOptions(FILE_SYNCHRONOUS_IO_ALERT 和 FILE_SYNCHRONOUS_IO_NONALERT)指定,只要通过返回的 FileHandle 引用的文件对象发生,文件上的所有 I/O 操作都将是同步的。 使用返回的句柄跨所有线程序列化此类文件上的所有 I/O。 对于上述任一 CreateOptions,必须设置 DesiredAccess SYNCHRONIZE 标志,以便 I/O 管理器将文件对象用作同步对象。 设置上述任一 CreateOptions 后,I/O 管理器将维护文件对象的“文件位置上下文”,即内部的当前文件位置偏移量。 此偏移量可用于对 ZwReadFileZwWriteFile 的调用。 也可以通过调用 ZwQueryInformationFile 或通过调用 ZwSetInformationFile 来查询其位置。

如果未指定 CreateOptions FILE_OPEN_REPARSE_POINT 标志,并且 IoCreateFileSpecifyDeviceObjectHint 尝试使用重新分析点打开文件,则文件将进行正常的重新分析点处理。 另一方面,如果指定了FILE_OPEN_REPARSE_POINT标志,则不会进行正常的重新分析处理, 并且 IoCreateFileSpecifyDeviceObjectHint 会尝试直接打开重新分析点文件。 在任一情况下,如果打开操作成功, IoCreateFileSpecifyDeviceObjectHint 将返回STATUS_SUCCESS;否则,例程将返回 NTSTATUS 错误代码。 IoCreateFileSpecifyDeviceObjectHint 从不返回STATUS_REPARSE。

CreateOptions FILE_OPEN_REQUIRING_OPLOCK 标志消除了打开文件和请求 oplock 之间的时间,oplock 可能会使第三方打开文件并发生共享冲突。 应用程序可以使用 IoCreateFileSpecifyDeviceObjectHint 上的 FILE_OPEN_REQUIRING_OPLOCK 标志,然后请求任何 oplock。 这可确保 oplock 所有者收到导致共享冲突的任何后续打开请求的通知。

在 Windows 7 中,如果应用程序使用 FILE_OPEN_REQUIRING_OPLOCK 标志时文件上存在其他句柄,则创建操作将失败并出现STATUS_OPLOCK_NOT_GRANTED。 从Windows 8开始,此限制不再存在。

如果此创建操作会中断文件上已存在的 oplock,则设置FILE_OPEN_REQUIRING_OPLOCK标志将导致创建操作失败并出现STATUS_CANNOT_BREAK_OPLOCK。 此创建操作不会破坏现有的 oplock。

使用此标志的应用程序必须在此调用成功后请求 oplock,否则将阻止以后打开该文件的所有尝试,而没有典型 oplock 处理的好处。 同样,如果此调用成功,但后来的 oplock 请求失败,则使用此标志的应用程序必须在检测到 oplock 请求失败后关闭其句柄。

FILE_OPEN_REQUIRING_OPLOCK标志在 Windows 7、Windows Server 2008 R2 和更高版本的 Windows 操作系统中可用。 在 Windows 7 中实现此标志的 Microsoft 文件系统是 NTFS、FAT 和 exFAT。

CreateOptions 标志FILE_RESERVE_OPFILTER允许应用程序请求级别 1、批处理或筛选器 oplock,以防止其他应用程序发生共享冲突。 但是,FILE_RESERVE_OPFILTER实际上只对筛选器 oplock 有用。 若要使用它,必须完成以下步骤:

  1. 使用 CreateOptions 发出创建请求 FILE_RESERVE_OPFILTER,DesiredAccess 为 exactly FILE_READ_ATTRIBUTES,ShareAccess 为 exactly FILE_SHARE_READ |FILE_SHARE_WRITE |FILE_SHARE_DELETE。

    • 如果已打开句柄,则创建请求将失败并STATUS_OPLOCK_NOT_GRANTED,下一个请求的 oplock 也会失败。

    • 如果以更多访问权限或更少的共享打开也会导致STATUS_OPLOCK_NOT_GRANTED失败。

  2. 如果创建请求成功,请请求 oplock。

  3. 打开文件的另一个句柄以执行 I/O。

步骤 3 使此功能仅适用于筛选器 oplock。 步骤 3 中打开的句柄可以包含最多FILE_READ_ATTRIBUTES的 DesiredAccess |FILE_WRITE_ATTRIBUTES |FILE_READ_DATA |FILE_READ_EA |FILE_EXECUTE |SYNCHRONIZE |READ_CONTROL,但仍未中断筛选器 oplock。 但是,任何大于 FILE_READ_ATTRIBUTES 的 DesiredAccess |FILE_WRITE_ATTRIBUTES |SYNCHRONIZE 会中断级别 1 或批处理 oplock,并使FILE_RESERVE_OPFILTER标志对这些 oplock 类型无用。

NTFS 是唯一实现FILE_RESERVE_OPFILTER的 Microsoft 文件系统。

IoCreateFileSpecifyDeviceObjectHint 不能用于获取卷的句柄。

如果传递给 IoCreateFileSpecifyDeviceObjectHint 的文件名路径包含重新分析点,则重新分析点必须解析为文件或目录所在的同一卷。 否则,将返回错误STATUS_INVALID_DEVICE_OBJECT_PARAMETER或STATUS_MOUNT_POINT_NOT_RESOLVED。

要求

要求
目标平台 通用
标头 ntddk.h (包括 Ntddk.h、Ntifs.h、FltKernel.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL

另请参阅

ACCESS_MASK

ACL

FILE_FULL_EA_INFORMATION

IO_DRIVER_CREATE_CONTEXT

InitializeObjectAttributes

IoCheckEaBufferValidity

IoCreateFile

IoCreateFileEx

UNICODE_STRING

ZwClose

ZwCreateFile

ZwQueryInformationFile

ZwReadFile

ZwSetInformationFile

ZwWriteFile