# Win95 USB Lab

## Windows 95 OSR2 的可重复虚拟机测试

**技术白皮书 · 2026 年 9 月 13 日 · 文档修订版 1.0**

为 Luke Kist 编写。本文描述软件版本 **0.1.0-preview.1**。本页为中文译文；下载的 PDF 为英文原文。

### 摘要

Win95 USB Lab 提供一个小型、可审查的框架，用于在现有 Windows 95 OSR2 虚拟机中评估 USB 输入、USB 存储及可选的网络连接。原生客户机程序记录设备状态、应用程序输入、文件完整性和网络交换。现代宿主机工具负责准备具有独立标识的测试介质、检查可执行文件导入，并评估报告。三阶段流程旨在 Windows 重启以及冷启动之后重复所选检查。

核心原则是：每项结论都需要与其对应的证据。设备名称不能证明驱动已启动；应用中的点击不能说明输入来自哪条通路；文件访问成功不能证明使用了 USB；关机请求不能证明机器已经停止。因此，框架将客户机诊断与独立的设备路由、生命周期观察要求结合起来。

预览版通过了 20 项宿主机测试。在同一构建环境中，从解压后的副本重新构建，得到了逐字节相同的发布压缩包；准备好的介质通过了回读；程序导入的 API 名称均能在本地保存的 OSR2 DLL 导出中找到。这些结果建立了经过检查的准备与报告基线。新预览版尚未在运行中的客户机内执行；USB HID 兼容性仍未解决，跨启动的存储 I/O 尚未验证，实机测试留待后续进行。

项目希望为 Windows 95 社区提供可复用的测试基础设施。软件包提供原创源代码和诊断程序；兼容 USB 驱动以及具有合法授权的操作系统安装仍需单独准备。

### 截至 2026 年 9 月 13 日的状态

| 范围 | 已有证据 |
| --- | --- |
| 准备、检查与打包 | 20 项宿主机测试通过；在记录的环境中重建出相同压缩包 |
| 客户机 API 接口 | 静态导入／导出审计通过；运行时行为尚未验证 |
| 实际 VM USB 存储与网络 | 已准备测试流程，尚待执行 |
| USB 鼠标／数位板 | 已准备诊断程序，兼容驱动仍未解决 |
| 物理 USB 硬件 | 未进行测试，不作兼容性声明 |
| 分发 | 已准备本地预览压缩包；尚未发布到 GitHub |

本文描述实验性预览版，不是 USB 驱动发布或硬件认证，也不声称测得吞吐量、延迟或可靠性基准。

<!-- pagebreak -->

## 1. 问题、范围与参考平台

### 1.1 结论必须说明完整路径

对本项目而言，有用的 USB 兼容性结果必须关联具体的客户机版本、控制器、外设、驱动栈和观察到的操作。安装向导接受 INF 只是早期观察。完整结果还应表明驱动已启动、预期操作已完成，并且配置能经历指定的生命周期转换，而无需再次处理驱动提示。

存储与输入必须分别对待。Conner McCoy 和 Rudolph Loew 的 XUSBSUPP 项目文档描述了包含 RLUSB9X 的 OSR2 存储路径。该软件包明确不提供 USB HID 键盘、鼠标、游戏杆驱动，也不提供 USB 2.0、USB 3.0 控制器支持。这些说明针对该软件包，并非对如今所有可能存在的驱动所作的调查。使用存储补充包不会自动为 Win95 USB Lab 带来 HID 能力。[来源：XUSBSUPP 作者文档](https://msfn.org/board/topic/177518-xusbsupp-extended-usb-supplement-for-windows-95-osr2/)。

预览版可选择 USB 输入、USB 存储或二者组合的测试套件。PCnet 网络是额外的可选检查。网络测试使用模拟的 PCI 网卡，并不测试 USB 以太网适配器。

### 1.2 首个验证目标

| 组件 | 参考配置 |
| --- | --- |
| 操作系统 | 现有、合法授权的 Windows 95 OSR2；版本 4.0，构建号至少为 1111，并符合 Win95 构建号范围检查 |
| 机器 | 禁用 ACPI 的 QEMU PC |
| CPU 与内存 | 一个 Pentium II CPU；64 MiB 内存 |
| 显示 | 标准 VGA；至少 640 × 480 |
| USB 控制器 | PIIX3 UHCI，USB 1.x |
| 输入候选设备 | QEMU USB 数位板；保留 PS/2 恢复操作途径 |
| 存储候选设备 | 由专用 FAT16 镜像支持的 USB bulk-only 存储 |
| 可选网络 | AMD PCnet，使用 QEMU 用户模式 NAT；不配置入站端口转发 |

`profiles/qemu-osr2.json` 记录了这套配置。它描述预期测试目标，不负责启动虚拟机。QEMU 文档将数位板描述为使用绝对坐标的指针设备，将 `usb-storage` 描述为由独立驱动器对象支持的 bulk-only 存储设备。拟用配置明确将候选设备连接到 UHCI。[来源：QEMU USB 模拟文档](https://www.qemu.org/docs/master/system/devices/usb.html)。

Windows 95 RTM、其他 Windows 版本、其他虚拟机平台、EHCI/xHCI 控制器以及物理外设均不在本预览版的验证范围内。检查器还识别特定 PCI 标识和驱动名称。更换平台或驱动栈，需要明确修订检查器与配置，并重新进行验证。

<!-- pagebreak -->

## 2. 架构与分发

### 2.1 三个协作组件

架构将准备工作、客户机观察和虚拟机管理责任分开。现代宿主机工具处理文件和报告评估；原生程序在 Windows 内执行操作；现有 VM 管理器负责启动、设备连接、输入路由、重启观察、关机和清理。

宿主机入口包括：用于创建新测试与介质的 `prepare.py`、用于评估客户机报告的 `check.py`、用于检查 API 名称的 `audit.py`，以及按明确文件清单打包的 `package.py`。客户机组件是 `U95TEST.EXE`。

证据流如下：

```text
源代码 + 发布的可执行文件
            |
       宿主机准备
            |
       清单 + 辅助介质
            |
   现有受管理 OSR2 VM ------> 路由／生命周期观察
            |                         |
       客户机 JSON 报告                 |
            |                         |
       客户机检查器 ----------------> 综合审查
```

**图 1。** 客户机诊断与外部 VM 观察分别提供验证记录的不同部分。便携检查器不会自动把它们合并为运行验证通过的结论。

工具不会启动 QEMU、创建替代操作系统磁盘，或打开宿主机原始 USB 设备。在本项目的环境中，生命周期与观察仍由 Perslis/GhostBridge 管理。公开工具包可以配合现有 VM 工作流程使用，无需导入 Perslis 专用控制器代码。

### 2.2 小型旧系统程序

探针由 C 源码构建为 32 位 x86 Windows 程序，OS 与子系统版本头均为 4.0。它直接调用 Windows API，并自行实现少量内存辅助函数，避免依赖 C 运行库。Configuration Manager 入口从 `CFGMGR32.DLL` 动态解析，网络操作使用 Winsock 1.1。

这一设计使导入接口易于审查，但不会让现代编译器产物自动兼容所有 Win95 安装。记录的 API 审计使用目标安装中保存的 DLL 检查候选程序；实际加载与运行仍是另一项测试。

### 2.3 分发内容

压缩包包含原创 C、Python、Shell 源代码、文档、配置、宿主机测试，以及 `U95TEST.EXE`。原创材料采用 MIT 许可证。压缩包不含 Windows DLL、第三方驱动、安装柜文件、操作系统镜像、保存的内存或私有机器配置。依赖与第三方许可证边界在 `THIRD_PARTY.md` 中另行说明。

<!-- pagebreak -->

## 3. 客户机诊断与受控文件操作

### 3.1 设备状态与父子关系

探针遍历 Configuration Manager 设备树，记录标识、父节点关系、状态查询返回码、问题码、设备类、驱动键及部分驱动绑定值。遍历设有深度与节点数上限；不完整的枚举不能作为完整证据通过检查。

检查器要求状态读取成功、设置 `DN_STARTED`、未设置 `DN_HAS_PROBLEM`、记录的问题值为零，且驱动键不为空。随后检查预期设备标识与祖先关系。Microsoft 文档说明了 `CM_Get_DevNode_Status` 的状态和问题输出；现行文档可供理解 API 语义，但不能证明其历史上的 Win95 可用性。[来源：Microsoft Configuration Manager 文档](https://learn.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_devnode_status)。

参考路径要求 UHCI 绑定 `UHCD.SYS`，其后代根集线器绑定 `USBHUB.SYS`，所选外设栈位于该集线器之下。输入路径预期 `HIDUSB.SYS` 及其 `MOUHID` 后代；存储路径预期 `RLUSB9X.SYS`；可选网络预期 PCnet 与 `PCNTN3.VXD`。这些检查确立的是系统报告的绑定和状态，不是对每个已加载驱动二进制文件的独立测量。

### 3.2 在 Windows 内观察输入

输入测试绘制两个相隔较远的目标，记录在规定坐标容差内收到的 Windows 鼠标按下／释放消息。程序不会自行合成光标移动。两分钟输入超时允许失败的尝试仍然产生诊断报告。

外部输入路由证据仍不可少：PS/2 输入也可能到达同一个窗口。只有观察者能将操作关联到预期 USB 数位板通路，客户机点击才构成 USB 证据。键盘 Enter 可以推进已完成的测试，但绝不计为指针成功。仅存储套件不要求指针测试。

### 3.3 使用新的运行标记进行存储测试

准备工具创建新的辅助 FAT16 镜像，大小约 32 MiB，分区从第 63 扇区开始。镜像中的 `U95VOL.TAG` 保存 32 字符运行标识及 CRLF，另有确定性内容的 64 KiB `SEED.BIN`。

写入前，探针要求标记精确匹配、种子文件正确，并且早期阶段文件保持完整。随后新建一个 64 KiB 的 `U95P0.BIN`、`U95P1.BIN` 或 `U95P2.BIN`，写入该阶段的确定性模式，刷新、关闭、重新打开并验证字节。它不会覆盖已有文件。宿主机与 C 实现生成的模式已互相核对。

所选驱动器必须为 D: 至 Z:。这一限制和标记机制降低了误写其他卷的可能性，但不能证明物理设备身份。文件访问成功必须同时有设备树与连接证据，证明镜像确实经 USB 访问。操作的数据量有限，但同步驱动 I/O 仍可能挂起。

<!-- pagebreak -->

## 4. 网络检查与三阶段流程

### 4.1 可选连接证据

默认禁用网络。启用后，客户机向配置的 IPv4 服务器发送 UDP DNS 查询，再连接返回 IPv4 地址的 TCP 80 端口，请求 HTTP 响应。默认 DNS 是 QEMU NAT 的 `10.0.2.3`，主机名为 `example.com`。请求包含运行标识和阶段，以关联当前测试。

检查器要求完成指定 DNS 交换、本地地址位于参考 `10.0.2.0/24` 网络且排除指定保留地址、远端为全球可路由 IPv4 地址，并获得语法正确的 HTTP/1.0 或 HTTP/1.1 状态行。HTTP 错误状态也可满足传输检查；这既不要求业务事务成功，也不是 HTTPS 测试。

套接字等待与传输循环设有超时，但这不能为所有旧 API 或驱动调用保证统一截止时间。工具保留原始 DHCP 注册表值供检查，不会将其直接解读为 DHCP 租约证明。租约及 PCnet 的 TCP/IP 绑定仍需外部审查。

### 4.2 安装与阶段顺序

安装程序校验旁边的 `TEST.INI`，创建 `C:\U95TEST`，复制探针和配置，并添加其专用 Windows Run 启动项。如果目录或启动项冲突则拒绝安装。它不安装任何设备驱动。`/inspect` 只生成设备快照，不消耗测试阶段、不发送网络请求、不写入存储测试文件。

| 阶段 | 所选检查 | 请求的转换与必要观察 |
| --- | --- | --- |
| 0：初次运行 | 设备状态及所选输入／存储／网络操作 | 请求 Windows 重启；观察者确认客户机在同一 VM 进程内重启 |
| 1：重启后 | 重复操作；若选择存储则验证阶段 0 数据 | 请求 Windows 关机；确认安全关机，停止模拟器并确认进程消失 |
| 2：冷启动后 | 重复操作；若选择存储则验证之前的文件 | 移除测试启动项并请求最终关机；观察者确认清理完成 |

客户机写出 `PHASE0.JSON` 至 `PHASE2.JSON` 及相应 `EXIT` 请求记录。持久阶段计数器在程序运行时递增，因此仅凭三份报告不能证明三种不同启动状态。

转换调用 `ExitWindowsEx`。Microsoft 文档说明，成功返回表示已发起请求，不保证完成。因此流程要求请求记录之外的观察。这里引用现行文档是为了说明这一区别，不是用它保证 Win95 兼容性。[来源：Microsoft ExitWindowsEx 文档](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-exitwindowsex)。

冷启动结果要求客户机已经关机、模拟器退出，并由新进程启动同一安装，且没有从保存的内存恢复。Win95 的“现在可以安全关闭计算机”画面可能需要管理器随后完成模拟器退出。进程身份、磁盘身份和观察到的启动行为都应进入证据记录。

<!-- pagebreak -->

## 5. 证据模型与通过结论的边界

### 5.1 客户机检查与实际运行验证

`check.py` 按运行清单评估三个阶段，检查所选套件、OS 代际、标识、设备状态、功能结果及相符的转换请求记录。缺失、格式错误、过期或不一致的报告会导致相应阶段失败。退出码为零表示所选客户机检查通过。

便携检查器的每份结果都保留 `liveQualified: false`。独立观察仍须证明确切 VM 与磁盘、所选 USB 通路、真实重启与冷启动完成、没有新的设备／源文件提示，以及最终清理。启用网络时，还需审查 DHCP 租约和协议绑定。当前工具不会在审查后颁发可由机器验证的认证。

| 观察 | 能支持什么 | 还需要什么 |
| --- | --- | --- |
| 驱动绑定及启动状态 | 客户机报告预期设备节点处于活动状态 | 确切二进制及版本、正确父子关系、操作成功 |
| 窗口中的两次点击 | Windows 交付了预期指针消息 | 识别 USB 数位板的宿主机输入路由 |
| 阶段文件验证成功 | 所选文件系统路径保留了测试字节 | USB 连接路径与真实生命周期转换 |
| DNS 与 HTTP 响应 | 客户机完成了配置的网络交换 | 租约／绑定证据；若声称应用兼容还需更广测试 |
| 退出请求记录 | 探针请求了指定转换 | 观察到转换完成及正确的后续启动 |
| 导入审计通过 | 所提供导出中存在需要的名称 | 加载、转发、初始化和运行时行为 |

### 5.2 完整性与信任假设

运行标识与校验和帮助防止介质、程序和报告被意外混用。将标记复制到另一个卷后，它仍然是匹配标记。未经签名的 SHA-256 校验和不认证作者，客户机生成的 JSON 也不是安全远程证明。框架假设操作员诚实，目标是可重复诊断，而不是抵御恶意客户机或伪造证据包。

报告保留了足以解释失败的上下文，包括设备描述及注册表诊断。共享证据前，应检查其中可识别环境的信息，同时保留评估结论所需的设备身份与观察。

### 5.3 失败也是有价值的结果

缺少 HID 驱动、设备问题码、错误标记、损坏种子、网络交换失败或重启中断，都具有诊断价值。应连同证据将其报告为失败或未完成的运行，而不应扩大为“所有 Win95 USB 支持都不可能”的结论。

中断的测试也需谨慎处理：计数器在执行时递增，再启动探针可能消耗下一阶段，却没有发生启动转换。应保存不完整记录、解决原因，并准备新测试进行验证。移除操作仅禁用本工具的启动项；驱动卸载仍按驱动自身流程处理。

<!-- pagebreak -->

## 6. 已记录的验证结果

以下结果来自 2026 年 9 月 13 日记录的本地发布验证，属于宿主机软件与产物检查。表中没有任何结果代表预览版已在 Windows 内运行。

| 检查 | 记录结果 | 含义 |
| --- | --- | --- |
| 便携自动化测试 | 从解压的压缩包运行，12 项通过 | 在被测宿主机环境中，准备与报告检查行为符合预期 |
| 父项目 Perslis 集成检查 | 8 项通过 | 宿主机集成假设和拒绝路径通过；不包含实际 VM 覆盖 |
| 宿主机测试总计 | 20 项通过 | 上述两个套件之和 |
| 压缩包重建 | 逐字节相同 | 在相同环境中从解压源码重建出原发布 ZIP |
| 压缩包校验和 | 验证通过 | 文件与压缩包记录的哈希相符 |
| 辅助介质回读 | 通过 | 从宿主机检查准备好的软盘／FAT16 内容和布局 |
| 导入 API 名称 | 全部找到 | 对保存的 OSR2 DLL 导出进行静态审计并通过 |
| 客户机实际执行 | 未进行 | 未证明安装、输入、存储、网络或启动结果 |
| 物理硬件 | 未进行 | 未测得控制器或外设兼容性 |

便携测试包含错误运行数据、OS 不匹配、把检查快照当作阶段证据、不合适的设备状态、存储损坏及无效网络响应等反例。测试还确认，即使文件结果成功，没有预期 USB 驱动证据也不能通过存储套件。原生 C 与宿主机生成的数据模式一致。介质检查包含分区式 FAT16 结构及安装软盘内容。

宿主机 Perslis 检查覆盖其他证据与预检失败，包括注册目标和拟使用客户机不匹配。这些测试使用受控测试数据；若将其描述为实际 Windows 集成测试，就夸大了覆盖范围。

静态 API 审计同时包含普通程序导入和动态解析的 Configuration Manager 函数。导出存在是有用的兼容性筛查，但不能证明加载器行为、转发导出、调用语义与初始化。因此参考配置仍保留 `runtimeQualified: false`。

### 6.1 可重复性的准确范围

压缩包重建结果来自同一记录的宿主机／工具链环境中的解压与重建。它不能证明任意编译器版本、操作系统或打包工具都产生相同输出。新的测试介质刻意使用新的运行标识，不声称独立准备之间逐字节相同。

公开压缩包包含 12 项便携测试。其余 8 项属于父项目集成，并非使用便携工具包所必需。发布记录在成功的宿主机结果旁同时标注 `guestTestExecuted: false`、`physicalHardwareTested: false` 和 `published: false`。

<!-- pagebreak -->

## 7. 验证路线：先 VM，后物理设备

### 7.1 完成参考 VM 实验

下一项有价值的里程碑，是使用单独获取的兼容驱动，在规定的 OSR2/UHCI 配置上完成整个存储套件。HID 未解决时，存储可以独立推进。操作员应记录驱动来源及版本、准备新的辅助介质，并在三个阶段中保留同一存储镜像。

必须通过拥有该 VM 的管理器选择候选安装。启动前确认现有合法授权磁盘、配置和可用测试名额。本项目环境只允许同时运行一个客户机或隔离测试会话。名额被占用是需要解决的操作前提，不是替换 Windows 版本或绕过生命周期管理的理由。

可审查结果必须将清单和程序关联到确切客户机，证明存储镜像通过 UHCI USB 连接，收集全部阶段与转换记录，并记载真实重启和冷启动。结束时须移除测试启动项，验证客户机及辅助进程清理。驱动／源文件提示或恢复操作必须明确报告。

### 7.2 独立解决并验证 HID

要得到有意义的鼠标／数位板通过结果，先要有兼容驱动栈。早先的 Win98 HID 回移实验暴露了尚未解决的内核／VxD 依赖，本预览版尚未因此获得已验证驱动。发布包不包含这些移植来源二进制或实验性的空操作兼容补丁。

后续驱动工作必须保留所需接口语义，并证明实际加载、枚举、输入交付，以及经历同样转换后的持续可用性。仅替换导入名称不是充分证据。首个成功结果应指明确切控制器、数位板型号、客户机构建号、驱动版本及剩余限制。

### 7.3 将方法用于实机

物理测试是未来扩展，并非已经备好的原始设备安装器。当前工具创建镜像文件，不负责制作实际 U 盘。硬件验证前，需要加入明确介质准备流程，并按实际控制器和驱动身份调整配置与检查器。如果机器不使用参考 NAT 子网，网络检查也需调整。

硬件记录应注明主板与 BIOS 设置、控制器 PCI ID、设备 VID/PID 和修订版、所经集线器、驱动版本、客户机构建号及介质身份。首先使用专用测试卷和可恢复的 OS 安装；测试 HID 时保留独立输入途径。

实机存储应重复标记、种子、写入／回读、重启和电源循环过程，并记录设备实际供电状态。计算机断电后，外部供电集线器或外设仍可能通电；这一差别影响结论。后续可加入热插拔、更大传输、长时间运行和更多设备。目前每阶段 64 KiB 的测试未测量这些能力。

兼容性矩阵应按实际观察到的配置逐项增长。模拟控制器与设备组合成功，只能支持 VM 特定结果；物理支持需要独立证据。

<!-- pagebreak -->

## 8. 复现与文档证据

### 8.1 最小存储实验

按照预览压缩包说明，使用现有合法授权的 OSR2 VM。此介质准备示例需要 Python 3.9+ 与 mtools。压缩包包含客户机程序；从源码重建还需要 i686 MinGW-w64 编译器及 POSIX Shell。

```sh
python3 prepare.py --out runs/storage-01 --suite storage \
  --storage-drive D --floppy
```

准备前选择客户机实际驱动器字母。通过 VM 管理器，将 `U95TEST.IMG` 作为只读软盘连接，将 `USBTEST.IMG` 以读写方式连接到 UHCI USB 存储设备。开始测试前，完成单独提供的驱动安装。随后在 Windows 内运行：

```text
A:\U95TEST.EXE /install
C:\U95TEST\U95TEST.EXE /run
```

按照 `docs/GUEST.TXT` 的三阶段流程操作，记录外部传输路径与生命周期证据。最终关机后，使用管理器已有传输方法或只读离线提取收集 `C:\U95TEST`。在宿主机上评估：

```sh
python3 check.py --run runs/storage-01 --evidence collected/U95TEST
```

使用 `--suite input` 进行 HID 诊断；两条路径都可用时使用 `--suite all`；添加 `--network` 启用 PCnet／DNS／HTTP 检查。报告模板见 `docs/TEST_REPORT.md`。检查器成功退出仍需第 5 节所述外部审查。

### 8.2 产物身份

本文描述 `win95-usb-lab-0.1.0-preview.1.zip`。

**发布 ZIP 的 SHA-256**

```text
5a197c390a5e1f7ee3ead7b750f902ff5f52b06f4bd5e28fe9ac8131ee3a1dfb
```

**客户机程序的 SHA-256**

```text
850a14b012f09fd1a05ff4110e1207a7aa9449b14ae8cceca5cd6815423de728
```

白皮书配套文件夹包含从本地发布证据复制的 `validation.json` 和 `import-audit.json`。源码依据是指定压缩包，特别是 `guest/probe.c`、`guest/storage.h`、`prepare.py`、`review.py`、`audit.py`、`package.py` 及 `profiles/qemu-osr2.json`。白皮书作为独立文档产物，不修改已标识的发布压缩包。

### 8.3 外部参考

- Conner McCoy 与 Rudolph Loew。[XUSBSUPP：Windows 95 OSR2 扩展 USB 补充包](https://msfn.org/board/topic/177518-xusbsupp-extended-usb-supplement-for-windows-95-osr2/)。作者软件包文档，2014 年。
- QEMU 项目。[USB 模拟](https://www.qemu.org/docs/master/system/devices/usb.html)。官方系统模拟文档。
- Microsoft。[CM_Get_DevNode_Status](https://learn.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_devnode_status)。API 状态与问题码语义。
- Microsoft。[ExitWindowsEx](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-exitwindowsex)。关机请求语义。

外部资料查阅日期为 2026 年 9 月 13 日。它们提供背景和 API 说明；项目自身的验证结论来自上述记录产物。
