대기/절전 모드 해제 IRP를 보낸 드라이버만 해당 IRP를 취소할 수 있습니다.
드라이버는 다음과 같은 상황에서 보류 중인 대기/절전 모드 해제 IRP를 취소해야 할 수 있습니다.
드라이버는 디바이스에 대한 PnP IRP_MN_STOP_DEVICE, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE또는 IRP_MN_SURPRISE_REMOVAL 요청을 받습니다. 드라이버는 디바이스를 다시 시작한 후 대기/절전 모드 해제 IRP(PoRequestPowerIrp)를 다시 실행해야 합니다.
시스템이 절전 모드로 전환되지만, 디바이스가 시스템을 깨우도록 설정되어서는 안 됩니다.
예를 들어 USB 허브 드라이버는 나중에 입력 디바이스 중 하나를 절전 모드로 전환할 경우 디바이스 시작 시 IRP_MN_WAIT_WAKE 요청을 보낼 수 있습니다. 시스템이 작동 상태에 있는 동안 디바이스의 절전 모드 해제 신호는 디바이스를 작업 상태로 반환하지만 시스템 전원 상태에는 영향을 주지 않습니다. 시스템이 종료를 준비할 때, 디바이스가 시스템을 깨우지 못하도록 해야 할 경우 USB 허브 드라이버가 해당 IRP를 취소합니다.
시스템이 디바이스가 깨울 수 없는 절전 상태로 들어갑니다. 즉, DEVICE_CAPABILITIES 구조에 지정된 SystemWake 값보다 성능이 낮은 상태를 입력합니다.
디바이스가 깨우기 신호에 응답할 수 없는 전원 상태에 진입하고 있습니다. 즉, DEVICE_CAPABILITIES 구조에 지정된 DeviceWake 값보다 성능이 낮은 상태를 입력합니다.
IRP를 취소하기 위해 대기/절전 해제 IRP를 보낸 드라이버는 드라이버가 PoRequestPowerIrp호출할 때 이전에 반환된 IRP의 포인터를 IoCancelIrp에 전달합니다.
드라이버는 전송하지 않은 대기/절전 모드 해제 IRP를 취소해서는 안 됩니다.
대기/웨이크 IRP에 대한 루틴 취소
많은 함수 및 버스 드라이버가 대기/절전 모드 IRPs에 대해 루틴을 취소해야 합니다. 이러한 루틴을 설정해야 하는 드라이버 유형은 다음과 같습니다.
장치의 깨우기 기능을 활성화하거나 비활성화하도록 장치 설정을 변경하는 드라이버입니다.
부모 디바이스의 드라이버에 IRP_MN_WAIT_WAKE 요청을 보내는 드라이버입니다.
취소 루틴을 사용하면 드라이버가 디바이스에 대해 절전 모드 해제를 사용하지 않도록 설정하고 보류 중인 대기/절전 모드 해제 IRP와 관련된 모든 데이터를 정리할 수 있습니다. 부모 디바이스에 대한 대기/절전 모드 해제 IRP를 요청하는 드라이버는 해당 IRP도 취소할 수 있습니다.
대기/절전 취소 루틴에서 드라이버는 다음 단계를 수행해야 합니다.
IoSetCancelRoutine 호출하여 IRP의 취소 루틴을 NULL 로 초기화합니다.
IoReleaseCancelSpinLock호출하여 IRP에 지정된 CancelIRQL 전달하여 IRP에 대한 취소 스핀 잠금을 해제합니다.
디바이스 확장에서 관련 필드를 다시 설정합니다. 예를 들어 대기/절전 모드 해제 IRP가 보류 중인 경우 대부분의 드라이버는 플래그를 설정하고 디바이스 확장에서 IRP에 대한 포인터를 유지합니다.
드라이버가 다른 IRP를 취소하는 동안 대기/절전 모드 해제 IRP를 받을 수 있습니다. 드라이버는 스핀 잠금 보호(또는 이에 해당하는 보호) 하에 IRP가 이미 있는지 확인해야 합니다. 이 경우, 드라이버는 작업을 신중하게 동기화하여 올바른 IRP를 취소하도록 해야 합니다. 취소 루틴에서 스핀 락을 사용하는 방법에 대한 자세한 내용은 IRP 취소를 참조하세요.
필요한 디바이스 설정을 변경합니다. 예를 들어 모뎀 드라이버는 디바이스의 절전 모드 해제 설정을 비활성화합니다.
Irp->IoStatus.Status를 STATUS_CANCELLED로 설정합니다.
IoCompleteRequest를 호출하여 대기/깨우기 IRP를 완료하고 IO_NO_INCREMENT를 지정하여 작업을 완료합니다.
드라이버가 이전에 부모 장치에 대한 관련 IRP_MN_WAIT_WAKE 요청을 한 경우, 드라이버는 그 IRP를 자신의 취소 루틴 내에서 반드시 취소해야 합니다. 드라이버는 부모의 IRP를 취소하기 전에 취소 스핀 잠금을 해제해야 합니다.
예를 들어, 디바이스의 버스 드라이버 역할을 하면서 부모 디바이스에 대해 전원 정책을 관리하는 드라이버는, 이전에 부모에게 보낸 관련 대기/절전 모드 해제 IRP를 취소해야 합니다. IoCancelIrp를 호출하면 디바이스 스택을 따라 부모의 취소 루틴이 차례로 호출됩니다.