KeSetKernelStackSwapEnable 函数 (ntifs.h)

KeSetKernelStackSwapEnable 例程允许和禁用调用方堆栈交换到磁盘。

语法

BOOLEAN KeSetKernelStackSwapEnable(
  [in] BOOLEAN Enable
);

参数

[in] Enable

指定是否启用属于调用线程的堆栈的交换。 如果 为 TRUE,则启用交换,并且可以分页和内存外分页堆栈的内容。 如果 为 FALSE,则禁用交换,并且堆栈是内存驻留的。

返回值

KeSetKernelStackSwapEnable 返回一个 BOOLEAN 值,该值指示在启动调用时是否启用了堆栈交换。 如果以前启用堆栈交换,则此值为 TRUE ;如果禁用堆栈交换,则为 FALSE

注解

内核模式驱动程序可以调用此例程来控制其堆栈是可分页还是锁定在内存中。

仅当线程处于来自用户模式应用程序的请求导致的等待状态时,才会发生堆栈交换。 无论是否启用堆栈交换,都永远不会发生由内核模式组件启动的等待状态。

通常不需要禁用堆栈交换。 仅在极少数情况下执行此操作。 有关讨论禁用堆栈交换的替代方法的示例,请参阅以下示例部分。

在对内核模式等待例程(如 KeWaitForSingleObject)的调用中,调用方指定 WaitMode 参数以指示调用方是在内核模式还是用户模式下等待。 如果 WaitMode = UserMode,并且等待持续时间足够长,则内存管理器可能会分页出属于等待线程的堆栈部分。 但是,如果堆栈包含的数据项必须在等待期间保持内存驻留状态,则线程可以通过调用 KeSetKernelStackSwapEnable 并指定 Enable = FALSE 来阻止堆栈进行分页。

当禁用堆栈交换或系统 bug 检查时,线程不得退出 (终止) 。

示例

在以下代码示例中,驱动程序线程在其堆栈上分配事件,并调用 KeSetKernelStackSwap 来暂时锁定内存中的堆栈,直到发出事件信号。 驱动程序使用 UserRequestWaitReason 调用 KeWaitForSingleObject,以指示其线程处于用户模式应用程序请求导致的等待状态,WaitMode 设置为 KernelMode 以指示等待发生在内核模式下。 等待完成后,线程会根据需要再次调用 KeSetKernelStackSwap ,以还原线程的原始堆栈交换状态。

KEVENT event;
BOOLEAN oldSwapEnable;
NTSTATUS status;

oldSwapEnable = KeSetKernelStackSwapEnable(FALSE);

KeInitializeEvent(&event, SynchronizationEvent, FALSE);

//
// TO DO: Insert code here to pass the event to another thread
// that will set the event to the signaled state.
//
...

status = KeWaitForSingleObject(&event, UserRequest, KernelMode, FALSE, NULL);

if (oldSwapEnable)
{
    KeSetKernelStackSwapEnable(TRUE);
}

事件对象必须是内存驻留的,而它可以设置为信号状态或非对齐状态,或者在线程等待事件时。 有关详细信息,请参阅 定义和使用事件对象

通常, 不需要使用 KeSetKernelStackSwap 例程,并且可以通过仅分配堆栈上的可分页数据项来避免。 在前面的示例中,驱动程序线程必须锁定堆栈,因为事件对象是在堆栈上分配的。 更好的选择可能是从非分页池分配事件。

要求

   
最低受支持的客户端 从 Windows 2000 开始可用。
目标平台 通用
标头 ntifs.h (包括 Ntifs.h、Fltkernel.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL <= APC_LEVEL

另请参阅

KeInitializeEvent

KeWaitForSingleObject