KeSetKernelStackSwapEnable 函数 (ntifs.h)
KeSetKernelStackSwapEnable 例程启用和禁用将调用方堆栈交换到磁盘。
语法
BOOLEAN KeSetKernelStackSwapEnable(
[in] BOOLEAN Enable
);
参数
[in] Enable
指定是否启用属于调用线程的堆栈的交换。 如果 TRUE,则启用交换,并且堆栈的内容可以分页和内存不足。 如果 FALSE,则禁用交换,并且堆栈是内存驻留的。
返回值
KeSetKernelStackSwapEnable 返回一个 BOOLEAN 值,该值指示在启动调用时是否启用了堆栈交换。 如果以前启用堆栈交换,则此值 TRUE;如果禁用堆栈交换,则为 FALSE FALSE。
言论
内核模式驱动程序可以调用此例程来控制其堆栈是可分页还是锁定在内存中。
仅当线程处于来自用户模式应用程序的请求导致的等待状态时,才会发生堆栈交换。 无论是否启用堆栈交换,都永远不会发生由内核模式组件启动的等待状态。
通常不需要禁用堆栈交换。 仅在极少数情况下执行此作。 有关讨论禁用堆栈交换的替代方法的示例,请参阅下面的“示例”部分。
在对内核模式等待例程(如 KeWaitForSingleObject)的调用中,调用方指定 WaitMode 参数,以指示调用方是在内核模式还是用户模式下等待。 如果 WaitMode = UserMode,并且等待持续时间足够长,则内存管理器可能会分页出属于等待线程的堆栈部分。 但是,如果堆栈包含必须在等待期间保持内存驻留的数据项,则线程可以通过调用 KeSetKernelStackSwapEnable 并指定 Enable = FALSE来阻止堆栈分页。
当禁用堆栈交换或系统 bug 检查时,线程不得退出(终止)。
例
在以下代码示例中,驱动程序线程在其堆栈上分配事件,并调用 KeSetKernelStackSwap,以暂时锁定内存中的堆栈,直到发出事件信号。 驱动程序调用 KeWaitForSingleObject,WaitReasonUserRequest 来指示其线程处于用户模式应用程序请求导致的等待状态,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) |
库 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <= APC_LEVEL |