RtlInsertElementGenericTable 函数 (ntddk.h)
RtlInsertElementGenericTable 例程向泛型表添加新元素。
语法
NTSYSAPI PVOID RtlInsertElementGenericTable(
[in] PRTL_GENERIC_TABLE Table,
[in] PVOID Buffer,
[in] CLONG BufferSize,
[out, optional] PBOOLEAN NewElement
);
参数
[in] Table
指向泛型表 (RTL_GENERIC_TABLE) 的指针。 表必须已通过调用 RtlInitializeGenericTable 进行初始化。
[in] Buffer
指向调用方分配的缓冲区的指针,该缓冲区包含要复制到新元素中的数据。 有关详细信息,请参阅 RtlInitializeGenericTable 的说明。
[in] BufferSize
插入新元素时要为调用方提供的数据分配的字节数。
[out, optional] NewElement
指向变量的指针,如果在泛型表中插入了具有 Buffer 处数据的新元素,则此变量接收 TRUE;如果未插入新元素,则为 FALSE。
返回值
RtlInsertElementGenericTable 返回指向新插入元素的关联数据的指针,如果泛型表中已存在匹配元素,则返回指向现有元素数据的指针。 如果未找到匹配的元素,但无法插入 (新元素,例如,因为 AllocateRoutine) 失败, 则 RtlInsertElementGenericTable 将返回 NULL。
注解
为了插入元素,RtlInsertElementGenericTable 调用在泛型表由 RtlInitializeGenericTable 初始化时注册的 CompareRoutine 和 AllocateRoutine。 插入新元素后, RtlInsertElementGenericTable 将重新平衡 splay 链接树。
将新元素插入表中时,其数据将从 Buffer 复制到新元素中。 因此, RtlInsertElementGenericTable 返回的指针永远不会等于 Buffer。
如果调用方 CompareRoutine 返回 GenericEqual,则假定 Buffer 中的数据复制泛型表中现有元素的数据。 在这种情况下, RtlInsertElementGenericTable 不会 (添加新元素,因此不会调用 AllocateRoutine) ,因为泛型表不能具有重复元素。
如果泛型表中已存在匹配元素, 则 RtlInsertElementGenericTable 返回指向现有元素数据的指针,并将 NewElement 设置为 FALSE。
Rtl. 的调用方。GenericTable 例程负责以独占方式同步对泛型表的访问。 排他快速互斥体是用于此目的的最有效同步机制。
默认情况下,操作系统使用 splay 树来实现泛型表。 在某些情况下,对 splay 树的操作会使树变得深而窄,甚至可能将其变成直线。 非常深的树会降低搜索的性能。 可以通过使用 Adelson-Velsky/Landis (AVL) 树来确保泛型表的更平衡、更浅的树实现。 如果要将泛型表例程配置为使用驱动程序中的 AVL 树而不是 splay 树,请在包含 Ntddk.h 之前在通用头文件中插入以下 define 语句:
#define RTL_USE_AVL_TABLES 0
如果未定义RTL_USE_AVL_TABLES,则必须使用泛型表例程的 AVL 形式。 例如,使用 RtlInsertElementGenericTableAvl 例程,而不是 RtlInsertElementGenericTable。 在调用 RtlInsertElementGenericTableAvl 时,调用方必须传递 RTL_AVL_TABLE 表结构,而不是 RTL_GENERIC_TABLE。
如果满足以下任一条件, 则 RtlInsertElementGenericTable 的调用方必须在 IRQL < DISPATCH_LEVEL 上运行:
- 调用方在 Table 或 Buffer 处分配的内存是可分页的。
- 调用方提供的 CompareRoutine 或 AllocateRoutine 包含可分页代码。
要求
要求 | 值 |
---|---|
目标平台 | 通用 |
标头 | ntddk.h (包括 Ntddk.h、Ntifs.h) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | < DISPATCH_LEVEL (请参阅“备注”部分) |