Как синхронизировать PFLT_POST_OPERATION_CALLBACK с потоком? - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть исходный код драйвера минифильтра, который регистрирует различные IRP-операции с файлами.
Архитектура драйвера довольно проста в своей простоте ...

Он имеет PRE_OPERATION_CALLBACK, этот обратный вызовпусто.

Имеет POST_OPERATION_CALLBACK.Этот обратный вызов получает данные от операций и другими способами (например, получение PID операции, выданной процессом) и добавляет эти данные в журнал «очереди».

И отдельный поток запускается следующим образом:

PsCreateSystemThread(hThread, (ACCESS_MASK)0,
NULL,
(HANDLE) 0,
NULL,
loggerThread,
NULL);

Тема каждые 10 минут проверяет, не заполнена ли очередь.И он заполнен, поток записывает его в журнал (журнал - это файл, но поток также выполняет некоторую обработку данных перед записью - т.е. архивирование и шифрование) и очищает «очередь».

Что такое «очередь»«?Это просто PWCHAR объявлено глобально.Это даже не UNICODE_STRING.Это:

PWCHAR szLogQueue;

Подводя итог: обратный вызов добавляет данные в глобальный PWCHAR;полностью несинхронизированные параллельные потоки проверяют это PWCHAR в первые 10 минут, открывает-пишет-закрывает журнал и снова выделяет PWCHAR (в NonPagedPool).

И все работает ... но код утечки памяти.Несколько часов и вся оперативная память заполнена.Я написал тест - и он за несколько секунд заполняет оперативную память.

Теперь я должен исправить это - добавить ExFreePoolWithTag, где это необходимо и т. Д.
Я не смог изменить архитектуру, т.е. создать пользовательский режимservice и использовать его для записи журнала.

ExFreePoolWithTag, вероятно, следует добавить в поток перед выделением.
Для синхронизации потока и обратного вызова мы могли бы использовать мьютексы.

Но... Пойдем в MSDN.Он говорит: POST_OPERATION_CALLBACK не должен приобретать мьютексы.Он может ждать их, но не получать.

Но MSDN позволяет использовать FltDoCompletionProcessingWhenSafe и FltQueueDeferredIoWorkItem.
Но эти функции не работают с IRP_MJ_WRITE, когда мой драйвер требует его работы (онзаписывает количество записанных байтов в журнал).

Единственный тип блокировки, который мы могли бы использовать, это спин-блокировки , но ограничение в 24 микросекунды может быть слишком маленьким.Я делаю это, если процессор медленный и много задач ...

Вывод: мы не могли использовать здесь какие-либо блокировки.А что делать?

...