Sdílet prostřednictvím


Zpracování požadavku IRP_MN_SURPRISE_REMOVAL

Správce PnP systému Windows 2000 a novější odešle tento IRP, aby informoval ovladače, že zařízení už není k dispozici pro vstupně-výstupní operace a pravděpodobně se z počítače neočekávaně odebralo ("odebrání překvapení").

Správce PnP odešle požadavek IRP_MN_SURPRISE_REMOVAL z následujících důvodů:

  • Pokud má sběrnice oznámení typu hot-plug, upozorní nadřazený ovladač sběrnice zařízení, že zařízení zmizelo. Řidič autobusu volá IoInvalidateDeviceRelations. V reakci správce PnP dotazuje řidiče sběrnice na své podřízené zařízení (IRP_MN_QUERY_DEVICE_RELATIONS pro BusRelations). Správce PnP zjistí, že zařízení není v novém seznamu podřízených položek, a zahájí operace neočekávaného odstranění pro zařízení.

  • Autobus je uveden z jiného důvodu a překvapivě odstraněné zařízení není zahrnuto do seznamu dětí. Správce PnP zahájí operace neočekávaného odebrání.

  • Ovladač funkce pro zařízení určuje, že zařízení už neexistuje (protože například jeho požadavky opakovaně vyprší). Sběrnice může být enumerovatelná, ale nemá oznámení o hot-plug připojení. V tomto případě ovladač funkce volá IoInvalidateDeviceState. V reakci správce PnP odešle do zásobníku zařízení požadavek IRP_MN_QUERY_PNP_DEVICE_STATE. Ovladač funkce nastaví příznak PNP_DEVICE_FAILED v PNP_DEVICE_STATE bitové maskě označující, že zařízení selhalo.

  • Zásobník ovladačů úspěšně dokončí požadavek IRP_MN_STOP_DEVICE , ale následný požadavek IRP_MN_START_DEVICE selže. V takových případech je zařízení pravděpodobně stále připojené.

Všechny ovladače PnP musí zpracovat tento IRP a musí nastavit Irp-IoStatus.Status> na STATUS_SUCCESS. Ovladač pro zařízení PnP musí být připravený ke zpracování IRP_MN_SURPRISE_REMOVAL kdykoli po volání rutiny AddDevice ovladače. Správné zpracování protokolu IRP umožňuje ovladačům a správci PnP provádět následující akce:

  1. Pokud je zařízení stále připojené, zakažte ho.

    Pokud ovladačová sada úspěšně dokončila požadavek IRP_MN_STOP_DEVICE, ale z nějakého důvodu selhal následný požadavek IRP_MN_START_DEVICE, musí být zařízení deaktivováno.

  2. Uvolněte hardwarové prostředky přiřazené k zařízení a zpřístupněte je jinému zařízení.

    Jakmile už zařízení nebude dostupné, měly by se uvolnit jeho hardwarové prostředky. Správce PnP pak může znovu přiřadit prostředky k jinému zařízení, včetně stejného zařízení, které uživatel může znovu připojit k počítači za použití horkého připojení.

  3. Minimalizujte riziko ztráty dat a přerušení systému.

    Zařízení, která podporují připojení za provozu, a jejich ovladače by měly být navrženy tak, aby zvládly nečekané odstranění. Uživatelé očekávají, že budou moct kdykoli odebrat zařízení, která podporují připojení za provozu.

Správce PnP odešle IRP_MN_SURPRISE_REMOVAL při IRQL = PASSIVE_LEVEL v kontextu systémového vlákna.

Správce PnP odešle tento protokol IRP ovladačům před oznámením aplikací v uživatelském režimu a dalším komponentám režimu jádra. Po dokončení protokolu IRP správce PnP odešle oznámení EventCategoryTargetDeviceChange s GUID_TARGET_DEVICE_REMOVE_COMPLETE komponentám režimu jádra, které jsou zaregistrované pro takové oznámení v zařízení.

Nejvyšší ovladač v zařízení stack zpracovává IRP_MN_SURPRISE_REMOVAL IRP a poté každý následující nižší ovladač.

V reakci na IRP_MN_SURPRISE_REMOVAL musí ovladač v uvedeném pořadí provést následující akce:

  1. Určete, jestli bylo zařízení odebráno.

    Ovladač se musí vždy pokusit zjistit, jestli je zařízení stále připojené. Pokud ano, ovladač se musí pokusit zařízení zastavit a zakázat ho.

  2. Uvolněte hardwarové prostředky zařízení (přerušení, vstupně-výstupní porty, registry paměti a kanály DMA).

  3. V ovladači nadřazené sběrnice vypněte slot sběrnice, pokud to ovladač dokáže. Zavolejte PoSetPowerState, aby informoval manažera napájení. Další informace najdete v tématu Řízení spotřeby.

  4. Zabraňte všem novým vstupně-výstupním operacím v zařízení.

    Ovladač by měl zpracovat následné IRP_MJ_CLEANUP, IRP_MJ_CLOSE, IRP_MJ_POWER a požadavky na IRP_MJ_PNP , ale ovladač musí zabránit jakýmkoli novým vstupně-výstupním operacím. Ovladač musí selhat všechny následné irps, které by ovladač zpracoval, pokud by zařízení existovalo, kromě zavření, vyčištění a PnP IRPs.

    Ovladač může v rozšíření zařízení nastavit bit, aby značil, že zařízení bylo neočekávaně odebráno. Rutiny dispečera řidiče by měly tento bit zkontrolovat.

  5. Selhání nevyřízených vstupně-výstupních požadavků na zařízení

  6. Pokračujte v předávání všech IRP, které ovladač pro zařízení nezpracovává.

  7. Zakažte rozhraní zařízení s IoSetDeviceInterfaceState.

  8. Vyčistěte všechny přidělení specifické pro zařízení, paměť, události nebo jiné systémové prostředky.

    Ovladač by mohl takové vyčištění odložit, dokud neobdrží následný požadavek IRP_MN_REMOVE_DEVICE, ale pokud má starší komponenta otevřený popisovač, jenž nelze uzavřít, pak IRP pro odebrání nikdy nebude odeslán.

  9. Ponechte objekt zařízení připojený ke zásobníku zařízení.

    Neodpojujte a neodstraňujte objekt zařízení, dokud nepřijde další požadavek IRP_MN_REMOVE_DEVICE.

  10. Dokončete IRP.

    V ovladači funkce nebo filtru:

    • Nastavte Irp–>IoStatus.Status na STATUS_SUCCESS.

    • Nastavte aktuální umístění zásobníku s IoSkipCurrentIrpStackLocation a předejte IRP dále nižšímu ovladači s IoCallDriver.

    • Zprostředkujte stav z IoCallDriver jako návratový stav z rutiny DispatchPnP.

    • Neprovádějte IRP.

    U řidiče autobusu (který zpracovává tento IRP pro podřízenou PDO):

    • Nastavte Irp–>IoStatus.Status na STATUS_SUCCESS.

    • Dokončete IRP (IoCompleteRequest) pomocí IO_NO_INCREMENT.

    • Vraťte se z rutiny DispatchPnP.

Jakmile je tento IRP úspěšně dokončen a všechny otevřené popisovače zařízení jsou uzavřeny, správce PnP odešle do zásobníku zařízení požadavek IRP_MN_REMOVE_DEVICE. V reakci na odebrání IRP ovladače odpojí své objekty zařízení ze zásobníku a odstraní je. Pokud má starší komponenta otevřený popisovač zařízení a ponechá popisovač otevřený i přes selhání vstupně-výstupních operací, správce PnP nikdy neodesílá odebrání protokolu IRP.

Všechny ovladače by měly zpracovat tento IRP a měly by si uvědomit, že zařízení bylo fyzicky odebráno z počítače. Některé obchodní faktory však nezpůsobí nežádoucí výsledky, pokud nezpracují IRP. Například zařízení, které nespotřebovává žádné systémové hardwarové prostředky a nachází se na sběrnici založené na protokolu, jako je USB nebo 1394, nemůže svázat hardwarové prostředky, protože nevyužívá žádné. Po odebrání zařízení nehrozí riziko, že se ovladače pokusí o přístup k zařízení, protože ovladače funkcí a filtrů přistupují k zařízení pouze prostřednictvím ovladače nadřazené sběrnice. Vzhledem k tomu, že sběrnice podporuje oznámení o odebrání, je nadřazený ovladač sběrnice upozorněn, když zařízení zmizí ze sběrnice, a ovladač sběrnice zablokuje všechny následné pokusy o přístup k zařízení.

Ve Windows 98/Me správce PnP neodesílá tento IRP. Pokud uživatel odebere zařízení bez použití příslušného uživatelského rozhraní, správce PnP odešle na ovladače zařízení pouze IRP_MN_REMOVE_DEVICE požadavek. Všechny ovladače WDM musí zpracovávat IRP_MN_SURPRISE_REMOVAL i IRP_MN_REMOVE_DEVICE. Kód pro IRP_MN_REMOVE_DEVICE by měl zkontrolovat, jestli ovladač obdržel předchozí IRP s překvapením a měl by zpracovat oba případy.

Použití GUID_REENUMERATE_SELF_INTERFACE_STANDARD

Rozhraní GUID_REENUMERATE_SELF_INTERFACE_STANDARD umožňuje ovladači požádat o opětovné rozpoznání jeho zařízení.

Pokud chcete toto rozhraní použít, odešlete IRP_MN_QUERY_INTERFACE IRP ovladači sběrnice pomocí InterfaceType = GUID_REENUMERATE_SELF_INTERFACE_STANDARD. Ovladač sběrnice dodává ukazatel na strukturu REENUMERATE_SELF_INTERFACE_STANDARD, která obsahuje ukazatele na jednotlivé rutiny rozhraní. Rutina ReenumerateSelf vyžaduje, aby ovladač sběrnice znovu inicializoval podřízené zařízení.

Informace o PNP_DEVICE_STATE

Typ PNP_DEVICE_STATE je bitová maska, která popisuje stav PnP zařízení. Ovladač vrátí hodnotu tohoto typu v reakci na požadavek IRP_MN_QUERY_PNP_DEVICE_STATE .

typedef ULONG PNP_DEVICE_STATE, *PPNP_DEVICE_STATE;

Bity příznaků v hodnotě PNP_DEVICE_STATE jsou definovány následujícím způsobem.

Bit příznaku Popis
PNP_DEVICE_DISABLED (Zařízení PNP je deaktivováno)

Zařízení je fyzicky přítomné, ale je deaktivované v hardwaru.

PNP_DEVICE_DONT_DISPLAY_IN_UI

Nezobrazovat zařízení v uživatelském rozhraní. Nastavte pro zařízení, které je fyzicky přítomno, ale není použitelné v aktuální konfiguraci, například pro port pro hry na přenosném počítači, který není použitelný, když je přenosný počítač odpojen. (Viz také příznak NoDisplayInUI ve struktuře DEVICE_CAPABILITIES .)

Zařízení PnP selhalo

Zařízení se nachází, ale nefunguje správně.

Pokud je nastaven tento příznak i PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED, musí být zařízení zastaveno, než správce PnP přiřadí nové hardwarové prostředky (trvalé přeřazení prostředků pro toto zařízení není podporováno).

PNP_DEVICE_NOT_DISABLEABLE

Zařízení se vyžaduje při spuštění počítače. Takové zařízení se nesmí deaktivovat.

Ovladač nastaví tento bit pro zařízení, které je vyžadováno pro správnou systémovou operaci. Pokud například ovladač obdrží oznámení, že zařízení je ve stránkovací cestě (IRP_MN_DEVICE_USAGE_NOTIFICATION pro DeviceUsageTypePaging), ovladač zavolá IoInvalidateDeviceState a nastaví tento příznak ve výsledném požadavku IRP_MN_QUERY_PNP_DEVICE_STATE.

Pokud je tento bit nastavený pro zařízení, správce PnP toto nastavení předá nadřazenému zařízení, nadřazenému nadřazeného zařízení a tak dále.

Pokud je tento bit nastaven pro zařízení s kořenovou enumerací, zařízení nelze zakázat ani odinstalovat.

PNP_ZAŘÍZENÍ_ODSTRANĚNO

Zařízení bylo fyzicky odebráno.

PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED

Změnily se požadavky na prostředky pro zařízení.

Ovladač sběrnice obvykle nastaví tento příznak, když zjistí, že musí rozšířit požadavky na prostředky, aby bylo možné vytvořit výčet nového podřízeného zařízení.

PNP_ZAŘÍZENÍ_ODPOJENO

Ovladač zařízení se načte, ale tento ovladač zjistil, že zařízení už není připojené k počítači. Tento příznak se obvykle používá pro ovladače funkcí, které komunikují s bezdrátovými zařízeními. Příznak se například nastaví, když se zařízení přesune mimo rozsah, a vymaže se poté, co se zařízení vrátí do rozsahu a znovu se připojí.

Řidič autobusu obvykle nenastavuje tento příznak. Ovladač sběrnice by měl místo toho zastavit výčet podřízeného zařízení, pokud už zařízení není připojené. Tento příznak se používá pouze v případě, že ovladač funkce spravuje připojení.

Jediným účelem tohoto příznaku je dát klientům vědět, jestli je zařízení připojené. Nastavení příznaku nemá vliv na to, zda je ovladač načten.

Správce PnP dotazuje stav PNP_DEVICE_STATE zařízení ihned po jeho spuštění odesláním dotazu IRP_MN_QUERY_PNP_DEVICE_STATE ke zásobníku zařízení. V reakci na toto IRP ovladače zařízení nastavily příslušné příznaky v PNP_DEVICE_STATE.

Pokud se některá z charakteristik stavu po počátečním dotazu změní, ovladač upozorní správce PnP voláním IoInvalidateDeviceState. V reakci na volání IoInvalidateDeviceState se správce PnP znovu dotazuje na stav PNP_DEVICE_STATE daného zařízení.

Pokud je zařízení označeno jako PNP_DEVICE_NOT_DISABLEABLE, ladicí program zobrazí uživatelský příznak DNUF_NOT_DISABLEABLE pro devnode. Ladicí program také zobrazí hodnotu DisableableDepends, která uvádí počet důvodů, proč zařízení nelze deaktivovat. Tato hodnota je součet X+Y, kde X je jedna, pokud zařízení nelze zakázat, a Y je počet podřízených zařízení, která nelze zakázat.