Uso delle pipe USB nei driver UMDF 1.x
Avviso
UMDF 2 è la versione più recente di UMDF e sostituisce UMDF 1. Tutti i nuovi driver UMDF devono essere scritti usando UMDF 2. Non vengono aggiunte nuove funzionalità a UMDF 1 ed è disponibile un supporto limitato per UMDF 1 nelle versioni più recenti di Windows 10. I driver di Windows universali devono usare UMDF 2.
Gli esempi di UMDF 1 archiviati sono disponibili nell'aggiornamento degli esempi di driver di Windows 11 versione 22H2 - Maggio 2022.
Per altre info, vedi Introduzione con UMDF.
Il framework rappresenta ogni pipe in un'interfaccia USB come oggetto pipe USB del framework. Quando un driver configura un dispositivo USB, il framework crea un oggetto pipe USB framework per ogni pipe in ogni interfaccia selezionata. I metodi dell'oggetto pipe consentono a un driver di:
Dopo che un driver UMDF chiama il metodo IWDFUsbInterface::RetrieveUsbPipeObject per ottenere un puntatore all'interfaccia IWDFUsbTargetPipe per un oggetto pipe USB, il driver può chiamare i metodi seguenti definiti dall'oggetto pipe USB per ottenere informazioni sulla pipe USB:
IWDFUsbTargetPipe::GetInformation
Recupera informazioni su una pipe USB e il relativo endpoint.
IWDFUsbTargetPipe::GetType
Restituisce il tipo di una pipe USB.
IWDFUsbTargetPipe::IsInEndPoint
Determina se una pipe USB è connessa a un endpoint di input.
IWDFUsbTargetPipe::IsOutEndPoint
Determina se una pipe USB è connessa a un endpoint di output.
IWDFUsbTargetPipe::RetrievePipePolicy
Recupera un criterio di pipe WinUsb.
Per leggere i dati da una pipe di input USB, il driver può usare entrambe le tecniche seguenti:
Legge i dati in modo sincrono.
Per leggere i dati in modo sincrono da una pipe di input USB, un driver UMDF chiama innanzitutto il metodo IWDFIoTarget::FormatRequestForRead per compilare una richiesta di lettura. Il driver chiama quindi il metodo IWDFIoRequest::Send , specificando il flag WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, per inviare la richiesta in modo sincrono.
Legge i dati in modo asincrono.
Per leggere i dati in modo asincrono da una pipe di input USB, un driver UMDF chiama innanzitutto il metodo IWDFIoTarget::FormatRequestForRead per compilare una richiesta di lettura. Il driver chiama quindi il metodo IWDFIoRequest::Send senza specificare il flag WDF_REQUEST_SEND_OPTION_SYNCHRONOUS.
Legge i dati in modo sincrono e continuo.
Un lettore continuo è un meccanismo fornito dal framework che garantisce che una richiesta di lettura sia sempre disponibile per una pipe USB. Questo meccanismo garantisce che il driver sia sempre pronto a ricevere dati da un dispositivo che fornisce un flusso di input asincrono e non richiesto. Ad esempio, un driver per una scheda di interfaccia di rete (NIC) può usare un lettore continuo per ricevere i dati di input.
Per configurare un lettore continuo per una pipe di input, la funzione di callback IPnpCallbackHardware::OnPrepareHardware deve chiamare il metodo IWDFUsbTargetPipe2::ConfigureContinuousReader . Questo metodo accoda un set di richieste di lettura alla destinazione di I/O del dispositivo.
Inoltre, la funzione di callback IPnpCallback::OnD0Entry del driver deve chiamare IWDFIoTargetStateManagement::Start per avviare il lettore continuo e la funzione di callback IPnpCallback::OnD0Exit deve chiamare IWDFIoTargetStateManagement::Stop per arrestare il lettore continuo.
Ogni volta che i dati sono disponibili dal dispositivo, la destinazione di I/O completerà una richiesta di lettura e il framework chiamerà una delle due funzioni di callback : IUsbTargetPipeContinuousReaderCallbackReadComplete::OnReaderCompletion se la destinazione di I/O legge correttamente i dati o IUsbTargetPipeContinuousReaderCallbackReadersFailed::OnReaderFailure se la destinazione di I/O segnala un errore.
Dopo che un driver ha chiamato IWDFUsbTargetPipe2::ConfigureContinuousReader, il driver non può usare IWDFIoRequest::Send per inviare richieste di I/O alla pipe a meno che la funzione di callback IUsbTargetPipeContinuousReaderCallbackReadersFailed::OnReaderFailure venga chiamata e restituisce FALSE.
I lettori continui sono supportati nelle versioni UMDF 1.9 e successive.
Per scrivere dati in una pipe di output USB, un driver UMDF può prima chiamare il metodo IWDFIoTarget::FormatRequestForWrite per compilare una richiesta di scrittura. Il driver può quindi chiamare il metodo IWDFIoRequest::Send per inviare la richiesta in modo asincrono.
Un driver UMDF può chiamare i metodi seguenti per arrestare, scaricare o reimpostare una pipe USB:
IWDFUsbTargetPipe::Abort
Invia in modo sincrono una richiesta per arrestare tutti i trasferimenti in sospeso su una pipe USB.
IWDFUsbTargetPipe::Flush
Invia in modo sincrono una richiesta di eliminare i dati salvati da WinUsb quando il dispositivo ha restituito più dati rispetto al client richiesto.
IWDFUsbTargetPipe::Reset
Invia in modo sincrono una richiesta per reimpostare una pipe USB.
Un driver UMDF può chiamare il metodo IWDFUsbTargetPipe::SetPipePolicy per controllare il comportamento usato da WinUsb per una pipe USB (ad esempio timeout, gestione di pacchetti brevi e altri comportamenti).
Se la destinazione USB del driver completa una richiesta di I/O con un valore di stato di errore, il driver deve eseguire le operazioni seguenti:
Chiamare IWDFIoTargetStateManagement::Stop con il flag WdfIoTargetCancelSentIo impostato. Questa chiamata arresta la pipe e annulla eventuali richieste di I/O aggiuntive inviate dal driver alla destinazione USB, se la destinazione non ha completato le richieste.
Chiamare IWDFUsbTargetPipe::Abort per inviare una richiesta di interruzione alla pipe.
Chiamare IWDFUsbTargetPipe::Reset per inviare una richiesta di reimpostazione alla pipe.
Chiamare IWDFIoTargetStateManagement::Start per riavviare la pipe.
Inviare nuovamente la richiesta di I/O non riuscita e tutte le richieste di I/O che hanno seguito la richiesta non riuscita.