WdfDeviceInitAssignWdmIrpPreprocessCallback-Funktion (wdfdevice.h)
[Gilt nur für KMDF]
Die WdfDeviceInitAssignWdmIrpPreprocessCallback- Methode registriert eine Rückruffunktion, um einen IRP-Hauptfunktionscode zu behandeln, und optional einen oder mehrere Hilfsfunktionscodes, 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 wichtigsten IRP-Funktionscodes, die in wdm.hdefiniert sind.
[in, optional] MinorFunctions
Ein Zeiger auf ein Array mit mindestens einem IRP-Hilfsfunktionscode, der dem angegebenen Hauptfunktionscode zugeordnet ist. Dieser Parameter ist optional und kann NULL-werden. Weitere Informationen finden Sie im folgenden Abschnitt "Hinweise".
[in] NumMinorFunctions
Die Anzahl der Hilfsfunktionscodes, die in der 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 wert MajorFunction ist ungültig. |
|
Es ist nicht genügend Arbeitsspeicher vorhanden. |
|
Der Treiber hat zuvor ein MinorFunctions Array für diese Hauptfunktion registriert und versucht, kleinere Funktionen erneut für den angegebenen MajorFunction--Code anzugeben. |
Die Methode gibt möglicherweise andere NTSTATUS-Wertezurück.
Bemerkungen
Treiber können die WdfDeviceInitAssignWdmIrpPreprocessCallback Methode aus zwei Gründen aufrufen:
-
Um einen IRP-Haupt- oder Hilfsfunktionscode zu behandeln, den das Framework nicht unterstützt.
Das Framework unterstützt z. B. IRP_MJ_FLUSH_BUFFERSnicht. Wenn Ihr Treiber dieses IRP unterstützen muss, muss er eine EvtDeviceWdmIrpPreprocess Rückruffunktion registrieren, die das IRP behandelt. Der Treiber muss WDM-Regeln für die Verarbeitung von IRPs befolgen.
-
So verarbeiten Sie ein IRP vor der Verarbeitung des Frameworks.
In seltenen Fällen kann es erforderlich sein, dass ein Treiber ein IRP verarbeitet, bevor das Framework verarbeitet wird. In solchen Fällen kann die EvtDeviceWdmIrpPreprocess Rückruffunktion das IRP verarbeiten und dann WdfDeviceWdmDispatchPreprocessedIrp aufrufen, um das IRP an das Framework zurückzugeben. Je nach Funktionscode des IRP verarbeitet das Framework das IRP selbst oder liefert das IRP erneut an den Treiber in einem Framework-Anforderungsobjekt.
Wenn der MinorFunctions- Arrayzeiger NULL-ist, ruft das Framework die Rückruffunktion für alle Hilfsfunktionscodes auf, die dem angegebenen Hauptfunktionscode zugeordnet sind. Wenn der MinorFunctions- Arrayzeiger nicht NULL-ist, erstellt das Framework eine Kopie des Arrays, sodass der Treiber sein Array nicht dauerhaft beibehalten muss.
Wenn der Treiber DeviceInit Zeiger von WdfPdoInitAllocate oder einer EvtChildListCreateDevice Ereignisrückruffunktion empfangen 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 eine oder mehrere Male aufruft, erhöht das Framework das StackSize Mitglied der WDM-DEVICE_OBJECT Struktur des Treibers einmal. Daher fügt der E/A-Manager allen IRPs einen zusätzlichen I/O-Stapelspeicherort hinzu, sodass die EvtDeviceWdmIrpPreprocess Rückruffunktion eine IoCompletion Routine festlegen kann. Beachten Sie, dass diese zusätzliche E/A-Stapelposition allen IRPs hinzugefügt wird, nicht nur die, die einen IRP-Hauptfunktionscode enthalten, den Sie in einem Aufruf von WdfDeviceInitAssignWdmIrpPreprocessCallbackangeben. Daher sollten Sie vermeiden, WdfDeviceInitAssignWdmIrpPreprocessCallback zu verwenden, um die Verwendung des nichtpageten Speicherpools unnötig zu erhöhen.
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 Framework-.
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- | Universal |
Minimale KMDF-Version | 1.0 |
Header- | wdfdevice.h (einschließen Wdf.h) |
Library | Wdf01000.sys (siehe Framework-Bibliotheksversionsverwaltung.) |
IRQL- | <= DISPATCH_LEVEL |
DDI-Complianceregeln | ChildDeviceInitAPI(kmdf), ControlDeviceInitAPI(kmdf), DeviceInitAPI(kmdf), DriverCreate (kmdf), InitFreeDeviceCallback(kmdf), InitFreeDeviceCreate(kmdf), InitFreeNull(km), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), Pdo, PdoInitFreeDeviceCallback(kmdf), PdoInitFreeDeviceCreate(kmdf) |