RtlInsertElementGenericTableFullAvl 函数 (ntddk.h)

RtlInsertElementGenericTableFullAvl 例程向泛型表添加新条目。

语法

NTSYSAPI PVOID RtlInsertElementGenericTableFullAvl(
  [in]            PRTL_AVL_TABLE      Table,
  [in]            PVOID               Buffer,
  [in]            CLONG               BufferSize,
  [out, optional] PBOOLEAN            NewElement,
  [in]            PVOID               NodeOrParent,
  [in]            TABLE_SEARCH_RESULT SearchResult
);

参数

[in] Table

指向泛型 Adelson-Velsky/Landis 的指针 (AVL) 表 (RTL_AVL_TABLE 通过调用 RtlInitializeGenericTableAvl 初始化的) 。

[in] Buffer

调用方分配的缓冲区,其中包含要复制到新元素的用户数据。 有关详细信息,请参阅 RtlInitializeGenericTableAvl

[in] BufferSize

缓冲区中数据的大小(以字节为单位 )。

[out, optional] NewElement

输出时,值为 TRUE 表示成功在泛型表中插入新元素。 值为 FALSE 表示插入失败。

[in] NodeOrParent

以前调用 RtlLookupElementGenericTableFullAvl 的搜索结果。 此值向 RtlInsertElementGenericTableFullAvl 例程指示树当前是否为空,或者是否为空,是将新条目插入父项的左侧还是右侧。 SearchResult 参数可以具有以下任何值:

TableEmptyTree

树是空的。 NodeOrParent 的内容尚未更改。

TableFoundNode

RtlInsertElementGenericTableFullAvl 例程发现了一个表条目,其键与 Buffer 中的数据匹配。 NodeOrParent 包含指向匹配项的指针。

TableInsertAsLeft

RtlInsertElementGenericTableFullAvl 例程找不到其键与 Buffer 中的数据匹配的表项。 如果 RtlInsertElementGenericTableFullAvl 搜索的条目位于表中,则它将是 NodeOrParent 指向的条目的左侧子项。

TableInsertAsRight

RtlInsertElementGenericTableFullAvl 例程找不到其键与 Buffer 中的数据匹配的表项。 如果 RtlInsertElementGenericTableFullAvl 搜索的条目位于表中,则它将是 NodeOrParent 指向的条目的正确子项。

[in] SearchResult

指向表项的指针。 如果 RtlInsertElementGenericTableFullAvl 例程匹配某个条目, 则 NodeOrParent 指向匹配项。 如果 RtlInsertElementGenericTableFullAvl 例程找不到匹配项, NodeOrParent 指向作为 RtlInsertElementGenericTableFullAvl 例程所搜索项的父项的条目。

返回值

RtlInsertElementGenericTableFullAvl 返回指向新插入条目的用户数据,或指向已在泛型表中的匹配项的用户数据。 如果没有找到匹配的条目,但 RtlInsertElementGenericTableFullAvl 无法插入新条目 (例如,因为 AllocateRoutine 失败) ,RtlInsertElementGenericTableFullAvl 返回 NULL

注解

为了插入条目,RtlInsertElementGenericTableFullAvl 调用由 RtlInitializeGenericTableAvl 初始化泛型表时注册的 CompareRoutineAllocateRoutine。 插入新条目后, RtlInsertElementGenericTableFullAvl 重新平衡 AVL 链接树。

将新条目插入表中时,其数据将从 Buffer 复制到新条目中。 因此, RtlInsertElementGenericTableFullAvl 返回的指针永远不会等于 Buffer

如果调用方 CompareRoutine 返回 GenericEqual,则假定 Buffer 中的数据将复制泛型表中现有条目的数据。 在这种情况下, RtlInsertElementGenericTableFullAvl 不会 (添加新条目,因此不会调用 AllocateRoutine) ,因为泛型表不能具有重复条目。

如果泛型表中已存在匹配项, RtlInsertElementGenericTableFullAvl 将返回指向现有条目数据的指针,并将 NewElement 设置为 FALSE

如果表中已不存在匹配项,RtlInsertElementGenericTableFullAvl 例 程会为新条目的用户数据分配足够的空间, (BufferSize) 以及与新条目关联的链接。 因此,总字节数至少为 BufferSize + 大小 (BALANCED_LINKS) 。 调用方不应使用 AllocateRoutine分配的内存 (BALANCED_LINKS) 字节的第一个大小

Rtl.的调用方。GenericTableAvl 例程负责以独占方式同步对泛型表的访问。 独占快速互斥体是用于此目的的最有效同步机制。

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

#define RTL_USE_AVL_TABLES 0

如果未定义RTL_USE_AVL_TABLES,则必须使用泛型表例程的 AVL 形式。 例如,使用 RtlInsertElementGenericTableFullAvl 例程,而不是 RtlInsertElementGenericTableFull。 在调用 RtlInsertElementGenericTableFullAvl 时,调用方必须传递 RTL_AVL_TABLE 表结构,而不是 RTL_GENERIC_TABLE

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

  • 缓冲区的调用方分配的内存可分页。
  • 调用方提供的 CompareRoutineAllocateRoutine 包含可分页代码。

要求

要求
最低受支持的客户端 在 Windows XP 和更高版本的 Windows 操作系统中可用。
目标平台 通用
标头 ntddk.h (包括 Ntddk.h、Ntifs.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL < DISPATCH_LEVEL (请参阅备注部分)

另请参阅

RtlDeleteElementGenericTable

RtlInitializeGenericTable