UMDF 1에서 UMDF 2로 드라이버 포팅
이 항목에서는 UMDF(User-Mode Driver Framework) 1 드라이버를 UMDF 2로 이식하는 방법을 설명합니다. Visual Studio 프로젝트가 아닌 원본/Dirs 파일을 사용하는 UMDF 1 드라이버로 시작하거나 Visual Studio 프로젝트에 포함된 UMDF 1 드라이버를 변환할 수 있습니다. 결과는 Visual Studio의 UMDF 2 드라이버 프로젝트가 됩니다. UMDF 2 드라이버는 데스크톱 버전(Home, Pro, Enterprise 및 Education) 및 Windows 10 Mobile Windows 10 둘 다에서 실행됩니다.
Echo 드라이버 샘플은 UMDF 1에서 UMDF 2로 이식된 드라이버의 예입니다.
시작하기
시작하려면 Visual Studio에서 새 드라이버 프로젝트를 엽니다. Visual C++->Windows Driver-WDF-User>> Mode Driver(UMDF 2) 템플릿을 선택합니다. Visual Studio는 드라이버가 구현해야 하는 콜백 함수에 대한 스텁을 포함하는 부분적으로 채워진 템플릿을 엽니다. 이 새로운 드라이버 프로젝트는 UMDF 2 드라이버의 기초가 될 것입니다. UMDF 2 Echo 샘플을 도입해야 하는 코드 형식에 대한 가이드로 사용합니다.
다음으로, 기존 UMDF 1 드라이버 코드를 검토하고 개체 매핑을 확인합니다. UMDF 1의 각 COM 개체에는 UMDF 2에 해당하는 WDF 개체가 있습니다. 예를 들어 IWDFDevice 인터페이스는 WDFDEVICE 핸들로 표시되는 WDF 디바이스 개체에 매핑됩니다. UMDF 1의 거의 모든 프레임워크 제공 인터페이스 메서드에는 UMDF 2에 해당하는 메서드가 있습니다. 예를 들어 IWDFDevice::GetDefaultIoQueue 는 WdfDeviceGetDefaultQueue에 매핑합니다.
마찬가지로 드라이버 제공 콜백 함수는 두 버전에 해당합니다. UMDF 1에서 드라이버 제공 인터페이스에 대한 명명 규칙( IDriverEntry 제외)은 IObjectCallbackXxx이고, UMDF 2에서는 드라이버 제공 루틴에 대한 명명 규칙이 EvtObjectXxx입니다. 예를 들어 IDriverEntry::OnDeviceAdd 콜백 메서드는 EvtDriverDeviceAdd에 매핑됩니다.
드라이버는 UMDF 1과 2 모두에서 콜백 함수를 구현하지만 드라이버가 콜백에 대한 포인터를 제공하는 방식은 다릅니다. UMDF 1에서 드라이버는 드라이버 제공 인터페이스의 멤버로 콜백 메서드를 구현합니다. 드라이버가 프레임워크 개체를 만들 때(예: IWDFDriver::CreateDevice를 호출하여) 프레임워크에 이러한 인터페이스를 등록합니다.
UMDF 2에서 드라이버는 WDF_DRIVER_CONFIG 및WDF_IO_QUEUE_CONFIG 같은 구성 구조에서 드라이버 제공 콜백 함수에 대한 포인터를 제공합니다.
개체 수명 관리
UMDF 1을 사용하는 드라이버는 개체를 삭제하는 것이 안전한 시기를 결정하기 위해 참조 계산을 구현해야 합니다. 프레임워크는 드라이버를 대신하여 개체 참조를 추적하므로 UMDF 2 드라이버는 참조를 계산할 필요가 없습니다.
UMDF 2에서 각 프레임워크 개체에는 기본 부모 개체가 있습니다. 부모 개체가 삭제되면 프레임워크는 연결된 자식 개체를 삭제합니다. 드라이버가 WdfDeviceCreate와 같은 개체 만들기 메서드를 호출하는 경우 기본 부모를 수락하거나 WDF_OBJECT_ATTRIBUTES 구조에서 사용자 지정 부모를 지정할 수 있습니다. 프레임워크 개체 및 기본 부모 개체 목록은 프레임워크 개체 요약을 참조하세요.
드라이버 초기화
UMDF 1 드라이버는 IDriverEntry 인터페이스를 구현합니다. IDriverEntry::OnDeviceAdd 콜백 메서드에서 드라이버는 일반적으로 다음과 같습니다.
- 디바이스 콜백 개체의 instance 만들고 초기화합니다.
- IWDFDriver::CreateDevice를 호출하여 새 프레임워크 디바이스 개체를 만듭니다.
- 디바이스의 큐 및 해당 콜백 개체를 설정합니다.
- IWDFDevice::CreateDeviceInterface를 호출하여 디바이스 인터페이스 클래스의 instance 만듭니다.
UMDF 2 드라이버는 DriverEntry 및 EvtDriverDeviceAdd를 구현합니다. DriverEntry 루틴에서 UMDF 2 드라이버는 일반적으로 WDF_DRIVER_CONFIG_INIT 호출하여 드라이버의 WDF_DRIVER_CONFIG 구조를 초기화합니다. 그런 다음 이 구조를 WdfDriverCreate에 전달합니다.
EvtDriverDeviceAdd 함수에서 드라이버는 다음 중 일부를 수행할 수 있습니다.
- 디바이스 개체를 만드는 데 사용되는 정보를 제공하는 WDFDEVICE_INIT 구조를 입력합니다. WDFDEVICE_INIT 사용에 대한 자세한 내용은 프레임워크 디바이스 개체 만들기를 참조하세요.
- 디바이스 개체의 컨텍스트 영역을 설정합니다. 프레임워크 개체의 컨텍스트 공간을 할당하고 액세스하는 방법에 대한 자세한 내용은 프레임워크 개체 컨텍스트 공간을 참조하세요.
- 디바이스 개체를 만듭니다.
- 디바이스 개체 에 대한 요청 처리기를 지정합니다.
- I/O 큐를 만듭니다.
- 디바이스 인터페이스를 만듭니다.
- 디바이스 개체가 전원 정책을 소유하는 경우 디바이스 유휴 정책 및 절전 모드 해제 설정을 설정합니다.
- 하드웨어에서 인터럽트 지원을 지원하는 경우 인터럽트 개체를 만듭니다.
드라이버 설치
Visual Studio에서 새 드라이버 프로젝트를 만들면 새 프로젝트에 .inx 파일이 포함됩니다. 드라이버를 빌드할 때 Visual Studio는 .inx 파일을 드라이버 패키지의 일부로 사용할 수 있는 INF 파일로 컴파일합니다.
UMDF 1 드라이버에 대한 INF 파일에는 드라이버 클래스 ID가 포함되어야 하지만 UMDF 2 드라이버의 INF 파일에는 DriverCLSID가 필요하지 않습니다.
또한 UMDF 1 드라이버는 INF 파일에서 공동 설치 관리자를 참조해야 하지만 UMDF 2 INF 파일에는 constaller 참조가 필요하지 않습니다. 코인스탈러 참조는 UMDF 2 드라이버에 대한 INF 파일에 표시할 수 있지만 필수는 아닙니다.
디바이스 컨텍스트 저장
UMDF 1에서 드라이버는 일반적으로 디바이스 콜백 개체 클래스의 프라이빗 멤버를 지정하는 등 드라이버에서 만든 콜백 개체에 디바이스 컨텍스트를 저장합니다. 또는 UMDF 1 드라이버는 IWDFObject::AssignContext 메서드를 호출하여 프레임워크 개체에 컨텍스트를 등록할 수 있습니다.
UMDF 2에서 프레임워크는 드라이버가 개체 만들기 메서드를 호출할 때 제공하는 선택적 WDF_OBJECT_ATTRIBUTES 구조에 따라 컨텍스트 공간을 할당합니다. 개체의 create 메서드를 호출한 후 드라이버는 WdfObjectAllocateContext 를 한 번 이상 호출하여 특정 개체에 추가 컨텍스트 공간을 할당할 수 있습니다. UMDF 2 드라이버가 컨텍스트 구조 및 접근자 메서드를 정의하는 데 사용해야 하는 단계는 프레임워크 개체 컨텍스트 공간을 참조하세요.
드라이버 디버깅
UMDF 2 드라이버를 디버그하려면 Wudfext.dll 대신 Wdfkd.dll 확장을 사용합니다. Wudfext.dll 확장에 대한 자세한 내용은 Wdfkd.dll디버거 확장 요약을 참조하세요.
UMDF 2에서는 KMDF 및 UMDF 2 드라이버에서 Inflight Trace Recorder 사용에 설명된 대로 IFR(Inflight Trace Recorder)을 통해 추가 드라이버 디버깅 정보를 가져올 수도 있습니다. 또한 프레임워크의 자체 IFR( In-flight Recorder )을 사용할 수 있습니다. 프레임워크의 이벤트 로거 사용을 참조하세요.