Eliminación de un dispositivo en un controlador de funciones
Al quitar un dispositivo, un controlador de función debe deshacer las operaciones que ha realizado para agregar e iniciar el dispositivo. En esta explicación se incluyen controladores de función para dispositivos periféricos y controladores de funciones para dispositivos de bus.
Un controlador de función quita un dispositivo mediante un procedimiento como el siguiente en su rutina DispatchPnP :
¿Se trata de un controlador de función para un dispositivo de autobús?
Si es así, puede eliminar cualquier PPO secundario pendiente para dispositivos en el bus.
Si el conductor del autobús controló una solicitud de IRP_MN_SURPRISE_REMOVAL anterior para el dispositivo secundario, pero el controlador aún no ha recibido la solicitud de IRP_MN_REMOVE_DEVICE posterior, el conductor del autobús deja intacto el PDO secundario. En algún momento posterior, cuando se cierran todos los identificadores del dispositivo secundario, el administrador de PnP enviará el IRP de eliminación para el dispositivo secundario y el controlador de autobús elimina el PDO secundario en ese momento.
Si el controlador de autobús ha controlado una solicitud de IRP_MN_REMOVE_DEVICE anterior para el dispositivo y no ha habido ninguna solicitud IRP_MN_SURPRISE_REMOVAL posterior, el controlador de autobús elimina el PDO secundario. En este caso, el administrador de PnP garantiza que cualquier función y controladores de filtro se hayan quitado del dispositivo secundario (se han eliminado los DO de FDO y de filtro) antes de enviar un IRP de eliminación al dispositivo de bus primario. Es posible que el PDO secundario siga estando presente, por lo que el controlador de bus debe eliminar el PDO secundario antes de quitar el dispositivo de bus.
¿El controlador ya ha controlado una solicitud de IRP_MN_SURPRISE_REMOVAL anterior para este FDO?
Si es así, realice cualquier limpieza restante y vaya al paso 8, IoCallDriver.
Normalmente, un controlador mantiene una marca en la extensión del dispositivo que indica si el controlador ha controlado una solicitud de IRP_MN_SURPRISE_REMOVAL para el dispositivo.
Si el controlador ha habilitado previamente el dispositivo para reactivación, cancele la solicitud de IRP_MN_WAIT_WAKE .
Asegúrese de que el dispositivo está inactivo.
Si el dispositivo aún no está inactivo en respuesta a un IRP_MN_QUERY_REMOVE_DEVICE anterior, el controlador debe marcar el dispositivo como no aceptar nuevas solicitudes y debe completar las solicitudes en cola en este controlador. El controlador debe producir un error en las solicitudes pendientes que requieran acceso al dispositivo.
Un controlador puede usar las rutinas IoXxxRemoveLockXxx para contar E/S pendientes y para establecer un evento que indique que el procesamiento de eliminación puede continuar.
Realice las operaciones de apagado.
Cada controlador del dispositivo realiza sus operaciones de apagado, si las hay, cuando recibe la solicitud de IRP_MN_REMOVE_DEVICE . El propietario de la directiva de energía para el dispositivo, normalmente el controlador de funciones, no envía una solicitud de IRP_MN_SET_POWER independiente para establecer el estado de alimentación del dispositivo en D3. El controlador de autobús primario normalmente apaga la ranura y notifica al administrador de energía con PoSetPowerState cuando el conductor del autobús obtiene el IRP de eliminación. Para obtener más información, consulte Administración de energía.
Deshabilite las interfaces de dispositivo mediante una llamada a IoSetDeviceInterfaceState.
Libere los recursos de hardware para el dispositivo en uso por el controlador.
Las operaciones exactas dependen del dispositivo y del controlador, pero pueden incluir desconectar una interrupción con IoDisconnectInterrupt, liberar intervalos de direcciones físicas con MmUnmapIoSpace y liberar puertos de E/S.
Pase la solicitud IRP_MN_REMOVE_DEVICE al controlador siguiente.
Configure la ubicación de la pila IRP para el siguiente controlador inferior con IoSkipCurrentIrpStackLocation y pase el IRP al siguiente controlador con IoCallDriver.
No es necesario que un controlador espere a que los controladores subyacentes finalicen sus operaciones de eliminación antes de continuar con sus actividades de eliminación.
Quite el objeto de dispositivo de la pila de dispositivos con IoDetachDevice.
Especifique un puntero al siguiente objeto de dispositivo inferior como parámetro TargetDevice . El controlador recibe este puntero de la llamada a IoAttachDeviceToDeviceStack en la rutina AddDevice del controlador.
Limpie las asignaciones específicas del dispositivo, la memoria, los eventos, etc.
Libere el FDO con IoDeleteDevice.
Vuelva de la rutina DispatchPnP , propagando el estado de retorno desde IoCallDriver.
Un controlador de función no especifica una rutina de IoCompletion para un IRP de eliminación, ni completa el IRP. El controlador primario del bus completa la eliminación de IRP.