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


Новые рабочие процедуры в WDM драйверах


Процедура AddDevice, вызываемая PnP Менеджером, только лишь производит инициализацию объекта устройства и, если необходимо, структуры данных расширения объекта устройства. В процедуре AddDevice, по правилам хорошего тона WDM модели, действия над собственно аппаратурой не должны совершаться. Но тогда остаются нерешенными две важные задачи:

  • резервирование и конфигурирование аппаратных ресурсов обслуживаемого физического устройства;
  • инициализация и подготовка аппаратной части к использованию.

Все это должен сделать драйвер по получении IRP пакета с кодом IRP_MJ_PNP. Такие IRP пакеты посылается PnP Менеджером, когда происходят события включения или выключения устройства, либо возникают вопросы по конфигурированию устройства.

Категория IRP_MJ_PNP пакетов включает запросы широкого спектра, которые детализируются суб-кодами IRP_MN_Xxx. Поскольку они пропускается через единственную рабочую процедуру, то ее обязанностью является вторичная диспетчеризация по этим суб-кодам, содержащимся в IRP пакете и описывающим специфические действия, осуществления которых ожидает PnP Менеджер.

Регистрация новой для WDM модели рабочей процедуры, которой будет поручено обрабатывать запросы IRP_MJ_PNP со всеми подтипами IRP_MN_Xxx, производится традиционным образом в процедуре DriverEntry:

pDriverObj-&#62MajorFunction[IRP_MJ_PNP] = MyPnP_Handler;

Пример программного кода для осуществления вторичной диспетчеризации на основе суб-кодов IRP_MN_Xxx приводится ниже.

NTSTATUS MyPnP_Handler ( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp ) { // Получить указатель на текущую ячейку стека IRP пакета PIO_STACK_LOCATION pIrpStackLocation = IoGetCurrentIrpStackLocation( pIrp );

switch (pIrpStackLocation -&#62MinorFunction) { case IRP_MN_START_DEVICE: . . . // Внимание. Все ветви оператора switch должны возвратить // результаты обработки . . . default: // если не поддерживается здесь, то передать запрос вниз: IoSkipCurrentIrpStackLocation(pIrp); return IoCallDriver(. . ., pIrp); } }

Первым параметром вызова IoCallDriver (см.


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