Funzione WdfDeviceInitAssignWdmIrpPreprocessCallback (wdfdevice.h)
[Si applica solo a KMDF]
Il metodo WdfDeviceInitAssignWdmIrpPreprocessCallback registra una funzione di callback per gestire un codice di funzione principale IRP e, facoltativamente, uno o più codici di funzione secondari associati al codice della funzione principale.
Sintassi
NTSTATUS WdfDeviceInitAssignWdmIrpPreprocessCallback(
[in] PWDFDEVICE_INIT DeviceInit,
[in] PFN_WDFDEVICE_WDM_IRP_PREPROCESS EvtDeviceWdmIrpPreprocess,
[in] UCHAR MajorFunction,
[in, optional] PUCHAR MinorFunctions,
[in] ULONG NumMinorFunctions
);
Parametri
[in] DeviceInit
Puntatore a una struttura WDFDEVICE_INIT.
[in] EvtDeviceWdmIrpPreprocess
Puntatore alla funzione di callback evtDeviceWdmIrpPreprocess del driver.
[in] MajorFunction
Uno dei codici di funzione principali di IRP definiti in wdm.h.
[in, optional] MinorFunctions
Puntatore a una matrice di uno o più codici di funzione secondaria IRP associati al codice della funzione principale specificato. Questo parametro è facoltativo e può essere NULL. Per altre informazioni, vedere la sezione Osservazioni seguente.
[in] NumMinorFunctions
Numero di codici di funzione secondari contenuti nella matrice MinorFunctions.
Valore restituito
Se l'operazione ha esito positivo, il metodo restituisce STATUS_SUCCESS. I valori restituiti aggiuntivi includono:
Codice restituito | Descrizione |
---|---|
|
Il valore MajorFunction non è valido. |
|
Memoria insufficiente. |
|
Il driver ha registrato in precedenza una matrice minorFunctions di per questa funzione principale e sta tentando di specificare di nuovo funzioni secondarie per il codice MajorFunction specificato. |
Il metodo potrebbe restituire altri valori NTSTATUS .
Osservazioni
I driver possono chiamare il metodo WdfDeviceInitAssignWdmIrpPreprocessCallback per uno dei due motivi seguenti:
-
Per gestire un codice di funzione principale o secondario di IRP non supportato dal framework.
Ad esempio, il framework non supporta IRP_MJ_FLUSH_BUFFERS. Se il driver deve supportare questo IRP, deve registrare un EvtDeviceWdmIrpPreprocess funzione di callback che gestisce l'IRP. Il driver deve seguire le regole WDM per l'elaborazione di runtime di integrazione.
-
Per pre-elaborare un IRP prima che il framework lo gestisca.
In rari casi, potrebbe essere necessario che un driver elabori un IRP prima che il framework lo elabori. In questi casi, il driver EvtDeviceWdmIrpPreprocess funzione di callback può elaborare l'IRP e quindi chiamare WdfDeviceWdmDispatchPreprocessedIrp per restituire l'IRP al framework. A seconda del codice della funzione di IRP, il framework potrebbe elaborare l'IRP stesso o recapitare nuovamente l'IRP al driver in un oggetto richiesta framework.
Se l'MinorFunctions puntatore alla matrice è NULL, il framework chiama la funzione di callback per tutti i codici di funzione secondari associati al codice della funzione principale specificato. Se l'MinorFunctions puntatore alla matrice non è NULL, il framework crea una copia della matrice in modo che il driver non deve mantenere permanentemente la matrice.
Se il driver ha ricevuto puntatore DeviceInit da WdfPdoInitAllocate o da un EvtChildListCreateDevice funzione di callback degli eventi, la funzione di callback evtDeviceWdmIrpPreprocess del driver non può impostare una routine di completamento per i runtime di integrazione che contengono un codice funzione principale di IRP_MJ_PNP. In caso contrario, Driver Verifier segnala un errore.
Se il driver chiama WdfDeviceInitAssignWdmIrpPreprocessCallback una o più volte, il framework incrementa il StackSize membro della struttura WDM DEVICE_OBJECT del driver una volta. Di conseguenza, il gestore di I/O aggiunge un percorso dello stack I/O aggiuntivo a tutti i provider di integrazione in modo che la funzione di callback EvtDeviceWdmIrpPreprocess possa impostare una routine IoCompletion. Si noti che questo percorso aggiuntivo dello stack di I/O viene aggiunto a tutti i runtime di integrazione, non solo a quelli che contengono un codice di funzione principale IRP specificato in una chiamata a WdfDeviceInitAssignWdmIrpPreprocessCallback. Pertanto, per evitare di aumentare inutilmente l'uso del driver del pool di memoria non di paging, è consigliabile evitare di usare WdfDeviceInitAssignWdmIrpPreprocessCallback a meno che non esista alcuna alternativa.
Se il driver chiama WdfDeviceInitAssignWdmIrpPreprocessCallback più volte per lo stesso codice principale, il framework mantiene solo l'ultimo set EvtDeviceWdmIrpPreprocess funzione di callback per questo codice principale. Il driver non può registrare più callback di pre-elaborazione per un singolo codice principale.
Per altre informazioni sul metodo WdfDeviceInitAssignWdmIrpPreprocessCallback, vedere Handling WDM IRPs outside of the Framework.
Esempi
L'esempio di codice seguente definisce un EvtDeviceWdmIrpPreprocess funzione di callback degli eventi e quindi registra la funzione di callback per gestire IRP_MJ_QUERY_INFORMATION IRP.
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;
}
...
}
Fabbisogno
Requisito | Valore |
---|---|
piattaforma di destinazione | Universale |
versione minima di KMDF | 1.0 |
intestazione | wdfdevice.h (include Wdf.h) |
libreria | Wdf01000.sys (vedere Controllo delle versioni della libreria framework). |
IRQL | <= DISPATCH_LEVEL |
regole di 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) |