Condividi tramite


Isolamento del pacchetto driver

L'isolamento dei pacchetti driver è un requisito per i driver di Windows che rende i pacchetti driver più resilienti alle modifiche esterne, all'aggiornamento più semplice e più semplice da installare.

Nota

Anche se l'isolamento dei pacchetti driver è necessario per i driver di Windows, i driver desktop di Windows ne traggono comunque vantaggio grazie a una maggiore resilienza e facilità di servizio.

Nella tabella seguente vengono illustrate alcune procedure di esempio per i pacchetti driver legacy non più consentite per i driver windows nella colonna sinistra insieme al comportamento necessario per i driver di Windows nella colonna destra.

Driver non isolato Driver isolato
INF copia i file in %windir%\System32 o %windir%\System32\drivers I file del driver vengono eseguiti dall'archivio driver
Interagisce con stack di dispositivi/driver usando percorsi hardcoded Interagisce con stack di dispositivi/driver usando le funzioni fornite dal sistema o le interfacce del dispositivo
Percorso hardcodes in percorsi globali del Registro di sistema Usa le funzioni HKR e fornite dal sistema per il percorso relativo del Registro di sistema e dello stato del file
Scritture di file di runtime in qualsiasi percorso I file vengono scritti in relazione ai percorsi forniti dal sistema operativo

Per informazioni su come determinare se il pacchetto driver soddisfa i requisiti di isolamento dei pacchetti driver, vedere Convalida dei driver di Windows. Per esempi di come aggiornare un INF per soddisfare i requisiti di isolamento dei pacchetti driver, vedere Conversione di un INF per seguire l'isolamento del pacchetto driver.

Eseguire dall'archivio driver

Tutti i pacchetti driver isolati lasciano i file del pacchetto driver nell'archivio driver. Ciò significa che specificano DIRID 13 nel relativo INF per specificare il percorso dei file del pacchetto driver durante l'installazione. Per altre informazioni su come usarlo in un pacchetto driver, vedere Eseguire dall'archivio driver.

Lettura e scrittura dello stato

Nota

Se il componente usa le proprietà dell'interfaccia del dispositivo o del dispositivo per archiviare lo stato, continuare a usare tale metodo e l'API del sistema operativo appropriata per archiviare e accedere allo stato. Le indicazioni seguenti per lo stato del Registro di sistema e del file sono destinate ad altri stati che devono essere archiviati da un componente.

L'accesso a vari stati del Registro di sistema e file deve essere eseguito chiamando le funzioni che forniscono a un chiamante la posizione dello stato e quindi lo stato viene letto/scritto in relazione a tale posizione. Non usare percorsi assoluti del Registro di sistema e percorsi di file hardcoded.

In questa sezione sono disponibili le procedure seguenti:

Stato del Registro di sistema

In questa sezione sono disponibili le procedure seguenti:

Stato del Registro di sistema del dispositivo PnP

I pacchetti driver isolati e i componenti in modalità utente usano in genere una delle due posizioni per archiviare lo stato del dispositivo nel Registro di sistema. Si tratta della chiave hardware (chiave del dispositivo) per il dispositivo e della chiave software (chiave del driver) per il dispositivo. La chiave hardware è in genere per le impostazioni relative al modo in cui una singola istanza del dispositivo interagisce con l'hardware. Ad esempio, per abilitare una funzionalità hardware o inserire l'hardware in una modalità specifica. La chiave software è in genere per le impostazioni relative al modo in cui una singola istanza del dispositivo interagisce con il sistema e altri software. Ad esempio, per configurare il percorso di un file di dati, per l'interazione con un framework o per accedere alle impostazioni dell'app per un dispositivo. Per recuperare un handle in questi percorsi del Registro di sistema, utilizzare una delle opzioni seguenti:

[ExampleDDInstall.HW]
AddReg = Example_DDInstall.AddReg

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

Stato del Registro di sistema dell'interfaccia del dispositivo

Per leggere e scrivere lo stato del Registro di sistema dell'interfaccia del dispositivo, usare una delle opzioni seguenti:

Stato del Registro di sistema del servizio

Lo stato del servizio deve essere classificato in una delle 3 categorie

Stato del Registro di sistema del servizio non modificabile

Lo stato del servizio non modificabile è lo stato fornito dal pacchetto driver che installa il servizio. Questi valori del Registro di sistema impostati da INF per i servizi driver e Win32 devono essere archiviati nella sottochiave "Parameters" del servizio fornendo una riga HKR in una sezione AddReg e quindi facendo riferimento a tale sezione nella sezione di installazione del servizio in INF. Ad esempio:

[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

Per accedere alla posizione di questo stato dal servizio in fase di esecuzione, usare una di queste funzioni:

Questi valori del Registro di sistema forniti da INF nella sottochiave "Parameters" per il servizio devono essere letti solo in fase di esecuzione e non modificati. Devono essere trattati come di sola lettura.

Se i valori del Registro di sistema forniti da INF sono impostazioni predefinite che possono essere sovrascritte in fase di esecuzione, i valori di override devono essere scritti nello stato del Registro di sistema del servizio interno o nello stato del Registro di sistema del servizio condiviso per il servizio. Quando si recuperano le impostazioni, l'impostazione può essere cercata per prima nello stato modificabile. Se non esiste, l'impostazione può essere cercata nello stato non modificabile. RtlQueryRegistryValueWithFallback può essere usato per consentire le impostazioni di query, ad esempio quelle con override e un valore predefinito.

Stato del Registro di sistema del servizio interno

Lo stato del servizio interno è lo stato scritto in fase di esecuzione e di proprietà e gestito solo dal servizio stesso ed è accessibile solo a tale servizio. Per accedere alla posizione per lo stato del servizio interno, usare una di queste funzioni dal servizio:

Se il servizio vuole consentire ad altri componenti di modificare queste impostazioni, il servizio deve esporre un'interfaccia che un altro componente può chiamare in che indica al servizio come modificare queste impostazioni. Ad esempio, un servizio Win32 potrebbe esporre un'interfaccia COM o RPC e un servizio driver potrebbe esporre un'interfaccia IOCTL tramite un'interfaccia dispositivo.

Stato del Registro di sistema del servizio condiviso

Lo stato del servizio condiviso è lo stato scritto in fase di esecuzione e può essere condiviso con altri componenti in modalità utente se sono sufficientemente privilegiati. Per accedere alla posizione per questo stato del servizio condiviso, usare una di queste funzioni:

Stato del file

In questa sezione sono disponibili le procedure seguenti:

Stato del file del dispositivo

Se i file correlati a un dispositivo devono essere scritti in fase di esecuzione, questi file devono essere archiviati in relazione a un handle o a un percorso di file fornito tramite l'API del sistema operativo. I file di configurazione specifici del dispositivo sono un esempio dei tipi di file da archiviare qui. Per accedere alla posizione di questo stato, usare una di queste funzioni dal servizio:

Stato del file del servizio

Lo stato del file di servizio può essere classificato in una delle 3 categorie

Stato del file del servizio non modificabile

Lo stato del file del servizio non modificabile è costituito da file che fanno parte del pacchetto driver. Per altre informazioni sull'accesso a tali file, vedere Eseguire da Driver Store.

Stato del file del servizio interno

Lo stato del file del servizio interno è lo stato scritto in fase di esecuzione e di proprietà e gestito solo dal servizio stesso ed è accessibile solo a tale servizio. Per accedere alla posizione per lo stato del servizio interno, usare una di queste funzioni dal servizio:

Se il servizio vuole consentire ad altri componenti di modificare queste impostazioni, il servizio deve esporre un'interfaccia che un altro componente può chiamare in che indica al servizio come modificare queste impostazioni. Ad esempio, un servizio Win32 potrebbe esporre un'interfaccia COM o RPC e un servizio driver potrebbe esporre un'interfaccia IOCTL tramite un'interfaccia dispositivo.

Stato del file del servizio condiviso

Lo stato del file del servizio condiviso è lo stato scritto in fase di esecuzione e può essere condiviso con altri componenti in modalità utente se sono sufficientemente privilegiati. Per accedere alla posizione per questo stato del servizio condiviso, usare una di queste funzioni:

  • IoGetDriverDirectory (WDM, KMDF) con il parametro DirectoryType impostato su DriverDirectorySharedData

  • GetSharedServiceDirectory (Servizi Win32) con il parametro DirectoryType impostato su ServiceSharedDirectoryPersistentState

DriverData e ProgramData

I file che possono essere condivisi con altri componenti, ma che non rientrano nella categoria dello stato del file del servizio condiviso possono essere scritti in percorsi DriverData o ProgramData .

Queste posizioni offrono ai componenti una posizione in cui scrivere lo stato temporaneo o lo stato che deve essere utilizzato da altri componenti e potenzialmente raccolti e copiati da un sistema da elaborare da un altro sistema. Ad esempio, i file di log personalizzati o i dump di arresto anomalo si adattano a questa descrizione.

Evitare di scrivere file nella radice delle DriverData directory o ProgramData . Creare invece una sottodirectory con il nome della società e quindi scrivere file e altre sottodirectory all'interno di tale directory.

Ad esempio, per un nome aziendale di Contoso, un driver in modalità kernel potrebbe scrivere un log personalizzato in \DriverData\Contoso\Logs e un'applicazione in modalità utente potrebbe raccogliere o analizzare i file di log da %DriverData%\Contoso\Logs.

DriverData

La DriverData directory è disponibile in Windows 10, versione 1803 e successive ed è accessibile agli amministratori e ai driver UMDF.

I driver in modalità kernel accedono alla DriverData directory usando un collegamento simbolico fornito dal sistema denominato \DriverData.

I programmi in modalità utente accedono alla DriverData directory usando la variabile %DriverData%di ambiente .

ProgramData

La %ProgramData% variabile di ambiente in modalità utente è disponibile per i componenti in modalità utente da usare per l'archiviazione dei dati.

File temporanei

I file temporanei vengono in genere usati nelle operazioni intermedie. Questi valori possono essere scritti in un sottopercorso nelle variabili di %TEMP% ambiente o %TMP% . Poiché questi percorsi sono accessibili tramite variabili di ambiente, questa possibilità è limitata ai componenti in modalità utente. Non vi sono garanzie sulla durata o la persistenza di questi file temporanei dopo la chiusura degli handle. Il sistema operativo o l'utente può rimuoverli in qualsiasi momento e potrebbe non essere persistente in un riavvio.

Evitare di scrivere file nella radice delle %TEMP% directory o %TMP% . Creare invece una sottodirectory con il nome della società e quindi scrivere file e altre sottodirectory all'interno di tale directory.

Stato della proprietà

Sia i dispositivi che le interfacce del dispositivo supportano l'archiviazione dello stato tramite il modello di proprietà PnP. Il modello di proprietà consente di archiviare i dati delle proprietà strutturate su un dispositivo o un'interfaccia del dispositivo. Ciò è destinato a dati più piccoli che si adattano ragionevolmente ai tipi di proprietà supportati dal modello di proprietà.

Per accedere alle proprietà del dispositivo, è possibile usare queste API:

Per accedere alle proprietà dell'interfaccia del dispositivo, è possibile usare queste API:

Uso delle interfacce dei dispositivi

Se un driver vuole consentire ad altri componenti di leggere o modificare lo stato interno del driver, il driver deve esporre un'interfaccia che un altro componente può chiamare in che indica al driver quali impostazioni restituire o come modificare determinate impostazioni. Ad esempio, il servizio driver potrebbe esporre un'interfaccia IOCTL tramite un'interfaccia del dispositivo.

In genere, il driver proprietario dello stato espone un'interfaccia del dispositivo in una classe di interfaccia dispositivo personalizzata. Quando il driver è pronto per consentire ad altri componenti di accedere allo stato, abilita l'interfaccia . Per ricevere notifiche quando un'interfaccia del dispositivo è abilitata, i componenti in modalità utente possono registrarsi per le notifiche di arrivo dell'interfaccia del dispositivo e i componenti in modalità kernel possono usare IoRegisterPlugPlayNotification. Per consentire a questi componenti di accedere allo stato, il driver che abilita l'interfaccia deve definire un contratto per la classe di interfaccia dispositivo personalizzata. Questo contratto è in genere uno dei due tipi seguenti:

  • Un contratto di I/O può essere associato a tale classe di interfaccia dispositivo che fornisce un meccanismo per l'accesso allo stato. Altri componenti usano l'interfaccia del dispositivo abilitata per inviare richieste di I/O conformi al contratto.

  • Interfaccia direct-call che viene restituita tramite un'interfaccia di query. Altri driver potrebbero inviare IRP_MN_QUERY_INTERFACE per recuperare i puntatori di funzione dal driver da chiamare.

In alternativa, se il driver proprietario dello stato consente l'accesso diretto allo stato, altri driver potrebbero accedere allo stato usando funzioni fornite dal sistema per l'accesso a livello di codice allo stato dell'interfaccia del dispositivo. Per altre informazioni, vedere Stato del Registro di sistema dell'interfaccia del dispositivo.

Queste interfacce o lo stato (a seconda del metodo di condivisione usato) devono essere correttamente con controllo delle versioni in modo che il driver proprietario dello stato possa essere eseguito indipendentemente da altri componenti che accedono a tale stato. I fornitori di driver non possono basarsi su altri componenti gestiti contemporaneamente al driver e rimanere nella stessa versione.

Poiché i dispositivi e i driver che controllano le interfacce sono disponibili, i driver e le applicazioni devono evitare di chiamare IoGetDeviceInterfaces all'avvio del componente per ottenere un elenco di interfacce abilitate. La procedura consigliata consiste invece nella registrazione per le notifiche relative all'arrivo o alla rimozione dell'interfaccia del dispositivo e quindi chiamare la funzione appropriata per ottenere l'elenco delle interfacce abilitate esistenti nel computer.

Per altre informazioni sulle interfacce dei dispositivi, vedere:

Riferimento rapido del supporto del sistema operativo per le API di gestione dello stato

La maggior parte dei pacchetti driver deve supportare una gamma di versioni del sistema operativo. Per altre informazioni su come ottenere questo risultato in un pacchetto driver, vedere Supporto di più versioni del sistema operativo. Le tabelle seguenti forniscono un riferimento rapido di quando è stato aggiunto il supporto del sistema operativo per varie API di gestione dello stato.

Driver WDM

Sistema operativo Aggiunta del supporto
Windows 2000 IoOpenDeviceRegistryKey
IoOpenDeviceInterfaceRegistryKey
Windows Vista IoGetDevicePropertyData
IoSetDevicePropertyData
Windows 8 IoGetDeviceInterfacePropertyData
IoSetDeviceInterfacePropertyData
Windows 8.1 IoQueryFullDriverPath
Windows 10 1803 IoOpenDriverRegistryKey per RegKeyType di DriverRegKeyParameters e DriverRegKeyPersistentState
IoGetDeviceDirectory
IoGetDriverDirectory per DirectoryType di DriverDirectoryImage e DriverDirectoryData
Windows 10 1809 RtlQueryRegistryValueWithFallback
Windows 11 21H2 IoOpenDriverRegistryKey per RegKeyType di DriverRegKeySharedPersistentState
IoGetDriverDirectory per DirectoryType di DriverDirectorySharedData

Driver KMDF

Versione kmdf Aggiunta del supporto
1.0 WdfDeviceOpenRegistryKey
WdfFdoInitOpenRegistryKey
WdfDriverOpenParametersRegistryKey
WdfDeviceQueryProperty
WdfDeviceAllocAndQueryProperty
WdfFdoInitQueryProperty
WdfFdoInitAllocAndQueryProperty
1.13 WdfDeviceQueryPropertyEx
WdfDeviceAllocAndQueryPropertyEx
WdfDeviceAssignProperty
WdfFdoInitQueryPropertyEx
WdfFdoInitAllocAndQueryPropertyEx
1.25 WdfDriverOpenPersistentStateRegistryKey (Windows 10 1803)

Driver UMDF

Versione di UMDF Aggiunta del supporto
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

Codice in modalità utente

Sistema operativo Aggiunta del supporto
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