Delen via


IRPs maken voor Lower-Level-drivers

Als u een IRP wilt toewijzen voor een asynchrone aanvraag, die wordt verwerkt in een willekeurige threadcontext door lagere stuurprogramma's, kan een DispatchReadWrite routine een van de volgende ondersteuningsroutines aanroepen:

  • IoAllocateIrp, waarmee een IRP en een aantal nul-geïnitieerde I/O-stacklocaties worden toegewezen

    De verzendroutine moet de volgende lagere I/O-stacklocatie van het stuurprogramma voor de zojuist toegewezen IRP instellen, meestal door informatie te kopiëren (mogelijk gewijzigd) van zijn eigen stacklocatie in het oorspronkelijke IRP. Als een stuurprogramma op een hoger niveau een eigen I/O-stacklocatie toewijst voor een nieuw toegewezen IRP, kan de verzendroutine daar contextinformatie per aanvraag instellen voor de IoCompletion- routine die moet worden gebruikt.

  • IoBuildAsynchronousFsdRequest, waarmee de I/O-stacklocatie van het stuurprogramma voor de aanroeper wordt ingesteld op basis van parameters die door de aanroeper zijn opgegeven

    Stuurprogramma's op een hoger niveau kunnen deze routine aanroepen om IRP's toe te wijzen voor IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERSen IRP_MJ_SHUTDOWN aanvragen.

    Wanneer een IoCompletion- routine wordt aangeroepen voor een dergelijk IRP, kan deze het I/O-statusblok controleren en indien nodig (of mogelijk) de I/O-stacklocatie van de lager gelegen driver opnieuw instellen in de IRP en de aanvraag opnieuw uitvoeren of hergebruiken. De IoCompletion- routine heeft echter geen lokale contextopslag voor zichzelf in het IRP, dus moet de driver de context van de oorspronkelijke aanvraag ergens anders in het interne geheugen behouden.

  • IoMakeAssociatedIrp, waarmee een IRP en een aantal nul-geïnitialiseerde I/O-stacklocaties worden toegewezen en de IRP wordt gekoppeld aan een master IRP.

    Tussenliggende stuurprogramma's kunnen IoMakeAssociatedIrp niet aanroepen om IRP's aan te maken voor lagere stuurprogramma's.

    Elk stuurprogramma op het hoogste niveau dat IoMakeAssociatedIrp- aanroept om IRP's te maken voor lagere stuurprogramma's, kan de controle teruggeven aan de I/O-manager nadat de bijbehorende IRP's zijn verzonden en IoMarkIrpPending- voor de oorspronkelijke hoofd-IRP aanroept. Een stuurprogramma op het hoogste niveau kan afhankelijk zijn van de I/O-manager om de hoofd-IRP te voltooien wanneer alle bijbehorende IRP's zijn voltooid door lagere stuurprogramma's.

    Stuurprogramma's stellen zelden een IoCompletion- routine in voor een bijbehorende IRP. Als een stuurprogramma op het hoogste niveau IoSetCompletionRoutine aanroept voor een gekoppeld IRP dat het aanmaakt, voltooit de I/O-manager de master-IRP niet als het stuurprogramma STATUS_MORE_PROCESSING_REQUIRED retourneert van zijn IoCompletion routine. In deze omstandigheden moet de IoCompletion- routine van de driver expliciet de hoofd-IRP voltooien met IoCompleteRequest.

Als een stuurprogramma een eigen I/O-stacklocatie toewijst in een nieuwe IRP, moet de verzendroutine IoSetNextIrpStackLocation aanroepen voordat het IoGetCurrentIrpStackLocation aanroept om de context in zijn eigen I/O-stacklocatie voor de IoCompletion routine in te stellen. Zie Verwerken van IRPs in een Intermediate-Level Drivervoor meer informatie.

De verzendroutine moet IoMarkIrpPending aanroepen met de oorspronkelijke IRP, maar niet met door stuurprogramma's toegewezen IRP's, omdat de IoCompletion routine ze vrijgeeft.

Als de dispatchroutine IRP's toedeelt voor gedeeltelijke overdrachten en het onderliggende apparaatstuurprogramma een verwisselbaar media-apparaat kan beheren, moet de dispatchroutine de threadcontext instellen in de zojuist toegewezen IRP's van de waarde van Tail.Overlay.Thread in het oorspronkelijke IRP.

Een onderliggend stuurprogramma voor een verwisselbaar media-apparaat kan IoSetHardErrorOrVerifyDeviceaanroepen, en verwijst daarbij naar de pointer op Irp->Tail.Overlay.Thread, voor een IRP die door het stuurprogramma is toegewezen. Als het stuurprogramma deze ondersteuningsroutine aanroept, kan het stuurprogramma van het bestandssysteem een dialoogvenster verzenden naar de juiste gebruikersthread waarmee de gebruiker wordt gevraagd een bewerking te annuleren, opnieuw te proberen of een bewerking uit te voeren waaraan het stuurprogramma niet kan voldoen. Zie Ondersteuning voor verwisselbare media voor meer informatie.

Verzendroutines moeten STATUS_PENDING retourneren nadat alle door het stuurprogramma toegewezen IRPs naar lagere stuurprogramma's zijn verzonden.

De IoCompletion- routine van een stuurprogramma moet alle door het stuurprogramma toegewezen IRP's met IoFreeIrp- vrijlaten voordat het IoCompleteRequest voor de oorspronkelijke IRP aanroept. Wanneer het oorspronkelijke IRP is voltooid, moet de IoCompletion- routine alle door het stuurprogramma toegewezen IRP's vrijmaken voordat deze controle retourneert.

Elk stuurprogramma op een hoger niveau stelt alle door het stuurprogramma toegewezen (en hergebruikt) IRP's voor lagere stuurprogramma's zodanig in dat het niet relevant is voor het onderliggende apparaatstuurprogramma, ongeacht of een bepaalde aanvraag afkomstig is van een tussenliggend stuurprogramma of afkomstig is van een andere bron, zoals een bestandssysteem- of gebruikersmodustoepassing.

Stuurprogramma's op het hoogste niveau kunnen IoMakeAssociatedIrp- aanroepen om IRP's toe te wijzen en klaar te maken voor een reeks van lagere stuurprogramma's. De I/O-manager voltooit automatisch de oorspronkelijke IRP wanneer alle bijbehorende IR's zijn voltooid, zolang het stuurprogramma niet IoSetCompletionRoutine met de oorspronkelijke IRP of met een van de bijbehorende IR's die het toewijst, niet aanroept. Stuurprogramma's op het hoogste niveau mogen echter geen gekoppelde IR's toewijzen voor IRP's die een gebufferde I/O-bewerking aanvragen.

Een stuurprogramma op tussenliggend niveau kan geen IRP's toewijzen voor stuurprogramma's op een lager niveau door IoMakeAssociatedIrpaan te roepen. Een IRP die een tussenliggend stuurprogramma ontvangt, kan al een bijbehorende IRP zijn en een stuurprogramma kan geen andere IRP koppelen aan een dergelijke IRP.

Als een tussenliggend stuurprogramma IRP's voor lagere stuurprogramma's maakt, moet het in plaats daarvan IoAllocateIrp, IoBuildDeviceIoControlRequest, IoBuildSynchronousFsdRequestof IoBuildAsynchronousFsdRequestaanroepen. IoBuildSynchronousFsdRequest kan echter alleen in de volgende omstandigheden worden aangeroepen:

  • Door een thread die door het stuurprogramma is gemaakt om IRP's te bouwen voor lees- of schrijfaanvragen, omdat een dergelijke thread kan wachten in een niet-arbitraire threadcontext (eigen) op een dispatcherobject, zoals een door het stuurprogramma geïnitialiseerde Gebeurtenis doorgegeven aan IoBuildSynchronousFsdRequest

  • In de context van de systeemthread tijdens initialisatie of bij het ontladen.

  • IRP's bouwen voor inherent synchrone bewerkingen, zoals het maken, het leegmaken, het afsluiten, het sluiten en aanvragen voor apparaatbeheer.

Het is echter waarschijnlijker dat een stuurprogramma IoBuildDeviceIoControlRequest aanroept om IRP's voor apparaatbeheer toe te wijzen dan IoBuildSynchronousFsdRequest.