WDF 드라이버 루틴용 DriverEntry
[KMDF 및 UMDF에 적용]
DriverEntry 는 드라이버가 로드된 후 호출되는 첫 번째 드라이버 제공 루틴입니다. 드라이버를 초기화해야 합니다.
구문
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
매개 변수
DriverObject [in]
드라이버의 WDM 드라이버 개체를 나타내는 DRIVER_OBJECT 구조체에 대한 포인터입니다.
RegistryPath [in]
레지스트리에서 드라이버의 Parameters 키에 대한 경로를 지정하는 UNICODE_STRING 구조체에 대한 포인터입니다.
반환 값
루틴이 성공하면 STATUS_SUCCESS 반환해야 합니다. 그렇지 않으면 ntstatus.h에 정의된 오류 상태 값 중 하나를 반환해야 합니다.
설명
모든 WDM 드라이버와 마찬가지로 프레임워크 기반 드라이버에는 드라이버가 로드된 후 호출되는 DriverEntry 루틴이 있어야 합니다. 프레임워크 기반 드라이버의 DriverEntry 루틴은 다음을 수행해야 합니다.
-
DriverEntry 에는 소프트웨어 추적을 활성화하는 WPP_INIT_TRACING 매크로가 포함되어야 합니다.
-
WdfDriverCreate를 호출하면 드라이버가 Windows 드라이버 프레임워크 인터페이스를 사용할 수 있습니다. (드라이버는 WdfDriverCreate를 호출하기 전에 다른 프레임워크 루틴을 호출할 수 없습니다.)
디바이스별이 아닌 시스템 리소스 및 필요할 수 있는 전역 변수를 할당합니다.
일반적으로 드라이버는 시스템 리소스를 개별 디바이스와 연결합니다. 따라서 프레임워크 기반 드라이버는 개별 디바이스가 검색될 때 호출되는 EvtDriverDeviceAdd 콜백에 대부분의 리소스를 할당합니다.
UMDF 드라이버의 여러 인스턴스가 Wudfhost의 별도 인스턴스에서 호스트될 수 있으므로 UMDF 드라이버의 모든 인스턴스에서 전역 변수를 사용할 수 없을 수 있습니다.
레지스트리에서 드라이버별 매개 변수를 가져옵니다.
일부 드라이버는 레지스트리에서 매개 변수를 가져옵니다. 이러한 드라이버는 WdfDriverOpenParametersRegistryKey 를 호출하여 이러한 매개 변수가 포함된 레지스트리 키를 열 수 있습니다.
DriverEntry 반환 값을 제공합니다.
참고 UMDF 드라이버는 사용자 모드 호스트 프로세스에서 실행되며 KMDF 드라이버는 시스템 프로세스에서 커널 모드로 실행됩니다. 프레임워크는 UMDF 드라이버의 여러 인스턴스를 호스트 프로세스의 별도 인스턴스로 로드할 수 있습니다. 결과는 다음과 같습니다.
- 프레임워크는 다른 호스트 프로세스에서 드라이버의 인스턴스를 로드하는 경우 UMDF 드라이버의 DriverEntry 루틴을 여러 번 호출할 수 있습니다. 반면 프레임워크는 KMDF 드라이버의 DriverEntry 루틴을 한 번만 호출합니다.
- UMDF 드라이버가 DriverEntry 루틴에서 전역 변수를 만드는 경우 드라이버의 모든 인스턴스에서 변수를 사용할 수 없을 수 있습니다. 그러나 KMDF 드라이버가 DriverEntry 루틴에서 만드는 전역 변수는 드라이버의 모든 인스턴스에서 사용할 수 있습니다.
프레임워크 기반 드라이버의 DriverEntry 루틴이 호출되는 시기에 대한 자세한 내용은 WDF 드라이버 빌드 및 로드를 참조하세요.
DriverEntry 루틴은 WDK 헤더에서 선언되지 않습니다. SDV(정적 드라이버 검증 도구) 및 기타 확인 도구에는 다음과 같은 선언이 필요할 수 있습니다.
DRIVER_INITIALIZE MyDriverEntry;
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
// Function body
}
예제
다음 코드 예제에서는 직렬(KMDF) 샘플 드라이버의 DriverEntry 루틴을 보여 줍니다.
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
WDF_DRIVER_CONFIG config;
WDFDRIVER hDriver;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes;
SERIAL_FIRMWARE_DATA driverDefaults;
//
// Initialize WPP tracing.
//
WPP_INIT_TRACING(
DriverObject,
RegistryPath
);
SerialDbgPrintEx(
TRACE_LEVEL_INFORMATION,
DBG_INIT,
"Serial Sample (WDF Version) - Built %s %s\n",
__DATE__, __TIME__
);
//
// Register a cleanup callback function (which calls WPP_CLEANUP)
// for the framework driver object. The framework will call
// the cleanup callback function when it deletes the driver object,
// before the driver is unloaded.
//
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.EvtCleanupCallback = SerialEvtDriverContextCleanup;
WDF_DRIVER_CONFIG_INIT(
&config,
SerialEvtDeviceAdd
);
status = WdfDriverCreate(
DriverObject,
RegistryPath,
&attributes,
&config,
&hDriver
);
if (!NT_SUCCESS(status)) {
SerialDbgPrintEx(
TRACE_LEVEL_ERROR,
DBG_INIT,
"WdfDriverCreate failed with status 0x%x\n",
status
);
//
// Clean up tracing here because WdfDriverCreate failed.
//
WPP_CLEANUP(DriverObject);
return status;
}
//
// Call an internal routine to obtain registry values
// to use for all the devices that the driver
// controls, including whether or not to break on entry.
//
SerialGetConfigDefaults(
&driverDefaults,
hDriver
);
//
// Break on entry if requested bt registry value.
//
if (driverDefaults.ShouldBreakOnEntry) {
DbgBreakPoint();
}
return status;
}