Manipulando um sistema Query-Power IRP em um proprietário de política de energia do dispositivo

Quando um proprietário da política de energia do dispositivo recebe um IRP_MN_QUERY_POWER para um estado de energia do sistema, ele responde passando a consulta e, em uma rotina IoCompletion , enviando uma IRP_MN_QUERY_POWER para um estado de energia do dispositivo. Quando todos os drivers na pilha tiverem concluído a consulta do dispositivo, o proprietário da política de energia do dispositivo concluirá a consulta do sistema.

Um proprietário de política de energia do dispositivo deve seguir as seguintes etapas em sua rotina DispatchPower para responder a uma consulta do sistema:

  1. Chame IoAcquireRemoveLock, passando o IRP atual, para garantir que o driver não receba uma solicitação de IRP_MN_REMOVE_DEVICE PnP durante a manipulação do IRP de energia.

    Se IoAcquireRemoveLock retornar uma falha status, o driver não deverá continuar processando o IRP. Em vez disso, a partir do Windows Vista, o driver deve chamar IoCompleteRequest para concluir o IRP e retornar a falha status. No Windows Server 2003, Windows XP e Windows 2000, o driver deve chamar PoStartNextPowerIrp, chamar IoCompleteRequest para concluir o IRP e retornar a falha status.

  2. Verifique se o driver pode dar suporte ao estado de energia do sistema consultado, conforme descrito em Falha em um sistema Query-Power IRP em um Filtro ou Driver de Função. Caso contrário, conclua o IRP com uma falha status conforme descrito nessa seção.

    No entanto, um driver não deverá falhar em uma consulta para S4 (PowerSystemHibernate) se o dispositivo estiver habilitado para ativação, mas não puder ativar o sistema do estado de hibernação. Nesse caso, o proprietário da política de energia do driver (que enviou o IRP_MN_WAIT_WAKE) deve cancelar o IRP de espera/ativação e ter êxito na consulta do sistema. Para obter mais informações, consulte Cancelando um IRP de espera/ativação.

  3. Se o driver puder dar suporte ao estado de energia do sistema consultado, chame IoMarkIrpPending.

  4. Configure o local da pilha IRP para o driver mais baixo chamando IoCopyCurrentIrpStackLocationToNext.

  5. Defina uma rotina IoCompletion no IRP de energia de consulta do sistema.

  6. Chame IoCallDriver (no Windows 7 e Windows Vista) ou PoCallDriver (no Windows Server 2003, Windows XP e Windows 2000), para passar o IRP para o driver mais baixo.

  7. Retornar STATUS_PENDING.

A rotina IoCompletion deve fazer o seguinte:

  1. Verifique Irp-IoStatus.Status> para garantir que os drivers inferiores tenham concluído o IRP com êxito. Se um driver inferior tiver especificado um valor NTSTATUS sem êxito, a rotina IoCompletion deverá retornar o valor NTSTATUS.

  2. Se drivers inferiores tiverem concluído o IRP com êxito, chame PoRequestPowerIrp para enviar um IRP de energia de consulta do dispositivo para um estado de energia do dispositivo válido para o estado de energia do sistema consultado. Se necessário, consulte a matriz DEVICE_STATE na estrutura DEVICE_CAPABILITIES para determinar quais estados de energia do dispositivo são válidos para o estado de energia do sistema consultado.

  3. Especifique uma rotina de retorno de chamada (parâmetro CompletionFunction ) na chamada para PoRequestPowerIrp e passe o IRP do sistema na área Contexto .

  4. Retorne STATUS_MORE_PROCESSING_REQUIRED para que o driver possa concluir o processamento do IRP de consulta do sistema na rotina de retorno de chamada.

Depois que o IRP for concluído e todas as rotinas de IoCompletion definidas durante o processamento irp forem executadas, o power manager, por meio do gerenciador de E/S, chamará a rotina de retorno de chamada do gerenciador de políticas de energia (o parâmetro CompletionFunction para PoRequestPowerIrp). A rotina de retorno de chamada, por sua vez, deve fazer o seguinte:

  1. Chame PoStartNextPowerIrp para iniciar o próximo IRP de energia. (Somente Windows Server 2003, Windows XP e Windows 2000.)

  2. Conclua o IRP de energia de consulta do sistema (chame IoCompleteRequest) com o status retornado para o IRP de energia de consulta do dispositivo.

  3. Chame IoReleaseRemoveLock para liberar o bloqueio adquirido anteriormente.

Lembre-se de que o proprietário da política de energia do dispositivo não só envia a consulta do dispositivo, mas também deve maniê-la em seu caminho para baixo na pilha do dispositivo. Para obter mais informações, consulte Manipulando IRP_MN_QUERY_POWER para estados de energia de dispositivo.