IRP_MN_QUERY_INTERFACE
La solicitud de IRP_MN_QUERY_INTERFACE permite a un controlador exportar una interfaz de llamada directa a otros controladores.
Un controlador de bus que exporte una interfaz debe controlar esta solicitud para sus dispositivos secundarios (PPO secundarios). La función y el filtro pueden controlar opcionalmente esta solicitud.
Una "interfaz" en este contexto consta de una o varias rutinas, y posiblemente datos, exportados por un controlador o un conjunto de controladores. Una interfaz tiene una estructura que describe su contenido y un GUID que identifica su tipo.
Por ejemplo, el controlador de bus PCMCIA exporta una interfaz de tipo GUID_PCMCIA_INTERFACE_STANDARD que contiene rutinas para operaciones como obtener la condición de protección de escritura de una tarjeta de memoria PCMCIA. El controlador de función para esta tarjeta de memoria puede enviar una solicitud de IRP_MN_QUERY_INTERFACE al controlador de bus PCMCIA primario para obtener punteros a las rutinas de la interfaz PCMCIA.
Nota:
Al introducir una nueva versión de una interfaz existente, cree un NUEVO GUID en lugar de revisar los campos Tamaño o Versión de la estructura INTERFACE . Para obtener más información, consulta Uso de interfaces de Driver-Defined.
En esta sección se describe el IRP de interfaz de consulta como mecanismo general. Los controladores que exponen una interfaz deben proporcionar información adicional sobre su interfaz específica.
Value
0x08
Código principal
Cuándo se envió
Un controlador o componente del sistema envía este IRP para obtener información sobre una interfaz exportada por un controlador para un dispositivo.
Un controlador o componente del sistema envía este IRP en IRQL = PASSIVE_LEVEL en un contexto de subproceso arbitrario.
Un controlador puede recibir este IRP en cualquier momento después de que se haya llamado a la rutina AddDevice del controlador para el dispositivo. Es posible que el dispositivo se inicie o no cuando se envíe este IRP (es decir, no se puede suponer que el controlador ha completado correctamente una solicitud de IRP_MN_START_DEVICE para el dispositivo).
Parámetros de entrada
El miembro Parameters.QueryInterface de la estructura IO_STACK_LOCATION es en sí misma una estructura, que describe la interfaz que se solicita. La estructura contiene la siguiente información:
CONST GUID *InterfaceType;
USHORT Size;
USHORT Version;
PINTERFACE Interface;
PVOID InterfaceSpecificData
Los miembros de la estructura se definen de la siguiente manera:
InterfaceType
Apunta a un GUID que identifica la interfaz que se solicita. El GUID puede ser para una interfaz definida por el sistema, como GUID_BUS_INTERFACE_STANDARD o una interfaz personalizada. Los GUID de las interfaces definidas por el sistema se enumeran en Wdmguid.h. Los GUID para interfaces personalizadas deben generarse con Uuidgen.
Tamaño
Especifica el tamaño de la interfaz que se solicita. Los controladores que controlan este IRP no deben devolver una estructura INTERFACE mayor que los bytes size .
Versión
Especifica la versión de la interfaz que se solicita.
Si un controlador admite más de una versión de una interfaz, el controlador devuelve la versión admitida más cercana sin superar la versión solicitada. El componente que envió el IRP debe examinar el campo Interface.Version devuelto y determinar qué hacer en función de ese valor.
Interface
Apunta a una estructura en la que se va a devolver la interfaz solicitada. Esta estructura debe contener una estructura INTERFACE como su primer miembro. El componente que envía el IRP asigna esta estructura de la memoria paginada.
Un controlador que exporta una interfaz define un nuevo tipo de estructura que contiene la estructura INTERFACE , además de miembros para rutinas o datos en la interfaz. (El controlador también define un GUID para la interfaz, como se describe en el miembro InterfaceType , arriba).
Un controlador que exporta una interfaz define el entorno de ejecución para cada rutina de la interfaz, incluido el IRQL en el que se puede llamar a la rutina, etc.
InterfaceSpecificData
Especifica información adicional sobre la interfaz que se solicita.
Para algunas interfaces, el componente que envía el IRP especifica información adicional en este campo. Normalmente, este campo es NULL y interfaceType y Version son suficientes para identificar la interfaz que se solicita.
Parámetros de salida
Si se ejecuta correctamente, un controlador rellena los miembros de la estructura Parameters.QueryInterface.Interface .
Bloque de estado de entrada/salida
Un controlador establece Irp-IoStatus.Status> en STATUS_SUCCESS o en un estado de error adecuado.
Si se ejecuta correctamente, un controlador de autobús establece Irp-IoStatus.Information> en cero.
Si una función o un controlador de filtro no controla este IRP, llama a IoSkipCurrentIrpStackLocation y pasa el IRP al siguiente controlador. Este controlador no debe modificar Irp-IoStatus.Status> y no debe completar el IRP.
Si un controlador de bus no exporta la interfaz solicitada y, por lo tanto, no controla este IRP para un PDO secundario, el controlador de bus deja Irp-IoStatus.Status> tal como está y completa el IRP.
Operación
Un controlador controla este IRP si los parámetros especifican una interfaz que admite el controlador.
Un controlador no debe poner en cola este IRP si el IRP solicita una interfaz que el controlador no admite. Un controlador debe comprobar Parameters.QueryInterface.InterfaceType en su estructura IO_STACK_LOCATION . Si la interfaz no es compatible con el controlador, el controlador debe pasar el IRP al siguiente controlador inferior de la pila de dispositivos sin bloquear.
Cada interfaz debe proporcionar rutinas InterfaceReference e InterfaceDereference , y el controlador que exporta la interfaz debe proporcionar las direcciones de estas rutinas en la estructura INTERFACE . Antes de que un controlador devuelva una interfaz en respuesta al IRP, debe incrementar el recuento de referencias de la interfaz llamando a su rutina InterfaceReference . Cuando el controlador que solicitó la interfaz ha terminado de usarlo, ese controlador debe disminuir el recuento de referencias llamando a la rutina InterfaceDereference de la interfaz.
Si el controlador que envía el IRP (driver x) pasa la interfaz a otro controlador (driver y), el controlador x debe incrementar el número de referencias de la interfaz y el controlador y debe disminuirla.
Un controlador que controle este IRP debe evitar pasar el IRP a otra pila de dispositivos para obtener la interfaz solicitada. Este diseño crearía dependencias entre las pilas de dispositivos que son difíciles de administrar. Por ejemplo, el dispositivo representado por la segunda pila de dispositivos no se puede quitar hasta que el controlador adecuado de la primera pila desreferencia la interfaz.
Las interfaces pueden ser específicas de bus o independientes del bus. Las interfaces específicas del bus se definen en los archivos de encabezado de esos buses. El sistema define una interfaz independiente del bus, BUS_INTERFACE_STANDARD, para exportar interfaces de bus estándar.
Consulte Plug and Play para conocer las reglas generales para controlar Plug and Play IRP menores.
Este IRP se usa específicamente para pasar puntos de entrada rutinarios entre controladores en modo kernel superpuestas para un dispositivo. No confunda las interfaces expuestas por este IRP con interfaces de dispositivo. Una interfaz de dispositivo se usa principalmente para exponer una ruta de acceso a un dispositivo para que lo usen los componentes en modo de usuario u otros componentes del kernel. Para obtener más información sobre las interfaces de dispositivo, consulte Clases de interfaz de dispositivo.
Envío de este IRP
Consulte Control de IRP para obtener información sobre el envío de IRP. Los pasos siguientes se aplican específicamente a este IRP:
Asigne una estructura INTERFACE del grupo paginado e inicialícela en ceros. Si se llamará a la interfaz en IRQL >= DISPATCH_LEVEL, en función del contrato de interfaz, el autor de la llamada puede copiar el contenido en la memoria asignada desde un grupo no paginado.
Establezca los valores en la siguiente ubicación de pila de E/S del IRP: establezca MajorFunction en IRP_MJ_PNP, establezca MinorFunction en IRP_MN_QUERY_INTERFACE y establezca los valores adecuados en Parameters.QueryInterface.
Inicialice IoStatus.Status en STATUS_NOT_SUPPORTED.
Desasigne el IRP y la estructura INTERFACE cuando ya no sean necesarios.
Use las rutinas de interfaz y el parámetro de contexto como se describe en la especificación de la interfaz.
Reduzca el recuento de referencias mediante la rutina InterfaceDereference cuando la interfaz ya no sea necesaria. No llame a ninguna rutina de interfaz después de desreferenciar la interfaz.
Normalmente, un controlador envía este IRP a la parte superior de la pila de dispositivos en la que está conectado el controlador. Si un controlador envía este IRP a una pila de dispositivos diferente, el controlador debe registrarse para la notificación de dispositivo de destino en el otro dispositivo si el otro dispositivo no es un antecesor del dispositivo que el controlador está atendiendo. Este controlador llama a IoRegisterPlugPlayNotification con eventCategory de EventCategoryTargetDeviceChange. Cuando el controlador recibe una notificación de tipo GUID_TARGET_DEVICE_QUERY_REMOVE, el controlador debe desreferenciar la interfaz. El controlador puede volver a consultar la interfaz si recibe una notificación de GUID_TARGET_DEVICE_REMOVE_CANCELLED posterior.
Requisitos
Encabezado |
Wdm.h (incluya Wdm.h, Ntddk.h o Ntifs.h) |