Функция 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. Если *RestartKeyNULL, значение TRUE указывает RtlEnumerateGenericTableLikeADirectory вернуть следующую запись в дереве после записи, которая соответствует данным в буфере . Значение FALSE указывает RtlEnumerateGenericTableLikeADirectory, чтобы вернуть запись в дереве, которая соответствует данным в буфере .
[in, out] RestartKey
Значение, определяющее, где начать или возобновить перечисление универсальных элементов таблицы. Если *RestartKeyNULL, перечисление начинается или возобновляется с позиции, описанной в буфере. Если не значение 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.
[in, out] DeleteCount
В выходных данных значение, указывающее текущее количество записей, удаленных из таблицы. Вызывающий объект должен передать это значение обратно в следующий вызов RtlEnumerateGenericTableLikeADirectory. Это значение помогает RtlEnumerateGenericTableLikeADirectory подпрограмме определить, произошли ли удаления из таблицы между вызовами RtlEnumerateGenericTableLikeADirectory. Если произошло удаление, перечисление возобновляется с записью таблицы, которая соответствует данным в буфере, а не с записью таблицы, указанной RestartKey. Если *RestartKeyNULL, этот параметр не влияет на перечисление.
[in] Buffer
Ключевое выражение, определяющее начало перечисления, когда *RestartKeyNULL. Вызывающий объект может передать сохраненный ключ, соответствующий определенной записи в таблице, и перечисление начнется с записи, указанной сохраненным ключом, если *RestartKeyNULL и NextFlagFALSE. Чтобы вернуть ключ, который сразу же следует за сохраненным ключом, передайте этот ключ здесь, задайте для параметра *RestartKeyзначение NULL и NextFlag значение TRUE. Если сохраненный ключ был удален, перечисление начнется со следующего соответствующего ключа.
Возвращаемое значение
Подпрограмма RtlEnumerateGenericTableLikeADirectory возвращает указатель на определяемую пользователем структуру, связанную со следующим элементом таблицы в перечислении. Если для возврата возвращаемого значения больше нет новых элементов, значение NULL.
Замечания
Подпрограмма RtlEnumerateGenericTableLikeADirectory предоставляет безопасные средства для перечисления универсальной таблицы между операциями вставки и удаления. Начиная с первого соответствующего имени ключа, RtlEnumerateGenericTableLikeADirectory возвращает каждое имя в таблице ровно один раз, если только имя не было вставлено или удалено во время перечисления. Если имя ключа вставляется или удаляется во время перечисления (т. е. между вызовами RtlEnumerateGenericTableLikeADirectory) может или не может быть включено в перечисление. Зависят ли такие имена от состояния имени, если RtlEnumerateGenericTableLikeADirectory обрабатывает диапазон каталогов, в котором найдено имя.
Существует четыре подпрограммы, которые можно использовать для перечисления универсальной таблицы:
По умолчанию операционная система использует деревья воспроизведения для реализации универсальных таблиц, но RtlEnumerateGenericTableLikeADirectory подпрограмма работает только с деревьями Adelson-Velsky/Landis (AVL). Чтобы настроить универсальные подпрограммы таблиц для использования деревьев AVL вместо деревьев воспроизведения в драйвере, вставьте следующую инструкцию определения в общий файл заголовка перед включением Ntddk.h:
#define RTL_USE_AVL_TABLES 0
Если RTL_USE_AVL_TABLES не определен, необходимо использовать форму AVL универсальных подпрограмм таблиц.
Вызывающие RtlEnumerateGenericTableLikeADirectory должны работать в IRQL <= APC_LEVEL, если имеет одно из следующих условий:
Выделенная вызывающей памятью таблица или буфера можно пространить.
Вызывающий MatchFunction содержит код, доступный для страниц.
Требования
Требование | Ценность |
---|---|
целевая платформа | Всеобщий |
заголовка | ntddk.h (include Ntddk.h, Ntifs.h, FltKernel.h) |
библиотеки | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= APC_LEVEL (см. раздел "Примечания") |