云计算百科
云计算领域专业知识百科平台

Windows 驱动实例分析系列:libwdi 驱动分析 - libwdi 篇(六)

子文档六:安装执行模块(installer.c)

installer.c 是 libwdi 中唯一需要以管理员权限运行的组件。它被编译为一个独立的可执行文件(installer_x86.exe、installer_x64.exe、installer_arm64.exe),由 wdi_install_driver 通过 UAC 提权启动。其职责是执行实际的驱动安装操作,并通过命名管道与父进程通信。

架构概览

installer 是一个控制台应用程序,其入口点 main 执行以下核心任务:

  • 连接到父进程创建的命名管道 \\\\.\\pipe\\libwdi-installer。
  • 通过管道请求获取设备 ID、硬件 ID 和当前用户 SID。
  • 启动后台线程实时读取 Windows 驱动安装日志(setupapi.dev.log),并将日志行通过管道回传给父进程。
  • 根据硬件 ID 调用 UpdateDriverForPlugAndPlayDevices 执行驱动安装。
  • 若设备未连接,则调用 SetupCopyOEMInf 将 INF 复制到系统目录,标记为“预安装”。
  • 若安装失败,通过 process_error 将错误码转换为 libwdi 错误码,并通过 IC_SET_STATUS 消息发送给父进程。
  • 管道通信协议

    安装器与父进程之间通过消息模式管道通信,定义了 9 种消息类型(在 installer.h 中枚举):

    • IC_PRINT_MESSAGE:父进程收到此消息后,将负载(文本)通过日志系统输出。
    • IC_SYSLOG_MESSAGE:同 IC_PRINT_MESSAGE,但标记为来自系统日志。
    • IC_GET_DEVICE_ID:安装器请求设备 ID,父进程回复设备 ID 字符串。
    • IC_GET_HARDWARE_ID:请求硬件 ID。
    • IC_GET_USER_SID:请求当前用户 SID(用于后续创建文件时的安全描述符)。
    • IC_SET_TIMEOUT_INFINITE:父进程请求将超时设置为无限。
    • IC_SET_TIMEOUT_DEFAULT:恢复默认超时(10 秒)。
    • IC_SET_STATUS:安装器向父进程报告状态码(libwdi 错误码)。
    • IC_INSTALLER_COMPLETED:安装器通知父进程它即将退出。

    通信采用请求-响应模式:父进程发送请求(如 IC_GET_HARDWARE_ID),安装器等待后回复数据。

    驱动安装核心

    installer 的主要安装逻辑如下:

  • 通过 request_data 获取硬件 ID(若设备未连接,硬件 ID 可能为空)。
  • 调用 UpdateDriverForPlugAndPlayDevices(NULL, hardware_id, inf_path, INSTALLFLAG_FORCE, NULL)。
    • 若成功,安装完成。
    • 若失败且错误码为 ERROR_NO_SUCH_DEVINST(设备未连接),则调用 SetupCopyOEMInf 将 INF 复制到系统目录,并调用 CM_Reenumerate_DevNode 触发设备重新枚举,以便下次插入时自动安装。
  • 若安装失败且错误码为 ERROR_NO_MORE_ITEMS,表示已有更新版本的驱动存在,这时会尝试强制安装(添加 DRIVER_PACKAGE_FORCE 标志)——但 libwdi 当前实现中并未使用 DriverPackageInstall,而是直接使用 UpdateDriverForPlugAndPlayDevices,故该逻辑可能未完全实现。
  • 系统日志实时读取

    安装器启动一个后台线程 syslog_reader_thread,负责读取 Windows 安装日志文件(%WINDIR%\\inf\\setupapi.dev.log、setupapi.log、setupact.log)。该线程:

    • 以只读共享方式打开日志文件。
    • 定位到文件末尾,记录偏移量。
    • 每隔一定时间检查文件大小是否变化,若有新内容,则读取新增部分,按行分割,通过管道发送给父进程(每条消息前缀为 IC_SYSLOG_MESSAGE)。

    这实现了安装进度的实时可视化,使用户能在父进程的日志窗口中看到详细的安装过程。

    系统还原点控制

    安装器在安装前通过 IGroupPolicyObject COM 接口临时禁用系统还原点创建(设置注册表值 DisableSystemRestore),安装完成后恢复。这是为了避免安装驱动时创建庞大的还原点,导致安装过程变慢。

    错误码转换

    process_error 函数将 Windows API 错误码(GetLastError 或 SetupAPI 错误)映射为 libwdi 定义的错误码(如 WDI_ERROR_INF_SYNTAX、WDI_ERROR_CAT_MISSING、WDI_ERROR_UNSIGNED 等),便于上层统一处理。

    资源清理

    installer 在退出前会关闭所有句柄(管道、线程、事件等),并恢复系统还原点设置。


    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Windows 驱动实例分析系列:libwdi 驱动分析 - libwdi 篇(六)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!