ВУЗ:
Составители:
59
указатель стека на один уровень вверх и продолжает работу. Если же код возврата
совпадает со значением STATUS_MORE_PROCESSING_REQUIRED, функция
IoCompleteRequest прерывает работу и возвращает управление тому, кто ее
вызвал. При этом пакет запроса ввода-вывода IRP оказывается в «подвешенном»
состоянии. Для вывода пакета из такого состояния драйвер, функция завершения
которого прервала
процесс «раскрутки» стека, выполнит эту дополнительную
обработку IRP и опять вызовет функцию IoCompleteRequest для продолжения
процесса завершения.
Следует отметить, что внутри функции завершения вызов функции
IoGetCurrentIrpStackLokation получает указатель на элемент стека, который был
текущим на момент вызова IoSetCompletionRoutine. В функции завершения
нельзя пользоваться содержимым элементов стека нижнего уровня. Во избежание
такого
соблазна функция IoCompleteRequest обнуляет большую часть полей
следующего элемента перед вызовом функции завершения.
3.16 Очереди запросов ввода-вывода
Бывает так, что драйвер получает пакет запроса ввода-вывода IRP, который
он не может обработать сразу. Диспетчерская функция может отвергнуть этот IRP
с кодом ошибки, или поместить его в очередь. Далее в драйвере
реализуется
логика взятия IRP из очереди и передачи его функции StartIo.
В принципе, организовать очередь IRP очень просто. Первый элемент
(якорь) списка включается в объект расширения устройства и инициализируется
функцией AddDevice:
typedef struct _DEVICE_EXTENSION {
LIST_ENTRY IrpQueue;
BOOLEAN DeviceBusy;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
NTSTATUS AddDevice(…)
{
…
InitializeListHead(&pdx->IrpQueue);
…
указатель стека на один уровень вверх и продолжает работу. Если же код возврата совпадает со значением STATUS_MORE_PROCESSING_REQUIRED, функция IoCompleteRequest прерывает работу и возвращает управление тому, кто ее вызвал. При этом пакет запроса ввода-вывода IRP оказывается в «подвешенном» состоянии. Для вывода пакета из такого состояния драйвер, функция завершения которого прервала процесс «раскрутки» стека, выполнит эту дополнительную обработку IRP и опять вызовет функцию IoCompleteRequest для продолжения процесса завершения. Следует отметить, что внутри функции завершения вызов функции IoGetCurrentIrpStackLokation получает указатель на элемент стека, который был текущим на момент вызова IoSetCompletionRoutine. В функции завершения нельзя пользоваться содержимым элементов стека нижнего уровня. Во избежание такого соблазна функция IoCompleteRequest обнуляет большую часть полей следующего элемента перед вызовом функции завершения. 3.16 Очереди запросов ввода-вывода Бывает так, что драйвер получает пакет запроса ввода-вывода IRP, который он не может обработать сразу. Диспетчерская функция может отвергнуть этот IRP с кодом ошибки, или поместить его в очередь. Далее в драйвере реализуется логика взятия IRP из очереди и передачи его функции StartIo. В принципе, организовать очередь IRP очень просто. Первый элемент (якорь) списка включается в объект расширения устройства и инициализируется функцией AddDevice: typedef struct _DEVICE_EXTENSION { LIST_ENTRY IrpQueue; BOOLEAN DeviceBusy; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; NTSTATUS AddDevice(…) { … InitializeListHead(&pdx->IrpQueue); … 59
Страницы
- « первая
- ‹ предыдущая
- …
- 57
- 58
- 59
- 60
- 61
- …
- следующая ›
- последняя »