Sdílet prostřednictvím


Spustit z úložiště ovladačů

INF, který je spuštěn z úložiště ovladačů, znamená, že INF používá při instalaci k určení umístění pro soubory balíčku ovladačůDIRID 13.

V případě souboru „spustit z úložiště ovladačů“ načteného inf musí podadresář uvedený v položce SourceDisksFiles pro soubor v INF odpovídat podadresáři uvedenému v položce DestinationDirs pro soubor v INF.

Kromě toho nelze použít direktivu CopyFiles k přejmenování souboru, který se spouští z úložiště ovladačů. Tato omezení jsou nutná, aby instalace INF na zařízení nezpůsobí vytvoření nových souborů v adresáři Úložiště ovladačů.

Vzhledem k tomu, že položky SourceDisksFiles nemohou mít více položek se stejným názvem souboru a copyFiles nelze použít k přejmenování souboru, musí mít každý soubor spuštěný z úložiště ovladačů, na který odkazuje INF, jedinečný název souboru.

Balíčky ovladačů mají obecnou podporu pro spouštění z Úložiště ovladačů od Windows 10 1709. Některé zásobníky zařízení ale můžou obsahovat další omezení pro soubory, které potřebujete poskytnout, aby se začlenily do daného zásobníku. Mezi příklady patří tyto zásobníky zařízení, které nepodporovaly „spouštění z Úložiště ovladačů“ až do Windows 10 verze 1803.

Pokud poskytujete binární soubor, který se připojí ke konkrétnímu zásobníku zařízení, projděte si dokumentaci ke konkrétnímu zásobníku zařízení, ke kterému připojujete, a zkontrolujte, jestli podporuje poskytnutí úplné cesty k souboru binárnímu souboru a jestli existují nějaká omezení pro tuto úplnou cestu k souboru. Pokud podporuje poskytnutí úplné cesty k binárnímu souboru bez omezení na tuto cestu, měl by podporovat spuštění souboru z úložiště ovladačů.

Dynamické hledání a načítání souborů z úložiště ovladačů

Někdy je potřeba, aby komponenta načetla soubor, který je součástí balíčku ovladače, který používá příkaz spustit z úložiště ovladačů. Cesty k těmto souborům balíčků ovladačů by neměly být pevně zakódované, protože se mohou lišit mezi různými verzemi balíčku ovladače, různými verzemi operačního systému, různými edicemi operačního systému atd. Pokud nastane taková potřeba načíst soubory balíčku ovladačů, měly by být tyto soubory balíčku ovladačů zjištěny a načteny dynamicky pomocí některých paradigmat popsaných níže.

Vyhledání a načtení souborů ve stejném balíčku ovladače

Pokud soubor v balíčku ovladače potřebuje načíst jiný soubor ze stejného balíčku ovladače, jednou z možných možností dynamického zjišťování tohoto souboru je určit adresář, ze kterého je tento soubor spuštěný, a načíst druhý soubor vzhledem k tomuto adresáři.

Ovladač WDM nebo KMDF, který běží z Úložiště ovladačů ve Windows 10 verze 1803 a novější, který potřebuje přístup k jiným souborům z balíčku ovladače, by měl volat IoGetDriverDirectory s DriverDirectoryImage jako typ adresáře, aby získal cestu k adresáři, ze které byl ovladač načten. Alternativně pro ovladače, které potřebují podporovat verze operačního systému před Windows 10 verze 1803, použijte IoQueryFullDriverPath k vyhledání cesty ovladače, získání cesty k adresáři, ze kterého byl načten, a vyhledejte soubory relativní k této cestě. Pokud je ovladač režimu jádra ovladač KMDF, může použít WdfDriverWdmGetDriverObject k načtení objektu ovladače WDM pro předání do IoQueryFullDriverPath.

Binární soubory uživatelského režimu můžou použít GetModuleHandleExW a GetModuleFileNameW k určení, odkud byl binární soubor načten. Binární soubor ovladače UMDF může například udělat něco podobného:

bRet = GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
                         (PCWSTR)&DriverEntry,
                         &handleModule);
if (bRet) {
    charsWritten = GetModuleFileNameW(handleModule,
                                      path,
                                      pathLength);
    …

Vyhledání a načtení souborů v libovolném balíčku ovladače

V některých scénářích může balíček ovladače obsahovat soubor, který má být načten binárním souborem v jiném balíčku ovladače nebo komponentou uživatelského režimu. Tuto metodu lze také použít pro soubory ze stejného balíčku ovladače, pokud je to vhodnější než metoda popsaná výše pro načítání souborů ze stejného balíčku ovladače.

Tady je několik příkladů scénářů, které můžou zahrnovat načtení souborů z balíčku ovladače:

  • Knihovna DLL uživatelského režimu v rámci balíčku ovladačů poskytuje rozhraní pro komunikaci s ovladačem v balíčku ovladačů.

  • Balíček ovladače rozšíření obsahuje konfigurační soubor, který ovladač načítá v základním balíčku ovladače.

V těchto situacích by měl balíček ovladače nastavit nějaký stav v rozhraní zařízení nebo zařízení, které označuje cestu k souboru, který se má načíst.

Balíček ovladače obvykle používá k nastavení tohoto stavu addReg HKR. V tomto příkladu by se mělo předpokládat, že pro ExampleFile.dll, balíček ovladače má položku SourceDisksFiles bez podadresáře. Výsledkem je soubor v kořenovém adresáři balíčku ovladače. Mělo by se také předpokládat, že DestinationDirs pro direktivu CopyFiles určuje dirid 13.

Tady je příklad INF pro nastavení tohoto stavu zařízení:

[ExampleDDInstall.HW]
AddReg = Example_DDInstall.AddReg

[Example_DDInstall.AddReg]
HKR,,ExampleValue,,%13%\ExampleFile.dll

Příklad INF pro nastavení tohoto stavu rozhraní zařízení:

[ExampleDDInstall.Interfaces]
AddInterface = {<fill in an interface class GUID for an interface exposed by the device>},,Example_Add_Interface_Section

[Example_Add_Interface_Section]
AddReg = Example_Add_Interface_Section.AddReg

[Example_Add_Interface_Section.AddReg]
HKR,,ExampleValue,,%13%\ExampleFile.dll

Předchozí příklady používají prázdnou hodnotu příznaků, což vede k REG_SZ hodnotě registru. Výsledkem je, že %13% je převedena na plně kvalifikovanou cestu k souboru v uživatelském režimu. V mnoha případech je vhodnější mít cestu relativní k proměnné prostředí. Pokud se použije hodnota příznaku 0x20000, hodnota registru je typu REG_EXPAND_SZ a %13% se převede na cestu s příslušnými proměnnými prostředí, aby se abstrahovalo umístění cesty. Při načítání této hodnoty registru zavolejte ExpandEnvironmentStrings k rozbalení proměnných prostředí v cestě.

Pokud je potřeba, aby hodnotu četla komponenta režimu jádra, měla by být hodnota typu REG_SZ. Když komponenta režimu jádra přečte tuto hodnotu, měla by před zařazením do rozhraní API, jako je ZwOpenFile, připojit \??\.

Pokud chcete získat přístup k tomuto nastavení, když je součástí stavu zařízení, musí aplikace nejprve najít identitu zařízení. Kód uživatelského režimu může použít CM_Get_Device_ID_List_Size a CM_Get_Device_ID_List k získání seznamu zařízení filtrovaných podle potřeby. Tento seznam zařízení může obsahovat více zařízení, proto před načtením stavu ze zařízení vyhledejte příslušné zařízení. Voláním CM_Get_DevNode_Property můžete například načíst vlastnosti na zařízení, když hledáte zařízení odpovídající konkrétním kritériím.

Jakmile se najde správné zařízení, zavolejte CM_Open_DevNode_Key, abyste získali popisovač k umístění registru, kde byl uložen stav zařízení.

Kód režimu jádra by měl načíst PDO (objekt fyzického zařízení) odpovídající zařízení podle jeho stavu a zavolat IoOpenDeviceRegistryKey. Jedním z možných způsobů, jak může kód režimu jádra načíst PDO zařízení, by bylo rozpoznat povolené rozhraní poskytované zařízením a použitím IoGetDeviceObjectPointer načíst objekt zařízení.

Pro přístup k tomuto nastavení, když je to stav rozhraní zařízení, může kód uživatelského režimu volat CM_Get_Device_Interface_List_Size a CM_Get_Device_Interface_List.

Kromě toho lze CM_Register_Notification využít k tomu, aby se oznamovaly příchody a odchody rozhraní zařízení, což umožňuje, aby byl program upozorněn, když je rozhraní povoleno, a následně může zjistit jeho stav. Ve třídě rozhraní zařízení používané ve výše uvedených rozhraních API může existovat více rozhraní zařízení. Prozkoumejte tato rozhraní a zjistěte, které rozhraní je správné pro čtení nastavení.

Jakmile se najde správné rozhraní zařízení, zavolejte CM_Open_Device_Interface_Key.

Kód režimu jádra může načíst symbolický název odkazu pro rozhraní zařízení, ze kterého se má získat stav. Uděláte to tak, že zavoláte IoRegisterPlugPlayNotification a zaregistrujete oznámení rozhraní zařízení v příslušné třídě rozhraní zařízení. Případně můžete volat IoGetDeviceInterfaces , abyste získali seznam aktuálních rozhraní zařízení v systému. Ve třídě rozhraní zařízení používané ve výše uvedených rozhraních API může existovat více rozhraní zařízení. Prozkoumejte tato rozhraní a zjistěte, které rozhraní je správné, které by mělo mít nastavení ke čtení.

Jakmile se najde odpovídající symbolický název odkazu, zavolejte IoOpenDeviceInterfaceRegistryKey k načtení popisovače k umístění registru, kde byl uložen stav rozhraní zařízení.

Poznámka:

Použijte příznak CM_GETIDLIST_FILTER_PRESENT s CM_Get_Device_ID_List_Size a CM_Get_Device_ID_List nebo příznak CM_GET_DEVICE_INTERFACE_LIST_PRESENT s CM_Get_Device_Interface_List_Size a CM_Get_Device_Interface_List. Tím se zajistí, že hardware související se stavem, který obsahuje cestu k souboru, je k dispozici a připravený ke komunikaci.

Odebrání balíčku ovladače

Ve výchozím nastavení se balíček ovladače nedá ze systému odebrat, pokud je stále nainstalovaný na všech zařízeních. Některé možnosti odebrání balíčku ovladačů ze systému umožňují pokusit se o jeho „vynucené“ odebrání. Tento pokus se pokouší odstranit balíček ovladače, i když je tento balíček ovladače stále nainstalovaný na některých zařízeních v systému. Nucená odstranění nejsou povolena pro balíčky ovladačů, které obsahují soubory spouštějící se z úložiště ovladačů. Při odebrání balíčku ovladače ze systému se odebere jeho obsah úložiště ovladačů. Pokud existují nějaká zařízení, která jsou s tímto balíčkem ovladačů stále nainstalovaná, všechny soubory "spouštěné z úložiště ovladačů" v tomto balíčku ovladačů budou nyní pryč a chybějící soubory můžou způsobit selhání tohoto zařízení. Pokud chcete zabránit tomu, aby se zařízení dostalo do špatného stavu, není možné vynutit odebrání balíčků ovladačů, které obsahují všechny soubory "spustit z úložiště ovladačů". Je možné je odebrat, jenom když už nejsou nainstalované na žádném zařízení. Pro pomoc při odstraňování těchto balíčků ovladačů, DiUninstallDriver nebo pnputil /delete-driver <oem#.inf> /uninstall lze použít. Tyto metody odebrání nejprve aktualizují všechna zařízení, která používají odebraný balíček ovladačů, aby se s tímto balíčkem ovladačů už nenainstalovala, než se pokusíte balíček ovladače odebrat.

Vývoj balíčků ovladačů

Testování privátních binárních souborů

Pokud při vývoji balíčku ovladačů potřebujete nahradit konkrétní spustitelný soubor z balíčku ovladače soukromou verzí místo úplné opětovného sestavení a nahrazení balíčku ovladače v systému, doporučuje se použít ladicí program jádra spolu s příkazem .kdfiles . Vzhledem k tomu, že úplná cesta k souboru v úložišti ovladačů by neměla být pevně zakódovaná, doporučuje se, aby v mapování souborů .kdfiles byl název souboru OldDriver pouze přímý název souboru bez předchozích informací o cestě. Pro usnadnění (a dalších scénářů) by názvy souborů v balíčcích ovladačů měly být co nejvíce jedinečné, takže neodpovídá názvu souboru z nesouvisejícího balíčku ovladače v systému.

Přenesení INF pro spuštění z úložiště ovladačů

Pokud máte existující balíček ovladačů s INF, který se nepoužívá z úložiště ovladačů, a portujete ho pro spouštění z Úložiště ovladačů, následující příklady ukazují některé běžné použití souborů v INF a vzory aktualizace těchto souborů pro jejich spouštění z Úložiště ovladačů.

Stručná referenční příručka pro aktualizace cílového adresáře

Následující tabulka obsahuje stručný přehled pro vyhledání vhodných pokynů na základě aktuálního cílového adresáře DIRID , který balíček ovladače INF určuje pro soubor.

DIRID Podadresář Podrobnosti
13 Soubor už používá příkaz spustit z úložiště ovladačů. Není potřeba žádná další práce.
1 DIRID 1 by se neměl používat. Neexistuje žádná záruka, že bude zdrojový adresář dostupný, když je potřeba vyřešit odkaz na soubor. Místo toho, pokud součásti balíčku ovladačů závisí na konkrétních souborech, zahrňte tyto soubory do balíčku ovladače a spusťte je z úložiště ovladačů.
10 Firmware (vestavěný software) Informace o tom, jak použít DIRID 13 s balíčkem ovladače pro aktualizaci firmwaru k tomu, aby bylo možné provést akci 'spustit z Úložiště ovladačů', naleznete v části Vytvoření balíčku ovladače aktualizace.
10 Viz Další soubory.
11 Viz Další soubory.
12 UMDF Viz binární soubor ovladače UMDF.
12 Většina souborů s cílem DIRID 12 představuje binární soubory služby ovladače. Viz binární soubor služby.
16422, 16426, 16427, 16428 Většina souborů s cílem těchto identifikátorů DIRID představuje instalaci aplikace. Místo toho zadejte aplikaci univerzální platformy Windows (UPW) a nainstalujte ji pomocí direktivy AddSoftware z oddílu DDInstall.Software balíčku ovladačů INF. Podrobnosti najdete v tématu Spárování ovladače s aplikací pro Univerzální platformu Windows (UPW).

Služební binární soubor

Pokud inf přidá službu a binární soubor se nespustí z úložiště ovladačů, může inf vypadat takto:

[DestinationDirs]
 ; Copy the file to %windir%\system32\drivers
 Example_CopyFiles = 12

[ExampleDDInstall]
CopyFiles = Example_CopyFiles

[Example_CopyFiles]
ExampleBinary.sys

[ExampleDDInstall.Services]
AddService = ExampleService,0x2,Example_Service_Inst

[Example_Service_Inst]
DisplayName   = %SvcDesc%
ServiceType   = %SERVICE_KERNEL_DRIVER%
StartType     = %SERVICE_DEMAND_START%
ErrorControl  = %SERVICE_ERROR_NORMAL%
; Point at the file in %windir%\system32\drivers
ServiceBinary = %12%\ExampleBinary.sys

Chcete-li přesunout tento soubor ke spuštění z úložiště ovladačů, bude nutné aktualizovat položku DestinationDirs, do které se soubor zkopíruje, a aktualizovat direktivu ServiceBinary odkazující na umístění tohoto souboru.

[DestinationDirs]
; Update the destination to DIRID 13
Example_CopyFiles = 13

[ExampleDDInstall]
CopyFiles = Example_CopyFiles

[Example_CopyFiles]
ExampleBinary.sys

[ExampleDDInstall.Services]
AddService = ExampleService,0x2,Example_Service_Inst

[Example_Service_Inst]
DisplayName   = %SvcDesc%
ServiceType   = %SERVICE_KERNEL_DRIVER%
StartType     = %SERVICE_DEMAND_START%
ErrorControl  = %SERVICE_ERROR_NORMAL%
; Point at the run from Driver Store file using DIRID 13
ServiceBinary = %13%\ExampleBinary.sys

Binární soubor ovladače UMDF

Pokud inf přidá ovladač UMDF a binární soubor se nespustí z úložiště ovladačů, může inf vypadat takto:

[DestinationDirs]
; Copy the file to %windir%\system32\drivers\UMDF
Example_CopyFiles = 12, UMDF

[ExampleDDInstall]
CopyFiles = Example_CopyFiles

[Example_CopyFiles]
ExampleUmdfDriver.dll

[ExampleDDInstall.Wdf]
UmdfService = ExampleUmdfDriver,Example_UMDF_Inst
...

[Example_UMDF_Inst]
; Point at the file in %windir%\system32\drivers\UMDF
ServiceBinary = %12%\UMDF\ExampleUmdfDriver.dll
...

Chcete-li přesunout tento soubor ke spuštění z úložiště ovladačů, bude nutné aktualizovat položku DestinationDirs, do které se soubor zkopíruje, a aktualizovat direktivu ServiceBinary odkazující na umístění tohoto souboru.

[DestinationDirs]
; Update the destination to DIRID 13
Example_CopyFiles = 13

[ExampleDDInstall]
CopyFiles = Example_CopyFiles

[Example_CopyFiles]
ExampleUmdfDriver.dll

[ExampleDDInstall.Wdf]
UmdfService = ExampleUmdfDriver,Example_UMDF_Inst
...

[Example_UMDF_Inst]
; Point at the run from Driver Store file using DIRID 13
ServiceBinary = %13%\ExampleUmdfDriver.dll
...

Další soubory

Pokud inf přidá soubor, který může být načten jinými komponentami a nespustí se z Úložiště ovladačů, pak inf může vypadat takto. V tomto příkladu se do stavu registru zařízení zapíše jenom název souboru. Komponenty, které čtou tuto hodnotu registru k určení, který soubor načíst, závisí buď na tom, že soubor je v %windir%\system32, nebo na tom, že pořadí hledání LoadLibrary je schopné soubor najít.

[DestinationDirs]
; Copy the file to %windir%\system32
Example_CopyFiles = 11

[ExampleDDInstall]
CopyFiles=Example_CopyFiles
AddReg=Example_AddReg

[Example_CopyFiles]
ExampleFile.dll

[Example_AddReg]
HKR,,FileLocation,,"ExampleFile.dll"

Pokud chcete přesunout tento soubor, který se má spustit z úložiště ovladačů, musíte aktualizovat položku DestinationDirs, do které se soubor zkopíruje, a aktualizovat umístění uložené ve stavu zařízení. To vyžaduje komponenty, které čtou tuto hodnotu registru, aby mohly tuto hodnotu registru zpracovat jako úplnou cestu k souboru místo cesty k souboru relativní k %windir%\system32.

[DestinationDirs]
Example_CopyFiles = 13 ; update the destination to DIRID 13

[ExampleDDInstall]
CopyFiles=Example_CopyFiles
AddReg=Example_AddReg

[Example_CopyFiles]
ExampleFile.dll

[Example_AddReg]
; Point at the run from Driver Store file using DIRID 13
HKR,,FileLocation,,"%13%\ExampleFile.dll"