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.
Para alocar um IRP para uma solicitação assíncrona, que será processada em um contexto de thread arbitrário por drivers inferiores, uma rotina DispatchReadWrite pode chamar uma das seguintes rotinas de suporte:
IoAllocateIrp, que aloca um IRP e vários locais de pilha de E/S de inicialização zero
A rotina de despacho deve configurar a localização da pilha de E/S do próximo driver inferior para o IRP que foi recém-alocado, geralmente copiando informações (possivelmente modificadas) a partir da sua própria localização de pilha no IRP original. Se um driver de nível superior aloca um local de pilha de E/S próprio para um IRP recém-alocado, a rotina de despacho pode configurar informações de contexto por solicitação para a rotina IoCompletion usar.
IoBuildAsynchronousFsdRequest, que configura o local da pilha de E/S do próximo driver inferior para o chamador, de acordo com os parâmetros especificados pelo chamador
Drivers de nível superior podem chamar esta rotina para alocar IRPs para solicitações IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS e IRP_MJ_SHUTDOWN.
Quando uma rotina IoCompletion é chamada para tal IRP, ela pode verificar o bloco de status de E/S e, se necessário (ou possível), configurar o local da pilha de E/S do próximo driver inferior no IRP novamente e tentar novamente a solicitação ou reutilizá-la. No entanto, a rotina IoCompletion não tem armazenamento de contexto local para si mesma no IRP, portanto, o driver deve manter o contexto sobre a solicitação original em outro lugar na memória residente.
IoMakeAssociatedIrp, que aloca um IRP e um número de locais de pilha de E/S inicializados a zero, associando o IRP a um IRP mestre.
Drivers intermediários não podem chamar IoMakeAssociatedIrp para criar IRPs para drivers de nível inferior.
Qualquer driver de nível mais alto que chame IoMakeAssociatedIrp para criar IRPs para drivers inferiores pode retornar o controlo ao gestor de E/S depois de enviar os IRPs associados e chamar IoMarkIrpPending para o IRP mestre original. Um driver de nível mais alto pode confiar no gerente de E/S para concluir o IRP mestre quando todos os IRPs associados tiverem sido concluídos por drivers inferiores.
Os drivers rara vez definem uma rotina IoCompletion para um IRP associado. Se um driver de nível mais alto chamar IoSetCompletionRoutine para um IRP associado que ele cria, o gestor de E/S não concluirá o IRP mestre se o driver retornar STATUS_MORE_PROCESSING_REQUIRED de sua rotina IoCompletion. Nessas circunstâncias, a rotina IoCompletion do driver deve preencher explicitamente o IRP mestre com IoCompleteRequest.
Se um driver aloca um local de pilha de E/S próprio em um novo IRP, a rotina de despacho deve chamar IoSetNextIrpStackLocation antes de chamar IoGetCurrentIrpStackLocation para configurar o contexto em seu próprio local de pilha de E/S para a rotina IoComplete. Para obter mais informações, consulte Processando IRPs num driver Intermediate-Level.
A rotina de despacho deve chamar IoMarkIrpPending com o IRP original, mas não com nenhum IRP alocado pelo driver porque a rotina IoCompletion os liberará.
Se a rotina de despacho estiver alocando IRPs para transferências parciais e o driver de dispositivo subjacente puder controlar um dispositivo de mídia removível, a rotina de despacho deverá configurar o contexto de thread em seus IRPs recém-alocados a partir do valor em Tail.Overlay.Thread no IRP original.
Um driver subjacente a um dispositivo de mídia removível pode chamar IoSetHardErrorOrVerifyDevice, que faz referência ao ponteiro em Irp->Tail.Overlay.Thread, para um IRP alocado pelo driver. Se o driver chamar essa rotina de suporte, o driver do sistema de arquivos pode enviar uma caixa de diálogo para o thread de usuário apropriado que solicita que o usuário cancele, tente novamente ou falhe uma operação que o driver não pôde satisfazer. Veja Suporte a suportes amovíveis para mais informações.
As rotinas de despacho devem retornar STATUS_PENDING depois de enviar todos os IRPs alocados pelo controlador para os controladores inferiores.
A rotina IoCompletion de um driver deve libertar todos os IRPs alocados pelo driver com IoFreeIrp antes de chamar IoCompleteRequest para o IRP original. Quando conclui o IRP original, a rotina IoCompletion deve liberar todos os IRPs alocados pelo driver antes de retornar o controle.
Cada driver de nível superior configura quaisquer IRPs alocados (e reutilizados) para drivers inferiores de tal forma que é irrelevante para o driver de dispositivo subjacente se uma determinada solicitação vem de um driver intermediário ou se origina de qualquer outra fonte, como um sistema de arquivos ou aplicativo de modo de usuário.
Os drivers de nível mais alto podem chamar IoMakeAssociatedIrp para alocar IRPs e configurá-los para uma cadeia de drivers mais baixos. O gerenciador de E/S conclui automaticamente o IRP original quando todos os IRPs associados foram concluídos, desde que o driver não chame IoSetCompletionRoutine com o IRP original ou com qualquer um dos IRPs associados que ele aloca. Os drivers de nível mais alto não devem, no entanto, alocar IRPs associados para qualquer IRP que solicite uma operação de E/S em buffer.
Um driver de nível intermediário não pode alocar IRPs para drivers de nível inferior chamando IoMakeAssociatedIrp. Qualquer IRP que um driver intermediário receba já pode ser um IRP associado, e um driver não pode associar outro IRP a esse IRP.
Em vez disso, se um driver intermediário criar IRPs para drivers inferiores, ele deverá chamar IoAllocateIrp, IoBuildDeviceIoControlRequest, IoBuildSynchronousFsdRequest ou IoBuildAsynchronousFsdRequest. No entanto, IoBuildSynchronousFsdRequest pode ser chamado somente nas seguintes circunstâncias:
Por um thread criado por driver para criar IRPs para solicitações de leitura ou gravação, porque esse thread pode aguardar em um contexto de thread não arbitrário (próprio) em um objeto dispatcher, como um evento inicializado pelo driver passado para IoBuildSynchronousFsdRequest
No contexto de thread do sistema durante a inicialização ou durante o descarregamento
Para criar IRPs para operações inerentemente síncronas, como criar, liberar, desligar, fechar e solicitações de controle de dispositivo
No entanto, é mais provável que um driver chame IoBuildDeviceIoControlRequest para alocar IRPs de controle de dispositivo do que IoBuildSynchronousFsdRequest.