Функция IoRegisterPlugPlayNotification (wdm.h)
Подпрограмма IoRegisterPlugPlayNotification регистрирует подпрограмму обратного вызова уведомления Plug and Play (PnP), которая вызывается при возникновении события PnP указанной категории.
Синтаксис
NTSTATUS IoRegisterPlugPlayNotification(
[in] IO_NOTIFICATION_EVENT_CATEGORY EventCategory,
[in] ULONG EventCategoryFlags,
[in, optional] PVOID EventCategoryData,
[in] PDRIVER_OBJECT DriverObject,
[in] PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine,
[in, optional] __drv_aliasesMem PVOID Context,
[out] PVOID *NotificationEntry
);
Параметры
[in] EventCategory
Задает значение перечисления из IO_NOTIFICATION_EVENT_CATEGORY , указывающее категорию события PnP, для которого регистрируется процедура обратного вызова.
[in] EventCategoryFlags
Пометки битов, которые изменяют операцию регистрации. Возможные значения:
PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
Допустимо только с EventCategoryEventCategoryDeviceInterfaceChange. Если этот параметр задан, диспетчер PnP вызывает подпрограмму обратного вызова драйвера для каждого зарегистрированного и активного экземпляра интерфейса устройства и регистрирует подпрограмму обратного вызова для будущих поступлений или удалений экземпляров интерфейса устройства.
[in, optional] EventCategoryData
Указатель на дополнительные сведения о событиях, для которых регистрируется CallbackRoutine . Сведения зависят от разных значений EventCategory :
Если eventCategory имеет значение EventCategoryDeviceInterfaceChange, EventCategoryData должен указывать на GUID, указывающий класс интерфейса устройства. CallbackRoutine будет вызываться при включении или удалении интерфейса этого класса.
Если eventCategory имеет значение EventCategoryHardwareProfileChange, EventCategoryData должно иметь значение NULL.
Если EventCategory имеет значение EventCategoryTargetDeviceChange, EventCategoryData должен указывать на объект файла, для которого запрашивается уведомление PnP.
[in] DriverObject
Указатель на объект драйвера вызывающего объекта.
Чтобы гарантировать, что драйвер остается загруженным, пока он зарегистрирован для уведомления PnP, этот вызов увеличивает количество ссылок в DriverObject. Диспетчер PnP уменьшает количество ссылок при удалении этой регистрации.
Для EventCategoryTargetDeviceChangeDriverObject не должен быть объектом драйвера целевого устройства; вместо этого он должен быть объектом драйвера, реализующего CallbackRoutine.
[in] CallbackRoutine
Указатель на подпрограмму обратного вызова уведомления PnP, вызываемую при возникновении указанного события PnP.
Прототип функции для этой подпрограммы обратного вызова определяется следующим образом:
typedef NTSTATUS
DRIVER_NOTIFICATION_CALLBACK_ROUTINE(
_In_ PVOID NotificationStructure,
_Inout_opt_ PVOID Context
);
NotificationStructure подпрограммы обратного вызова зависит от значения EventCategory, как показано в следующей таблице.
Категория событий | Структура уведомления |
---|---|
EventCategoryDeviceInterfaceChange | DEVICE_INTERFACE_CHANGE_NOTIFICATION |
EventCategoryHardwareProfileChange | HWPROFILE_CHANGE_NOTIFICATION |
EventCategoryTargetDeviceChange | TARGET_DEVICE_REMOVAL_NOTIFICATION Дополнительные сведения см. в статье Использование уведомлений PnP и TARGET_DEVICE_CUSTOM_NOTIFICATION. |
Параметр Context подпрограммы обратного вызова содержит данные контекста, предоставленные драйвером во время регистрации.
Сведения о включении объявления функции для подпрограммы обратного вызова, которая соответствует требованиям статического средства проверки драйверов (SDV), см. в разделе Примеры.
Диспетчер PnP вызывает процедуры обратного вызова драйвера в IRQL = PASSIVE_LEVEL.
[in, optional] Context
Указатель на буфер, выделенный вызывающим объектом, содержащий контекст, который диспетчер PnP передает подпрограмме обратного вызова.
[out] NotificationEntry
Указатель на непрозрачное значение, возвращаемое этим вызовом, идентифицирующее регистрацию. Передайте это значение в подпрограмму IoUnregisterPlugPlayNotificationEx , чтобы удалить регистрацию.
Возвращаемое значение
IoRegisterPlugPlayNotification возвращает STATUS_SUCCESS или соответствующее состояние ошибки.
Комментарии
Драйвер регистрируется для категории событий. Каждая категория включает один или несколько типов событий PnP.
Драйвер может регистрировать различные процедуры обратного вызова для разных категорий событий или зарегистрировать одну подпрограмму обратного вызова. Одна подпрограмма обратного вызова может привести NotificationStructure к PLUGPLAY_NOTIFICATION_HEADER и использовать поле Event для определения точного типа структуры уведомлений.
Если вызывающий объект указывает PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, операционная система может дважды вызвать подпрограмму обратного вызова уведомления PnP для одного события EventCategoryDeviceInterfaceChange для существующего интерфейса. Вы можете спокойно игнорировать второй вызов обратного вызова. Операционная система не будет вызывать обратный вызов более двух раз для одного события.
Процедуры обратного вызова уведомлений PnP должны как можно быстрее выполнять свои задачи и возвращать управление диспетчеру PnP, чтобы предотвратить задержки при уведомлении других драйверов и приложений, зарегистрированных для события.
Диспетчер PnP не извлекает ссылку на объект файла, когда драйвер регистрируется для уведомления о событии EventCategoryTargetDeviceChange . Если подпрограмме обратного вызова уведомления PnP драйвера требуется доступ к объекту файла, драйвер должен извлечь дополнительную ссылку на объект файла перед вызовом IoRegisterPlugPlayNotification.
Как правило, драйверы Kernel-Mode Driver Framework (KMDF) должны вызывать IoRegisterPlugPlayNotification из функции обратного вызова EvtDeviceSelfManagedIoInit и вызывать IoUnregisterPlugPlayNotification из функции обратного вызова EvtDeviceSelfManagedIoCleanup . Эти драйверы не должны вызывать IoRegisterPlugPlayNotification из функции обратного вызова EvtDriverDeviceAdd ; В противном случае подпрограмма обратного вызова уведомления PnP может быть вызвана перед запуском стека драйверов с помощью PnP. В этом случае драйвер не будет подготовлен к обработке уведомления.
Дополнительные сведения см. в разделе Использование уведомления PnP.
Примеры
Чтобы определить подпрограмму обратного вызова уведомления PnP, необходимо сначала предоставить объявление функции, определяющее тип определяемой процедуры обратного вызова. Windows предоставляет набор типов функций обратного вызова для драйверов. Объявление функции с помощью типов функций обратного вызова помогает анализу кода для драйверов, средству проверки статических драйверов (SDV) и другим средствам проверки находить ошибки, и это требование для написания драйверов для операционной системы Windows.
Например, чтобы определить подпрограмму обратного вызова уведомления PnP с именем MyCallbackRoutine
, используйте тип DRIVER_NOTIFICATION_CALLBACK_ROUTINE, как показано в следующем примере кода:
DRIVER_NOTIFICATION_CALLBACK_ROUTINE MyCallbackRoutine;
Затем реализуйте процедуру обратного вызова следующим образом:
_Use_decl_annotations_
NTSTATUS
MyCallbackRoutine(
PVOID NotificationStructure,
PVOID Context
)
{
// Function body
}
Тип функции DRIVER_NOTIFICATION_CALLBACK_ROUTINE определен в файле заголовка Wdm.h. Чтобы более точно определить ошибки при запуске средств анализа кода, обязательно добавьте заметку Use_decl_annotations в определение функции. Заметка Use_decl_annotations гарантирует использование заметок, которые применяются к типу функции DRIVER_NOTIFICATION_CALLBACK_ROUTINE в файле заголовка. Дополнительные сведения о требованиях к объявлениям функций см. в разделе Объявление функций с помощью типов ролей функций для драйверов WDM. Дополнительные сведения о _Use_decl_annotations_
см. в статье Поведение функции с заметками.
Требования
Требование | Значение |
---|---|
Целевая платформа | Универсальное |
Верхняя часть | wdm.h (включая Wdm.h, Ntddk.h, Ntifs.h) |
Библиотека | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL |
Правила соответствия DDI | HwStorPortProhibitedDIs(storport), MarkPower(wdm), MarkPowerDown(wdm), MarkQueryRelations(wdm), MarkStartDevice(wdm), PowerIrpDDis(wdm) |
См. также раздел
DEVICE_INTERFACE_CHANGE_NOTIFICATION
IoUnregisterPlugPlayNotification
IoUnregisterPlugPlayNotificationEx