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 principal IRP et, éventuellement, un ou plusieurs codes de fonction secondaires associés au code de fonction principal.

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 principaux IRP définis dans wdm.h.

[in, optional] MinorFunctions

Pointeur vers un tableau d’un ou plusieurs codes de fonction secondaire IRP associés au code de fonction principal spécifié. Ce paramètre est facultatif et peut être NULL. Pour plus d’informations, consultez la section Remarques suivante.

[in] NumMinorFunctions

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

Valeur de retour

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

Retourner le code 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 principale 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 principal ou secondaire IRP 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 cet IRP, il doit inscrire une EvtDeviceWdmIrpPreprocess fonction de rappel qui gère l’IRP. Le pilote doit respecter 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 le framework 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 l’IRP au pilote à nouveau dans un objet de demande d’infrastructure.

L’infrastructure appelle la fonction de rappel EvtDeviceWdmIrpPreprocess chaque fois qu’elle reçoit un paquet de requête d’E/S (IRP) qui contient un code de fonction principal IRP qui correspond au paramètre MajorFunction et à un code de fonction secondaire qui correspond à l’un des codes de fonction secondaires qui se trouvent dans le tableau MinorFunctions.

Si l'MinorFunctions pointeur de tableau est NULL, l’infrastructure appelle la fonction de rappel pour tous les codes de fonction secondaires associés au code de fonction principal spécifié. Si la MinorFunctions pointeur de tableau 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 pointeur deviceInit de WdfPdoInitAllocate ou un EvtChildListCreateDevice fonction de rappel d’événement, la fonction de rappel d’événement EvtDeviceWdmIrpPreprocess 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, vérificateur de pilotes signale une erreur.

Si votre pilote appelle WdfDeviceInitAssignWdmIrpPreprocessCallback une ou plusieurs fois, l’infrastructure incrémente le StackSize membre 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 irps 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, pas seulement ceux qui contiennent un code de fonction principal IRP que vous spécifiez dans un appel à WdfDeviceInitAssignWdmIrpPreprocessCallback. Par conséquent, pour éviter d’augmenter inutilement l’utilisation de votre pilote du pool de mémoires non paginés, 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 principal, l’infrastructure conserve uniquement l’ensemble le plus récent défini EvtDeviceWdmIrpPreprocess fonction de rappel pour ce code principal. (Votre pilote ne peut pas inscrire plusieurs rappels de préprocesseur pour un seul code principal.)

Pour plus d’informations sur la méthode WdfDeviceInitAssignWdmIrpPreprocessCallback, consultez Gestion des irps WDM en dehors du framework.

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

Exigences

Exigence Valeur
plateforme cible Universel
version minimale de KMDF 1.0
d’en-tête wdfdevice.h (include Wdf.h)
bibliothèque Wdf01000.sys (voir Versioning de la bibliothèque Framework.)
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