Supporto dei contesti dei clienti

Un driver WPD (Windows Portable Devices) fornisce il canale di comunicazione tra le applicazioni e il dispositivo fisico. Possono essere in esecuzione più applicazioni WPD in qualsiasi momento. Il driver deve gestire le richieste provenienti da client diversi nel computer e identificare i client in base alle richieste in coda. In altre parole, il driver richiede un modo efficiente e semplice per archiviare i dati client in base alla connessione e recuperare i dati su richiesta.

La User-Mode Driver Frameork (UMDF) supporta questa funzionalità usando un'area di contesto: un meccanismo generico in cui un driver salva i dati client. Un driver WPD deve allocare una struttura di dati o un oggetto per contenere i dati client, assegnare la struttura dei dati all'area di contesto per l'oggetto framework e recuperare il contesto in un secondo momento.

L'oggetto framework WDF appropriato per ogni connessione da usare è l'oggetto file WDF.

Assegnazione del contesto

Il driver assegna il contesto quando il computer client apre una connessione nei suoi confronti.

Quando un'applicazione WPD chiama il metodo IPortableDevice::Open o IPortableDeviceService::Open , l'API WPD crea un handle per il driver usando il metodo CreateFile Win32 . Sul lato driver, User-Mode Driver Frameork (UMDF) inizializza un oggetto IWDFFile e lo inoltra, insieme alla richiesta di creazione, al metodo IQueueCallbackCreate::OnCreateFile del driver. L'oggetto IWDFFile in questo caso rappresenta un HANDLE Win32 utilizzato per la successiva comunicazione da questo client al driver.

È possibile trovare un esempio di implementazione del callback CreateFile nel metodo CQueue::OnCreateFile di WpdWudfSampleDriver. Un oggetto COM ContextMap specifico del driver viene usato per archiviare i dati client (nome dell'applicazione, versione, enumerazione in corso e contesti di risorse e così via). Tenere presente che l'uso di oggetti COM come dati di contesto non è richiesto da UMDF; UMDF vede i dati di contesto come PVOID. Se si utilizza un oggetto COM per archiviare i dati di contesto, il driver deve mantenere il conteggio dei riferimenti per tale oggetto COM e assicurarsi che le relative risorse vengano liberate nei metodi di pulizia appropriati.

Per salvare i dati di contesto, il driver inizializza un nuovo oggetto ContextMap e chiama il metodo IWDFObject::AssignContext per l'oggetto IWDFFile passato da UMDF. I parametri per questo metodo sono puntatori a un oggetto IObjectCleanup e a ContextMap appena creato. L'oggetto IObjectCleanup contiene il codice di pulizia del contesto; la mappa appena creata contiene i dati archiviati. Il driver chiama il metodo IObjectCleanup::OnCleanup quando l'oggetto file viene eliminato definitivamente durante CloseHandle.

Inoltre, è possibile assegnare un solo contesto all'oggetto file (o a qualsiasi oggetto framework UMDF). Le chiamate successive al metodo AssignContext hanno esito negativo se è già stato assegnato un contesto. Per aggiungere o rimuovere dati specifici del client in modo dinamico, un driver può implementare un oggetto mapping per gestire i dati e assegnare un puntatore a tale oggetto come contesto dell'oggetto file. Per un esempio, fare riferimento all'oggetto ContextMap di WpdWudfSampleDriver.

Recupero e salvataggio dei dati del contesto

Per accedere ai dati del client durante le richieste, un driver WPD recupera il contesto dall'oggetto IWDFFile specificato.

La sequenza di recupero viene eseguita completando i passaggi seguenti:

  1. Il driver chiama il metodo IWDFIoRequest::GetFileObject per ottenere l'oggetto IWDFFile .
  2. Il driver chiama il metodo IWDFObject::RetrieveContext sull'oggetto IWDFFile per accedere all'area di contesto. Nel driver di esempio l'area di contesto è il puntatore all'oggetto ContextMap creato in CQueue::OnCreateFile quando l'applicazione ha chiamato IPortableDevice::Open.
  3. Il driver aggiunge dati o rimuove i dati dall'oggetto ContextMap direttamente quando elabora i comandi WPD. Ogni volta che un'applicazione si connette chiamando IPortableDevice::Open, avrà i propri oggetti IWDFFile e ContextMap.

Fare riferimento al codice di WpdWudfSampleDriver per esempi di come recuperare le mappe del contesto e aggiungere informazioni client. La tabella seguente descrive dove è possibile trovare il codice in WpdWudfSampleDriver.

Esempio Percorso nel driver di esempio
Recupero della mappa di contesto dall'oggetto file per la richiesta WDF. CQueue::OnDeviceIoControl
Aggiunta di informazioni sul cliente alla mappa del contesto durante l'elaborazione del comando WPD_COMMAND_COMMON_SAVE_CLIENT_INFORMATION WpdBaseDriver::OnSaveClientInfo

Rilascio del contesto

Quando l'applicazione client chiama il metodo IPortableDevice::Close , l'API WPD chiama a sua volta CloseHandle sull'handle Win32 associato alla connessione aperta. Prima che UMDF elimini definitivamente l'oggetto IWDFFile in risposta a CloseHandle, chiama il metodo IObjectCleanup::OnCleanup dell'oggetto file passato dal driver in AssignContext durante OnCreateFile.

Un'implementazione di esempio del callback IQueueCleanup è il metodo CQueue::OnCleanup del driver WpdWudfSampleDriver. Questo metodo recupera l'oggetto ContextMap archiviato nell'oggetto IWDFObject (in questo caso l'istanza di IWDFFile da OnCreateFile) e libera la memoria allocata, inclusi gli oggetti contenuti in ContextMap. Per evitare perdite di memoria, assicurarsi che gli oggetti siano correttamente puliti e,se applicabile, decrementare il conteggio dei riferimenti.


Gli esempi di piloti WPD