취소 루틴 구현

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

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

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

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

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

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

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

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

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

  • 취소 루틴은 컨트롤을 반환할 때 시스템 취소 스핀 잠금을 보유할 수 없습니다. 즉, 모든 Cancel 루틴은 컨트롤을 반환하기 전에 IoReleaseCancelSpinLock 을 한 번 이상 호출해야 합니다.

  • IoAcquireCancelSpinLock을 호출하는 경우 Cancel 루틴은 가능한 한 빨리 IoReleaseCancelSpinLock에 대한 상호 호출을 수행해야 합니다.

  • 스핀 잠금을 유지하는 동안 IRP를 사용하여 IoCompleteRequest 를 호출하지 마세요. 스핀 잠금을 유지하는 동안 IRP를 완료하려고 하면 교착 상태가 발생할 수 있습니다.