Ordinamento dei driver di filtro del dispositivo
Microsoft ha sviluppato un metodo per aggiungere filtri in modo dichiarativo esprimendo la finalità del filtro, anziché la posizione dello stack, nota come ordinamento dei driver di filtro dei dispositivi.
La necessità di ordinare driver di filtro del dispositivo
Prima di Windows 10 versione 1903, l'unico modo supportato per registrare un driver di filtro del dispositivo era l'aggiunta di una voce del Registro di sistema (usando la direttiva AddReg). Tuttavia, questo metodo di manipolazione del Registro di sistema non offre la flessibilità necessaria per specificare esattamente la posizione in cui registrare un particolare filtro.
Filtrare la registrazione usando la direttiva AddReg semplicemente aggiunge il filtro alla fine dell'elenco di filtri. Questo approccio usa un elenco di valori in cui l'ordine è importante e determina dove viene caricato il filtro nello stack.
L'uso di un singolo elenco di valori ordinati è minore dell'ideale, soprattutto quando AddReg viene aggiunto solo alla fine, perché esistono conseguenze negative quando più driver aggiungono filtri allo stesso dispositivo.
Nello scenario in cui è coinvolto almeno un INF di estensione, se gli INFS usano in modo improprio AddReg (in altre parole non usano il flag di accodamento), potrebbero cancellare un filtro aggiunto da un INF diverso.
Inoltre, più estensioni INF potrebbero aggiungere filtri e l'ordinamento relativo di tali filtri può essere importante; Tuttavia, la piattaforma Plug and Play (PnP) non garantisce un ordine di installazione per le estensioni. Il risultato è che l'ordine delle "appende" non è garantito.
Implementazione dell'ordinamento dei driver di filtro dei dispositivi
Per fornire un metodo dichiarativo flessibile per registrare i filtri dei dispositivi, Microsoft ha sviluppato un metodo per aggiungere filtri in modo dichiarativo esprimendo la finalità del filtro, anziché la posizione dello stack. La soluzione fornisce agli autori dei driver di funzione la possibilità di esprimere nel proprio INF un set ordinato di posizioni (denominate livelli) rispetto a cui un filtro può registrarsi.
Oltre a un livello specifico, un filtro può registrare in modo dichiarativo semplicemente come filtro di livello superiore o inferiore .
L'infrastruttura si basa su un nuovo metodo di registrazione del filtro per determinare quali driver degli ordini devono essere inclusi nello stack di dispositivi. Il nuovo metodo non interrompe la compatibilità per il vecchio modo di aggiungere filtri. Tuttavia, consente ai nuovi filtri di passare a un meccanismo di registrazione più affidabile e flessibile.
Il metodo è abilitato con la definizione dell'INF di base di un elenco ordinato di uno o più "livelli". Sia l'INF di base che qualsiasi estensione INFS possono registrare un filtro dichiarativo tramite una nuova direttiva INF che specifica il nome del servizio e il livello a cui appartiene il filtro. I filtri superiori e inferiori ognuno di essi sono rappresentati dal rispettivo elenco ordinato di livelli.
Questi elenchi di filtri superiori e inferiori vengono creati ordinando tutti i driver di filtro in base al relativo livello. L'ordine dei filtri all'interno di ogni livello deve essere considerato arbitrario, in cui nessuna dipendenza può essere presa nell'ordine dei filtri all'interno di un determinato livello. Negli scenari in cui è necessario garantire l'ordine relativo di due filtri, devono essere registrati in livelli diversi.
Si consideri l'esempio di driver di dispositivo seguente:
L'INF di base del driver di dispositivo dichiara due livelli di filtro superiore, A e B (in tale ordine). Nell'INF di base associato Extension INF vengono aggiunti due filtri in ognuno dei due livelli.
Il risultato dell'installazione del driver di dispositivo è un ordine dello stack di dispositivi che unisce gli elenchi di driver di filtro rispettando il posizionamento e l'ordinamento desiderati. L'ordine dello stack di dispositivi risultante garantisce che qualsiasi filtro inserito nel livello "A" venga preceduto da qualsiasi filtro nel livello "B". Tuttavia, all'interno di ogni livello, l'ordine è arbitrario.
Come illustrato nell'esempio, Filter3 potrebbe venire prima di Filter5 o potrebbe venire dopo Filter5. In ogni caso, Filter3 e Filter5 verranno prima che i filtri al livello successivo, "B".
Quando si progetta la serie di livelli in cui è possibile registrare i filtri, anziché creare una serie di livelli per l'ordinamento, i livelli devono essere denominati e ordinati in modo che eseseguono il mapping alla finalità del filtro. Ad esempio, un dispositivo di I/O può definire il livello Crittografia, a cui deve essere registrato qualsiasi filtro di crittografia. In questo modo la finalità del filtro può essere facilmente compresa e gestita e rende lo stack più affidabile rispetto alle modifiche di rilievo apportate al driver di funzione.
Nota
Anche senza livelli definiti dall'INF di base, un filtro dichiarativo può essere registrato come semplicemente superiore o inferiore. Quando i livelli non sono definiti, questo equivale logicamente all'aggiunta del filtro alla fine del valore del Registro di sistema UpperFilters/LowerFilters. Quando vengono definiti i livelli, uno dei livelli deve essere contrassegnato come livello predefinito nel driver di base e in questo caso il filtro verrà registrato in tale livello.
Scenari
Si consideri un driver di dispositivo di I/O che crittografa i dati provenienti dallo stack. Un'implementazione tipica può usare un driver di filtro inferiore immediatamente sotto il driver di funzione per eseguire questa operazione. Per garantire che il filtro di crittografia sia posizionato nella posizione esatta desiderata dall'autore del driver, possono usare filtri dichiarativi, come illustrato di seguito:
L'INF di base stabilisce due livelli di filtri inferiori, "Crittografia" e "Monitoraggio" (impostazione predefinita). "Monitoraggio" (impostazione predefinita) in questo esempio sono il resto dei filtri inferiori che potrebbero esistere per questo particolare dispositivo. Posizionando in modo esplicito il driver di filtro "Crittografa" a livello di "Crittografia", il driver garantisce che l'ordine dello stack di dispositivi risultante inserisca il driver di filtro "Encrypt" prima di qualsiasi altro filtro inferiore e immediatamente dopo il driver di funzione.
Esaminiamo l'esempio un ulteriore passo avanti. Si supponga che venga pubblicata una versione più recente del driver e che l'autore abbia compilato la crittografia per il driver di funzione. In questo modo viene rimossa la necessità di un driver di filtro "Encrypt" separato. L'autore deve semplicemente rimuovere il livello che conteneva il filtro "Encrypt" da Base INF e quando il driver viene aggiornato, lo stack viene compilato di nuovo in modo dinamico.
Se un filtro dichiara di essere in un livello esplicito che non esiste, il filtro non si trova nello stack di dispositivi. Nell'esempio, l'INF di base è stato aggiornato e, anche se l'estensione INF rimane invariata, lo stack di dispositivi risultante esclude il filtro "Encrypt" perché non è stato incluso nella dichiarazione di livelli di Base INF.
Livello di filtro predefinito
Per generare lo stack di filtri finale, tutte le origini delle informazioni sui filtri vengono unite in un unico elenco. È importante notare che la logica di unione viene eseguita durante la creazione dello stack di dispositivi. Se viene aggiunto un nuovo filtro installando un driver di base o di estensione nuovo/aggiornato, i dispositivi verranno riavviati durante l'installazione e ritireranno un nuovo elenco di filtri.
Alcune origini di filtri non contengono informazioni sulla posizione, ovvero filtri aggiunti tramite i valori legacy del Registro di sistema UpperFilters/LowerFilters o tramite la sintassi dichiarativa di sola posizione (descritta di seguito).
Per supportare un'unione efficace quando mancano le informazioni sulla posizione, è necessario definire un'informazione aggiuntiva da INF di base: un livello di filtro predefinito. Il livello di filtro predefinito è una posizione in cui verranno inseriti i filtri, privi di informazioni sul livello o sulla posizione.
Ad esempio, i livelli di filtro possono essere definiti in Base INF come:
Level Order: A, B, C
DefaultFilterLevel: C
Se si specifica il livello predefinito come livello finale, viene indicato che qualsiasi filtro privo di informazioni sulla posizione verrà aggiunto all'elenco di filtri. In alternativa, l'autore del driver potrebbe voler terminare sempre lo stack con filtri registrati in modo esplicito al livello C:
Level Order: A, B, C
DefaultFilterLevel: B
A causa del livello di filtro predefinito impostato su B, qualsiasi filtro aggiuntivo senza informazioni sulla posizione verrà inserito tra i filtri di A e i filtri di C.
Sintassi
Registrazione dei filtri
Per altre informazioni, vedere la sezione INF DDInstall.Filters e la documentazione della direttiva AddFilter.
[DDInstall.Filters]
AddFilter = <FilterName>, [Flags], FilterSection
FilterLevel OR FilterPosition può essere specificato in uno dei due modi seguenti:
Opzione 1:
[FilterSection]
FilterLevel=<LevelName>
Opzione 2:
[FilterSection]
FilterPosition=Upper/Lower
Questa operazione può essere eseguita sia nell'INF di base che in quello dell'estensione.
[DDInstall.Filters]
FilterName è il nome del servizio nel sistema.
I flag sono attualmente inutilizzati e devono essere lasciati vuoti o impostati su 0.
FilterSection è una sezione che descrive il filtro.
[Sezione Filtro]
Una sezione di filtro deve contenere esattamente una delle due direttive seguenti: FilterLevel o FilterPosition.
FilterLevel è una posizione specifica per inserire il filtro del dispositivo nello stack, definito dall'INF di base. All'interno di ogni livello, l'ordine dei filtri è arbitrario.
Un oggetto FilterPosition viene usato nel caso in cui la classe abbia una posizione specifica per l'inserimento di filtri di terze parti.A FilterPosition is used in the case where the class has one specific place for third-party filters to be inserted.
Definizione dei livelli di filtro
[DDInstall.HW]
AddReg = FilterLevel_Definition
[FilterLevel_Definition]
HKR,,UpperFilterLevels,%REG_MULTI_SZ%,"LevelA","LevelB","LevelC"
HKR,,UpperFilterDefaultLevel,,"LevelC"
HKR,,LowerFilterLevels,%REG_MULTI_SZ%,"LevelD","LevelE","LevelF"
HKR,,LowerFilterDefaultLevel,,"LevelE"
Questa operazione può essere eseguita solo da un driver di base .
È possibile recuperare l'elenco dichiarativo completo dei filtri per un dispositivo specifico eseguendo una query sulle proprietà seguenti:
DEVPKEY_Device_CompoundUpperFilters
DEVPKEY_Device_CompoundLowerFilters
Registrazione del filtro equivalente legacy
Si esaminerà ora come eseguire l'approccio legacy del tentativo di aggiungere un filtro superiore tramite INF:
[DDInstall.HW]
AddReg = Filters
[Filters]
HKR,,"UpperFilters", 0x00010008, "MyFilter"
Questa sintassi aggiungerà "MyFilter" alla fine dell'elenco dei filtri superiori.
Con la nuova sintassi introdotta, la sezione precedente è logicamente simile a:
[DDInstall.Filters]
AddFilter = MyFilter,,MyUpperFilterInstall
[MyUpperFilterInstall]
FilterPosition = Upper
Specifica che il filtro "MyFilter" deve essere aggiunto all'elenco dei filtri superiori. Se l'INF di base ha specificato livelli di filtro, l'utilizzo di FilterPosition registrerà il filtro nel livello predefinito per tale posizione.
Se i livelli di filtro non vengono specificati, questo filtro verrà registrato come filtro superiore in ordine arbitrario.