Dela via


Exempel på DCH-kompatibelt drivrutinspaket

Den här artikeln beskriver hur DCHU-drivrutinsexemplet tillämpar DCH-designprinciper. Du kan använda den som modell för att tillämpa DCH-designprinciper på ditt eget drivrutinspaket.

Om du vill ha en lokal kopia av exempellagringsplatsen klonar du från Windows-driver-samples.

Vissa delar av exemplet kan använda direktiv och API:er som endast är tillgängliga i vissa versioner av Windows 10 och senare. Se Installation av enhet och drivrutin för att se vilken operativsystemversion ett visst direktiv stöds på.

Förutsättningar

Innan du läser det här avsnittet bör du bekanta dig med DCH-designprinciperna.

Översikt

Exemplet innehåller exempelscenarier där två maskinvarupartners, Contoso (en systembyggare eller OEM) och Fabrikam (en enhetstillverkare eller IHV) arbetar tillsammans för att skapa en drivrutin som är DCH-kompatibel för en enhet i Contosos kommande system. Enheten i fråga är ett OSR USB FX2-utbildningspaket. Tidigare skulle Fabrikam skriva ett äldre drivrutinspaket som har anpassats till en specifik Contoso-produktlinje och sedan överlämna det till OEM-tillverkaren för att hantera service. Den här processen resulterade i betydande underhållskostnader, så Fabrikam bestämde sig för att omstrukturera koden och skapa ett DCH-kompatibelt drivrutinspaket i stället.

Använd deklarativa avsnitt/direktiv och isolera INF korrekt

Först granskar Fabrikam listan över INF-avsnitt och -direktiv som är ogiltiga i DCH-kompatibla drivrutinspaket. Under den här övningen märker Fabrikam att de använder många av de här avsnitten och direktiven i sitt drivrutinspaket.

Deras inf-drivrutin registrerar en coinstaller som tillämpar plattformsberoende inställningar och filer. Drivrutinspaketet är större än det ska vara, och det är svårare att betjäna drivrutinen när ett fel endast påverkar en delmängd av OEM-systemen som skickar drivrutinen. De flesta OEM-specifika ändringar är relaterade till varumärkesanpassning. Fabrikam måste därför uppdatera drivrutinspaketet varje gång de lägger till en OEM-tillverkare eller när ett mindre problem påverkar en delmängd av OEM-system.

Fabrikam tar bort de icke-deklarerande avsnitten och direktiven och använder InfVerif-verktyget för att kontrollera att det nya drivrutinspaketets INF-fil följer deklarativa INF-kravet.

Använda tilläggs-INF:er för att komponentisera ett drivrutinspaket

Fabrikam separerar sedan anpassningar som är specifika för OEM-partner (till exempel Contoso) från basdrivrutinspaketet till ett tilläggs-INF.

Följande kodfragment, uppdaterat från [osrfx2_DCHU_extension.inx], anger Extension klassen och identifierar Contoso som provider eftersom de äger tilläggsdrivrutinspaketet:

[Version]
...
Class       = Extension
ClassGuid   = {e2f84ce7-8efa-411c-aa69-97454ca4cb57}
Provider    = Contoso
ExtensionId = {zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz} ; replace with your own GUID
...

I [osrfx2_DCHU_base.inx] specificerar Fabrikam följande poster:

[OsrFx2_AddReg]
HKR, OSR, "OperatingMode",, "Default" ; FLG_ADDREG_TYPE_SZ
HKR, OSR, "OperatingParams",, "None" ; FLG_ADDREG_TYPE_SZ

I [osrfx2_DCHU_extension.inx] åsidosätter Contoso registervärdet OperatingParams som angetts av basen och lägger till OperatingExceptions:

[OsrFx2Extension_AddReg]
HKR, OSR, "OperatingParams",, "-Extended"
HKR, OSR, "OperatingExceptions",, "x86"

Systemet bearbetar alltid tillägg efter bas-INF men i ingen bestämd ordning. Om du uppdaterar en bas-INF till en nyare version, gör systemet fortfarande om tilläggen när den har installerat den nya bas-INF:n.

Installera en tjänst från en INF-fil

Fabrikam använder en Win32-tjänst för att styra lysdioderna på OSR-tavlan. De ser den här komponenten som en del av enhetens kärnfunktioner, så de inkluderar den som en del av sin bas-INF ([osrfx2_DCHU_base.inx]). Den här användarlägestjänsten (usersvc) kan läggas till och startas deklarativt genom att ange AddService-direktivet i INF-filen:

[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

Du kan också installera en sådan tjänst i en komponent eller tilläggs-INF, beroende på scenariot.

Använda en komponent för att installera äldre programvara från ett drivrutinspaket

Fabrikam har en körbar fil osrfx2_DCHU_componentsoftware.exe som de tidigare installerade med hjälp av en coinstaller. Den här äldre programvaran visar registernycklarna som angetts av brädet och som krävs av OEM-tillverkaren. Den här körbara filen är en GUI-baserad app som endast körs i Windows för skrivbordsversioner. För att installera det skapar Fabrikam ett separat komponentdrivrutinspaket och lägger till det i tillägget INF.

Följande kodfragment från [osrfx2_DCHU_extension.inx] använder AddComponent-direktivet för att skapa en virtuell underordnad enhet:

[OsrFx2Extension_Install.NT.Components]
AddComponent = osrfx2_DCHU_component,,OsrFx2Extension_ComponentInstall


[OsrFx2Extension_ComponentInstall]
ComponentIds=VID_045e&PID_94ab

I komponenten INF [osrfx2_DCHU_component.inx] anger Fabrikam sedan AddSoftware-direktivet för att installera den valfria körbara filen:

[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

Källkoden för Win32-appen ingår i exemplet.

Komponentdrivrutinspaketet distribueras endast på skrivbords-SKU:er på grund av måluppsättningen i Windows Hardware Dev Center-instrumentpanelen. Mer information finns i Publicera en drivrutin till Windows Update.

Tillåt kommunikation med en maskinvarusupportapp

Fabrikam vill tillhandahålla en GUI-baserad kompletterande app som en del av Windows-drivrutinspaketet. Eftersom Win32-baserade kompletterande program inte kan ingå i ett Windows-drivrutinspaket portar Fabrikam sin Win32-app till UWP (Universal Windows Platform) och parkopplar appen med enheten.

Följande kodfragment från osrfx2_DCHU_base/device.c visar hur basdrivrutinspaketet lägger till en anpassad funktion i enhetsgränssnittsinstansen:

    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);

Den nya appen (ingår inte i exemplet) är säker och du kan enkelt uppdatera den i Microsoft Store. När UWP-programmet är klart använder Contoso DISM – Service och hantering av distributionsavbildningar för att förinstallera programmet på Windows Desktop-avbildningar.

Nära koppling av flera INF-filer

Helst bör det finnas starka versionskontrakt mellan bas-, tilläggs- och komponenter. Det finns servicefördelar med att få dessa tre paket tjänsthanterade oberoende (det löst kopplade scenariot), men det finns scenarier där de måste paketeras i ett enda drivrutinspaket ("tätt kopplat") på grund av dåliga versionskontrakt. Exemplet innehåller exempel på båda scenarierna:

[OsrFx2Extension_Install.NT]
CopyInf=osrfx2_DCHU_component.inf

Du kan också använda det här direktivet för att samordna installationen av INF-filer i multifunktionsenheter. Mer information finns i Kopiera INF-filer.

Anmärkning

Även om en basdrivrutin kan nyttolasta ett tillägg (och rikta in sig på basdrivrutinen i fraktetiketten), kan du inte publicera ett tillägg som paketeras med en annan drivrutin till tilläggets maskinvaru-ID.

Kör från drivrutinsarkivet

För att göra det enklare att uppdatera drivrutinen anger Fabrikam drivrutinsarkivet som mål för att kopiera drivrutinsfilerna med dirid 13 där det är möjligt. Om du använder målkatalogvärdet 13 kan det leda till förbättrad stabilitet under drivrutinsuppdateringsprocessen. Här är ett exempel från [osrfx2_DCHU_base.inx]:

[DestinationDirs]
OsrFx2_CopyFiles = 13 ; copy to driver store

Mer information om hur du dynamiskt hittar och läser in filer från drivrutinsarkivet finns i artikeln Kör från drivrutinsarkiv .

Sammanfattning

Följande diagram visar drivrutinspaketen som Fabrikam och Contoso skapade för sin DCH-kompatibla drivrutin. I det löst kopplade exemplet gör de tre separata inlämningar på Windows Hardware Dev Center-instrumentpanelen: en för basen, en för tillägget och en för komponenten. I det nära kopplade exemplet gör de två inlämningar: bas och tillägg/komponent.

Skärmbild av ett diagram som visar relationerna mellan tilläggs-, bas- och komponentdrivrutinspaket i både löst kopplade och nära kopplade scenarier.

Komponentens INF matchar komponentens maskinvaru-ID, medan bas- och tilläggen matchar brädets maskinvaru-ID.

Se även