Partilhar via


Configurando e usando filas de dispositivos

Um driver configura um objeto de fila de dispositivo chamando KeInitializeDeviceQueue na inicialização do driver ou do dispositivo. Depois de iniciar seus dispositivos, o driver insere IRPs nessa fila chamando KeInsertDeviceQueue ou KeInsertByKeyDeviceQueue. A figura a seguir ilustra essas chamadas.

configurando e usando filas de dispositivos.

Como mostra essa figura, o driver deve fornecer o armazenamento para um objeto de fila do dispositivo, que deve ser residente. Os drivers que configuram um objeto de fila de dispositivo geralmente fornecem o armazenamento necessário na extensão do dispositivo de um objeto de dispositivo criado pelo driver, mas o armazenamento pode estar em uma extensão de controlador se o driver usar um objeto de controlador ou em um pool nãopagado alocado pelo driver.

Se o driver fornecer armazenamento para o objeto de fila do dispositivo em uma extensão de dispositivo, ele chamará KeInitializeDeviceQueue depois de criar o objeto do dispositivo e antes de iniciar o dispositivo. Em outras palavras, o driver pode inicializar a fila de sua rotina AddDevice ou quando lida com uma solicitação de IRP_MN_START_DEVICE PnP. Na chamada para KeInitializeDeviceQueue, o driver passa um ponteiro para o armazenamento que fornece para o objeto de fila do dispositivo.

Depois de iniciar seus dispositivos, o driver pode inserir um IRP em sua fila de dispositivos chamando KeInsertDeviceQueue, que coloca o IRP na parte final da fila, ou KeInsertByKeyDeviceQueue, que coloca o IRP na fila de acordo com um valor SortKey determinado pelo driver, conforme mostrado na figura anterior.

Cada uma dessas rotinas de suporte retorna um valor booliano que indica se o IRP foi inserido na fila. Cada uma dessas chamadas também define o estado do objeto de fila do dispositivo como Ocupado se a fila estiver vazia no momento (Não Ocupado). No entanto, se a fila estiver vazia (Não Ocupada), nem a rotina De DeviceQueue do KeInsertXxx insere o IRP na fila. Em vez disso, ele define o estado do objeto de fila do dispositivo como Ocupado e retorna FALSE. Como o IRP não foi enfileirado, o driver deve passá-lo para outra rotina de driver para processamento adicional.

Ao configurar filas de dispositivo suplementares, siga esta diretriz de implementação:

Quando uma chamada para KeInsertXxxDeviceQueue retorna FALSE, o chamador deve passar o IRP em que tentou fazer fila para processamento adicional para outra rotina de driver. No entanto, a chamada para KeInsertXxxDeviceQueue altera o estado do objeto de fila do dispositivo para Ocupado, portanto, o próximo IRP a entrar é inserido na fila, a menos que o driver chame KeRemoveXxxDeviceQueue primeiro.

Quando o estado do objeto da fila do dispositivo é definido como Ocupado, o driver pode desempacotar um IRP para processamento adicional ou redefinir o estado para Not-Busy chamando uma das seguintes rotinas de suporte:

  • KeRemoveDeviceQueue para remover o IRP no cabeçalho da fila

  • KeRemoveByKeyDeviceQueue para remover um IRP escolhido de acordo com um valor SortKey determinado pelo driver

  • KeRemoveEntryDeviceQueue para remover um IRP específico na fila ou para determinar se um IRP específico está na fila

    KeRemoveEntryDeviceQueue retorna um Boolean indicando se o IRP estava na fila do dispositivo.

Chamar qualquer uma dessas rotinas para remover uma entrada de uma fila de dispositivos vazia, mas Ocupado altera o estado da fila para Não Ocupado.

Cada objeto de fila de dispositivo é protegido por um bloqueio de rotação executivo interno (não mostrado na figura Usando um objeto de fila de dispositivo ). Como resultado, um driver pode inserir IRPs na fila e removê-los de maneira segura de vários processadores de qualquer rotina de driver em execução em menos de ou igual a IRQL = DISPATCH_LEVEL. Devido a essa restrição irql, um driver não pode chamar qualquer rotina KeXxxDeviceQueue de suas rotinas ISR ou SynchCritSection , que são executadas em DIRQL.

Consulte Gerenciando prioridades de hardware e bloqueios de rotação para obter mais informações. Para requisitos de IRQL para uma rotina de suporte específica, consulte a página de referência da rotina.