Compartir a través de


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
STATUS_INVALID_PARAMETER
El valor MajorFunction no es válido.
STATUS_INSUFFICIENT_RESOURCES
No hay memoria suficiente.
STATUS_INVALID_DEVICE_REQUEST
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.

El marco llama a la función de devolución de llamada EvtDeviceWdmIrpPreprocess cada vez que recibe un paquete de solicitud de E/S (IRP) que contiene un código de función principal de IRP que coincide con el parámetro MajorFunction y un código de función secundaria que coincide con uno de los códigos de función secundarias que se encuentran en la matriz MinorFunctions .

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)

Consulte también

WdfDeviceWdmDispatchPreprocessedIrp