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 |
---|---|
|
Der MajorFunction-Wert ist ungültig. |
|
Es ist nicht genügend Arbeitsspeicher vorhanden. |
|
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.
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) |