IRP_MN_QUERY_INTERFACE

A solicitação IRP_MN_QUERY_INTERFACE permite que um driver exporte uma interface de chamada direta para outros drivers.

Um driver de barramento que exporta uma interface deve lidar com essa solicitação para seus dispositivos filho (PDOs filho). A função e o filtro podem, opcionalmente, lidar com essa solicitação.

Uma "interface" nesse contexto consiste em uma ou mais rotinas e, possivelmente, dados, exportados por um driver ou conjunto de drivers. Uma interface tem uma estrutura que descreve seu conteúdo e um GUID que identifica seu tipo.

Por exemplo, o driver de barramento PCMCIA exporta uma interface do tipo GUID_PCMCIA_INTERFACE_STANDARD que contém rotinas para operações como obter a condição de proteção de gravação de uma cartão de memória PCMCIA. O driver de função para esse cartão de memória pode enviar uma solicitação IRP_MN_QUERY_INTERFACE ao driver de barramento PCMCIA pai para obter ponteiros para as rotinas da interface PCMCIA.

Observação

Ao introduzir uma nova versão de uma interface existente, crie um novo GUID em vez de revisar os campos Tamanho ou Versão da estrutura interface . Para obter mais informações, consulte Usando interfaces Driver-Defined.

Esta seção descreve o IRP da interface de consulta como um mecanismo geral. Os drivers que expõem uma interface devem fornecer informações adicionais sobre sua interface específica.

Valor

0x08

Código principal

IRP_MJ_PNP

Quando enviado

Um driver ou componente do sistema envia esse IRP para obter informações sobre uma interface exportada por um driver para um dispositivo.

Um driver ou componente do sistema envia esse IRP em IRQL = PASSIVE_LEVEL em um contexto de thread arbitrário.

Um driver pode receber esse IRP a qualquer momento depois que a rotina AddDevice do driver tiver sido chamada para o dispositivo. O dispositivo pode ou não ser iniciado quando esse IRP é enviado (ou seja, você não pode assumir que o driver concluiu com êxito uma solicitação de IRP_MN_START_DEVICE para o dispositivo).

Parâmetros de Entrada

O membro Parameters.QueryInterface da estrutura IO_STACK_LOCATION é uma estrutura, que descreve a interface que está sendo solicitada. A estrutura contém as seguintes informações:

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

Os membros da estrutura são definidos da seguinte maneira:

Interfacetype
Aponta para um GUID que identifica a interface que está sendo solicitada. O GUID pode ser para uma interface definida pelo sistema, como GUID_BUS_INTERFACE_STANDARD ou uma interface personalizada. Os GUIDs para interfaces definidas pelo sistema são listados em Wdmguid.h. GuiDs para interfaces personalizadas devem ser gerados com Uuidgen.

Tamanho
Especifica o tamanho da interface que está sendo solicitada. Os drivers que lidam com esse IRP não devem retornar uma estrutura interface maior que bytes de tamanho .

Version
Especifica a versão da interface que está sendo solicitada.

Se um driver der suporte a mais de uma versão de uma interface, o driver retornará a versão mais próxima com suporte sem exceder a versão solicitada. O componente que enviou o IRP deve examinar o campo Interface.Version retornado e determinar o que fazer com base nesse valor.

Interface
Aponta para uma estrutura na qual retornar a interface solicitada. Essa estrutura deve conter uma estrutura INTERFACE como seu primeiro membro. O componente que envia o IRP aloca essa estrutura da memória paginada.

Um driver que exporta uma interface define um novo tipo de estrutura que contém a estrutura INTERFACE , além de membros para rotinas e/ou dados na interface. (O driver também define um GUID para a interface, conforme descrito no membro InterfaceType , acima.)

Um driver que exporta uma interface define o ambiente de execução para cada rotina na interface, incluindo o IRQL no qual a rotina pode ser chamada e assim por diante.

InterfaceSpecificData
Especifica informações adicionais sobre a interface que está sendo solicitada.

Para algumas interfaces, o componente que envia o IRP especifica informações adicionais nesse campo. Normalmente, esse campo é NULL e InterfaceType e Version são suficientes para identificar a interface que está sendo solicitada.

Parâmetros de saída

Em caso de êxito, um driver preenche os membros da estrutura Parameters.QueryInterface.Interface .

Bloco de Status de E/S

Um driver define Irp-IoStatus.Status> como STATUS_SUCCESS ou como um erro apropriado status.

Em caso de êxito, um motorista de ônibus define Irp-IoStatus.Information> como zero.

Se um driver de função ou filtro não manipular esse IRP, ele chamará IoSkipCurrentIrpStackLocation e passará o IRP para o próximo driver. Esse driver não deve modificar Irp-IoStatus.Status> e não deve concluir o IRP.

Se um motorista de ônibus não exportar a interface solicitada e, portanto, não manipular esse IRP para um PDO filho, o motorista do ônibus deixará Irp-IoStatus.Status> como está e concluirá o IRP.

Operação

Um driver manipulará esse IRP se os parâmetros especificarem uma interface à qual o driver dá suporte.

Um driver não deverá enfileirar esse IRP se o IRP solicitar uma interface à qual o driver não dá suporte. Um driver deve marcar Parameters.QueryInterface.InterfaceType em sua estrutura IO_STACK_LOCATION. Se a interface não for compatível com o driver, o driver deverá passar o IRP para o próximo driver inferior na pilha do dispositivo sem bloqueio.

Cada interface deve fornecer rotinas InterfaceReference e InterfaceDereference , e o driver que exporta a interface deve fornecer os endereços dessas rotinas na estrutura interface . Antes que um driver retorne uma interface em resposta ao IRP, ele deve incrementar a contagem de referência da interface chamando sua rotina InterfaceReference . Quando o driver que solicitou a interface terminar de usá-la, esse driver deverá diminuir a contagem de referência chamando a rotina InterfaceDereference da interface.

Se o driver que envia o IRP (driver x) posteriormente passar a interface para outro driver (driver y), o driver x deverá incrementar a contagem de referência da interface e o driver y deverá decrementá-la.

Um driver que manipula esse IRP deve evitar passar o IRP para outra pilha de dispositivos para obter a interface solicitada. Esse design criaria dependências entre as pilhas de dispositivos que são difíceis de gerenciar. Por exemplo, o dispositivo representado pela segunda pilha de dispositivos não pode ser removido até que o driver apropriado na primeira pilha desrefere a interface.

As interfaces podem ser específicas de ônibus ou independentes de ônibus. As interfaces específicas do barramento são definidas nos arquivos de cabeçalho para esses ônibus. O sistema define uma interface independente de barramento, BUS_INTERFACE_STANDARD, para exportar interfaces de barramento padrão.

Consulte Plug and Play para obter as regras gerais para lidar com Plug and Play IRPs menores.

Esse IRP é usado especificamente para passar pontos de entrada de rotina entre drivers de modo kernel em camadas para um dispositivo. Não confunda as interfaces expostas por esse IRP com interfaces de dispositivo. Uma interface do dispositivo é usada principalmente para expor um caminho a um dispositivo para uso por componentes do modo de usuário ou outros componentes do kernel. Para obter mais informações sobre interfaces de dispositivo, consulte Classes de interface do dispositivo.

Enviando este IRP

Consulte Manipulando IRPs para obter informações sobre como enviar IRPs. As seguintes etapas se aplicam especificamente a este IRP:

  • Aloque uma estrutura interface do pool paginado e inicialize-a para zeros. Se a interface for chamada em IRQL >= DISPATCH_LEVEL, com base no contrato de interface, o chamador poderá copiar o conteúdo para a memória alocada do pool nãopagado.

  • Defina os valores no próximo local da pilha de E/S do IRP: defina MajorFunctioncomo IRP_MJ_PNP, defina MinorFunctioncomo IRP_MN_QUERY_INTERFACE e defina os valores apropriados em Parameters.QueryInterface.

  • Inicialize IoStatus.Status para STATUS_NOT_SUPPORTED.

  • Desaloque o IRP e a estrutura interface quando eles não forem mais necessários.

  • Use as rotinas de interface e o parâmetro de contexto, conforme descrito na especificação da interface .

  • Decremente a contagem de referência usando a rotina InterfaceDereference quando a interface não for mais necessária. Não chame nenhuma rotina de interface depois de desreferenciar a interface.

Um driver normalmente envia esse IRP para a parte superior da pilha de dispositivos na qual o driver está anexado. Se um driver enviar esse IRP para uma pilha de dispositivos diferente, o driver deverá se registrar para notificação do dispositivo de destino no outro dispositivo se o outro dispositivo não for um ancestral do dispositivo que o driver está atendendo. Esse driver chama IoRegisterPlugPlayNotification com uma EventCategory de EventCategoryTargetDeviceChange. Quando o driver recebe uma notificação do tipo GUID_TARGET_DEVICE_QUERY_REMOVE, o driver deve desreferenciar a interface. O driver poderá solicitar a interface se receber uma notificação de GUID_TARGET_DEVICE_REMOVE_CANCELLED subsequente.

Requisitos

parâmetro

Wdm.h (inclua Wdm.h, Ntddk.h ou Ntifs.h)

Confira também

BUS_INTERFACE_STANDARD

INTERFACE

IoRegisterPlugPlayNotification