Compartilhar via


Como concluir um IRP em uma rotina de expedição

Se um IRP de entrada puder ser concluído imediatamente, uma rotina de expedição fará o seguinte:

  1. Define os membros status e informações do bloco de status de E/S do IRP com valores apropriados, em geral:

    • A rotina de expedição define Status como STATUS_SUCCESS ou como um erro apropriado (STATUS_XXX), que pode ser o valor retornado por uma chamada para uma rotina de suporte ou, para determinadas solicitações síncronas, por um driver inferior.

      Se um driver de nível inferior retornar STATUS_PENDING, um driver de nível superior não deverá chamar IoCompleteRequest para o IRP, com uma exceção: o driver de nível superior pode usar um evento para sincronizar entre sua rotina IoCompletion e sua rotina de expedição, nesse caso, a rotina IoCompletion sinaliza o evento e retorna STATUS_MORE_PROCESSING_REQUIRED. A rotina de expedição aguarda o evento e chama IoCompleteRequest para concluir o IRP.

    • Ele define Informações como o número de bytes transferidos com êxito se uma solicitação de transferência de dados, como uma solicitação de leitura ou gravação, foi atendida.

    • Ele define Informações como um valor que varia de acordo com a solicitação específica para outros IRPs que ele conclui com STATUS_SUCCESS.

    • Ele define Informações como um valor que varia de acordo com a solicitação específica para IRPs que ele conclui com um aviso STATUS_XXX. Por exemplo, ele definiria Informações como o número de bytes transferidos para um aviso como STATUS_BUFFER_OVERFLOW.

    • Normalmente, ele define Informações como zero para solicitações concluídas com um erro STATUS_XXX.

  2. Chama IoCompleteRequest com o IRP e com PriorityBoost = IO_NO_INCREMENT.

  3. Retorna o STATUS_XXX apropriado que ele já definiu no bloco de status de E/S. Observe que uma chamada para IoCompleteRequest torna o IRP fornecido inacessível pelo chamador, portanto, o valor retornado de uma rotina de expedição não pode ser definido do bloco de E/S status de um IRP já concluído.

Siga esta diretriz de implementação para chamar IoCompleteRequest com um IRP:

Sempre solte qualquer bloqueio de rotação que o driver esteja mantendo antes de chamar IoCompleteRequest.

Leva um tempo indeterminado para concluir um IRP, particularmente em uma cadeia de drivers em camadas. Além disso, um deadlock poderá ocorrer se uma rotina IoCompletion de um driver de nível superior enviar um IRP de volta para um driver inferior que esteja mantendo um bloqueio de rotação.