Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье описывается, как пример драйвера DCHU применяет принципы проектирования DCH. Его можно использовать в качестве модели для применения принципов проектирования DCH к собственному пакету драйвера.
Если вы хотите выполнить локальную копию репозитория, клонируйте из примеров windows-driver-samples.
Некоторые части примера могут использовать директивы и API, доступные только в определенных версиях Windows 10 и более поздних версий. Ознакомьтесь с разделом "Установка устройства и драйвера", чтобы узнать, какая версия ОС поддерживается в данной директиве.
Необходимые компоненты
Прежде чем прочитать этот раздел, необходимо ознакомиться с принципами проектирования DCH.
Обзор
В этом примере приведены примеры сценариев, в которых два партнера по оборудованию, Contoso (системный построитель или OEM) и Fabrikam (производитель устройств или IHV) совместно работают над созданием драйвера, соответствующего DCH для устройства в предстоящей системе Contoso. Устройство, на которое имеется вопрос, является комплектом обучения OSR USB FX2. В прошлом Fabrikam напишет устаревший пакет драйвера, настроенный для конкретной линии продуктов Contoso, а затем передать его изготовителю оборудования для обработки обслуживания. Этот процесс привел к значительным затратам на обслуживание, поэтому Fabrikam решил рефакторинг кода и создать пакет драйвера, совместимый с DCH.
Использование декларативных разделов и директив и правильной изоляции INF
Во-первых, Fabrikam проверяет список разделов INF и директив, недопустимых в пакетах драйверов, совместимых с DCH. В этом упражнении Fabrikam отмечает, что они используют многие из этих разделов и директив в пакете драйверов.
Данный драйвер INF регистрирует соинсталлятор, который применяет параметры и файлы, зависящие от платформы. Пакет драйвера больше, чем он должен быть, и труднее обслуживать драйвер, если ошибка влияет только на подмножество систем OEM, которые отправят драйвер. Большинство изменений OEM-специфичных связано с брендингом. Таким образом, Fabrikam необходимо обновлять пакет драйверов каждый раз, когда он добавляет OEM или когда дополнительная проблема влияет на подмножество систем OEM.
Fabrikam удаляет нерекларативные разделы и директивы и использует средство InfVerif для проверки того, что новый INF-файл пакета драйвера следует декларативному требованию INF.
Использование расширений INFs для компонента пакета драйвера
Затем Fabrikam отделяет настройки, относящиеся к партнерам OEM (например, Contoso) из базового пакета драйвера в расширение INF.
Следующий фрагмент кода, обновленный из [osrfx2_DCHU_extension.inx], указывает Extension класс и определяет Contoso как поставщика, так как он владеет пакетом драйвера расширения:
[Version]
...
Class = Extension
ClassGuid = {e2f84ce7-8efa-411c-aa69-97454ca4cb57}
Provider = Contoso
ExtensionId = {zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz} ; replace with your own GUID
...
В [osrfx2_DCHU_base.inx], Fabrikam указывает следующие записи:
[OsrFx2_AddReg]
HKR, OSR, "OperatingMode",, "Default" ; FLG_ADDREG_TYPE_SZ
HKR, OSR, "OperatingParams",, "None" ; FLG_ADDREG_TYPE_SZ
В [osrfx2_DCHU_extension.inx]Contoso переопределяет значение реестра OperatingParams , заданное базовой базой, и добавляет OperatingExceptions:
[OsrFx2Extension_AddReg]
HKR, OSR, "OperatingParams",, "-Extended"
HKR, OSR, "OperatingExceptions",, "x86"
Система всегда обрабатывает расширения после базового INF, но в неопределённом порядке. При обновлении базового INF-файла до более новой версии система по-прежнему применяет расширения после установки нового базового INF.
Установка службы из INF-файла
Fabrikam использует службу Win32 для управления индикаторами на плате OSR. Они рассматривают этот компонент как часть основных функциональных возможностей устройства, поэтому они включают его в состав базовой INF ([osrfx2_DCHU_base.inx]). Эту службу в режиме пользователя (usersvc) можно добавить и запустить декларативно, указав директиву AddService в INF-файле:
[OsrFx2_Install.NT]
CopyFiles = OsrFx2_CopyFiles
[OsrFx2_Install.NT.Services]
AddService = WUDFRd, 0x000001fa, WUDFRD_ServiceInstall ; Flag 0x2 sets this as the service for the device
AddService = osrfx2_DCHU_usersvc,, UserSvc_ServiceInstall
[UserSvc_ServiceInstall]
DisplayName = %UserSvcDisplayName%
ServiceType = 0x10 ; SERVICE_WIN32_OWN_PROCESS
StartType = 0x3 ; SERVICE_DEMAND_START
ErrorControl = 0x1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %13%\osrfx2_DCHU_usersvc.exe
AddTrigger = UserSvc_AddTrigger ; AddTrigger syntax is only available in Windows 10 Version 2004 and above
[UserSvc_AddTrigger]
TriggerType = 1 ; SERVICE_TRIGGER_TYPE_DEVICE_INTERFACE_ARRIVAL
Action = 1 ; SERVICE_TRIGGER_ACTION_SERVICE_START
SubType = %GUID_DEVINTERFACE_OSRFX2% ; Interface GUID
DataItem = 2, "USB\VID_0547&PID_1002" ; SERVICE_TRIGGER_DATA_TYPE_STRING
[OsrFx2_CopyFiles]
osrfx2_DCHU_base.dll
osrfx2_DCHU_filter.dll
osrfx2_DCHU_usersvc.exe
Вы также можете установить такую службу в компоненте или расширении INF в зависимости от сценария.
Использование компонента для установки устаревшего программного обеспечения из пакета драйвера
Fabrikam имеет исполняемый файл osrfx2_DCHU_componentsoftware.exe, который ранее был установлен с помощью соустановщика. Это устаревшее программное обеспечение отображает ключи реестра, заданные платой и необходимые OEM. Этот исполняемый файл является приложением с графическим интерфейсом пользователя, которое работает только в Windows для настольных версий. Чтобы установить его, Fabrikam создает отдельный пакет драйвера компонентов и добавляет его в расширение INF.
Следующий фрагмент кода из [osrfx2_DCHU_extension.inx] использует директиву AddComponent для создания виртуального дочернего устройства:
[OsrFx2Extension_Install.NT.Components]
AddComponent = osrfx2_DCHU_component,,OsrFx2Extension_ComponentInstall
[OsrFx2Extension_ComponentInstall]
ComponentIds=VID_045e&PID_94ab
Затем в компоненте INF [osrfx2_DCHU_component.inx], Fabrikam указывает директиву AddSoftware , чтобы установить необязательный исполняемый файл:
[OsrFx2Component_Install.NT.Software]
AddSoftware = osrfx2_DCHU_componentsoftware,, OsrFx2Component_SoftwareInstall
[OsrFx2Component_SoftwareInstall]
SoftwareType = 1
SoftwareBinary = osrfx2_DCHU_componentsoftware.exe
SoftwareArguments = <<DeviceInstanceId>>
SoftwareVersion = 1.0.0.0
[OsrFx2Component_CopyFiles]
osrfx2_DCHU_componentsoftware.exe
Исходный код для приложения Win32 включен в пример.
Пакет драйвера компонентов распространяется только на SKU для настольных компьютеров из-за настройки целевой аудитории на панели управления Центра разработки оборудования Windows. Дополнительные сведения см. в статье "Публикация драйвера в Обновл. Windows".
Разрешить взаимодействие с приложением поддержки оборудования
Fabrikam хотел бы предоставить приложение-компаньон на основе графического интерфейса в составе пакета драйвера Windows. Так как приложения-компаньоны на основе Win32 не могут быть частью пакета драйвера Windows, Fabrikam портирует свое приложение Win32 на универсальную платформу Windows (UWP) и связывает приложение с устройством.
В следующем фрагменте osrfx2_DCHU_base/device.c кода показано, как базовый пакет драйверов добавляет пользовательскую возможность в экземпляр интерфейса устройства:
WDF_DEVICE_INTERFACE_PROPERTY_DATA PropertyData = { 0 };
static const wchar_t customCapabilities[] = L"CompanyName.yourCustomCapabilityName_YourStorePubId\0";
WDF_DEVICE_INTERFACE_PROPERTY_DATA_INIT(&PropertyData,
&GUID_DEVINTERFACE_OSRUSBFX2,
&DEVPKEY_DeviceInterface_UnrestrictedAppCapabilities);
Status = WdfDeviceAssignInterfaceProperty(Device,
&PropertyData,
DEVPROP_TYPE_STRING_LIST,
sizeof(customCapabilities),
(PVOID)customCapabilities);
Новое приложение (не включено в пример) безопасно, и его можно легко обновить в Microsoft Store. Когда приложение UWP готово, компания Contoso использует DISM — обслуживание образов развертывания и управление ими для предварительной загрузки приложения на образах издания Windows Desktop.
Тесное связывание нескольких INF-файлов
В идеале должны быть строгие контракты управления версиями между базовыми, расширениями и компонентами. Существуют преимущества обслуживания при наличии этих трех пакетов, обслуживающихся независимо (сценарий с слабой связью), но существуют сценарии, в которых их необходимо упаковать в один пакет драйверов ("тесно связаны") из-за плохих контрактов управления версиями. Пример содержит примеры обоих сценариев:
DCHU_Sample\osrfx2_DCHU_extension_tight
Если расширение и компонент находятся в одном пакете драйвера ("тесно связаны"), расширение INF указывает директиву CopyINF , чтобы система копирует компонент INF в целевую систему. DCHU_Sample\osrfx2_DCHU_extension_tight\osrfx2_DCHU_extension\osrfx2_DCHU_extension.inx демонстрирует этот метод:
[OsrFx2Extension_Install.NT]
CopyInf=osrfx2_DCHU_component.inf
Эту директиву также можно использовать для координации установки INF-файлов на многофункционных устройствах. Дополнительные сведения см. в разделе "Копирование INF-файлов".
Примечание.
Хотя базовый драйвер может загрузить расширение (и нацелить базовый драйвер в метке доставки), невозможно опубликовать расширение, упакованое с другим драйвером в идентификатор оборудования расширения.
Запуск из хранилища драйверов
Чтобы упростить обновление драйвера, Fabrikam указывает хранилище драйверов в качестве места назначения для копирования файлов драйверов с помощью dirid 13 по возможности. Использование значения каталога назначения 13 может привести к улучшению стабильности во время процесса обновления драйвера. Ниже приведен пример из [osrfx2_DCHU_base.inx]:
[DestinationDirs]
OsrFx2_CopyFiles = 13 ; copy to driver store
Дополнительные сведения о том, как динамически находить и загружать файлы из хранилища драйверов, см. в статье "Запуск из магазина драйверов ".
Итоги
На следующей схеме показаны пакеты драйверов, созданные Fabrikam и Contoso для соответствующего драйвера DCH. В слабо связанном примере они делают три отдельные отправки на панель мониторинга Windows Hardware Dev Center: одна для базы, одна для расширения и одна для компонента. В тесно связанном примере они делают две отправки: базовую и расширение/компонент.
Компонент INF соответствует идентификатору оборудования компонента, а основные и расширения соответствуют идентификатору оборудования платы.