Exemplo de pacote de driver compatível com DCH
Este artigo descreve como o exemplo de driver DCHU aplica os princípios de design do DCH. Você pode usá-lo como um modelo para aplicar os princípios de design do DCH ao seu próprio pacote de driver.
Se você quiser uma cópia local do repositório de exemplo, clone de Windows-driver-samples.
Algumas partes do exemplo podem usar diretivas e APIs que só estão disponíveis em determinadas versões do Windows 10 e superiores. Consulte Instalação de Dispositivo e Driver para ver em qual versão do sistema operacional uma determinada diretiva é suportada.
Pré-requisitos
Antes de ler esta seção, você deve se familiarizar com os Princípios de Design do DCH.
Visão geral
O exemplo fornece cenários de exemplo em que dois parceiros de hardware, Contoso (um construtor de sistemas ou OEM) e Fabrikam (um fabricante de dispositivos ou IHV) estão trabalhando juntos para criar um driver compatível com DCH para um dispositivo no próximo sistema da Contoso. O dispositivo em questão é um kit de aprendizagem OSR USB FX2. No passado, a Fabrikam escrevia um pacote de driver herdado que era personalizado para uma linha de produtos específica da Contoso e, em seguida, entregava ao OEM para que ele cuidasse da manutenção. Isso resultava em uma sobrecarga de manutenção significativa, então a Fabrikam decidiu refatorar o código e criar um pacote de driver compatível com DCH.
Usar seções/diretivas declarativas e isolar corretamente o INF
Primeiro, a Fabrikam examina a lista de seções e diretivas INF que são inválidas em pacotes de driver compatíveis com DCH. Durante este exercício, a Fabrikam percebe que está usando muitas dessas seções e diretivas em seu pacote de driver.
O driver INF registra um coinstalador que aplica configurações e arquivos dependentes da plataforma. Isso significa que o pacote de driver é maior do que deveria e é mais difícil fazer a manutenção do driver quando um bug afeta apenas um subconjunto dos sistemas do OEM que enviam o driver. Além disso, a maioria das modificações específicas do OEM está relacionada à identidade visual, portanto, a Fabrikam precisa atualizar o pacote de driver sempre que um OEM é adicionado ou quando um pequeno problema afeta um subconjunto de sistemas do OEM.
A Fabrikam remove as seções e diretivas não declarativas e usa a ferramenta InfVerif para verificar se o arquivo INF do novo pacote de driver segue o requisito INF declarativo.
Usar extensões INF para dividir em componentes um pacote de driver
Em seguida, a Fabrikam separa as personalizações específicas para parceiros OEM (como a Contoso) do pacote de driver base em uma extensão INF.
O snippet a seguir, atualizado de [osrfx2_DCHU_extension.inx
], especifica a classe Extension
e identifica a Contoso como o provedor, pois eles serão proprietários do pacote de driver de extensão:
[Version]
...
Class = Extension
ClassGuid = {e2f84ce7-8efa-411c-aa69-97454ca4cb57}
Provider = Contoso
ExtensionId = {zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz} ; replace with your own GUID
...
Em [osrfx2_DCHU_base.inx
], a Fabrikam especifica as seguintes entradas:
[OsrFx2_AddReg]
HKR, OSR, "OperatingMode",, "Default" ; FLG_ADDREG_TYPE_SZ
HKR, OSR, "OperatingParams",, "None" ; FLG_ADDREG_TYPE_SZ
Em [osrfx2_DCHU_extension.inx
], a Contoso substitui o valor do Registro OperatingParams definido pela base e adiciona OperatingExceptions:
[OsrFx2Extension_AddReg]
HKR, OSR, "OperatingParams",, "-Extended"
HKR, OSR, "OperatingExceptions",, "x86"
As extensões são sempre processadas após o INF base, mas sem ordem definida. Se um INF base for atualizado para uma versão mais recente, as extensões ainda serão aplicadas novamente depois que o novo INF base for instalado.
Instalar um serviço a partir de um arquivo INF
A Fabrikam usa um serviço Win32 para controlar os LEDs na placa OSR. Eles veem esse componente como parte da funcionalidade principal do dispositivo e o incluem como parte de seu INF base ([osrfx2_DCHU_base.inx
]). Esse serviço de modo de usuário (usersvc) pode ser adicionado e iniciado declarativamente especificando a diretiva AddService no arquivo 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
Esse serviço também pode ser instalado em um componente ou extensão INF, dependendo do cenário.
Usar um componente para instalar software herdado de um pacote de driver
A Fabrikam tem um arquivo osrfx2_DCHU_componentsoftware.exe
executável que instalaram anteriormente usando um coinstalador. Esse software herdado exibe as chaves do registro definidas pela placa e é exigido pelo OEM. Este é um executável baseado em GUI que só é executado no Windows para edições de desktop. Para instalá-lo, a Fabrikam cria um pacote de driver de componente separado e o adiciona em sua extensão INF.
O seguinte snippet de [osrfx2_DCHU_extension.inx
] usa a diretiva AddComponent para criar um dispositivo filho virtual:
[OsrFx2Extension_Install.NT.Components]
AddComponent = osrfx2_DCHU_component,,OsrFx2Extension_ComponentInstall
[OsrFx2Extension_ComponentInstall]
ComponentIds=VID_045e&PID_94ab
Em seguida, no componente INF [osrfx2_DCHU_component.inx
], a Fabrikam especifica a diretiva AddSoftware para instalar o executável opcional:
[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
O código-fonte do aplicativo Win32 está incluído no exemplo.
O pacote de driver de componente só é distribuído em SKUs da Desktop devido ao direcionamento definido no painel do Centro de Desenvolvimento para Hardware do Windows. Para obter mais informações, consulte Publicar um driver no Windows Update.
Permitir a comunicação com um aplicativo de suporte de hardware
A Fabrikam gostaria de fornecer um aplicativo complementar baseado em GUI como parte do pacote de driver do Windows. Como os aplicativos complementares baseados em Win32 não podem fazer parte de um pacote de driver do Windows, eles portam seu aplicativo Win32 para a UWP (Plataforma Universal do Windows) e emparelham o aplicativo com o dispositivo.
O snippet a seguir de osrfx2_DCHU_base/device.c
mostra como o pacote de driver base adiciona uma funcionalidade personalizada à instância da interface do dispositivo:
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);
O novo aplicativo (não incluído no exemplo) é seguro e pode ser atualizado facilmente na Microsoft Store. Com o aplicativo UWP pronto, a Contoso usa o DISM – Gerenciamento e Manutenção de Imagens de Implantação para pré-carregar o aplicativo em imagens da edição Windows Desktop.
Acoplamento rígido de vários arquivos INF
Idealmente, deve haver contratos de controle de versão fortes entre base, extensões e componentes. Há vantagens de manutenção em ter esses três pacotes atendidos de forma independente (o cenário "fracamente acoplado"), mas há cenários em que eles precisam ser agrupados em um único pacote de driver ("fortemente acoplado") devido a contratos de controle de versão ruins. O exemplo inclui exemplos de ambos os cenários:
DCHU_Sample\osrfx2_DCHU_extension_tight
Quando a extensão e o componente estão no mesmo pacote de driver ("fortemente acoplados"), a extensão INF especifica a diretiva CopyINF para fazer com que o INF do componente seja copiado para o sistema de destino. Isso é demonstrado em DCHU_Sample\osrfx2_DCHU_extension_tight\osrfx2_DCHU_extension\osrfx2_DCHU_extension.inx:
[OsrFx2Extension_Install.NT]
CopyInf=osrfx2_DCHU_component.inf
Essa diretiva também pode ser usada para coordenar a instalação de arquivos INF em dispositivos multifuncionais. Para obter mais informações, consulte Copiar arquivos INF.
Observação
Embora um driver base possa carregar uma extensão (e direcionar o driver base na etiqueta de remessa), uma extensão empacotada com outro driver não pode ser publicada no ID de hardware da extensão.
Executar do Repositório de Drivers
Para facilitar a atualização do driver, a Fabrikam especifica o Repositório de Drivers como o destino para copiar os arquivos de driver usando dirid 13 sempre que possível. O uso de um valor de diretório de destino igual a 13 pode resultar em estabilidade aprimorada durante o processo de atualização do driver. Este é um exemplo de [osrfx2_DCHU_base.inx
]:
[DestinationDirs]
OsrFx2_CopyFiles = 13 ; copy to Driver Store
Consulte a página Executar do Repositório de Drivers para obter mais detalhes sobre como localizar e carregar dinamicamente arquivos do Repositório de Drivers.
Resumo
O diagrama a seguir mostra os pacotes de driver que a Fabrikam e a Contoso criaram para o driver compatível com DCH. No exemplo de acoplamento fraco, eles farão três envios separados no painel do Centro de Desenvolvimento para Hardware do Windows: um para a base, um para a extensão e um para o componente. No exemplo de acoplamento forte, eles farão dois envios: base e extensão/componente.
O componente INF corresponderá ao ID de hardware do componente, enquanto a base e as extensões corresponderão ao ID de hardware da placa.
Confira também
Introdução ao desenvolvimento de drivers do Windows
Usar um arquivo INF de extensão
"loosely coupled" osrfx2_DCHU_component.inx
"loosely coupled" osrfx2_DCHU_extension.inx