Ячейки стека ввода/вывода
Основное назначение ячеек стека ввода/вывода (I/O stack location) состоит в том, чтобы хранить функциональный код и параметры запроса на ввод/вывод (последние могут претерпевать изменения при путешествии пакета по стеку драйверов). Ниже приводятся поля ячеек стека ввода/вывода, к которым драйвер может обращаться непосредственно по указателю (чего не рекомендуется делать для остальных полей).
Таблица 8.6. Некоторые элементы ячейки стека ввода/вывода
IO_STACK_LOCATION, *PIO_STACK_LOCATION | ||
Поля | Описание | |
UCHAR MajorFunction | Код IRP_MJ_XXX, описывающий назначение операции | |
UCHAR MinorFunction | Суб-код операции | |
PDEVICE_OBJECT DeviceObject |
Указатель на объект устройства, которому был адресован данный запрос IRP | |
PFILE_OBJECT FileObject | Файловый объект для данного запроса, если он задан | |
union Parameters (трактовка определяется значением MajorFunction): | ||
struct Read | Параметры для IRP типа IRP_MJ_READ: • ULONG Length • ULONG Key • LARGE_INTEGER ByteOffset |
|
struct Write | Параметры для IRP типа IRP_MJ_WRITE: • ULONG Length • ULONG Key • LARGE_INTEGER ByteOffset |
|
struct DeviceIoControl | Параметры для IRP типа IRP_MJ_DEVICE_CONTROL: • ULONG OutputBufferLenght • ULONG InputBufferLenght • ULONG IoControlCode • PVOID Type3InputBuffer |
Для запроса, который адресован драйверу самого нижнего уровня, соответствующий IRP пакет имеет только одну ячейку стека. Для запроса, который послан драйверу верхнего уровня, Диспетчер ввода/вывода создает пакет IRP с несколькими стековыми ячейками — по одной на каждый драйверный слой. Другими словами, размер стека в пакете IRP численно равен количеству драйверных слоев, участвующих в обработке запроса на данную операцию. Любому драйверу в иерархии разрешен доступ только к его собственной — "числящейся" за ним — ячейке стека пакета IRP (хотя никто не контролирует и иные "противоправные" действия).
В случае если текущий драйвер решит обратиться к драйверу более низкого уровня с новым пакетом IRP собственного производства, то он должен гарантировать, что в новом IRP пакете имеется достаточное количество стековых ячеек.
Когда драйвер передает IRP пакет нижнему драйверному уровню, Диспетчер ввода/вывода автоматически изменяет указатель стека ввода/вывода IRP пакета таким образом, что он указывает на стековую ячейку, предназначенную для драйвера очередного нижнего уровня. Когда обработка пакета драйвером нижнего уровня завершена, и он "отпускает" пакет IRP, указатель стека снова возвращается в исходное положение и указывает на ячейку стека для лежащего выше драйвера. Разумеется, для получения указателя на текущую ячейку стека существует специальный системный вызов IoGetCurrentStackLocation.