IoRegisterPlugPlayNotification 函数 (wdm.h)
IoRegisterPlugPlayNotification 例程注册即插即用 (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
仅对 EventCategoryDeviceInterfaceChange 的 EventCategory 有效。 如果已设置,PnP 管理器会为当前注册和处于活动状态的每个设备接口实例调用驱动程序回调例程,并为将来到达或删除设备接口实例注册回调例程。
[in, optional] EventCategoryData
一个指针,指向有关要为其注册 CallbackRoutine 的事件的进一步信息。 信息因不同的 EventCategory 值而异:
当 EventCategory 为 EventCategoryDeviceInterfaceChange 时, EventCategoryData 必须指向指定设备接口类的 GUID。 启用或删除该类的接口时,将调用 CallbackRoutine。
当 EventCategory 为 EventCategoryHardwareProfileChange 时, EventCategoryData 必须为 NULL。
当 EventCategory 为 EventCategoryTargetDeviceChange 时, EventCategoryData 必须指向请求 PnP 通知的文件对象。
[in] DriverObject
指向调用方驱动程序对象的指针。
为了确保驱动程序在注册 PnP 通知时保持加载状态,此调用会递增 DriverObject 上的引用计数。 删除此注册时,PnP 管理器会递减引用计数。
对于 EventCategoryTargetDeviceChange,DriverObject 不得是目标设备的驱动程序对象; 相反,它应该是实现 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 并使用 “事件” 字段来确定通知结构的确切类型。
如果调用方指定PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,则操作系统可能会为现有接口的单个 EventCategoryDeviceInterfaceChange 事件调用两次 PnP 通知回调例程。 可以安全地忽略对回调的第二次调用。 操作系统不会为单个事件调用回调两次以上。
PnP 通知回调例程应尽快完成任务,并将控制权返回到 PnP 管理器,以防止在通知其他已注册事件的驱动程序和应用程序时出现延迟。
当驱动程序注册 EventCategoryTargetDeviceChange 事件的通知时,PnP 管理器不会对文件对象执行引用。 如果驱动程序的 PnP 通知回调例程需要访问文件对象,则驱动程序应在调用 IoRegisterPlugPlayNotification 之前对文件对象执行额外的引用。
通常,Kernel-Mode Driver Framework (KMDF) 驱动程序应从其 EvtDeviceSelfManagedIoInit 回调函数调用 IoRegisterPlugPlayNotification,并应从其 EvtDeviceSelfManagedIoCleanup 回调函数调用 IoUnregisterPlugPlayNotification。 这些驱动程序不应从其 EvtDriverDeviceAdd 回调函数调用 IoRegisterPlugPlayNotification;否则,可能会在 PnP 启动驱动程序堆栈之前调用 PnP 通知回调例程,在这种情况下,驱动程序不会准备好处理通知。
有关详细信息,请参阅 使用 PnP 通知。
示例
若要定义 PnP 通知回调例程,必须先提供一个函数声明,用于标识要定义的回调例程的类型。 Windows 为驱动程序提供了一组回调函数类型。 使用回调函数类型声明函数可帮助 驱动程序的代码分析、 静态驱动程序验证程序 (SDV) 和其他验证工具查找错误,这是为 Windows 操作系统编写驱动程序的要求。
例如,若要定义名为 MyCallbackRoutine
的 PnP 通知回调例程,请使用 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) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL |
DDI 符合性规则 | HwStorPortProhibitedDDI (storport) 、 MarkPower (wdm) 、 MarkPowerDown (wdm) 、 MarkQueryRelations (wdm) 、 MarkStartDevice (wdm) 、 PowerIrpDDis (wdm) |
另请参阅
DEVICE_INTERFACE_CHANGE_NOTIFICATION
IoUnregisterPlugPlayNotification
IoUnregisterPlugPlayNotificationEx