Синхронизация отмены отправленных запросов
Когда драйвер пытается отменить запрос ввода-вывода, который он перенаправил в целевой объект ввода-вывода, драйвер должен убедиться, что он передает допустимый дескриптор запроса методу WdfRequestCancelSentRequest . Дескриптор запроса становится недопустимым, если целевой объект ввода-вывода завершает запрос, так как функция обратного вызова CompletionRoutine драйвера вызовет WdfRequestComplete (который пытается удалить объект запроса).
Чтобы избежать этой проблемы, драйвер может отслеживать запросы, отправленные в целевой объект ввода-вывода, например, создавая коллекцию объектов запросов. Драйвер может вызвать WdfSpinLockAcquire для синхронизации доступа к коллекции.
При вызове функции обратного вызова CompletionRoutine драйвера она получает блокировку, удаляет дескриптор завершенного запроса из коллекции и вызывает WdfSpinLockRelease , чтобы снять блокировку.
Перед попыткой отменить запрос, который драйвер перенаправил в целевой объект ввода-вывода, драйвер может:
Вызовите WdfSpinLockAcquire , чтобы получить спиновую блокировку.
Найдите дескриптор объекта запроса в коллекции, чтобы убедиться, что подпрограмма завершения драйвера не завершила запрос и не удалила дескриптор из коллекции.
Вызовите WdfObjectReference , чтобы увеличить число ссылок объекта запроса, чтобы невозможно было удалить объект.
Вызовите WdfSpinLockRelease , чтобы освободить спин-блокировку.
Вызовите WdfRequestCancelSentRequest.
Вызовите WdfObjectDereference для уменьшения количества ссылок объекта.
Эта последовательность гарантирует, что если целевой объект ввода-вывода завершает запрос до того, как драйвер вызовет WdfRequestCancelSentRequest, дескриптор запроса по-прежнему действителен (из-за добавочного количества ссылок), даже если функция обратного вызова CompletionRoutine драйвера вызывает WdfRequestComplete.