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


Процедуры AddDevice в драйверах функций или фильтров

Подпрограмма AddDevice в драйвере функции или фильтра должна выполнить следующие действия.

  1. Вызовите IoCreateDevice , чтобы создать функциональный объект или объект устройства фильтра (FDO или фильтр DO) для добавляемого устройства.

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

    Включите FILE_DEVICE_SECURE_OPEN в параметр DeviceCharacteristics . Эта характеристика указывает диспетчеру ввода-вывода выполнять проверки безопасности объекта устройства для всех открытых запросов, включая относительные открытия и открытия конечных имен файлов.

  2. [необязательно] Создайте одну или несколько символических ссылок на устройство.

    Вызовите IoRegisterDeviceInterface , чтобы зарегистрировать функциональные возможности устройства и создать символьную ссылку, которую приложения или системные компоненты могут использовать для открытия устройства. Драйвер должен включить интерфейс, вызвав IoSetDeviceInterfaceState при обработке запроса IRP_MN_START_DEVICE . Дополнительные сведения см. в разделе Классы интерфейса устройства.

  3. Сохраните указатель на PDO устройства в расширении устройства.

    Диспетчер PnP предоставляет указатель на PDO в качестве параметра PhysicalDeviceObject для AddDevice. Драйверы используют указатель PDO в вызовах подпрограмм, таких как IoGetDeviceProperty.

  4. Определите флаги в расширении устройства для отслеживания определенных состояний PnP устройства, таких как приостановлено, удалено и неожиданно удалено.

    Например, определите один флаг, указывающий на то, что входящие irp должны быть удержаны, пока устройство находится в приостановленном состоянии. Создайте очередь для хранения IRP, если у драйвера еще нет механизма для очередей IRP. Дополнительные сведения см. в разделе Очереди и вывод из очереди irPs .

    Кроме того, выделите IO_REMOVE_LOCK структуру в расширении устройства и вызовите IoInitializeRemoveLock для инициализации этой структуры. Дополнительные сведения см. в разделе Использование снятия блокировок.

  5. Задайте бит флага DO_BUFFERED_IO или DO_DIRECT_IO в объекте устройства, чтобы указать тип буферизации, который диспетчер ввода-вывода будет использовать для запросов ввода-вывода, отправляемых в стек устройств. Драйверы более высокого уровня ИЛИ этот элемент с тем же значением, что и следующий драйвер в стеке, за исключением драйверов самого высокого уровня. Дополнительные сведения см. в разделе Инициализация объекта устройства.

  6. При необходимости установите флаг DO_POWER_INRUSH или DO_POWER_PAGABLE для управления питанием. Драйверы, доступные для страниц, должны устанавливать флаг DO_POWER_PAGABLE. Флаги объекта устройства обычно устанавливаются драйвером шины при создании PDO для устройства. Однако драйверам более высокого уровня иногда может потребоваться изменять значения этих флагов в подпрограммах AddDevice при создании FDO или фильтра DO. Дополнительные сведения см. в разделе Настройка флагов объектов устройства для управления питанием .

  7. Создайте и(или) инициализируйте любые другие программные ресурсы, используемые драйвером для управления этим устройством, например событиями, спин-блокировками или другими объектами. (Аппаратные ресурсы, такие как порты ввода-вывода, настраиваются позже в ответ на запрос IRP_MN_START_DEVICE .)

    Так как подпрограмма AddDevice выполняется в контексте системного потока в irQL = PASSIVE_LEVEL, любая память, выделенная с помощью ExAllocatePoolWithTag для использования исключительно во время инициализации, может находиться в выгружаемом пуле, если драйвер не управляет устройством, на котором хранится файл системной подкачки. Такое выделение памяти должно быть освобождено с помощью ExFreePool , прежде чем AddDevice вернет управление.

  8. Подключите объект устройства к стеку устройств (IoAttachDeviceToDeviceStack).

    Укажите указатель на PDO устройства в параметре TargetDevice .

    Сохраните указатель, возвращенный IoAttachDeviceToDeviceStack. Этот указатель, указывающий на объект устройства следующего ниже драйвера для устройства, является обязательным параметром IoCallDriver и PoCallDriver при передаче IRP вниз по стеку устройств.

  9. Снимите флаг DO_DEVICE_INITIALIZING в FDO или отфильтруйте DO с помощью следующей инструкции:

    FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    
  10. Будьте готовы к обработке PnP IRP для устройства (например , IRP_MN_QUERY_RESOURCE_REQUIREMENTS и IRP_MN_START_DEVICE).

Драйвер не должен начинать управление устройством, пока не получит IRP_MN_START_DEVICE , содержащий список аппаратных ресурсов, назначенных устройству диспетчером PnP.