【发布时间】:2020-01-19 03:45:02
【问题描述】:
我正在尝试将我的 QEMU VM 桥接到我的 Windows 10 主机中的本地适配器,但 QEMU 抱怨无法打开由 ifname 选项提供的接口名称 -netdev 参数。我已按照https://superuser.com/questions/1317652/how-to-set-up-nat-for-qemu-with-tap-backend-windows-10 中的答案进行操作,但没有运气。我已经从源代码交叉编译了 QEMU 来调试这种行为,是否可以检测到接口名称,显然 QEMU 可以找到适配器的名称,但不能找到 TAP 设备文件。为了进一步解释我的观点,这里是来自 QEMU 4.2.0 源代码(撰写本文时的最新版本)的net/tap-win32.c:595 的代码 sn-p,特别是 tap_win32_open 函数,我将强调它在此失败的地方函数(寻找// THIS IS WHERE IT WILL FAIL. cmets):
- 使用正确的现有网络接口进行测试:
static int tap_win32_open(tap_win32_overlapped_t **phandle,
const char *preferred_name)
{
...
rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer));
if (rc)
return -1;
snprintf (device_path, sizeof(device_path), "%s%s%s",
USERMODEDEVICEDIR,
device_guid,
TAPSUFFIX);
handle = CreateFile (
device_path,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
0 );
if (handle == INVALID_HANDLE_VALUE) {
return -1; // THIS IS WHERE IT WILL FAIL.
}
...
- 使用不正确(不存在)的网络接口进行测试:
static int tap_win32_open(tap_win32_overlapped_t **phandle,
const char *preferred_name)
{
...
rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer));
if (rc)
return -1; // THIS IS WHERE IT WILL FAIL.
snprintf (device_path, sizeof(device_path), "%s%s%s",
USERMODEDEVICEDIR,
device_guid,
TAPSUFFIX);
handle = CreateFile (
device_path,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
0 );
if (handle == INVALID_HANDLE_VALUE) {
return -1;
}
...
QEMU 使用前缀USERMODEDEVICEDIR,即\\.\Global\ 和设备GUID 的后缀.tap 在Windows 中创建设备路径。例如,我正在处理的网络适配器导致以下设备路径:\\.\Global\{990DA322-3986-4854-AE93-1D6FB0BFA137}.tap。知道为什么CreateFile 总是在设备路径上产生INVALID_HANDLE_VALUE 吗?顺便说一句,GetLastError() 返回2,从docs.microsoft.com 的含义如下:
...
ERROR_FILE_NOT_FOUND
2 (0x2)
The system cannot find the file specified.
...
【问题讨论】:
-
尝试使用WinObjEx64查看设备是否真的存在
-
如果您使用 ASCII 版本 API
CreateFileA,请确保传递给CreateFile的路径为"\\\\.\\Global\\{990DA322-3986-4854-AE93-1D6FB0BFA137}.tap"。如果您使用 unicode 版本 APICreateFileW,则传递L"\\\\.\\Global\\{990DA322-3986-4854-AE93-1D6FB0BFA137}.tap"。
标签: winapi cross-compiling device qemu file-not-found