Partilhar via


IO_COMPLETION_ROUTINE função de retorno de chamada (wdm.h)

A rotina de IoCompletion conclui o processamento de operações de E/S.

Sintaxe

IO_COMPLETION_ROUTINE IoCompletionRoutine;

NTSTATUS IoCompletionRoutine(
  [in]           PDEVICE_OBJECT DeviceObject,
  [in]           PIRP Irp,
  [in, optional] PVOID Context
)
{...}

Parâmetros

[in] DeviceObject

Ponteiro fornecido pelo chamador para uma estrutura de DEVICE_OBJECT. Esse é o objeto do dispositivo de destino, criado anteriormente pela rotina de addDevice do driver.

[in] Irp

Ponteiro fornecido pelo chamador para uma estrutura IRP que descreve a operação de E/S.

[in, optional] Context

Ponteiro fornecido pelo chamador para informações de contexto específicas do driver, fornecido anteriormente ao chamar IoSetCompletionRoutine ou IoSetCompletionRoutineEx. As informações de contexto devem ser armazenadas na memória nãopagada, uma vez que uma rotina de do IoCompletion pode ser chamada em DISPATCH_LEVEL. Para obter mais informações, consulte a seção Comentários a seguir.

Valor de retorno

Se a rotina IoCompletion determinar que o processamento adicional é necessário para o IRP, ele deve retornar STATUS_MORE_PROCESSING_REQUIRED. Para obter mais informações, consulte a seção Comentários a seguir. Caso contrário, ele deverá retornar STATUS_SUCCESS. (O gerente de E/S verifica apenas a presença ou ausência de STATUS_MORE_PROCESSING_REQUIRED.)

Observações

A rotina de IoCompletion de do driver é executada em um thread arbitrário ou contexto DPC e em um IRQL menor ou igual a DISPATCH_LEVEL. Como o código escrito para execução em DISPATCH_LEVEL também será executado em níveis mais baixos, rotinas de IoCompletion devem ser projetadas para execução em DISPATCH_LEVEL. No entanto, como essas rotinas não têm garantia de serem executadas em DISPATCH_LEVEL, elas não devem chamar rotinas do sistema que realmente exigem execução em DISPATCH_LEVEL. (Para obter mais informações sobre IRQLs, consulte gerenciamento de prioridades de hardware.)

Para registrar uma rotina de IoCompletion para um IRP específico, um driver deve chamar IoSetCompletionRoutine ou IoSetCompletionRoutineEx, que armazena o endereço da rotina IoCompletion do no local da pilha de E/S do driver mais baixo. (Portanto, um driver de nível mais baixo não pode registrar uma rotina de IoCompletion.) Um driver normalmente chama IoSetCompletionRoutine ou IoSetCompletionRoutineEx de uma de suas rotinas de expedição, cada vez que um IRP é recebido. A maioria dos drivers, incluindo todos os drivers PnP, pode usar IoSetCompletionRoutine para registrar sua rotina de IoCompletion. Drivers não PnP que podem ser descarregados antes de executar a rotina de do IoCompletion devem usar IoSetCompletionRoutineEx.

Quando qualquer driver conclui um IRP, ele chama IoCompleteRequest, que, por sua vez, chama a rotina de IoCompletion de cada driver de nível superior, do mais alto ao mais alto, até que todas as rotinas de IoCompletion mais altas sejam chamadas ou até que uma rotina retorne STATUS_MORE_PROCESSING_REQUIRED.

Ao criar o IRP, aloque um local de pilha para o driver atual, bem como todos os drivers inferiores. Se você não alocar locais de pilha suficientes, o ponteiro DeviceObject poderá ser definido como NULL quando a rotina de conclusão for chamada. Você pode evitar alocar um local de pilha extra para o driver atual se usar o campo de Contexto para passar informações para IoCompletion em vez de depender do parâmetro deviceObject.

Se uma rotina IoCompletion retornar STATUS_MORE_PROCESSING_REQUIRED, a chamada do driver inferior para IoCompleteRequest retornará imediatamente. Nesse caso, um driver de nível superior precisará chamar IoCompleteRequest para concluir o IRP.

Para obter mais informações sobre como implementar rotinas de IoCompletion, consulte Concluindode IRPs.

Exemplos

Para definir uma rotina de retorno de chamada IoCompletion, primeiro você deve fornecer uma declaração de função que identifique o tipo de rotina de retorno de chamada que você está definindo. O Windows fornece um conjunto de tipos de função de retorno de chamada para drivers. Declarar uma função usando os tipos de função de retorno de chamada ajuda a análise de código para drivers, SDV (Verificador de Driver Estático) e outras ferramentas de verificação encontram erros e é um requisito para gravar drivers para o sistema operacional Windows.

Por exemplo, para definir uma rotina de retorno de chamada IoCompletion denominada MyIoCompletion, use o tipo IO_COMPLETION_ROUTINE conforme mostrado neste exemplo de código:

IO_COMPLETION_ROUTINE MyIoCompletion;

Em seguida, implemente sua rotina de retorno de chamada da seguinte maneira:

_Use_decl_annotations_
NTSTATUS
  MyIoCompletion(
    PDEVICE_OBJECT  DeviceObject,
    PIRP  Irp,
    PVOID  Context
    )
  {
      // Function body
  }

O tipo de função IO_COMPLETION_ROUTINE é definido no arquivo de cabeçalho Wdm.h. Para identificar erros com mais precisão ao executar as ferramentas de análise de código, adicione a anotação _Use_decl_annotations_ à sua definição de função. A anotação _Use_decl_annotations_ garante que as anotações aplicadas ao tipo de função IO_COMPLETION_ROUTINE no arquivo de cabeçalho sejam usadas. Para obter mais informações sobre os requisitos para declarações de função, consulte Declarando funções usando tipos de função de função para drivers WDM. Para obter informações sobre _Use_decl_annotations_, consulte Anotando o comportamento da função.

Requisitos

Requisito Valor
da Plataforma de Destino Área de trabalho
cabeçalho wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
IRQL Chamado no IRQL <= DISPATCH_LEVEL (consulte a seção Comentários).