Последовательность запуска

Так как драйвер адаптера устанавливается в качестве службы драйверов в режиме ядра, операционная система загружает драйвер адаптера во время запуска системы и вызывает подпрограмму DriverEntry драйвера. Подпрограмма DriverEntry получает два параметра: объект драйвера и имя пути реестра. DriverEntry должен вызвать функцию PortCls PcInitializeAdapterDriver с параметрами имени драйвера-объекта и пути реестра, а также третьим параметром, который является указателем на функцию AddDevice драйвера адаптера.

В следующем примере функция DriverEntry драйвера передает указатель MyAddDeviceфункции, который указывает на функцию AddDevice драйвера в качестве третьего параметра в подпрограмму PcInitializeAdapterDriver .

NTSTATUS 
  DriverEntry( 
    PDRIVER_OBJECT  DriverObject,
    PUNICODE_STRING  RegistryPath
    )
  {
      return PcInitializeAdapterDriver(DriverObject, RegistryPath, MyAddDevice);
  }

Подпрограмма PcInitializeAdapterDriver устанавливает указанную подпрограмму AddDevice в расширение драйвера и устанавливает обработчики IRP драйвера PortCls в самом объекте драйвера.

Следующий код является примером реализации функции драйвера MyAddDevice .

#define MAX_MINIPORTS 6    // maximum number of miniports
NTSTATUS
  MyAddDevice(
    PDRIVER_OBJECT  DriverObject,
    PDEVICE_OBJECT  PhysicalDeviceObject 
    )
  {
      return PcAddAdapterDevice(DriverObject, PhysicalDeviceObject, MyStartDevice,
                                MAX_MINIPORTS, 0);
  }

Эта функция вызывает функцию PortCls PcAddAdapterDevice, которая создает указанное устройство адаптера, связывает драйвер с устройством и сохраняет указатель на функцию драйвера MyStartDevice адаптера, которая вызывается при запуске устройства (см. раздел "Запуск устройства"). Подпрограмма PcAddAdapterDevice создает функциональный объект устройства (FDO) и связывает его с объектом физического устройства (PDO), предоставляемым системой. Новый FDO создается с расширением, которое PortCls использует для хранения сведений о контексте устройства. Этот контекст включает указатель функции, предоставленный MyStartDeviceMyAddDevice.

После того как операционная система определяет, какие ресурсы (прерывания, каналы DMA, адреса портов ввода-вывода и т. д.) назначаются устройству, он отправляет устройству запрос на запуск (IRP_MN_START_DEVICE). В ответ на этот запрос обработчик запросов в драйвере PortCls вызывает функцию драйвера MyStartDevice адаптера, которая показана в следующем примере кода:

NTSTATUS
  MyStartDevice(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PRESOURCELIST ResourceList
    )
  {
    ...
  }

Обработчик запросов предоставляет MyStartDevice указатели на объект устройства, запрос IRP_MN_START_DEVICE и список ресурсов (см. IResourceList). Функция MyStartDevice секционирует список ресурсов в ресурсы, необходимые для каждого драйвера минипорта, который необходимо запустить. Затем функция запускает каждый мини-драйвер и возвращает управление PortCls, которая завершает IRP и возвращает управление операционной системе.

Дополнительные примеры кода запуска драйвера можно найти среди образцов драйверов аудиоадаптеров в комплектах драйверов для Microsoft Windows (WDK).