title | description | keywords | topic_type | ms.topic | api_type | ms.date | |||||
---|---|---|---|---|---|---|---|---|---|---|---|
DriverEntry for WDF Drivers Routine |
DriverEntry is the first driver-supplied routine that is called after a driver is loaded. It is responsible for initializing the driver. |
|
|
reference |
|
10/17/2018 |
[Applies to KMDF and UMDF]
DriverEntry is the first driver-supplied routine that is called after a driver is loaded. It is responsible for initializing the driver.
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
DriverObject [in]
A pointer to a DRIVER_OBJECT structure that represents the driver's WDM driver object.
RegistryPath [in]
A pointer to a UNICODE_STRING structure that specifies the path to the driver's Parameters key in the registry.
If the routine succeeds, it must return STATUS_SUCCESS. Otherwise, it must return one of the error status values that are defined in ntstatus.h.
Like all WDM drivers, framework-based drivers must have a DriverEntry routine, which is called after the driver is loaded. A framework-based driver's DriverEntry routine must:
-
Activate WPP software tracing.
DriverEntry should include a WPP_INIT_TRACING macro to activate software tracing.
-
Call WdfDriverCreate.
The call to WdfDriverCreate enables the driver to use Windows Driver Framework interfaces. (The driver cannot call other framework routines before calling WdfDriverCreate.)
-
Allocate any non-device-specific system resources and global variables that it might need.
Typically, drivers associate system resources with individual devices. Therefore, framework-based drivers allocate most resources in an EvtDriverDeviceAdd callback, which is called when individual devices are detected.
Because multiple instances of a UMDF driver might be hosted by separate instances of Wudfhost, a global variable might not be available across all instances of a UMDF driver.
-
Obtain driver-specific parameters from the registry.
Some drivers obtain parameters from the registry. These drivers can call WdfDriverOpenParametersRegistryKey to open the registry key that contains these parameters.
-
Provide a DriverEntry return value.
Note A UMDF driver runs in a user-mode host process, while a KMDF driver runs in kernel mode in a system process. The framework might load multiple instances of a UMDF driver into separate instances of the host process. As a result:
- The framework might call a UMDF driver’s DriverEntry routine multiple times if it loads instances of the driver in different host processes. In contrast, the framework calls a KMDF driver's DriverEntry routine only once.
- If a UMDF driver creates a global variable in its DriverEntry routine, the variable might may not be available to all instances of the driver. However, a global variable that a KMDF driver creates in its DriverEntry routine is available to all instances of the driver.
For more information about when a framework-based driver's DriverEntry routine is called, see Building and Loading a WDF Driver.
The DriverEntry routine is not declared in WDK headers. Static Driver Verifier (SDV) and other verification tools may require a declaration such as the following:
DRIVER_INITIALIZE MyDriverEntry;
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
// Function body
}
The following code example shows the Serial (KMDF) sample driver's DriverEntry routine.
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;
}