WdfDeviceInitAssignWdmIrpPreprocessCallback-Funktion (wdfdevice.h)

[Gilt nur für KMDF]

Die WdfDeviceInitAssignWdmIrpPreprocessCallback-Methode registriert eine Rückruffunktion, um einen IRP-Hauptfunktionscode und optional einen oder mehrere Nebenfunktionscodes zu verarbeiten, die dem Hauptfunktionscode zugeordnet sind.

Syntax

NTSTATUS WdfDeviceInitAssignWdmIrpPreprocessCallback(
  [in]           PWDFDEVICE_INIT                  DeviceInit,
  [in]           PFN_WDFDEVICE_WDM_IRP_PREPROCESS EvtDeviceWdmIrpPreprocess,
  [in]           UCHAR                            MajorFunction,
  [in, optional] PUCHAR                           MinorFunctions,
  [in]           ULONG                            NumMinorFunctions
);

Parameter

[in] DeviceInit

Ein Zeiger auf eine WDFDEVICE_INIT-Struktur .

[in] EvtDeviceWdmIrpPreprocess

Ein Zeiger auf die EvtDeviceWdmIrpPreprocess-Rückruffunktion des Treibers.

[in] MajorFunction

Einer der IRP-Hauptfunktionscodes, die in wdm.h definiert sind.

[in, optional] MinorFunctions

Ein Zeiger auf ein Array aus einem oder mehreren IRP-Nebenfunktionscodes, die dem angegebenen Hauptfunktionscode zugeordnet sind. Dieser Parameter ist optional und kann NULL sein. Weitere Informationen finden Sie im folgenden Abschnitt "Hinweise".

[in] NumMinorFunctions

Die Anzahl der Nebenfunktionscodes, die im MinorFunctions-Array enthalten sind.

Rückgabewert

Wenn der Vorgang erfolgreich ist, gibt die Methode STATUS_SUCCESS zurück. Weitere Rückgabewerte sind:

Rückgabecode Beschreibung
STATUS_INVALID_PARAMETER
Der MajorFunction-Wert ist ungültig.
STATUS_INSUFFICIENT_RESOURCES
Es ist nicht genügend Arbeitsspeicher vorhanden.
STATUS_INVALID_DEVICE_REQUEST
Der Treiber hat zuvor ein MinorFunctions-Array für diese Hauptfunktion registriert und versucht erneut, Nebenfunktionen für den angegebenen MajorFunction-Code anzugeben.
 

Die -Methode gibt möglicherweise andere NTSTATUS-Werte zurück.

Hinweise

Treiber können die WdfDeviceInitAssignWdmIrpPreprocessCallback-Methode aus zwei Gründen aufrufen:

  • Um einen IRP-Haupt- oder Nebenfunktionscode zu behandeln, der vom Framework nicht unterstützt wird.

    Das Framework unterstützt beispielsweise keine IRP_MJ_FLUSH_BUFFERS. Wenn Ihr Treiber diese IRP unterstützen muss, muss er eine EvtDeviceWdmIrpPreprocess-Rückruffunktion registrieren, die die IRP verarbeitet. Der Treiber muss WDM-Regeln für die Verarbeitung von IRPs befolgen.

  • Um ein IRP vorzuverarbeiten, bevor es vom Framework verarbeitet wird.

    In seltenen Fällen kann es erforderlich sein, dass ein Treiber ein IRP verarbeitet, bevor das Framework es verarbeitet. In solchen Fällen kann die EvtDeviceWdmIrpPreprocess-Rückruffunktion des Treibers das IRP verarbeiten und dann WdfDeviceWdmDispatchPreprocessedIrp aufrufen, um das IRP an das Framework zurückzugeben. Abhängig vom Funktionscode des IRP kann das Framework das IRP selbst verarbeiten oder das IRP in einem Frameworkanforderungsobjekt erneut an den Treiber übermitteln.

Das Framework ruft die Rückruffunktion EvtDeviceWdmIrpPreprocess auf, wenn es ein E/A-Anforderungspaket (IRP) empfängt, das einen IRP-Hauptfunktionscode enthält, der mit dem MajorFunction-Parameter übereinstimmt, und einen Nebenfunktionscode, der mit einem der Nebenfunktionscodes im MinorFunctions-Array übereinstimmt.

Wenn der MinorFunctions-Arrayzeiger NULL ist, ruft das Framework die Rückruffunktion für alle Nebenfunktionscodes auf, die dem angegebenen Hauptfunktionscode zugeordnet sind. Wenn der MinorFunctions-Arrayzeiger nicht NULL ist, erstellt das Framework eine Kopie des Arrays, damit der Treiber sein Array nicht dauerhaft beibehalten muss.

Wenn der Treiber den DeviceInit-Zeiger von WdfPdoInitAllocate oder eine EvtChildListCreateDevice-Ereignisrückruffunktion erhalten hat , kann die EvtDeviceWdmIrpPreprocess-Rückruffunktion des Treibers keine Abschlussroutine für IRPs festlegen, die einen Hauptfunktionscode von IRP_MJ_PNP enthalten. Andernfalls meldet driver verifier einen Fehler.

Wenn Ihr Treiber WdfDeviceInitAssignWdmIrpPreprocessCallback mehrmals aufruft, erhöht das Framework einmal den StackSize-Member der WDM-DEVICE_OBJECT-Struktur des Treibers. Daher fügt der E/A-Manager allen IRPs einen zusätzlichen E/A-Stapelspeicherort hinzu, sodass die Rückruffunktion EvtDeviceWdmIrpPreprocess eine IoCompletion-Routine festlegen kann. Beachten Sie, dass dieser zusätzliche E/A-Stapelspeicherort allen IRPs hinzugefügt wird, nicht nur denen, die einen IRP-Hauptfunktionscode enthalten, den Sie in einem Aufruf von WdfDeviceInitAssignWdmIrpPreprocessCallback angeben. Daher sollten Sie die Verwendung von WdfDeviceInitAssignWdmIrpPreprocessCallback vermeiden, um die Verwendung des nicht auslagerten Speicherpools durch den Treiber unnötig zu erhöhen, es sei denn, es gibt keine Alternative.

Wenn Ihr Treiber WdfDeviceInitAssignWdmIrpPreprocessCallback mehrmals für denselben Hauptcode aufruft, behält das Framework nur die zuletzt festgelegte EvtDeviceWdmIrpPreprocess-Rückruffunktion für diesen Hauptcode bei. (Ihr Treiber kann nicht mehrere Vorverarbeitungsrückrufe für einen einzelnen Hauptcode registrieren.)

Weitere Informationen zur WdfDeviceInitAssignWdmIrpPreprocessCallback-Methode finden Sie unter Behandeln von WDM-IRPs außerhalb des Frameworks.

Beispiele

Im folgenden Codebeispiel wird eine EvtDeviceWdmIrpPreprocess-Ereignisrückruffunktion definiert und anschließend die Rückruffunktion registriert, um IRP_MJ_QUERY_INFORMATION IRPs zu verarbeiten.

NTSTATUS
SerialQueryInformationFile(
    IN WDFDEVICE Device,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine is used to query the end of file information on
    the opened serial port.  Any other file information request
    is returned with an invalid parameter.

    This routine always returns an end of file of 0.

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    The function value is the final status of the call

--*/

{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpSp;

    SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_PNP, ">SerialQueryInformationFile(%p, %p)\n", Device, Irp);

    PAGED_CODE();


    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    Irp->IoStatus.Information = 0L;
    Status = STATUS_SUCCESS;

    if (IrpSp->Parameters.QueryFile.FileInformationClass ==
        FileStandardInformation) {

        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(FILE_STANDARD_INFORMATION))
        {
                Status = STATUS_BUFFER_TOO_SMALL;
        }
        else
        {
            PFILE_STANDARD_INFORMATION Buf = Irp->AssociatedIrp.SystemBuffer;

            Buf->AllocationSize.QuadPart = 0;
            Buf->EndOfFile = Buf->AllocationSize;
            Buf->NumberOfLinks = 0;
            Buf->DeletePending = FALSE;
            Buf->Directory = FALSE;
            Irp->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
        }

    } else if (IrpSp->Parameters.QueryFile.FileInformationClass ==
               FilePositionInformation) {

        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
                sizeof(FILE_POSITION_INFORMATION))
        {
                Status = STATUS_BUFFER_TOO_SMALL;
        }
        else
        {

            ((PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer)->
                CurrentByteOffset.QuadPart = 0;
            Irp->IoStatus.Information = sizeof(FILE_POSITION_INFORMATION);
        }

    } else {
        Status = STATUS_INVALID_PARAMETER;
    }

    Irp->IoStatus.Status = Status;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;

}

NTSTATUS
SerialEvtDeviceAdd(
    IN WDFDRIVER Driver,
    IN PWDFDEVICE_INIT DeviceInit
    )
{
...
    status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
                                                 DeviceInit,
                                                 SerialQueryInformationFile,
                                                 IRP_MJ_QUERY_INFORMATION,
                                                 NULL, // Pointer to the minor function table
                                                 0 // Number of entries in the table
                                                 ); 
    if (!NT_SUCCESS(status)) {
        return status;
    }
...
}

Anforderungen

Anforderung Wert
Zielplattform Universell
KMDF-Mindestversion 1.0
Kopfzeile wdfdevice.h (einschließen von Wdf.h)
Bibliothek Wdf01000.sys (siehe Versionsverwaltung der Frameworkbibliothek).)
IRQL <= DISPATCH_LEVEL
DDI-Complianceregeln ChildDeviceInitAPI(kmdf), ControlDeviceInitAPI(kmdf), DeviceInitAPI(kmdf), DriverCreate(kmdf), InitFreeDeviceCallback(kmdf), InitFreeDeviceCreate(kmdf), InitFreeNull(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), PdoDeviceInitAPI(kmdf), PdoInitFreeDeviceCallback(kmdf), PdoInitFreeDeviceCreate(kmdf)

Weitere Informationen

WdfDeviceWdmDispatchPreprocessedIrp