Поделиться через


Функция 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 приведены следующим образом:

Таблица (CompareRoutine)

Указатель на универсальную таблицу.

FirstStruct

Указатель на первый элемент для сравнения.

Вторая структура

Указатель на второй элемент, который нужно сравнить.

CompareRoutine должны строго отслеживать порядок всех элементов в универсальной таблице, чтобы он смог определить любой конкретный элемент. Структура, определяемая вызывающим элементом, обычно включает элемент, значение которого уникально и может использоваться в качестве ключа сортировки. Все Rtl... Подпрограммы genericTable, которые вызывают CompareRoutine принимают указатель буфера в качестве параметра, который передается в свою очередь CompareRoutine. Буфер содержит значение ключа, предоставленное вызывающим объектом, которое должно соответствовать CompareRoutine с ключом элемента, который выполняется поиск.

Учитывая два таких значения ключей, CompareRoutine возвращает GenericLessThan, GenericGreaterThanили GenericEqual.

[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, чтобы освободить память для удаления элементов из универсальной таблицы. FreeRoutine является противоположностью AllocateRoutine.

[in, optional] TableContext

Необязательный указатель на контекст, предоставленный вызывающим для универсальной таблицы. Этот параметр может быть NULL.

Возвращаемое значение

Никакой

Замечания

Файловые системы вызывают RtlInitializeGenericTable для инициализации универсальной таблицы для хранения данных, относящихся к файловой системе, таких как сведения о поиске имен для открытых файлов. Порядок сортировки, структура и содержимое элементов определяются вызывающим элементом.

Файловые системы должны вызывать RtlInitializeGenericTable, чтобы инициализировать универсальную таблицу перед использованием любой другой Rtl... Подпрограммы genericTable в новой универсальной таблице. Инициализированная универсальная структура таблицы должна считаться непрозрачной.

Вызывающие Rtl... Подпрограммы genericTable отвечают за исключительно синхронизацию доступа к универсальной таблице. Эксклюзивный быстрый мьютекс является наиболее эффективным механизмом синхронизации, используемым для этой цели.

Вызывающий CompareRoutine вызывается перед AllocateRoutine, чтобы найти соответствующее расположение, в котором должен быть вставлен новый элемент. CompareRoutine также вызывается перед FreeRoutine, чтобы найти элемент для удаления.

По умолчанию операционная система использует деревья воспроизведения для реализации универсальных таблиц. При некоторых обстоятельствах операции с деревом воспроизведения сделают дерево глубоким и узким и даже может превратить его в прямую линию. Очень глубокие деревья ухудшают производительность поиска. Вы можете обеспечить более сбалансированную, неглубокую реализацию универсальных таблиц с помощью деревьев Adelson-Velsky/Landis (AVL). Если вы хотите настроить универсальные подпрограммы таблиц для использования деревьев AVL вместо деревьев воспроизведения в драйвере, вставьте следующую инструкцию определения в общий файл заголовка перед включением Ntddk.h:

`#define RTL_USE_AVL_TABLES 0`

Если вы хотите использовать таблицы AVL и если RTL_USE_AVL_TABLES не определены, необходимо использовать форму AVL универсальных подпрограмм таблиц. Например, используйте подпрограмму RtlInitializeGenericTableAvl вместо RtlInitializeGenericTable. RtlInitializeGenericTableAvl возвращает инициализированную 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, AllocateRoutineи FreeRoutine должны быть неизменяемыми кодом, а ВыделенныйRoutine должен выделять память из непагрегированного пула.

Требования

Требование Ценность
целевая платформа Всеобщий
заголовка ntddk.h (include Ntddk.h, Ntifs.h, Fltkernel.h)
библиотеки NtosKrnl.lib
DLL NtosKrnl.exe
IRQL IRQL <= DISPATCH_LEVEL (см. раздел "Примечания")

См. также

ExInitializeFastMutex

RtlDeleteElementGenericTable

RtlEnumerateGenericTable

RtlEnumerateGenericTableWithoutSplaying

RtlGetElementGenericTable

RtlInsertElementGenericTable

RtlLookupElementGenericTable

RtlNumberGenericTableElements