Delen via


Toegang tot gegevensbuffers in WDF-stuurprogramma's (KMDF of UMDF)

Wanneer een WDF-stuurprogramma (Windows Driver Frameworks) een I/O-beheeraanvraag voor lezen, schrijven of apparaat ontvangt, bevat het aanvraagobject een invoerbuffer, een uitvoerbuffer of beide.

Invoerbuffers bevatten informatie die het stuurprogramma nodig heeft. Voor schrijfaanvragen zijn deze gegevens doorgaans gegevens die een functiestuurprogramma naar een apparaat moet verzenden. Voor I/O-beheeraanvragen van apparaten kan een invoerbuffer informatie bevatten die aangeeft welk type bewerking het stuurprogramma moet uitvoeren.

Uitvoerbuffers ontvangen informatie van het stuurprogramma. Voor leesaanvragen zijn deze gegevens doorgaans gegevens die een functiestuurprogramma van een apparaat ontvangt. Voor I/O-beheeraanvragen van apparaten kan een uitvoerbuffer status of andere informatie ontvangen die is opgegeven door de I/O-beheercode van de aanvraag.

De techniek die uw stuurprogramma gebruikt voor toegang tot de gegevensbuffers van een aanvraag, is afhankelijk van de methode van het stuurprogramma voor het openen van gegevensbuffers voor een apparaat. Er zijn drie toegangsmethoden:

  • gebufferde invoer/uitvoer. De I/O-manager maakt tussenliggende buffers die worden gedeeld met het stuurprogramma.
  • Direct I/O. De I/O-manager vergrendelt de bufferruimte in fysiek geheugen en biedt het stuurprogramma directe toegang tot de bufferruimte.
  • geen gebufferde of directe I/O-. De I/O-manager biedt het stuurprogramma de virtuele adressen van de bufferruimte van de aanvraag. De I/O-manager valideert de bufferruimte van de aanvraag niet, dus moet het stuurprogramma controleren of de bufferruimte toegankelijk is en de bufferruimte vergrendelen in fysiek geheugen.

Een Kernel-Mode KMDF-stuurprogramma (Driver Framework) kan een van de drie toegangsmethoden gebruiken. Een stuurprogramma van User-Mode Driver Framework (UMDF) kan gebufferde of directe I/O gebruiken voor lees-, schrijf- en IOCTL-aanvragen en kan aanvragen converteren die de METHOD_NEITHER methodeopgeven.

buffertoegangsmethode opgeven

KMDF-stuurprogramma's

Voor lees- en schrijfaanvragen moeten alle stuurprogramma's in een stuurprogrammastack dezelfde methode gebruiken voor toegang tot de buffers van een apparaat, met uitzondering van het stuurprogramma op het hoogste niveau, dat de methode 'geen van beide' kan gebruiken, ongeacht welke methode wordt gebruikt door lagere stuurprogramma's.

Vanaf versie 1.13 geeft een KMDF-stuurprogramma de toegangsmethode op voor alle lees- en schrijfaanvragen van een apparaat door het aanroepen van WdfDeviceInitSetIoTypeEx voor elk apparaat. Als een stuurprogramma bijvoorbeeld de gebufferde I/O-methode opgeeft voor een van de apparaten, gebruikt de I/O-manager de methode voor gebufferde I/O bij het leveren van lees- en schrijfaanvragen aan het stuurprogramma voor dat apparaat.

Voor I/O-beheeraanvragen van apparaten bevat de I/O-besturingscode (IOCTL) bits die de buffertoegangsmethode opgeven. Als gevolg hiervan hoeft een KMDF-stuurprogramma geen actie te ondernemen om een buffermethode voor IOCTL's te selecteren. Zie I/O-besturingscodes definiërenvoor meer informatie over IOCTL's. In tegenstelling tot lees- en schrijfaanvragen hoeven alle IOCTL's van een apparaat niet dezelfde toegangsmethode op te geven.

UMDF-stuurprogramma's

Een UMDF-stuurprogramma specificeert voorkeuren voor de toegangsmethode die het framework gebruikt voor lees- en schrijfaanvragen, evenals I/O-beheeraanvragen voor apparaten. De waarden die een UMDF-stuurprogramma biedt, zijn alleen voorkeuren en worden niet gegarandeerd door het framework gebruikt. Zie Buffertoegangsmethoden beheren in UMDF-stuurprogramma'svoor meer informatie.

Een UMDF-stuurprogramma specificeert de toegangsmethode voor alle lees-, schrijf- en IOCTL-aanvragen van een apparaat door voor elk apparaat WdfDeviceInitSetIoTypeEx- aan te roepen. Als een stuurprogramma bijvoorbeeld de opgeslagen I/O-methode voor een van de apparaten opgeeft, gebruikt het framework de in buffer geplaatste I/O-methode bij het leveren van lees-, schrijf- en IOCTL-aanvragen aan het stuurprogramma voor dat apparaat.

Let op het verschil in buffertoegangstechniek voor IOCTL's tussen KMDF en UMDF. KMDF-stuurprogramma's geven geen buffertoegangsmethode op voor IOCTLs, terwijl UMDF-stuurprogramma's wel de buffertoegangsmethode voor IOCTL's opgeven.

Als een WDF-stuurprogramma de buffer van een I/O-aanvraag beschrijft met behulp van een techniek die onjuist is voor de I/O-methode die een I/O-doel gebruikt, corrigeert het framework de beschrijving van de buffer. Als een stuurprogramma bijvoorbeeld een MDL gebruikt om een buffer te beschrijven die wordt doorgegeven aan WdfIoTargetSendReadSynchronously, en als het I/O-doel gebruikmaakt van gebufferde I/O (waarvoor buffers moeten worden opgegeven met behulp van virtuele adressen in plaats van MCL's), converteert het framework de bufferbeschrijving van een MDL naar een virtueel adres en lengte. Het is echter efficiënter als uw stuurprogramma buffers in de juiste indeling opgeeft.

Zie Memory Buffers gebruikenvoor informatie over frameworkgeheugenobjecten, lookaside-lijsten, MDL's en lokale buffers.

Zie levenscyclus van geheugenbuffersvoor informatie over wanneer geheugenbuffers worden verwijderd.

toegang tot gegevensbuffers voor gebufferde I/O

Als uw stuurprogramma gebruikmaakt van gebufferde I/O, verandert het gedrag ervan, afhankelijk van het type gegevensaanvraag en of het KMDF of UMDF gebruikt.

KMDF-stuurprogramma's

Wanneer een KMDF-stuurprogramma gebruikmaakt van gebufferde I/O, maakt de I/O-manager één tussenliggende buffer waartoe het stuurprogramma toegang heeft voor elk type aanvraag. Dit is wat er gebeurt:

  • Schrijfaanvragen. De I/O-manager draagt invoergegevens over van de invoerbuffer van de aanroepende app voordat de stuurprogrammastack wordt aangeroepen. Vervolgens leest het KMDF-stuurprogramma invoergegevens van de tussenliggende buffer en schrijft het naar het apparaat.
  • Leesaanvragen. Het KMDF-stuurprogramma leest informatie van het apparaat en slaat deze op in de tussenliggende buffer. Vervolgens kopieert de I/O-manager de uitvoergegevens van de tussenliggende buffer naar de uitvoerbuffer van de app.
  • Beheeraanvragen voor apparaat-I/O. Het KMDF-stuurprogramma leest of schrijft gegevens voor die aanvraag naar of van de tussenliggende buffer.

UMDF-stuurprogramma's

Wanneer een UMDF-stuurprogramma gebruikmaakt van gebufferde I/O, maakt het hostproces van het stuurprogramma een of twee tussenliggende buffers, afhankelijk van het type aanvraag. Dit is wat er gebeurt:

  • Schrijfaanvragen. Het framework maakt één buffer, draagt invoergegevens over van de invoerbuffer van de aanroepende app en roept vervolgens de stuurprogrammastack aan. Het UMDF-stuurprogramma leest invoergegevens van de tussenliggende buffer en schrijft deze naar het apparaat.
  • Leesaanvragen. Een UMDF-stuurprogramma leest informatie van een apparaat en slaat deze op in een buffer die door het framework is gemaakt. Het hostproces van het stuurprogramma kopieert de uitvoergegevens van de tussenliggende buffer naar de uitvoerbuffer van de app.
  • Beheeraanvragen voor apparaat-I/O. Het framework maakt twee buffers die overeenkomen met invoer- en uitvoerbuffers van de IOCTL waartoe het stuurprogramma toegang heeft. Het framework kopieert de invoergegevens van de IOCTL naar de nieuwe tussenliggende buffer en maakt deze beschikbaar voor het stuurprogramma. Het framework kopieert de inhoud van de uitvoerbuffer niet, dus het stuurprogramma mag er niet vanuit proberen te lezen (anders worden er garbagegegevens gelezen). Alle gegevens die het stuurprogramma naar de uitvoerbuffer schrijft, worden terug gekopieerd naar de oorspronkelijke IOCTL-buffer en worden geretourneerd naar de app nadat de I/O-aanvraag is voltooid. Houd er rekening mee dat alle gegevens die het stuurprogramma naar de invoerbuffer schrijft, worden verwijderd en niet worden geretourneerd naar de aanroepende app.

Als u een ingang wilt ophalen naar een frameworkgeheugenobject dat de buffer vertegenwoordigt, roepen KMDF- en UMDF-stuurprogramma's WdfRequestRetrieveInputMemory of WdfRequestRetrieveOutputMemoryaan, afhankelijk van of dit een lees- of schrijfaanvraag is. Het stuurprogramma kan vervolgens een aanwijzer naar de buffer ophalen door WdfMemoryGetBufferaan te roepen. Als u de buffer wilt lezen en schrijven, roept het stuurprogramma WdfMemoryCopyFromBuffer of WdfMemoryCopyToBufferaan.

Als u het virtuele adres en de lengte van de buffer wilt ophalen, roept het stuurprogramma WdfRequestRetrieveInputBuffer of WdfRequestRetrieveOutputBufferaan.

Als een KMDF-stuurprogramma een lijst met geheugendescriptors (MDL) voor de buffer wil toewijzen en bouwen, roept het WdfRequestRetrieveInputWdmMdl of WdfRequestRetrieveOutputWdmMdl aan.

toegang tot gegevensbuffers voor directe I/O

KMDF-stuurprogramma's

Als uw stuurprogramma directe I/O gebruikt, controleert de I/O-manager de toegankelijkheid van de bufferruimte die de oorspronkelijke bron van de I/O-aanvraag (meestal een gebruikersmodustoepassing) heeft opgegeven, vergrendelt de bufferruimte in het fysieke geheugen en geeft het stuurprogramma vervolgens directe toegang tot de bufferruimte.

UMDF-stuurprogramma's

Als uw stuurprogramma een voorkeur voor directe I/O heeft opgegeven en aan alle UMDF-vereisten voor directe I/O is voldaan (zie Methoden voor buffertoegang beheren in UMDF-stuurprogramma's), wijst het framework de geheugenbuffer toe die het ontvangt van de I/O-manager rechtstreeks naar de adresruimte van het hostproces van het stuurprogramma en biedt het stuurprogramma dus directe toegang tot de bufferruimte.

Als u een ingang wilt ophalen naar een frameworkgeheugenobject dat de bufferruimte vertegenwoordigt, roept het stuurprogramma WdfRequestRetrieveInputMemory of WdfRequestRetrieveOutputMemoryaan. Het stuurprogramma kan vervolgens een aanwijzer naar de buffer ophalen door WdfMemoryGetBufferaan te roepen. Als u de buffer wilt lezen en schrijven, roept het stuurprogramma WdfMemoryCopyFromBuffer of WdfMemoryCopyToBufferaan.

Om het virtuele adres en de lengte van de bufferruimte op te halen, roept het stuurprogramma WdfRequestRetrieveInputBuffer of WdfRequestRetrieveOutputBufferaan.

Als de stuurprogramma's van een apparaat directe I/O gebruiken, beschrijft de I/O-manager buffers met behulp van MCL's. Om een aanwijzer naar de MDL van een buffer op te halen, roept een KMDF-stuurprogramma WdfRequestRetrieveInputWdmMdl of WdfRequestRetrieveOutputWdmMdlaan. Een UMDF-stuurprogramma heeft geen toegang tot MDL's.

toegang tot gegevensbuffers voor niet-gebufferde of directe I/O

KMDF-stuurprogramma's

Als uw stuurprogramma gebruikmaakt van de buffertoegangsmethode die bekendstaat als de geen van beide gebufferde I/O-methoden of directe I/O-methode (of de methode 'geen van beide'), biedt de I/O-manager gewoon de virtuele adressen die de origineel verstrekker van het I/O-verzoek heeft opgegeven voor de bufferruimte van de aanvraag. De I/O-beheerfunctie valideert de bufferruimte van de I/O-aanvraag niet, dus moet het stuurprogramma controleren of de bufferruimte toegankelijk is en de bufferruimte vergrendelen in fysiek geheugen.

De virtuele adressen die door de I/O-manager worden verstrekt, kunnen alleen worden geopend in de procescontext van de originator van de I/O-aanvraag. Alleen het stuurprogramma op het hoogste niveau in de stuurprogrammastack wordt gegarandeerd uitgevoerd in de procescontext van de originator.

Als u toegang wilt krijgen tot de bufferruimte van een I/O-aanvraag, moet het stuurprogramma op het hoogste niveau een EvtIoInCallerContext callback-functie opgeven. Het framework roept deze callback-functie aan telkens wanneer deze een I/O-aanvraag voor het stuurprogramma ontvangt.

Als de buffertoegangsmethode van een aanvraag geen van beide is, moet een KMDF-stuurprogramma het volgende doen voor elke buffer:

  1. Roep WdfRequestRetrieveUnsafeUserInputBuffer of WdfRequestRetrieveUnsafeUserOutputBuffer aan om het virtuele adres van de buffer te verkrijgen.

  2. Roep WdfRequestProbeAndLockUserBufferForRead of WdfRequestProbeAndLockUserBufferForWrite aan om de buffer te testen en te vergrendelen en een ingang te verkrijgen voor een frameworkgeheugenobject voor de buffer.

  3. Sla de geheugenobjectgrepen op in de contextruimte van de aanvraag.

  4. Roep WdfDeviceEnqueueRequestaan, waarmee de aanvraag wordt geretourneerd naar het framework.

Het framework voegt de aanvraag vervolgens toe aan een van de I/O-wachtrijen van het stuurprogramma. Als het stuurprogramma aanvraaghandlersheeft verstrekt, roept het framework uiteindelijk de juiste aanvraaghandler aan.

De verzoekhandler kan de geheugenobjecthandvatten van het verzoek ophalen uit de contextruimte van het verzoek. Het stuurprogramma kan de handvatten doorgeven aan WdfMemoryGetBuffer om het adres van de buffer te verkrijgen.

Af en toe moet een stuurprogramma op het hoogste niveau de voorgaande stappen gebruiken om toegang te krijgen tot een buffer in de gebruikersmodus, zelfs als het stuurprogramma de toegangsmethode 'geen van beide' gebruikt. Stel dat het stuurprogramma gebruikmaakt van gebufferde I/O. Een I/O-besturingscode die gebruikmaakt van de gebufferde toegangsmethode, kan een structuur met een ingesloten aanwijzer doorgeven aan een buffer in de gebruikersmodus. In dat geval moet het stuurprogramma een EvtIoInCallerContext callback-functie opgeven waarmee de aanwijzers uit de structuur worden geëxtraheerd en vervolgens de voorgaande stappen 2 tot en met 4 worden gebruikt.

UMDF-stuurprogramma’s

UMDF biedt geen ondersteuning voor buffers of directe I/O-typebuffers, dus een UMDF-stuurprogramma hoeft dit type buffer nooit rechtstreeks te verwerken.

Als het framework echter dergelijke buffers ontvangt voor lezen of schrijven van de I/O-manager, maakt het deze beschikbaar voor een UMDF-stuurprogramma als gebufferde I/O of directe I/O, afhankelijk van de toegangsmethode die door het stuurprogramma is geselecteerd. Als het framework een IOCTL ontvangt die de buffermethode 'geen van beide' opgeeft, kan het eventueel de buffertoegangsmethode van de IOCTL-aanvraag converteren naar een gebufferde I/O of directe I/O op basis van de aanwezigheid van een INF-instructie. Zie Methoden voor buffertoegang beheren in UMDF-stuurprogramma's voor meer informatie.