Процедура DriverEntry для драйверов WDF
[Применимо к KMDF и UMDF]
DriverEntry — это первая подпрограмма, предоставляемая драйвером, которая вызывается после загрузки драйвера. Он отвечает за инициализацию драйвера.
Синтаксис
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
);
Параметры
DriverObject [in]
Указатель на структуру DRIVER_OBJECT , представляющую объект драйвера WDM драйвера.
RegistryPath [in]
Указатель на структуру UNICODE_STRING , указывающую путь к разделу параметров драйвера в реестре.
Возвращаемое значение
Если подпрограмма завершается успешно, она должна вернуть STATUS_SUCCESS. В противном случае он должен вернуть одно из значений состояния ошибки, определенных в ntstatus.h.
Комментарии
Как и все драйверы WDM, драйверы на основе платформы должны иметь подпрограмму DriverEntry , которая вызывается после загрузки драйвера. Подпрограмма DriverEntry драйвера на основе платформы должна:
Активация трассировки программного обеспечения WPP.
DriverEntry должен включать макрос WPP_INIT_TRACING для активации трассировки программного обеспечения.
Вызовите WdfDriverCreate.
Вызов WdfDriverCreate позволяет драйверу использовать интерфейсы Windows Driver Framework. (Драйвер не может вызывать другие подпрограммы платформы перед вызовом WdfDriverCreate.)
Выделите все системные ресурсы, не относящиеся к устройствам, и глобальные переменные, которые могут потребоваться.
Как правило, драйверы связывают системные ресурсы с отдельными устройствами. Поэтому драйверы на основе платформы выделяют большую часть ресурсов в обратном вызове EvtDriverDeviceAdd , который вызывается при обнаружении отдельных устройств.
Так как несколько экземпляров драйвера UMDF могут размещаться в отдельных экземплярах Wudfhost, глобальная переменная может быть доступна не во всех экземплярах драйвера UMDF.
Получение параметров драйвера из реестра.
Некоторые драйверы получают параметры из реестра. Эти драйверы могут вызывать WdfDriverOpenParametersRegistryKey , чтобы открыть раздел реестра, содержащий эти параметры.
Укажите возвращаемое значение DriverEntry.
Примечание Драйвер UMDF выполняется в хост-процессе в пользовательском режиме, а драйвер KMDF — в режиме ядра в системном процессе. Платформа может загружать несколько экземпляров драйвера UMDF в отдельные экземпляры хост-процесса. В результате имеем следующее:
- Платформа может несколько раз вызывать подпрограмму DriverEntry драйвера UMDF, если она загружает экземпляры драйвера в разных хост-процессах. В отличие от этого, платформа вызывает подпрограмму DriverEntry драйвера KMDF только один раз.
- Если драйвер UMDF создает глобальную переменную в своей подпрограмме DriverEntry, эта переменная может быть недоступна для всех экземпляров драйвера. Однако глобальная переменная, которую драйвер KMDF создает в своей подпрограмме DriverEntry, доступна для всех экземпляров драйвера.
Дополнительные сведения о том, когда вызывается подпрограмма DriverEntry драйвера на основе платформы, см. в разделе Создание и загрузка драйвера WDF.
Подпрограмма DriverEntry не объявлена в заголовках WDK. Для статического средства проверки драйверов (SDV) и других средств проверки может потребоваться объявление, например следующее:
DRIVER_INITIALIZE MyDriverEntry;
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
// Function body
}
Примеры
В следующем примере кода показана подпрограмма DriverEntry для примера драйвера serial (KMDF).
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;
}