Control de una solicitud de 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 a 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 registradas para la notificación en el dispositivo (o un dispositivo relacionado).
Esto incluye las aplicaciones registradas para la notificación en el dispositivo, en uno de los descendientes del dispositivo (dispositivo secundario, secundario de elemento secundario, etc.), o en una de las relaciones de eliminación del dispositivo. Una aplicación se registra para dicha notificación llamando a RegisterDeviceNotification.
En respuesta a esta notificación, una aplicación se prepara para la eliminación de dispositivos (cierra los identificadores del dispositivo) o produce un error en la consulta.
Notifica a todos los controladores en modo kernel registrados para la notificación en el dispositivo (o un dispositivo relacionado).
Esto incluye los controladores registrados 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 eventos de EventCategoryTargetDeviceChange.
En respuesta a esta notificación, un controlador se prepara para la eliminación de dispositivos (cierra los identificadores del dispositivo) o produce un error en la consulta.
Envía IRP_MN_QUERY_REMOVE_DEVICE IRP a los controladores para los descendientes del dispositivo.
(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 cualquier filtro del sistema de archivos. Si hay identificadores abiertos en el dispositivo, el sistema de archivos suele producir un error en la solicitud de eliminación de consultas. Si no es así, el sistema de archivos normalmente bloquea el volumen para evitar que las creaciones futuras se realicen correctamente. 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.
El controlador superior de la pila del dispositivo controla primero una solicitud de IRP_MN_QUERY_REMOVE_DEVICE y, a continuación, cada controlador inferior siguiente. Los controladores de controlador quitan irP en su rutina DispatchPnP .
En respuesta a un IRP_MN_QUERY_REMOVE_DEVICE, un controlador debe hacer lo siguiente:
Determine si el dispositivo se puede quitar de la máquina sin interrumpir la operación.
Un controlador debe producir un error en irP de eliminación de consultas si se cumple alguna de las siguientes condiciones:
Si se quita el dispositivo, se podrían perder datos.
Si un componente tiene un identificador abierto para el 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 una vez completada la IRP_MN_QUERY_REMOVE_DEVICE ).
Si se ha notificado a un controlador (a través de un IRP de IRP_MN_DEVICE_USAGE_NOTIFICATION ) que el dispositivo está en la ruta de acceso 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.
Si no se puede quitar el dispositivo, se producirá un error en el IRP de eliminación de consultas.
Establezca Irp-IoStatus.Status> en un estado de error adecuado (normalmente STATUS_UNSUCCESSFUL), llame a IoCompleteRequest con IO_NO_INCREMENT y vuelva de la rutina DispatchPnP del controlador. No pase irP al siguiente controlador inferior.
Si el controlador envió previamente una solicitud de IRP_MN_WAIT_WAKE para habilitar el dispositivo para reactivación, cancele el IRP de espera-reactivación.
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 se cancela la consulta (IRP_MN_CANCEL_REMOVE_DEVICE). El estado anterior suele ser "iniciado", que es el estado que el dispositivo escribe cuando el controlador completa correctamente una solicitud de IRP_MN_START_DEVICE .
Sin embargo, otros estados anteriores son posibles. Por ejemplo, es posible que el usuario haya deshabilitado el dispositivo a través de Administrador de dispositivos. O bien, en respuesta a una solicitud de IRP_MN_QUERY_CAPABILITIES , el controlador de autobús primario (o un controlador de filtro en el controlador de autobús) podría haber informado de que el hardware del dispositivo está deshabilitado. En cualquier caso, el controlador del dispositivo deshabilitado puede recibir una solicitud de IRP_MN_QUERY_REMOVE_DEVICE antes de recibir una solicitud de IRP_MN_START_DEVICE .
Finalice el IRP:
En una función o un controlador de filtro:
Establezca Irp-IoStatus.Status> en STATUS_SUCCESS.
Configure la siguiente ubicación de pila con IoSkipCurrentIrpStackLocation y pase el IRP al siguiente controlador inferior con IoCallDriver.
Propaga el estado de IoCallDriver como estado devuelto de la rutina DispatchPnP .
No complete el IRP.
En un conductor de autobús:
Establezca Irp-IoStatus.Status> en STATUS_SUCCESS.
Complete el IRP (IoCompleteRequest) con IO_NO_INCREMENT.
Vuelva de la rutina DispatchPnP .
Si algún controlador de la pila de dispositivos produce un error en un IRP_MN_QUERY_REMOVE_DEVICE, el administrador de PnP envía un IRP_MN_CANCEL_REMOVE_DEVICE a la pila de dispositivos. Esto evita que los controladores requieran una rutina de IoCompletion para que un IRP de eliminación de consultas detecte si un controlador inferior ha producido un error en el IRP.
Una vez que un controlador realiza correctamente un IRP_MN_QUERY_REMOVE_DEVICE y considera que el dispositivo está en estado de eliminación pendiente, el controlador debe producir un error en 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.