Funzione WdfDeviceInitAssignWdmIrpPreprocessCallback (wdfdevice.h)
[Si applica solo a KMDF]
Il metodo WdfDeviceInitAssignWdmIrpPreprocessCallback registra una funzione di callback per gestire un codice di funzione principale di 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 ulteriori informazioni, vedere la sezione Osservazioni successiva.
[in] NumMinorFunctions
Numero di codici di funzione secondaria 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 per questa funzione principale e sta tentando di specificare nuovamente funzioni secondarie per il codice MajorFunction specificato. |
Il metodo potrebbe restituire altri valori NTSTATUS.
Commenti
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 una funzione di callback EvtDeviceWdmIrpPreprocess che gestisce l'IRP. Il driver deve seguire le regole WDM per l'elaborazione dei provider 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, la funzione di callback EvtDeviceWdmIrpPreprocess del driver 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 del framework.
Se il puntatore alla matrice MinorFunctions è NULL, il framework chiama la funzione di callback per tutti i codici di funzione secondaria associati al codice della funzione principale specificato. Se il puntatore alla matrice MinorFunctions non è NULL, il framework crea una copia della matrice in modo che il driver non deve mantenere definitivamente la matrice.
Se il driver ha ricevuto il puntatore DeviceInit da WdfPdoInitAllocate o da una funzione di callback dell'evento EvtChildListCreateDevice , la funzione di callback EvtDeviceWdmIrpPreprocess del driver non può impostare una routine di completamento per i runtime di integrazione che contengono un codice di 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 membro StackSize della struttura wdm DEVICE_OBJECT del driver una volta. Di conseguenza, il gestore di I/O aggiunge un percorso dello stack di 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 provider di integrazione, non solo a quelli che contengono un codice di funzione principale di 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 vi sia alcuna alternativa.
Se il driver chiama WdfDeviceInitAssignWdmIrpPreprocessCallback più volte per lo stesso codice principale, il framework mantiene solo la funzione di callback EvtDeviceWdmIrpPreprocess impostata più di recente 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.For more information about the WdfDeviceInitAssignWdmIrpPreprocessCallback method, see Handling WDM IRPs Outside of the Framework.
Esempio
L'esempio di codice seguente definisce una funzione di callback dell'evento EvtDeviceWdmIrpPreprocess 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;
}
...
}
Requisiti
Requisito | Valore |
---|---|
Piattaforma di destinazione | Universale |
Versione KMDF minima | 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) |