Windows XP 远程桌面上的 ClearType






4.93/5 (21投票s)
一个内核补丁,可在 Windows XP SP2 的 RDP 上启用 ClearType。
引言
我最喜欢的一些东西是
- Windows XP 中的 ClearType 字体平滑
- 使用远程桌面在家工作
- 不运行 Vista
不幸的是,当使用远程桌面协议 (RDP) 连接到您的 Windows XP 计算机时,ClearType 的字体平滑将被禁用。我猜在 XP 发布于 2001 年时,微软就决定 RDP 上的 ClearType 会慢得令人无法忍受。
然而,在 2007 年,多兆比特宽带已经非常普遍,而禁用 ClearType 的决定似乎有些过时(微软自己似乎也意识到了这一点……Windows Vista 支持 RDP 上的 ClearType)。
因此,在掌握了 WinDBG 和我关于修改内核中几个关键字节就能解决这个问题的假设后,我开始着手在 Windows XP 的 RDP 上启用 ClearType。
一些背景信息
我希望我能详细描述我用来查找执行 RDP 检查的代码路径的确切方法,但那真的只是大量的试错。另外,我写这段代码已经一年多了,这意味着我甚至都不记得所有细节了。那些徒劳地在反汇编的内核代码中摸索的日子,似乎很快就被遗忘了。
所以,尽管它实际上没有多少教学价值,但我还是想把这个实用程序放出来。它让长时间的远程桌面工作在我的眼睛上感觉更轻松,我知道我分享过的其他 ClearType 爱好者也同样庆幸他们终于有了一个解决方案。
概述
该程序分为两部分
- 一个内核驱动程序,它修改 win32k.sys 中的几个字节
- 一个用户模式应用程序,它加载驱动程序并指示它进行修改
内核部分很简单。基本上,在 win32k.sys 中,有一个代码路径如下(由 WinDBG 的反汇编器提供)
bf811387 66393550399abf cmp word ptr [win32k!gProtocolType (bf9a3950)],si
bf81138e 0f85c2feffff jne win32k!LFONTOBJ::ppfeMapFont+0x77 (bf811256)
我在调试中发现,`gProtocolType` 变量在控制台会话和通过远程桌面访问计算机时是不同的。在控制台会话中,`jne` 分支**不**会被执行;而在 RDP 上会被执行。
最简单的改变(也是产生预期结果的改变)是跳过那个 `jne` 指令。将其替换为 `nop`(无操作)意味着分支将不会被遵循——非 RDP 代码路径将始终被采用。
该程序的内核部分(RdpClearType.sys)就是执行这个 `nop` 修改。
但是,有一个注意事项:似乎每个登录会话都有自己的 win32k.sys 副本映射到其地址空间(在一个称为“会话空间”的区域)。当我安装驱动程序并将其设置为启动时启动,或手动通过服务控制管理器 (SCM) 启动它时,它没有起作用。我猜测,在这两种情况下,因为驱动程序是由 SCM 加载的(SCM 没有在我的登录会话中运行),所以效果从我的会话中是看不见的。
我的解决方案是创建一个用户模式加载器应用程序,将过程分解为两个步骤
- 通过标准的 SCM 接口(`CreateService` 和 `StartService`)加载并启动驱动程序。我的驱动程序的 `DriverEntry` 代码将在 SCM 的一个线程上执行,并在其登录会话中运行。这就是为什么我的 `DriverEntry` 函数不执行实际修改的原因……它只是创建一个对用户模式可见的“设备”,名为 `\DosDevices\RdpClearType`。
- 驱动程序加载并启动后,用户模式代码打开 `\DosDevices\RdpClearType` 设备并调用 `DeviceIoControl`。在处理此调用时,驱动程序的代码将在**我的**登录会话中**我的**线程上执行。在这里进行的修改会影响我在会话空间中的 win32k.sys。
- 最后,调用 Windows API 函数 `ValidateRect` 会导致整个屏幕刷新。所有字体现在都使用 ClearType 渲染。
为了简单起见,我将 RdpClearType.sys 驱动程序嵌入到 RdpClearType.exe 作为资源。当你运行 RdpClearType.exe 时,SYS 文件会被提取到你的 temp 目录并从中加载。
用法
再简单不过了……只需在你连接**到**的机器上运行 RdpClearType.exe。你甚至可以在远程桌面连接时安全地运行它(这很有趣,因为你可以亲眼看到转换的发生!)。
修改和驱动程序都不会在重启后保留。每次重启后都需要运行 RdpClearType.exe。
兼容性
我已在 Windows XP Professional SP2 上使用此功能一年左右。我相信某个 Service Pack 会使我硬编码的地址失效,而且我没有进行任何内存扫描或符号查找来定位。只有一个简单的检查,以确保现有字节与我期望的一致。
如果 Service Pack 或更新破坏了它,我会尽力及时更新代码。当然,如果你有 Windows Driver Development Kit (DDK)、Visual Studio、WinDBG 和大量的耐心,你可以自己找到新的地址并重新编译程序。(好玩!)
历史
- 2007-10-13:首次发布
- 2007-10-22:添加了另一个可能的修改地址。修改现在将与 win32k.sys 版本 5.1.2600.3099 和 5.1.2600.2770 一起工作。非常感谢 Rob deMontarnal 在调试初始发布时的兼容性问题上提供的帮助!
- 2007-11-06:为 win32k.sys 版本 5.1.2600.3180 和 5.1.2600.3115 添加了修改地址
- 2007-11-09:为 win32k.sys 版本 5.1.2600.2180 添加了修改地址