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 |
---|---|
|
La valeur MajorFunction n’est pas valide. |
|
La mémoire est insuffisante. |
|
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.
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) |