Отмена запросов ввода/вывода Всякий раз, когда запрос ввода/вывода удерживается драйвером
в течение продолжительного отрезка времени, драйвер должен быть готов
к отмене данного запроса. В случае закрытия потока диспетчер ввода/вывода
пытается отменить все запросы ввода/вывода, отправленные этим потоком
и еще не завершенные. Пока все такие запросы ввода/вывода не будут завершены
устройством, ему не придет запрос IRP_MJ_ CLOSE, и, следовательно, не
освободится объект-файл, а впоследствии - и само устройство (драйвер никогда
не получит запрос DriverUnload). PDRIVER_CANCEL loSetCancelRoutine(IN
PIRP Irp, Где функция CancelRoutine() имеет такой же прототип, как и все диспетчерские функции. VOID CancelRoutine(IN PDEVICE_OBJECT
DeviceObject, Она вызывается на уровне IRQL DISPATCH_LEVEL в случайном контексте потока, однако перед ее вызовом происходит захват специальной системной спин-блокировки. До тех пор, пока системная спин-блокировка не будет освобождена, функция CancelRoutine() работает на уровне IRQL DISPATCH_LEVEL. Уровень IRQL, на который нужно перейти после освобождения блокировки указывается при вызове IoReleaseCancelSpinLock() (см. ниже). Принцип реализации функции следующий:
Системная спин-блокировка отмены IRP освобождается с помощью loRelease CancelSpinLock(): VOID IoReleaseCancelSpinLock(IN KIRQL Irgl); Где: Irql - уровень IRQL, на который система должна вернуться после освобождения спин-блокировки. Это значение хранится в IRP в поле Cancellrql. Отмена IRP и Системная Очередь Пример функции отмены IRP драйвера, использующего системную очередь, показан в следующем листинге. Необходимо отметить, что для удаления IRP из системной очереди используется функция KeRemoveEntryDeviceQueue() так, как это показано в листинге. VOID Cancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ Отмена IRP и очереди, управляемые драйвером VOID Cancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ ' |
Blog
Home - Blog