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 初始化泛型數據表時所註冊的 CompareRoutine 和 AllocateRoutine。 插入新項目之後, RtlInsertElementGenericTableFullAvl 會重新平衡 AVL 連結樹狀結構。
當新專案插入數據表時,其數據會從 Buffer 複製到新專案。 因此 ,RtlInsertElementGenericTableFullAvl 傳回的指標永遠不會等於 Buffer。
如果呼叫端的 CompareRoutine 傳回 GenericEqual,則會假設 Buffer 上的數據會複製泛型數據表中現有項目的數據。 在此情況下, RtlInsertElementGenericTableFullAvl 不會新增專案 (,因此不會呼叫 AllocateRoutine) ,因為泛型數據表不能有重複的專案。
如果泛型數據表中已經有相符的專案, RtlInsertElementGenericTableFullAvl 會 傳回現有項目數據的指標,並將 NewElement 設定為 FALSE。
如果數據表中還沒有相符的專案,RtlInsertElementGenericTableFullAvl 例程會為新專案的用戶數據配置足夠的空間, (BufferSize) 加上與新專案相關聯的連結。 因此,位元組總數至少會是 BufferSize + sizeof (BALANCED_LINKS) 。 呼叫端不應該使用 AllocateRoutine配置之內存的第一個 sizeof (BALANCED_LINKS) 位元組。
Rtl 的呼叫端。GenericTableAvl 例程負責獨佔同步處理泛型數據表的存取。 獨佔快速 Mutex 是用於此用途的最有效率同步處理機制。
根據預設,操作系統會使用 splay 樹狀架構來實作一般數據表,但 RtlInsertElementGenericTableFullAvl 例程只適用於 Adelson-Velsky/Landis (AVL) 樹狀結構。 若要將泛型數據表例程設定為使用AVL樹狀結構,而不是驅動程式中的splay樹狀結構,請在包含 Ntddk.h之前,先在通用頭檔中插入下列 define 語句:
#define RTL_USE_AVL_TABLES 0
如果未定義RTL_USE_AVL_TABLES,您必須使用泛型數據表例程的AVL格式。 例如,使用 RtlInsertElementGenericTableFullAvl 例程,而不是 RtlInsertElementGenericTableFull。 在 對 RtlInsertElementGenericTableFullAvlAvl 的呼叫中,呼叫端必須傳遞 RTL_AVL_TABLE 數據表結構,而不是 RTL_GENERIC_TABLE。
如果符合下列任一條件, 則 RtlInsertElementGenericTableFullAvl 的 呼叫端必須在 IRQL < DISPATCH_LEVEL上執行:
- 數據表或 Buffer 的呼叫端配置記憶體是可分頁的。
- 呼叫端提供的 CompareRoutine 或 AllocateRoutine 包含可分頁程式代碼。
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | 可在 Windows XP 和更新版本的 Windows 作業系統中使用。 |
目標平台 | Universal |
標頭 | ntddk.h (包含 Ntddk.h、Ntifs.h) |
程式庫 | NtosKrnl.lib |
Dll | NtosKrnl.exe |
IRQL | < DISPATCH_LEVEL (请参阅一节) |