다음을 통해 공유


Driver-Allocated 리소스 릴리스

드라이버가 레지스트리를 사용하는 방법, 디바이스 확장, 컨트롤러 확장 또는 드라이버 할당 비페이지 풀에서 시스템 개체 및 리소스를 설정하는 방법에 대한 세부 정보는 드라이버마다 다릅니다. 그러나 언로드 루틴은 드라이버가 사용 중인 리소스를 단계적으로 해제해야 합니다.

드라이버의 언로드 루틴은 다른 드라이버 루틴이 현재 사용 중이거나 해당 리소스를 해제하기 전에 특정 리소스를 곧 사용하고 있는지 확인해야 합니다.

일반적으로 언로드 루틴은 다음 단계에서 드라이버 할당 리소스를 모두 해제합니다.

  1. 드라이버가 아직 수행하지 않은 경우 가능한 경우 물리적 디바이스에서 인터럽트를 사용하지 않도록 설정한 다음 인터럽트가 비활성화되는 즉시 IoDisconnectInterrupt 를 호출합니다.

  2. 다른 드라이버 루틴이 언로드 루틴에서 해제하려는 리소스를 참조할 수 없는지 확인합니다.

    예를 들어 드라이버의 IoTimer 루틴이 현재 특정 디바이스 개체에 대해 사용하도록 설정된 경우 언로드 루틴은 IoStopTimer를 호출해야 합니다. 드라이버의 디스패처 개체를 기다리는 스레드가 없고, 디스패처 개체에 대한 스토리지를 해제하기 전에 해당 타이머 개체가 CustomTimerDpc 루틴에 대한 호출을 위해 큐에 대기되지 않도록 해야 합니다. ISR이 큐에 대기했을 수 있는 CustomDpc 루틴이 있는 경우 KeRemoveQueueDpc를 호출해야 합니다.

    드라이버가 IoQueueWorkItem이라고 하는 경우 작업 항목이 완료되었는지 확인해야 합니다. IoQueueWorkItem 은 연결된 디바이스 개체에 대한 참조를 가져옵니다. 이러한 참조가 남아 있는 경우 드라이버를 언로드할 수 없습니다.

    드라이버가 PsCreateSystemThread라고 하는 경우 드라이버가 언로드 되기 전에 스레드 자체가 PsTerminateSystemThread 를 호출할 수 있도록 드라이버에서 만든 스레드도 실행되도록 언로드 루틴도 실행해야 합니다. 드라이버는 PsCreateSystemThread에서 반환된 ThreadHandle을 사용하여 ZwClose를 호출하여 드라이버에서 만든 시스템 스레드를 해제할 수 없습니다.

  3. 드라이버가 할당한 디바이스별 리소스를 해제합니다. 이렇게 하려면 다음 시스템 지원 루틴을 호출해야 할 수 있습니다.

  4. DriverEntry 또는 Reinitialize 루틴이 디바이스 개체의 디바이스 확장 또는 컨트롤러 개체의 컨트롤러 확장에 설정된 시스템 개체 및 리소스를 해제합니다(만든 경우). 특히 드라이버는 디바이스 개체(IoDeleteDevice) 또는 컨트롤러 개체(IoDeleteController)를 삭제하기 전에 다음을 수행해야 합니다.

    • IoDisconnectInterrupt를 호출하여 해당 디바이스 또는 컨트롤러 확장에 저장된 인터럽트 개체 포인터를 해제합니다.
    • IoGetDeviceObjectPointer를 호출하고 이 포인터를 디바이스 또는 컨트롤러 확장에 저장한 경우 다음으로 낮은 드라이버의 파일 개체에 대한 포인터를 사용하여 ObDereferenceObject를 호출합니다.
    • IoAttachDevice 또는 IoAttachDeviceToDeviceStack을 호출하고 이 포인터를 디바이스 또는 컨트롤러 확장에 저장한 경우 하위 드라이버의 디바이스 개체에 대한 포인터를 사용하여 IoDetachDevice를 호출합니다.
  5. 드라이버의 물리적 디바이스에 대해 DriverEntry 또는 Reinitialize 루틴이 주장한 하드웨어 리소스(있는 경우)를 \Registry\Machine\Hardware\ResourceMap 트리 아래의 레지스트리에서 해제합니다.

  6. DriverEntry 또는 \Registry 아래 레지스트리에 저장된 루틴을 다시 초기화하는 디바이스의 이름을 제거합니다. \DeviceMap 트리도 마찬가지입니다.

드라이버가 디바이스, 시스템 및 하드웨어 리소스를 릴리스한 후 디바이스 및 컨트롤러 개체 해제에 설명된 대로 디바이스 및 컨트롤러 개체를 삭제할 수 있습니다.