драйвером шины по заданию диспетчера PnP, когда драйвер шины, перечисляя устройства на своей шине, сообщает о наличии какого-либо устройства. PDO представляет физический интерфейс устройства.
(o) Необязательные группы объектов-фильтров (filter device objects, FiDO) Одна группа таких объектов размещается между PDO и FDO (создается драйверами фильтров шин), вторая – между FDO и первой группой FiDO (создается низкоуровневыми драйверами фильтров), третья – над FDO (создается высокоуровневыми драйверами фильтров).
(o) Объект «функциональное устройство» (functional device object, FDO) Создается функциональным драйвером, который загружается диспетчером PnP для управления обнаруженным устройством. FDO представляет логический интерфейс устройства. Функциональный драйвер может выступать и в роли драйвера шины, если к устройству, представленному FDO, подключены другие устройства. Этот драйвер часто создает интерфейс к PDO, соответствующему данному FDO, что позволяет приложениям и другим драйверам открывать устройство и взаимодействовать с ним. Иногда функциональные драйверы подразделяются на драйвер класса, порт-драйвер и минипорт-драйвер, совместно управляющие вводом-выводом для FDO.
Узлы устройств полагаются на функциональность диспетчера ввода-вывода; поток IRP идет по узлу устройств сверху вниз. Решение об окончании обработки IRP может быть принято на любом уровне узла устройств. Например, функциональный драйвер может обработать запрос на чтение, не пересылая IRP драйверу шины. IRP проходит весь путь сверху вниз и далее к узлу устройств, содержащему драйвер шины, только если функциональному драйверу нужна помощь драйвера шины.
До сих пор мы так и не ответили на два важных вопроса: как диспетчер PnP определяет, какой функциональный драйвер нужно загрузить для данного устройства и как драйверы фильтров регистрируют свое присутствие, чтобы их можно было загружать при создании узла устройств?
Ответ на оба вопроса надо искать в реестре. Перечисляя устройства, драйвер шины сообщает диспетчеру PnP идентификаторы обнаруженных устройств. Эти идентификаторы специфичны для конкретной шины. Например, для шины USB такой идентификатор состоит из идентификатора изготовителя (vendor ID, VID) и идентификатора продукта (product ID, PID), назначенного устройству изготовителем (подробнее о форматах идентификаторов устройств см. в DDK). B совокупности эти идентификаторы образуют то, что в терминологии спецификации Plug and Play называется
ЭКСПЕРИМЕНТ: просмотр детальных сведений об узлах устройств в диспетчере устройств
По умолчанию апплет Device Manager (Диспетчер устройств), доступный с вкладки Hardware (Оборудование) окна свойств системы, не показывает детальных сведений об узле устройств. Однако в Windows XP и Windows Server 2003 вы можете активизировать вкладку Details (Сведения), создав переменную окружения devmgr_show_details и присвоив ей значение 1. Ha этой вкладке отображается целый набор полей, в том числе идентификатор экземпляра устройства для узла, имя сервиса, фильтры и возможности в управлении электропитанием.
Самый простой способ запустить диспетчер устройств с вкладкой Details – открыть окно командной строки и ввести:
C:›set devmgr_show_details=1 C:›devmgmt.msc
Ha следующем экранном снимке показано, как выглядит содержимое этой вкладки для одного из устройств.
Параметр ClassGUID позволяет диспетчеру PnP найти раздел класса устройства в HKLMSYSTEM CurrentControlSetControlClass. Раздел класса клавиатур показан на рис. 9-29. Раздел, созданный для устройства в процессе перечисления, и раздел класса предоставляют диспетчеру PnP всю информацию, на основе которой он загружает драйверы, необходимые для узла данного устройства. Загрузка драйверов происходит в следующем порядке.
1. Любые низкоуровневые драйверы фильтров, указанные в параметре LowerFilters раздела, созданного для устройства в процессе перечисления.
2. Любые низкоуровневые драйверы фильтров, указанные в параметре Lo-werFilters раздела класса данного устройства.
3. Функциональный драйвер, заданный в параметре Service раздела, созданного для устройства в процессе перечисления. Значение этого параметра интерпретируется как имя раздела драйвера в HKLM SYSTEMCurrentControlSetServices.
4. Любые высокоуровневые драйверы фильтров, указанные в параметре UpperFilters раздела, созданного для устройства в процессе перечисления.
5. Любые высокоуровневые драйверы фильтров, указанные в параметре UpperFilters раздела класса данного устройства.
Ссылки на драйверы всегда содержат имена их разделов в HKLMSYSTEM CurrentControlSet Services.
Устройство «клавиатура», представленное на рис. 9-28 и 9-29, не имеет низкоуровневых драйверов фильтров. Его функциональный драйвер – i8042prt; в разделе класса клавиатур указано два высокоуровневых драйвера фильтров – kbdclass и ctrl2cap.
Если диспетчер PnP встречает устройство, драйвер которого не установлен, он обращается к диспетчеру PnP пользовательского режима, и тот устанавливает нужный драйвер. Если устройство обнаруживается при загрузке системы, для него определяется узел устройств, но загрузка драйверов откладывается до запуска диспетчера PnP пользовательского режима (он реализован в WindowsSystem32Umpnpmgr.dll и выполняется как сервис в процессе Services.exe).
Компоненты, участвующие в установке драйвера, показаны на рис. 9-30. Серые блоки на этом рисунке соответствуют компонентам, обычно предоставляемым системой, а остальные блоки – компонентам, предоставляемым установочными файлами. Сначала драйвер шины информирует диспетчер PnP о перечисленном устройстве, сообщая его DIID (1). Диспетчер PnP проверяет, определен ли в реестре подходящий функциональный драйвер. Если нет, он уведомляет диспетчер PnP пользовательского режима