Tworzenie pakietów żądań wejścia/wyjścia (IRPs) dla sterowników Lower-Level
Aby przydzielić protokół IRP dla żądania asynchronicznego, który zostanie przetworzony w dowolnym kontekście wątku przez niższe sterowniki, dispatchReadWrite procedury mogą wywołać jedną z następujących procedur pomocy technicznej:
IoAllocateIrp, która przydziela pakiet żądań IRP i wiele lokalizacji stosu we/wy zainicjowanych zerami
Procedura wysyłania musi skonfigurować lokalizację stosu we/wy następnego niższego sterownika dla nowo przydzielonej IRP, zwykle przez skopiowanie (ewentualnie zmodyfikowanych) informacji z własnej lokalizacji stosu w oryginalnej IRP. Jeśli sterownik wyższego poziomu przydziela własną lokalizację stosu we/wy dla nowo przydzielonego IRP, procedura obsługi żądań może skonfigurować tam informacje kontekstowe dla IoCompletion w celu użycia.
IoBuildAsynchronousFsdRequest, który konfiguruje lokalizację stosu we/wy następnego niższego sterownika dla elementu wywołującego, zgodnie z parametrami określonymi przez obiekt wywołujący
Sterowniki wyższego poziomu mogą wywoływać tę procedurę w celu przydzielenia IRP dla następujących żądań: IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, oraz IRP_MJ_SHUTDOWN.
Po wywołaniu procedury IoCompletion dla takiego protokołu IRP można sprawdzić blok stanu we/wy, a w razie potrzeby (lub możliwe) skonfigurować lokalizację stosu we/wy następnego niższego sterownika w IRP i ponowić próbę żądania lub użyć go ponownie. Jednakże, rutyna IoCompletion nie ma lokalnego magazynu kontekstu dla siebie w ramach IRP, więc sterownik musi przechowywać informacje o pierwotnym żądaniu w innym miejscu w pamięci operacyjnej.
IoMakeAssociatedIrp, który przydziela protokół IRP i wiele lokalizacji stosu we/wy ze zera i kojarzy protokół IRP z master IRP.
Sterowniki pośrednie nie mogą wywoływać IoMakeAssociatedIrp w celu tworzenia IRP dla niższych sterowników.
Każdy sterownik najwyższego poziomu, który wywołuje IoMakeAssociatedIrp, aby utworzyć IRP dla niższych sterowników, może zwrócić kontrolę do menedżera we/wy po wysłaniu skojarzonych IRP i wywołaniu IoMarkIrpPending dla oryginalnego głównego IRP. Sterownik najwyższego poziomu może polegać na menedżerze we/wy, aby ukończyć główny IRP, gdy wszystkie powiązane IRP zostaną ukończone przez sterowniki niższych poziomów.
Sterowniki rzadko ustawiają procedurę IoCompletion dla skojarzonego protokołu IRP. Jeśli sterownik najwyższego poziomu wywołuje IoSetCompletionRoutine dla skojarzonego protokołu IRP, który tworzy, menedżer we/wy nie ukończy głównego protokołu IRP, jeśli sterownik zwróci STATUS_MORE_PROCESSING_REQUIRED z jego IoCompletion procedury. W takich okolicznościach IoCompletion sterownika procedury musi jawnie ukończyć główny protokół IRP przy użyciu IoCompleteRequest.
Jeśli sterownik przydziela własną lokalizację stosu wejścia/wyjścia w nowym IRP, procedura dyspozycji musi wywołać IoSetNextIrpStackLocation przed wywołaniem IoGetCurrentIrpStackLocation, aby skonfigurować kontekst we własnej lokalizacji stosu we/wy dla procedury IoCompletion. Aby uzyskać więcej informacji, zobacz Przetwarzanie IRP w sterowniku Intermediate-Level.
Rutyna wysyłania musi wywołać IoMarkIrpPending z oryginalnym IRP, ale nie z żadnymi przydzielonymi przez sterownik IRP, ponieważ IoCompletion rutyna je uwolni.
Jeśli procedura wysyłania przydziela IRPs na potrzeby transferów częściowych, a bazowy sterownik urządzenia może kontrolować urządzenie z nośnikiem wymiennym, procedura wysyłania musi skonfigurować kontekst wątku w nowo przydzielonych IRPs, wykorzystując wartość z Tail.Overlay.Thread w oryginalnym IRP.
Bazowy sterownik urządzenia nośnika wymiennego może wywołać IoSetHardErrorOrVerifyDevice, który odwołuje się do wskaźnika w Irp->Tail.Overlay.Thread, dla alokowanego przez sterownik IRP. Jeśli sterownik wywołuje tę procedurę pomocy technicznej, sterownik systemu plików może wysłać okno dialogowe do odpowiedniego wątku użytkownika, który monituje użytkownika o anulowanie, ponawianie próby lub niepowodzenie operacji, których sterownik nie może spełnić. Aby uzyskać więcej informacji, zobacz Obsługa nośników wymiennych.
Procedury wysyłania muszą zwracać STATUS_PENDING po wysłaniu wszystkich IRP przydzielonych przez sterownik do niższych sterowników.
IoCompletion rutynowe kierowcy powinny zwolnić wszystkie IRP-y przydzielone przez sterownik z IoFreeIrp zanim wywoła IoCompleteRequest dla oryginalnego IRP. Po zakończeniu oryginalnego protokołu IRP procedury IoCompletion musi zwolnić wszystkie przydzielone sterowniki irps, zanim zwróci kontrolę.
Każdy sterownik wyższego poziomu konfiguruje przydzielone (i ponownie używane) IRP w taki sposób, że dla bazowego sterownika urządzenia bez znaczenia jest, czy dane żądanie pochodzi ze sterownika pośredniego, czy z dowolnego innego źródła, na przykład z systemu plików lub aplikacji użytkownika.
Sterowniki najwyższego poziomu mogą wywoływać IoMakeAssociatedIrp w celu przydzielenia IRP i skonfigurowania ich w łańcuchu niższych sterowników. Menedżer we/wy automatycznie kończy oryginalny IRP po zakończeniu wszystkich skojarzonych z nim IRP, o ile sterownik nie wywołuje IoSetCompletionRoutine z oryginalnym IRP lub żadnym ze skojarzonych IRP, które przydziela. Sterowniki najwyższego szczebla nie mogą jednak przydzielić skojarzonych IRP dla dowolnego IRP, który żąda buforowanej operacji we/wy.
Sterownik poziomu pośredniego nie może przydzielić IRP dla sterowników niższego poziomu, wywołując IoMakeAssociatedIrp. Każdy protokół IRP odbierany przez pośredni sterownik może być już skojarzony z IRP, a sterownik nie może skojarzyć innego protokołu IRP z takim IRP.
Zamiast tego, jeśli sterownik pośredni tworzy IRP dla niższych sterowników, powinien wywołać IoAllocateIrp, IoBuildDeviceIoControlRequest, IoBuildSynchronousFsdRequestlub IoBuildAsynchronousFsdRequest. Jednak IoBuildSynchronousFsdRequest można wywołać tylko w następujących okolicznościach:
Przez wątek utworzony przez sterownik do kompilowania adresów IP dla żądań odczytu lub zapisu, ponieważ taki wątek może czekać w kontekście wątku niearbitrary (własnym) na obiekcie dyspozytora, na przykład zainicjowane przez sterownik zdarzenie przekazane do IoBuildSynchronousFsdRequest
W kontekście wątku systemowego podczas inicjowania lub przy rozładowywaniu
Aby utworzyć adresy IRPs dla z natury synchronicznych operacji, np. tworzenie, opróżnianie, zamknięcie, zamykanie i żądania sterowania urządzeniem
Jednak bardziej prawdopodobne jest, że sterownik wywoła IoBuildDeviceIoControlRequest, aby przydzielić IRP do kontroli urządzenia niż IoBuildSynchronousFsdRequest.