Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A figura que ilustra a abertura de um objeto de arquivo mostra um IRP com dois locais de pilha de E/S, mas um IRP pode ter qualquer número de locais de pilha de E/S, dependendo de quantos drivers em camadas lidarão com uma determinada solicitação.
A figura a seguir ilustra com mais detalhes como os drivers na figura Abrindo um objeto de arquivo usam rotinas de suporte de E/S (IoXxx rotinas) para processar o IRP para uma solicitação de leitura ou gravação.
O gestor de E/S chama o controlador do sistema de arquivos (FSD) com o IRP que alocou para a solicitação de leitura/gravação do subsistema. O FSD acede ao seu local de pilha de E/S no IRP para determinar que operação deve realizar.
O FSD pode dividir a solicitação original em solicitações menores (possivelmente para mais de um driver de dispositivo) chamando uma rotina de suporte de E/S (IoAllocateIrp) uma ou mais vezes para alocar IRPs adicionais. Os IRPs adicionais são retornados ao FSD com locais de pilha de E/S preenchidos com zeros para os drivers de nível inferior. A seu critério, o FSD pode reutilizar o IRP original, em vez de alocar IRPs adicionais, como mostrado na figura anterior, configurando o local da pilha de E/S do próximo driver inferior no IRP original e passando-o para drivers inferiores.
Para cada IRP alocado pelo driver, o FSD na figura anterior chama uma rotina de suporte de E/S para registar uma rotina de conclusão fornecida pelo FSD; na rotina de conclusão, o FSD pode determinar se os drivers inferiores satisfizeram a solicitação e pode liberar cada IRP alocado pelo driver quando os drivers inferiores a tiverem completado. O gerente de E/S chamará a rotina de conclusão fornecida pelo FSD se cada IRP alocado pelo driver foi concluído com êxito, concluído com um status de erro ou cancelado. Um driver de nível superior é responsável por liberar quaisquer IRPs que aloca e configura em seu próprio nome para drivers de nível inferior. O gestor de E/S liberta os IRPs que aloca depois que todos os drivers os concluírem.
Em seguida, o FSD chama uma rotina de suporte de E/S (IoGetNextIrpStackLocation) para acessar a localização da pilha de E/S do próximo driver do nível inferior, a fim de configurar a solicitação para o próximo driver do nível inferior. (Na figura anterior, o próximo driver inferior passa a ser o driver de nível mais baixo.) Em seguida, o FSD chama uma rotina de suporte de E/S (IoCallDriver) para passar esse IRP para o driver inferior seguinte.
Quando é chamado com o IRP, o driver de nível mais baixo verifica a sua localização de pilha de E/S para determinar qual operação (indicada pelo código de função IRP_MJ_XXX) deve executar no dispositivo de destino. O dispositivo de destino é representado pelo objeto de dispositivo na sua localização designada na pilha de E/S e é passado juntamente com o IRP para o controlador. O driver de nível mais baixo pode assumir que o gerente de E/S roteou o IRP para um ponto de entrada que o driver definiu para a operação de IRP_MJ_XXX (aqui IRP_MJ_READ ou IRP_MJ_WRITE) e que o driver de nível superior verificou a validade de outros parâmetros para a solicitação.
Se não houvesse nenhum driver de nível superior, o driver de nível mais baixo verificaria se os parâmetros de entrada para uma operação IRP_MJ_XXX são válidos. Se estiverem, o driver geralmente chama rotinas de suporte de E/S para informar ao gerente de E/S que uma operação de dispositivo está pendente no IRP e para enfileirar o IRP ou passá-lo para outra rotina fornecida pelo driver que acessa o dispositivo de destino (aqui, um dispositivo físico ou lógico: o disco ou uma partição no disco).
O gestor de E/S determina se o driver já está ocupado a processar outro IRP para o dispositivo de destino, coloca o IRP em fila se estiver e retorna. Caso contrário, o gerenciador de E/S roteia o IRP para uma rotina fornecida pelo driver que inicia a operação de E/S em seu dispositivo. (Neste estágio, ambos os drivers na figura anterior e o gerenciador de E/S retornam o controle.)
Quando o dispositivo interrompe, a rotina de serviço de interrupção (ISR) do controlador faz apenas o trabalho necessário para parar a interrupção do dispositivo e guardar o contexto necessário sobre a operação. Em seguida, o ISR chama uma rotina de suporte de E/S (IoRequestDpc) com o IRP para enfileirar uma rotina DPC (Deferred Procedure Call) fornecida pelo driver para completar a operação solicitada com uma prioridade de hardware inferior à do ISR.
Quando o DPC do driver assume o controlo, utiliza o contexto (passado na chamada do ISR para IoRequestDpc) para concluir a operação de E/S. O DPC chama uma rotina de suporte para retirar da fila o próximo IRP (se houver) e passar esse IRP para a rotina fornecida pelo driver que inicia as operações de E/S no dispositivo (consulte a Etapa 5). Em seguida, o DPC define o status sobre a operação recém-concluída no bloco de status de E/S do IRP e o retorna ao gerenciador de E/S com IoCompleteRequest.
O gestor de E/S define a zero a localização da pilha de E/S do driver de nível mais baixo no IRP e invoca a rotina de conclusão registada do sistema de ficheiros (veja o Passo 3) com o IRP alocado pelo FSD. Essa rotina de conclusão verifica o bloco de estado de E/S para determinar se a solicitação deve ser repetida ou se deve atualizar qualquer estado interno mantido sobre a solicitação original e liberar o IRP alocado pelo driver. O sistema de arquivos pode coletar informações de status de todos os IRPs alocados pelo driver e enviados para drivers de nível inferior, permitindo assim definir o status de E/S e completar o IRP original. Quando o sistema de arquivos concluir o IRP original, o gestor de E/S retornará um valor NTSTATUS ao solicitante original (função nativa do subsistema) da operação de E/S.
Como o driver do sistema de arquivos mostrado na figura Processando IRPs em Layered Drivers, qualquer novo driver adicionado a uma cadeia de drivers existentes pode fazer o seguinte:
Defina sua própria rotina de conclusão em um IRP. A rotina IoCompletion verifica o bloco de status de E/S para determinar se os drivers de nível inferior concluíram o IRP com êxito, se cancelaram o IRP e/ou se o completaram com um erro. A rotina de conclusão também pode atualizar qualquer estado específico do IRP que o driver possa ter salvo, liberar quaisquer recursos específicos da operação que o driver possa ter alocado e assim por diante, antes de concluir o IRP. Além disso, a rotina de conclusão pode adiar a conclusão do IRP (informando ao gerente de E/S que é necessário mais processamento no IRP) e pode enviar outra solicitação para o próximo driver de nível inferior antes de permitir que o IRP seja concluído.
Configure o local da pilha de E/S do próximo driver de nível inferior nos IRPs que ele aloca e envie solicitações para o driver de nível inferior seguinte.
Encaminhe todas as solicitações recebidas para drivers inferiores, definindo a localização da pilha de I/O do próximo driver mais baixo em cada IRP e chamando IoCallDriver. (Observe que para IRPs com código de função principal IRP_MJ_POWER, os drivers devem usar PoCallDriver.)
Cada objeto de dispositivo criado pelo driver representa um dispositivo físico, lógico ou virtual para o qual um driver específico executa solicitações de E/S. Para obter informações detalhadas sobre como criar e configurar um objeto de dispositivo, consulte Device Objects and Device Stacks.
Como a figura Processamento de IRPs em Camadas de Drivers também mostra, a maioria dos drivers processa cada IRP em etapas por meio de um conjunto fornecido pelo driver de rotinas padrão definidas pelo sistema, mas os drivers em diferentes níveis de uma cadeia necessariamente têm rotinas padrão diferentes. Por exemplo, apenas os drivers de nível mais baixo lidam com interrupções de um dispositivo físico, portanto, apenas um driver de nível mais baixo teria um ISR e um DPC que concluem operações de E/S controladas por interrupção. Por outro lado, como esse driver sabe que a E/S está completa quando recebe uma interrupção do seu dispositivo, ele não precisa de uma rotina de conclusão. Apenas um driver de nível superior teria uma ou mais rotinas de conclusão como o FSD mostrado na figura.