다음을 통해 공유


취소 루틴 구현

I/O 관리자는 취소할 입력 IRP와 I/O 요청의 대상 디바이스를 나타내는 DeviceObject 포인터를 사용하여 드라이버 제공 취소 루틴을 호출합니다.

IRP는 드라이버의 DispatchReadWrite 루틴이 현재 사용자가 Win32 애플리케이션을 닫을 때 큐에 대기한 것일 수 있습니다. IRP는 기본 디바이스의 특성에 따라 상위 수준 드라이버가 명시적으로 취소한 것일 수도 있습니다.

Cancel 루틴이 호출되면 입력 IRP는 이미 대상 디바이스 개체의 CurrentIrp이거나 드라이버에 StartIo 루틴이 있는 경우 대상 디바이스 개체와 연결된 디바이스 큐에 있을 수 있습니다. 드라이버에 StartIo 루틴이 없는 경우, Cancel 루틴이 호출될 때 IRP는 드라이버가 관리하는 내부 IRP 큐에 있을 수 있습니다. 어쨌든 I/O 관리자가 들어오는 IRP에 대해 Cancel 루틴을 호출하기 전에 I/O 관리자는 이 IRP의 Cancel 멤버를 TRUE 설정하고 IRP의 CancelRoutine 멤버를 NULL 설정합니다.

연결된 IRP가 있는 마스터 IRP에 대한 취소 루틴은 IoCancelIrp 호출하여 관련 IRP를 취소합니다.

모든 취소 루틴은 다음 지침을 따라야 합니다.

  • IoReleaseCancelSpinLock 호출하여 시스템의 취소 스핀 잠금을 해제합니다.

  • I/O 상태 블록의 상태 멤버를 STATUS_CANCELLED 설정하고 Information 멤버를 0으로 설정합니다.

  • IoCompleteRequest호출하여 지정된 IRP를 완료합니다.

  • 취소 루틴은 항상 시스템 취소 스핀 잠금이 유지된 상태에서 호출되므로 이 루틴은 IoReleaseCancelSpinLock 먼저 호출하지 않는 한 IoAcquireCancelSpinLock 호출해서는 안 됩니다.

  • 취소 루틴은 제어를 반환할 때 시스템 취소 스핀 잠금을 가지고 있을 수 없습니다. 즉, 취소 루틴은 컨트롤을 반환하기 전에 IoReleaseCancelSpinLock 한 번 이상 호출해야 합니다.

  • IoAcquireCancelSpinLock을 호출하는 경우, 취소 실행 코드는 가능한 한 빨리 IoReleaseCancelSpinLock을 호출해야 합니다.

  • 스핀 잠금을 유지하는 동안 IRP로 IoCompleteRequest 호출하지 마세요. 스핀 락을 보유한 상태에서 IRP를 완료하려고 시도하면 교착 상태가 발생할 수 있습니다.