컨트롤 디바이스 개체 사용

제어 디바이스 개체는 PnP(플러그 앤 플레이) 또는 전원 관리 작업을 지원하지 않는 프레임워크 디바이스 개체입니다. 드라이버는 제어 디바이스 개체를 사용하여 소프트웨어 전용 가상 디바이스 또는 레거시 하드웨어 디바이스 (즉, PnP 또는 전원 관리 기능을 제공하지 않는 디바이스)를 나타낼 수 있습니다.

컨트롤 디바이스 개체를 만드는 드라이버도 일반적으로 디바이스 개체에 대한 기호 링크를 만듭니다. 애플리케이션은 기호 링크 이름을 Microsoft Win32 CreateFile 함수와 같은 API 요소에 전달하여 컨트롤 디바이스 개체에 I/O 요청을 보낼 수 있습니다.

프레임워크는 제어 디바이스 개체를 디바이스 스택에 연결하지 않습니다. 따라서 애플리케이션이 컨트롤 디바이스 개체에 I/O 요청을 보낼 때 I/O 관리자는 스택 맨 위에 있는 드라이버 대신 컨트롤 디바이스 개체를 만든 드라이버에 직접 요청을 전달합니다. 그러나 추가 드라이버는 IoAttachDevice 를 호출하여 디바이스 개체를 제어 디바이스 개체 위에 연결할 수 있습니다. 이 경우 추가 드라이버가 먼저 I/O 요청을 받습니다.)

제어 디바이스 개체 사용

제어 디바이스의 일반적인 두 가지 용도는 다음과 같습니다.

  1. 드라이버가 사용할 애플리케이션에 대한 사용자 지정 I/O 컨트롤 코드 집합을 지원하는 경우 PnP 디바이스에 대한 필터 드라이버입니다.

    애플리케이션이 사용자 지정 I/O 컨트롤 코드를 드라이버 스택의 맨 위로 보내려고 시도하는 경우(예: 디바이스 인터페이스의 기호 링크 이름 사용) 드라이버가 사용자 지정 I/O 컨트롤 코드를 인식하지 못하는 경우 필터 드라이버 위의 드라이버가 I/O 요청에 실패할 수 있습니다. 이 문제를 방지하기 위해 필터 드라이버는 제어 디바이스 개체를 만들 수 있습니다. 애플리케이션은 컨트롤 디바이스 개체의 기호 링크 이름을 사용하여 I/O 컨트롤 코드를 필터 드라이버에 직접 보낼 수 있습니다.

    필터 드라이버가 문제를 방지하는 더 좋은 방법은 버스 드라이버 역할을 하고 원시 모드에서 작동하는 자식 디바이스를 열거하는 것입니다. 즉, 필터 드라이버가 지원하는 각 디바이스에 대해 드라이버는 함수 드라이버가 필요하지 않은 PDO(물리적 디바이스 개체)를 만들 수 있습니다. 드라이버는 이러한 각 디바이스에 대해 WdfPdoInitAssignRawDeviceWdfDeviceInitAssignName 을 호출하고 애플리케이션은 사용자 지정 I/O 컨트롤 코드를 보낼 때 이름으로 디바이스를 식별할 수 있습니다.)

  2. PnP를 지원하지 않는 디바이스용 드라이버입니다.

    이러한 디바이스의 디바이스 개체는 디바이스 스택에 있지 않고 PnP 기능을 제공하지 않으므로 이러한 드라이버는 제어 디바이스 개체를 사용해야 합니다. PnP가 아닌 디바이스를 지원하는 방법에 대한 자세한 내용은 비 PnP 드라이버에서 Kernel-Mode Driver Framework 사용을 참조하세요.

컨트롤 디바이스 개체 만들기

컨트롤 디바이스 개체를 만들려면 드라이버는 다음을 수행해야 합니다.

  1. WdfControlDeviceInitAllocate를 호출하여 WDFDEVICE_INIT 구조를 가져옵니다.

  2. 필요에 따라 개체 초기화 메서드를 호출하여 WDFDEVICE_INIT 구조를 초기화합니다. 드라이버는 다음 초기화 메서드만 호출할 수 있습니다.

  3. WDFDEVICE_INIT 구조체의 내용을 사용하여 프레임워크 디바이스 개체를 만드는 WdfDeviceCreate를 호출합니다.

  4. 다음 초기화 작업을 완료합니다.

  5. WdfControlFinishInitializing을 호출합니다.

제어 디바이스 개체 사용에 대한 규칙

제어 디바이스 개체를 만드는 드라이버는 다음 규칙을 준수해야 합니다.

  • 드라이버는 제어 디바이스 개체의 핸들을 자식 디바이스를 열거하는 프레임워크 메서드에 전달할 수 없습니다.

  • 드라이버는 제어 디바이스 개체의 핸들을 디바이스 인터페이스를 지원하는 프레임워크 메서드에 전달할 수 없습니다.

  • 드라이버는 I/O 큐를 만들고 큐에 대한 요청 처리기를 등록할 수 있지만 프레임워크는 큐를 전원 관리하도록 허용하지 않습니다.

  • 드라이버는 제어 디바이스 개체에 대한 파일 개체 를 만들 수 있습니다.

컨트롤 디바이스 개체 이름 지정

모든 제어 디바이스 개체의 이름을 지정해야 합니다. 일반적으로 드라이버는 WdfDeviceInitAssignName 을 호출하여 디바이스 이름을 할당한 다음 , WdfDeviceCreateSymbolicLink 를 호출하여 애플리케이션이 개체에 액세스하는 데 사용할 수 있는 기호 링크 이름을 만듭니다.

드라이버가 WdfDeviceInitAssignName 을 호출하여 디바이스 이름을 할당하지 않으면 프레임워크는 제어 디바이스의 이름을 자동으로 생성하지만 드라이버는 WdfDeviceCreateSymbolicLink를 호출할 수 없습니다.

드라이버는 WdfDeviceInitSetDeviceClass 를 호출하여 제어 디바이스에 대한 디바이스 설정 클래스 를 지정할 수 있습니다. 디바이스 설정 클래스는 설치 클래스에 속하는 디바이스에 대한 관리자가 제공한 정보를 포함하는 레지스트리의 섹션을 식별합니다. WdfDeviceInitSetDeviceClass를 호출하는 방법에 대한 자세한 내용은 Framework-Based 드라이버에서 디바이스 액세스 제어를 참조하세요.

시스템 종료 알림 수신

제어 디바이스 개체는 PnP를 지원하지 않으므로 드라이버가 디바이스의 전원 상태가 변경될 때 드라이버에 알리는 콜백 함수를 등록할 수 없습니다. 그러나 드라이버는 WdfControlDeviceInitSetShutdownNotification 을 호출하여 EvtDeviceShutdownNotification 콜백 함수를 등록할 수 있습니다. 이 콜백 함수는 시스템이 전원을 잃을 때 드라이버에 알릴 수 있습니다.

컨트롤 디바이스 개체 삭제

일부 드라이버는 다음과 같이 드라이버가 언로드되기 전에 컨트롤 디바이스 개체를 삭제해야 합니다.

  • 드라이버가 PnP 또는 전원 관리를 지원하지 않는 제어 디바이스 개체를 만들고 드라이버가 PnP 및 전원 관리를 지원하는 프레임워크 디바이스 개체도 만드는 경우 드라이버는 결국 IRQL = PASSIVE_LEVEL WdfObjectDelete 를 호출하여 제어 디바이스 개체를 삭제해야 합니다.

    드라이버가 두 가지 유형의 디바이스 개체를 모두 만드는 경우 드라이버가 제어 디바이스 개체를 삭제할 때까지 운영 체제에서 드라이버를 언로드할 수 없습니다.

    그러나 프레임워크가 다른 디바이스 개체를 삭제할 때까지 드라이버는 제어 디바이스 개체를 삭제해서는 안됩니다. 프레임워크가 다른 디바이스 개체를 삭제한 시기를 확인하려면 드라이버가 해당 개체에 대해 EvtCleanupCallback 함수를 제공해야 합니다.

  • 드라이버가 컨트롤 디바이스 개체를 만들지만 PnP 및 전원 관리를 지원하는 프레임워크 디바이스 개체를 만들지 않는 경우 드라이버는 제어 디바이스 개체를 삭제할 필요가 없습니다.

    이 경우 프레임워크는 드라이버의 EvtDriverUnload 콜백 함수가 반환된 후 컨트롤 디바이스 개체를 삭제합니다.