Enumerazione dinamica
L'enumerazione dinamica è la possibilità di rilevare e segnalare le modifiche al numero e al tipo di dispositivi connessi al sistema durante l'esecuzione del sistema.
I driver del bus devono usare l'enumerazione dinamica se il numero o i tipi di dispositivi connessi al dispositivo padre dipendono dalla configurazione di un sistema. Alcuni di questi dispositivi potrebbero essere sempre connessi al sistema e alcuni potrebbero essere collegati e scollegati durante l'esecuzione del sistema.
Ad esempio, il numero e il tipo di dispositivi collegati al bus PCI di un sistema sono dipendenti dal sistema, ma sono permanenti a meno che un utente non disattiva l'alimentazione, apre il case e aggiunge o rimuove un dispositivo usando un cacciavite. D'altra parte, un utente può aggiungere o rimuovere dispositivi USB collegando o scollegando un cavo durante l'esecuzione del sistema.
Elenchi figlio dinamici
Il framework consente ai driver di supportare l'enumerazione dinamica fornendo oggetti elenco figlio del framework. Ogni oggetto elenco figlio rappresenta un elenco di dispositivi figlio connessi a un dispositivo padre. Il driver del bus per il dispositivo padre deve identificare i dispositivi figlio dell'elemento padre, aggiungerli all'elenco figlio del dispositivo padre e creare un oggetto dispositivo fisico (PDO) per ogni figlio.
Ogni volta che un driver crea un oggetto dispositivo framework che rappresenta un oggetto FDO per un dispositivo, il framework crea un elenco figlio vuoto e predefinito per il dispositivo. Il driver può ottenere un handle per l'elenco figlio predefinito di un dispositivo chiamando WdfFdoGetDefaultChildList. In genere, se si scrive un driver del bus che enumera i figli di un dispositivo, il driver può aggiungere elementi figlio all'elenco figlio predefinito. Se è necessario creare elenchi figlio aggiuntivi, il driver può chiamare WdfChildListCreate.
Prima che un driver possa usare un elenco figlio, deve configurare l'oggetto elenco figlio inizializzando una struttura WDF_CHILD_LIST_CONFIG e passando la struttura a WdfFdoInitSetDefaultChildListConfig, per l'elenco figlio predefinito o a WdfChildListCreate, per elenchi figlio aggiuntivi.
Descrizioni figlio dinamiche
Ogni volta che un driver del bus identifica un dispositivo figlio, deve aggiungere la descrizione del dispositivo figlio a un elenco figlio. Una descrizione figlio è costituita da una descrizione di identificazione obbligatoria e da una descrizione dell'indirizzo facoltativa.
Descrizione identificazione Una descrizione di identificazione è una struttura che contiene informazioni che identificano in modo univoco ogni dispositivo enumera il driver. Il driver definisce questa struttura, ma il primo membro deve essere una struttura WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER .
In genere, una descrizione di identificazione contiene le stringhe di identificazione del dispositivo, possibilmente un numero di serie e informazioni sulla posizione del dispositivo sul bus, ad esempio un numero di slot.
Il driver può fornire il set seguente di funzioni di callback, che consentono al framework di modificare le informazioni in una descrizione di identificazione:
EvtChildListIdentificationDescriptionCompare, che confronta il contenuto di due strutture di descrizione di identificazione.
EvtChildListIdentificationDescriptionCopy, che copia il contenuto di una struttura di descrizione di identificazione in un'altra.
EvtChildListIdentificationDescriptionDuplicate, che crea una nuova descrizione di identificazione duplicando una struttura di descrizione di identificazione esistente e, se necessario, assegnando buffer aggiuntivi.
EvtChildListIdentificationDescriptionCleanup, che deallocate i buffer allocati dalla funzione evtChildListIdentificationDescriptionDuplicate callback.
In genere, sarà necessario fornire queste funzioni di callback se le strutture di descrizione di identificazione del driver contengono puntatori ai buffer allocati dinamicamente. Per altre informazioni sullo scopo di queste funzioni di callback, vedere le pagine di riferimento.
Descrizione indirizzo Una descrizione dell'indirizzo è una struttura che contiene informazioni che il driver richiede in modo che possa accedere al dispositivo nel suo bus, se le informazioni possono cambiare mentre il dispositivo è collegato. Il driver definisce questa struttura, ma il primo membro deve essere una struttura WDF_CHILD_ADDRESS_DESCRIPTION_HEADER .
Le descrizioni degli indirizzi sono facoltative. Se le informazioni sull'indirizzo di un dispositivo non possono cambiare tra il momento in cui il dispositivo è collegato e il momento in cui viene scollegato, tutte le informazioni sull'indirizzo del dispositivo possono essere archiviate in una descrizione di identificazione. Ad esempio, i controller USB assegnano indirizzi ai dispositivi quando i dispositivi sono collegati e questi indirizzi non cambiano.
D'altra parte, alcuni autobus usano informazioni di indirizzamento che possono cambiare. Ad esempio, il bus IEEE 1394 usa un "numero di generazione", ovvero il numero di reimpostazioni del bus che si sono verificate. Ogni richiesta di I/O asincrona a un dispositivo IEEE 1394 deve includere il conteggio della generazione. Poiché queste informazioni sull'indirizzo possono cambiare, il driver deve archiviarlo in una descrizione dell'indirizzo.
Il driver può fornire il set seguente di funzioni di callback per modificare le informazioni in una descrizione dell'indirizzo:
EvtChildListAddressDescriptionCopy, che copia il contenuto di una struttura di descrizione degli indirizzi in un altro.
EvtChildListAddressDescriptionDuplicate, che crea una nuova descrizione dell'indirizzo duplicando una struttura di descrizione degli indirizzi esistente e, se necessario, assegnando buffer aggiuntivi.
EvtChildListAddressDescriptionCleanup, che deallocate i buffer allocati dalla funzione evtChildListAddressDescriptionDuplicate callback.
In genere, sarà necessario fornire queste funzioni di callback se le strutture di descrizione degli indirizzi del driver contengono puntatori ai buffer allocati dinamicamente. Per altre informazioni sullo scopo di queste funzioni di callback, vedere le pagine di riferimento.
Aggiunta di dispositivi a un elenco figlio dinamico
Quando il framework chiama la funzione di callback EvtDriverDevice di un driver del bus, la funzione di callback deve chiamare WdfDeviceCreate per creare un oggetto FDO per il dispositivo padre, che in genere è un adattatore del bus. Per altre informazioni sulla creazione di un oggetto FDO, vedere Creazione di oggetti dispositivo in un driver di funzione. Il driver deve quindi enumerare gli elementi figlio del dispositivo padre e aggiungere gli elementi figlio a un elenco figlio.
Facoltativamente, il driver può chiamare WdfDeviceSetBusInformationForChildren per fornire al framework informazioni sul bus. In questo modo è consigliabile perché semplifica l'identificazione del bus da parte di dispositivi figlio e app.
Per aggiungere elementi figlio a un elenco figlio, il driver deve chiamare WdfChildListAddOrUpdateChildDescriptionAsPresent per ogni dispositivo figlio trovato. Questa chiamata informa il framework che un driver ha individuato un dispositivo figlio connesso a un dispositivo padre. Quando il driver chiama WdfChildListAddOrUpdateChildDescriptionAsPresent, fornisce una descrizione di identificazione e, facoltativamente, una descrizione dell'indirizzo.
Dopo che il driver chiama WdfChildListAddOrUpdateChildDescriptionAsPresent per segnalare un nuovo dispositivo, il framework informa la gestione PnP che il nuovo dispositivo esiste. Il gestore PnP compila quindi uno stack di dispositivi e uno stack di driver per il nuovo dispositivo. Come parte di questo processo, il framework chiama la funzione di callback evtChildListCreateDevice del driver del bus. Questa funzione di callback deve chiamare WdfDeviceCreate per creare un PDO per il nuovo dispositivo.
In genere, diversi dispositivi figlio sono connessi a un padre, quindi il driver del bus dovrà chiamare WdfChildListAddOrUpdateChildDescriptionAsPresent più volte. Il modo più efficiente per eseguire questa operazione è quanto segue:
Chiamare WdfChildListBeginScan.
Chiamare WdfChildListAddOrUpdateChildDescriptionAsPresent per ogni dispositivo figlio.
Chiamare WdfChildListEndScan.
Se si circonda l'enumerazione dinamica del driver con chiamate a WdfChildListBeginScan e WdfChildListEndScan, il framework archivia tutte le modifiche nell'elenco figlio e notifica al gestore PnP delle modifiche quando il driver chiama WdfChildListEndScan. In un secondo momento, il framework chiama la funzione di callback EvtChildListCreateDevice per ogni dispositivo nell'elenco figlio. Questa funzione di callback chiama WdfDeviceCreate per creare un PDO per ogni nuovo dispositivo.
Quando il driver chiama WdfChildListBeginScan, il framework contrassegna tutti i dispositivi segnalati in precedenza come non più presenti. Pertanto, il driver deve chiamare WdfChildListAddOrUpdateChildDescriptionAsPresent per tutti gli elementi figlio che il driver può rilevare, non solo i bambini appena individuati. Per aggiungere un singolo figlio a un elenco figlio, il driver può effettuare una singola chiamata a WdfChildListUpdateAllChildDescriptionsAsPresent senza prima chiamare WdfChildListBeginScan.
Aggiornamento di un elenco figlio dinamico
Esistono due modi comuni per aggiornare le informazioni in un elenco figlio dinamico:
Quando un dispositivo padre riceve un interruzione che indica l'arrivo o la rimozione di un figlio, la funzione di callback evtInterruptDpc del driver chiama WdfChildListAddOrUpdateChildEscriptionAsPresent se un dispositivo è stato collegato o WdfChildListUpdateChildEscriptionAsMissing se un dispositivo è stato scollegato.
Il driver può fornire una funzione di callback EvtChildListScanForChildren , che il framework chiama ogni volta che il dispositivo padre entra nello stato di lavoro (D0). Questa funzione di callback deve enumerare tutti i dispositivi figlio chiamando WdfChildListBeginScan, WdfChildListAddOrUpdateChildDescriptionAsPresent (o WdfChildListUpdateAllChildDescriptionsAsPresent) e WdfChildListEndScan.
È possibile usare una o entrambe queste tecniche nel driver.
Attraversamento di un elenco figlio dinamico
Se si vuole che il driver esamini il contenuto di un elenco figlio, può attraversare l'elenco usando una delle tecniche seguenti:
Per ottenere il contenuto di ogni descrizione del dispositivo figlio, uno alla volta, il driver può:
- Chiamare WdfChildListBeginIteration.
- Chiamare WdfChildListRetrieveNextDevice, quante volte necessario.
- Chiamare WdfChildListEndIteration.
Quando si chiama WdfChildListBeginIteration, il driver specifica un flag tipizzato WDF_RETRIEVE_CHILD_FLAGS che indica se il framework deve recuperare tutte le descrizioni dei dispositivi o solo un subset. Quando WdfChildListRetrieveNextDevice trova una corrispondenza, recupera l'identificazione e l'indirizzo del dispositivo figlio, oltre a un handle per l'oggetto dispositivo.
Se è necessario ottenere la descrizione dell'indirizzo attualmente contenuta in una descrizione del dispositivo figlio, il driver può chiamare WdfChildListRetrieveAddressDescription, specificando una descrizione di identificazione. Il framework attraversa l'elenco figlio finché non trova un dispositivo figlio con una descrizione di identificazione corrispondente e quindi recupera la descrizione dell'indirizzo.
Se è necessario ottenere un handle per l'oggetto dispositivo framework associato a un determinato dispositivo figlio, il driver può chiamare WdfChildListRetrievePdo. Il framework attraversa l'elenco figlio finché non trova un dispositivo figlio con una descrizione di identificazione corrispondente e quindi restituisce un handle oggetto dispositivo. Assicurarsi di eseguire il wrapping della chiamata con WdfChildListBeginIteration e WdfChildListEndIteration per proteggere il chiamante dalla rimozione improvvisa di PnP del PDO in un altro thread.
Accesso alle descrizioni di identificazione e indirizzo di un oggetto PDO
Il driver può chiamare i metodi seguenti per accedere alla descrizione o alla descrizione dell'indirizzo di un oggetto PDO:
WdfPdoRetrieveIdentificationDescription, che recupera la descrizione di identificazione associata a un oggetto PDO.
WdfPdoRetrieveAddressDescription, che recupera la descrizione dell'indirizzo associata a un oggetto PDO.
WdfPdoUpdateAddressDescription, che aggiorna la descrizione dell'indirizzo associata a un oggetto PDO.
Gestione delle richieste di rinumerazione
I driver bus basati su framework che supportano l'enumerazione dinamica possono ricevere una richiesta di riesenumerazione di un determinato dispositivo figlio tramite l'interfaccia REENUMERATE_SELF_INTERFACE_STANDARD . Per altre info, vedi Gestione delle richieste di enumerazione