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.
Kierowcy wyższego poziomu mają inny zestaw standardowych procedur niż sterowniki urządzeń najniższego poziomu, z nakładającymi się podzbiorem standardowych procedur typowych dla obu typów sterowników.
Zestaw procedur dla kierowców pośrednich i najwyższych poziomów również różni się w zależności od następujących kryteriów:
Charakter bazowego urządzenia fizycznego
Określa, czy podstawowy sterownik urządzenia konfiguruje obiekty urządzeń dla operacji we/wy bezpośrednich lub buforowanych
Konstrukcja indywidualnego sterownika wyższego poziomu
Na poniższej ilustracji przedstawiono ścieżkę, którą IRP może przejść przez standardowe procedury pośredniego sterownika lustrzanego, umiejscowionego gdzieś nad najniższym poziomem sterownika urządzenia opisanego w poprzedniej sekcji.
Sterownik pokazany na poniższej ilustracji ma następujące cechy:
Sterownik jest warstwowany na więcej niż jedno urządzenie fizyczne, a także być może na więcej niż jeden sterownik urządzenia.
Sterownik czasami przydziela dodatkowe IRP dla sterowników niższego poziomu, w zależności od operacji żądanej w wejściowym IRP.
Sterownik ma co najmniej jeden sterownik systemu plików ułożony ponad nim, a sterownik systemu plików może być również ułożony ponad innymi sterownikami pośredniczącymi na wyższym poziomie niż ten sterownik.
Jak pokazano na rysunku, menedżer we/wy tworzy IRP i wysyła go do procedury obsługi sterownika dla danego kodu znaczącej funkcji. Zakładając, że kod funkcji jest IRP_MJ_WRITE, procedury wysyłania to DDDispatchWrite. Lokalizacja stosu we/wy pośredniego sterownika jest wyświetlana w środku z nieokreśloną liczbą lokalizacji stosu we/wy dla sterowników wyższego i niższego poziomu pokazanych w cieniu.
Przydzielanie IRPs
Sterownik dublowania służy do wysyłania żądań zapisu do kilku urządzeń fizycznych i wysyłania żądań odczytu alternatywnie do sterowników tych urządzeń. W przypadku żądań zapisu sterownik tworzy zduplikowane IRP dla każdego urządzenia, na którym mają być zapisywane dane, przy założeniu, że parametry w wejściowym IRP są prawidłowe.
Na poprzedniej ilustracji przedstawiono wywołanie funkcji IoAllocateIrp, ale sterowniki wyższego poziomu mogą wywoływać inne procedury pomocnicze w celu przydzielania IRP dla sterowników niższego poziomu. Zobacz Tworzenie adresów IRP dla sterowników Lower-Level.
Gdy procedura wysyłania wywołuje IoAllocateIrp, określa liczbę lokalizacji stosu we/wy wymaganych dla IRP. Sterownik musi określić lokalizację stosu dla każdego niższego sterownika w łańcuchu, uzyskując odpowiednią wartość z obiektów urządzenia każdego sterownika znajdującego się bezpośrednio pod sterownikiem lustrzanym. Opcjonalnie sterownik może dodać 1 do tej wartości przy wywołaniu IoAllocateIrp, aby uzyskać własną lokalizację stosu dla każdego przydzielanego przez niego IRP, tak jak sterownik na poprzedniej ilustracji.
Rutyna wysyłania tego pośredniego sterownika wywołuje funkcję IoGetCurrentIrpStackLocation (nie pokazano) z oryginalnym IRP, aby sprawdzić parametry.
Wywołuje metodę IoSetNextIrpStackLocation, ponieważ przydzieliła własną lokalizację stosu w każdym nowo utworzonym IRP oraz IoGetCurrentIrpStackLocation w celu utworzenia kontekstu, który później używa w procedurze IoCompletion.
Następnie wywołuje funkcję IoGetNextIrpStackLocation z każdym nowo utworzonym IRP, aby skonfigurować lokalizacje stosu I/O kolejnych sterowników niższego poziomu w przydzielonych IRP. Procedura wysyłania sterownika lustrzanego kopiuje kody funkcji IRP i parametry (wskaźnik do bufora transferu, długość w bajtach do przeniesienia w ramach IRP_MJ_WRITE) do lokalizacji stosu we/wy dla sterowników o niższej kolejności. Te sterowniki z kolei skonfigurują lokalizacje stosu we/wy dla sterowników tuż pod nimi, jeśli istnieją.
Wywoływanie metody IoSetCompletionRoutine i IoCallDriver
Procedura wysyłania na poprzedniej ilustracji wywołuje metodę IoSetCompletionRoutine dla każdego przydzielonego protokołu IRP. Ponieważ sterownik na poprzedniej ilustracji musi usunąć przydzielone elementy IRPs, ten sterownik ustawia procedurę IoCompletion , która ma być wywoływana, gdy niższe sterowniki zakończą swoje środowiska IRPs, niezależnie od tego, czy operacja we/wy została ukończona pomyślnie, nie powiodła się, czy została anulowana.
Ponieważ sterownik na poprzedniej ilustracji dubluje się równolegle, przekazuje oba środowiska IRPs przydzielone do sterowników następnego niższego poziomu przez wywołanie IoCallDriver dwa razy, raz dla każdego obiektu urządzenia docelowego reprezentującego dublowaną partycję.
Przetwarzanie pakietów IRP w procedurze IoCompletion sterownika
Gdy dowolny zestaw sterowników niższego poziomu ukończy żądaną operację, menedżer we/wy wywołuje procedurę IoCompletion pośredniego sterownika lustrzanego. Sterownik lustrzany utrzymuje licznik w swojej lokalizacji stosu I/O dla oryginalnego IRP, aby śledzić, kiedy niższe sterowniki zakończyły wszystkie zduplikowane IRP.
Zakładając, że blok stanu we/wy wskazuje, że jeden zestaw niższych sterowników zakończył zduplikowany protokół IRP pokazany na poprzedniej ilustracji, procedura IoCompletion sterownika dublowania zmniejsza jego liczbę, ale nie może ukończyć oryginalnego protokołu IRP, dopóki nie zmniejszy liczby do zera. Jeśli dekrementowana liczba nie jest jeszcze równa zero, procedura IoCompletion wywołuje metodę IoFreeIrp z pierwszą zwracaną wartością IRP (DupIRP1 na poprzedniej ilustracji), którą sterownik przydzielił i zwróci STATUS_MORE_PROCESSING_REQUIRED.
Gdy rutyna IoCompletion sterownika lustrzanego jest wywoływana ponownie z DupIRP2 pokazanym na wcześniejszej ilustracji, rutyna IoCompletion zmniejsza licznik w oryginalnym IRP i określa, że oba zestawy sterowników niższego poziomu przeprowadziły żądane operacje.
Zakładając, że blok stanu we/wy w DupIRP2 jest również ustawiony na STATUS_SUCCESS, procedura IoCompletion kopiuje blok stanu we/wy z DupIRP2 do oryginalnego IRP i zwalnia DupIRP2. Wywołuje IoCompleteRequest z oryginalnym IRP i zwraca STATUS_MORE_PROCESSING_REQUIRED. Zwracanie tego stanu uniemożliwia menedżerowi I/O podjęcie próby dalszego przetwarzania ukończenia na DupIRP2; ponieważ IRP nie jest skojarzony z wątkiem, jego przetwarzanie powinno zakończyć się na sterowniku, który go utworzył.
Jeśli którykolwiek z zestawów sterowników niższego poziomu nie ukończy pomyślnie IRP sterownika dublowania, procedura IoCompletion sterownika dublowania powinna rejestrować błąd i podejmować odpowiednie odzyskiwanie danych przez dublowanie. Aby uzyskać więcej informacji, zobacz Rejestrowanie błędów.