Envío de IRP a colas de E/S
[Se aplica a KMDF y UMDF]
Un controlador basado en marcos puede especificar dinámicamente una cola de destino para un IRP entrante. Para enviar un IRP a una cola específica, un controlador debe llamar al método WdfDeviceWdmDispatchIrpToIoQueue .
Normalmente, un controlador llama a WdfDeviceWdmDispatchIrpToIoQueue desde su función de devolución de llamada EvtDeviceWdmIrpPreprocess o EvtDeviceWdmIrpDispatch . Para obtener el mejor rendimiento, la mayoría de los controladores no proporcionan ambas funciones de devolución de llamada.
Nota Un controlador UMDF puede proporcionar una función de devolución de llamada EvtDeviceWdmIrpDispatch , pero solo los controladores KMDF pueden proporcionar EvtDeviceWdmIrpPreprocess.
Si el controlador ya proporciona EvtDeviceWdmIrpPreprocess, puede usarlo para seleccionar dinámicamente una cola. Si no es así, proporcione EvtDeviceWdmIrpDispatch y llame a WdfDeviceWdmDispatchIrpToIoQueue desde dentro de esa función de devolución de llamada.
Además, debe tener en cuenta lo siguiente:
Un método alternativo para enviar un IRP a una cola de E/S es crear una cola predeterminada y, a continuación, desde el controlador de la cola, llame a WdfRequestForwardToIoQueue. Esta técnica está disponible a partir de KMDF 1.0, pero no funciona bien con las colas de progreso hacia delante y está en general más lenta. Considere la posibilidad de usar WdfDeviceWdmDispatchIrpToIoQueue en su lugar.
Al llamar a WdfDeviceConfigureWdmIrpDispatchCallback para registrar una función de devolución de llamada EvtDeviceWdmIrpDispatch , el controlador debe establecer el parámetro MajorFunction en uno de los siguientes: IRP_MJ_DEVICE_CONTROL, IRP_MJ_INTERNAL_DEVICE_CONTROL, IRP_MJ_READ, IRP_MJ_WRITE. Aunque este requisito no se aplica a EvtDeviceWdmIrpPreprocess, solo los IRP de estos tipos se pueden enviar dinámicamente a las colas especificadas.
Las IRP que van a EvtDeviceWdmIrpPreprocess tienen una ubicación de pila adicional. Los IRP que van a EvtDeviceWdmIrpDispatch (sin una invocación anterior de EvtDeviceWdmIrpPreprocess) no lo hacen.
EvtDeviceWdmIrpPreprocess no facilita el envío de información de contexto definida por el controlador, mientras que EvtDeviceWdmIrpDispatch sí.
Envío de IRP no preprocesados
Para enviar IRP desde la función de devolución de llamada EvtDeviceWdmIrpDispatch de un controlador, use el procedimiento siguiente:
Desde su función de devolución de llamada EvtDriverDeviceAdd , el controlador llama a WdfDeviceConfigureWdmIrpDispatchCallback para registrar una función de devolución de llamada EvtDeviceWdmIrpDispatch .
Si el destino es la cola de E/S del dispositivo primario, un controlador KMDF debe llamar a WdfPdoInitAllowForwardingRequestToParent antes de llamar a WdfDeviceCreate. Si un controlador KMDF también ha proporcionado una función de devolución de llamada EvtDeviceWdmIrpPreprocess , el marco llama a esa función primero cuando llega un IRP. Una vez que la función de devolución de llamada preprocesa la solicitud, llama a WdfDeviceWdmDispatchPreprocessedIrp para devolver el IRP al marco.
El marco llama a la función de devolución de llamada EvtDeviceWdmIrpDispatch del controlador.
Desde EvtDeviceWdmIrpDispatch, el controlador puede llamar a WdfDeviceWdmDispatchIrpToIoQueue o WdfDeviceWdmDispatchIrp, pero no a ambos. Un controlador KMDF tiene la opción adicional de llamar a ninguno de estos métodos y, en su lugar, completar el IRP o marcarlo pendiente.
Si un controlador KMDF ha establecido la marca de WDF_DISPATCH_IRP_TO_IO_QUEUE_INVOKE_INCALLERCTX_CALLBACK y no ha habilitado el progreso hacia delante garantizado para la cola de E/S de destino, el marco llama a EvtIoInCallerContext del controlador, si se proporciona. Después de preprocesar la solicitud, la función de devolución de llamada debe ponerla en cola llamando a WdfDeviceEnqueueRequest o completarla llamando a WdfRequestComplete.
Envío de IRP preprocesados
Para enviar IRP desde la función de devolución de llamada EvtDeviceWdmIrpPreprocess de un controlador a una cola de E/S específica, use el procedimiento siguiente:
- El controlador registra una función de devolución de llamada EvtDeviceWdmIrpPreprocess llamando a WdfDeviceInitAssignWdmIrpPreprocessCallback.
- El controlador llama a WdfPdoInitAllowForwardingRequestToParent si el destino es la cola de E/S del dispositivo primario.
- Desde EvtDeviceWdmIrpPreprocess, llame a WdfDeviceWdmDispatchIrpToIoQueue con Marcas establecidas en WDF_DISPATCH_IRP_TO_IO_QUEUE_PREPROCESSED_IRP.
- Si el controlador ha establecido la marca de WDF_DISPATCH_IRP_TO_IO_QUEUE_INVOKE_INCALLERCTX_CALLBACK y no ha habilitado el progreso hacia delante garantizado para la cola de E/S de destino, el marco llama a EvtIoInCallerContext del controlador, si se proporciona. Después de que la función de devolución de llamada haya terminado de preprocesar la solicitud, debe ponerla en cola llamando a WdfDeviceEnqueueRequest o completarla llamando a WdfRequestComplete.