Zpracování IRP v ovladači Intermediate-Level

Ovladače vyšší úrovně mají jinou sadu standardních rutin než ovladače zařízení nejnižší úrovně s překrývající se podmnožinou standardních rutin, které jsou společné pro oba typy ovladačů.

Sada rutin pro středně pokročilé a vysoce pokročilé ovladače se také liší podle následujících kritérií.

  • Povaha základního fyzického zařízení

  • Určuje, jestli základní ovladač zařízení nastavuje objekty zařízení pro přímou nebo bufferovanou vstupně-výstupní operaci.

  • Návrh individuálního ovladače vyšší úrovně

Následující obrázek znázorňuje cestu, kterou může IRP projít standardními rutinami mezilehlého ovladače zrcadla vrstvené někde nad ovladačem zařízení nejnižší úrovně popsaným v předchozí části.

Ovladač zobrazený na následujícím obrázku má následující charakteristiky:

  • Ovladač je vrstvený přes více než jedno fyzické zařízení a možná více než jeden ovladač zařízení.

  • Ovladač někdy přiděluje další IRP pro ovladače nižší úrovně, v závislosti na požadované operaci ve vstupním IRP.

  • Ovladač má alespoň jeden ovladač systému souborů vrstvený nad ním a tento ovladač systému souborů může být vrstvený nad jinými zprostředkujícími ovladači na vyšší úrovni než tento ovladač.

diagram znázorňující cestu IRP skrze rutiny pro mezilehlé ovladače

Jak znázorňuje obrázek, správce vstupně-výstupních operací vytvoří IRP a odešle ho do rutiny odeslání ovladače pro daný kód hlavní funkce. Za předpokladu, že kód funkce je IRP_MJ_WRITE, rutina dispatch je DDDispatchWrite. Umístění zásobníku vstupně-výstupních operací zprostředkujícího ovladače se zobrazuje uprostřed s neomezeným počtem umístění zásobníku vstupně-výstupních operací pro ovladače vyšší a nižší úrovně.

Přidělování IRP

Účelem ovladače zrcadla je posílat žádosti o zápis do několika fyzických zařízení a posílat žádosti o čtení alternativně ovladačům těchto zařízení. V případě požadavků na zápis ovladač vytvoří duplicitní IRP pro každé zařízení, na která se mají data zapisovat, za předpokladu, že parametry v zadaném IRP jsou platné.

Předchozí obrázek znázorňuje volání IoAllocateIrp , ale ovladače vyšší úrovně můžou volat jiné rutiny podpory pro přidělení irps pro ovladače nižší úrovně. Viz Vytváření IRP pro ovladače Lower-Level.

Když rutina odesílání volá IoAllocateIrp, určuje počet umístění vstupně-výstupních zásobníků potřebných pro IRP. Ovladač musí zadat umístění zásobníku pro každý nižší ovladač v řetězu a získat odpovídající hodnotu z objektů zařízení každého ovladače těsně pod ovladačem zrcadlení. Volitelně může ovladač přidat jednu z těchto hodnot, když volá IoAllocateIrp , aby získal vlastní umístění zásobníku pro každý IRP, který přiděluje, jak to dělá ovladač na předchozím obrázku.

Rutina odesílání tohoto zprostředkujícího ovladače volá rutinu IoGetCurrentIrpStackLocation (není zobrazena) s původním protokolem IRP pro kontrolu parametrů.

Volá IoSetNextIrpStackLocation , protože přidělil své vlastní umístění zásobníku v každém nově vytvořeném IRP a IoGetCurrentIrpStackLocation k vytvoření kontextu pro sebe, který používá později v rutině IoCompletion .

Dále volá IoGetNextIrpStackLocation s každým nově vytvořeným IRP, aby mohl nastavit umístění vstupně-výstupního stohu ovladačů na nižší úrovni v IRP, které přidělil. Rutina odesílání zrcadlového ovladače kopíruje kódy a parametry funkce IRP (ukazatel na vyrovnávací paměť přenosu, délka bajtů, které se mají přenést pro IRP_MJ_WRITE) do umístění zásobníku vstupně-výstupních operací pro další nižší ovladače. Tyto ovladače zase nastaví umístění vstupně-výstupního zásobníku pro ovladače přímo pod nimi, pokud nějaké existují.

Volání IoSetCompletionRoutine a IoCallDriver

Vysílací rutina v předchozím obrázku volá IoSetCompletionRoutine pro každý přidělený IRP. Vzhledem k tomu, že ovladač na předchozím obrázku musí zlikvidovat přidělené IRP, nastaví tento ovladač rutinu IoCompletion tak, aby se volala, když nižší ovladače dokončí jeho IRP, bez ohledu na to, zda vstupně-výstupní operace byla úspěšně dokončena, selhala nebo byla zrušena.

Vzhledem k tomu, že ovladač na předchozím obrázku zrcadlí paralelně, předá obě IRPs, které přidělil ovladačům nižší úrovně, tím, že dvakrát zavolá IoCallDriver, jednou pro každý objekt cílového zařízení, který představuje zrcadlený oddíl.

Zpracování irps v rutině IoCompletion ovladače

Když některý ze skupin ovladačů nižší úrovně dokončí požadovanou operaci, V/V manažer zavolá rutinu IoCompletion ovladače přechodného zrcadla. Ovladač zrcadla udržuje počet ve vlastním umístění vstupně-výstupního zásobníku pro původní IRP, aby sledoval, kdy nižší ovladače dokončily všechny duplicitní irps.

Za předpokladu, že blok stavu vstupně-výstupní operace indikuje, že jedna sada nižších ovladačů dokončila duplicitní vstupně-výstupní operaci zobrazenou na předchozím obrázku, rutina ovladače zrcadlení IoCompletion sníží jeho počet, ale nemůže dokončit původní IRP, dokud nesníží počet na nulu. Pokud dekrementovaný počet ještě není nulový, rutina IoCompletion volá IoFreeIrp s první vrácenou hodnotou IRP (DupIRP1 na předchozím obrázku), kterou ovladač přidělil a vrací STATUS_MORE_PROCESSING_REQUIRED.

Když je rutina IoCompletion ovladače zrcadla znovu volána s DupIRP2 zobrazeným na předchozím obrázku, rutina IoCompletion sníží počet v původním protokolu IRP a určí, že obě sady ovladačů nižší úrovně provedly požadované operace.

Za předpokladu, že je blok stavu vstupně-výstupních operací v dupIRP2 nastavený také s STATUS_SUCCESS, rutina IoCompletion zkopíruje blok stavu vstupně-výstupních operací z DupIRP2 do původního IRP a uvolní DupIRP2. Volá IoCompleteRequest s původním IRP a vrací STATUS_MORE_PROCESSING_REQUIRED. Vrácení tohoto stavu brání správci vstupně-výstupních operací v pokusu o jakékoli další zpracování dokončování na DupIRP2. Protože IRP není přidružen k vláknu, jeho zpracování dokončování by mělo končit u ovladače, který ho vytvořil.

Pokud některá ze sad ovladačů nižší úrovně nedokončí IRPs zrcadlového ovladače úspěšně, rutina IoCompletion ovladače zrcadlení by měla protokolovat chybu a pokusit se o obnovení relevantních zrcadlených dat. Další informace naleznete v tématu Chyby protokolování.