Treiberpaketisolation

Die Isolierung von Treiberpaketen ist eine Voraussetzung für Windows-Treiber, die dafür sorgt, dass Treiberpakete resilienter gegenüber externen Änderungen, einfacher zu aktualisieren und unkomplizierter zu installieren sind.

Hinweis

Auch wenn die Isolierung von Treiberpaketen für Windows-Treiber erforderlich ist, profitieren Windows-Desktop-Treiber dennoch von ihr, da sie die Resilienz und die Wartungsfähigkeit verbessert.

Die folgende Tabelle zeigt in der linken Spalte einige Beispiele für veraltete Pakete, die für Windows-Treiber nicht mehr zugelassen sind, und in der rechten Spalte das erforderliche Verhalten für Windows-Treiber.

Nicht-isolierter Treiber Isolierter Treiber
INF copies files to %windir%\System32 or %windir%\System32\drivers Treiberdateien werden aus dem Treiber-Store ausgeführt
Interaktion mit Gerätestacks/Treibern über fest programmierte Pfade Interagiert mit Gerätestacks/Treibern über vom System bereitgestellte Funktionen oder Geräteschnittstellen
Fest programmierte Pfade zu globalen Registrierungsorten Verwendet HKR und vom System bereitgestellte Funktionen zur relativen Ermittlung von Registrierungs- und Dateistatus
Runtime schreibt Dateien an einen beliebigen Ort Dateien werden relativ zu den vom Betriebssystem bereitgestellten Speicherorten geschrieben

Hilfe bei der Feststellung, ob Ihr Treiberpaket die Anforderungen an die Isolierung von Treiberpaketen erfüllt, finden Sie unter Validierung von Windows-Treibern. Beispiele dafür, wie Sie eine INF aktualisieren können, um die Anforderungen an die Isolierung des Treiberpakets zu erfüllen, finden Sie unter Portieren einer INF, um die Isolierung des Treiberpakets zu gewährleisten.

Ausführen aus dem Treiber-Store

Alle isolierten Treiberpakete lassen ihre Treiberpaketdateien im Treiber-Store. Das bedeutet, dass sie DIRID 13 in ihrer INF angeben, um den Speicherort für die Dateien des Treiberpakets bei der Installation festzulegen. Weitere Informationen darüber, wie Sie dies in einem Treiberpaket verwenden, finden Sie unter Aus dem Store ausführen.

Lesen und Schreiben des Status

Hinweis

Wenn Ihre Komponente ein Gerät oder eine Geräteschnittstelle Eigenschaften verwendet, um den Status zu speichern, verwenden Sie weiterhin diese Methode und die entsprechenden APIs des Betriebssystems, um den Status zu speichern und darauf zuzugreifen. Die folgende Anleitung für Registrierungs- und Dateistatus gilt für andere Status, die von einer Komponente gespeichert werden müssen.

Der Zugriff auf verschiedene Registrierungs- und Dateistatus sollte durch den Aufruf von Funktionen erfolgen, die dem Aufrufer den Speicherort des Status mitteilen. Der Status wird dann relativ zu diesem Speicherort gelesen/geschrieben. Verwenden Sie keine fest kodierten absoluten Registrierungs- und Dateipfade.

Dieser Abschnitt enthält die folgenden Unterabschnitte:

Registrierungsstatus

Dieser Abschnitt enthält die folgenden Unterabschnitte:

Registrierungsstatus von PnP-Geräten

Isolierte Treiberpakete und Komponenten für den Benutzermodus verwenden in der Regel einen von zwei Orten, um den Status des Geräts in der Registrierung zu speichern. Dies sind der Hardwareschlüssel (Geräteschlüssel) für das Gerät und der Softwareschlüssel (Treiberschlüssel) für das Gerät. Der Hardwareschlüssel ist in der Regel für Einstellungen vorgesehen, die sich darauf beziehen, wie eine einzelne Instanz des Geräts mit der Hardware interagiert. Zum Beispiel, um eine Funktion der Hardware zu aktivieren oder die Hardware in einen bestimmten Modus zu versetzen. Der Softwareschlüssel dient in der Regel für Einstellungen, die sich darauf beziehen, wie eine einzelne Instanz des Geräts mit dem System und anderer Software interagiert. Zum Beispiel, um den Speicherort einer Datendatei festzulegen, um mit einem Framework zu interagieren oder um auf App-Einstellungen für ein Gerät zuzugreifen. Verwenden Sie eine der folgenden Optionen, um ein Handle zu diesen Speicherorten der Registrierung zu erhalten:

[ExampleDDInstall.HW]
AddReg = Example_DDInstall.AddReg

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

Registrierungsstatus von Geräteschnittstellen

Um den Registrierungsstatus der Geräteschnittstelle zu lesen und zu schreiben, verwenden Sie eine der folgenden Optionen:

Registrierungsstatus von Diensten

Der Status eines Dienstes sollte in eine von 3 Kategorien eingeteilt werden

Nicht veränderbarer Registrierungsstatus des Dienstes

Der unveränderliche Status des Dienstes ist der Status, der vom Treiberpaket, das den Dienst installiert, bereitgestellt wird. Diese Registrierungswerte, die von der INF für Treiber- und Win32-Dienste festgelegt werden, müssen unter dem Unterschlüssel „Parameter“ des Dienstes gespeichert werden, indem Sie eine HKR-Zeile in einem AddReg-Abschnitt bereitstellen und dann auf diesen Abschnitt im Dienstinstallationsabschnitt in der INF verweisen. Zum Beispiel:

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

[Example_Service_Inst]
DisplayName    = %ExampleService.SvcDesc%
ServiceType    = 1
StartType      = 3
ErrorControl   = 1
ServiceBinary  = %13%\ExampleService.sys
AddReg=Example_Service_Inst.AddReg

[Example_Service_Inst.AddReg]
HKR, Parameters, ExampleValue, 0x00010001, 1

Um vom Dienst aus zur Laufzeit auf den Speicherort dieses Status zuzugreifen, verwenden Sie eine dieser Funktionen:

Diese von der INF im Unterschlüssel „Parameter“ für den Dienst bereitgestellten Registrierungswerte sollten nur zur Laufzeit gelesen und nicht verändert werden. Sie sollten als schreibgeschützt behandelt werden.

Wenn es sich bei den von der INF gelieferten Registrierungswerten um Standardeinstellungen handelt, die zur Laufzeit überschrieben werden können, sollten die überschreibenden Werte in den internen Registrierungsstatus des Dienstes oder gemeinsamen Registrierungsstatus des Dienstes geschrieben werden. Beim Abrufen der Einstellungen kann die Einstellung zunächst im veränderbaren Status gesucht werden. Wenn sie dort nicht vorhanden ist, kann die Einstellung im unveränderlichen Status gesucht werden. RtlQueryRegistryValueWithFallback kann verwendet werden, um Einstellungen wie diese abzufragen, die eine Überschreibung und einen Standardwert haben.

Interner Registrierungsstatus des Dienstes

Der interne Status eines Dienstes ist ein Status, der zur Laufzeit geschrieben wird und nur dem Dienst selbst gehört und verwaltet wird und nur für diesen Dienst zugänglich ist. Um auf den Speicherort für den internen Status des Dienstes zuzugreifen, verwenden Sie eine der folgenden Funktionen des Dienstes:

Wenn der Dienst anderen Komponenten die Möglichkeit bieten will, diese Einstellungen zu ändern, muss der Dienst eine Schnittstelle bereitstellen, die eine andere Komponente aufrufen kann und die dem Dienst mitteilt, wie er diese Einstellungen ändern kann. Ein Win32-Dienst könnte zum Beispiel eine COM- oder RPC-Schnittstelle und ein Treiberdienst eine IOCTL-Schnittstelle über eine Geräteschnittstelle bereitstellen.

Gemeinsamer Registrierungsstatus des Dienstes

Der gemeinsame Status eines Dienstes ist ein Status, der zur Laufzeit geschrieben wird und mit anderen Komponenten im Benutzermodus geteilt werden kann, wenn diese ausreichend privilegiert sind. Um auf den Speicherort für diesen gemeinsamen Dienststatus zuzugreifen, verwenden Sie eine dieser Funktionen:

Dateistatus

Dieser Abschnitt enthält die folgenden Unterabschnitte:

Status der Gerätedatei

Wenn Dateien, die sich auf ein Gerät beziehen, zur Laufzeit geschrieben werden müssen, sollten diese Dateien relativ zu einem Handle oder Dateipfad gespeichert werden, der über die APIs des Betriebssystems bereitgestellt wird. Ein Beispiel für Dateien, die hier gespeichert werden sollten, sind gerätespezifische Konfigurationsdateien. Um auf den Speicherort dieses Status zuzugreifen, verwenden Sie eine der folgenden Funktionen des Dienstes:

Status der Servicedatei

Der Status der Servicedatei kann in eine von 3 Kategorien eingeteilt werden

Nicht veränderbarer Status der Servicedatei

Unveränderliche Status der Servicedatei sind Dateien, die Teil des Treiberpakets sind. Weitere Informationen zum Zugriff auf diese Dateien finden Sie unter Ausführen aus dem Treiber-Store.

Interner Status der Servicedatei

Ein interner Status der Servicedatei ist ein Status, der zur Laufzeit geschrieben wird und nur dem Dienst selbst gehört und verwaltet wird und auf den nur dieser Dienst Zugriff hat. Um auf den Speicherort für den internen Status des Dienstes zuzugreifen, verwenden Sie eine der folgenden Funktionen des Dienstes:

Wenn der Dienst anderen Komponenten die Möglichkeit bieten will, diese Einstellungen zu ändern, muss der Dienst eine Schnittstelle bereitstellen, die eine andere Komponente aufrufen kann und die dem Dienst mitteilt, wie er diese Einstellungen ändern kann. Ein Win32-Dienst könnte zum Beispiel eine COM- oder RPC-Schnittstelle und ein Treiberdienst eine IOCTL-Schnittstelle über eine Geräteschnittstelle bereitstellen.

Gemeinsamer Status der Servicedatei

Der Status der gemeinsam genutzten Status der Servicedatei ist ein Status, der zur Laufzeit geschrieben wird und mit anderen Komponenten im Benutzermodus geteilt werden kann, wenn diese ausreichend privilegiert sind. Um auf den Speicherort für diesen gemeinsamen Dienststatus zuzugreifen, verwenden Sie eine dieser Funktionen:

  • IoGetDriverDirectory (WDM, KMDF) mit dem Parameter DirectoryType festgelegt auf DriverDirectorySharedData

  • GetSharedServiceDirectory (Win32-Dienste), wobei der Parameter DirectoryType auf ServiceSharedDirectoryPersistentState festgelegt ist

DriverData und ProgramData

Dateien, die mit anderen Komponenten gemeinsam genutzt werden können, aber nicht in die Kategorie Gemeinsamer Status der Servicedatei passen, können entweder an DriverData- oder ProgramData-Speicherorte geschrieben werden.

Diese Speicherorte bieten Komponenten einen Ort, an dem sie temporäre Zustände oder Zustände schreiben können, die von anderen Komponenten verbraucht und möglicherweise von einem System gesammelt und kopiert werden sollen, um von einem anderen System verarbeitet zu werden. Dies gilt zum Beispiel für angepasste Log-Dateien oder Crash Dumps.

Vermeiden Sie das Schreiben von Dateien im Root der Verzeichnisse DriverData oder ProgramData. Erstellen Sie stattdessen ein Unterverzeichnis mit Ihrem Firmennamen und schreiben Sie dann Dateien und weitere Unterverzeichnisse in dieses Verzeichnis.

Bei einem Firmennamen wie Contoso könnte zum Beispiel ein Kernel-Mode-Treiber eine angepasste Log-Datei nach \DriverData\Contoso\Logs schreiben und eine User-Mode-Anwendung könnte die Log-Dateien aus %DriverData%\Contoso\Logs sammeln oder analysieren.

DriverData

Das Verzeichnis DriverData steht in Windows 10 ab Version 1803 zur Verfügung und ist für Administrator*innen und UMDF-Treiber zugreifbar.

Treiber im Kernel-Modus greifen auf das Verzeichnis DriverData über einen vom System bereitgestellten symbolischen Link namens \DriverData zu.

Benutzer*innen greifen auf das Verzeichnis DriverData mit Hilfe der Umgebungsvariablen %DriverData% zu.

ProgramData

Die Umgebungsvariable %ProgramData% für den Benutzermodus steht den Komponenten des Benutzermodus für das Speichern von Daten zur Verfügung.

Temporäre Dateien

Temporäre Dateien werden in der Regel für Zwischenvorgänge verwendet. Diese können in einen Unterpfad unter den Umgebungsvariablen %TEMP% oder %TMP% geschrieben werden. Da der Zugriff auf diese Speicherorte über Umgebungsvariablen erfolgt, ist diese Möglichkeit auf Komponenten im Benutzermodus beschränkt. Es gibt keine Garantien für die Lebensdauer oder das Fortbestehen dieser temporären Dateien, nachdem Handles auf sie geschlossen wurden. Das Betriebssystem oder der Benutzer*innen können sie jederzeit löschen und sie bleiben möglicherweise nicht über einen Neustart hinaus bestehen.

Vermeiden Sie das Schreiben von Dateien im Root der Verzeichnisse %TEMP% oder %TMP%. Erstellen Sie stattdessen ein Unterverzeichnis mit Ihrem Firmennamen und schreiben Sie dann Dateien und weitere Unterverzeichnisse in dieses Verzeichnis.

Eigenschaftsstatus

Sowohl Geräte als auch Geräteschnittstellen unterstützen das Speichern des Status über das PnP-Eigenschaftsmodell. Das Eigenschaftsmodell bietet die Möglichkeit, strukturierte Eigenschaftsdaten für ein Gerät oder eine Geräteschnittstelle zu speichern. Dies ist für kleinere Daten gedacht, die vernünftigerweise in die vom Eigenschaftsmodell unterstützten Eigenschaftstypen passen.

Für den Zugriff auf Geräteeigenschaften können diese APIs verwendet werden:

Für den Zugriff auf Eigenschaften von Geräteschnittstellen können diese APIs verwendet werden:

Verwenden von Geräteschnittstellen

Wenn ein Treiber anderen Komponenten die Möglichkeit bieten möchte, den internen Status des Treibers zu lesen oder zu ändern, sollte der Treiber eine Schnittstelle bereitstellen, die eine andere Komponente aufrufen kann und die dem Treiber mitteilt, welche Einstellungen er zurückgeben oder wie er bestimmte Einstellungen ändern soll. Der Treiberdienst könnte zum Beispiel eine IOCTL-Schnittstelle über eine Geräteschnittstelle bereitstellen.

In der Regel stellt der Treiber, dem der Status gehört, eine Geräteschnittstelle in einer angepassten Geräteschnittstellenklasse zur Verfügung. Wenn der Treiber bereit ist, dass andere Komponenten auf den Status zugreifen können, aktiviert er die Schnittstelle. Um benachrichtigt zu werden, wenn eine Geräteschnittstelle aktiviert ist, können sich Benutzer*innen für Geräteschnittstellen-Ankunftsbenachrichtigungen registrieren und Kernel-Komponenten können IoRegisterPlugPlayNotification verwenden. Damit diese Komponenten auf den Status zugreifen können, muss der Treiber, der die Schnittstelle aktiviert, einen Vertrag für seine angepasste Geräte-Schnittstellenklasse definieren. Dieser Vertrag ist in der Regel eine von zwei Arten:

  • Ein E/A-Vertrag kann mit dieser Geräte-Schnittstellenklasse verknüpft werden, der einen Mechanismus für den Zugriff auf den Status bereitstellt. Andere Komponenten verwenden die aktivierte Geräteschnittstelle, um E/A-Anfragen zu senden, die dem Vertrag entsprechen.

  • Eine Direct-Call-Schnittstelle, die über eine Abfrage-Schnittstelle zurückgegeben wird. Andere Treiber könnten IRP_MN_QUERY_INTERFACE senden, um Funktionszeiger von dem aufzurufenden Treiber zu erhalten.

Wenn der Treiber, dem der Status gehört, den direkten Zugriff auf den Status zulässt, könnten andere Treiber alternativ auf den Status zugreifen, indem sie die vom System bereitgestellten Funktionen für den programmgesteuerten Zugriff auf den Status der Geräteschnittstelle verwenden. Weitere Informationen finden Sie unter Geräteschnittstellen-Registrierungsstatus.

Diese Schnittstellen oder der Status (je nach verwendeter Freigabemethode) müssen ordnungsgemäß versioniert werden, damit der Treiber, dem der Status gehört, unabhängig von anderen Komponenten, die auf diesen Status zugreifen, gewartet werden kann. Die Anbieter von Treibern können sich nicht darauf verlassen, dass andere Komponenten zur gleichen Zeit wie der Treiber gewartet werden und auf der gleichen Version bleiben.

Da Geräte und Treiber, die Schnittstellen steuern, kommen und gehen, sollten Treiber und Anwendungen den Aufruf von IoGetDeviceInterfaces beim Start der Komponente vermeiden, um eine Liste der aktivierten Schnittstellen zu erhalten. Stattdessen ist es am besten, sich für Benachrichtigungen über das Eintreffen oder Entfernen von Geräteschnittstellen zu registrieren und dann die entsprechende Funktion aufzurufen, um die Liste der auf dem Computer vorhandenen aktivierten Schnittstellen zu erhalten.

Weitere Informationen über Geräteschnittstellen finden Sie unter:

Kurzreferenz der Betriebssystemunterstützung für Status-Management-APIs

Die meisten Treiberpakete müssen eine Reihe von Betriebssystemversionen unterstützen. Unter Unterstützung mehrerer Betriebssystemversionen finden Sie weitere Informationen darüber, wie Sie dies in einem Treiberpaket erreichen. In den folgenden Tabellen finden Sie eine Kurzreferenz darüber, wann der Betriebssystem-Support für verschiedene Status-Management-APIs hinzugefügt wurde.

WDM-Treiber

Betriebssystem Hinzugefügte Unterstützung
Windows 2000 IoOpenDeviceRegistryKey
IoOpenDeviceInterfaceRegistryKey
Windows Vista IoGetDevicePropertyData
IoSetDevicePropertyData
Windows 8 IoGetDeviceInterfacePropertyData
IoSetDeviceInterfacePropertyData
Windows 8,1 IoQueryFullDriverPath
Windows 10 1803 IoOpenDriverRegistryKey für RegKeyType von DriverRegKeyParameters und DriverRegKeyPersistentState
IoGetDeviceDirectory
IoGetDriverDirectory für DirectoryType von DriverDirectoryImage und DriverDirectoryData
Windows 10 1809 RtlQueryRegistryValueWithFallback
Windows 11 21H2 IoOpenDriverRegistryKey für RegKeyType von DriverRegKeySharedPersistentState
IoGetDriverDirectory für DirectoryType von DriverDirectorySharedData

KMDF-Treiber

KMDF-Version Hinzugefügte Unterstützung
1.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
1.13 WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
1,25 WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)

UMDF-Treiber

UMDF-Version Hinzugefügte Unterstützung
2.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
WdfDeviceQueryInterfaceProperty (Windows 8.1)
WdfDeviceAllocAndQueryInterfaceProperty (Windows 8.1)
WdfDeviceAssignInterfaceProperty (Windows 8.1)
2,25 WdfDeviceRetrieveDeviceDirectoryString
WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)
2.27 WdfDriverRetrieveDriverDataDirectoryString

Benutzermodus-Code

Betriebssystem Hinzugefügte Unterstützung
Windows 2000 CM_Open_DevNode_Key
Windows Vista CM_Open_Device_Interface_Key
CM_Get_DevNode_Property
CM_Set_DevNode_Property
CM_Get_Device_Interface_Property
CM_Set_Device_Interface_Property
Windows 10 2004 GetServiceRegistryStateKey
GetServiceDirectory
Windows 11 21H2 GetSharedServiceRegistryStateKey
GetSharedServiceDirectory