共用方式為


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

呼叫端配置的緩衝區指標,其大小必須至少為 ( RTL_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 參數如下所示:

Table (CompareRoutine)

泛型數據表的指標。

FirstStruct

要比較之第一個專案的指標。

SecondStruct

要比較之第二個專案的指標。

CompareRoutine 必須嚴格追蹤泛型數據表中所有元素的順序,以便識別任何特定元素。 元素數據的呼叫端定義結構通常包含其值是唯一且可作為排序索引鍵的成員。 所有 Rtl... 呼叫 CompareRoutine 的 GenericTable 例程會採用緩衝區指標作為參數,而該參數會接著傳遞至 CompareRoutine。 緩衝區包含呼叫端提供的索引鍵值,由 CompareRoutine 與所搜尋專案的索引鍵進行比對。

假設有兩個這類索引鍵值, CompareRoutine 會傳回 GenericLessThanGenericGreaterThanGenericEqual

[in] AllocateRoutine

配置回呼例程的進入點,宣告如下:

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

AllocateRoutine 參數如下所示:

Table (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 參數如下所示:

Table (FreeRoutine)

泛型數據表的指標。

Buffer

正在刪除之項目的指標。

Rtl。。。GenericTable 例程會呼叫 FreeRoutine ,以解除分配要從泛型數據表中刪除之專案的記憶體。 FreeRoutineAllocateRoutine 相反。

[in, optional] TableContext

泛型數據表之呼叫端提供內容的選擇性指標。 此參數可以是 Null

傳回值

備註

文件系統會呼叫 RtlInitializeGenericTable 來初始化泛型數據表,以儲存文件系統特定的數據,例如目前開啟檔案的名稱查閱資訊。 元素的排序順序、結構和內容都是呼叫端定義的。

文件系統必須先呼叫 RtlInitializeGenericTable 來初始化泛型數據表,才能使用任何其他 Rtl...新泛 型數據表上的 GenericTable 例程。 初始化的泛型數據表結構應該視為不透明。

Rtl 的呼叫端 ...GenericTable 例程負責獨佔同步處理泛型數據表的存取。 獨佔快速 Mutex 是用於此用途的最有效率同步處理機制。

呼叫端提供的 CompareRoutine 會在 AllocateRoutine 之前呼叫,以找出應該插入新元素的適當位置。 CompareRoutine 也會在 FreeRoutine 之前呼叫,以找出要刪除的專案。

根據預設,操作系統會使用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 會在 Table 參數指向的緩衝區中傳回初始化的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、CompareRoutine、AllocateRoutineFreeRoutine 都必須是不可分頁的程式代碼,且 AllocateRoutine 應該從非分頁集區配置記憶體。

規格需求

需求
目標平台 Universal
標頭 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