KeRegisterProcessorChangeCallback 函数 (wdm.h)
KeRegisterProcessorChangeCallback 例程向操作系统注册回调函数,以便操作系统在向硬件分区添加新处理器时通知驱动程序。
语法
PVOID KeRegisterProcessorChangeCallback(
[in] PPROCESSOR_CALLBACK_FUNCTION CallbackFunction,
[in, optional] PVOID CallbackContext,
[in] ULONG Flags
);
参数
[in] CallbackFunction
指向驱动程序提供的处理器更改回调函数的指针,每当将新处理器添加到硬件分区时,操作系统就会调用该函数。 处理器更改回调函数定义如下:
VOID
ProcessorCallback(
__in PVOID CallbackContext,
__in PKE_PROCESSOR_CHANGE_NOTIFY_CONTEXT ChangeContext,
__inout PNTSTATUS OperationStatus
);
CallbackContext
回调函数注册到操作系统时, CallbackContext 参数中提供给 KeRegisterProcessorChangeCallback 例程的上下文。
ChangeContext
指向描述处理器更改通知事件的 KE_PROCESSOR_CHANGE_NOTIFY_CONTEXT 结构的指针。
OperationStatus
指向包含 NTSTATUS 代码的变量的指针。 设备驱动程序不得更改此变量的值,除非当 ChangeContext 参数指向的 KE_PROCESSOR_CHANGE_NOTIFY_CONTEXT 结构的 State 成员包含 KeProcessorAddStartNotify 时在回调函数处理期间发生错误。
处理器更改回调函数在 IRQL = PASSIVE_LEVEL 中调用。
[in, optional] CallbackContext
传递给回调函数的驱动程序提供的上下文。 此参数可以为 NULL。
[in] Flags
可选标志,用于修改 KeRegisterProcessorChangeCallback 例程的行为。 下面是一个可能的标志:
KE_PROCESSOR_CHANGE_ADD_EXISTING
如果设置了此标志,则除了在将新处理器添加到硬件分区时调用外,还会立即为硬件分区中当前存在的每个活动处理器调用已注册的回调函数。 如果未设置此标志,则仅在向系统添加新处理器时调用已注册的回调函数。
返回值
如果回调函数已成功注册到操作系统,KeRegisterProcessorChangeCallback 将返回非 NULL 回调注册句柄。 否则, KeRegisterProcessorChangeCallback 返回 NULL。 有关此句柄的详细信息,请参阅以下“备注”部分。
注解
设备驱动程序调用 KeRegisterProcessorChangeCallback 例程来注册一个回调函数,每当将新处理器添加到硬件分区时,操作系统将调用该回调函数。 当用户将新处理器热插入分区时,操作系统会调用已注册的回调函数,以重新平衡分区中处理器之间分配的系统资源。
每当将新处理器添加到硬件分区时,注册的回调函数将调用两次。 首次调用回调函数时,由 ChangeContext 参数指向的 KE_PROCESSOR_CHANGE_NOTIFY_CONTEXT 结构的 State 成员包含 KeProcessorAddStartNotify。 在此回调期间,设备驱动程序应分配每个处理器的任何资源,并执行任何其他任务,为新处理器在硬件分区中变为活动状态做准备。 如果设备驱动程序处理此回调时发生错误,如果操作系统继续将新处理器添加到硬件分区,则回调函数会将 OperationStatus 参数指向的变量设置为描述错误条件的 NTSTATUS 代码。 例如,如果设备驱动程序在新处理器的每个处理器数据结构中遇到内存分配失败,则回调函数将此变量设置为STATUS_INSUFFICIENT_RESOURCES。 如果成功处理回调,则不应更改 OperationStatus 参数指向的变量的内容。
第二次调用回调函数时,ChangeContext 参数指向的 KE_PROCESSOR_CHANGE_NOTIFY_CONTEXT 结构的 State 成员包含 KeProcessorAddCompleteNotify(指示操作系统已成功将新处理器添加到硬件分区)或 KeProcessorAddFailureNotify,指示操作系统未将新处理器添加到硬件分区。 如果操作系统成功将新处理器添加到硬件分区,则在启动新处理器并可用于线程计划之前,不会第二次调用回调函数。 如果操作系统未将新处理器添加到硬件分区,则设备驱动程序应在第一次回调期间分配的第二次回调期间释放任何每个处理器的资源。
如果设备驱动程序在调用 KeRegisterProcessorChangeCallback 例程时在 Flags 参数中指定KE_PROCESSOR_CHANGE_ADD_EXISTING标志,则会立即为硬件分区中当前存在的每个活动处理器调用一次回调函数。 对于这些回调,ChangeContext 参数指向的 KE_PROCESSOR_CHANGE_NOTIFY_CONTEXT 结构的 State 成员包含 KeProcessorAddStartNotify。 正是在这些回调期间,设备驱动程序应分配任何每个处理器的资源,并执行任何其他任务,以准备使用硬件分区中的现有处理器。 如果设备驱动程序成功处理当前存在于硬件分区中的所有活动处理器的此回调,则会立即再次针对硬件分区中当前存在的每个活动处理器再次调用回调函数。 对于这些回调,ChangeContext 参数指向的 KE_PROCESSOR_CHANGE_NOTIFY_CONTEXT 结构的 State 成员包含 KeProcessorAddCompleteNotify。 KeRegisterProcessorChangeCallback 在这些回调完成后返回。
如果设备驱动程序处理硬件分区中某个现有活动处理器的第一个回调时发生错误,如果驱动程序要继续加载,则回调函数会将 OperationStatus 参数指向的变量设置为描述错误条件的 NTSTATUS 代码。 例如,如果设备驱动程序在现有活动处理器的每个处理器数据结构中遇到内存分配失败,则回调函数将此变量设置为STATUS_INSUFFICIENT_RESOURCES。 如果成功处理回调,则不应更改 OperationStatus 参数指向的变量的内容。
如果设备驱动程序指示在处理硬件分区中某个现有活动处理器的第一个回调时出错,则不会为任何其他现有活动处理器调用回调函数。 相反,对于第一次调用回调的每个活动处理器,回调函数将立即调用第二次,不包括回调指示错误的主动处理器。 对于这些回调,ChangeContext 参数指向的 KE_PROCESSOR_CHANGE_NOTIFY_CONTEXT 结构的 State 成员包含 KeProcessorAddFailureNotify。
设备驱动程序通常从其 DriverEntry 例程中调用 KeRegisterProcessorChangeCallback 例程。 如果对 KeRegisterProcessorChangeCallback 例程的调用返回 NULL,则设备驱动程序的 DriverEntry 例程应返回描述错误条件的 NTSTATUS 代码。
设备驱动程序可以使用 CallbackContext 参数中传递给 KeRegisterProcessorChangeCallback 例程的上下文作为回调函数可以存储描述错误条件的 NTSTATUS 代码的位置。 然后,可以将此 NTSTATUS 代码用作设备驱动程序的 DriverEntry 例程的返回值。
KeRegisterProcessorChangeCallback 返回的状态值仅指示回调函数的注册是成功还是失败。 它并不表示 在 KeRegisterProcessorChangeCallback 返回之前对回调函数的任何调用成功或失败。
在从操作系统卸载设备驱动程序之前,必须取消注册已注册处理器更改通知的回调函数。 若要取消注册回调函数,设备驱动程序会调用 KeDeregisterProcessorChangeCallback 例程,并将调用 KeRegisterProcessorChangeCallback 例程返回的注册句柄作为输入参数传递给此例程。
要求
要求 | 值 |
---|---|
目标平台 | 通用 |
标头 | wdm.h(包括 Wdm.h、Ntddk.h、Ntifs.h) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL |