前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >最新版chromium 76如何支持xp

最新版chromium 76如何支持xp

作者头像
龙泉寺扫地僧
发布2019-07-11 10:43:14
1.7K0
发布2019-07-11 10:43:14
举报
文章被收录于专栏:盟主来了盟主来了

我知道,当我写下这个标题的时候,肯定一大波人会过来嘲讽:都什么年代了,还XP?

道理我都懂,但据我咨询了腾讯同事一些内部数据,XP在中国依然百之十几个点的占有率。里面最多的就是政企单位。这些电脑配置不好,比较古老了,而且关键是很多配套的软件只有xp版本。让他们升级系统?想法很好,但谁出钱找那些配套工具的厂商呢,更何况很多年久失修的软件的厂商可能早就倒闭不见了,人都找不到。

哈哈,其实我说了这么大堆,只是个借口。真实原因是有不少公司愿意出钱购买chrome支持xp的技术解决方案。我这才有动力研究了一番。

进入正题。要支持xp,要解决几个点:

补上或改掉xp下没有的系统api。 修改部分api调用参数。否则xp下可能出错。 修改部分流程,解决一些例如字体显示问题、声音播放不了等问题。 修改一些编译参数,主要是为了解决TLS问题 整个做下来,如果对chromium非常熟悉,大概1个半月可以搞定。技术难度不算很大,最麻烦的是有很多小坑要去调试找原因,这是最蛋疼的。

先看第一点,这个比较好办。把编译好的文件拿xp下看下就知道缺了哪些api。

目前有三类:

1,读写锁,条件变量相关。

这个是chromium里面用的最多的xp下没有的api。我的解决方案是自己撸了一套山寨版的api,接口和原型完全和windows原版一样。例如AcquireSRWLockExclusive、AcquireSRWLockShared这些。参考了部分ReactOS的代码(但要吐槽一下,那个代码是有bug的。我跑起来后各种断言错误)。过程比较麻烦的一点是一定要多测试,因为涉及到多线程的东西很容易藏隐藏的bug。

另外就是要夸一下windows的新api设计,读写锁和条件变量都是共用了一套机制,调用了内核的NtkeyWaitxxx系列api。而且数据结构设计成只有一个指针大小的变量,利用位运算,小心翼翼的榨干每个位的价值,而且不用event和其他锁就搞定了,十分简洁高效。这点我看其他人实现都是要用event什么的模仿,显得比较笨重了。

2,d2d、d3d系列。

这部分我直接砍掉了。不影响。因为d2d可以用GDI,D3D可以走angle或者swiftshader。这里夸一下谷歌,居然把swiftshader收购了。swiftshader是一个很古老的软件渲染器,以前是给windows或者机顶盒系统做软渲染的。谷歌果然财大气粗,为了能实现全平台全硬件利用起3D加速,真是无所不用其极。给我的感觉就是为了造一部汽车,就先买了一座铁矿。话说回来,chromium的渲染走的是opengl,但这个在windows下驱动支持的各种问题,所以谷歌会用angle把opengl转发给D3D。如果D3D启动有问题(这个很常见,很多垃圾显卡对硬件加速支持的各种bug,为此谷歌做了个显卡黑名单在chromium里,碰到了关闭硬件渲染),就走纯软件渲染,也就是swiftshader。swiftshader和angle编译出来都是libGLESv2.dll接口都一样。哪个可用就用哪个,非常爽。

3,其他杂项类api。

这个很多,有GetIfTable2,有InitPropVariantFromCLSID、RaiseFailFastException、GetUserDefaultLocaleName、SHGetPropertyStoreForWindow等等。这些其实比较好办,就是找到以前版本chromium是用哪个老api,然后替换回去就行。这类api太多了,就不在赘述。

把api全部替换完,只是万里长征第一步。下一步就是修复各种流程上的bug。

下面挑几个点讲下。

首先是字体渲染。操蛋的谷歌把老GDI渲染全部干掉,走DWrite渲染。更操蛋的是干掉就算了,还把代码都删了。其实完全可以判断下版本走哪个分支的。因为据我所知,dw在某些win7可能都还有点小bug。但谷歌是完全不管了。估计认为这些老系统没必要支持吧。所以针对这个问题,需要找到当年的patch,再把gdi渲染补充回来。

然后是声音播放不了。这个也是干掉了老的wavexxxx系列api导致。补充回来即可

再然后是src\build\config\win\BUILD.gn里记得加上/Zc:threadSafeInit-

原因是xp的动态tls实现的不完善。需要全部关闭掉vs的动态tls机制。但这会带来一个问题,就是有些地方可能有多线程竞争问题。这就需要一个个的修改。地方比较多,就不说了。

还有个点,就是如果要支持xp sp2,还会碰到个大麻烦,就是vs的xp工具集,编译出来的runtime,是要依赖某个xp sp2没有的api。这个我头痛了几天。最后想到个很简单的办法,就是所有dll都编译成md模式,然后把concrt14.dll做一个IAT HOOK,重定向kernel32.dll到我写的一个转发dll里。里面再实现那个api即可。要支持sp1也可以用这种方式。但sp1实在太少人用了,我估计全国可能都没有一千人,就不折腾sp1了。

此外,还有个大麻烦是沙箱。其实如果你对安全性要求不高,完全可以关闭沙箱。但我比较追求完美(其实是任务要求,蛤蛤),最后还是把沙箱跑起来了。沙箱里面很多地方是根据系统来做hook。有些hook在xp下要去掉。

最后,还有些小问题要修复,例如net\cert\http://cert_verify_proc_win.cc里要去掉ssl error的检查,防止加载不了https网站、http://file_enumerator_win.cc要修改下调用参数等等。这些大家调试一遍就知道了,比较简单。

整个过程基本就是这样,当然还有非常非常多的细节需要拿代码来讲,这里就懒得展开了。如果大家有兴趣也可以私信我交流。

总之,这种事情是个苦力活(尤其是编译和调试chromium,那叫一个慢啊,最后我实在受不了,直接花了几千块加内存加SSD)。不过看在金钱的份上,我忍了……zhic 

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档