WDF 驱动程序例程的 DriverEntry
[适用于 KMDF 和 UMDF]
DriverEntry 是在加载驱动程序后调用的第一个驱动程序提供的例程。 它负责初始化驱动程序。
语法
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
参数
DriverObject [in]
指向 DRIVER_OBJECT 结构的指针,该结构表示驱动程序的 WDM 驱动程序对象。
RegistryPath [in]
指向 UNICODE_STRING 结构的指针,该结构指定注册表中驱动程序 的 Parameters 键 的路径。
返回值
如果例程成功,则必须返回STATUS_SUCCESS。 否则,它必须返回 ntstatus.h 中定义的错误状态值之一。
注解
与所有 WDM 驱动程序一样,基于框架的驱动程序必须具有 DriverEntry 例程,该例程在加载驱动程序后调用。 基于框架的驱动程序的 DriverEntry 例程必须:
激活 WPP 软件跟踪。
DriverEntry 应包含用于激活软件跟踪 的WPP_INIT_TRACING 宏。
调用 WdfDriverCreate。
调用 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;
}