RtlEnumerateGenericTableLikeADirectory 函式 (ntddk.h)
RtlEnumerateGenericTableLikeADirectory 例程會以定序順序傳回泛型數據表的專案。一對一。
語法
NTSYSAPI PVOID RtlEnumerateGenericTableLikeADirectory(
[in] PRTL_AVL_TABLE Table,
[in, optional] PRTL_AVL_MATCH_FUNCTION MatchFunction,
[in, optional] PVOID MatchData,
[in] ULONG NextFlag,
[in, out] PVOID *RestartKey,
[in, out] PULONG DeleteCount,
[in] PVOID Buffer
);
參數
[in] Table
Adelson-Velsky/Landis (AVL) 數據表的指標, (將列舉 RTL_AVL_TABLE) 。
[in, optional] MatchFunction
比對函式,決定要傳回的專案。 如果未指定,則會傳回所有節點。
[in, optional] MatchData
要傳遞至比對函式的數據。
[in] NextFlag
如果 RestartKey 不是 NULL,則值為 TRUE 表示列舉將會略過元素。 如果 為 FALSE ,則列舉會繼續在先前呼叫 RtlEnumerateGenericTableLikeADirectory 時離開的位置。 如果 RestartKey 為 NULL,則 TRUE 的值會指示 RtlEnumerateGenericTableLikeADirectory 在符合 Buffer 中數據的項目之後,傳回樹狀結構中的下一個專案。 FALSE 的值會指示 RtlEnumerateGenericTableLikeADirectory 傳回樹狀結構中符合 Buffer 中數據的專案。
[in, out] RestartKey
值,決定要從何處開始或繼續泛型數據表專案的列舉。 如果 RestartKey 為 NULL,列舉就會從 Buffer 中所述的位置開始或繼續。 如果不是 NULL,列舉會從 RestartKey 所指出的點繼續。 傳回時, RestartKey 會保留一個值,指出列舉離開的樹狀結構中的位置。 在下一次呼叫 RtlEnumerateGenericTableLikeADirectory 呼叫端時,應該將相同的值傳回 ,以通知 RtlEnumerateGenericTableLikeADirectory 繼續列舉的位置。 下列程式代碼範例說明如何執行這項操作:
NextFlag = FALSE;
RestartKey = NULL;
DeleteCount = 0;
// Initialize Buffer for start/resume point
Buffer = ...
for (ptr = NULL; ptr != NULL; ) {
// Value returned in RestartKey will be passed back in
// on following call (iteration):
ptr = RtlEnumerateGenericTableLikeADirectory(
&MyTable, NULL, NULL, TRUE, &RestartKey,
&DeleteCount, &Buffer, sizeof(LONG) );
...
// The value output in RestartKey will still be in
// RestartKey when the
// RtlEnumerationGenericTableLikeADirectory routine
// is called in the next iteration of this loop.
// This ensures that the enumeration will pick up
// where it left off.
}
如果在呼叫 RtlEnumerateGenericTableLikeADirectory 之間從樹狀結構中刪除節點,則不論 RestartKey 的值為何,列舉都會從 Buffer 中所述的樹狀結構中的位置繼續執行。
[in, out] DeleteCount
在輸出時,值表示從數據表中刪除的專案目前計數。 呼叫端必須在下一次呼叫 RtlEnumerateGenericTableLikeADirectory 時傳回此值。 此值可協助 RtlEnumerateGenericTableLikeADirectory 例程判斷從數據表刪除是否發生在 呼叫 RtlEnumerateGenericTableLikeADirectory 之間。 如果發生刪除,列舉會繼續執行符合 Buffer 中數據的數據表專案,而不是 使用 RestartKey 所指示的數據表專案。 如果 RestartKey 為 NULL,則此參數不會影響 列舉。
[in] Buffer
當 RestartKey 為 NULL 時,決定要從何處開始列舉的索引鍵表達式。 呼叫端可以傳入符合數據表中特定專案的已儲存密鑰,而且列舉會從儲存的金鑰所指定的項目開始,前提是 RestartKey 為 NULL ,且 NextFlag 為 FALSE。 若要傳回緊接在已儲存密鑰之後的金鑰,請在這裡傳入密鑰,將 RestartKey 設定為 NULL ,並將 NextFlag 設定為 TRUE。 如果已刪除儲存的金鑰,列舉會以下一個相符的索引鍵開始。
傳回值
RtlEnumerateGenericTableLikeADirectory 例程會傳回與列舉中下一個數據表元素相關聯的使用者定義結構指標。 如果沒有其他新元素可傳回,則傳回值為 NULL。
備註
RtlEnumerateGenericTableLikeADirectory 例程提供安全的方法,可列舉混合插入和刪除作業之間的泛型數據表。 從第一個相符的索引鍵名稱開始,除非在列舉期間插入或刪除名稱, 否則 RtlEnumerateGenericTableLikeADirectory 會傳回數據表中每個名稱一次。 在列舉期間插入或刪除索引鍵名稱時 (亦即,在 呼叫 RtlEnumerateGenericTableLikeADirectory 之間,) 可能或可能不會包含在列舉中。 當 RtlEnumerateGenericTableLikeADirectory 處理找到名稱的目錄範圍時,是否包含這類名稱取決於名稱的狀態。
有四個例程可用來列舉泛型數據表:
根據預設,操作系統會使用 splay 樹狀結構來實作一般數據表,但 RtlEnumerateGenericTableLikeADirectory 例程只適用於 Adelson-Velsky/Landis (AVL) 樹狀結構。 若要將泛型數據表例程設定為使用AVL樹狀結構,而不是驅動程式中的splay樹狀結構,請在包含Ntddk.h之前,先在通用頭檔中插入下列 define 語句:
#define RTL_USE_AVL_TABLES 0
如果未定義RTL_USE_AVL_TABLES,您必須使用泛型數據表例程的AVL格式。
如果下列任一條件成立, 則 RtlEnumerateGenericTableLikeADirectory 的呼叫端必須在 IRQL <= APC_LEVEL執行:
數據表或 Buffer 的呼叫端配置記憶體是可分頁的。
呼叫端提供的 MatchFunction 包含可分頁程序代碼。
規格需求
需求 | 值 |
---|---|
目標平台 | Universal |
標頭 | ntddk.h (包含 Ntddk.h、Ntifs.h、FltKernel.h) |
程式庫 | NtosKrnl.lib |
Dll | NtosKrnl.exe |
IRQL | <= APC_LEVEL (请参阅一节) |