Sammanfattning av läs-/skrivrutiner

Tänk på följande när du implementerar en DispatchRead-, DispatchWrite- eller DispatchReadWrite-rutin :

  • Det är den högsta drivrutinens ansvar i en kedja med skiktade drivrutiner att kontrollera parametrarna för inkommande läs-/skriv-IRP:er för giltighet innan du konfigurerar drivrutinens I/O-stackplats på nästa lägre nivå i en IRP.

  • Mellanliggande och lågnivådrivrutiner kan i allmänhet förlita sig på drivrutinen på högsta nivån i kedjan för att skicka överföringsbegäranden med giltiga parametrar. Alla drivrutiner kan dock utföra sanitetskontroller på parametrarna på dess I/O-stackplats för en IRP, och varje enhetsdrivrutin bör kontrollera parametrarna för villkor som kan bryta mot eventuella begränsningar som införts av enheten.

  • Om en DispatchReadWrite-rutin slutför en IRP med ett fel bör den ange I/O-stackens platsstatusmedlem med ett lämpligt värde av NTSTATUS-typ, ange informationsmedlemmen till noll och anropa IoCompleteRequest med IRP och en PriorityBoost för IO_NO_INCREMENT.

  • Om en drivrutin använder buffrad I/O kan den behöva definiera en struktur som ska innehålla data som ska överföras och kan behöva buffra ett visst antal av dessa strukturer internt.

  • Om en drivrutin använder direkt I/O kan den behöva kontrollera om MDL på Irp-MdlAddress> beskriver en buffert som innehåller för mycket data (eller för många sidbrytningar) för att den underliggande enheten ska kunna hantera i en enda överföringsåtgärd. I så fall måste drivrutinen dela upp den ursprungliga överföringsbegäran i en sekvens med mindre överföringsåtgärder.

    En nära kopplad klassdrivrutin skulle kunna dela upp en sådan begäran i sin DispatchReadWrite-rutin för sin underliggande portdrivrutin. SCSI-klassdrivrutiner, särskilt för masslagringsenheter, krävs för att göra detta. Mer information om kraven för SCSI-drivrutiner finns i Lagringsdrivrutiner.

  • En lägre nivå av enhetsdrivrutinens DispatchReadWrite-rutin bör skjuta upp uppdelningen av en stor överföringsbegäran till partiella överföringar tills en annan drivrutinsrutin tar bort IRP för att konfigurera enheten för överföringen.

  • Om en enhetsdrivrutin på lägre nivå köar en läs-/skriv-IRP för vidare bearbetning av sina egna rutiner måste den anropa IoMarkIrpPending innan den köar IRP:n. DispatchReadWrite-rutinen måste också returnera kontrollen med STATUS_PENDING under dessa omständigheter.

  • Om DispatchReadWrite-rutinen skickar en IRP till lägre drivrutiner måste den konfigurera I/O-stackplatsen för den nästa lägre drivrutinen i IRP.If the DispatchReadWrite routine passes an IRP on to lower drivers, it must set up the I/O stack location for the next-lower driver in the IRP. Om drivrutinen på högre nivå också sätter en IoCompletion-rutin i IRP innan den skickas vidare med IoCallDriver beror på drivrutinens design och de drivrutiner som är inlagda under den.

    En drivrutin på högre nivå måste dock anropa IoSetCompletionRoutine innan den anropar IoCallDriver om den allokerar några resurser, till exempel IP-adresser eller minne. Dess IoCompletion-rutin måste frigöra alla drivrutinsallokerade resurser när lägre drivrutiner har slutfört begäran, men innan IoCompletion-rutinen anropar IoCompleteRequest med den ursprungliga IRP:en.

  • Om en drivrutin på högre nivå allokerar IP-adresser för lägre drivrutiner som kan innehålla en underliggande drivrutin för flyttbara medier måste allokeringsdrivrutinen upprätta trådkontexten i varje IRP som den allokerar.