C++ 在 windows 下获取 tuntap 虚拟网卡的 ComponentId

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;
}

你可能感兴趣的:(C/C++)