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


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

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

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

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

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

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

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

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

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

  5. Вызвать WdfRequestCancelSentRequest.

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

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