fltGetFileNameInformation 函数 (fltkernel.h)

FltGetFileNameInformation 例程返回文件或目录的名称信息。

语法

NTSTATUS FLTAPI FltGetFileNameInformation(
  [in]  PFLT_CALLBACK_DATA         CallbackData,
  [in]  FLT_FILE_NAME_OPTIONS      NameOptions,
  [out] PFLT_FILE_NAME_INFORMATION *FileNameInformation
);

参数

[in] CallbackData

指向 FLT_CALLBACK_DATA 结构的指针,该结构是 I/O 操作的回调数据结构。 此参数是必需的,不能为 NULL

[in] NameOptions

一个 FLT_FILE_NAME_OPTIONS 值,其中包含指定要返回的名称信息的格式以及筛选器管理器要使用的查询方法的标志。 调用方必须包含名称格式标志和查询方法标志。 名称提供程序微筛选器驱动程序可以使用其他标志来指定名称查询选项。 此参数是必需的,不能为 NULL

下面是文件名格式标志值。 只能指定以下标志之一。 有关这些格式的说明,请参阅 FLT_FILE_NAME_INFORMATION

名称格式标志值 含义
FLT_FILE_NAME_NORMALIZED FileNameInformation 参数接收结构的地址,该结构包含文件的规范化名称。
FLT_FILE_NAME_OPENED FileNameInformation 参数接收结构的地址,该结构包含打开文件时使用的名称。
FLT_FILE_NAME_SHORT FileNameInformation 参数接收结构的地址,其中包含文件的短 (8.3) 名称。 短名称最多包含 8 个字符,后跟句点,最多再多 3 个字符。 文件的短名称不包括卷名称、目录路径或流名称。 在预创建路径中无效。

下面是文件名查询方法标志值。 只能指定以下标志之一。

查询方法标志值 含义
FLT_FILE_NAME_QUERY_DEFAULT 如果当前无法安全地在文件系统中查询文件名, 则 FltGetFileNameInformation 不执行任何操作。 否则, FltGetFileNameInformation 会查询筛选器管理器的名称缓存以获取文件名信息。 如果在缓存中找不到该名称, 则 FltGetFileNameInformation 将查询文件系统并缓存结果。
FLT_FILE_NAME_QUERY_CACHE_ONLY FltGetFileNameInformation 在筛选器管理器的名称缓存中查询文件名信息。 FltGetFileNameInformation 不会查询文件系统。
FLT_FILE_NAME_QUERY_FILESYSTEM_ONLY FltGetFileNameInformation 在文件系统中查询文件名信息。 FltGetFileNameInformation 不会查询筛选器管理器的名称缓存,也不会缓存文件系统查询的结果。
FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP FltGetFileNameInformation 在筛选器管理器的名称缓存中查询文件名信息。 如果在缓存中找不到该名称,并且当前可以安全地执行此操作, 则 FltGetFileNameInformation 会查询文件系统中的文件名信息并缓存结果。

名称提供程序微筛选器使用以下标志来指定文件名操作的属性。

名称提供程序标志值 含义
FLT_FILE_NAME_REQUEST_FROM_CURRENT_PROVIDER 名称提供程序微筛选器可以使用此标志指定名称查询请求应重定向到自身 (名称提供程序微筛选器) ,而不是由堆栈中较低的名称提供程序满足。
FLT_FILE_NAME_DO_NOT_CACHE 此标志表示不应缓存从此查询检索到的名称。 名称提供程序微筛选器在执行中间查询以生成名称时使用此标志。
FLT_FILE_NAME_ALLOW_QUERY_ON_REPARSE 名称提供程序微筛选器可以使用此标志来指定即使返回了STATUS_REPARSE,也可以安全地查询创建后路径中的名称。 调用方负责确保 FileObject-FileName> 字段未更改。 请勿将此标志与装入点或符号链接重新分析点一起使用。

[out] FileNameInformation

指向调用方分配的变量的指针,该变量接收包含文件名信息的系统分配 FLT_FILE_NAME_INFORMATION 结构的地址。 FltGetFileNameInformation 从分页池分配此结构。 此参数是必需的,不能为 NULL

返回值

如果成功返回名称信息, FltGetFileNameInformation 将返回STATUS_SUCCESS。 否则,它将返回相应的 NTSTATUS 值,如以下值之一:

返回代码 说明
STATUS_FLT_INVALID_NAME_REQUEST

如果无法从筛选器管理器的名称缓存中满足查询,则 FltGetFileNameInformation 在以下任何情况下都无法获取文件名信息:

  • 在分页 I/O 路径中。
  • 当前线程的 TopLevelIrp 字段不为 NULL 时,因为生成的文件系统递归可能会导致死锁或堆栈溢出。 (有关此问题的详细信息,请参阅 IoGetTopLevelIrp.)
  • 完成IRP_MJ_CLEANUP操作后;也就是说,在清理后、关闭前或关闭后路径 (目标文件对象) 设置了FO_CLEANUP_COMPLETE标志。
  • 在预操作 (PFLT_PRE_OPERATION_CALLBACK) 或操作后 (PFLT_POST_OPERATION_CALLBACK) 以下任何操作的回调例程:
    • IRP_MJ_ACQUIRE_FOR_CC_FLUSH
    • IRP_MJ_ACQUIRE_FOR_MOD_WRITE
    • IRP_MJ_RELEASE_FOR_CC_FLUSH
    • IRP_MJ_RELEASE_FOR_MOD_WRITE
    • IRP_MJ_RELEASE_FOR_SECTION_SYNCHRONIZATION
  • 在IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION的后操作回调例程中。
  • 禁用所有 APC 时;即, 当 KeAreAllApcsDisabled 返回 TRUE 时。

FltGetFileNameInformation 无法获取预创建路径中文件的短名称。

STATUS_FLT_INVALID_NAME_REQUEST是错误代码。

STATUS_INSUFFICIENT_RESOURCES
FltGetFileNameInformation 遇到池分配失败。 这是错误代码。
STATUS_INVALID_PARAMETER
在传递无效参数时返回,如下所示之一:
  • FileNameInformation 参数不能为 NULL
  • CallbackData 参数不能为 NULL
STATUS_INVALID_PARAMETER是错误代码。
STATUS_FLT_NAME_CACHE_MISS
在名称缓存中找不到文件名信息, NameOptions 包含FLT_FILE_NAME_QUERY_CACHE_ONLY。

-或-

NameOptions 包含FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP并且无法从文件系统查询文件名信息时,在名称缓存中找不到文件名信息。

NameOptions 中设置FLT_FILE_NAME_QUERY_FILESYSTEM_ONLY对 FltGetFileNameInformation 的附加调用可能会返回文件名信息。

STATUS_NOT_SAME_DEVICE
在预创建期间要查询的文件位于与其父目录不同的卷上。 对于规范化的名称查询,将返回此错误,其中文件是解析为不同卷的交接点或符号链接。
STATUS_ACCESS_DENIED
如果用户按文件 ID 打开了文件,但没有整个路径的遍历权限, 则 FltGetFileNameInformation 将失败并显示此返回值。

STATUS_ACCESS_DENIED是错误代码。

-或-

该文件是拒绝所有访问的系统文件。

注解

FltGetFileNameInformation 以指定格式返回作为 CallbackData 所述操作目标的文件或目录的请求名称信息。 文件系统尚不需要打开文件或目录。

对于预创建操作,如果 CallbackData-Iopb-OperationFlags>> 成员包含SL_OPEN_TARGET_DIRECTORY按位标志,则 FltGetFileNameInformation 将返回包含给定文件的父 (父) 目录的名称。 此名称是创建操作打开的实际路径。

若要分析 FltGetFileNameInformation 返回的 FLT_FILE_NAME_INFORMATION 结构的内容,请调用 FltParseFileNameInformation。 (有关文件名格式的详细信息,请参阅 FLT_FILE_NAME_INFORMATION.)

成功调用 FltGetFileNameInformation 后,调用方负责在不再需要指针时释放 FileNameInformation 参数中返回的指针。 调用方通过调用 FltReleaseFileNameInformation 来执行此操作。

调用方不得修改 FileNameInformation 参数中返回的结构的内容,因为此结构由筛选器管理器缓存,以便所有微筛选器驱动程序都可以使用它。

如果在创建操作的预操作回调例程中调用 FltGetFileNameInformation 以检索打开的名称,即使卷上不存在打开的文件的路径, FltGetFileNameInformation 也会成功。

如果在创建操作前回调例程中调用 FltGetFileNameInformation 以检索规范化名称,则即使卷上不存在打开的文件路径的最后一个组件, FltGetFileNameInformation 也会成功。

注意

服务器消息块 (SMB) 对远程卷上查询规范化文件名的支持因Windows 10版本而异。 有关详细信息,请参阅 MS-SMB2 协议

在创建、硬链接和重命名操作中,文件名隧道可能会导致规范化文件名信息中微筛选器驱动程序在预操作回调例程中检索的最终组件失效。 如果微筛选器驱动程序通过调用例程(如 FltGetFileNameInformation)在预操作回调 (PFLT_PRE_OPERATION_CALLBACK) 例程中检索规范化文件名信息,则必须从其操作后回调 (PFLT_POST_OPERATION_CALLBACK) 例程中调用 FltGetTunneledName,以检索文件的正确文件名信息。

对于Windows 8.1及更早版本,FltGetFileNameInformation当从筛选器的预创建回调调用时才能包含流类型。 若要区分文件的默认流和元数据流,应在预创建操作中进行此调用。 生成的流类型将在文件的生存期内保持有效。

在Windows 8之前,筛选器管理器通过收集文件路径的每个组件的名称信息来获取文件或目录的规范化名称。 这需要对文件系统进行多次查询才能编译完整路径。 从Windows 8开始,本地文件系统支持 FileNormalizedNameInformation 文件信息类,只需一个查询即可获取规范化名称。 远程文件系统可能不支持 FileNormalizedNameInformation 文件信息类。 在这种情况下,仍需要对文件路径的每个组件进行查询,以汇编规范化名称。 在某些网络条件下,全名查询可能需要很长时间才能完成。

有关规范化文件名信息的详细信息,请参阅 FLT_FILE_NAME_INFORMATION

注意

文件名隧道仅以这种方式影响创建、硬链接和重命名操作。 它不会影响其他 I/O 操作,例如读取和写入。

以下配对操作可能会导致文件名通过隧道传输:

  • 删除 (名称) /create (name)
  • 删除 (名称) /rename (source, name)
  • 重命名 (名称、newname) /create (name)
  • rename (name, newname) /rename (source,name)

要求

要求
目标平台 通用
标头 fltkernel.h (包括 Fltkernel.h)
Library FltMgr.lib
DLL Fltmgr.sys
IRQL <= APC_LEVEL (请参阅返回值)

另请参阅

FLT_CALLBACK_DATA

FLT_FILE_NAME_INFORMATION

FLT_FILE_NAME_OPTIONS

FltGetDestinationFileNameInformation

FltGetFileNameInformationUnsafe

FltGetTunneledName

FltParseFileNameInformation

FltReferenceFileNameInformation

FltReleaseFileNameInformation

IoGetTopLevelIrp

PFLT_POST_OPERATION_CALLBACK

PFLT_PRE_OPERATION_CALLBACK