Obsługa żądania IRP_MN_QUERY_REMOVE_DEVICE
Menedżer PnP wysyła tę IRP, aby poinformować sterowniki, że urządzenie ma zostać usunięte z maszyny i zapytać, czy urządzenie można usunąć bez zakłócania działania maszyny. Wysyła również ten protokół IRP, gdy użytkownik żąda aktualizacji sterowników dla urządzenia.
Menedżer PnP wysyła ten protokół IRP w PASSIVE_LEVEL IRQL w kontekście wątku systemowego.
Przed przekazaniem tego IRP do sterowników urządzenia wykonywane są następujące czynności:
Powiadamia wszystkie aplikacje w trybie użytkownika, które zostały zarejestrowane w celu otrzymywania powiadomień na urządzeniu (lub powiązanym urządzeniu).
Obejmuje to aplikacje zarejestrowane w celu otrzymywania powiadomień na urządzeniu, na jednym z elementów podrzędnych urządzenia (urządzenie podrzędne, podrzędne i tak dalej) lub na jednym z relacji usuwania urządzenia. Aplikacja rejestruje się w celu uzyskania takiego powiadomienia, wywołując CM_Register_Notification lub RegisterDeviceNotification.
W odpowiedzi na to powiadomienie aplikacja przygotowuje się do usunięcia urządzenia (zamyka dojścia do urządzenia) lub kończy się niepowodzeniem zapytania. Aby uzyskać więcej informacji na temat obsługi tych powiadomień, zobacz Registering for Notification of Device Interface Arrival and Device Removal (Rejestrowanie w celu otrzymywania powiadomień o nadejściu interfejsu urządzenia i usunięciu urządzenia).
Powiadamia wszystkie sterowniki trybu jądra, które zostały zarejestrowane w celu otrzymywania powiadomień na urządzeniu (lub powiązanym urządzeniu).
Obejmuje to sterowniki zarejestrowane w celu otrzymywania powiadomień na urządzeniu, na jednym z elementów potomnych urządzenia lub w jednej z relacji usuwania urządzenia. Sterownik rejestruje się na to powiadomienie, wywołując IoRegisterPlugPlayNotification z kategorią zdarzenia EventCategoryTargetDeviceChange.
W odpowiedzi na to powiadomienie sterownik albo przygotowuje się do usunięcia urządzenia (zamykając uchwyty do urządzenia), albo odrzuca zapytanie.
Wysyła IRP_MN_QUERY_REMOVE_DEVICE IRPs do sterowników podrzędnych urządzenia. Zobacz poniżej, aby uzyskać więcej informacji na temat sposobu obsługi tego protokołu IRP przez stos urządzeń.
(Systemy Windows 2000 i nowsze) Jeśli system plików jest zamontowany na urządzeniu, menedżer PnP wysyła żądanie usunięcia do systemu plików i wszystkich filtrów systemu plików. Jeśli urządzenie ma otwarte uchwyty, system plików zazwyczaj odrzuca żądanie usunięcia urządzenia. Jeśli nie, system plików zazwyczaj blokuje wolumin, aby uniemożliwić przyszłe udane tworzenie. Jeśli zamontowany system plików nie obsługuje żądania usunięcia, menedżer PnP odrzuci żądanie usunięcia dla urządzenia.
Jeśli wszystkie powyższe kroki się powiedzie, menedżer PnP wyśle IRP_MN_QUERY_REMOVE_DEVICE do sterowników urządzenia.
Żądanie IRP_MN_QUERY_REMOVE_DEVICE jest obsługiwane najpierw przez najwyższy sterownik w stosie sterowników urządzenia, a następnie przez każdy kolejny niższy sterownik. Sterownik obsługuje usuwanie IRPs w swojej procedurze DispatchPnP.
W odpowiedzi na zapytanie IRP_MN_QUERY_REMOVE_DEVICE, sterownik powinien wykonać następujące czynności:
Ustal, czy urządzenie można bezpiecznie usunąć z maszyny.
Sterownik musi zablokować zapytanie o usunięcie IRP, jeśli spełniony jest którykolwiek z następujących warunków:
Usunięcie urządzenia może spowodować utratę danych.
Jeśli składnik ma otwarte połączenie do urządzenia. (Jest to problem tylko w systemie Windows 98/Me. System Windows 2000 i nowsze wersje systemu Windows śledzą otwarte dojścia i jeśli po zakończeniu IRP_MN_QUERY_REMOVE_DEVICE pozostają otwarte dojścia, zapytanie kończy się niepowodzeniem.)
Jeśli sterownik został powiadomiony (za pośrednictwem IRP_MN_DEVICE_USAGE_NOTIFICATION IRP), że urządzenie znajduje się w ścieżce do stronicowania, zrzutu awaryjnego lub pliku hibernacji.
Jeśli sterownik ma doskonałe odwołanie do interfejsu względem urządzenia. Oznacza to, że sterownik dostarczył interfejs w odpowiedzi na żądanie IRP_MN_QUERY_INTERFACE, a interfejs nie został zdezynkrementowany.
Jeśli nie można usunąć urządzenia, należy zakończyć niepowodzeniem zapytanie o usunięcie IRP.
Ustaw Irp->IoStatus.Status na odpowiedni stan błędu (zazwyczaj STATUS_UNSUCCESSFUL), wywołaj IoCompleteRequest z IO_NO_INCREMENT i powróć z procedury sterownika DispatchPnP. Nie przekazuj IRP do następnego niższego sterownika.
Jeśli sterownik wcześniej wysłał żądanie IRP_MN_WAIT_WAKE, aby włączyć urządzenie do wznawiania, anuluj protokół IRP oczekiwania wznawiania.
Zarejestruj poprzedni stan PnP urządzenia.
Sterownik powinien zarejestrować stan PnP urządzenia w momencie, gdy otrzymał żądanie IRP_MN_QUERY_REMOVE_DEVICE, ponieważ musi przywrócić urządzenie do tego stanu, jeśli zapytanie zostanie anulowane (IRP_MN_CANCEL_REMOVE_DEVICE). Poprzedni stan to zazwyczaj "uruchomiony", czyli stan, do którego urządzenie przechodzi po pomyślnym zakończeniu realizacji żądania IRP_MN_START_DEVICE przez sterownik.
Jednak inne wcześniejsze stany są możliwe. Na przykład użytkownik mógł wyłączyć urządzenie za pośrednictwem Menedżera urządzeń. Ewentualnie, w odpowiedzi na żądanie IRP_MN_QUERY_CAPABILITIES, sterownik magistrali nadrzędnej (lub sterownik filtru na sterowniku magistrali) mógł zgłosić, że sprzęt urządzenia został wyłączony. W obu przypadkach sterownik wyłączonego urządzenia może otrzymać żądanie IRP_MN_QUERY_REMOVE_DEVICE, zanim otrzyma żądanie IRP_MN_START_DEVICE.
Sfinalizuj protokół IRP:
W funkcji lub sterowniku filtru:
Ustaw > IoStatus.Status na STATUS_SUCCESS.
Skonfiguruj kolejną lokalizację stosu przy użyciu IoSkipCurrentIrpStackLocation i przekaż IRP do następnego niższego sterownika za pomocą IoCallDriver.
Przekaż status z IoCallDriver jako status zwrotny z procedury DispatchPnP.
Nie należy wypełniać protokołu IRP.
U kierowcy autobusu:
Ustaw IoStatus.Status> na STATUS_SUCCESS.
Ukończ protokół IRP (IoCompleteRequest) przy użyciu IO_NO_INCREMENT.
Wróć z procedury
DispatchPnP.
Jeśli jakikolwiek sterownik w stosie urządzenia ulegnie awarii IRP_MN_QUERY_REMOVE_DEVICE, menedżer PnP wysyła IRP_MN_CANCEL_REMOVE_DEVICE do stosu urządzenia. Zapobiega to sytuacji, w której sterowniki wymagają procedur IoCompletion dla IRP zapytania o usunięcie w celu wykrycia, czy niższy sterownik odmówił obsługi IRP.
Gdy sterownik z powodzeniem zakończy operację IRP_MN_QUERY_REMOVE_DEVICE i uzna, że urządzenie znajduje się w stanie oczekiwania na usunięcie, musi odrzucać wszelkie kolejne żądania tworzenia dla tego urządzenia. Sterownik przetwarza wszystkie inne środowiska IRPs jak zwykle, dopóki sterownik nie otrzyma IRP_MN_CANCEL_REMOVE_DEVICE lub IRP_MN_REMOVE_DEVICE.