Поделиться через


Инициализация объекта устройства

После возврата IoCreateDevice , предоставив вызывающму объекту указатель на DeviceObject , содержащий указатель на расширение устройства, драйверы должны настроить определенные поля в объектах устройства для соответствующих физических, логических и (или) виртуальных устройств.

IoCreateDevice задает для поля StackSize вновь созданного объекта устройства значение 1. Драйвер самого низкого уровня может игнорировать это поле. Когда драйвер более высокого уровня вызывает IoAttachDeviceToDeviceStack для подключения к драйверу следующего уровня, эта подпрограмма автоматически устанавливает поле StackSize в объекте устройства в значение объекта устройства следующего ниже драйвера плюс один. Однако для некоторых типов устройств драйверу более высокого уровня может потребоваться задать для поля StackSize большее значение, как указано в документации по устройству. Настройка размера стека гарантирует, что irP, отправляемые драйверу более высокого уровня, будут содержать расположение стека ввода-вывода для конкретного драйвера, а также правильное количество расположений стека ввода-вывода для всех драйверов более низкого уровня в цепочке.

IoCreateDevice задает для поля AlignmentRequirement вновь созданного объекта устройства размер строки кэша данных процессора минус единица, чтобы обеспечить правильное выравнивание буферов, используемых в прямом вводе-выводе. После возврата IoCreateDevice драйверы физических устройств самого низкого уровня должны выполнять следующие действия.

  1. Вычитает один из требований к выравниванию устройства.

  2. Сравните результат шага 1 с текущим значением объекта устройства AlignmentRequirement.

  3. Если для устройства больше требований к выравниванию, задайте для параметра AlignmentRequirement результат шага 1. В противном случае оставьте значение AlignmentRequirement , заданное IoCreateDevice.

После того, как любой драйвер более высокого уровня связан с другим драйвером путем вызова IoGetDeviceObjectPointer, драйвер более высокого уровня должен задать поле AlignmentRequirement своего вновь созданного объекта устройства на поле устройства следующего ниже уровня. Как правило, драйвер более высокого уровня не должен изменять это значение. Если драйвер более высокого уровня вызывает IoAttachDevice или IoAttachDeviceToDeviceStack, эти подпрограммы автоматически устанавливают поле AlignmentRequirement в объекте устройства на поле объекта устройства драйвера нижнего уровня.

IoGetDeviceObjectPointer возвращает указатели как на объект устройства драйвера нижнего уровня, так и на связанный файловый объект. Только FSD (или, возможно, другой драйвер самого высокого уровня) может использовать возвращаемый указатель на объект файла. Промежуточный драйвер, вызывающий IoGetDeviceObjectPointer , должен сохранить этот указатель на объект файла, чтобы его можно было разыменовать, вызвав ObDereferenceObject при выгрузке драйвера.

После подключения FSD тома, содержащего файловый объект, представляющий объект устройства нижнего драйвера, промежуточный драйвер не может связать себя между файловой системой и нижним драйвером, вызвав IoAttachDevice или IoAttachDeviceToDeviceStack. Кроме того, FSD может задать элемент SectorSize объекта устройства на основе геометрии базового оборудования тома при подключении. Дополнительные сведения см. в разделе DEVICE_OBJECT.

Драйвер промежуточного или нижнего уровня также задает бит в флагах объекта устройства путем ORing он либо с DO_DIRECT_IO, либо с DO_BUFFERED_IO в каждом создаваемом объекте устройства. Высокоуровневые драйверы логических или виртуальных устройств могут избежать установки флагов для буферизованного или прямого ввода-вывода, если модуль записи драйверов решит, что дополнительная работа окупится в повышении производительности драйвера. Промежуточный драйвер должен настроить поле Флаги своего объекта устройства в соответствии с полем объекта устройства следующего ниже драйвера.

Настройка поля флагов объекта устройства с DO_DIRECT_IO или DO_BUFFERED_IO определяет, как диспетчер ввода-вывода передает доступ к пользовательским буферам во всех запросах на передачу данных, отправляемых драйверу.

Затем драйвер может задать любые другие зависимые от устройства значения в объекте устройства. Например, драйверы, не относящиеся к WDM, для устройств со съемными носителями должны иметь или элемент Flags объекта устройства с DO_VERIFY_VOLUME, если они обнаруживают (или подозревают) изменение носителя во время операций ввода-вывода. (Дополнительные сведения см. в разделе Поддержка съемных носителей .) Драйверы устройств, для которых требуется вхощревающее питание, должны иметь или член Flags с DO_POWER_INRUSH, а драйверы устройств, которые не находятся в системном пути разбиения по страницам, должны иметь или элемент Flags с DO_POWER_PAGABLE. Драйверы функций и фильтров должны снять флаг DO_DEVICE_INITIALIZING.

После инициализации объекта устройства драйвер может также инициализировать любые объекты, определенные ядром, и другие системные структуры данных, для которых он предоставил хранилище в расширении устройства. Именно то, когда драйвер выполняет эти задачи, зависит от его устройства, типа объекта и (или) характера данных. Как правило, любые объекты или структуры данных, которые могут сохраняться с помощью запросов запуска и остановки PnP, можно инициализировать в подпрограмме AddDevice . Те, для которых требуются сведения о ресурсе, предоставленные запросом IRP_MN_START_DEVICE PnP или которые могут потребовать изменений при остановке и (или) перезапуске устройства, должны быть инициализированы, когда драйвер обрабатывает запрос IRP_MN_START_DEVICE . Дополнительные сведения о процедурах AddDevice см. в статье Создание процедуры AddDevice.