IRP를 처리하는 드라이버 루틴에서 취소 동기화
드라이버의 StartIo 루틴을 포함하여 취소 가능한 상태로 유지되는 IRP를 사용하여 큐에서 제거하거나 호출되는 모든 드라이버 루틴은 다음을 수행해야 합니다.
IoAcquireCancelSpinLock을 호출합니다.
Irp가 DeviceObject-CurrentIrp>와 같은지 확인합니다. 그렇지 않은 경우 IoReleaseCancelSpinLock을 호출하고 컨트롤을 반환합니다.
둘이 동일하지 않은 경우 IoStartPacket이 취소 스핀 잠금을 해제하고 이 루틴이 이를 획득한 시간 사이에 CurrentIrp가 취소되었을 수 있습니다.
NULL CancelRoutine 포인터를 사용하여 IoSetCancelRoutine을 호출하여 취소 가능한 상태에서 IRP를 제거합니다.
IRP 취소> 필드를 확인하여 IRP를 취소할지 아니면 I/O 요청 처리를 시작할지 결정합니다.
Irp-Cancel>이 TRUE로 설정된 경우 다음을 수행합니다.
IoReleaseCancelSpinLock을 호출합니다.
Irp-IoStatus.Status>를 STATUS_CANCELLED 설정합니다.
Irp-IoStatus.Information>을 0으로 설정합니다.
우선 순위가 IO_NO_INCREMENT IoCompleteRequest를 호출하여 IRP를 완료합니다.
Irp-Cancel>이 FALSE로 설정된 경우 IoReleaseCancelSpinLock을 호출하고 요청된 I/O 요청 처리를 시작하거나 IRP를 다음 하위 드라이버에 적절하게 전달합니다.
I/O 관리자 제공 디바이스 큐를 사용하는 대신 자체 IRP 큐를 관리하는 드라이버는 IoSetCancelRoutine을 호출할 때 취소 스핀 잠금을 획득할 필요가 없습니다. 그러나 이러한 드라이버는 IoSetCancelRoutine이 반환하는 취소 루틴 포인터를 확인하여 취소 루틴이 이미 시작되었는지 확인해야 합니다.
취소 가능한 IRP를 처리하는 모든 드라이버에서 기본 디바이스가 요청된 I/O 작업에 대해 프로그래밍되기 전에 IRP를 처리하는 모든 드라이버 루틴은 들어오는 모든 IRP의 취소 가능한 상태를 확인해야 합니다. 특히 StartIo 및 ControllerControl 루틴을 모두 사용하는 최고 수준의 디바이스 드라이버는 이미 설명한 대로 이러한 드라이버 루틴 모두에서 들어오는 IRP를 처리해야 합니다.