Partager via


WdfDeviceInitAssignWdmIrpPreprocessCallback, fonction (wdfdevice.h)

[S’applique uniquement à KMDF]

La méthode WdfDeviceInitAssignWdmIrpPreprocessCallback inscrit une fonction de rappel pour gérer un code de fonction principale IRP et, éventuellement, un ou plusieurs codes de fonction mineurs associés au code de fonction principale.

Syntaxe

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

Paramètres

[in] DeviceInit

Pointeur vers une structure WDFDEVICE_INIT .

[in] EvtDeviceWdmIrpPreprocess

Pointeur vers la fonction de rappel EvtDeviceWdmIrpPreprocess du pilote.

[in] MajorFunction

Un des codes de fonction principale IRP définis dans wdm.h.

[in, optional] MinorFunctions

Pointeur vers un tableau d’un ou plusieurs codes de fonction mineure IRP associés au code de fonction principale spécifié. Ce paramètre est facultatif et peut être NULL. Pour plus d'informations, consultez la section Notes qui suit.

[in] NumMinorFunctions

Nombre de codes de fonction mineurs contenus dans le tableau MinorFunctions .

Valeur retournée

Si l’opération réussit, la méthode retourne STATUS_SUCCESS. Les valeurs de retour supplémentaires sont les suivantes :

Code de retour Description
STATUS_INVALID_PARAMETER
La valeur MajorFunction n’est pas valide.
STATUS_INSUFFICIENT_RESOURCES
La mémoire est insuffisante.
STATUS_INVALID_DEVICE_REQUEST
Le pilote a précédemment inscrit un tableau MinorFunctions pour cette fonction majeure et tente de spécifier à nouveau des fonctions mineures pour le code MajorFunction spécifié.
 

La méthode peut retourner d’autres valeurs NTSTATUS.

Remarques

Les pilotes peuvent appeler la méthode WdfDeviceInitAssignWdmIrpPreprocessCallback pour deux raisons :

  • Pour gérer un code de fonction IRP majeur ou mineur que l’infrastructure ne prend pas en charge.

    Par exemple, l’infrastructure ne prend pas en charge IRP_MJ_FLUSH_BUFFERS. Si votre pilote doit prendre en charge cette IRP, il doit inscrire une fonction de rappel EvtDeviceWdmIrpPreprocess qui gère l’IRP. Le pilote doit suivre les règles WDM pour le traitement des IRPs.

  • Pour prétraiter un IRP avant que l’infrastructure ne le gère.

    Dans de rares cas, il peut être nécessaire qu’un pilote traite un IRP avant que l’infrastructure ne le traite. Dans ce cas, la fonction de rappel EvtDeviceWdmIrpPreprocess du pilote peut traiter l’IRP, puis appeler WdfDeviceWdmDispatchPreprocessedIrp pour renvoyer l’IRP au framework. Selon le code de fonction de l’IRP, l’infrastructure peut traiter l’IRP lui-même ou remettre à nouveau l’IRP au pilote dans un objet de requête d’infrastructure.

L’infrastructure appelle la fonction de rappel EvtDeviceWdmIrpPreprocess chaque fois qu’elle reçoit un paquet de demande d’E/S (IRP) qui contient un code de fonction principale IRP qui correspond au paramètre MajorFunction et un code de fonction secondaire correspondant à l’un des codes de fonction mineurs figurant dans le tableau MinorFunctions .

Si le pointeur du tableau MinorFunctions a la valeur NULL, l’infrastructure appelle la fonction de rappel pour tous les codes de fonction mineurs associés au code de fonction principale spécifié. Si le pointeur du tableau MinorFunctions n’est pas NULL, l’infrastructure effectue une copie du tableau afin que le pilote n’ait pas à conserver définitivement son tableau.

Si le pilote a reçu un pointeur DeviceInit de WdfPdoInitAllocate ou une fonction de rappel d’événement EvtChildListCreateDevice , la fonction de rappel EvtDeviceWdmIrpPreprocess du pilote ne peut pas définir une routine d’achèvement pour les irPs qui contiennent un code de fonction principal de IRP_MJ_PNP. Sinon, Driver Verifier signale une erreur.

Si votre pilote appelle WdfDeviceInitAssignWdmIrpPreprocessCallback une ou plusieurs fois, l’infrastructure incrémente le membre StackSize de la structure wdM DEVICE_OBJECT du pilote une fois. Par conséquent, le gestionnaire d’E/S ajoute un emplacement de pile d’E/S supplémentaire à tous les IRP afin que la fonction de rappel EvtDeviceWdmIrpPreprocess puisse définir une routine IoCompletion . Notez que cet emplacement de pile d’E/S supplémentaire est ajouté à tous les IRPs, et pas seulement à ceux qui contiennent un code de fonction principale IRP que vous spécifiez dans un appel à WdfDeviceInitAssignWdmIrpPreprocessCallback. Par conséquent, pour éviter d’augmenter inutilement l’utilisation par votre pilote du pool de mémoire non paginée, vous devez éviter d’utiliser WdfDeviceInitAssignWdmIrpPreprocessCallback , sauf s’il n’existe aucune alternative.

Si votre pilote appelle WdfDeviceInitAssignWdmIrpPreprocessCallback plusieurs fois pour le même code majeur, l’infrastructure conserve uniquement la fonction de rappel EvtDeviceWdmIrpPreprocess la plus récente pour ce code majeur. (Votre pilote ne peut pas inscrire plusieurs rappels de prétraitement pour un seul code majeur.)

Pour plus d’informations sur la méthode WdfDeviceInitAssignWdmIrpPreprocessCallback , consultez Gestion des IRPs WDM en dehors de l’infrastructure.

Exemples

L’exemple de code suivant définit une fonction de rappel d’événement EvtDeviceWdmIrpPreprocess , puis inscrit la fonction de rappel pour gérer IRP_MJ_QUERY_INFORMATION IRPs.

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

Configuration requise

Condition requise Valeur
Plateforme cible Universal
Version KMDF minimale 1.0
En-tête wdfdevice.h (include Wdf.h)
Bibliothèque Wdf01000.sys (consultez Gestion de version de la bibliothèque d’infrastructure.)
IRQL <= DISPATCH_LEVEL
Règles de 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)

Voir aussi

WdfDeviceWdmDispatchPreprocessedIrp