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


Исполняемый код драйвера - часть 8


Однако в системной очереди это не проходит &#8212 повторный вызов IoStartPacket с только что извлеченным из системной очереди IRP пакетом надежно "заклинивает" системную очередь. В этом имеется своя логика &#8212 если устройство не смогло обработать запрос сейчас, то зачем его снова вставлять в очередь IRP пакетов с такими же параметрами? Они все равно не смогут быть обработаны. Лучшее решение состоит в том, чтобы вернуть управление с соответствующим кодом завершения клиенту, который сам решит, как лучше поступить.

Однако, может возразить внимательный читатель, у драйвера одна процедура StartIo на все типы запросов. И в том случае, если ко всем будет применяться "прогон" через системную очередь, то вполне возможно, что одни запросы действительно не смогут быть обработаны в данный момент (это может установить, например, сама функция StartIo, "пообщавшись" с устройством), в то время как другие запросы могут быть обработаны вполне успешно. Вот если бы можно было выделить из очереди пакеты второго типа, оставляя напоследок пакеты первого типа! Возможно также, что к моменту завершения обработки пакетов более "удачного" типа, устройство станет доступно и для обработки первых, ранее бесперспективных. В данном случае процедуре StartIo (или другим процедурам, получившим управление по ее воле) придется пожертвовать текущим IRP пакетом, который следует завершить с кодом ошибки. Но далее процедура StartIo при помощи вызова IoStartNextPacketByKey

может определить приоритет на извлечение из очереди IRP пакетов по определенному ключу и воплотить таким образом "экономичное" представление разработчика драйвера о работе с IRP пакетами и их сериализацией.

В коде данного драйвера часто встречаются фрагменты, когда указатель на текущий IRP пакет извлекается из поля CurrentIrp в структуре объекта устройства. Возникает вопрос: а всегда ли так можно поступать? Ведь это достаточно простой и удобный способ получения ссылки на IRP пакет в любом месте драйвера, которым так хочется пользоваться! Ответ: к сожалению, далеко не всегда и не везде. Диспетчер ввода/вывода устанавливает в поле CurrentIrp в структуре объекта устройства значение указателя на IRP пакет только для текущего пакета, который участвует в работе через системную очередь (System Queuing). Этот IRP пакет сейчас один из всех, которые возможно были занесены в эту очередь данным драйвером или, иными словами, данным объектом устройства, поступил на обработку в функцию StartIo и до окончания его обработки (с каким либо кодом завершения в одной из функций драйвера) другого адреса в поле CurrentIrp не появится. Соответственно, если разработчик так написал драйвер, что адрес такого IRP пакета где-то "оседает" (задерживается, например, в параллельно работающем системном потоке данного драйвера), то это может быть источником краха системы, поскольку обращение к области хранения полностью завершенных IRP пакетов совершенно некорректно.
<


Начало  Назад  Вперед