Manipulando IRP_MN_QUERY_POWER para estados de energia do dispositivo
Um dispositivo query-power IRP consulta sobre uma alteração de estado para um único dispositivo e é enviado para todos os drivers na pilha do dispositivo. Esse IRP especifica DevicePowerState no membro Power.Type do local da pilha de E/S.
Os motoristas lidam com IRPs query-power enquanto viajam pela pilha.
Um driver de função ou filtro poderá falhar em uma solicitação de IRP_MN_QUERY_POWER se qualquer uma das seguintes opções for verdadeira:
O dispositivo está habilitado para ativação e o estado de energia solicitado está abaixo do estado do qual o dispositivo pode ativar o sistema. Por exemplo, um dispositivo que pode ativar o sistema de D2, mas não de D3, falharia em uma consulta para D3, mas teria êxito em uma consulta para D2.
Entrar no estado solicitado forçaria o driver a abandonar uma operação que perderia dados, como uma conexão de modem aberto. Um driver raramente falhará em uma consulta por esse motivo; na maioria das circunstâncias, o aplicativo lida com esses casos.
Para falhar em uma solicitação de IRP_MN_QUERY_POWER , um driver executa as seguintes etapas:
Chame PoStartNextPowerIrp para indicar que o driver está preparado para lidar com o próximo IRP de energia. (Somente Windows Server 2003, Windows XP e Windows 2000.)
Defina Irp-IoStatus.Status> como uma falha status e chame IoCompleteRequest, especificando IO_NO_INCREMENT. O driver não passa o IRP mais abaixo na pilha do dispositivo.
Retornar um erro status de sua rotina DispatchPower.
Se o driver tiver êxito no IRP de energia de consulta, ele não deverá iniciar nenhuma operação ou tomar qualquer outra ação que impeça a conclusão bem-sucedida de uma solicitação de IRP_MN_SET_POWER subsequente para o estado de energia consultado.
Um driver que tenha êxito no IRP deve se preparar para um IRP de set-power para o estado consultado e passar o IRP de consulta da seguinte maneira:
Conclua todas as operações de E/S pendentes.
Solicitações de E/S de entrada na fila.
Evite iniciar outras novas atividades que interfiram em uma transição para o estado de energia especificado. No entanto, o driver não deve salvar o contexto do dispositivo nem seguir outras etapas para o desligamento.
Chame IoCopyCurrentIrpStackLocationToNext para definir o local da pilha IRP para o driver mais baixo.
Definir uma rotina IoCompletion . Na rotina IoCompletion , chame PoStartNextPowerIrp (somente Windows Server 2003, Windows XP e Windows 2000) para indicar a preparação do driver para lidar com o irP de energia seguinte.
Chame IoCallDriver (no Windows 7 e Windows Vista) ou PoCallDriver (no Windows Server 2003, Windows XP e Windows 2000) para passar o IRP de consulta para o driver mais baixo. Não conclua o IRP.
Retornar STATUS_PENDING. O driver não deve alterar o valor em Irp-IoStatus.Status>.
Quando o IRP de energia de consulta atinge o driver de barramento, o motorista do barramento chama PoStartNextPowerIrp (somente Windows Server 2003, Windows XP e Windows 2000) e define Irp-IoStatus.Status> como STATUS_SUCCESS se o driver puder alterar para o estado de energia especificado ou definir uma falha status se não puder. Em seguida, o motorista do ônibus chama IoCompleteRequest, especificando IO_NO_INCREMENT.
Os drivers em uma pilha de dispositivo típica lidam com um IRP de consulta de dispositivo da seguinte maneira:
A maioria dos drivers de filtro deve simplesmente passar o IRP para o driver mais baixo (consulte Passando IRPs de Energia) e retornar STATUS_PENDING. Alguns drivers de filtro, no entanto, podem primeiro precisar executar tarefas específicas do dispositivo, como enfileirar IRPs de entrada ou salvar o estado de energia do dispositivo.
Um driver de função executa tarefas específicas do dispositivo (como, concluir solicitações de E/S pendentes, enfileirar solicitações de E/S de entrada, salvar o contexto do dispositivo ou alterar a energia do dispositivo), define uma rotina de IoCompletion e passa o IRP de energia do dispositivo para o driver mais baixo (consulte Passando Power IRPs). Ele retorna STATUS_PENDING de sua rotina DispatchPower .
O driver de barramento chama PoStartNextPowerIrp (somente Windows Server 2003, Windows XP e Windows 2000) para iniciar o IRP de energia seguinte. Em seguida, ele conclui o IRP, especificando IO_NO_INCREMENT. Se o driver não puder concluir o IRP imediatamente, ele chamará IoMarkIrpPending, retornará STATUS_PENDING de sua rotina DispatchPower e concluirá o IRP posteriormente.
Mesmo que o dispositivo de destino já esteja no estado de energia consultado, cada driver de função ou filtro deverá enfileirar E/S e passar o IRP para o driver mais baixo. O IRP deve percorrer toda a pilha do dispositivo até o motorista do ônibus, o que o conclui.
Ao lidar com uma solicitação de IRP_MN_QUERY_POWER , um driver deve retornar da rotina DispatchPower o mais rápido possível. Um driver não deve esperar em sua rotina DispatchPower para um evento de kernel sinalizado por código que manipula o mesmo IRP. Como os IRPs de energia são sincronizados em todo o sistema, pode ocorrer um deadlock.