Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W przypadku większości sterowników pośrednich i najniższych poziomów rozszerzenie urządzenia jest najważniejszą strukturą danych skojarzona z obiektem urządzenia. Jego wewnętrzna struktura jest definiowana przez sterownik i zwykle jest używana do:
Zachowaj informacje o stanie urządzenia.
Zapewnij przechowywanie dla dowolnych obiektów zdefiniowanych przez jądro lub innych zasobów systemowych, takich jak blokady spinowe, używane przez sterownik.
Przechowuj wszystkie dane, które sterownik musi mieć w przestrzeni systemowej, aby przeprowadzać operacje we/wy.
Ponieważ większość sterowników magistrali, funkcji i filtrów (sterowników najniższego i pośredniego poziomu) działa w kontekście dowolnego wątku (który w danej chwili jest bieżący), rozszerzenie urządzenia jest głównym elementem dla każdego sterownika do zarządzania stanem urządzenia i wszystkimi innymi danymi specyficznymi dla urządzenia, których sterownik potrzebuje. Na przykład każdy sterownik implementujący procedurę CustomTimerDpc lub CustomDpc zwykle zapewnia magazyn dla wymaganych obiektów czasomierza zdefiniowanego przez jądro i/lub DPC w rozszerzeniu urządzenia.
Każdy sterownik, który posiada ISR, musi zapewnić przechowywanie wskaźnika do zestawu obiektów przerwań zdefiniowanych przez jądro, a większość sterowników urządzeń przechowuje wskaźnik w rozszerzeniu urządzenia. Każdy sterownik określa rozmiar rozszerzenia urządzenia podczas tworzenia obiektu urządzenia, a każdy sterownik definiuje zawartość i strukturę własnych rozszerzeń urządzeń.
Procedury IoCreateDevice i IoCreateDeviceSecure Menedżera I/O przydzielają pamięć dla obiektu urządzenia i rozszerzenia z niestronicowanej puli pamięci.
Każda standardowa procedura sterownika odbierającego protokół IRP otrzymuje również wskaźnik do obiektu urządzenia reprezentującego urządzenie docelowe dla żądanej operacji we/wy. Te procedury sterowników mogą uzyskiwać dostęp do odpowiedniego rozszerzenia urządzenia za pośrednictwem tego wskaźnika. Zazwyczaj wskaźnik DeviceObject jest również parametrem wejściowym ISR sterownika poziomu najniższego.
Na poniższej ilustracji przedstawiono reprezentatywny zestaw danych określonych przez sterownik dla rozszerzenia urządzenia obiektu urządzenia sterownika najniższego poziomu. Sterownik wyższego poziomu nie zapewni magazynu dla wskaźnika obiektu przerwania zwróconego przez IoConnectInterrupt i przekazanego do KeSynchronizeExecution i IoDisconnectInterrupt. Jednak sterownik wyższego poziomu zapewnia magazyn dla obiektów czasomierza i DPC pokazanych na poniższej ilustracji, jeśli sterownik ma procedurę CustomTimerDpc . Sterownik wyższego poziomu może również zapewnić magazyn dla blokady spin executive i zablokowania kolejki pracy.
Oprócz zapewnienia pamięci dla wskaźnika obiektu przerwania, sterownik urządzenia najniższego poziomu musi dostarczyć pamięć dla spinlocka dla przerwań, jeśli jego ISR obsługuje przerwania dla dwóch lub więcej urządzeń na różnych wektorach lub jeśli ma więcej niż jeden ISR. Aby uzyskać więcej informacji na temat rejestrowania isr, zobacz Rejestrowanie isr.
Zazwyczaj sterowniki przechowują wskaźniki do obiektów urządzeń w rozszerzeniach urządzeń, jak pokazano na rysunku. Sterownik może również przechowywać kopię listy zasobów dla urządzenia w rozszerzeniu.
Sterownik urządzeń wyższego poziomu zazwyczaj przechowuje wskaźnik do obiektu urządzenia sterownika niższego poziomu w jego rozszerzeniu. Sterownik wyższego poziomu musi przekazać wskaźnik do obiektu urządzenia następnego niższego sterownika do funkcji IoCallDriver, po skonfigurowaniu lokalizacji stosu we/wy następnego niższego sterownika w IRP, zgodnie z opisem w temacie Obsługa IRP.
Należy również pamiętać, że każdy sterownik wyższego poziomu, który przydziela IRP-y dla sterowników niższego poziomu, musi określić, ile lokalizacji stosu mają mieć nowe IRP-y. W szczególności jeśli sterownik wyższego poziomu wywołuje IoMakeAssociatedIrp, IoAllocateIrp lub IoInitializeIrp, musi uzyskać dostęp do obiektu urządzenia docelowego sterownika następnego niższego poziomu, aby odczytać jego wartość StackSize, w celu podania poprawnego rozmiaru StackSize jako argumentu dla tych procedur pomocniczych.
Chociaż sterownik wyższego poziomu może odczytywać dane z obiektu urządzenia sterownika następnego niższego poziomu za pośrednictwem wskaźnika zwróconego przez IoAttachDeviceToDeviceStack, taki sterownik musi postępować zgodnie z następującymi wytycznymi implementacji:
Nigdy nie próbuj zapisywać danych w obiekcie urządzenia niższego sterownika.
Jedynymi wyjątkami od tych wytycznych są systemy plików, które ustawiają i usuwają DO_VERIFY_VOLUME w flagach obiektów urządzeń sterowników nośników wymiennych niższego poziomu.
Nigdy nie próbuj uzyskać dostępu do rozszerzenia urządzenia niższego sterownika z następujących powodów:
Nie ma bezpiecznego sposobu synchronizowania dostępu do jednego rozszerzenia urządzenia między dwoma sterownikami.
Nie można uaktualnić indywidualnie pary sterowników, które implementują taki schemat komunikacji typu backdoor; nie da się wstawić między nimi pośredniego sterownika bez zmiany istniejącego kodu źródłowego sterowników, a także nie można ich łatwo ponownie skompilować i przenieść z jednej platformy Windows na drugą.
Aby zachować współdziałanie z sterownikami niższego poziomu z jednej platformy lub wersji systemu Windows do następnej, sterowniki wyższego poziomu muszą ponownie użyć środowiska IRPs podane lub muszą utworzyć nowe środowiska IRPs i muszą używać usługi IoCallDriver do przekazywania żądań do sterowników niższego poziomu.