VirtualBox

Ignore:
Timestamp:
Dec 2, 2015 4:57:40 PM (9 years ago)
Author:
vboxsync
Message:

NetCfg/win: Retry creation of host-only adapter device if network connection not created properly (#7973)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp

    r58795 r58956  
    27642764    PVOID pQueueCallbackContext = NULL;
    27652765    DWORD ret = 0;
    2766     BOOL found = FALSE;
    27672766    BOOL registered = FALSE;
    27682767    BOOL destroyList = FALSE;
     
    27742773    LPWSTR lpszApp = NULL;
    27752774
    2776     do
    2777     {
     2775    for (int attempt = 0; attempt < 2; ++attempt)
     2776    {
     2777        BOOL found = FALSE;
    27782778        GUID netGuid;
    27792779        SP_DRVINFO_DATA DriverInfoData;
     
    30563056            SetErrBreak(("SetupDiOpenDevRegKey failed (0x%08X)", GetLastError()));
    30573057
    3058         SC_HANDLE hSCM = NULL;
    3059         SC_HANDLE hService = NULL;
    3060 
    3061         hSCM = OpenSCManager(NULL, NULL, GENERIC_READ);
    3062         if (hSCM)
    3063             hService = OpenService(hSCM, _T("NetSetupSvc"), GENERIC_READ);
    3064         else
    3065             NonStandardLogFlow(("OpenSCManager failed (0x%x)", GetLastError()));
    3066 
    30673058        /* Query the instance ID; on Windows 10, the registry key may take a short
    30683059         * while to appear. Microsoft recommends waiting for up to 5 seconds, but
    3069          * we want to be on the safe side, so let's wait for a minute.
     3060         * we want to be on the safe side, so let's wait for 20 seconds. Waiting
     3061         * longer is harmful as network setup service will shut down after a period
     3062         * of inactivity.
    30703063         */
    3071         for (int retries = 0; retries < 2 * 60; ++retries)
     3064        for (int retries = 0; retries < 2 * 20; ++retries)
    30723065        {
    30733066            cbSize = sizeof(pWCfgGuidString);
     
    30793072            else
    30803073                break;
    3081             /* Bail out as soon as NetSetupSvc has stopped. */
    3082             if (hService && retries > 10 && vboxNetCfgWinIsNetSetupStopped(hService))
    3083                 break;
    3084         }
    3085 
    3086         if (ret == ERROR_FILE_NOT_FOUND && hService)
    3087         {
    3088             NonStandardLogFlow(("Timed out while waiting for NetCfgInstanceId, trying to obtain INetCfg...\n"));
     3074        }
     3075
     3076        if (ret == ERROR_FILE_NOT_FOUND && attempt == 0)
     3077        {
    30893078            /*
    3090              * NetCfgInstanceId still is not there, let's try to nudge network
    3091              * configuration engine by obtaining INetCfg. The idea is to trigger
    3092              * NetSetupSvc start, which will re-enumerate devices, and we need to
    3093              * obtain INetCfg anyway later on. Note that we need to make sure
    3094              * NetSetupSvc has stopped before we attempt to obtain INetCfg.
     3079             * This is the first time we fail to obtain NetCfgInstanceId, let us
     3080             * retry it once. It is needed to handle the situation when network
     3081             * setup fails to recognize the arrival of our device node while it
     3082             * is busy removing another host-only interface, and it gets stuck
     3083             * with no matching network interface created for our device node.
     3084             * See @bugref{7973} for details.
    30953085             */
    3096             for (int retries = 0; retries < 60 && !vboxNetCfgWinIsNetSetupStopped(hService); ++retries)
    3097                 Sleep(1000);
    3098             HRESULT hr = VBoxNetCfgWinQueryINetCfg(&pNetCfg, TRUE, L"VirtualBox Host-Only Creation",
    3099                                                    30 * 1000, /* on Vista we often get 6to4svc.dll holding the lock, wait for 30 sec.  */
    3100                                                    &lpszApp);
    3101             if (hr != S_OK)
    3102                 NonStandardLogFlow(("VBoxNetCfgWinCreateHostOnlyNetworkInterface: failed to obtain INetCfg (0x%x)\n", hr));
    3103             for (int retries = 0; retries < 30; ++retries)
    3104             {
    3105                 /*
    3106                  * Once again, there is no point in checking for NetCfgInstanceId
    3107                  * while NetSetupSvc is down. Also if it is not enough to check once,
    3108                  * because it may take a while for NetSetupSvc to complete network
    3109                  * configuration changes.
    3110                  */
    3111                 if (vboxNetCfgWinIsNetSetupRunning(hService))
    3112                 {
    3113                     /* Retry querying NetCfgInstanceId */
    3114                     cbSize = sizeof(pWCfgGuidString);
    3115                     ret = RegQueryValueExW (hkey, L"NetCfgInstanceId", NULL,
    3116                                             &dwValueType, (LPBYTE) pWCfgGuidString, &cbSize);
    3117                     if (ret != ERROR_FILE_NOT_FOUND)
    3118                         break;
    3119                 }
    3120                 Sleep(1000);
    3121             }
    3122         }
    3123         if (hService)
    3124             CloseServiceHandle(hService);
    3125         else
    3126             NonStandardLogFlow(("OpenService failed (0x%x)\n", GetLastError()));
    3127         if (hSCM)
    3128             CloseServiceHandle(hSCM);
     3086            NonStandardLogFlow(("Timed out while waiting for NetCfgInstanceId, remove the device and try again...\n"));
     3087            if (hkey != INVALID_HANDLE_VALUE)
     3088            {
     3089                RegCloseKey (hkey);
     3090                hkey = (HKEY)INVALID_HANDLE_VALUE;
     3091            }
     3092            if (pQueueCallbackContext)
     3093            {
     3094                SetupTermDefaultQueueCallback(pQueueCallbackContext);
     3095                pQueueCallbackContext = NULL;
     3096            }
     3097            SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
     3098            SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData);
     3099            SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData,
     3100                                         SPDIT_CLASSDRIVER);
     3101            SetupDiDestroyDeviceInfoList(hDeviceInfo);
     3102            destroyList = FALSE;
     3103            registered = FALSE;
     3104            continue;
     3105        }
    31293106
    31303107        if (ret != ERROR_SUCCESS)
     
    31693146                          GetLastError()));
    31703147#endif /* !VBOXNETCFG_DELAYEDRENAME */
    3171     }
    3172     while (0);
     3148
     3149        /* Success, don't need another attempt */
     3150        break;
     3151    }
    31733152
    31743153    /*
     
    31873166            SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData);
    31883167
    3189         found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData);
     3168        SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData);
    31903169
    31913170        /* destroy the driver info list */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette