Condividi tramite


Funzione WdfDeviceInitAssignWdmIrpPreprocessCallback (wdfdevice.h)

[Si applica solo a KMDF]

Il metodo WdfDeviceInitAssignWdmIrpPreprocessCallback registra una funzione di callback per gestire un codice di funzione principale IRP e, facoltativamente, uno o più codici di funzione secondari associati al codice della funzione principale.

Sintassi

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

Parametri

[in] DeviceInit

Puntatore a una struttura WDFDEVICE_INIT.

[in] EvtDeviceWdmIrpPreprocess

Puntatore alla funzione di callback evtDeviceWdmIrpPreprocess del driver.

[in] MajorFunction

Uno dei codici di funzione principali di IRP definiti in wdm.h.

[in, optional] MinorFunctions

Puntatore a una matrice di uno o più codici di funzione secondaria IRP associati al codice della funzione principale specificato. Questo parametro è facoltativo e può essere NULL. Per altre informazioni, vedere la sezione Osservazioni seguente.

[in] NumMinorFunctions

Numero di codici di funzione secondari contenuti nella matrice MinorFunctions.

Valore restituito

Se l'operazione ha esito positivo, il metodo restituisce STATUS_SUCCESS. I valori restituiti aggiuntivi includono:

Codice restituito Descrizione
STATUS_INVALID_PARAMETER
Il valore MajorFunction non è valido.
STATUS_INSUFFICIENT_RESOURCES
Memoria insufficiente.
STATUS_INVALID_DEVICE_REQUEST
Il driver ha registrato in precedenza una matrice minorFunctions di per questa funzione principale e sta tentando di specificare di nuovo funzioni secondarie per il codice MajorFunction specificato.
 

Il metodo potrebbe restituire altri valori NTSTATUS .

Osservazioni

I driver possono chiamare il metodo WdfDeviceInitAssignWdmIrpPreprocessCallback per uno dei due motivi seguenti:

  • Per gestire un codice di funzione principale o secondario di IRP non supportato dal framework.

    Ad esempio, il framework non supporta IRP_MJ_FLUSH_BUFFERS. Se il driver deve supportare questo IRP, deve registrare un EvtDeviceWdmIrpPreprocess funzione di callback che gestisce l'IRP. Il driver deve seguire le regole WDM per l'elaborazione di runtime di integrazione.

  • Per pre-elaborare un IRP prima che il framework lo gestisca.

    In rari casi, potrebbe essere necessario che un driver elabori un IRP prima che il framework lo elabori. In questi casi, il driver EvtDeviceWdmIrpPreprocess funzione di callback può elaborare l'IRP e quindi chiamare WdfDeviceWdmDispatchPreprocessedIrp per restituire l'IRP al framework. A seconda del codice della funzione di IRP, il framework potrebbe elaborare l'IRP stesso o recapitare nuovamente l'IRP al driver in un oggetto richiesta framework.

Il framework chiama la EvtDeviceWdmIrpPreprocess funzione di callback ogni volta che riceve un pacchetto di richiesta I/O (IRP) che contiene un codice funzione principale IRP corrispondente al parametro MajorFunction parametro e un codice di funzione secondario corrispondente a uno dei codici di funzione secondari presenti nella matrice MinorFunctions.

Se l'MinorFunctions puntatore alla matrice è NULL, il framework chiama la funzione di callback per tutti i codici di funzione secondari associati al codice della funzione principale specificato. Se l'MinorFunctions puntatore alla matrice non è NULL, il framework crea una copia della matrice in modo che il driver non deve mantenere permanentemente la matrice.

Se il driver ha ricevuto puntatore DeviceInit da WdfPdoInitAllocate o da un EvtChildListCreateDevice funzione di callback degli eventi, la funzione di callback evtDeviceWdmIrpPreprocess del driver non può impostare una routine di completamento per i runtime di integrazione che contengono un codice funzione principale di IRP_MJ_PNP. In caso contrario, Driver Verifier segnala un errore.

Se il driver chiama WdfDeviceInitAssignWdmIrpPreprocessCallback una o più volte, il framework incrementa il StackSize membro della struttura WDM DEVICE_OBJECT del driver una volta. Di conseguenza, il gestore di I/O aggiunge un percorso dello stack I/O aggiuntivo a tutti i provider di integrazione in modo che la funzione di callback EvtDeviceWdmIrpPreprocess possa impostare una routine IoCompletion. Si noti che questo percorso aggiuntivo dello stack di I/O viene aggiunto a tutti i runtime di integrazione, non solo a quelli che contengono un codice di funzione principale IRP specificato in una chiamata a WdfDeviceInitAssignWdmIrpPreprocessCallback. Pertanto, per evitare di aumentare inutilmente l'uso del driver del pool di memoria non di paging, è consigliabile evitare di usare WdfDeviceInitAssignWdmIrpPreprocessCallback a meno che non esista alcuna alternativa.

Se il driver chiama WdfDeviceInitAssignWdmIrpPreprocessCallback più volte per lo stesso codice principale, il framework mantiene solo l'ultimo set EvtDeviceWdmIrpPreprocess funzione di callback per questo codice principale. Il driver non può registrare più callback di pre-elaborazione per un singolo codice principale.

Per altre informazioni sul metodo WdfDeviceInitAssignWdmIrpPreprocessCallback, vedere Handling WDM IRPs outside of the Framework.

Esempi

L'esempio di codice seguente definisce un EvtDeviceWdmIrpPreprocess funzione di callback degli eventi e quindi registra la funzione di callback per gestire IRP_MJ_QUERY_INFORMATION IRP.

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;
    }
...
}

Fabbisogno

Requisito Valore
piattaforma di destinazione Universale
versione minima di KMDF 1.0
intestazione wdfdevice.h (include Wdf.h)
libreria Wdf01000.sys (vedere Controllo delle versioni della libreria framework).
IRQL <= DISPATCH_LEVEL
regole di conformità DDI 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)

Vedere anche

WdfDeviceWdmDispatchPreprocessedIrp