Программирование драйверов Windows




Удаление IRP пакетов - часть 4


Лучшим приемом будет &#8212 дождаться естественного развития событий, когда пакет вернется, вероятнее всего, с каким-нибудь кодом ошибки.

Выяснить, обрабатывается ли рассматриваемый пакет именно сейчас, можно при помощи следующего кода, поскольку, если задействован механизм System Queuing и какой-либо пропущенный через него IRP пакет в настоящий момент обрабатывается, то именно адрес этого IRP пакета "лежит" в поле pDeviceObject-&#62CurrentIrp (иначе там будет NULL):

VOID MyCancelRoutine ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { if( pIrp == pDeviceObject-&#62CurrentIrp ) { . . .

Конкретная реализация действий по удалению текущего пакета (если она возможна) остается задачей разработчика драйвера.

Существенно проще становится ситуация, когда пакет, предназначенный для уничтожения, только что поступил в процедуру StartIo либо еще находится в очереди отложенных (pending) пакетов.

VOID StartIo ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIRp) { KIRQL CancelIrql; IoAcquireCancelSpinLock(&CancelIrql); If(pIrp-&#62Cancel) { IoReleaseCancelSpinLock(CancelIrql); return; } // Удаляем процедуру обработки удаления, делая пакет // "not cancelable" - неуничтожаемым IoSetCancelRoutine(pIrp, NULL); IoReleaseCancelSpinLock(CancelIrql); . . . }

В случае, если удаляемый IRP пакет пока находится в системной очереди (которая называется еще "управляемая StartIo"), a перед его размещением

там (то есть вместе с вызовом IoMarkIrpPending) была зарегистрирована процедура MyCancelRoutine для этого IRP пакета, то действия по удалению такого пакета (не текущего &#8212 не находящегося в обработке) могут выглядеть следующим образом:

VOID MyCancelRoutine( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { if( pIrp == pDeviceObject-&#62CurrentIrp ) { // Текущий IRP IoReleaseCancelSpinLock(pIrp-&#62CancelIrql); // Вряд ли можно сделать что-то еще... } else { // Удаляем из системной очереди: KeRemoveEntryDeviceQueue( &pDeviceObject-&#62DeviceQueue, &pIrp-&#62Tail.Overlay.DeviceQueueEntry); // Только теперь можно освободить спин-блокировку: IoReleaseCancelSpinLock(pIrp-&#62CancelIrql);




Содержание  Назад  Вперед