Partilhar via


Usando E/S não armazenada em buffer nem direta

Se um driver não estiver usando E/S direta nem em buffer, o gerenciador de E/S passará os endereços virtuais de espaço do usuário originais em IRPs que ele envia para o driver. Para acessar esses buffers com segurança, o driver deve estar em execução no contexto do thread de chamada. Normalmente, portanto, apenas drivers de nível mais alto, como FSDs, podem usar esse método para acessar buffers.

Um driver intermediário ou de nível mais baixo nem sempre pode atender a essa condição. Por exemplo, se um thread solicitante aguardar a conclusão de uma solicitação de E/S ou se um driver de nível superior estiver em camadas sobre o driver intermediário ou de nível mais baixo, é improvável que as rotinas do driver de nível inferior sejam chamadas no contexto do thread solicitante.

O gerenciador de E/S determina que uma operação de E/S não está usando E/S em buffer nem direta da seguinte maneira:

Quando um driver recebe um IRP que especifica uma operação de E/S sem buffer nem E/S direta, ele deve fazer o seguinte:

  1. Verifique a validade do intervalo de endereços do buffer de usuário e marcar se o acesso de leitura ou gravação apropriado é permitido, usando as rotinas de suporte ProbeForRead e ProbeForWrite. O driver deve colocar seus acessos ao intervalo de endereços do buffer dentro de um manipulador de exceção fornecido pelo driver, para que um thread de usuário não possa alterar os direitos de acesso para o buffer enquanto o driver estiver acessando a memória. Se a investigação gerar uma exceção, o driver deverá retornar um erro. O driver deve chamar essas rotinas dentro do contexto do thread que fez a solicitação de E/S; portanto, apenas um driver de nível superior pode executar essa tarefa.

  2. Gerencie buffers e operações de memória de uma das seguintes maneiras:

    • Execute suas próprias operações de buffer duplo, como o gerenciador de E/S faz para drivers que usam E/S em buffer. Para obter mais informações, consulte Usando E/S em buffer.
    • Crie seus próprios MDLs e bloqueie o buffer chamando as rotinas de suporte do gerenciador de memória, como o gerenciador de E/S faz para drivers que usam E/S direta. Para obter mais informações, consulte Usando E/S direta.
    • Execute todas as operações necessárias no buffer do usuário diretamente no contexto do thread de chamada. O driver deve encapsular seu acesso ao buffer dentro de um manipulador de exceção fornecido pelo driver, caso um thread de usuário altere os direitos de acesso para o buffer ou os dados no buffer enquanto o driver está acessando a memória. Para obter mais informações, consulte Tratamento de exceções.

Na verdade, o driver deve escolher por IRP se deseja fazer E/S em buffer, E/S direta ou E/S no contexto do thread de chamada e deve manipular quaisquer exceções que possam ocorrer em um contexto de thread no modo de usuário. O driver deve gerenciar seus próprios acessos de buffer de usuário, operações de buffer duplo e mapeamentos de memória, conforme necessário, em vez de permitir que o gerenciador de E/S manipule essas operações para o driver.