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 以暂时锁定内存中的堆栈,直到事件收到信号。 驱动程序使用 WaitReasonUserRequest 调用 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 |