IRP를 처리하는 드라이버 루틴에서 취소 동기화

드라이버의 StartIo 루틴을 포함하여 취소 가능한 상태로 유지되는 IRP를 사용하여 큐에서 제거하거나 호출되는 모든 드라이버 루틴은 다음을 수행해야 합니다.

  1. IoAcquireCancelSpinLock을 호출합니다.

  2. IrpDeviceObject-CurrentIrp>와 같은지 확인합니다. 그렇지 않은 경우 IoReleaseCancelSpinLock을 호출하고 컨트롤을 반환합니다.

    둘이 동일하지 않은 경우 IoStartPacket이 취소 스핀 잠금을 해제하고 이 루틴이 이를 획득한 시간 사이에 CurrentIrp이 취소되었을 수 있습니다.

  3. NULLCancelRoutine 포인터를 사용하여 IoSetCancelRoutine을 호출하여 취소 가능한 상태에서 IRP를 제거합니다.

  4. IRP 취소> 필드를 확인하여 IRP를 취소할지 또는 I/O 요청 처리를 시작할지 여부를 확인합니다.

    Irp-Cancel>TRUE로 설정된 경우 다음을 수행합니다.

    • IoReleaseCancelSpinLock을 호출합니다.

    • Irp-IoStatus.Status>를 STATUS_CANCELLED 설정합니다.

    • Irp-IoStatus.Information>을 0으로 설정합니다.

    • IoStartNextPacket(StartIo 루틴)을 호출하여 다음 패킷을 시작합니다.

    • 우선 순위가 IO_NO_INCREMENT IoCompleteRequest 를 호출하여 IRP를 완료합니다.

    Irp-Cancel>FALSE로 설정된 경우 IoReleaseCancelSpinLock을 호출하고 요청된 I/O 요청 처리를 시작하거나 IRP를 다음 하위 드라이버에 적절하게 전달합니다.

I/O 관리자에서 제공하는 디바이스 큐를 사용하는 대신 자체 IRP 큐를 관리하는 드라이버는 IoSetCancelRoutine을 호출할 때 취소 스핀 잠금을 획득할 필요가 없습니다. 그러나 이러한 드라이버는 취소 루틴이 이미 시작되었는지 여부를 확인하기 위해 IoSetCancelRoutine이 반환하는 취소 루틴 포인터를 검사 합니다.

취소 가능한 IRP를 처리하는 모든 드라이버에서 기본 디바이스가 요청된 I/O 작업에 대해 프로그래밍되기 전에 IRP를 처리하는 모든 드라이버 루틴은 들어오는 모든 IRP의 취소 가능한 상태를 검사 합니다. 특히 StartIoControllerControl 루틴을 모두 사용하는 최상위 디바이스 드라이버는 이미 설명한 대로 이러한 드라이버 루틴 모두에서 들어오는 IRP를 처리해야 합니다.