为什么Windows在内核中处理滚动条?

Fil*_*und 9 windows operating-system kernel scrollbar windows-kernel

"所有"Windows版本的新1位漏洞使用处理滚动条的内核代码中的错误.这让我思考.为什么Windows在内核中处理滚动条而不是用户模式?历史原因?有没有其他操作系统这样做?

And*_*ers 8

TL; DR:微软牺牲了性能安全性.


Scrollbars在Windows上有点特殊.大多数滚动条不是真正的窗口,而是在"父"窗口中实现为装饰.这引出了一个更普遍的问题; 为什么Windows在Windows上以内核模式实现?

让我们看看替代方案:

  1. 用户模式下的每个进程.
  2. 用户模式下的单个"主"进程.

替代方案1在处理您自己的窗户时具有很大的优势; 没有上下文切换/内核转换.问题当然是来自不同进程的窗口存在于同一个屏幕上,并且有人必须负责决定哪个窗口处于活动状态并在用户切换到不同窗口时协调更改.这个人必须是一个特殊的系统进程或内核,因为这些信息不能是每个进程,它必须存储在全局的某个地方.这种双重信息设计将变得复杂,因为全局窗口管理器不能信任每进程信息.我确信这个理论设计还有很多其他的缺点,但我不会在这里花更多的时间.

Windows NT 3实现了替代方案2的变体.窗口管理器在NT 4中被移入内核模式,主要是出于性能原因:

...窗口管理器(USER)和图形设备接口(GDI)已从Win32子系统移动到Windows NT Executive.Win32用户模式设备驱动程序(包括图形显示和打印机驱动程序)也已移至Executive.这些更改旨在简化图形处理,降低内存要求并提高性能.

......在同一份文件中还有更多的技术细节和理由:

首次设计Windows NT时,Win32环境子系统被设计为支持MS-DOS,POSIX和OS/2中的应用程序的环境子系统的对等体.但是,应用程序和其他子系统需要在Win32子系统中使用图形,窗口和消息传递功能.为避免重复这些功能,Win32子系统用作所有子系统的图形功能的服务器.

这种设计适用于Windows NT 3.5和3.51,但它低估了图形调用的数量和频率.在单独的进程中具有诸如消息传递和窗口控制之类的基本功能,从客户端/服务器消息传递,数据收集和管理多个线程产生了大量的内存开销.它还需要多个上下文切换,这会消耗CPU周期和内存.每秒图形支持调用量会降低系统性能.很明显,在Windows NT 4.0中重新设计这个方面可以回收这些浪费的系统资源并提高性能.

其他子系统现在并不相关,但性能问题仍然存在.

如果我们看一下像IsWindowVisible这样的简单函数,那么当窗口管理器处于内核模式时,就没有很多开销:该函数将在用户模式下执行几条指令,然后将CPU切换到第0循环,整个操作(验证传入的窗口句柄,如果有效,则检索可见属性)在内核模式下执行.然后它切换回用户模式,这就是它.

如果窗口管理器位于另一个进程中,那么你将至少加倍内核转换量,并且必须以某种方式将函数输入和输出传递给窗口管理器进程,并且必须以某种方式导致窗口管理器进程在您等待时执行为了结果.NT 3通过使用共享内存,LPC和称为成对线程的模糊功能的组合来实现这一点.