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 configura um objeto de fila de dispositivo ao chamar KeInitializeDeviceQueue durante a inicialização do driver ou do dispositivo. Depois de iniciar o(s) seu(s) dispositivo(s), o driver insere IRPs nessa fila chamando KeInsertDeviceQueue ou KeInsertByKeyDeviceQueue. A figura a seguir ilustra essas chamadas.
Como mostra esta figura, o driver deve fornecer o armazenamento para um objeto de fila de dispositivos, que deve permanecer residente. Os drivers que configuram um objeto de fila de dispositivo geralmente fornecem o armazenamento necessário no de extensão de 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 de ou em pool não paginado alocado pelo driver.
Se o driver fornecer armazenamento para o objeto de fila de dispositivo em uma extensão de dispositivo, ele chamará KeInitializeDeviceQueue depois de criar o objeto de dispositivo e antes de iniciar o dispositivo. Em outras palavras, o driver pode inicializar a fila a partir da sua rotina AddDevice, ou quando lida com uma solicitação de PnP IRP_MN_START_DEVICE. Na chamada para KeInitializeDeviceQueue, o driver passa um ponteiro para o armazenamento que fornece para o objeto de fila de dispositivos.
Depois de iniciar o seu dispositivo, o driver pode inserir um IRP na sua fila de dispositivos chamando KeInsertDeviceQueue, que coloca o IRP no fim da fila, ou KeInsertByKeyDeviceQueue, que coloca o IRP na fila de acordo com o valor de SortKey determinado pelo driver, conforme mostrado na figura anterior.
Cada uma dessas rotinas de suporte retorna um valor booleano indicando se o IRP foi inserido na fila. Cada uma dessas chamadas também define o estado do objeto de fila de dispositivos como Ocupado se a fila estiver vazia no momento (Not-Busy). No entanto, se a fila estiver vazia (Not-Busy), nenhuma das rotinas KeInsertXxxDeviceQueue insere o IRP na fila. Em vez disso, ele define o estado do objeto de fila de dispositivos como Ocupado e retorna FALSE. Como o IRP não foi enfileirado, o driver deve passá-lo para outra rotina de driver para processamento posterior.
Ao configurar filas de dispositivos suplementares, siga esta diretriz de implementação:
Quando uma chamada para KeInsertXxxDeviceQueue retorna FALSE, o chamador deve passar o IRP que tentou enfileirar para processamento adicional para outra rotina de driver. No entanto, a chamada para KeInsertXxxDeviceQueue altera o estado do objeto de fila de dispositivos para Busy, de modo que o próximo IRP a entrar é inserido na fila, a menos que o driver chame KeRemoveXxxDeviceQueue primeiro.
Quando o estado do objeto de fila de dispositivos é definido como Ocupado, o controlador pode remover um IRP da fila para processamento adicional ou redefinir o estado de volta para Not-Busy chamando uma das seguintes rotinas de suporte:
KeRemoveDeviceQueue remover o IRP no início da fila
KeRemoveByKeyDeviceQueue para remover um IRP escolhido de acordo com um valor de SortKey determinado pelo controlador
KeRemoveEntryDeviceQueue remover um determinado IRP na fila ou determinar se um determinado IRP está na fila
KeRemoveEntryDeviceQueue devolve um valor booleano indicando se o IRP estava na fila de dispositivos.
Chamar qualquer uma dessas rotinas para remover uma entrada de uma fila de dispositivos que está vazia, mas ocupada, altera o estado da fila para Não-ocupado.
Cada objeto de fila de dispositivo é protegido por um bloqueio giratório 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 forma segura em ambientes multiprocessadores de qualquer rotina de driver em execução a um nível de IRQL inferior ou igual a DISPATCH_LEVEL. Devido a essa restrição de IRQL, um driver não pode chamar nenhuma rotina de KeXxxDeviceQueue de suas rotinas deISR ouSynchCritSection, que são executadas em DIRQL.
Consulte Gerir Prioridades de Hardware e Bloqueios de Giro para obter mais informações. Para obter os requisitos de IRQL para uma rotina de suporte específica, consulte a página de referência da rotina.