디바이스 전원 상태에 대한 IRP_MN_QUERY_POWER 처리
디바이스 쿼리 전원 IRP는 단일 디바이스의 상태 변경에 대해 쿼리하고 디바이스의 스택에 있는 모든 드라이버로 전송됩니다. 이러한 IRP는 I/O 스택 위치의 Power.Type 멤버에서 DevicePowerState를 지정합니다.
드라이버는 스택 아래로 이동할 때 쿼리 전원 IRP를 처리합니다.
함수 또는 필터 드라이버는 다음 중 한 가지가 true인 경우 IRP_MN_QUERY_POWER 요청에 실패할 수 있습니다.
디바이스가 절전 모드 해제를 사용하도록 설정되어 있고 요청된 전원 상태가 디바이스가 시스템을 절전 모드 해제할 수 있는 상태보다 낮습니다. 예를 들어 D2에서 시스템을 절전 모드에서 해제할 수 있지만 D3에서 해제할 수 없는 디바이스는 D3에 대한 쿼리에 실패하지만 D2에 대한 쿼리는 성공합니다.
요청된 상태를 입력하면 드라이버가 열려 있는 모뎀 연결과 같은 데이터가 손실되는 작업을 중단해야 합니다. 드라이버가 이러한 이유로 쿼리에 실패하는 경우는 거의 없습니다. 대부분의 상황에서 애플리케이션은 이러한 경우를 처리합니다.
IRP_MN_QUERY_POWER 요청에 실패하기 위해 드라이버는 다음 단계를 수행합니다.
PoStartNextPowerIrp를 호출하여 드라이버가 다음 전원 IRP를 처리할 준비가 되었음을 나타냅니다. (Windows Server 2003, Windows XP 및 Windows 2000만 해당)
Irp-IoStatus.Status>를 오류 상태 설정하고 IoCompleteRequest를 호출하여 IO_NO_INCREMENT 지정합니다. 드라이버는 IRP를 디바이스 스택 아래로 더 멀리 전달하지 않습니다.
DispatchPower 루틴에서 오류 상태 반환합니다.
드라이버가 쿼리 전원 IRP에 성공하는 경우 작업을 시작하거나 쿼리된 전원 상태에 대한 후속 IRP_MN_SET_POWER 요청이 성공적으로 완료되지 않도록 하는 다른 작업을 수행해서는 안 됩니다.
IRP에 성공한 드라이버는 다음과 같이 쿼리된 상태에 대한 설정 전원 IRP를 준비하고 쿼리 IRP를 전달해야 합니다.
미해결 I/O 작업을 완료합니다.
들어오는 I/O 요청을 큐에 추가합니다.
지정된 전원 상태로의 전환을 방해하는 다른 새 활동을 시작하지 마세요. 그러나 드라이버는 디바이스 컨텍스트를 저장하거나 종료를 향한 다른 단계를 수행해서는 안 됩니다.
IoCopyCurrentIrpStackLocationToNext를 호출하여 다음 하위 드라이버에 대한 IRP 스택 위치를 설정합니다.
IoCompletion 루틴을 설정합니다. IoCompletion 루틴에서 PoStartNextPowerIrp(Windows Server 2003, Windows XP 및 Windows 2000에만 해당)을 호출하여 드라이버가 다음 전원 IRP를 처리할 준비가 되었음을 나타냅니다.
IoCallDriver(Windows 7 및 Windows Vista) 또는 PoCallDriver(Windows Server 2003, Windows XP 및 Windows 2000)를 호출하여 쿼리 IRP를 다음 하위 드라이버에 전달합니다. IRP를 완료하지 마세요.
STATUS_PENDING 반환합니다. 드라이버는 Irp-IoStatus.Status>에서 값을 변경해서는 안 됩니다.
쿼리 전원 IRP가 버스 드라이버에 도달하면 버스 드라이버는 PoStartNextPowerIrp(Windows Server 2003, Windows XP 및 Windows 2000에만 해당)을 호출하고, 드라이버가 지정된 전원 상태로 변경되거나 실패 상태 설정할 수 없는 경우 Irp-IoStatus.Status>를 STATUS_SUCCESS 설정합니다. 그런 다음 버스 드라이버는 IoCompleteRequest를 호출하여 IO_NO_INCREMENT 지정합니다.
일반적인 디바이스 스택의 드라이버는 다음과 같이 디바이스 쿼리 전원 IRP를 처리합니다.
대부분의 필터 드라이버는 IRP를 다음 하위 드라이버( Power IRP 전달 참조)에 전달하고 STATUS_PENDING 반환해야 합니다. 그러나 일부 필터 드라이버는 먼저 들어오는 IRP를 큐에 대기하거나 디바이스 전원 상태를 저장하는 것과 같은 디바이스별 작업을 수행해야 할 수 있습니다.
함수 드라이버는 디바이스별 작업(예: 보류 중인 I/O 요청 완료, 들어오는 I/O 요청 큐 대기, 디바이스 컨텍스트 저장 또는 디바이스 전원 변경) 을 수행하고, IoCompletion 루틴을 설정하고, 디바이스 전원 IRP를 다음 하위 드라이버에 전달합니다( Power IRP 전달 참조). DispatchPower 루틴에서 STATUS_PENDING 반환합니다.
버스 드라이버는 PoStartNextPowerIrp (Windows Server 2003, Windows XP 및 Windows 2000에만 해당)을 호출하여 다음 전원 IRP를 시작합니다. 그런 다음, IO_NO_INCREMENT 지정하여 IRP를 완료합니다. 드라이버가 IRP를 즉시 완료할 수 없는 경우 IoMarkIrpPending을 호출하고DispatchPower 루틴에서 STATUS_PENDING 반환하며 나중에 IRP를 완료합니다.
대상 디바이스가 이미 쿼리된 전원 상태에 있더라도 각 함수 또는 필터 드라이버는 I/O를 큐에 대기하고 IRP를 다음 하위 드라이버로 전달해야 합니다. IRP는 디바이스 스택을 따라 버스 드라이버까지 이동해야 하며, 이를 완료합니다.
IRP_MN_QUERY_POWER 요청을 처리하는 동안 드라이버는 DispatchPower 루틴에서 최대한 빨리 돌아와야 합니다. 드라이버는 동일한 IRP를 처리하는 코드에서 신호를 받는 커널 이벤트에 대해 DispatchPower 루틴에서 대기해서는 안 됩니다. 전원 IRP는 시스템 전체에서 동기화되므로 교착 상태가 발생할 수 있습니다.