Función WdfDeviceInitAssignWdmIrpPreprocessCallback (wdfdevice.h)
[Solo se aplica a KMDF]
El método WdfDeviceInitAssignWdmIrpPreprocessCallback registra una función de devolución de llamada para controlar un código de función principal de IRP y, opcionalmente, uno o varios códigos de función menores asociados al código de función principal.
Sintaxis
NTSTATUS WdfDeviceInitAssignWdmIrpPreprocessCallback(
[in] PWDFDEVICE_INIT DeviceInit,
[in] PFN_WDFDEVICE_WDM_IRP_PREPROCESS EvtDeviceWdmIrpPreprocess,
[in] UCHAR MajorFunction,
[in, optional] PUCHAR MinorFunctions,
[in] ULONG NumMinorFunctions
);
Parámetros
[in] DeviceInit
Puntero a una estructura de WDFDEVICE_INIT .
[in] EvtDeviceWdmIrpPreprocess
Puntero a la función de devolución de llamada EvtDeviceWdmIrpPreprocess del controlador.
[in] MajorFunction
Uno de los códigos de función principales de IRP definidos en wdm.h.
[in, optional] MinorFunctions
Puntero a una matriz de uno o varios códigos de función secundaria irP asociados al código de función principal especificado. Este parámetro es opcional y puede ser NULL. Para obtener más información, vea la sección Comentarios que se muestra más adelante.
[in] NumMinorFunctions
Número de códigos de función menores contenidos en la matriz MinorFunctions .
Valor devuelto
Si la operación se realiza correctamente, el método devuelve STATUS_SUCCESS. Entre los valores devueltos adicionales se incluyen:
Código devuelto | Descripción |
---|---|
|
El valor MajorFunction no es válido. |
|
No hay memoria suficiente. |
|
El controlador registró previamente una matriz MinorFunctions para esta función principal y está intentando especificar las funciones secundarias de nuevo para el código MajorFunction especificado. |
El método podría devolver otros valores NTSTATUS.
Comentarios
Los controladores pueden llamar al método WdfDeviceInitAssignWdmIrpPreprocessCallback por cualquiera de estas dos razones:
-
Para controlar un código de función principal o secundaria de IRP que el marco no admite.
Por ejemplo, el marco no admite IRP_MJ_FLUSH_BUFFERS. Si el controlador debe admitir este IRP, debe registrar una función de devolución de llamada EvtDeviceWdmIrpPreprocess que controle el IRP. El controlador debe seguir las reglas de WDM para procesar IRP.
-
Para preprocesar un IRP antes de que el marco lo controle.
En raras ocasiones, podría ser necesario que un controlador procese un IRP antes de que el marco lo procese. En tales casos, la función de devolución de llamada EvtDeviceWdmIrpPreprocess del controlador puede procesar el IRP y, a continuación, llamar a WdfDeviceWdmDispatchPreprocessedIrp para devolver el IRP al marco. Dependiendo del código de función del IRP, el marco podría procesar el IRP en sí o podría entregar el IRP al controlador de nuevo en un objeto de solicitud de marco.
Si el puntero de matriz MinorFunctions es NULL, el marco llama a la función de devolución de llamada para todos los códigos de función menores asociados al código de función principal especificado. Si el puntero de matriz MinorFunctions no es NULL, el marco realiza una copia de la matriz para que el controlador no tenga que mantener permanentemente su matriz.
Si el controlador recibió el puntero DeviceInit de WdfPdoInitAllocate o una función de devolución de llamada de evento EvtChildListCreateDevice , la función de devolución de llamada EvtDeviceWdmIrpPreprocess del controlador no puede establecer una rutina de finalización para IRP que contengan un código de función principal de IRP_MJ_PNP. De lo contrario, el Comprobador de controladores notificará un error.
Si el controlador llama a WdfDeviceInitAssignWdmIrpPreprocessCallback una o varias veces, el marco incrementa el miembro StackSize de la estructura DEVICE_OBJECT WDM del controlador una vez. Como resultado, el administrador de E/S agrega una ubicación de pila de E/ S adicional a todos los IRP para que la función de devolución de llamada EvtDeviceWdmIrpPreprocess pueda establecer una rutina de IoCompletion . Tenga en cuenta que esta ubicación de pila de E/S adicional se agrega a todos los IRP, no solo a los que contienen un código de función principal de IRP que especifique en una llamada a WdfDeviceInitAssignWdmIrpPreprocessCallback. Por lo tanto, para evitar aumentar innecesariamente el uso del controlador del grupo de memoria no paginado, debe evitar el uso de WdfDeviceInitAssignWdmIrpPreprocessCallback a menos que no haya ninguna alternativa.
Si el controlador llama a WdfDeviceInitAssignWdmIrpPreprocessCallback más de una vez para el mismo código principal, el marco conserva solo la función de devolución de llamada EvtDeviceWdmIrpPreprocess establecida recientemente para este código principal. (El controlador no puede registrar varias devoluciones de llamada de preprocesamiento para un único código principal).
Para obtener más información sobre el método WdfDeviceInitAssignWdmIrpPreprocessCallback , vea Control de IRP de WDM fuera del marco.
Ejemplos
En el ejemplo de código siguiente se define una función de devolución de llamada de eventos EvtDeviceWdmIrpPreprocess y, a continuación, registra la función de devolución de llamada para controlar 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;
}
...
}
Requisitos
Requisito | Value |
---|---|
Plataforma de destino | Universal |
Versión mínima de KMDF | 1.0 |
Encabezado | wdfdevice.h (incluya Wdf.h) |
Library | Wdf01000.sys (consulte Control de versiones de la biblioteca de marcos). |
IRQL | <= DISPATCH_LEVEL |
Reglas de cumplimiento de 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) |