RtlEnumerateGenericTableLikeADirectory 函数 (ntddk.h)

RtlEnumerateGenericTableLikeADirectory 例程按排序规则顺序逐个返回泛型表的元素。

语法

NTSYSAPI PVOID RtlEnumerateGenericTableLikeADirectory(
  [in]           PRTL_AVL_TABLE          Table,
  [in, optional] PRTL_AVL_MATCH_FUNCTION MatchFunction,
  [in, optional] PVOID                   MatchData,
  [in]           ULONG                   NextFlag,
  [in, out]      PVOID                   *RestartKey,
  [in, out]      PULONG                  DeleteCount,
  [in]           PVOID                   Buffer
);

参数

[in] Table

指向 Adelson-Velsky/Landis (AVL) 表的指针, (将枚举 RTL_AVL_TABLE) 。

[in, optional] MatchFunction

确定要返回的条目的匹配函数。 如果未指定,则返回所有节点。

[in, optional] MatchData

要传递给 match 函数的数据。

[in] NextFlag

如果 RestartKey 不为 NULL,则值为 TRUE 表示枚举将跳过元素。 如果 为 FALSE ,则枚举会从上次调用 RtlEnumerateGenericTableLikeADirectory 时中断的位置恢复。 如果 RestartKeyNULL,则值为 TRUE 指示 RtlEnumerateGenericTableLikeADirectory 在与 Buffer 中的数据匹配的条目之后返回树中的下一个条目。 值为 FALSE 指示 RtlEnumerateGenericTableLikeADirectory 返回树中与 Buffer 中的数据匹配的条目。

[in, out] RestartKey

一个 值,该值确定从何处开始或恢复泛型表元素的枚举。 如果 RestartKeyNULL,则枚举将从 Buffer 中所述的位置开始或恢复。 如果不是 NULL,则枚举将从 RestartKey 指示的点恢复。 返回时, RestartKey 保留一个值,该值指示枚举在树中离开的位置。 下次调用 RtlEnumerateGenericTableLikeADirectory 时,调用方应将相同的值传回,以通知 RtlEnumerateGenericTableLikeADirectory 恢复枚举的位置。 下面的代码示例演示了如何执行此操作:

NextFlag = FALSE;
RestartKey = NULL;
DeleteCount = 0;
// Initialize Buffer for start/resume point
Buffer = ...
for (ptr = NULL; ptr != NULL;  ) {
  // Value returned in RestartKey will be passed back in
  // on following call (iteration):
  ptr = RtlEnumerateGenericTableLikeADirectory(
      &MyTable, NULL, NULL, TRUE, &RestartKey,
      &DeleteCount, &Buffer, sizeof(LONG) );
      ...
  // The value output in RestartKey will still be in
  // RestartKey when the
  // RtlEnumerationGenericTableLikeADirectory routine
  // is called in the next iteration of this loop.
  // This ensures that the enumeration will pick up
  // where it left off.
}

如果在调用 RtlEnumerateGenericTableLikeADirectory 期间从树中删除节点,枚举将从 Buffer 中所述的树中的位置恢复,无论 RestartKey 的值是什么。

[in, out] DeleteCount

输出时,该值指示从表中删除的条目的当前计数。 调用方必须在下次调用 RtlEnumerateGenericTableLikeADirectory 时传回此值。 此值可帮助 RtlEnumerateGenericTableLikeADirectory 例程确定在调用 RtlEnumerateGenericTableLikeADirectory 之间是否从表删除。 如果进行了删除,枚举会随着与 Buffer 中的数据匹配的表项(而不是 RestartKey 指示的表项)一起恢复。 如果 RestartKeyNULL,则此参数对 枚举无效。

[in] Buffer

一个键表达式,用于确定 在 RestartKeyNULL 时从何处开始枚举。 调用方可以传入与表中特定条目匹配的已保存键,枚举将从保存的键指定的条目开始,前提是 RestartKeyNULLNextFlagFALSE。 若要返回紧跟在已保存密钥之后的密钥,请在此处传递密钥,将 RestartKey 设置为 NULL将 NextFlag 设置为 TRUE。 如果已删除保存的密钥,枚举将从下一个匹配的键开始。

返回值

RtlEnumerateGenericTableLikeADirectory 例程返回指向与枚举中的下一个 table 元素关联的用户定义的结构的指针。 如果没有更多新元素可返回,则返回值为 NULL

注解

RtlEnumerateGenericTableLikeADirectory 例程提供了一种安全的方法,用于跨混合插入和删除操作枚举泛型表。 从第一个匹配的键名称开始, RtlEnumerateGenericTableLikeADirectory 只返回表中每个名称一次,除非在枚举期间插入或删除了该名称。 在枚举期间插入或删除键名称时, (即在调用 RtlEnumerateGenericTableLikeADirectory) 枚举中可能包含该键名称,也可能不包含该键名称。 是否包含此类名称取决于 RtlEnumerateGenericTableLikeADirectory 处理在其中找到名称的目录范围时的名称状态。

可以使用四个例程来枚举泛型表:

默认情况下,操作系统使用 splay 树来实现泛型表,但 RtlEnumerateGenericTableLikeADirectory 例程仅适用于 Adelson-Velsky/Landis (AVL) 树。 若要将泛型表例程配置为在驱动程序中使用 AVL 树而不是 splay 树,请在包含 Ntddk.h 之前在通用头文件中插入以下 define 语句:

 #define RTL_USE_AVL_TABLES 0

如果未定义RTL_USE_AVL_TABLES,则必须使用泛型表例程的 AVL 形式。

如果满足以下任一条件, 则 RtlEnumerateGenericTableLikeADirectory 的调用方必须在 IRQL <= APC_LEVEL 运行:

  • 调用方在 TableBuffer 处分配的内存是可分页的。

  • 调用方提供的 MatchFunction 包含可分页代码。

要求

要求
目标平台 通用
标头 ntddk.h (包括 Ntddk.h、Ntifs.h、FltKernel.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= APC_LEVEL (请参阅备注部分)

另请参阅

RtlEnumerateGenericTable

RtlEnumerateGenericTableWithoutSplaying

RtlGetElementGenericTable