Locais de pilha de E/S

O gerente de E/S fornece a cada driver em uma cadeia de drivers em camadas um local de pilha de E/S para cada IRP configurado. Cada local de pilha de E/S consiste em uma estrutura de IO_STACK_LOCATION .

O gerente de E/S cria uma matriz de locais de pilha de E/S para cada IRP, com um elemento de matriz correspondente a cada driver em uma cadeia de drivers em camadas. Cada driver possui um dos locais de pilha no pacote e chama IoGetCurrentIrpStackLocation para obter informações específicas do driver sobre a operação de E/S.

Cada driver em tal cadeia é responsável por chamar IoGetNextIrpStackLocation e, em seguida, configurar o local da pilha de E/S do driver mais baixo. Qualquer local de pilha de E/S do driver de nível superior também pode ser usado para armazenar contexto sobre uma operação para que a rotina de IoCompletion do driver possa executar suas operações de limpeza.

A figura de PROCESSAMENTO de IRPs em Drivers em Camadas mostra dois locais de pilha de E/S no IRP original porque mostra dois drivers, um driver do sistema de arquivos e um driver de dispositivo de armazenamento em massa. Os IRPs alocados pelo driver no processamento de IRPs na figura drivers em camadas não têm um local de pilha para o FSD que os criou. Qualquer driver de nível superior que aloca IRPs para drivers de nível inferior também determina quantos locais de pilha de E/S os novos IRPs devem ter, de acordo com o valor StackSize do objeto de dispositivo do driver mais baixo.

A figura a seguir mostra o conteúdo do IRP mais detalhadamente.

diagram illustrating the contents of i/o stack location in an irp.

Conforme mostrado na figura, cada local de pilha de E/S específica do driver em um IRP contém as seguintes informações gerais:

  • O código de função principal (IRP_MJ_XXX), indicando a operação básica que o driver deve executar

  • Para alguns códigos de função principais tratados por FSDs, drivers SCSI de nível superior e todos os drivers PnP, um código de função menor (IRP_MN_XXX), indicando qual subcase da operação básica o driver deve realizar

  • Um conjunto de argumentos específicos da operação, como o comprimento e o local inicial de um buffer no qual ou do qual o driver transfere dados

  • Um ponteiro para o objeto de dispositivo criado pelo driver, representando o dispositivo de destino (físico, lógico ou virtual) para a operação solicitada

  • Um ponteiro para o objeto de arquivo, representando um arquivo aberto, um dispositivo, um diretório ou um volume

    Um driver do sistema de arquivos acessa o objeto de arquivo por meio de seu local de pilha de E/S em IRPs. Outros drivers geralmente ignoram o objeto de arquivo.

O conjunto de códigos de função principal e secundária do IRP que um driver específico manipula pode ser específico do tipo de dispositivo. No entanto, drivers de nível mais baixo e drivers intermediários (incluindo drivers de filtro e função PnP) geralmente lidam com o seguinte conjunto de solicitações básicas:

  • IRP_MJ_CREATE – abra o objeto de dispositivo de destino, indicando que ele está presente e disponível para operações de E/S

  • IRP_MJ_READ – transferir dados do dispositivo

  • IRP_MJ_WRITE – transferir dados para o dispositivo

  • IRP_MJ_DEVICE_CONTROL – configurar (ou redefinir) o dispositivo, de acordo com um ioctl (código de controle de E/S) específico do tipo de dispositivo definido pelo sistema

  • IRP_MJ_CLOSE – fechar o objeto de dispositivo de destino

  • IRP_MJ_PNP – execute uma operação de Plug and Play no dispositivo. Uma solicitação de IRP_MJ_PNP é enviada pelo gerente PnP por meio do gerente de E/S.

  • IRP_MJ_POWER – executar uma operação de energia no dispositivo. Uma solicitação de IRP_MJ_POWER é enviada pelo power manager por meio do gerente de E/S.

Para obter mais informações sobre os principais códigos de função IRP que os drivers precisam manipular, consulte códigos de função principais do IRP.

Em geral, o gerente de E/S envia IRPs com pelo menos dois locais de pilha de E/S para drivers de dispositivo de armazenamento em massa porque um sistema de arquivos está em camadas sobre outros drivers para dispositivos de armazenamento em massa. O gerente de E/S envia IRPs com um único local de pilha para qualquer driver que não tenha nenhum outro driver em camadas acima dele.

No entanto, o gerente de E/S fornece suporte para adicionar um novo driver a qualquer cadeia de drivers existentes no sistema. Por exemplo, um driver espelho intermediário que faz backup de dados em uma determinada partição de disco pode ser inserido entre um par de drivers, como o driver do sistema de arquivos e o driver de nível mais baixo mostrados na figura processando IRPs em drivers em camadas . Quando esse novo driver se anexa à pilha de dispositivos, o gerenciador de E/S ajusta o número de locais de pilha de E/S em todos os IRPs que envia para o sistema de arquivos, o espelho e os drivers de nível mais baixo. Cada IRP que o sistema de arquivos na figura de Processamento de IRPs em Drivers em Camadas alocada também conteria outro local de pilha de E/S para um driver espelho tão novo.

Observe que esse suporte para adicionar novos drivers a uma cadeia existente implica determinadas restrições ao acesso de qualquer driver específico aos locais de pilha de E/S em IRPs:

  • Um driver de nível superior em uma cadeia de drivers em camadas pode acessar com segurança apenas seus próprios locais de pilha de E/S do driver de nível inferior em qualquer IRP. Esse driver deve configurar o local da pilha de E/S para o próximo driver de nível inferior em IRPs. No entanto, ao criar um driver de nível mais alto, você não pode prever quando (ou se) um novo driver será adicionado à cadeia existente logo abaixo do driver.

    Portanto, você deve assumir que qualquer driver adicionado posteriormente lidará com os mesmos códigos de função principais do IRP (IRP_MJ_XXX) que o driver de nível inferior deslocado fez.

  • O driver de nível mais baixo em uma cadeia de drivers em camadas pode acessar com segurança apenas seu próprio local de pilha de E/S em qualquer IRP. Ao criar esse driver, você não pode prever quando (ou se) um novo driver será adicionado à cadeia existente acima do driver do dispositivo.

    Ao criar um driver de nível mais baixo, suponha que o driver possa continuar processando IRPs usando as informações passadas em seu próprio local de pilha de E/S, qualquer que seja a fonte de origem de um determinado IRP e por mais que muitos drivers estejam em camadas acima dele.