Paso de IRP de PnP hacia abajo en la pila de dispositivos
El administrador de PnP usa IRP para dirigir los controladores para iniciar, detener y quitar dispositivos y consultar controladores sobre sus dispositivos. Todos los IRP de PnP tienen el código de función principal IRP_MJ_PNP, y todos los controladores PnP deben proporcionar una rutina DispatchPnP para atender este código de función. El administrador de PnP inicializa Irp-IoStatus.Status> para STATUS_NOT_SUPPORTED cuando envía un IRP. Para obtener más información, vea DispatchPnP Routines.
Para obtener una lista de irP menores de PnP, consulte Plug and Play IRP menores.
Todos los controladores de un dispositivo deben tener la oportunidad de responder a un IRP de PnP a menos que un controlador de la pila produzca un error en el IRP. (Vea la ilustración siguiente).
Ningún controlador único para un dispositivo puede suponer que es el único controlador que responderá a un IRP de PnP. Considere, por ejemplo, un controlador de función que responde a una solicitud de IRP_MN_QUERY_CAPABILITIES y completa el IRP sin pasarlo al controlador inferior siguiente. No se notifica ninguna de las funcionalidades admitidas por controladores inferiores, como un identificador de instancia único o funcionalidades de administración de energía compatibles con el controlador de bus primario.
Un IRP de PnP recorre la copia de seguridad de la pila del dispositivo cuando el controlador de bus primario llama a IoCompleteRequest y el administrador de E/S llama a cualquier rutina de IoCompletion registrada por el controlador de función o los controladores de filtro.
Una función o controlador de filtro debe hacer lo siguiente cuando recibe un IRP de PnP:
- Si el controlador realiza acciones en respuesta al IRP:
- Realice las acciones adecuadas.
- Establezca Irp-IoStatus.Status> en un estado adecuado, como STATUS_SUCCESS. Establezca Irp-IoStatus.Information>, si procede para irP.
- Configure la siguiente ubicación de pila con IoSkipCurrentIrpStackLocation o IoCopyCurrentIrpStackLocationToNext. Llame a la última rutina si establece una rutina de IoCompletion .
- Establezca una rutina de IoCompletion , si es necesario.
- No complete el IRP. (No llame a IoCompleteRequest). El controlador primario del autobús completará el IRP.
- Si el controlador no realiza acciones para este IRP, simplemente se prepara para pasar el IRP al siguiente controlador:
- Llame a IoSkipCurrentIrpStackLocation para quitar su ubicación de pila del IRP.
- No establezca ningún campo en Irp-IoStatus>.
- No establezca una rutina de IoCompletion .
- No complete el IRP. (No llame a IoCompleteRequest). El controlador primario del autobús completará el IRP.
Si una función o un controlador de filtro no produjo un error en el IRP, pasa el IRP al controlador inferior siguiente con IoCallDriver. Un controlador tiene un puntero al controlador inferior siguiente; ese puntero se devolvió desde la llamada IoAttachDeviceToDeviceStack en la rutina AddDevice del controlador superior.
El controlador de autobús primario completa el IRP después de realizar cualquier tarea para responder al IRP. Una vez que el controlador de bus llama a IoCompleteRequest, el administrador de E/S llama a las rutinas de IoCompletion registradas por la función o los controladores de filtro para el dispositivo.