다음을 통해 공유


잠금 제거 사용

잠금 제거 루틴은 디바이스의 미해결 I/O 작업 수를 추적하고 드라이버의 디바이스 개체를 분리하고 삭제하는 것이 안전한 시기를 결정하는 방법을 제공합니다. 시스템은 자체 추적 메커니즘을 구현하는 대신 드라이버 작성기에 이러한 루틴을 제공합니다.

드라이버는 다음 두 가지 용도로 이 메커니즘을 사용할 수 있습니다.

  1. 잠금이 유지되는 동안 드라이버의 DispatchPnP 루틴이 IRP_MN_REMOVE_DEVICE 요청을 완료하지 않도록 합니다(예: 다른 드라이버 루틴이 디바이스에 액세스하는 동안).

  2. 드라이버가 디바이스 개체를 삭제하지 않아야 하는 이유의 수를 계산하고, 해당 수가 0으로 이동할 때 이벤트를 설정하려면

잠금 제거를 초기화하려면 드라이버가 디바이스 확장에서 IO_REMOVE_LOCK 구조를 할당한 다음 IoInitializeRemoveLock을 호출해야 합니다. 일반적으로 드라이버는 디바이스 개체에 대한 디바이스 확장의 나머지 부분을 초기화할 때 AddDevice 루틴에서 IoInitializeRemoveLock을 호출합니다.

드라이버는 I/O 작업을 시작할 때마다 IoAcquireRemoveLock을 호출해야 합니다. 드라이버는 I/O 작업을 완료할 때마다 IoReleaseRemoveLock을 호출해야 합니다. 드라이버는 잠금을 두 번 이상 획득할 수 있습니다. 잠금 제거 루틴은 잠금의 미해결 획득 횟수를 유지합니다. IoAcquireRemoveLock에 대한 각 호출은 개수를 증가시키고 IoReleaseRemoveLock은 개수를 감소합니다.

드라이버가 해당 코드에 대한 참조(타이머, DPC, 콜백 등)를 전달하는 경우에도 IoAcquireRemoveLock을 호출해야 합니다. 그런 다음, 이벤트가 반환되면 드라이버는 IoReleaseRemoveLock을 호출해야 합니다.

IRP_MN_REMOVE_DEVICE 대한 디스패치 코드에서 드라이버는 잠금을 다시 한 번 획득한 다음 IoReleaseRemoveLockAndWait을 호출해야 합니다. 이 루틴은 잠금의 미해결 인수가 모두 해제될 때까지 반환되지 않습니다. 큐에 대기된 I/O 작업이 완료되도록 하려면 각 드라이버는 IRP_MN_REMOVE_DEVICE 요청을 다음 하위 드라이버에 전달한 후 메모리를 해제하기 전에 IoDetachDevice를 호출하거나 IoDeleteDevice를 호출한 후 IoReleaseRemoveLockAndWait을 호출해야 합니다. IoReleaseRemoveLockAndWait이 특정 제거 잠금에 대해 호출되면 동일한 제거 잠금에 대한 IoAcquireRemoveLock에 대한 모든 후속 호출이 실패합니다.

IoReleaseRemoveLockAndWait이 반환되면 드라이버는 디바이스를 제거할 준비가 되어 있고 I/O 작업을 수행할 수 없는 상태로 간주해야 합니다. 따라서 드라이버는 제거 잠금을 다시 초기화하기 위해 IoInitializeRemoveLock을 호출하지 않아야 합니다. 드라이버 검증 도구에서 드라이버를 확인하는 동안 이 규칙을 위반하면 버그 검사가 발생합니다.

드라이버는 디바이스 개체의 디바이스 확장에 IO_REMOVE_LOCK 구조를 저장하므로 드라이버가 IRP_MN_REMOVE_DEVICE 요청을 처리하는 동안 디바이스 확장을 삭제하면 제거 잠금이 삭제됩니다.