Compartilhar via


Locais da pilha de E/S

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

O gerente de E/S cria uma matriz de posições da pilha de E/S para cada IRP, com cada elemento da matriz correspondendo a um 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 próximo driver inferior. Qualquer posição da pilha de E/S de um driver de nível superior também pode ser usada para armazenar informações de contexto sobre uma operação, permitindo que a rotina IoCompletion do driver execute suas operações de limpeza.

A figura de Processamento de IRPs em Drivers em Camadas mostra dois locais de pilha de I/O no IRP original porque exibe dois drivers: um driver de sistema de arquivos e um driver de dispositivo de armazenamento em massa. Os IRPs alocados pelo driver na figura Processamento de IRPs em Drivers em Camadas não possuem uma localização de pilha para o FSD (Driver do Sistema de Arquivos) que os gerou. 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 com mais detalhes.

diagrama ilustrando o conteúdo da localização da pilha de E/S em um IRP.

Conforme mostrado na figura, cada posição da pilha de E/S específica ao 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 realizar

  • Para alguns códigos principais de função tratados por FSDs, drivers SCSI de nível superior e todos os drivers PnP, um código de função secundária (IRP_MN_XXX) indica qual subcaso 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, dispositivo, diretório ou volume

    Um driver do sistema de arquivos acessa o objeto de arquivo por meio de sua posição na pilha de E/S em IRPs (Pacotes de Solicitação de Entrada/Saída). Outros drivers geralmente ignoram o objeto de arquivo.

O conjunto de códigos de função principal e secundária do IRP que um determinado driver manipula pode ser específico do tipo de dispositivo. No entanto, drivers de nível mais baixo e drivers intermediários (incluindo drivers de função PnP e filtro) 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 – feche o objeto de dispositivo de destino

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

  • IRP_MJ_POWER – execute uma operação de energia no dispositivo. Uma solicitação 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 lidar, consulte Códigos de Função Principais do IRP.

Em geral, o gerente de E/S envia IRPs com pelo menos duas posições na pilha de E/S para drivers de dispositivos de armazenamento em massa, porque um sistema de arquivos é estruturado em camadas sobre outros drivers para esses dispositivos. O gerente de E/S envia IRPs com uma única posição de pilha para qualquer driver que não tenha nenhum outro driver sobreposto a ele.

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 enviados para o sistema de arquivos, o espelho e os drivers de nível mais baixo. Cada IRP que o sistema de arquivos na figura Processamento de IRPs em Drivers em Camadas alocado também conteria outro local de pilha de E/S para um novo driver espelho.

Observe que esse suporte para adicionar novos drivers a uma cadeia existente implica certas restrições ao acesso que qualquer driver específico tem 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 e os locais de pilha de E/S do driver de nível imediatamente inferior em qualquer IRP. Esse driver deve configurar o local da pilha de E/S para o driver de nível inferior seguinte em IRPs. No entanto, ao projetar 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 manipulará os mesmos códigos de função principais do IRP (IRP_MJ_XXX) que o driver de nível inferior deslocado.

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

    Ao projetar um driver de nível mais baixo, suponha que o driver possa continuar a processar IRPs usando as informações passadas em sua própria posição de pilha de E/S, qualquer que seja a fonte de origem de um determinado IRP e independentemente de quantos drivers estejam em camadas acima dele.