Gestione di una richiesta di IRP_MN_QUERY_REMOVE_DEVICE
Il gestore PnP invia questo IRP per informare i driver che un dispositivo sta per essere rimosso dal computer e di chiedere se il dispositivo può essere rimosso senza interrompere il computer. Invia anche questo IRP quando un utente richiede di aggiornare i driver per il dispositivo.
Il gestore PnP invia questo IRP in IRQL PASSIVE_LEVEL nel contesto di un thread di sistema.
Prima di inviare questo IRP ai driver per un dispositivo, vengono eseguite le seguenti operazioni:
Notifica a tutte le applicazioni in modalità utente registrate per la notifica nel dispositivo (o un dispositivo correlato).
Sono incluse le applicazioni registrate per la notifica nel dispositivo, in uno dei discendenti del dispositivo (dispositivo figlio, figlio di figlio e così via) o in una delle relazioni di rimozione del dispositivo. Un'applicazione si registra per ricevere tale notifica chiamando CM_Register_Notification o RegisterDeviceNotification.
In risposta a questa notifica, un'applicazione si prepara alla rimozione del dispositivo (chiude gli handle al dispositivo) o fallisce la query. Per maggiori informazioni su come gestire queste notifiche, consultare la sezione Registrazione per la notifica dell'arrivo dell'interfaccia del dispositivo e della rimozione del dispositivo.
Notifica a tutti i driver in modalità kernel registrati per la notifica nel dispositivo (o in un dispositivo correlato).
Sono inclusi i driver registrati per la notifica nel dispositivo, in uno dei discendenti del dispositivo o in una delle relazioni di rimozione del dispositivo. Un driver esegue la registrazione per questa notifica chiamando IoRegisterPlugPlayNotification con una categoria di eventi di EventCategoryTargetDeviceChange.
In risposta a questa notifica, un driver prepara la rimozione del dispositivo (chiude gli handle al dispositivo) o rifiuta la query.
Invia IRP_MN_QUERY_REMOVE_DEVICE IRP ai driver per i discendenti del dispositivo. Per altre informazioni su come uno stack di dispositivi gestisce questo IRP, vedere di seguito.
(Sistemi Windows 2000 e versioni successive) Se un file system viene montato sul dispositivo, il gestore Plug and Play invia una richiesta di rimozione di query al file system e a eventuali filtri del file system. Se sono presenti handle aperti per il dispositivo, il file system in genere non riesce a soddisfare la richiesta di rimozione. In caso contrario, il file system blocca in genere il volume per impedire la riuscita di future operazioni di creazione. Se un file system montato non supporta una richiesta di interrogazione di rimozione, il gestore PnP non riesce nella richiesta di interrogazione di rimozione riguardante il dispositivo.
Se tutti i passaggi precedenti hanno esito positivo, il gestore PnP invia il IRP_MN_QUERY_REMOVE_DEVICE ai driver per il dispositivo.
Una richiesta di IRP_MN_QUERY_REMOVE_DEVICE viene gestita prima dal driver superiore nello stack di dispositivi e quindi da ogni driver inferiore successivo. Un driver gestisce le IRP di rimozione nella sua routine DispatchPnP.
In risposta a un IRP_MN_QUERY_REMOVE_DEVICE, un driver deve eseguire le operazioni seguenti:
Determinare se il dispositivo può essere rimosso dal computer in modo sicuro.
Un driver deve avere esito negativo su un IRP di rimozione di query se è true una delle condizioni seguenti:
Se la rimozione del dispositivo potrebbe comportare la perdita di dati.
Se un componente ha un handle aperto per il dispositivo. Si tratta di un problema solo in Windows 98/Me. Windows 2000 e versioni successive di Windows rilevano gli handle aperti e rifiutano la query se sono presenti handle aperti dopo il completamento dell'operazione IRP_MN_QUERY_REMOVE_DEVICE.
Se un driver riceve una notifica (tramite un IRP_MN_DEVICE_USAGE_NOTIFICATION IRP) che il dispositivo si trova nel percorso di un paging, un dump della memoria in caso di crash o un file di ibernazione.
Se il driver ha un riferimento all'interfaccia in sospeso sul dispositivo. Ovvero, il driver ha fornito un'interfaccia in risposta a una richiesta IRP_MN_QUERY_INTERFACE e l'interfaccia non è stata ancora dereferenziata.
Se il dispositivo non può essere rimosso, rifiuta la query-remove IRP.
Impostare Irp->IoStatus.Status su uno stato di errore appropriato (in genere STATUS_UNSUCCESSFUL), chiamare IoCompleteRequest con IO_NO_INCREMENT e tornare dalla routine DispatchPnP del driver. Non passare l'IRP al driver inferiore successivo.
Se il driver ha inviato in precedenza una richiesta di IRP_MN_WAIT_WAKE per abilitare il dispositivo alla riattivazione, annullare l'IRP di attesa per la riattivazione.
Registrare lo stato PnP precedente del dispositivo.
Un driver deve registrare lo stato PnP in cui si trovava il dispositivo quando il driver ha ricevuto la richiesta di IRP_MN_QUERY_REMOVE_DEVICE perché il driver deve restituire il dispositivo a tale stato se la query viene annullata (IRP_MN_CANCEL_REMOVE_DEVICE). Lo stato precedente è in genere "avviato", ovvero lo stato immesso dal dispositivo quando il driver completa correttamente una richiesta di IRP_MN_START_DEVICE.
Tuttavia, sono possibili altri stati precedenti. Ad esempio, l'utente potrebbe aver disabilitato il dispositivo tramite Gestione dispositivi. In alternativa, in risposta a una richiesta di IRP_MN_QUERY_CAPABILITIES, il driver del bus principale (o un driver di filtro sul driver del bus) potrebbe aver segnalato che l'hardware del dispositivo è disattivato. In entrambi i casi, il driver per il dispositivo disabilitato può ricevere una richiesta di IRP_MN_QUERY_REMOVE_DEVICE prima di ricevere una richiesta di IRP_MN_START_DEVICE.
Finisci l'IRP:
In una funzione o in un driver di filtro:
Impostare Irp->IoStatus.Status su STATUS_SUCCESS.
Configurare la posizione successiva dello stack con IoSkipCurrentIrpStackLocation e passare l'IRP al driver inferiore successivo con IoCallDriver.
Propagare lo stato da IoCallDriver come stato restituito dalla routine DispatchPnP.
Non completare l'IRP.
In un autista di autobus:
Impostare Irp->IoStatus.Status su STATUS_SUCCESS.
Completare l'IRP (IoCompleteRequest) con IO_NO_INCREMENT.
Tornare dalla routine DispatchPnP.
Se un driver nello stack di dispositivi ha esito negativo per un IRP_MN_QUERY_REMOVE_DEVICE, il manager PnP invia un IRP_MN_CANCEL_REMOVE_DEVICE nello stack di dispositivi. Ciò impedisce ai driver di richiedere una routine IoCompletion per un IRP di query-remove per rilevare se un driver inferiore ha fallito nell'elaborare l'IRP.
Quando un driver riesce a un IRP_MN_QUERY_REMOVE_DEVICE e considera che il dispositivo sia nello stato di rimozione in attesa, il driver deve respingere qualsiasi richiesta di creazione successiva per il dispositivo. Il driver elabora tutti gli altri IRP come di consueto, finché il driver non riceve un IRP_MN_CANCEL_REMOVE_DEVICE o un IRP_MN_REMOVE_DEVICE.