VirtualBox

Ignore:
Timestamp:
Dec 7, 2015 8:32:39 AM (9 years ago)
Author:
vboxsync
Message:

NetCfg/win: Retry creation of host-only adapter twice for compatibility with different Win 10 builds (#7973)

File:
1 edited

Legend:

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

    r58956 r59014  
    24932493}
    24942494
    2495 static const char *vboxNetCfgWinGetStateText(DWORD dwState)
    2496 {
    2497     switch (dwState)
    2498     {
    2499         case SERVICE_STOPPED: return "is not running";
    2500         case SERVICE_STOP_PENDING: return "is stopping";
    2501         case SERVICE_CONTINUE_PENDING: return "continue is pending";
    2502         case SERVICE_PAUSE_PENDING: return "pause is pending";
    2503         case SERVICE_PAUSED: return "is paused";
    2504         case SERVICE_RUNNING: return "is running";
    2505         case SERVICE_START_PENDING: return "is starting";
    2506     }
    2507     return "state is invalid";
    2508 }
    2509 
    2510 static DWORD vboxNetCfgWinGetNetSetupState(SC_HANDLE hService)
    2511 {
    2512     SERVICE_STATUS status;
    2513     status.dwCurrentState = SERVICE_RUNNING;
    2514     if (hService) {
    2515         if (QueryServiceStatus(hService, &status))
    2516             NonStandardLogFlow(("NetSetupSvc %s\n", vboxNetCfgWinGetStateText(status.dwCurrentState)));
    2517         else
    2518             NonStandardLogFlow(("QueryServiceStatus failed (0x%x)\n", GetLastError()));
    2519     }
    2520     return status.dwCurrentState;
    2521 }
    2522 
    2523 DECLINLINE(bool) vboxNetCfgWinIsNetSetupRunning(SC_HANDLE hService)
    2524 {
    2525     return vboxNetCfgWinGetNetSetupState(hService) == SERVICE_RUNNING;
    2526 }
    2527 
    2528 DECLINLINE(bool) vboxNetCfgWinIsNetSetupStopped(SC_HANDLE hService)
    2529 {
    2530     return vboxNetCfgWinGetNetSetupState(hService) == SERVICE_STOPPED;
    2531 }
    2532 
    25332495#define DRIVERHWID _T("sun_VBoxNetAdp")
    25342496
     
    27552717}
    27562718
    2757 VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface(IN LPCWSTR pInfPath, IN bool bIsInfPathFile,
    2758                                                                         OUT GUID *pGuid, OUT BSTR *lppszName, OUT BSTR *pErrMsg)
     2719static const char *vboxNetCfgWinGetStateText(DWORD dwState)
     2720{
     2721    switch (dwState)
     2722    {
     2723        case SERVICE_STOPPED: return "is not running";
     2724        case SERVICE_STOP_PENDING: return "is stopping";
     2725        case SERVICE_CONTINUE_PENDING: return "continue is pending";
     2726        case SERVICE_PAUSE_PENDING: return "pause is pending";
     2727        case SERVICE_PAUSED: return "is paused";
     2728        case SERVICE_RUNNING: return "is running";
     2729        case SERVICE_START_PENDING: return "is starting";
     2730    }
     2731    return "state is invalid";
     2732}
     2733
     2734static DWORD vboxNetCfgWinGetNetSetupState(SC_HANDLE hService)
     2735{
     2736    SERVICE_STATUS status;
     2737    status.dwCurrentState = SERVICE_RUNNING;
     2738    if (hService) {
     2739        if (QueryServiceStatus(hService, &status))
     2740            NonStandardLogFlow(("NetSetupSvc %s\n", vboxNetCfgWinGetStateText(status.dwCurrentState)));
     2741        else
     2742            NonStandardLogFlow(("QueryServiceStatus failed (0x%x)\n", GetLastError()));
     2743    }
     2744    return status.dwCurrentState;
     2745}
     2746
     2747DECLINLINE(bool) vboxNetCfgWinIsNetSetupRunning(SC_HANDLE hService)
     2748{
     2749    return vboxNetCfgWinGetNetSetupState(hService) == SERVICE_RUNNING;
     2750}
     2751
     2752DECLINLINE(bool) vboxNetCfgWinIsNetSetupStopped(SC_HANDLE hService)
     2753{
     2754    return vboxNetCfgWinGetNetSetupState(hService) == SERVICE_STOPPED;
     2755}
     2756
     2757static HRESULT vboxNetCfgWinCreateHostOnlyNetworkInterface(IN LPCWSTR pInfPath, IN bool bIsInfPathFile,
     2758                                                           OUT GUID *pGuid, OUT BSTR *lppszName, OUT BSTR *pErrMsg)
    27592759{
    27602760    HRESULT hrc = S_OK;
     
    27732773    LPWSTR lpszApp = NULL;
    27742774
    2775     for (int attempt = 0; attempt < 2; ++attempt)
     2775    do
    27762776    {
    27772777        BOOL found = FALSE;
     
    30743074        }
    30753075
    3076         if (ret == ERROR_FILE_NOT_FOUND && attempt == 0)
    3077         {
    3078             /*
    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.
    3085              */
    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;
     3076        if (ret == ERROR_FILE_NOT_FOUND)
     3077        {
     3078            hrc = E_ABORT;
     3079            break;
    31053080        }
    31063081
     
    31463121                          GetLastError()));
    31473122#endif /* !VBOXNETCFG_DELAYEDRENAME */
    3148 
    3149         /* Success, don't need another attempt */
    3150         break;
    3151     }
     3123    }
     3124    while (0);
    31523125
    31533126    /*
     
    32523225        *pErrMsg = bstrError.Detach();
    32533226
     3227    return hrc;
     3228}
     3229
     3230VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface(IN LPCWSTR pInfPath, IN bool bIsInfPathFile,
     3231                                                                        OUT GUID *pGuid, OUT BSTR *lppszName, OUT BSTR *pErrMsg)
     3232{
     3233    HRESULT hrc = vboxNetCfgWinCreateHostOnlyNetworkInterface(pInfPath, bIsInfPathFile, pGuid, lppszName, pErrMsg);
     3234    if (hrc == E_ABORT)
     3235    {
     3236        NonStandardLogFlow(("Timed out while waiting for NetCfgInstanceId, try again immediately...\n"));
     3237        /*
     3238         * This is the first time we fail to obtain NetCfgInstanceId, let us
     3239         * retry it once. It is needed to handle the situation when network
     3240         * setup fails to recognize the arrival of our device node while it
     3241         * is busy removing another host-only interface, and it gets stuck
     3242         * with no matching network interface created for our device node.
     3243         * See @bugref{7973} for details.
     3244         */
     3245        hrc = vboxNetCfgWinCreateHostOnlyNetworkInterface(pInfPath, bIsInfPathFile, pGuid, lppszName, pErrMsg);
     3246        if (hrc == E_ABORT)
     3247        {
     3248            NonStandardLogFlow(("Timed out again while waiting for NetCfgInstanceId, try again after a while...\n"));
     3249            /*
     3250             * This is the second time we fail to obtain NetCfgInstanceId, let us
     3251             * retry it once more. This time we wait to network setup service
     3252             * to go down before retrying. Hopefully it will resolve all error
     3253             * conditions. See @bugref{7973} for details.
     3254             */
     3255
     3256            SC_HANDLE hSCM = NULL;
     3257            SC_HANDLE hService = NULL;
     3258
     3259            hSCM = OpenSCManager(NULL, NULL, GENERIC_READ);
     3260            if (hSCM)
     3261            {
     3262                hService = OpenService(hSCM, _T("NetSetupSvc"), GENERIC_READ);
     3263                if (hService)
     3264                {
     3265                    for (int retries = 0; retries < 60 && !vboxNetCfgWinIsNetSetupStopped(hService); ++retries)
     3266                        Sleep(1000);
     3267                    CloseServiceHandle(hService);
     3268                    hrc = vboxNetCfgWinCreateHostOnlyNetworkInterface(pInfPath, bIsInfPathFile, pGuid, lppszName, pErrMsg);
     3269                }
     3270                else
     3271                    NonStandardLogFlow(("OpenService failed (0x%x)\n", GetLastError()));
     3272                CloseServiceHandle(hSCM);
     3273            }
     3274            else
     3275                NonStandardLogFlow(("OpenSCManager failed (0x%x)", GetLastError()));
     3276            /* Give up and report the error. */
     3277            if (hrc == E_ABORT)
     3278            {
     3279                bstr_t bstrError = bstr_printf("Querying NetCfgInstanceId failed (0x%08X)", ERROR_FILE_NOT_FOUND);
     3280                *pErrMsg = bstrError.Detach();
     3281                hrc = E_FAIL;
     3282            }
     3283        }
     3284    }
    32543285    return hrc;
    32553286}
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