Função WdfDeviceInitAssignWdmIrpPreprocessCallback (wdfdevice.h)

[Aplica-se somente ao KMDF]

O método WdfDeviceInitAssignWdmIrpPreprocessCallback registra uma função de retorno de chamada para manipular um código de função principal IRP e, opcionalmente, um ou mais códigos de função secundárias associados ao código de função principal.

Sintaxe

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

Um ponteiro para uma estrutura WDFDEVICE_INIT .

[in] EvtDeviceWdmIrpPreprocess

Um ponteiro para a função de retorno de chamada EvtDeviceWdmIrpPreprocess do driver.

[in] MajorFunction

Um dos principais códigos de função IRP definidos em wdm.h.

[in, optional] MinorFunctions

Um ponteiro para uma matriz de um ou mais códigos de função secundária IRP associados ao código de função principal especificado. Esse parâmetro é opcional e pode ser NULL. Para obter mais informações, consulte a seção Comentários a seguir.

[in] NumMinorFunctions

O número de códigos de função secundária contidos na matriz MinorFunctions .

Valor retornado

Se a operação for bem-sucedida, o método retornará STATUS_SUCCESS. Os valores de retorno adicionais incluem:

Código de retorno Descrição
STATUS_INVALID_PARAMETER
O valor MajorFunction é inválido.
STATUS_INSUFFICIENT_RESOURCES
Não há memória suficiente.
STATUS_INVALID_DEVICE_REQUEST
O driver registrou anteriormente uma matriz MinorFunctions para essa função principal e está tentando especificar funções secundárias novamente para o código MajorFunction especificado.
 

O método pode retornar outros valores NTSTATUS.

Comentários

Os drivers podem chamar o método WdfDeviceInitAssignWdmIrpPreprocessCallback por dois motivos:

  • Para lidar com um código de função principal ou secundária irp que a estrutura não dá suporte.

    Por exemplo, a estrutura não dá suporte a IRP_MJ_FLUSH_BUFFERS. Se o driver precisar dar suporte a esse IRP, ele deverá registrar uma função de retorno de chamada EvtDeviceWdmIrpPreprocess que manipula o IRP. O driver deve seguir as regras do WDM para processar IRPs.

  • Para pré-processar um IRP antes que a estrutura o manipule.

    Em casos raros, pode ser necessário que um driver processe um IRP antes que a estrutura o processe. Nesses casos, a função de retorno de chamada EvtDeviceWdmIrpPreprocess do driver pode processar o IRP e chamar WdfDeviceWdmDispatchPreprocessedIrp para retornar o IRP à estrutura. Dependendo do código de função do IRP, a estrutura pode processar o IRP em si ou pode entregar o IRP ao driver novamente em um objeto de solicitação de estrutura.

A estrutura chama a função de retorno de chamada EvtDeviceWdmIrpPreprocess sempre que recebe um IRP (pacote de solicitação de E/S) que contém um código de função principal IRP que corresponde ao parâmetro MajorFunction e a um código de função secundária que corresponde a um dos códigos de função secundária que estão na matriz MinorFunctions .

Se o ponteiro da matriz MinorFunctions for NULL, a estrutura chamará a função de retorno de chamada para todos os códigos de função secundária associados ao código de função principal especificado. Se o ponteiro da matriz MinorFunctions não for NULL, a estrutura fará uma cópia da matriz para que o driver não precise manter permanentemente sua matriz.

Se o driver recebeu o ponteiro DeviceInit de WdfPdoInitAllocate ou uma função de retorno de chamada de evento EvtChildListCreateDevice , a função de retorno de chamada EvtDeviceWdmIrpPreprocess do driver não poderá definir uma rotina de conclusão para IRPs que contenham um código de função principal de IRP_MJ_PNP. Caso contrário, o Verificador de Driver relatará um erro.

Se o driver chamar WdfDeviceInitAssignWdmIrpPreprocessCallback uma ou mais vezes, a estrutura incrementará o membro StackSize do WDM do driver DEVICE_OBJECT estrutura uma vez. Como resultado, o gerenciador de E/S adiciona um local de pilha de E/S adicional a todos os IRPs para que a função de retorno de chamada EvtDeviceWdmIrpPreprocess possa definir uma rotina de IoCompletion . Observe que esse local de pilha de E/S extra é adicionado a todos os IRPs, não apenas aos que contêm um código de função principal IRP que você especifica em uma chamada para WdfDeviceInitAssignWdmIrpPreprocessCallback. Portanto, para evitar aumentar desnecessariamente o uso do pool de memória nãopagada pelo driver, evite usar WdfDeviceInitAssignWdmIrpPreprocessCallback , a menos que não haja alternativa.

Se o driver chamar WdfDeviceInitAssignWdmIrpPreprocessCallback mais de uma vez para o mesmo código principal, a estrutura manterá apenas a função de retorno de chamada EvtDeviceWdmIrpPreprocess definida mais recentemente para esse código principal. (O driver não pode registrar vários retornos de chamada de pré-processamento para um único código principal.)

Para obter mais informações sobre o método WdfDeviceInitAssignWdmIrpPreprocessCallback , consulte Como manipular IRPs do WDM fora da Estrutura.

Exemplos

O exemplo de código a seguir define uma função de retorno de chamada de evento EvtDeviceWdmIrpPreprocess e registra a função de retorno de chamada para manipular IRP_MJ_QUERY_INFORMATION IRPs.

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 retured 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

   
Plataforma de Destino Universal
Versão mínima do KMDF 1,0
Cabeçalho wdfdevice.h (include Wdf.h)
Biblioteca Wdf01000.sys (consulte o Controle de Versão da Biblioteca de Estruturas).)
IRQL <= DISPATCH_LEVEL
Regras de conformidade 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)

Confira também

WdfDeviceWdmDispatchPreprocessedIrp