NtQueryDirectoryFileEx 函数 (ntifs.h)

NtQueryDirectoryFileEx 例程返回有关给定文件句柄指定的目录中文件的各种信息。

语法

__kernel_entry NTSYSCALLAPI NTSTATUS NtQueryDirectoryFileEx(
  [in]           HANDLE                 FileHandle,
  [in, optional] HANDLE                 Event,
  [in, optional] PIO_APC_ROUTINE        ApcRoutine,
  [in, optional] PVOID                  ApcContext,
  [out]          PIO_STATUS_BLOCK       IoStatusBlock,
  [out]          PVOID                  FileInformation,
  [in]           ULONG                  Length,
                 FILE_INFORMATION_CLASS FileInformationClass,
  [in]           ULONG                  QueryFlags,
  [in, optional] PUNICODE_STRING        FileName
);

参数

[in] FileHandle

NtCreateFileNtOpenFile 为表示要为其请求信息的目录的文件对象返回的句柄。 如果调用方为 EventApcRoutine 指定了非 NULL 值,则必须为异步 I/O 打开文件对象。

[in, optional] Event

调用方创建的事件的可选句柄。 如果提供了此参数,则调用方将进入等待状态,直到请求的操作完成,并且给定的事件设置为“已发出信号”状态。 此参数是可选的,可以为 NULL。 如果调用方将等待 FileHandle 设置为“已发出信号”状态,则必须为 NULL。

[in, optional] ApcRoutine

调用方提供的可选 APC 例程的地址,该例程将在请求的操作完成时调用。 此参数是可选的,可以为 NULL。 如果存在与文件对象关联的 I/O 完成对象,则此参数必须为 NULL。

[in, optional] ApcContext

如果调用方提供 APC 或 I/O 完成对象与文件对象关联,则为指向调用方确定的上下文区域的可选指针。 操作完成后,如果指定了上下文,则此上下文将传递到 APC,或者作为 I/O 管理器发布到关联的 I/O 完成对象的完成消息的一部分包含在内。

此参数是可选的,可以为 NULL。 如果 ApcRoutine 为 NULL 并且没有与文件对象关联的 I/O 完成对象,则它必须为 NULL。

[out] IoStatusBlock

指向接收最终完成状态和操作相关信息 的IO_STATUS_BLOCK 结构的指针。 对于返回数据的成功调用,写入 FileInformation 缓冲区的字节数将在结构的 Information 成员中返回。

[out] FileInformation

指向输出缓冲区的指针,该缓冲区接收有关文件的所需信息。 缓冲区中返回的信息的结构由 FileInformationClass 参数定义。

[in] Length

FileInformation 指向的缓冲区的大小(以字节为单位)。 调用方应根据给定 的 FileInformationClass 设置此参数。

FileInformationClass

要返回的有关目录中文件的信息类型。 要返回的有关目录中文件的信息的类型。 FileInformationClass 可以是以下 FILE_INFORMATION_CLASS 值之一。

含义
FileDirectoryInformation (1) 返回每个文件的 FILE_DIRECTORY_INFORMATION 结构。
FileFullDirectoryInformation (2) 返回每个文件的 FILE_FULL_DIR_INFORMATION 结构。
FileBothDirectoryInformation (3) 为每个文件返回 FILE_BOTH_DIR_INFORMATION 结构。
FileNamesInformation (12) 返回每个文件的 FILE_NAMES_INFORMATION 结构。
FileObjectIdInformation (29) 为卷上具有对象 ID 的每个文件返回 FILE_OBJECTID_INFORMATION 结构。 此信息类仅对 NTFS 卷上的特殊目录“\$Extend\$ObjId:$O:$INDEX_ALLOCATION”有效。
FileQuotaInformation (32) 为应用了配额的卷上的每个用户返回单个 FILE_QUOTA_INFORMATION 结构。 此信息类仅对 NTFS 卷上的特殊目录“\$Extend\$Quota:$Q:$INDEX_ALLOCATION”有效。
FileReparsePointInformation (33) 为卷上具有重分析点的每个文件返回单个 FILE_REPARSE_POINT_INFORMATION 结构。 此信息类仅对 NTFS 和 ReFS 卷上的特殊目录“\$Extend\$Reparse:$R:$INDEX_ALLOCATION”有效。
FileIdBothDirectoryInformation (37) 返回每个文件的 FILE_ID_BOTH_DIR_INFORMATION 结构。
FileIdFullDirectoryInformation (38) 为每个文件返回 FILE_ID_FULL_DIR_INFORMATION 结构。
FileIdGlobalTxDirectoryInformation (50) 为每个文件返回 FILE_ID_GLOBAL_TX_DIR_INFORMATION 结构。
FileIdExtdDirectoryInformation (60) 为每个文件返回 FILE_ID_EXTD_DIR_INFORMATION 结构。
FileIdExtdBothDirectoryInformation (63) 为每个文件返回 FILE_ID_EXTD_BOTH_DIR_INFORMATION 结构。

[in] QueryFlags

SL_QUERY_DIRECTORY_MASK中包含的一个或多个标志。 下表中指定了可能的值。

含义
SL_RESTART_SCAN (0x00000001) 扫描将从目录中的第一个条目开始。 如果未设置此标志,扫描将从上次查询结束的位置恢复。
SL_RETURN_SINGLE_ENTRY (0x00000002) 通常,返回缓冲区包含任意数量的匹配目录条目。 如果设置了此标志,则文件系统一次仅返回一个目录条目。 这确实会使操作效率降低。
SL_INDEX_SPECIFIED (0x00000004) 扫描应从目录中的指定索引位置开始。 仅当生成自己的IRP_MJ_DIRECTORY_CONTROL IRP 时,才能设置此标志;索引在 IRP 中指定。 位置的指定方式因文件系统而异。
SL_RETURN_ON_DISK_ENTRIES_ONLY (0x00000008) 执行目录虚拟化或实时扩展的任何文件系统筛选器都应将请求传递到文件系统,并返回当前位于磁盘上的条目。 并非所有文件系统都支持此标志。
SL_NO_CURSOR_UPDATE_QUERY (0x00000010) 文件系统维护每个 FileObject 目录的游标信息。 当多个线程使用相同的 FileObject 执行查询时,对 per-FileObject 结构的访问是单线程的,以防止游标状态损坏。 此标志指示文件系统不要更新每个 FileObject 游标状态信息,从而允许多个线程使用同一句柄并行查询。 它的行为就像在每次调用中指定SL_RESTART_SCAN一样。 如果在下一次调用中提供了野生卡模式,则操作将不会从上次查询结束的位置获取。 这允许真正的异步目录查询支持。 如果在 TxF 事务中使用此标志,则操作将失败。 并非所有文件系统都支持此标志。

[in, optional] FileName

一个可选指针,指向调用方分配的 Unicode 字符串的可选指针,该字符串包含文件 (或多个文件的名称(如果在 FileHandle 指定的目录中) 使用通配符)。 此参数是可选的:

  • 如果 FileName 不为 NULL,则目录扫描中仅包含名称与 FileName 字符串匹配的文件。
  • 如果 FileName 为 NULL:
    • 如果未在 QueryFlags 中设置SL_RETURN_SINGLE_ENTRY,则包含所有文件。
    • 如果设置了SL_RETURN_SINGLE_ENTRY,则仅包含一个文件。

FileName 用作搜索表达式,在首次调用 NtQueryDirectoryFileEx 时捕获给定句柄。 对 NtQueryDirectoryFileEx 的后续调用将使用第一次调用中设置的搜索表达式。 将忽略传递给后续调用的 FileName 参数。

返回值

NtQueryDirectoryFileEx 返回STATUS_SUCCESS或适当的错误状态。 可返回的错误状态值集是特定于文件系统的。 NtQueryDirectoryFileEx 还返回实际写入 IoStatusBlock的信息成员中给定 FileInformation 缓冲区的字节数。 一些可能的错误代码和原因可能如下:

返回代码 含义
STATUS_BUFFER_OVERFLOW 输出缓冲区不够大,无法返回完整文件名。
STATUS_BUFFER_TOO_SMALL 至少对于 FileInformationClass 标识的基本结构而言,输出缓冲区不够大。
STATUS_INVALID_INFO_CLASS 指定的 FileInformationClass 无效,或者信息类仅对特殊条件有效 (例如,仅对特殊目录) 有效。
STATUS_INVALID_PARAMETER 其中一个参数对文件系统无效。

注解

NtQueryDirectoryFileEx 返回 FileHandle 表示的目录中包含的文件的相关信息。

如果提供,FileName 将确定目录扫描中包含的条目,以便针对给定 FileHandleNtQueryDirectoryFileEx 的所有后续调用。

如果至少有一个匹配项, NtQueryDirectoryFileEx 将为每个条目创建 FILE_XXX_INFORMATION 结构,并将其存储在缓冲区中。

假设找到至少一个匹配的目录条目,则返回信息的条目数是下列项中的 最小 项:

  • 如果在 QueryFlags 中设置了SL_RETURN_SINGLE_ENTRY且 FileName 为 NULL,则为一个条目。
  • 如果 FileName 不为 NULL,则为与 FileName 字符串匹配的条目数。 如果字符串不包含通配符,则最多可以有一个匹配项。
  • 其信息适合指定缓冲区的条目数。
  • 目录中包含的条目数。

首次调用 NtQueryDirectoryFileEx 时,如果它为找到的第一个条目创建的结构太大,无法容纳到输出缓冲区中,则此例程将执行以下操作:

  • 将 结构的固定部分写入 FileInformation 的输出缓冲区。 固定部分包含除最终 FileName 字符串之外的所有字段。 在第一次调用(而不是后续调用时)时,I/O 系统确保缓冲区足够大,可以容纳相应 FILE_XXX_INFORMATION 结构的固定部分。
  • 尽可能多地写入输出缓冲区的 FileName 字符串。
  • 返回适当的状态值,例如STATUS_BUFFER_OVERFLOW。

每次调用时,NtQueryDirectoryFileEx 返回FILE_XXX_INFORMATION结构 (每个目录条目) 一个结构,因为可以完全包含在 FileInformation 指向的缓冲区中:

  • 在第一次调用时,仅当输出缓冲区至少包含一个完整结构时, NtQueryDirectoryFileEx 才返回STATUS_SUCCESS。
  • 在后续调用中,如果输出缓冲区不包含任何结构,则 NtQueryDirectoryFileEx 返回STATUS_SUCCESS但设置 IoStatusBlock-Information> = 0 以通知调用方此情况。 在这种情况下,调用方应分配更大的缓冲区并再次调用 NtQueryDirectoryFileEx 。 不会报告有关任何剩余条目的信息。 因此,除了上面列出的只返回一个条目的情况外,必须至少调用 两次 NtQueryDirectoryFileEx 才能枚举整个目录的内容。

调用 NtQueryDirectoryFileEx 时,你可能会看到对目录所做的更改与 NtQueryDirectoryFileEx 调用并行发生。 此行为取决于基础文件系统的实现。

NtQueryDirectoryFileEx 的最终调用返回空输出缓冲区并报告适当的状态值,例如STATUS_NO_MORE_FILES。

如果在同一目录上多次调用 NtQueryDirectoryFileEx ,并且某些其他操作更改了该目录的内容,则根据操作的时间安排,可能会看到或看不到任何更改。

NtQueryDirectoryFileEx 在文件系统不支持的 FILE_XXX_INFORMATION 结构的任何成员中返回零。

NtQueryDirectoryFileEx 的调用方必须在 IRQL = PASSIVE_LEVEL运行,并且启用了特殊内核 APC

有关其他文件信息查询例程的信息,请参阅 文件对象

注意

如果对 NtQueryDirectoryFileEx 函数的调用在内核模式下发生,则应使用名称“ZwQueryDirectoryFileEx”而不是“NtQueryDirectoryFileEx”。

对于来自内核模式驱动程序的调用,Windows Native System Services 例程的 NtXxxZwXxx 版本在处理和解释输入参数的方式上的行为可能有所不同。 有关例程的 NtXxxZwXxx 版本之间的关系的详细信息,请参阅 使用本机系统服务例程的 Nt 和 Zw 版本

要求

要求
最低受支持的客户端 Windows 10 版本 1709
标头 ntifs.h
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL (请参阅“备注”部分)

另请参阅

FILE_BOTH_DIR_INFORMATION

FILE_DIRECTORY_INFORMATION

FILE_FULL_DIR_INFORMATION

FILE_ID_BOTH_DIR_INFORMATION

FILE_ID_FULL_DIR_INFORMATION

FILE_NAMES_INFORMATION

FILE_OBJECTID_INFORMATION

FILE_REPARSE_POINT_INFORMATION

UNICODE_STRING

使用本机系统服务例程的 Nt 和 Zw 版本

ZwCreateFile

ZwOpenFile