子文档五:Zadig 网络更新与配置解析模块
Zadig 支持自动检查更新,该功能由zadig_net.c和zadig_parser.c两个模块共同实现。本节将深入分析这两个模块的实现细节。
网络更新检查模块(zadig_net.c)
1. 网络连接检测
GetInternetSession函数首先通过INetworkListManagerCOM 接口检测系统是否连接到互联网(调用get_IsConnectedToInternet)。若 COM 接口不可用或检测失败,则回退到InternetGetConnectedStateAPI。如果检测到未连接,函数直接返回 NULL,避免后续无谓的网络请求。
2. 版本文件下载
DownloadFile函数实现了 HTTP 文件下载功能,其步骤包括:
- 使用
InternetOpen打开会话,设置用户代理字符串(包含应用程序名称和版本)。 - 使用
InternetCrackUrl解析 URL,提取主机名、端口和路径。 - 使用
InternetConnect建立连接,然后HttpOpenRequest打开请求句柄。 - 发送请求并检查 HTTP 状态码(必须为 200)。
- 通过
HttpQueryInfo获取内容长度,创建本地文件。 - 循环调用
InternetReadFile读取数据块,写入本地文件,并通过进度条控件(若提供)更新进度。 - 完成后关闭所有句柄。
该函数支持同步下载,并提供了超时设置(NET_SESSION_TIMEOUT),防止网络阻塞导致 UI 冻结。
3. 后台检查更新线程
CheckForUpdatesThread是一个独立的后台线程,执行实际的更新检查逻辑:
- 首先从注册表读取上次检查时间和检查间隔,若未到下次检查时间则直接退出(除非强制检查)。
- 构造版本文件 URL:
https://zadig.akeo.ie/<app>_<arch>_<os_major>.<os_minor>.ver,并尝试逐步降低 OS 版本号(例如6.2→6)以兼容旧版本系统。 - 使用
InternetOpen等函数下载版本文件(格式为键值对,如version=2.9.788)。 - 调用
parse_update解析文件内容,填充APPLICATION_UPDATE结构体。 - 比较本地版本与远程版本,若远程版本更高且满足最低平台要求,则触发下载新版本。
该线程设计为在后台静默运行,不会阻塞 UI。若检测到新版本,它会等待当前安装操作结束后才弹出下载对话框,避免干扰用户正在进行的操作。
4. WinINet 错误处理
WinInetErrorString函数将 WinINet 错误码转换为可读的字符串,覆盖了从ERROR_INTERNET_OUT_OF_HANDLES到ERROR_INTERNET_LOGIN_FAILURE_DISPLAY_ENTITY_BODY等数十种错误,便于调试和用户反馈。
配置解析模块(zadig_parser.c)
1. UTF-16 配置文件解析器
zadig_parser.c实现了一个轻量级的配置文件解析器,专门用于处理 UTF-16 编码的键值对文件(例如 Zadig 的设备预设文件.cfg)。其核心函数get_token_data_line从一行文本中解析token = "data"格式的数据,支持引号包裹的值,并处理转义字符(如\n、\t等)。
2. 文件解析
get_token_data_file使用_wfopen以 Unicode 模式打开文件(自动识别 BOM),逐行读取并调用get_token_data_line查找匹配的令牌。若找到,将值转换为 UTF-8 并返回。
3. 缓冲区解析
get_token_data_buffer用于解析内存中的 UTF-8 字符串(如从网络下载的版本文件)。它首先将整个缓冲区转换为 UTF-16,然后逐行处理,并支持跳过大括号包裹的多行内容(用于 RTF 等复杂格式)。
4. 更新数据解析
parse_update专门用于解析更新版本文件。它首先对缓冲区进行“清洗”,仅允许安全字符(字母、数字、空格、标点等),防止注入攻击。然后依次提取version、platform_min、download_url和release_notes字段,并填充APPLICATION_UPDATE结构体。
5. 预设配置文件加载
Zadig 支持通过菜单“打开”加载.cfg文件,该文件可包含设备 VID、PID、描述、MI、GUID 等预设值。parse_preset函数调用profile_open(来自profile.c)解析 INI 风格的配置文件,并将读取到的值填充到 UI 控件中,方便用户快速配置特定设备。
注册表配置存储
zadig_registry.h提供了一组内联函数,用于读写注册表中 Zadig 的配置项(如更新检查间隔、是否包含测试版、上次检查时间等)。这些函数封装了RegOpenKeyEx、RegCreateKeyEx、RegQueryValueEx、RegSetValueEx等底层操作,并支持 32 位/64 位整数、字符串和布尔值。
注册表根键为HKEY_CURRENT_USER\Software\Akeo Consulting\Zadig,所有用户设置存储在此,无需管理员权限。