FltCreateFileEx2 函数 (fltkernel.h)

微筛选器驱动程序调用 FltCreateFileEx2 以创建新文件或打开现有文件。 此例程包括一个可选的创建上下文参数 (ECP) 。

语法

NTSTATUS FLTAPI FltCreateFileEx2(
  [in]            PFLT_FILTER               Filter,
  [in, optional]  PFLT_INSTANCE             Instance,
  [out]           PHANDLE                   FileHandle,
  [out, optional] PFILE_OBJECT              *FileObject,
  [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                     CreateDisposition,
  [in]            ULONG                     CreateOptions,
  [in, optional]  PVOID                     EaBuffer,
  [in]            ULONG                     EaLength,
  [in]            ULONG                     Flags,
  [in, optional]  PIO_DRIVER_CREATE_CONTEXT DriverContext
);

参数

[in] Filter

调用方不透明的筛选器指针。

[in, optional] Instance

创建请求要发送到的微筛选器驱动程序实例的不透明实例指针。 实例必须附加到文件或目录所在的卷。 此参数是可选的,可以为 NULL。 如果此参数为 NULL,则请求将发送到卷的文件系统驱动程序堆栈顶部的设备对象。 如果此参数为非 NULL,则请求仅发送到附加到指定实例下方的微筛选器驱动程序实例。

[out] FileHandle

指向调用方分配的变量的指针,如果对 FltCreateFileEx2 的调用成功,该变量接收文件句柄。

[out, optional] FileObject

指向调用方分配的变量的指针,如果对 FltCreateFileEx2 的调用成功,该变量接收文件对象指针。 此参数是可选的,可以为 NULL

[in] DesiredAccess

标志的位掩码,指定对调用方所需的文件或目录的访问类型。 有关此参数和标志值列表的详细信息,请参阅 IoCreateFileExDesiredAccess 参数。

[in] ObjectAttributes

指向已使用 InitializeObjectAttributes 初始化的不透明OBJECT_ATTRIBUTES结构的指针。 有关详细信息和每个结构成员的说明,请参阅 IoCreateFileExObjectAttributes 参数。

[out] IoStatusBlock

指向 IO_STATUS_BLOCK 结构的指针,该结构接收最终完成状态和有关所请求操作的信息。 有关此参数的详细信息,请参阅 IoCreateFileExIoStatusBlock 参数。

[in, optional] AllocationSize

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

[in] FileAttributes

指定一个或多个 FILE_ATTRIBUTE_XXX 标志,这些标志表示在创建、取代或覆盖文件时要设置的文件属性。 有关更多详细信息和标志列表,请参阅 IoCreateFileExFileAttributes 参数。

[in] ShareAccess

指定调用方所需的文件的共享访问类型,为零个或一个,或者标志的组合。 有关更多详细信息和标志列表,请参阅 IoCreateFileExShareAccess 参数。

[in] CreateDisposition

指定一个值,该值确定要执行的操作,具体取决于文件是否已存在。 有关可能值的列表,请参阅 IoCreateFileExDisposition 参数。

[in] CreateOptions

指定要在创建或打开文件时应用的选项。 此参数是 IoCreateFileExCreateOptions 参数中列出和描述的标志的兼容组合。

[in, optional] EaBuffer

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

[in] EaLength

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

[in] Flags

指定要在创建请求期间使用的选项。 有关可能选项的列表,请参阅 IoCreateFileExOptions 参数。

[in, optional] DriverContext

指向 IoInitializeDriverCreateContext 已初始化的IO_DRIVER_CREATE_CONTEXT结构的可选指针。

返回值

FltCreateFileEx2 返回STATUS_SUCCESS或相应的 NTSTATUS 值。 有关可能的 返回 代码的列表,请参阅 IoCreateFileEx 的返回值部分。

注意

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

注解

FltCreateFileEx2 类似于 FltCreateFileFltCreateFileEx,只不过它支持 DriverContext 输入参数。

若要将 ECP 指定为创建操作的一部分,请使用 FltAllocateExtraCreateParameterList 例程初始化 IO_DRIVER_CREATE_CONTEXT 结构的 ExtraCreateParameter 成员。 如果使用 ECP,则必须使用适当的例程创建、操作和释放它们。

FltCreateFileEx2 调用方下方的筛选器驱动程序不应添加或删除调用方上的 ECP。 因此,从对 FltCreateFileEx2 的调用返回后,ECP 列表应保持不变,并可能传递给 FltCreateFileEx2 的其他调用以执行其他创建操作。 请注意,操作系统不会自动解除分配 ECP 列表结构 - FltCreateFileEx2 的调用方必须通过调用 FltFreeExtraCreateParameterList 例程解除分配此结构。

若要在事务上下文中创建/打开文件,请将 IO_DRIVER_CREATE_CONTEXT 结构的 TxnParameters 成员设置为 IoGetTransactionParameterBlock 例程返回的值。

FltCreateFileEx2 仅将创建请求发送到附加到指定微筛选器驱动程序实例下方的实例和文件系统。 指定的实例和上面附加的实例不会收到创建请求。 如果未指定任何实例,则请求将转到堆栈顶部,并且所有实例和文件系统都会收到请求。

可通过两种备用方法指定要使用 FltCreateFileEx2 创建或打开的文件的名称:

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

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

FltCreateFileEx2 获取的任何 FileHandle 最终都必须通过调用 FltClose 来释放。 此外,如果通过调用 ObDereferenceObject 不再需要任何返回的 FileObject 指针,则必须取消 引用

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

注意

请勿使用非 NULL 顶级 IRP 值调用此例程,因为可能导致系统死锁。

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

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

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

  • 为文件设置FILE_WRITE_DATA标志还允许在文件末尾以外的写入请求发生。 文件也会自动针对这种类型的写入请求进行扩展。

  • 如果仅设置了FILE_EXECUTE和 SYNCHRONIZE 标志,则调用方无法使用 FileHandle 参数中返回的句柄直接读取或写入文件的任何数据。 也就是说,对文件的所有操作都必须使用系统分页 I/O 来读取或写入文件数据。

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

若要成功打开共享文件,文件请求的 DesiredAccess 必须与之前尚未使用 FltClose 释放的所有打开请求的 DesiredAccessShareAccess 规范兼容。 也就是说,指定给给定文件的 FltCreateFileEx2DesiredAccess 参数不得与文件的其他打开程序禁止的访问冲突。

注意

如果在 Flags 参数中指定了IO_IGNORE_SHARE_ACCESS_CHECK,则 I/O 管理器将忽略 ShareAccess 参数。 但是,文件系统可能仍会执行访问检查。 因此,即使使用 IO_IGNORE_SHARE_ACCESS_CHECK 标志,也务必为 ShareAccess参数指定所需的共享模式。 此外,请注意,指定IO_IGNORE_SHARE_ACCESS_CHECK时,文件系统不会跟踪当前打开的所需访问权限或共享访问权限。 因此,对同一文件的后续打开调用可能会成功。

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

CreateDisposition 值FILE_OVERWRITE_IF和FILE_SUPERSEDE相似。 如果使用现有文件以及其中任一 CreateDisposition 值调用 FltCreateFileEx2,则会替换该文件。

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

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

  • 指定的文件属性与使用按位 OR 操作已应用于文件的属性组合在一起。 这意味着,如果文件已被另一个线程打开, 则 FltCreateFileEx2 的后续调用方无法禁用现有的 FileAttributes 标志,但可以为同一文件启用其他标志。 请注意,这种覆盖文件的样式与 MS-DOS、Windows 3.1 和 OS/2 一致。

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

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

CreateOptions FILE_SYNCHRONOUS_IO_ALERT 和 FILE_SYNCHRONOUS_IO_NONALERT 标志(如其名称所示是相互排斥的)指定正在为同步 I/O 打开文件。 这意味着,文件上的所有 I/O 操作都是同步的,只要这些操作通过返回的 FileHandle 引用的文件对象进行。 使用返回的句柄跨所有线程序列化此类文件上的所有 I/O。 设置上述任一 CreateOptions 标志后,I/O 管理器将保留文件对象的 CurrentByteOffset 字段中的当前文件位置偏移量。 此偏移量可用于对 ZwReadFileZwWriteFile 的调用。 也可以通过调用 ZwQueryInformationFileZwSetInformationFile 来查询或设置它。

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

CreateOptions FILE_OPEN_REQUIRING_OPLOCK标志消除了打开文件和请求可能使第三方能够打开文件并发生共享冲突的 oplock 之间的时间。 应用程序可以使用 FltCreateFileEx2 上的 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实际上仅适用于筛选器操作锁。 若要使用它,必须完成以下步骤:

  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 使此功能仅适用于筛选器操作锁。 在步骤 3 中打开的句柄可以包含最多FILE_READ_ATTRIBUTES的 DesiredAccess |FILE_WRITE_ATTRIBUTES |FILE_READ_DATA |FILE_READ_EA |FILE_EXECUTE |SYNCHRONIZE |READ_CONTROL,但仍不中断筛选器操作锁。 但是,任何大于 FILE_READ_ATTRIBUTES 的 DesiredAccess |FILE_WRITE_ATTRIBUTES |SYNCHRONIZE 将中断级别 1 或批处理 oplock,并使FILE_RESERVE_OPFILTER标志对这些 oplock 类型毫无用。

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

微筛选器驱动程序必须使用 FltSetInformationFile(而不是 ZwSetInformationFile)来重命名文件。

注意

如果尝试打开卷,但只为 DesiredAccess 参数指定以下标志的组合, 则 FltCreateFileEx2 将打开一个独立于文件系统的句柄,该句柄可直接访问卷的存储设备。

  • FILE_READ_ATTRIBUTES
  • READ_CONTROL
  • WRITE_DAC
  • WRITE_OWNER
  • SYNCHRONIZE

不得使用 FltCreateFileEx2 打开可直接访问卷的存储设备的句柄,否则会泄漏系统资源。 如果要打开可直接访问存储设备的句柄,请改为调用 IoCreateFileExIoCreateFileSpecifyDeviceObjectHintZwCreateFile 函数。

FltCreateFileEx2 的调用方希望为卷目标启用重新分析时,可以将 FLT_CREATEFILE_TARGET_ECP_CONTEXT 作为 ECP 包含在 DriverContext 参数中的 ECP 列表中。 如果存在此 ECP,FltCreateFileEx2 将调整创建操作的目标设备,并尝试查找适用于给定文件信息的卷的筛选实例。 从Windows 8开始,可以使用此 ECP。

要求

要求
最低受支持的客户端 从 Windows Vista 开始可用。
目标平台 通用
标头 fltkernel.h (包括 FltKernel.h)
Library Fltmgr.lib
IRQL PASSIVE_LEVEL

另请参阅

ACCESS_MASK

ACL

DEVICE_OBJECT

FILE_FULL_EA_INFORMATION

FltAcknowledgeEcp

FltAllocateExtraCreateParameter

FltAllocateExtraCreateParameterList

FltClose

FltFindExtraCreateParameter

FltFreeExtraCreateParameter

FltFreeExtraCreateParameterList

FltGetEcpListFromCallbackData

FltGetNextExtraCreateParameter

FltInsertExtraCreateParameter

FltIsEcpAcknowledged

FltIsEcpFromUserMode

FltQueryInformationFile

FltReadFile

FltRemoveExtraCreateParameter

FltSetEcpListIntoCallbackData

FltSetInformationFile

FltWriteFile

IO_DRIVER_CREATE_CONTEXT

InitializeObjectAttributes

IoCreateFile

IoCreateFileSpecifyDeviceObjectHint

IoInitializeDriverCreateContext

ObDereferenceObject

SECURITY_DESCRIPTOR

UNICODE_STRING

ZwCreateFile

ZwQueryInformationFile

ZwReadFile

ZwSetInformationFile

ZwWriteFile