Sdílet prostřednictvím


Rozšíření zařízení

U většiny středně pokročilých a nejnižších ovladačů je rozšíření zařízení nejdůležitější datovou strukturou přidruženou k objektu zařízení. Jeho vnitřní struktura je definovaná ovladačem a obvykle se používá k:

  • Udržujte informace o stavu zařízení.

  • Poskytněte úložiště pro jakékoliv objekty definované jádrem nebo jiné systémové prostředky, jako jsou spin locky, používané ovladačem.

  • Aby mohl ovladač provádět své vstupně-výstupní operace, musí mít všechna data rezidentní v systémovém prostoru.

Vzhledem k tomu, že většina ovladačů sběrnice, funkčních a filtračních ovladačů (ovladače nejnižší úrovně a zprostředkující ovladače) běží v libovolném vláknovém kontextu (tedy v kontextu aktuálního vlákna), je rozšíření zařízení pro každý ovladač primárním místem pro udržování stavu zařízení a všech dalších dat specifických pro zařízení, která ovladač potřebuje. Například každý ovladač, který implementuje rutinu CustomTimerDpc nebo CustomDpc , obvykle poskytuje úložiště pro požadované objekty časovače definované jádrem nebo DPC v rozšíření zařízení.

Každý ovladač, který má isR, musí poskytovat úložiště pro ukazatel na sadu objektů přerušení definovaných jádrem a většina ovladačů zařízení tento ukazatel ukládá do rozšíření zařízení. Každý ovladač určuje velikost rozšíření zařízení při vytváření objektu zařízení a každý ovladač definuje obsah a strukturu vlastních rozšíření zařízení.

Rutiny IoCreateDevice a IoCreateDeviceSecure ve správci vstupně-výstupních operací přidělují paměť pro objekt zařízení a rozšíření z nestránkového fondu paměti.

Každá standardní rutina ovladače, která obdrží IRP, obdrží také ukazatel na objekt zařízení představující cílové zařízení pro požadovanou vstupně-výstupní operaci. Tyto rutiny ovladačů mají přístup k odpovídajícímu rozšíření zařízení prostřednictvím tohoto ukazatele. Ukazatel DeviceObject je obvykle také vstupním parametrem isR ovladače nejnižší úrovně.

Následující obrázek znázorňuje reprezentativní sadu dat definovaných ovladačem pro rozšíření zařízení objektu ovladače na nejnižší úrovni. Ovladač vyšší úrovně neposkytuje úložiště pro ukazatel objektu přerušení vrácený službou IoConnectInterrupt a předán do KeSynchronizeExecution a IoDisconnectInterrupt. Ovladač vyšší úrovně by však poskytoval úložiště pro objekty časovače a DPC zobrazené na následujícím obrázku, pokud má ovladač rutinu CustomTimerDpc . Ovladač vyšší úrovně může také poskytovat úložiště pro zámek vedení a vzájemně zamknutou pracovní frontu.

diagram znázorňující ukázkové rozšíření zařízení pro ovladač nejnižší úrovně

Kromě poskytování úložiště pro ukazatel objektu přerušení musí ovladač zařízení nejnižší úrovně poskytnout úložiště pro zámek přerušení, pokud jeho ISR zpracovává přerušení pro dvě nebo více zařízení v různých vektorech nebo pokud má více než jeden ISR. Další informace o registraci isR naleznete v tématu Registrace isR.

Ovladače obvykle ukládají ukazatele na objekty zařízení ve svých rozšířeních zařízení, jak je znázorněno na obrázku. Ovladač může také uchovávat kopii seznamu prostředků pro zařízení v rozšíření.

Ovladač vyšší úrovně obvykle ukládá ukazatel na objekt zařízení nižšího ovladače v rozšíření svého zařízení. Ovladač vyšší úrovně musí předat ukazatel na objekt zařízení dalšího nižšího ovladače do IoCallDriver, jakmile nastaví umístění vstupně-výstupního zásobníku dalšího nižšího ovladače v IRP, jak je vysvětleno v Zpracování IRPs.

Všimněte si také, že každý ovladač vyšší úrovně, který přiděluje IRP pro ovladače nižší úrovně, musí určit, kolik umístění zásobníku by nová IRP měla mít. Konkrétně platí, že pokud ovladač vyšší úrovně volá IoMakeAssociatedIrp, IoAllocateIrp nebo IoInitializeIrp, musí přistupovat k objektu cílového zařízení ovladače na další nižší úrovni, aby přečetl jeho hodnotu StackSize , aby bylo možné zadat správný StackSize jako argument pro tyto rutiny podpory.

Zatímco ovladač vyšší úrovně může číst data z objektu zařízení ovladače další nižší úrovně prostřednictvím ukazatele vráceného funkcí IoAttachDeviceToDeviceStack, takový ovladač musí postupovat podle těchto pokynů k implementaci:

  • Nikdy se nepokoušejte zapisovat data do objektu zařízení nižšího ovladače.

    Jedinými výjimkami tohoto pokynu jsou systémy souborů, které nastavují a vymažou DO_VERIFY_VOLUME v příznakech objektů zařízení ovladačů pro vyměnitelná média nižší úrovně.

  • Nikdy se nepokoušejte o přístup k rozšíření zařízení nižšího ovladače z následujících důvodů:

    • Neexistuje žádný bezpečný způsob synchronizace přístupu k jednomu rozšíření zařízení mezi dvěma ovladači.

    • Dvojici ovladačů, které implementují takové komunikační schéma backdooru, nejde upgradovat jednotlivě, nemůže mít mezi sebou vložený zprostředkující ovladač beze změny existujícího zdroje ovladačů a nelze je znovu zkompilovat a snadno přesunout z jedné platformy Windows na další.

Aby se zachovala jejich interoperabilita s ovladači nižší úrovně z jedné platformy nebo verze Windows na další, ovladače vyšší úrovně musí buď znovu použít tyto ip adresy, nebo musí vytvořit nové irps a musí použít IoCallDriver ke komunikaci požadavků na ovladače nižší úrovně.