VmWare服务VMUSBArbService 实现原理详解
2025-08-06
0
0
VMUSBArbService 的核心功能是 仲裁 USB 设备在主机和虚拟机之间的访问权,确保同一时间只有一个系统能控制 USB 设备。它的实现涉及 USB 设备重定向(USB Redirection) 和 虚拟化技术。
1. 架构与数据流
+---------------------+ +---------------------+ +---------------------+
| Host OS (Windows) | <---> | VMUSBArbService | <---> | Virtual Machine (VM) |
+---------------------+ | (仲裁服务) | +---------------------+
| +---------------------+ |
| | |
v v v
+---------------------+ +---------------------+ +---------------------+
| USB Device Stack | | Virtual USB Bus | | VM USB Controller |
| (主机USB驱动栈) | | (虚拟USB总线) | | (虚拟机USB控制器) |
+---------------------+ +---------------------+ +---------------------+
| | |
+------------------------------+----------------------------+
USB 设备数据流
关键组件说明:
- Host OS USB Stack
- 主机系统的 USB 驱动栈,负责检测和管理物理 USB 设备。
- VMUSBArbService
- 运行在主机上的服务,监听 USB 设备插拔事件,决定设备分配给主机还是虚拟机。
- Virtual USB Bus
- 虚拟化平台(如 Hyper-V、VMware)提供的虚拟 USB 总线,用于在主机和虚拟机之间传递 USB 数据。
- VM USB Controller
- 虚拟机内部的 USB 控制器,接收来自虚拟 USB 总线的数据,使虚拟机识别 USB 设备。
2. 核心工作流程
(1) USB 设备插入主机
- 主机 USB 驱动栈检测到设备,并加载驱动。
- VMUSBArbService 收到通知,检查是否有虚拟机请求该设备。
- 如果 无虚拟机请求,设备由主机独占。
- 如果 有虚拟机请求,进入仲裁流程。
(2) 设备仲裁(主机 vs 虚拟机)
- 主机优先模式:默认情况下,主机优先控制设备,除非手动分配给虚拟机。
- 虚拟机抢占模式:如果虚拟机请求设备,VMUSBArbService 会:
- 卸载主机驱动(防止冲突)。
- 将设备挂载到虚拟 USB 总线。
- 虚拟机识别设备,就像直接插在虚拟机上一样。
(3) 设备释放(虚拟机 → 主机)
- 当虚拟机释放设备(如安全弹出),VMUSBArbService 会:
- 从虚拟机卸载设备。
- 重新挂载到主机 USB 栈,主机重新识别设备。
3. 关键技术点
(1) USB 设备重定向(USB Redirection)
- 方法1:USB over IP(如 VMware USB Arbitrator)
- 设备数据通过 TCP/IP 传输到虚拟机(适用于远程虚拟机)。
- 方法2:虚拟 USB 总线(Virtual USB Bus)
- Hyper-V / VMware 提供的虚拟通道,直接映射 USB 设备到虚拟机。
(2) 设备劫持(Device Hijacking)
- 在主机上卸载 USB 驱动,防止主机和虚拟机同时访问设备。
- 使用 libusb 或 WinUSB 进行底层控制(避免系统自动加载驱动)。
(3) 事件监听(Plug & Play 事件)
- 使用 Windows RegisterDeviceNotification API 监听 USB 设备插拔。
- 使用 WMI (Windows Management Instrumentation) 监控设备状态。
4. 自己如何实现类似功能?
(1) 开发环境
- 语言:C/C++(Windows 驱动开发)或 C#(WMI 监听)。
- 工具:
- Windows Driver Kit (WDK) – 用于 USB 驱动劫持。
- LibUSB/WinUSB – 直接控制 USB 设备。
- VirtualBox/Hyper-V API – 实现虚拟 USB 总线。
(2) 关键代码示例(C++)
① 监听 USB 设备插拔(WMI)
#include <windows.h>
#include <wmiutils.h>
#include <iostream>
// 监听 USB 设备插拔事件
void MonitorUSBEvents() {
HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
IWbemLocator* pLoc = NULL;
hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
// 连接到 WMI
IWbemServices* pSvc = NULL;
hr = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
// 注册事件查询
IWbemObjectSink* pSink = new EventSink(); // 自定义事件接收器
hr = pSvc->ExecNotificationQueryAsync(
_bstr_t("WQL"),
_bstr_t("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2 OR EventType = 3"),
WBEM_FLAG_SEND_STATUS, NULL, pSink);
// 等待事件
Sleep(INFINITE);
pSvc->CancelAsyncCall(pSink);
pLoc->Release();
CoUninitialize();
}
② 卸载主机 USB 驱动(设备劫持)
#include <windows.h>
#include <setupapi.h>
#include <cfgmgr32.h>
bool UnloadUSBDriver(const char* deviceId) {
DEVINST devInst;
if (CM_Locate_DevNodeA(&devInst, (DEVINSTID_A)deviceId, CM_LOCATE_DEVNODE_NORMAL) != CR_SUCCESS) {
return false;
}
return CM_Request_Device_Eject(devInst, NULL, NULL, 0, 0) == CR_SUCCESS;
}
③ 虚拟 USB 总线(模拟 Hyper-V 虚拟 USB)
- 可使用 USB/IP 开源项目(如
usbip-win
)或 VirtualBox API 实现虚拟 USB 通道。
5. 优化与扩展
- 动态策略:允许用户自定义仲裁策略(如“自动分配给最后一个使用的系统”)。
- USB 透传(Passthrough):让虚拟机直接接管 USB 控制器(类似 PCIe 直通)。
- 远程 USB:通过网络共享 USB 设备(类似 USB over Network)。
总结
关键点 | 实现方式 |
---|---|
设备检测 | WMI / RegisterDeviceNotification |
设备劫持 | CM_Request_Device_Eject / LibUSB |
虚拟化通道 | USB/IP / Hyper-V Virtual USB |
仲裁策略 | 优先级队列 / 用户配置 |
如果要开发类似功能,建议先研究 libusb 和 USB/IP,再结合虚拟化平台 API(如 Hyper-V)实现完整方案。
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936