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.
Um driver de classe ou outro driver de nível superior pode alocar IRPs para solicitações de controle de E/S e enviá-los para o próximo driver inferior da seguinte maneira:
Aloque ou reutilize um pacote de solicitação de E/S (IRP) com o código de função principal IRP_MJ_DEVICE_CONTROL ou IRP_MJ_INTERNAL_DEVICE_CONTROL. Você pode usar a rotina IoBuildDeviceIoControlRequest para alocar especificamente um IRP IOCTL. Você também pode usar rotinas de inicialização e criação de IRP de uso geral, como IoAllocateIrp, IoReuseIrp ou IoInitializeIrp. Para obter mais informações sobre a alocação de IRP, consulte Criando IRPs para drivers de Lower-Level.
Configure a localização da pilha de E/S do driver de nível inferior para o IRP, com o código IOCTL_XXX e os parâmetros apropriados.
Se a solicitação IOCTL for concluída de forma assíncrona, chame a rotina KeInitializeEvent para inicializar um objeto de evento como um evento de notificação. O driver usa esse evento para aguardar a conclusão de uma operação de E/S.
Chame IoSetCompletionRoutine com o IRP para que o driver superior possa fornecer uma rotina IoCompletion, se necessário, para fazer o seguinte:
Determine como o driver inferior lidou com uma determinada solicitação.
Reutilize o IRP criado para enviar outra solicitação ou descarte-o, após o driver inferior concluir a operação solicitada. O driver não pode reutilizar IRPs que IoBuildDeviceIoControlRequest criou. Para obter mais informações, consulte Reutilizando IRPs.
Chame o IoCallDriver para passar a solicitação para o driver inferior.
Se IoCallDriver retornar STATUS_PENDING, chame a rotina KeWaitForSingleObject para colocar o thread atual em um estado de espera. O driver define o parâmetro Object da rotina como o endereço do objeto de evento que foi inicializado na chamada para KeInitializeEvent.
Observação Se o driver chamar KeWaitForSingleObject com seu parâmetro Timeout definido como NULL ou para o endereço de uma variável que contém um valor diferente de zero, o driver deve estar sendo executado em IRQL <= APC_LEVEL em um contexto de thread não arbitrário. Caso contrário, o driver deve estar sendo executado em IRQL <= DISPATCH_LEVEL.
O evento é sinalizado por sua rotina IoCompletion quando a solicitação IOCTL é concluída. Uma vez que o evento é sinalizado, o thread retoma a execução.
Importante Se o driver aloca o objeto de evento como uma variável local na pilha, o driver deve chamar KeWaitForSingleObject com seu parâmetro WaitMode definido como KernelMode. Esse valor de parâmetro impede que a pilha seja paginada.
Para evitar problemas de sincronização e possíveis violações de acesso, os parâmetros para códigos de controle de E/S raramente incluem ponteiros incorporados. Exceto para determinadas solicitações SCSI, os buffers em Irp->AssociatedIrp.SystemBuffer, em Irp->MdlAddress e em Parameters.DeviceIoControl.Type3InputBuffer no local da pilha de E/S de um driver não contêm ponteiros para outros buffers de dados, nem contêm estruturas que tenham ponteiros para códigos de controle de E/S definidos pelo sistema. Para obter mais informações sobre como os buffers de dados são usados com IRPs que contêm códigos de controle de E/S, consulte Descrições de buffer para códigos de controle de E/S.
No entanto, um par de drivers de classe/porta que definem códigos de controle de E/S internos pode passar um ponteiro incorporado para a memória alocada pelo driver do driver de nível superior para o driver de nível inferior. Esse par de drivers de classe/porta é responsável por garantir que o seguinte seja verdadeiro:
Apenas um condutor de cada vez pode aceder aos dados.
Os buffers de dados privados são acessíveis em um contexto de thread arbitrário pelo driver de porta.
Os drivers de vídeo podem chamar a função GDI EngDeviceIoControl para enviar solicitações de controle de E/S definidas de forma privada e específicas do dispositivo, bem como solicitações de controle de E/S públicas definidas pelo sistema, através do driver da porta de vídeo do sistema até os drivers de miniporta de vídeo específicos do adaptador correspondentes.
Qualquer componente de modo de usuário de um pacote de driver pode chamar DeviceIoControl para enviar solicitações de controle de E/S para uma pilha de drivers. O gestor de E/S cria um pedido de IRP_MJ_DEVICE_CONTROL e entrega-o ao controlador de nível mais elevado.