WINE IE 与 wine_gecko 架构分析

WINE IE 与 wine_gecko 架构分析

一、整体架构

ReactOS 中的 Internet Explorer 采用 四层架构,每一层都是独立的 DLL/EXE 模块:

复制代码
iexplore.exe  (可执行入口)
     |
     v
ieframe.dll   (浏览器框架 - 窗口、菜单、导航栏、IWebBrowser2)
     |
     v
mshtml.dll    (Trident COM ↔ XPCOM 桥接层 - HTMLDocument, IHTMLDocument2)
     |
     v
wine_gecko    (Mozilla Gecko 引擎 - xul.dll + 配套 DLL)

核心设计理念 :mshtml.dll 不包含自有的 HTML/CSS 引擎实现 ,而是作为 Trident(MSHTML)COM 接口与 Mozilla Gecko(XPCOM)引擎之间的桥接层。这使得 ReactOS/Wine 无需重新实现整个浏览器引擎即可提供 HTML 渲染能力。


二、各层详解

2.1 iexplore.exe --- 可执行入口

位置base/applications/iexplore/main.c

  • 极简的包装器 EXE
  • 主要逻辑通过 IEWinMain() 委托给 ieframe.dll
  • 支持 /regserver/unregserver 命令行参数

2.2 ieframe.dll --- 浏览器框架

位置dll/win32/ieframe/

职责:完整的浏览器壳(shell),提供用户可见的 UI 元素和浏览器服务。

核心结构体
结构体 文件 职责
DocHost ieframe.h:119 文档宿主机,管理 WebBrowser 控件、URL、状态、travel log
ShellBrowser ieframe.h:84 IShellBrowser/IBrowserService 实现,与 shell 集成
WebBrowser ieframe.h:178 IWebBrowser2 COM 接口实现,供外部调用
TravelLog shellbrowser.c:41 ITravelLog COM 接口,管理浏览历史
关键 COM 接口
接口 用途
IWebBrowser2 外部控制浏览器的主要 COM 接口(Navigate, GoBack, GoForward 等)
IShellBrowser 与 Windows Shell 的集成接口
IBrowserService 浏览器内部服务接口
IDocHostUIHandler2 自定义 MSHTML 宿主行为(菜单、键盘、拖放等)
IOleClientSite OLE 嵌入容器接口
IDocObjectService 文档对象服务(BeforeNavigate2, NavigateComplete2 事件)
启动流程
复制代码
IEWinMain() → InternetExplorer_Construct()
    → DocHost_Init()              # 初始化 DocHost
    → HlinkFrame_Init()           # 初始化超链接框架
    → IWebBrowser2_Navigate2()    # 导航到 URL
        → OleCreate(CLSID_HTMLDocument)  # 创建 mshtml 的 HTMLDocument

2.3 mshtml.dll --- Trident/Gecko 桥接层

位置dll/win32/mshtml/

职责:实现 Trident(MSHTML)COM 接口,但将实际渲染工作委托给 wine_gecko。

核心组件
组件 文件 职责
HTMLDocumentObj htmldoc.c IHTMLDocument2/3 的 COM 实现
NSContainer nsembed.c Gecko 容器,持有 XPCOM 接口指针
load_gecko() nsembed.c:754 Gecko 加载入口
load_xul() nsembed.c:472 加载 xul.dll
init_xpcom() nsembed.c:690 初始化 XPCOM 运行时
Gecko 加载流程
复制代码
mshtml.dll DLL_PROCESS_ATTACH
    → load_gecko()                    [DLL 加载时调用]
        → load_wine_gecko(gre_path)   [从注册表读取 Gecko 路径]
            → RegOpenKey(HKLM\Software\Wine\MSHTML\2.40)
            → RegQueryValueExW("GeckoPath")
                → "%SystemRoot%\wine_gecko" (REG_EXPAND_SZ)
                → ExpandEnvironmentStringsW → "C:\ReactOS\wine_gecko"
            → check_version()          [验证 VERSION 文件 = "Wine Gecko 2.40"]
            → load_xul()               [LoadLibraryExW(xul.dll)]
                → set_environment()    [设置 PATH, NSPR_LOG_MODULES 等]
                → GetProcAddress 解析 15 个 XPCOM 核心函数
        → init_xpcom(gre_path)        [初始化 XPCOM]
            → NS_InitXPCOM2()
            → 获取 nsIComponentManager
            → 注册 nsIComponentRegistrar (nsio, mutation observer)
            → 设置偏好 (set_preferences)
            → 注册自定义 nsIO 服务
        ← 成功: pCompMgr != NULL
        ← 失败: "Could not load wine-gecko. HTML rendering will be disabled."
动态解析的 XPCOM 函数

从 xul.dll 通过 GetProcAddress 解析的 15 个核心函数:

函数 用途
NS_InitXPCOM2 初始化 XPCOM 运行时
NS_ShutdownXPCOM 关闭 XPCOM
NS_GetComponentRegistrar 获取组件注册器
NS_StringContainerInit2 初始化 Unicode 字符串容器
NS_CStringContainerInit2 初始化 C 字符串容器
NS_StringContainerFinish 销毁 Unicode 字符串容器
NS_CStringContainerFinish 销毁 C 字符串容器
NS_StringSetData 设置 Unicode 字符串数据
NS_CStringSetData 设置 C 字符串数据
NS_NewLocalFile 创建 nsIFile 本地文件对象
NS_StringGetData 获取 Unicode 字符串数据
NS_CStringGetData 获取 C 字符串数据
NS_Alloc / NS_Free XPCOM 内存分配/释放
循环收集函数 ccref_incr, ccref_decr, ccref_init, ccp_init, describe_cc_node, note_cc_edge
NSContainer --- Gecko 与 MSHTML 的桥接

位置mshtml_private.h:650

NSContainer 是 mshtml 中最核心的桥接结构体,它持有 Gecko 引擎的 XPCOM 接口指针:

c 复制代码
struct NSContainer {
    nsIWebBrowserChrome      nsIWebBrowserChrome_iface;   // Gecko 浏览器 chrome
    nsIContextMenuListener   nsIContextMenuListener_iface; // 右键菜单监听
    nsIURIContentListener    nsIURIContentListener_iface;  // URI 内容监听
    nsIEmbeddingSiteWindow   nsIEmbeddingSiteWindow_iface; // 嵌入站点窗口
    nsITooltipListener       nsITooltipListener_iface;     // 工具提示
    nsIInterfaceRequestor    nsIInterfaceRequestor_iface;  // 接口请求器
    nsISupportsWeakReference nsISupportsWeakReference_iface;

    nsIWebBrowser *webbrowser;       // Gecko 的 WebBrowser 对象
    nsIBaseWindow *window;           // Gecko 的基础窗口
    nsIWebNavigation *navigation;    // 导航接口 (GoBack, GoForward, LoadURI)
    nsIWebBrowserFocus *focus;       // 焦点管理
    nsIWebBrowserSetup *setup;       // 浏览器设置
    HTMLDocumentObj *doc;            // 关联的 MSHTML 文档对象
    NSContainer *parent;             // 父容器
    HWND hwnd;                       // Gecko 子窗口句柄
    ...
};
导航时序
复制代码
IWebBrowser2::Navigate(url)
    → navigate_url()                [navigate.c:941]
        → 触发 BeforeNavigate2 事件  [IDocObjectService::FireBeforeNavigate2]
        → OleCreate(CLSID_HTMLDocument)  [创建 HTMLDocument]
            → HTMLDocument_Create()      [htmldoc.c:4821]
                → create_nscontainer()   [nsembed.c:2093]
                    → load_gecko()       [首次使用时触发]
                    → init_nscontainer() [创建 nsIWebBrowser + nsIBaseWindow]
                → 创建 IHTMLDocument2 接口
        → nsIWebNavigation::LoadURI()  [委托给 Gecko]
        → NavigateComplete2 事件        [IDocObjectService::FireNavigateComplete2]
        → 更新 travel log               [update_travellog in dochost.c]
        → DocumentComplete 事件         [IDocObjectService::FireDocumentComplete]
XPCOM 接口定义

位置dll/win32/mshtml/nsiface.idl

这是一个特殊的 IDL 文件

"This file is not a typical idl file. Interfaces in this file are XPCOM interfaces (NOT MSCOM!), but we generate the header file with WIDL compatible with XPCOM, usable in C code."

定义了约 100 个 XPCOM 接口的 C 语言绑定,涵盖:

  • 核心接口:nsIWebBrowser, nsIBaseWindow, nsIWebNavigation
  • 内容接口:nsIURIContentListener, nsIWebPageDescriptor
  • 历史接口:nsIGlobalHistory, nsIHistoryEntry
  • 安全接口:nsISecureBrowserUI, nsISSLStatus
  • 打印接口:nsIWebBrowserPrint, nsIWebProgressListener
  • 辅助接口:nsIIOService, nsIFileProtocolHandler, nsICategoryManager

2.4 wine_gecko --- Mozilla Gecko 引擎

位置modules/optional/wine_gecko/

文件清单

复制代码
wine_gecko/
├── xul.dll                  # Gecko 核心引擎 DLL (~30MB)
├── VERSION                  # 版本文件:"Wine Gecko 2.40"
├── omni.ja                  # 打包的 JS/XPCOM 组件(ZIP 格式)
├── platform.ini             # 平台配置
├── dependentlibs.list       # 依赖列表
├── LICENSE
├── freebl3.dll              # NSS 加密库
├── mozglue.dll              # Mozilla 胶水库
├── nss3.dll                 # NSS 安全层
├── nssckbi.dll              # NSS CKBI 内置根证书
├── nssdbm3.dll              # NSS DBM 数据库
├── softokn3.dll             # NSS 软件令牌
├── libEGL.dll               # EGL 图形接口
├── libGLESv2.dll            # GLESv2 图形接口
├── plugin-container.exe     # 插件进程容器
├── plugin-hang-ui.exe       # 插件挂起 UI
├── dictionaries/
│   ├── en-US.aff            # 拼写检查词形
│   └── en-US.dic            # 拼写检查词典
└── gmp-clearkey/0.1/        # ClearKey DRM
    ├── clearkey.dll
    └── clearkey.info

注册表配置boot/bootdata/hivedef.inf:1997-1999):

ini 复制代码
; Gecko 下载 URL
HKCU,"SOFTWARE\Wine\MSHTML","GeckoUrl",,"http://source.winehq.org/winegecko.php"
; 安装 CAB 目录
HKCU,"SOFTWARE\Wine\MSHTML","GeckoCabDir",0x00020000,"%SystemRoot%\"
; Gecko 安装路径 (REG_EXPAND_SZ)
HKLM,"SOFTWARE\Wine\MSHTML\2.40","GeckoPath",0x00020000,"%SystemRoot%\wine_gecko"

三、关键接口映射

Trident (MSCOM) Gecko (XPCOM) 功能
IHTMLDocument2 nsIWebBrowser + nsIDOMDocument HTML 文档对象
IWebBrowser2::Navigate nsIWebNavigation::LoadURI URL 导航
IHTMLElement nsIDOMHTMLElement DOM 元素操作
IHTMLWindow2 nsIDOMWindow 窗口对象
IDocHostUIHandler nsIWebBrowserChrome 宿主 UI 自定义
IOleInPlaceSite nsIEmbeddingSiteWindow 内嵌站点窗口

四、宿主 UI 自定义链

复制代码
应用程序 → ieframe.dll DocHostUIHandler
                  ↓ (通过 hostui 链式转发)
            外部宿主 (如应用程序自定义的 IDocHostUIHandler)
                  ↓
            mshtml.dll 内部处理
                  ↓
            NSContainer → nsIWebBrowserChrome
                  ↓
            xul.dll (Gecko 引擎)

关键方法(dochost.c:790-951):

方法 功能
ShowContextMenu 右键菜单(可以禁止或自定义)
GetHostInfo 返回 DOCHOSTUIFLAG(如禁用脚本、禁用 ActiveX 等)
GetOptionKeyPath IE 选项的注册表路径
GetExternal 提供 window.external 的 IDispatch 接口
TranslateAccelerator 键盘加速键处理
GetDropTarget OLE 拖放目标
FilterDataObject 剪贴板数据过滤

五、wine_gecko 安装机制

5.1 首次安装时

系统安装向导(syssetup/wizard.c:2710)调用 appwiz.cpl,,install_gecko,弹出安装对话框。

5.2 安装流程

dll/cpl/appwiz/addons.c

复制代码
install_addon(ADDON_GECKO)
  → install_from_registered_dir()    # 尝试从 GeckoCabDir 安装 MSI
      → 搜索 GeckoCabDir\wine_gecko-2.40-x86.msi
      → MsiInstallProductW()
  → [失败时] download_proc()         # 弹出下载对话框
      → URLDownloadToFileW(url, temp_msi)
      → SHA1 校验
      → MsiInstallProductW(temp_msi)

5.3 MSI 安装结果

MSI 将 xul.dll 等文件解压到 %SystemRoot%\wine_gecko\,并在注册表中写入 GeckoPath。

5.4 系统自带的 wine_gecko

ReactOS 的 bootcd.iso 中已包含 wine_gecko(modules/optional/wine_gecko/),通过 txtsetup.sif 在系统安装时直接复制到 %SystemRoot%\wine_gecko\,无需下载。


六、构建系统集成

6.1 mshtml.dll 构建

cmake 复制代码
# dll/win32/mshtml/CMakeLists.txt
add_idl_headers(mshtml_nsiface_header nsiface.idl)   # 从 XPCOM IDL 生成头文件
...
add_library(mshtml MODULE nsembed.c ...)              # nsembed.c 是 Gecko 集成核心
add_dependencies(mshtml mshtml_nsiface_header)        # 依赖 XPCOM 头文件

6.2 wine_gecko 文件集成

cmake 复制代码
# modules/CMakeLists.txt
# 使用 NO_CAB 确保文件直接放在 ISO 上,不打包进 CAB
add_cd_file(FILE .../wine_gecko/xul.dll
            DESTINATION reactos/wine_gecko
            NO_CAB
            FOR bootcd livecd regtest)

6.3 安装时文件复制

txtsetup.sif 中定义了 5 个目录 ID(82, 88-91)和 27 个文件条目,确保安装程序将所有 wine_gecko 文件复制到 %SystemRoot%\wine_gecko\


七、ReactOS 特有修复

详见 wine_gecko集成与修复总结.md,主要包括:

# 文件 修复
1 nsembed.c 支持 REG_EXPAND_SZ 展开 %SystemRoot%
2 hivedef.inf GeckoPath 使用 REG_EXPAND_SZ
3 msvcrt.spec 去掉 -version=0x600+ 限制
4 kernel32/time.c 实现 GetSystemTimePreciseAsFileTime
5 modules/CMakeLists.txt wine_gecko 用 NO_CAB
6 txtsetup.sif 添加目录 ID 和文件复制规则

八、调试指南

调试频道

频道名 启用方式 范围
ieframe WINE_DEFAULT_DEBUG_CHANNEL(ieframe) 浏览器框架
gecko WINE_DECLARE_DEBUG_CHANNEL(gecko) Gecko 集成 (nsembed.c)

常见错误日志

日志 含义
err: Could not open VERSION file VERSION 文件未找到
err: Could not load XUL: %d xul.dll 加载失败(依赖缺失)
err: xul.dll failing with c0000139 缺少 CRT 导出函数 (DLL_NOT_FOUND)
err: Could not load wine-gecko Gecko 加载链路中任一阶段失败
fixme: BrowserService_GetTravelLog ITravelLog 未实现(已修复)
err: class {591209c7-...} not registered ApplicationAssociationRegistration 未注册(已修复)

九、架构图示

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                       iexplore.exe                              │
│  (base/applications/iexplore/main.c)                            │
└───────────────────────────┬─────────────────────────────────────┘
                            │ IEWinMain()
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│                       ieframe.dll                                │
│  (dll/win32/ieframe/)                                           │
│                                                                 │
│  ┌───────────────┐  ┌───────────────┐  ┌────────────────────┐  │
│  │   WebBrowser  │  │  ShellBrowser │  │      DocHost        │  │
│  │  (IWebBrowser2)│  │(IShellBrowser)│  │(IDocHostUIHandler2) │  │
│  └───────┬───────┘  └───────┬───────┘  └─────────┬──────────┘  │
│          │                 │                     │             │
│          └─────────────────┴─────────────────────┘             │
│                            │                                    │
│                      IWebBrowser2::Navigate()                   │
└───────────────────────────┬─────────────────────────────────────┘
                            │ OleCreate(CLSID_HTMLDocument)
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│                        mshtml.dll                                │
│  (dll/win32/mshtml/)                                            │
│                                                                 │
│  ┌──────────────────────┐  ┌──────────────────────────────────┐ │
│  │   HTMLDocumentObj     │  │          NSContainer              │ │
│  │  (IHTMLDocument2/3)   │  │                                  │ │
│  │  (IDispatch)          │  │  nsIWebBrowser                   │ │
│  └──────────┬───────────┘  │  nsIWebNavigation                 │ │
│             │               │  nsIBaseWindow                    │ │
│             │               │  nsIWebBrowserChrome              │ │
│             │               │  nsIWebBrowserFocus               │ │
│             │               │  ...                              │ │
│             │               └──────────┬───────────────────────┘ │
│             │                          │                         │
│             └──────────────────────────┼─────────────────────────┘
│                                        │                         │
│              load_gecko() ◄────────────┘                         │
│              (加载 xul.dll + 初始化 XPCOM)                        │
└────────────────────────────────────────┬─────────────────────────┘
                                         │ XPCOM 调用
                                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                    wine_gecko (xul.dll)                          │
│  (modules/optional/wine_gecko/)                                 │
│                                                                 │
│  Mozilla Gecko 引擎                                              │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐                       │
│  │  Gecko   │ │  Necko   │ │  NSS     │                       │
│  │ (HTML/CSS)│ │ (网络层)  │ │ (安全层)  │                       │
│  ├──────────┤ ├──────────┤ ├──────────┤                       │
│  │ Spider-  │ │  DOM     │ │  Layout  │                       │
│  │ monkey   │ │          │ │  Engine  │                       │
│  │ (JS引擎)  │ │          │ │          │                       │
│  └──────────┘ └──────────┘ └──────────┘                       │
└─────────────────────────────────────────────────────────────────┘

十、关键文件索引

文件路径 说明
base/applications/iexplore/main.c IE 可执行入口
dll/win32/ieframe/iexplore.c IEWinMain, InternetExplorer_Construct
dll/win32/ieframe/webbrowser.c IWebBrowser2 实现
dll/win32/ieframe/dochost.c DocHost, IDocHostUIHandler2, travel log
dll/win32/ieframe/shellbrowser.c ShellBrowser, IBrowserService, ITravelLog
dll/win32/ieframe/navigate.c navigate_url 函数
dll/win32/ieframe/client.c IOleClientSite, IOleInPlaceSite
dll/win32/ieframe/ieframe.h 核心数据结构定义
dll/win32/mshtml/nsembed.c Gecko 加载、XPCOM 初始化、NSContainer
dll/win32/mshtml/nsiface.idl ~100 个 XPCOM 接口的 C 绑定
dll/win32/mshtml/htmldoc.c HTMLDocument COM 实现
dll/win32/mshtml/navigate.c MSHTML 导航逻辑
dll/win32/mshtml/mshtml_private.h NSContainer 等内部结构
dll/win32/mshtml/main.c DllMain, DLL_PROCESS_ATTACH 时调用 load_gecko
modules/optional/wine_gecko/ wine_gecko 文件目录
modules/optional/wine_gecko-2.40-x86.msi wine_gecko MSI 安装包
modules/CMakeLists.txt wine_gecko 构建集成
boot/bootdata/hivedef.inf Gecko 注册表默认值
boot/bootdata/txtsetup.sif 安装时文件复制规则
dll/cpl/appwiz/addons.c Gecko 安装/下载 UI
dll/win32/syssetup/wizard.c 系统安装时触发 Gecko 安装
相关推荐
微三云 - 廖会灵 (私域系统开发)5 小时前
电商系统从单体到微服务拆分实践:拆什么、怎么拆、拆完后怎么办
微服务·云原生·架构
在水一缸6 小时前
苹果AI国行版过审背后的技术架构深度解析:端侧模型与私有云计算的融合实践
人工智能·架构·云计算·技术架构·苹果ai·端侧模型·私有云计算
爱上纯净的蓝天6 小时前
具身智能架构演进:从“纸上大脑“到“落地干活“的三层架构设计
架构
Kel6 小时前
输出层与反分词(Output Layer & Detokenization)
人工智能·算法·架构
宇宙第一小趴菜6 小时前
五、Oracle vs MySQL 架构深度对比笔记
mysql·oracle·架构
qq_454245037 小时前
ClineRule系统提示词
人工智能·架构
BerryS3N7 小时前
深度解析 LangChain V1.3:架构演进、核心源码剖析与企业级应用落地指南
架构·langchain
学网安的肆伍7 小时前
【046-WEB攻防篇】注入工具&SQLMAP&Tamper编写&指纹修改&高权限操作&目录架构
前端·架构
某林2129 小时前
ROS2 + WebRTC + MQTT 异构系统架构
架构·系统架构·机器人·硬件架构·webrtc·ros2