Windows 커널 & 드라이버 시리즈 — 19화
WDF 프레임워크 소개 — WDM과 무엇이 다른가
2개월차에서 WDM(Windows Driver Model) 방식으로 드라이버를 배웠는데, 사실 요즘 Microsoft가 권장하는 방식은 WDF(Windows Driver Foundation)예요. WDM이 "날것 그대로의 API"라면, WDF는 그 위에 올라탄 더 안전하고 편리한 프레임워크예요. 이번 화에서 둘의 차이를 명확히 짚고 WDF로 넘어가 볼게요.
WDM의 불편함
WDM으로 드라이버를 만들면서 이런 것들이 불편하지 않으셨나요?
- IRP를 받아서 처리하다 보면 정말 많은 보일러플레이트 코드가 생겨요
- PnP(플러그앤플레이) IRP를 처리하려면 수많은 Minor Code를 일일이 다 처리해야 해요
- 전원 관리(IRP_MJ_POWER) 처리도 복잡해요
- 취소(Cancel) 처리를 제대로 구현하기가 어렵고 버그가 나기 쉬워요
- 동기화를 직접 관리해야 해요
WDF는 이런 반복적이고 오류가 나기 쉬운 부분들을 프레임워크가 대신 처리해주도록 설계됐어요.
WDF의 두 갈래 — KMDF와 UMDF
| 구분 | KMDF | UMDF |
|---|---|---|
| 실행 위치 | 커널 모드 | 유저 모드 |
| 안정성 | 버그 시 BSOD 가능 | 버그 시 해당 프로세스만 종료 |
| 성능 | 높음 | 상대적으로 낮음 (커널↔유저 전환) |
| 접근 가능한 것 | 모든 커널 리소스 | 제한된 커널 리소스 |
| 주요 용도 | 디스크, 네트워크, 필터 드라이버 | USB, HID, 프린터, 간단한 장치 |
| 추천 대상 | 고성능, 커널 접근 필요 시 | 안전성 우선, USB 장치 등 |
💡 UMDF 드라이버가 크래시해도 블루스크린이 안 나요!
UMDF 드라이버는 유저 모드 프로세스 안에서 실행되기 때문에, 버그가 생겨도 해당 드라이버 호스트 프로세스만 종료돼요. OS는 살아있고, Windows가 드라이버를 자동으로 재시작할 수도 있어요. 안전성이 최우선이라면 UMDF를 고려하세요.
WDF의 핵심 개념 — 오브젝트 모델
WDF는 WDM의 "IRP 중심" 모델과 달리, 오브젝트(WDFOBJECT) 중심 모델이에요. 모든 것이 오브젝트로 표현되고, 오브젝트 간에 부모-자식 관계가 있어요.
- WDFDRIVER — 드라이버 자체
- WDFDEVICE — 디바이스
- WDFQUEUE — IRP를 받아서 처리하는 큐
- WDFREQUEST — IRP를 래핑한 WDF 요청 객체
- WDFMEMORY — 메모리 버퍼 래퍼
- WDFSPINLOCK — 스핀락 래퍼
- WDFTIMER — 타이머
오브젝트의 부모가 삭제되면 자식도 자동으로 삭제돼요. 예를 들어 WDFDEVICE가 삭제되면 그 하위에 만들어진 WDFQUEUE, WDFTIMER 등이 자동으로 정리됩니다. 메모리 누수가 훨씬 줄어드는 이유가 여기 있어요.
WDM vs WDF — 코드 비교
WDM으로 드라이버 초기화 시 해야 했던 것들 vs WDF로 하면 얼마나 줄어드는지 보면 차이가 확 느껴져요:
| 작업 | WDM | KMDF(WDF) |
|---|---|---|
| PnP IRP 처리 | IRP_MN_* 약 20개 직접 처리 | 프레임워크가 기본 처리, 필요한 것만 콜백 등록 |
| 전원 관리 | IRP_MJ_POWER + 각 MinorCode 처리 | WdfDeviceInitSetPnpPowerEventCallbacks로 간단히 |
| IRP 큐잉/취소 | 직접 구현 (복잡하고 버그 나기 쉬움) | WDFQUEUE가 자동 처리 |
| 동기화 | SpinLock, Mutex 직접 관리 | WDF 오브젝트 락 자동 지원 |
| 메모리 정리 | DriverUnload에서 수동 정리 | 오브젝트 트리로 자동 정리 |
KMDF의 기본 구조
// KMDF 드라이버의 최소 골격 #include <wdm.h> #include <wdf.h> // 디바이스 생성 콜백 EVT_WDF_DRIVER_DEVICE_ADD MyEvtDeviceAdd; // 드라이버 진입점 (WDM의 DriverEntry와 같은 위치) NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { WDF_DRIVER_CONFIG config; WDF_DRIVER_CONFIG_INIT(&config, MyEvtDeviceAdd); return WdfDriverCreate( DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE); } // 디바이스 추가 콜백 (PnP Manager가 새 장치 발견 시 호출) NTSTATUS MyEvtDeviceAdd( _In_ WDFDRIVER Driver, _In_ PWDFDEVICE_INIT DeviceInit) { UNREFERENCED_PARAMETER(Driver); WDFDEVICE device; // WDFDEVICE 생성 NTSTATUS status = WdfDeviceCreate( &DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &device); if (!NT_SUCCESS(status)) return status; // 여기에 큐 생성, 타이머 등록 등을 추가하면 됩니다 DbgPrint("[KMDF] Device added!\n"); return STATUS_SUCCESS; }WDM의 DriverEntry와 비교해보면, DriverObject에 MajorFunction을 일일이 채우는 코드가 없어요. WDF가 내부적으로 처리해줍니다.
📌 WDF 드라이버는 Verifier에서 더 잘 잡혀요
Driver Verifier(verifier.exe)는 드라이버의 잘못된 사용을 감지하는 도구인데, WDF 드라이버는 WDF 자체가 추가적인 검증을 수행해서 문제를 더 일찍, 더 명확한 메시지로 잡아줍니다.
✅ 19화 요약
- WDF는 WDM 위에 올라탄 프레임워크로, 반복적인 보일러플레이트를 줄여줍니다.
- KMDF(커널 모드)와 UMDF(유저 모드) 두 종류가 있어요.
- WDF는 오브젝트 모델을 사용해 부모-자식 관계로 리소스를 자동 정리합니다.
- PnP, 전원 관리, IRP 큐잉/취소를 프레임워크가 기본 처리합니다.
- 진입점은 여전히 DriverEntry지만, WdfDriverCreate + EvtDeviceAdd 콜백으로 초기화합니다.
다음 화
20화 — KMDF 드라이버 개발 실습: I/O 큐와 요청 처리 완전 정복 →
#WDF #KMDF #UMDF #WdfDriverCreate #드라이버프레임워크
'Programming > 7. Device Driver' 카테고리의 다른 글
| 고급 기법 & 실무 적용 - 21화 필터 드라이버 아키텍처 (0) | 2026.06.11 |
|---|---|
| 고급 기법 & 실무 적용 - 20화 KMDF 드라이버 개발 실습 (0) | 2026.06.10 |
| 드라이버 개발 핵심 - 18화 인터럽트, ISR, DPC (0) | 2026.06.08 |
| 드라이버 개발 핵심 - 17화 MDL (0) | 2026.06.05 |
| 드라이버 개발 핵심 - 16화 커널 메모리 풀 관리 (0) | 2026.06.04 |