RtlInitializeGenericTable 函数 (ntddk.h)

RtlInitializeGenericTable 例程初始化泛型表。

语法

NTSYSAPI VOID RtlInitializeGenericTable(
  [out]          PRTL_GENERIC_TABLE            Table,
  [in]           PRTL_GENERIC_COMPARE_ROUTINE  CompareRoutine,
  [in]           PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine,
  [in]           PRTL_GENERIC_FREE_ROUTINE     FreeRoutine,
  [in, optional] PVOID                         TableContext
);

参数

[out] Table

指向调用方分配的缓冲区的指针,该缓冲区的大小必须至少为 sizeofRTL_GENERIC_TABLE) 字节,以包含初始化的泛型表结构。

[in] CompareRoutine

比较回调例程的入口点,声明如下:

RTL_GENERIC_COMPARE_RESULTS
(*PRTL_GENERIC_COMPARE_ROUTINE) (
    __in struct _RTL_GENERIC_TABLE  *Table,
    __in PVOID  FirstStruct,
    __in PVOID  SecondStruct
    ); 

compareRoutine 参数 如下所示:

表 (CompareRoutine)

指向泛型表的指针。

FirstStruct

指向要比较的第一项的指针。

SecondStruct

指向要比较的第二项的指针。

CompareRoutine 必须严格跟踪泛型表中所有元素的排序,以便它可以标识任何特定元素。 元素数据的调用方定义结构通常包括其值唯一且可用作排序键的成员。 所有 Rtl...泛型Table 例程,用于调用 CompareRoutine 将缓冲区指针作为参数,该参数又传递给 CompareRoutine。 缓冲区包含要由 CompareRoutine 与要搜索的元素的键匹配的调用方提供的键值。

给定两个此类键值时,CompareRoutine返回 genericLessThanGenericGreaterThanGenericEqual

[in] AllocateRoutine

分配回调例程的入口点,声明如下:

PVOID
(*PRTL_GENERIC_ALLOCATE_ROUTINE) (
    __in struct _RTL_GENERIC_TABLE  *Table,
    __in CLONG  ByteSize
    );

AllocateRoutine 参数如下所示:

表 (AllocateRoutine)

指向泛型表的指针。

ByteSize

要分配的字节数。

对于每个新元素,将调用 AllocateRoutine 来为调用方提供的数据分配内存,以及 Rtl 要使用的一些附加内存...GenericTable 例程。 请注意,由于此“额外内存”,调用方提供的例程不能访问泛型表中任何元素的第一个 (sizeof(RTL_SPLAY_LINKS) + sizeof(LIST_ENTRY) 字节。

[in] FreeRoutine

解除分配回调例程的入口点,声明如下:

VOID
(*PRTL_GENERIC_FREE_ROUTINE) (
    __in struct _RTL_GENERIC_TABLE  *Table,
    __in PVOID  Buffer
    );

FreeRoutine 参数如下所示:

表 (FreeRoutine)

指向泛型表的指针。

缓冲区

指向要删除的元素的指针。

Rtl...GenericTable 例程调用 FreeRoutine 解除分配要从泛型表中删除的元素的内存。 FreeRoutineAllocateRoutine相反。

[in, optional] TableContext

指向泛型表的调用方提供的上下文的可选指针。 此参数可以 NULL

返回值

没有

言论

文件系统调用 RtlInitializeGenericTable 初始化泛型表以存储特定于文件系统的数据,例如当前打开的文件的名称查找信息。 元素的排序顺序、结构和内容是调用方定义的。

文件系统必须先调用 RtlInitializeGenericTable 来初始化泛型表,然后才能使用任何其他 Rtl...新泛型表上的 GenericTable 例程。 初始化的泛型表结构应被视为不透明。

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

调用方提供的 CompareRoutineAllocateRoutine 之前调用,以找到应插入新元素的适当位置。 CompareRoutineFreeRoutine 之前调用,以查找要删除的元素。

默认情况下,作系统使用 splay 树来实现泛型表。 在某些情况下,splay 树上的作会使树变得深窄,甚至可能将其变成直线。 非常深的树会降低搜索的性能。 可以使用 Adelson-Velsky/Landis (AVL) 树确保泛型表的更平衡、更浅的树实现。 如果要将泛型表例程配置为使用 AVL 树而不是驱动程序中的 splay 树,请在包含 Ntddk.h之前,在通用头文件中插入以下 define 语句:

`#define RTL_USE_AVL_TABLES 0`

如果要使用 AVL 表,如果未定义RTL_USE_AVL_TABLES,则必须使用泛型表例程的 AVL 形式。 例如,使用 RtlInitializeGenericTableAvl 例程,而不是 RtlInitializeGenericTableRtlInitializeGenericTableAvl 返回 参数指向的缓冲区中初始化的 RTL_AVL_TABLE 表结构。 在调用 RtlInitializeGenericTableAvl中,调用方必须传递PRTL_AVL_COMPARE_ROUTINE类型的比较回调例程、PRTL_AVL_ALLOCATE_ROUTINE类型的分配回调例程和PRTL_AVL_FREE_ROUTINE类型的解除分配回调例程,而不是类似的 PRTL_GENERIC_Xxx类型化例程。

RtlInitializeGenericTable 的调用方必须在 IRQL <= DISPATCH_LEVEL 上运行。 请注意,如果 Rtl...GenericTable 例程用于 IRQL DISPATCH_LEVEL、CompareRoutineAllocateRoutineFreeRoutine 都必须是不可分页的代码,并且 AllocateRoutine 应从非分页池分配内存。

要求

要求 价值
目标平台 普遍
标头 ntddk.h (包括 Ntddk.h、Ntifs.h、Fltkernel.h)
NtosKrnl.lib
DLL NtosKrnl.exe
IRQL IRQL <= DISPATCH_LEVEL (请参阅“备注”部分)

另请参阅

ExInitializeFastMutex

RtlDeleteElementGenericTable

RtlEnumerateGenericTable

RtlEnumerateGenericTableWithoutSplaying

RtlGetElementGenericTable

RtlInsertElementGenericTable

RtlLookupElementGenericTable

RtlNumberGenericTableElements