Compartir a través de


Control de una solicitud IRP_MN_QUERY_REMOVE_DEVICE

El administrador de PnP envía este IRP para informar a los controladores de que un dispositivo está a punto de quitarse de la máquina y preguntar si el dispositivo se puede quitar sin interrumpir la máquina. También envía este IRP cuando un usuario solicita actualizar controladores para el dispositivo.

El administrador de PnP envía este IRP en IRQL PASSIVE_LEVEL en el contexto de un subproceso del sistema.

Hace lo siguiente antes de enviar este IRP a los controladores de un dispositivo:

  • Notifica a todas las aplicaciones en modo de usuario que se registraron para la notificación en el dispositivo (o un dispositivo relacionado).

    Esto incluye las aplicaciones registradas para recibir notificaciones en el dispositivo, en uno de los descendientes del dispositivo (dispositivo secundario, secundario del secundario, etc.), o en una de las relaciones de eliminación del dispositivo. Una aplicación se registra para dicha notificación llamando a CM_Register_Notification o RegisterDeviceNotification.

    En respuesta a esta notificación, una aplicación se prepara para la eliminación del dispositivo (cierra los identificadores del dispositivo) o falla la consulta. Consulte Registro para recibir notificaciones de la llegada y eliminación de la interfaz del dispositivo para obtener más información sobre cómo gestionar estas notificaciones.

  • Notifica a todos los controladores en modo núcleo que se registraron para recibir notificaciones en el dispositivo (o en un dispositivo relacionado).

    Esto incluye los controladores que se registraron para la notificación en el dispositivo, en uno de los descendientes del dispositivo o en una de las relaciones de eliminación del dispositivo. Un controlador se registra para esta notificación llamando a ioRegisterPlugPlayNotification con una categoría de evento de EventCategoryTargetDeviceChange.

    En respuesta a esta notificación, un controlador se prepara para la eliminación del dispositivo (cierra los identificadores del dispositivo) o falla la consulta.

  • Envía IRP IRP_MN_QUERY_REMOVE_DEVICE a los controladores para los descendientes del dispositivo. Consulte a continuación para obtener más información sobre cómo controla una pila de dispositivos este IRP.

  • (Sistemas Windows 2000 y versiones posteriores) Si se monta un sistema de archivos en el dispositivo, el administrador de PnP envía una solicitud de eliminación de consultas al sistema de archivos y a cualquier filtro del sistema de archivos. Si hay identificadores abiertos para el dispositivo, el sistema de archivos normalmente rechaza la solicitud de eliminación de consultas. Si no es así, el sistema de archivos normalmente bloquea el volumen para evitar que las futuras creaciones tengan éxito. Si un sistema de archivos montado no admite una solicitud de eliminación de consultas, el administrador de PnP produce un error en la solicitud de eliminación de consultas para el dispositivo.

Si todos los pasos anteriores se realizan correctamente, el administrador de PnP envía el IRP_MN_QUERY_REMOVE_DEVICE a los controladores del dispositivo.

Primero, una solicitud de IRP_MN_QUERY_REMOVE_DEVICE es gestionada por el controlador superior de la pila de dispositivos, y luego por cada controlador situado más abajo. Un controlador maneja las IRP de eliminación en su rutina DispatchPnP.

En respuesta a un IRP_MN_QUERY_REMOVE_DEVICE, un controlador debe hacer lo siguiente:

  1. Determine si el dispositivo se puede quitar de la máquina de forma segura.

    Un controlador debe producir un error de IRP de eliminación de consultas si se cumple alguno de los siguientes elementos:

    • Si quitar el dispositivo podría provocar la pérdida de datos.

    • Si un componente tiene un identificador abierto al dispositivo. (Este es un problema solo en Windows 98/Me. Windows 2000 y versiones posteriores de Windows realizan un seguimiento de los identificadores abiertos y producen un error en la consulta si hay identificadores abiertos después de que se complete IRP_MN_QUERY_REMOVE_DEVICE).

    • Si se ha notificado a un controlador de dispositivo (a través de un IRP IRP_MN_DEVICE_USAGE_NOTIFICATION) que el dispositivo está en la ruta de un archivo de paginación, volcado de memoria o hibernación.

    • Si el controlador tiene una referencia de interfaz pendiente en el dispositivo. Es decir, el controlador proporcionó una interfaz en respuesta a una solicitud de IRP_MN_QUERY_INTERFACE y la interfaz no se ha desreferenciado.

  2. Si el dispositivo no se puede eliminar, genera un error en el IRP de solicitud de eliminación.

    Establecer Irp->IoStatus.Status en un estado de error adecuado (normalmente STATUS_UNSUCCESSFUL), llamar a IoCompleteRequest con IO_NO_INCREMENT y volver de la rutina de DispatchPnP del controlador. No pasar el IRP al siguiente controlador inferior.

  3. Si el controlador envió previamente una solicitud IRP_MN_WAIT_WAKE para habilitar el dispositivo para la reactivación, cancelar el IRP de espera-reactivación.

  4. Registre el estado PnP anterior del dispositivo.

    Un controlador debe registrar el estado PnP en el que el dispositivo estaba cuando el controlador recibió la solicitud de IRP_MN_QUERY_REMOVE_DEVICE porque el controlador debe devolver el dispositivo a ese estado si la consulta se cancela (IRP_MN_CANCEL_REMOVE_DEVICE). El estado previo suele ser "iniciado", que es el estado en el que el dispositivo entra cuando el controlador finaliza con éxito una solicitud de IRP_MN_START_DEVICE.

    Sin embargo, otros estados anteriores son posibles. Por ejemplo, el usuario podría haber deshabilitado el dispositivo a través del Administrador de dispositivos. O bien, en respuesta a una solicitud IRP_MN_QUERY_CAPABILITIES, el controlador del bus principal (o un controlador de filtro en el controlador del bus) podría haber informado que el hardware del dispositivo está desactivado. En cualquier caso, el controlador del dispositivo deshabilitado puede recibir una solicitud IRP_MN_QUERY_REMOVE_DEVICE antes de recibir una solicitud IRP_MN_START_DEVICE.

  5. Finalizar el IRP:

    En una función o un controlador de filtro:

    • Establecer Irp->IoStatus.Status en STATUS_SUCCESS.

    • Configurar la siguiente ubicación de pila con IoSkipCurrentIrpStackLocation y pasar el IRP al siguiente controlador inferior con IoCallDriver.

    • Propagar el estado de IoCallDriver como el estado devuelto de la rutina DispatchPnP en.

    • No completar el IRP.

    En un conductor de autobús:

    • Establecer Irp->IoStatus.Status en STATUS_SUCCESS.

    • Completar el IRP (IoCompleteRequest) con IO_NO_INCREMENT.

    • Volver de la rutina DispatchPnP.

Si se produce un error en algún controlador de la pila de dispositivos para IRP_MN_QUERY_REMOVE_DEVICE, el administrador de PnP envía IRP_MN_CANCEL_REMOVE_DEVICE a la pila de dispositivos. Esto impide que los controladores requieran una rutina IoCompletion para que un IRP de eliminación de consultas detecte si un controlador inferior produjo un error en el IRP.

Una vez que un controlador gestiona correctamente IRP_MN_QUERY_REMOVE_DEVICE y considera que el dispositivo está en el estado de eliminación pendiente, el controlador debe rechazar las solicitudes de creación posteriores del dispositivo. El controlador procesa todos los demás IRP como de costumbre, hasta que el controlador recibe un IRP_MN_CANCEL_REMOVE_DEVICE o un IRP_MN_REMOVE_DEVICE.