FltCreateFile 函数 (fltkernel.h)
微筛选器驱动程序调用 FltCreateFile 以创建新文件或打开现有文件。
语法
NTSTATUS FLTAPI FltCreateFile(
[in] PFLT_FILTER Filter,
[in, optional] PFLT_INSTANCE Instance,
[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 CreateDisposition,
[in] ULONG CreateOptions,
[in, optional] PVOID EaBuffer,
[in] ULONG EaLength,
[in] ULONG Flags
);
参数
[in] Filter
调用方不透明的筛选器指针。
[in, optional] Instance
创建请求要发送到的微筛选器驱动程序实例的不透明实例指针。 实例必须附加到文件或目录所在的卷。 此参数是可选的,可以为 NULL。 如果此参数为 NULL,则请求将发送到卷的文件系统驱动程序堆栈顶部的设备对象。 如果为非 NULL,则请求仅发送到附加到指定实例下方的微型筛选器驱动程序实例。
[out] FileHandle
指向调用方分配的变量的指针,如果对 FltCreateFile 的调用成功,该变量将接收文件句柄。
[in] DesiredAccess
标志的位掩码,指定对调用方所需的文件或目录的访问类型。 有关此参数和标志值列表的详细信息,请参阅 IoCreateFileEx 的 DesiredAccess 参数。
[in] ObjectAttributes
指向已使用 InitializeObjectAttributes 初始化的不透明OBJECT_ATTRIBUTES结构的指针。 有关详细信息和每个结构成员的说明,请参阅 IoCreateFileEx 的 ObjectAttributes 参数。
[out] IoStatusBlock
指向 IO_STATUS_BLOCK 结构的指针,该结构接收最终完成状态和有关所请求操作的信息。 有关此参数的详细信息,请参阅 IoCreateFileEx 的 IoStatusBlock 参数。
[in, optional] AllocationSize
(可选)指定文件流的初始分配大小(以字节为单位)。 除非正在创建、覆盖或取代文件,否则非零值不起作用。
[in] FileAttributes
指定一个或多个 FILE_ATTRIBUTE_XXX 标志,这些标志表示在创建、取代或覆盖文件时要设置的文件属性。 有关更多详细信息和标志列表,请参阅 IoCreateFileEx 的 FileAttributes 参数。
[in] ShareAccess
指定调用方所需的文件的共享访问类型,为零个或一个,或者标志的组合。 有关更多详细信息和标志列表,请参阅 IoCreateFileEx 的 ShareAccess 参数。
[in] CreateDisposition
指定一个值,该值确定要执行的操作,具体取决于文件是否已存在。 有关可能值的列表,请参阅 IoCreateFileEx 的 Disposition 参数。
[in] CreateOptions
指定要在创建或打开文件时应用的选项。 此参数是 IoCreateFileEx 的 CreateOptions 参数中列出和描述的标志的兼容组合。
[in, optional] EaBuffer
指向调用方提供的 FILE_FULL_EA_INFORMATION结构化缓冲区的指针,其中包含要应用于文件的扩展属性 (EA) 信息。
[in] EaLength
EaBuffer 的长度(以字节为单位)。
[in] Flags
指定要在创建请求期间使用的选项。 有关可能选项的列表,请参阅 IoCreateFileEx 的 Options 参数。
返回值
FltCreateFile 返回STATUS_SUCCESS或相应的 NTSTATUS 值。 有关可能的 返回 代码的列表,请参阅 IoCreateFileEx 的返回值部分。
注意
FltCreateFile 可能会返回STATUS_FILE_LOCK_CONFLICT作为返回值,或者在 IoStatusBlock 参数指向的IO_STATUS_BLOCK结构的 Status 成员中返回。 仅当 NTFS 日志文件已满并且 FltCreateFile 尝试处理这种情况时出错时,才会发生这种情况。
注解
在 Windows 2000 SP4 和 Windows Server 2003 SP1 的 Microsoft Windows 更新汇总版本上, 微筛选器驱动程序应调用 FltCreateFile 而不是 IoCreateFile、IoCreateFileSpecifyDeviceObjectHint 或 ZwCreateFile 以获取用于 Zw Xxx I/O 例程(如 ZwReadFile 和 ZwQueryInformationFile)的文件句柄。
在适用于 Windows 2000 SP4、Windows Server 2003 SP1 及更高版本的 Microsoft Windows 更新汇总上,微筛选器驱动程序可以使用 FltCreateFileEx 获取用于 FltXxx文件例程(如 FltReadFile 和 FltWriteFile)的文件对象指针。 在早期版本的 Windows 上,可以通过调用 ObReferenceObjectByHandle 将从 FltCreateFile 获取的句柄转换为文件对象指针,如下所示:
status = ObReferenceObjectByHandle(
handle, //Handle
0, //DesiredAccess
NULL, //ObjectType
KernelMode, //AccessMode
&handleFileObject, //Object
NULL); //HandleInformation</pre>
FltCreateFile 仅将创建请求发送到附加到指定微筛选器驱动程序实例下方的实例和文件系统。 指定的实例和上面附加的实例不会收到创建请求。 如果未指定任何实例,则请求将转到堆栈顶部,并且所有实例和文件系统都会收到请求。
可通过两种替代方法指定要使用 FltCreateFile 创建或打开的文件的名称:
- 作为完全限定的路径名,在输入 ObjectAttributes 的 ObjectName 成员中提供。
- 作为相对于输入 ObjectAttributes 的 RootDirectory 成员中的句柄表示的目录文件的路径名。
最终必须通过调用 FltClose 释放从 FltCreateFile 获取的任何句柄。
不在系统进程上下文中运行的驱动程序例程必须为 FltCreateFile 的 ObjectAttributes 参数设置 OBJ_KERNEL_HANDLE 属性。 设置此属性会将 FltCreateFile 返回的句柄的使用限制为在内核模式下运行的进程。 否则,运行驱动程序的上下文的进程可以访问句柄。
注意
请勿使用非 NULL 顶级 IRP 值调用此例程,因为可能导致系统死锁。
请勿在未完成 的 FsRtlEnterFileSystem 或 KeEnterCriticalRegion (禁用 APC 的情况下调用此例程,因为可能导致线程死锁。
某些 DesiredAccess 标志和标志组合具有以下效果:
对于通过等待返回 的 FileHandle 设置为“已信号”状态来同步 I/O 完成的调用方,必须设置 SYNCHRONIZE 标志。
如果只设置了FILE_APPEND_DATA和 SYNCHRONIZE 标志,则调用方只能写入文件末尾,并且有关写入文件的任何偏移量信息将被忽略。 但是,对于这种类型的写入操作,文件会自动扩展。
为文件设置FILE_WRITE_DATA标志还允许写入文件末尾以外的操作。 文件也会自动扩展为此类写入。
如果只设置了 FILE_EXECUTE 和 SYNCHRONIZE 标志,则调用方无法使用返回的 FileHandle 直接读取或写入文件中的任何数据。 也就是说,对文件的所有操作都必须使用系统分页 I/O 来读取或写入文件数据。
ShareAccess 参数确定单独的线程是否可以同时访问同一文件。 如果两个文件打开程序都具有以指定方式访问文件的权限,则可以成功打开和共享该文件。 如果 FltCreateFile 的原始调用方未指定FILE_SHARE_READ、FILE_SHARE_WRITE或FILE_SHARE_DELETE,则无法对文件执行其他打开操作,因为原始调用方被授予对该文件的独占访问权限。
若要成功打开共享文件,文件请求的 DesiredAccess 必须与之前尚未使用 FltClose 发布的所有打开的 DesiredAccess 和 ShareAccess 规范兼容。 也就是说,指定给给定文件的 FltCreateFile 的 DesiredAccess 不得与文件的其他打开程序禁止的访问发生冲突。
注意
如果在 Flags 参数中指定了IO_IGNORE_SHARE_ACCESS_CHECK,则 I/O 管理器将忽略 ShareAccess 参数。 但是,文件系统可能仍会执行访问检查。 因此,请务必为 ShareAccess 参数指定所需的共享模式,即使使用 IO_IGNORE_SHARE_ACCESS_CHECK 标志也是如此。 此外,请注意,指定IO_IGNORE_SHARE_ACCESS_CHECK时,文件系统不会跟踪当前打开的所需访问权限或共享访问权限。 因此,对同一文件的后续打开调用可能会成功。
CreateDisposition 值FILE_SUPERSEDE要求调用方对现有文件对象具有 DELETE 访问权限。 如果是这样,如果成功调用 FltCreateFile 并FILE_SUPERSEDE现有文件,则会有效地删除该文件,然后重新创建该文件。 这意味着,如果文件已被另一个线程打开,则它通过指定一个 ShareAccess 参数来打开文件,并设置了FILE_SHARE_DELETE标志。 请注意,这种类型的处置与覆盖文件的 POSIX 样式一致。
CreateDisposition 值FILE_OVERWRITE_IF和FILE_SUPERSEDE相似。 如果使用现有文件以及其中任一 CreateDisposition 值调用 FltCreateFile,则会替换该文件。
覆盖文件在语义上等效于取代操作,但以下情况除外:
- 调用方必须对文件具有写入访问权限,而不是删除访问权限。 这意味着,如果文件已由另一个线程打开,它将在输入 ShareAccess 中设置FILE_SHARE_WRITE标志打开文件。
- 指定的文件属性在逻辑上与文件上已有的属性一起为 ORed。 这意味着,如果文件已被另一个线程打开, 则 FltCreateFile 的后续调用方无法禁用现有的 FileAttributes 标志,但可以为同一文件启用其他标志。 请注意,这种覆盖文件的样式与 MS-DOS、Windows 3.1 和 OS/2 一致。
CreateOptions FILE_DIRECTORY_FILE 值指定要创建或打开的文件是目录文件。 创建目录文件时,文件系统会在磁盘上创建适当的结构,以表示该特定文件系统的磁盘上结构的空目录。 如果指定了此选项,并且要打开的给定文件不是目录文件,或者调用方指定了不一致的 CreateOptions 或 CreateDisposition 值,则对 FltCreateFile 的调用将失败。
CreateOptions FILE_NO_INTERMEDIATE_BUFFERING 标志阻止文件系统代表调用方执行任何中间缓冲。 指定此值对 Zw 的调用方参数存在某些限制 。文件 例程,包括以下内容:
- 传递给 ZwReadFile 或 ZwWriteFile 的任何字节偏移值必须是扇区大小的倍数。
- 传递给 ZwReadFile 或 ZwWriteFile 的 Length 必须是扇区大小的倍数。 请注意,如果在传输过程中到达文件的末尾,则指定对长度正好为扇区大小的缓冲区的读取操作可能会导致传输到该缓冲区的重要字节数减少。
- 缓冲区必须根据基础存储设备的对齐要求进行对齐。 可以通过调用 FltCreateFile 获取表示物理设备的文件对象的句柄,然后使用该句柄调用 ZwQueryInformationFile ,将 FileAlignmentInformation 指定为 FileInformationClass 来获取此信息。 有关 ntifs.h 中定义的系统FILE_XXX_ALIGNMENT值的详细信息,请参阅 DEVICE_OBJECT 和 初始化设备对象。
- 调用 FileInformationClass 参数设置为 FilePositionInformation 的 ZwSetInformationFile 时,必须指定扇区大小的倍数的偏移量。
CreateOptions FILE_SYNCHRONOUS_IO_ALERT 和 FILE_SYNCHRONOUS_IO_NONALERT(顾名思义)指定为同步 I/O 打开文件。 这意味着,只要通过返回的 FileHandle 引用的文件对象发生,文件上的所有 I/O 操作都将是同步的。 使用返回的句柄跨所有线程序列化此类文件上的所有 I/O。 设置上述任一 CreateOptions 后,I/O 管理器将保留文件对象的 CurrentByteOffset 字段中的当前文件位置偏移量。 此偏移量可用于对 ZwReadFile 和 ZwWriteFile 的调用。 还可以通过调用 ZwQueryInformationFile 或 ZwSetInformationFile 来查询或设置它。
如果未指定 CreateOptions FILE_OPEN_REPARSE_POINT 标志,并且 FltCreateFile 尝试使用重新分析点打开文件,则文件将进行正常的重新分析点处理。 另一方面,如果指定了FILE_OPEN_REPARSE_POINT标志,则不会进行正常的重新分析处理, FltCreateFile 会尝试直接打开重新分析点文件。 在任一情况下,如果打开操作成功, FltCreateFile 将返回STATUS_SUCCESS;否则,例程将返回 NTSTATUS 错误代码。 FltCreateFile 从不返回STATUS_REPARSE。
CreateOptions FILE_OPEN_REQUIRING_OPLOCK 标志消除了打开文件和请求 oplock 之间的时间,oplock 可能会使第三方打开文件并发生共享冲突。 应用程序可以使用 FltCreateFile 上的 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 有用。 若要使用它,必须完成以下步骤:
使用 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失败。
如果创建请求成功,请请求 oplock。
打开文件的另一个句柄以执行 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 文件系统。
微筛选器驱动程序必须使用 FltSetInformationFile(而不是 ZwSetInformationFile)重命名文件。
注意
如果尝试打开卷,但仅为 DesiredAccess 参数指定以下标志的组合, FltCreateFile 将打开一个独立于文件系统的句柄,该句柄对卷的存储设备具有直接访问权限。
- FILE_READ_ATTRIBUTES
- READ_CONTROL
- WRITE_DAC
- WRITE_OWNER
- SYNCHRONIZE
不得使用 FltCreateFile 打开直接访问卷存储设备的句柄,否则会泄漏系统资源。 如果要打开直接访问存储设备的句柄,请改为调用 IoCreateFileEx、 IoCreateFileSpecifyDeviceObjectHint 或 ZwCreateFile 函数。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | 适用于 SP4、Windows XP SP2、Windows Server 2003 SP1 的 Windows 2000 更新汇总 1 |
目标平台 | 通用 |
标头 | fltkernel.h (包括 FltKernel.h) |
Library | Fltmgr.lib |
IRQL | PASSIVE_LEVEL |