Changeset 58794 in vbox for trunk/src/VBox/HostDrivers/VBoxNetFlt/win/cfg
- Timestamp:
- Nov 20, 2015 1:14:13 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp
r57639 r58794 35 35 #include <Wbemidl.h> 36 36 #include <comdef.h> 37 #ifdef VBOXNETCFG_DELAYEDRENAME 38 #include <Ws2tcpip.h> 39 #endif /* VBOXNETCFG_DELAYEDRENAME */ 37 40 38 41 … … 448 451 if (SetupDiSetSelectedDevice(hDevInfo, pDev)) 449 452 { 453 #ifndef VBOXNETCFG_DELAYEDRENAME 450 454 /* Figure out NetCfgInstanceId. */ 451 455 HKEY hKey = SetupDiOpenDevRegKey(hDevInfo, … … 508 512 RegCloseKey(hKey); 509 513 } 514 #endif /* VBOXNETCFG_DELAYEDRENAME */ 510 515 511 516 if (SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, pDev)) … … 701 706 if (cCurId >= cPnPId) 702 707 { 703 NonStandardLogFlow(("!wcsnicmp(pCurId = (%S), pwszPnPId = (%S), cPnPId = (%d)) ", pCurId, pwszPnPId, cPnPId));708 NonStandardLogFlow(("!wcsnicmp(pCurId = (%S), pwszPnPId = (%S), cPnPId = (%d))\n", pCurId, pwszPnPId, cPnPId)); 704 709 705 710 pCurId += cCurId - cPnPId; … … 742 747 Pc.enmPcType = enmPcType; 743 748 Pc.hr = S_OK; 744 NonStandardLogFlow(("Calling VBoxNetCfgWinEnumNetDevices with lpszPnPId =(%S) and vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback ", lpszPnPId));749 NonStandardLogFlow(("Calling VBoxNetCfgWinEnumNetDevices with lpszPnPId =(%S) and vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback\n", lpszPnPId)); 745 750 746 751 HRESULT hr = VBoxNetCfgWinEnumNetDevices(lpszPnPId, vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback, &Pc); … … 1705 1710 VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableStaticIpConfig(IN const GUID *pGuid, IN ULONG ip, IN ULONG mask) 1706 1711 { 1707 NonStandardLogFlow(("VBoxNetCfgWinEnableStaticIpConfig: ip=0x%x mask=0x%x ", ip, mask));1712 NonStandardLogFlow(("VBoxNetCfgWinEnableStaticIpConfig: ip=0x%x mask=0x%x\n", ip, mask)); 1708 1713 ComPtr<IWbemServices> pSvc; 1709 1714 HRESULT hr = netIfWinCreateIWbemServices(pSvc.asOutParam()); … … 1752 1757 } 1753 1758 1754 NonStandardLogFlow(("VBoxNetCfgWinEnableStaticIpConfig: returns 0x%x ", hr));1759 NonStandardLogFlow(("VBoxNetCfgWinEnableStaticIpConfig: returns 0x%x\n", hr)); 1755 1760 return hr; 1756 1761 } … … 1887 1892 } 1888 1893 1894 #ifdef VBOXNETCFG_DELAYEDRENAME 1895 static const char *vboxNetCfgWinAddrToStr(char *pszBuf, LPSOCKADDR pAddr) 1896 { 1897 switch (pAddr->sa_family) 1898 { 1899 case AF_INET: 1900 sprintf(pszBuf, "%d.%d.%d.%d", 1901 ((PSOCKADDR_IN)pAddr)->sin_addr.S_un.S_un_b.s_b1, 1902 ((PSOCKADDR_IN)pAddr)->sin_addr.S_un.S_un_b.s_b2, 1903 ((PSOCKADDR_IN)pAddr)->sin_addr.S_un.S_un_b.s_b3, 1904 ((PSOCKADDR_IN)pAddr)->sin_addr.S_un.S_un_b.s_b4); 1905 break; 1906 case AF_INET6: 1907 sprintf(pszBuf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", 1908 ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[0], ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[1], 1909 ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[2], ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[3], 1910 ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[4], ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[5], 1911 ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[6], ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[7], 1912 ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[8], ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[9], 1913 ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[10], ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[11], 1914 ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[12], ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[13], 1915 ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[14], ((PSOCKADDR_IN6)pAddr)->sin6_addr.s6_addr[15]); 1916 break; 1917 default: 1918 strcpy(pszBuf, "unknown"); 1919 break; 1920 } 1921 return pszBuf; 1922 } 1923 #endif /* VBOXNETCFG_DELAYEDRENAME */ 1924 1889 1925 typedef bool (*PFNVBOXNETCFG_IPSETTINGS_CALLBACK) (ULONG ip, ULONG mask, PVOID pContext); 1890 1926 … … 1894 1930 for (pAdapter = pAddresses; pAdapter; pAdapter = pAdapter->Next) 1895 1931 { 1896 PIP_ADAPTER_UNICAST_ADDRESS pAddr = pAdapter->FirstUnicastAddress; 1897 PIP_ADAPTER_PREFIX pPrefix = pAdapter->FirstPrefix; 1898 1899 if (pAddr && pPrefix) 1900 { 1901 do 1902 { 1903 bool fIPFound, fMaskFound; 1904 fIPFound = fMaskFound = false; 1905 ULONG ip, mask; 1906 for (; pAddr && !fIPFound; pAddr = pAddr->Next) 1907 { 1908 switch (pAddr->Address.lpSockaddr->sa_family) 1909 { 1910 case AF_INET: 1911 fIPFound = true; 1912 memcpy(&ip, 1913 &((struct sockaddr_in *)pAddr->Address.lpSockaddr)->sin_addr.s_addr, 1914 sizeof(ip)); 1915 break; 1916 // case AF_INET6: 1917 // break; 1918 } 1919 } 1920 1921 for (; pPrefix && !fMaskFound; pPrefix = pPrefix->Next) 1922 { 1923 switch (pPrefix->Address.lpSockaddr->sa_family) 1924 { 1925 case AF_INET: 1926 if (!pPrefix->PrefixLength || pPrefix->PrefixLength > 31) /* in case the ip helper API is queried while NetCfg write lock is held */ 1927 break; /* the address values can contain illegal values */ 1928 fMaskFound = true; 1929 mask = (~(((ULONG)~0) >> pPrefix->PrefixLength)); 1930 mask = htonl(mask); 1931 break; 1932 // case AF_INET6: 1933 // break; 1934 } 1935 } 1936 1937 if (!fIPFound || !fMaskFound) 1938 break; 1939 1940 if (!pfnCallback(ip, mask, pContext)) 1941 return; 1942 } while (true); 1932 char szBuf[80]; 1933 1934 NonStandardLogFlow(("+- Enumerating adapter '%ls' %s\n", pAdapter->FriendlyName, pAdapter->AdapterName)); 1935 for (PIP_ADAPTER_PREFIX pPrefix = pAdapter->FirstPrefix; pPrefix; pPrefix = pPrefix->Next) 1936 { 1937 const char *pcszAddress = vboxNetCfgWinAddrToStr(szBuf, pPrefix->Address.lpSockaddr); 1938 /* We are concerned with IPv4 only, ignore the rest. */ 1939 if (pPrefix->Address.lpSockaddr->sa_family != AF_INET) 1940 { 1941 NonStandardLogFlow(("| +- %s %d: not IPv4, ignoring\n", pcszAddress, pPrefix->PrefixLength)); 1942 continue; 1943 } 1944 /* Ignore invalid prefixes as well as host addresses. */ 1945 if (pPrefix->PrefixLength < 1 || pPrefix->PrefixLength > 31) 1946 { 1947 NonStandardLogFlow(("| +- %s %d: host or broadcast, ignoring\n", pcszAddress, pPrefix->PrefixLength)); 1948 continue; 1949 } 1950 /* Ignore multicast and beyond. */ 1951 ULONG ip = ((struct sockaddr_in *)pPrefix->Address.lpSockaddr)->sin_addr.s_addr; 1952 if ((ip & 0xF0) > 224) 1953 { 1954 NonStandardLogFlow(("| +- %s %d: multicast, ignoring\n", pcszAddress, pPrefix->PrefixLength)); 1955 continue; 1956 } 1957 ULONG mask = htonl((~(((ULONG)~0) >> pPrefix->PrefixLength))); 1958 bool fContinue = pfnCallback(ip, mask, pContext); 1959 if (!fContinue) 1960 { 1961 NonStandardLogFlow(("| +- %s %d: CONFLICT!\n", pcszAddress, pPrefix->PrefixLength)); 1962 return; 1963 } 1964 else 1965 NonStandardLogFlow(("| +- %s %d: no conflict, moving on\n", pcszAddress, pPrefix->PrefixLength)); 1943 1966 } 1944 1967 } … … 1976 1999 HRESULT hr = S_OK; 1977 2000 /* 1978 * Most of the hosts probably have less than 10 adapters, 1979 * so we'll mostly succeed from the first attempt. 2001 * MSDN recommends to pre-allocate a 15KB buffer. 1980 2002 */ 1981 ULONG uBufLen = sizeof(IP_ADAPTER_ADDRESSES) * 10;2003 ULONG uBufLen = 15 * 1024; 1982 2004 PIP_ADAPTER_ADDRESSES pAddresses = (PIP_ADAPTER_ADDRESSES)malloc(uBufLen); 1983 2005 if (!pAddresses) … … 2006 2028 ULONG ipProbe = rand()*255/RAND_MAX; 2007 2029 ipProbe = ip192168 | (ipProbe << 16); 2030 unsigned char *a = (unsigned char *)&ipProbe; 2031 NonStandardLogFlow(("probing %d.%d.%d.%d\n", a[0], a[1], a[2], a[3])); 2008 2032 IPPROBE_INIT(&Context, ipProbe); 2009 2033 vboxNetCfgWinEnumIpConfig(pAddresses, vboxNetCfgWinIpProbeCallback, &Context); 2010 2034 if (!Context.bConflict) 2011 2035 { 2036 NonStandardLogFlow(("found unused net %d.%d.%d.%d\n", a[0], a[1], a[2], a[3])); 2012 2037 *pNetIp = ipProbe; 2013 2038 *pNetMask = inet_addr("255.255.255.0"); … … 2472 2497 } 2473 2498 2499 static const char *vboxNetCfgWinGetStateText(DWORD dwState) 2500 { 2501 switch (dwState) 2502 { 2503 case SERVICE_STOPPED: return "is not running"; 2504 case SERVICE_STOP_PENDING: return "is stopping"; 2505 case SERVICE_CONTINUE_PENDING: return "continue is pending"; 2506 case SERVICE_PAUSE_PENDING: return "pause is pending"; 2507 case SERVICE_PAUSED: return "is paused"; 2508 case SERVICE_RUNNING: return "is running"; 2509 case SERVICE_START_PENDING: return "is starting"; 2510 } 2511 return "state is invalid"; 2512 } 2513 2514 static DWORD vboxNetCfgWinGetNetSetupState(SC_HANDLE hService) 2515 { 2516 SERVICE_STATUS status; 2517 status.dwCurrentState = SERVICE_RUNNING; 2518 if (hService) { 2519 if (QueryServiceStatus(hService, &status)) 2520 NonStandardLogFlow(("NetSetupSvc %s\n", vboxNetCfgWinGetStateText(status.dwCurrentState))); 2521 else 2522 NonStandardLogFlow(("QueryServiceStatus failed (0x%x)\n", GetLastError())); 2523 } 2524 return status.dwCurrentState; 2525 } 2526 2527 DECLINLINE(bool) vboxNetCfgWinIsNetSetupRunning(SC_HANDLE hService) 2528 { 2529 return vboxNetCfgWinGetNetSetupState(hService) == SERVICE_RUNNING; 2530 } 2531 2532 DECLINLINE(bool) vboxNetCfgWinIsNetSetupStopped(SC_HANDLE hService) 2533 { 2534 return vboxNetCfgWinGetNetSetupState(hService) == SERVICE_STOPPED; 2535 } 2536 2474 2537 #define DRIVERHWID _T("sun_VBoxNetAdp") 2475 2538 … … 2712 2775 HKEY hkey = (HKEY)INVALID_HANDLE_VALUE; 2713 2776 bstr_t bstrError; 2777 INetCfg *pNetCfg = NULL; 2778 LPWSTR lpszApp = NULL; 2714 2779 2715 2780 do … … 2995 3060 SetErrBreak(("SetupDiOpenDevRegKey failed (0x%08X)", GetLastError())); 2996 3061 3062 SC_HANDLE hSCM = NULL; 3063 SC_HANDLE hService = NULL; 3064 3065 hSCM = OpenSCManager(NULL, NULL, GENERIC_READ); 3066 if (hSCM) 3067 hService = OpenService(hSCM, _T("NetSetupSvc"), GENERIC_READ); 3068 else 3069 NonStandardLogFlow(("OpenSCManager failed (0x%x)", GetLastError())); 2997 3070 2998 3071 /* Query the instance ID; on Windows 10, the registry key may take a short 2999 * while to appear. Microsoft recommends waiting for up to 5 seconds. 3072 * while to appear. Microsoft recommends waiting for up to 5 seconds, but 3073 * we want to be on the safe side, so let's wait for a minute. 3000 3074 */ 3001 for (int retries = 0; retries < 5 * 5; ++retries)3075 for (int retries = 0; retries < 2 * 60; ++retries) 3002 3076 { 3003 3077 cbSize = sizeof(pWCfgGuidString); … … 3006 3080 /* As long as the return code is FILE_NOT_FOUND, sleep and retry. */ 3007 3081 if (ret == ERROR_FILE_NOT_FOUND) 3008 Sleep( 200); /* 1/5 of a second.*/3082 Sleep(500); /* half second */ 3009 3083 else 3010 3084 break; 3011 } 3085 /* Bail out as soon as NetSetupSvc has stopped. */ 3086 if (hService && retries > 10 && vboxNetCfgWinIsNetSetupStopped(hService)) 3087 break; 3088 } 3089 3090 if (ret == ERROR_FILE_NOT_FOUND && hService) 3091 { 3092 NonStandardLogFlow(("Timed out while waiting for NetCfgInstanceId, trying to obtain INetCfg...\n")); 3093 /* 3094 * NetCfgInstanceId still is not there, let's try to nudge network 3095 * configuration engine by obtaining INetCfg. The idea is to trigger 3096 * NetSetupSvc start, which will re-enumerate devices, and we need to 3097 * obtain INetCfg anyway later on. Note that we need to make sure 3098 * NetSetupSvc has stopped before we attempt to obtain INetCfg. 3099 */ 3100 for (int retries = 0; retries < 60 && !vboxNetCfgWinIsNetSetupStopped(hService); ++retries) 3101 Sleep(1000); 3102 HRESULT hr = VBoxNetCfgWinQueryINetCfg(&pNetCfg, TRUE, L"VirtualBox Host-Only Creation", 3103 30 * 1000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec. */ 3104 &lpszApp); 3105 if (hr != S_OK) 3106 NonStandardLogFlow(("VBoxNetCfgWinCreateHostOnlyNetworkInterface: failed to obtain INetCfg (0x%x)\n", hr)); 3107 for (int retries = 0; retries < 30; ++retries) 3108 { 3109 /* 3110 * Once again, there is no point in checking for NetCfgInstanceId 3111 * while NetSetupSvc is down. Also if it is not enough to check once, 3112 * because it may take a while for NetSetupSvc to complete network 3113 * configuration changes. 3114 */ 3115 if (vboxNetCfgWinIsNetSetupRunning(hService)) 3116 { 3117 /* Retry querying NetCfgInstanceId */ 3118 cbSize = sizeof(pWCfgGuidString); 3119 ret = RegQueryValueExW (hkey, L"NetCfgInstanceId", NULL, 3120 &dwValueType, (LPBYTE) pWCfgGuidString, &cbSize); 3121 if (ret != ERROR_FILE_NOT_FOUND) 3122 break; 3123 } 3124 Sleep(1000); 3125 } 3126 } 3127 if (hService) 3128 CloseServiceHandle(hService); 3129 else 3130 NonStandardLogFlow(("OpenService failed (0x%x)\n", GetLastError())); 3131 if (hSCM) 3132 CloseServiceHandle(hSCM); 3012 3133 3013 3134 if (ret != ERROR_SUCCESS) 3014 SetErrBreak(("Querying NetCfgInstanceId failed (0x%08X)", GetLastError())); 3015 3135 SetErrBreak(("Querying NetCfgInstanceId failed (0x%08X)", ret)); 3136 3137 #ifndef VBOXNETCFG_DELAYEDRENAME 3016 3138 /* 3017 3139 * We need to query the device name after we have succeeded in querying its … … 3045 3167 } 3046 3168 } 3169 #else /* !VBOXNETCFG_DELAYEDRENAME */ 3170 /* Re-use DevName for device instance id retrieval. */ 3171 if (!SetupDiGetDeviceInstanceId(hDeviceInfo, &DeviceInfoData, DevName, RT_ELEMENTS(DevName), &cbSize)) 3172 SetErrBreak (("SetupDiGetDeviceInstanceId failed (0x%08X)", 3173 GetLastError())); 3174 #endif /* !VBOXNETCFG_DELAYEDRENAME */ 3047 3175 } 3048 3176 while (0); … … 3076 3204 if (SUCCEEDED(hrc)) 3077 3205 { 3206 HRESULT hr; 3207 #ifndef VBOXNETCFG_DELAYEDRENAME 3078 3208 WCHAR ConnectionName[128]; 3079 3209 ULONG cbName = sizeof(ConnectionName); 3080 3210 3081 HRESULThr = VBoxNetCfgWinGenHostonlyConnectionName(DevName, ConnectionName, &cbName);3211 hr = VBoxNetCfgWinGenHostonlyConnectionName(DevName, ConnectionName, &cbName); 3082 3212 if (SUCCEEDED(hr)) 3083 3213 hr = VBoxNetCfgWinRenameConnection(pWCfgGuidString, ConnectionName); 3084 3214 #endif 3085 3215 if (lppszName) 3086 3216 { … … 3100 3230 } 3101 3231 3102 INetCfg *pNetCfg = NULL; 3103 LPWSTR lpszApp = NULL; 3104 hr = VBoxNetCfgWinQueryINetCfg(&pNetCfg, TRUE, L"VirtualBox Host-Only Creation", 3105 30 * 1000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec. */ 3106 /* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */ 3107 &lpszApp); 3232 /* Check if INetCfg has been queried already, query if it hasn't been. */ 3233 if (pNetCfg == NULL) 3234 hr = VBoxNetCfgWinQueryINetCfg(&pNetCfg, TRUE, L"VirtualBox Host-Only Creation", 3235 30 * 1000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec. */ 3236 /* TODO: special handling for 6to4svc.dll ???, i.e. several retrieves */ 3237 &lpszApp); 3238 else 3239 hr = S_OK; 3108 3240 if (hr == S_OK) 3109 3241 { … … 3148 3280 } 3149 3281 3282 #ifdef VBOXNETCFG_DELAYEDRENAME 3283 VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRenameHostOnlyConnection(IN const GUID *pGuid, IN LPCWSTR pwszId, OUT BSTR *pDevName) 3284 { 3285 HRESULT hr = S_OK; 3286 WCHAR wszDevName[256]; 3287 WCHAR wszConnectionNewName[128]; 3288 ULONG cbName = sizeof(wszConnectionNewName); 3289 3290 HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_NET, NULL); 3291 if (hDevInfo != INVALID_HANDLE_VALUE) 3292 { 3293 SP_DEVINFO_DATA DevInfoData; 3294 3295 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 3296 if (SetupDiOpenDeviceInfo(hDevInfo, pwszId, NULL, 0, &DevInfoData)) 3297 { 3298 if (SetupDiGetDeviceRegistryPropertyW(hDevInfo, &DevInfoData, 3299 SPDRP_FRIENDLYNAME, NULL, 3300 (PBYTE)wszDevName, RT_ELEMENTS(wszDevName), NULL)) 3301 { 3302 hr = VBoxNetCfgWinGenHostonlyConnectionName(wszDevName, wszConnectionNewName, &cbName); 3303 if (SUCCEEDED(hr)) 3304 { 3305 WCHAR wszGuid[50]; 3306 int cbWGuid = StringFromGUID2(*pGuid, wszGuid, RT_ELEMENTS(wszGuid)); 3307 if (cbWGuid) 3308 { 3309 hr = VBoxNetCfgWinRenameConnection(wszGuid, wszConnectionNewName); 3310 if (FAILED(hr)) 3311 NonStandardLogFlow(("NetIf: VBoxNetCfgWinRenameConnection failed (0x%x)\n", hr)); 3312 } 3313 else 3314 { 3315 DWORD winEr = GetLastError(); 3316 hr = HRESULT_FROM_WIN32(winEr); 3317 if (SUCCEEDED(hr)) 3318 hr = E_FAIL; 3319 NonStandardLogFlow(("StringFromGUID2 failed winEr=%u, hr=0x%x\n", winEr, hr)); 3320 } 3321 } 3322 else 3323 NonStandardLogFlow(("NetIf: VBoxNetCfgWinGenHostonlyConnectionName failed (0x%x)\n", hr)); 3324 if (SUCCEEDED(hr) && pDevName) 3325 { 3326 *pDevName = SysAllocString((const OLECHAR *)wszDevName); 3327 if (!*pDevName) 3328 { 3329 NonStandardLogFlow(("SysAllocString failed\n")); 3330 hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); 3331 } 3332 } 3333 } 3334 else 3335 { 3336 DWORD winEr = GetLastError(); 3337 hr = HRESULT_FROM_WIN32(winEr); 3338 NonStandardLogFlow(("NetIf: SetupDiGetDeviceRegistryPropertyW failed (0x%x)\n", winEr)); 3339 } 3340 } 3341 else 3342 { 3343 DWORD winEr = GetLastError(); 3344 hr = HRESULT_FROM_WIN32(winEr); 3345 NonStandardLogFlow(("NetIf: SetupDiOpenDeviceInfo failed (0x%x)\n", winEr)); 3346 } 3347 SetupDiDestroyDeviceInfoList(hDevInfo); 3348 } 3349 3350 return hr; 3351 } 3352 #endif /* VBOXNETCFG_DELAYEDRENAME */ 3353 3150 3354 #undef SetErrBreak 3151 3355
Note:
See TracChangeset
for help on using the changeset viewer.