Condividi tramite


IRP_MN_QUERY_INTERFACE

La richiesta di IRP_MN_QUERY_INTERFACE consente a un driver di esportare un'interfaccia di chiamata diretta ad altri driver.

Un driver del bus che esporta un'interfaccia deve gestire questa richiesta per i relativi dispositivi figlio (PDO figlio). La funzione e il filtro possono gestire facoltativamente questa richiesta.

Un 'interfaccia' in questo contesto è costituito da una o più routine, e possibilmente dati, esportati da un driver o da un set di driver. Un'interfaccia ha una struttura che descrive il relativo contenuto e un GUID che identifica il relativo tipo.

Ad esempio, il driver del bus PCMCIA esporta un'interfaccia di tipo GUID_PCMCIA_INTERFACE_STANDARD che contiene routine per le operazioni, ad esempio ottenere la condizione di protezione in scrittura di una scheda di memoria PCMCIA. Il driver di funzione per tale scheda di memoria può inviare una richiesta di IRP_MN_QUERY_INTERFACE al driver del bus PCMCIA padre per ottenere puntatori alle routine di interfaccia PCMCIA.

Nota

Quando si introduce una nuova versione di un'interfaccia esistente, creare un nuovo GUID anziché rivedere i campi Size o Version della struttura INTERFACE . Per altre informazioni, vedere Uso di interfacce Driver-Defined.

Questa sezione descrive l'IRP dell'interfaccia di query come meccanismo generale. I driver che espongono un'interfaccia devono fornire informazioni aggiuntive sull'interfaccia specifica.

Valore

0x08

Codice principale

IRP_MJ_PNP

Data di invio

Un driver o un componente di sistema invia questo IRP per ottenere informazioni su un'interfaccia esportata da un driver per un dispositivo.

Un driver o un componente di sistema invia questo IRP in IRQL = PASSIVE_LEVEL in un contesto di thread arbitrario.

Un driver può ricevere l'IRP in qualsiasi momento dopo che la routine AddDevice del driver è stata chiamata per il dispositivo. Il dispositivo potrebbe o non essere avviato quando viene inviato l'IRP, ovvero non è possibile presupporre che il driver abbia completato correttamente una richiesta di IRP_MN_START_DEVICE per il dispositivo.

Parametri di input

Il membro Parameters.QueryInterface della struttura IO_STACK_LOCATION è una struttura, che descrive l'interfaccia richiesta. La struttura contiene le informazioni seguenti:

CONST GUID *InterfaceType;
USHORT Size;
USHORT Version;
PINTERFACE Interface;
PVOID InterfaceSpecificData

I membri della struttura sono definiti come segue:

Interfacetype
Punta a un GUID che identifica l'interfaccia richiesta. Il GUID può essere per un'interfaccia definita dal sistema, ad esempio GUID_BUS_INTERFACE_STANDARD o un'interfaccia personalizzata. I GUID per le interfacce definite dal sistema sono elencati in Wdmguid.h. I GUID per le interfacce personalizzate devono essere generati con Uuidgen.

Dimensione
Specifica le dimensioni dell'interfaccia richiesta. I driver che gestiscono questo IRP non devono restituire una struttura INTERFACE più grande di byte di dimensioni .

Versione
Specifica la versione dell'interfaccia richiesta.

Se un driver supporta più versioni di un'interfaccia, il driver restituisce la versione più vicina supportata senza superare la versione richiesta. Il componente che ha inviato l'IRP deve esaminare il campo Interface.Version restituito e determinare cosa fare in base a tale valore.

Interfaccia
Punta a una struttura in cui restituire l'interfaccia richiesta. Questa struttura deve contenere una struttura INTERFACE come primo membro. Il componente che invia l'IRP alloca questa struttura dalla memoria paginata.

Un driver che esporta un'interfaccia definisce un nuovo tipo di struttura contenente la struttura INTERFACE , oltre ai membri per routine e/o dati nell'interfaccia. Il driver definisce anche un GUID per l'interfaccia, come descritto nel membro InterfaceType , sopra.

Un driver che esporta un'interfaccia definisce l'ambiente di esecuzione per ogni routine nell'interfaccia, incluso irQL in corrispondenza del quale è possibile chiamare la routine e così via.

InterfaceSpecificData
Specifica informazioni aggiuntive sull'interfaccia richiesta.

Per alcune interfacce, il componente che invia l'IRP specifica informazioni aggiuntive in questo campo. In genere, questo campo è NULL e InterfaceType e Version sono sufficienti per identificare l'interfaccia richiesta.

Parametri di output

Al termine dell'operazione, un driver inserisce i membri della struttura Parameters.QueryInterface.Interface .

Blocco dello stato I/O

Un driver imposta Irp-IoStatus.Status> su STATUS_SUCCESS o su uno stato di errore appropriato.

In caso di esito positivo, un driver del bus imposta Irp-IoStatus.Information> su zero.

Se un driver di funzione o filtro non gestisce questa IRP, chiama IoSkipCurrentIrpStackLocation e passa l'IRP fino al driver successivo. Tale driver non deve modificare Irp-IoStatus.Status> e non deve completare l'IRP.

Se un driver del bus non esporta l'interfaccia richiesta e pertanto non gestisce questo IRP per un pdO figlio, il driver del bus lascia Irp-IoStatus.Status> così come è e completa l'IRP.

Operazione

Un driver gestisce questa IRP se i parametri specificano un'interfaccia supportata dal driver.

Se l'IRP richiede un'interfaccia non supportata dal driver, un driver non deve accodarsi a questo tipo di IRP. Un driver deve controllare Parameters.QueryInterface.InterfaceType nella relativa struttura IO_STACK_LOCATION . Se l'interfaccia non è un driver supportato, il driver deve passare l'IRP al driver inferiore successivo nello stack di dispositivi senza bloccare.

Ogni interfaccia deve fornire routine InterfaceReference e InterfaceDereference e il driver che esporta l'interfaccia deve fornire gli indirizzi di queste routine nella struttura INTERFACE . Prima che un driver restituisca un'interfaccia in risposta all'IRP, deve aumentare il conteggio dei riferimenti dell'interfaccia chiamando la routine InterfaceReference . Al termine dell'uso dell'interfaccia, il driver deve decrerere il conteggio dei riferimenti chiamando la routine InterfaceDereference dell'interfaccia.

Se il driver che invia l'IRP (driver x) in un secondo momento passa l'interfaccia a un altro driver (driver y), driver x deve aumentare il conteggio dei riferimenti dell'interfaccia e il driver y deve decrementarlo.

Un driver che gestisce questo IRP deve evitare di passare l'IRP a un altro stack di dispositivi per ottenere l'interfaccia richiesta. Tale progettazione creerebbe dipendenze tra gli stack di dispositivi difficili da gestire. Ad esempio, il dispositivo rappresentato dal secondo stack di dispositivi non può essere rimosso finché il driver appropriato nel primo stack dereferenzia l'interfaccia.

Le interfacce possono essere specifiche del bus o indipendenti dal bus. Le interfacce specifiche del bus sono definite nei file di intestazione per tali bus. Il sistema definisce un'interfaccia indipendente dal bus, BUS_INTERFACE_STANDARD, per l'esportazione di interfacce bus standard.

Vedere Plug and Play per le regole generali per la gestione degli IRP secondari Plug and Play.

Questo IRP viene usato in modo specifico per passare punti di ingresso di routine tra i driver in modalità kernel a livelli per un dispositivo. Non confondere le interfacce esposte da questa IRP con le interfacce del dispositivo. Un'interfaccia del dispositivo viene usata principalmente per esporre un percorso a un dispositivo da usare dai componenti in modalità utente o da altri componenti del kernel. Per altre informazioni sulle interfacce del dispositivo, vedere Classi di interfaccia dispositivo.

Invio di questo IRP

Per informazioni sull'invio di IRP, vedere Gestione degli INDIRIZZI DI accesso. I passaggi seguenti si applicano in modo specifico a questo IRP:

  • Allocare una struttura INTERFACE dal pool impaginato e inizializzarla a zero. Se l'interfaccia verrà chiamata in IRQL >= DISPATCH_LEVEL, in base al contratto di interfaccia, il chiamante può copiare il contenuto in memoria allocato dal pool non a pagina.

  • Impostare i valori nella posizione successiva dello stack di I/O dell'IRP: impostare MajorFunction su IRP_MJ_PNP, impostare MinorFunction su IRP_MN_QUERY_INTERFACE e impostare i valori appropriati in Parameters.QueryInterface.

  • Inizializzare IoStatus.Status per STATUS_NOT_SUPPORTED.

  • Deallocare l'IRP e la struttura INTERFACE quando non sono più necessari.

  • Usare le routine di interfaccia e il parametro di contesto, come descritto nella specifica per l'interfaccia.

  • Decrementare il conteggio dei riferimenti usando la routine InterfaceDereference quando l'interfaccia non è più necessaria. Non chiamare routine di interfaccia dopo la dereferenza dell'interfaccia.

Un driver invia in genere l'IRP all'inizio dello stack di dispositivi in cui è collegato il driver. Se un driver invia questo IRP a uno stack di dispositivi diverso, il driver deve registrare per la notifica del dispositivo di destinazione nell'altro dispositivo se l'altro dispositivo non è un predecessore del dispositivo che il driver sta manutenzione. Tale driver chiama IoRegisterPlugPlayNotification con un EventCategory di EventCategoryTargetDeviceChange. Quando il driver riceve una notifica di tipo GUID_TARGET_DEVICE_QUERY_REMOVE, il driver deve dereferenziare l'interfaccia. Il driver può eseguire nuovamente laquery per l'interfaccia se riceve una notifica successiva GUID_TARGET_DEVICE_REMOVE_CANCELLED.

Requisiti

Intestazione

Wdm.h (include Wdm.h, Ntddk.h o Ntifs.h)

Vedi anche

BUS_INTERFACE_STANDARD

INTERFACCIA

IoRegisterPlugPlayNotification