windows 上面虚拟网卡(vNIC)安装时会自动配置 “SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e972-e325-11ce-bfc1-08002be10318}” 注册类,但具体安装在这个注册类哪一项没有明确的值(不是一个固定值,每次安装驱动到操作系统都会不同),所以想要获取其的注册项,只有采取枚举注册项的办法来实现,NetCfgInstanceId 子项代表了配置的网卡实例编号,我们需要在 windows 上访问 tuntap 的网卡的话就必须要拿到这个设备实例的 GUID。
const char* GetComponentId()
{
char szOwnerKeyPath[] = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e972-e325-11ce-bfc1-08002be10318}";
HKEY hOwnerKey = NULL; // {4d36e972-e325-11ce-bfc1-08002be10318}:类别:NSIS网卡驱动
char* szDevComponentId = NULL;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, szOwnerKeyPath, 0, KEY_ALL_ACCESS, &hOwnerKey) == ERROR_SUCCESS)
{
char szClassName[MAX_PATH];
DWORD dwIndex = 0;
while (szDevComponentId == NULL && RegEnumKeyA(hOwnerKey, dwIndex++, szClassName, MAX_PATH) == ERROR_SUCCESS)
{
BYTE data[MAX_PATH];
DWORD dwRegType = REG_NONE;
DWORD dwSize = sizeof(data);
HKEY hSubKey = NULL;
char szSubKeyPath[MAX_PATH];
sprintf(szSubKeyPath, "%s\\%s", szOwnerKeyPath, szClassName);
if (RegOpenKeyA(HKEY_LOCAL_MACHINE, szSubKeyPath, &hSubKey) != ERROR_SUCCESS)
{
continue;
}
if (RegQueryValueExA(hSubKey, "ComponentId", NULL, &dwRegType, data, &dwSize) == ERROR_SUCCESS && dwRegType == REG_SZ)
{
dwSize = sizeof(data);
if (strcmp("tap0901", (char*)data) == 0 && RegQueryValueExA(hSubKey, "NetCfgInstanceId", NULL,
&dwRegType, data, &dwSize) == ERROR_SUCCESS && dwRegType == REG_SZ)
{
szDevComponentId = (char*)memcpy(__malloc(dwSize), data, dwSize);
}
}
RegCloseKey(hSubKey);
}
RegCloseKey(hOwnerKey);
}
return szDevComponentId;
}