Синхронизация отмены отправленных запросов

Когда драйвер пытается отменить запрос ввода-вывода, который он перенаправил в целевой объект ввода-вывода, драйвер должен убедиться, что он передает допустимый дескриптор запроса методу WdfRequestCancelSentRequest . Дескриптор запроса становится недопустимым, если целевой объект ввода-вывода завершает запрос, так как функция обратного вызова CompletionRoutine драйвера вызовет WdfRequestComplete (который пытается удалить объект запроса).

Чтобы избежать этой проблемы, драйвер может отслеживать запросы, отправленные в целевой объект ввода-вывода, например, создавая коллекцию объектов запросов. Драйвер может вызвать WdfSpinLockAcquire для синхронизации доступа к коллекции.

При вызове функции обратного вызова CompletionRoutine драйвера она получает блокировку, удаляет дескриптор завершенного запроса из коллекции и вызывает WdfSpinLockRelease , чтобы снять блокировку.

Перед попыткой отменить запрос, который драйвер перенаправил в целевой объект ввода-вывода, драйвер может:

  1. Вызовите WdfSpinLockAcquire , чтобы получить спиновую блокировку.

  2. Найдите дескриптор объекта запроса в коллекции, чтобы убедиться, что подпрограмма завершения драйвера не завершила запрос и не удалила дескриптор из коллекции.

  3. Вызовите WdfObjectReference , чтобы увеличить число ссылок объекта запроса, чтобы невозможно было удалить объект.

  4. Вызовите WdfSpinLockRelease , чтобы освободить спин-блокировку.

  5. Вызовите WdfRequestCancelSentRequest.

  6. Вызовите WdfObjectDereference для уменьшения количества ссылок объекта.

Эта последовательность гарантирует, что если целевой объект ввода-вывода завершает запрос до того, как драйвер вызовет WdfRequestCancelSentRequest, дескриптор запроса по-прежнему действителен (из-за добавочного количества ссылок), даже если функция обратного вызова CompletionRoutine драйвера вызывает WdfRequestComplete.