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
初期化されたジェネリック テーブル構造を格納するには、呼び出し元によって割り当てられたバッファーへのポインター 。 sizeof(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
比較する 2 番目の項目へのポインター。
CompareRoutine は、特定の要素を識別できるように、ジェネリック テーブル内のすべての要素の順序を厳密に追跡する必要があります。 通常、要素データの呼び出し元定義構造体には、値が一意であり、並べ替えキーとして使用できるメンバーが含まれます。 すべての Rtl...CompareRoutine を呼び出す GenericTable ルーチンは、バッファー ポインターをパラメーターとして受け取り、次に CompareRoutine に渡されます。 バッファーには、 CompareRoutine によって検索対象の要素のキーと照合される呼び出し元から指定されたキー値が含まれています。
このような 2 つのキー値を指定すると、 CompareRoutine は GenericLessThan、 GenericGreaterThan、または GenericEqual を返します。
[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)
ジェネリック テーブルへのポインター。
バッファー
削除される要素へのポインター。
Rtl。。。GenericTable ルーチンは FreeRoutine を呼び出して、ジェネリック テーブルから削除される要素のメモリの割り当てを解除します。 FreeRoutine は AllocateRoutine の反対です。
[in, optional] TableContext
ジェネリック テーブルの呼び出し元から指定されたコンテキストへの省略可能なポインター。 このパラメーターは、NULL でもかまいません。
戻り値
なし
解説
ファイル システムは RtlInitializeGenericTable を 呼び出して汎用テーブルを初期化し、ファイル システム固有のデータ (現在開いているファイルの名前参照情報など) を格納します。 要素の並べ替え順序、構造、および内容は、呼び出し元によって定義されます。
ファイル システムは、他の Rtl... を使用する前に、汎用テーブルを初期化するために RtlInitializeGenericTable を呼び出す必要があります 。 新しいジェネリック テーブルの GenericTable ルーチン。 初期化されたジェネリック テーブル構造は不透明と見なす必要があります。
Rtl の呼び出し元 ...GenericTable ルーチンは、ジェネリック テーブルへのアクセスを排他的に同期する役割を担います。 排他高速ミューテックスは、この目的で使用する最も効率的な同期メカニズムです。
呼び出し元が指定した CompareRoutine は 、AllocateRoutine の前に呼び出され、新しい要素を挿入する適切な場所を見つけます。 また、削除する要素を見つけるために、FreeRoutine の前に CompareRoutine も呼び出されます。
既定では、オペレーティング システムは splay ツリーを使用して汎用テーブルを実装します。 状況によっては、スプレイ ツリーを操作すると、ツリーが深く狭く、直線に変わる場合もあります。 非常に深いツリーでは、検索のパフォーマンスが低下します。 Adelson-Velsky/Landis (AVL) ツリーを使用して、ジェネリック テーブルのよりバランスの取れた浅いツリー実装を確保できます。 ドライバーでツリーを再生する代わりに AVL ツリーを使用するように汎用テーブル ルーチンを構成する場合は、 Ntddk.h を含める前に、共通ヘッダー ファイルに次の define ステートメントを挿入します。
`#define RTL_USE_AVL_TABLES 0`
AVL テーブルを使用し、RTL_USE_AVL_TABLESが定義されていない場合は、汎用テーブル ルーチンの AVL 形式を使用する必要があります。 たとえば、 RtlInitializeGenericTable の代わりに RtlInitializeGenericTableAvl ルーチン を使用します。 RtlInitializeGenericTableAvl は、Table パラメーターが指すバッファー内の初期化されたRTL_AVL_TABLEテーブル構造を返します。 RtlInitializeGenericTableAvl の呼び出しでは、呼び出し元は、同様のPRTL_GENERIC_Xxx 型ルーチンではなく、PRTL_AVL_COMPARE_ROUTINE型比較コールバック ルーチン、PRTL_AVL_ALLOCATE_ROUTINE型割り当てコールバック ルーチン、およびPRTL_AVL_FREE_ROUTINE型割り当て解除コールバック ルーチンを渡す必要があります。
RtlInitializeGenericTable の呼び出し元は、IRQL <= DISPATCH_LEVELで実行されている必要があります。 Rtl..の場合は注意してください。GenericTable ルーチンは IRQL DISPATCH_LEVELで使用されます。CompareRoutine、AllocateRoutine、FreeRoutine はすべてページ不可能なコードである必要があり、AllocateRoutine は非ページ プールからメモリを割り当てる必要があります。
要件
要件 | 値 |
---|---|
対象プラットフォーム | ユニバーサル |
Header | ntddk.h (Ntddk.h、Ntifs.h、Fltkernel.h を含む) |
Library | NtosKrnl.lib |
[DLL] | NtosKrnl.exe |
IRQL | IRQL <= DISPATCH_LEVEL (「解説」セクションを参照) |