From 89db56acbc607f13746b5a46fef59a5108764ba5 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Fri, 18 Feb 2022 17:18:34 +0000 Subject: [PATCH] [net] add fallback to InternetGetConnectedState() when INetworkListManager service dependencies are missing * INetworkListManager appears to depend on specific services to be able to work, which one can actually disable while still getting full Internet connectivity. * If that is the case, HRESULT_FROM_WIN32(ERROR_SERVICE_DEPENDENCY_FAIL) will be returned, therefore we add a fallback to using InternetGetConnectedState(), which does not have such dependencies (but has other limitations per b2492908bee869932e0707ccdd85a2b3e6a2b982) when we detect a dependency error. * Also take this opportunity to switch to using INetworkListManager::get_IsConnectedToInternet(). * Also fix Coverity breakage due to Synopsys having upgraded their toolchain. * Closes #1801 --- .github/workflows/coverity.yml | 4 +++- src/net.c | 21 +++++++++++++++++---- src/rufus.rc | 10 +++++----- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 91600e51..b9010753 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -49,7 +49,9 @@ jobs: msbuild-architecture: x64 - name: Build with Coverity - run: cov-build.exe --dir cov-int msbuild ${{ env.SOLUTION_FILE_PATH }} /m /p:Configuration=${{ env.BUILD_CONFIGURATION }},Platform=${{ env.TARGET_PLATFORM }} + run: | + cov-configure --msvc + cov-build.exe --dir cov-int msbuild ${{ env.SOLUTION_FILE_PATH }} /m /p:Configuration=${{ env.BUILD_CONFIGURATION }},Platform=${{ env.TARGET_PLATFORM }} - name: Publish Coverity artifacts uses: actions/upload-artifact@v2 diff --git a/src/net.c b/src/net.c index ee7a71a4..508a62ea 100644 --- a/src/net.c +++ b/src/net.c @@ -57,6 +57,10 @@ static DWORD error_code, fido_len = 0; static BOOL force_update_check = FALSE; static const char* request_headers = "Accept-Encoding: gzip, deflate"; +#if defined(__MINGW32__) +#define INetworkListManager_get_IsConnectedToInternet INetworkListManager_IsConnectedToInternet +#endif + /* * FormatMessage does not handle internet errors * https://docs.microsoft.com/en-us/windows/desktop/wininet/wininet-errors @@ -267,16 +271,18 @@ static HINTERNET GetInternetSession(BOOL bRetry) int i; char agent[64]; BOOL decodingSupport = TRUE; - DWORD dwTimeout = NET_SESSION_TIMEOUT, dwProtocolSupport = HTTP_PROTOCOL_FLAG_HTTP2; + VARIANT_BOOL InternetConnection = VARIANT_FALSE; + DWORD dwFlags, dwTimeout = NET_SESSION_TIMEOUT, dwProtocolSupport = HTTP_PROTOCOL_FLAG_HTTP2; HINTERNET hSession = NULL; HRESULT hr = S_FALSE; INetworkListManager* pNetworkListManager; - NLM_CONNECTIVITY Connectivity = NLM_CONNECTIVITY_DISCONNECTED; PF_TYPE_DECL(WINAPI, HINTERNET, InternetOpenA, (LPCSTR, DWORD, LPCSTR, LPCSTR, DWORD)); PF_TYPE_DECL(WINAPI, BOOL, InternetSetOptionA, (HINTERNET, DWORD, LPVOID, DWORD)); + PF_TYPE_DECL(WINAPI, BOOL, InternetGetConnectedState, (LPDWORD, DWORD)); PF_INIT_OR_OUT(InternetOpenA, WinInet); PF_INIT_OR_OUT(InternetSetOptionA, WinInet); + PF_INIT(InternetGetConnectedState, WinInet); // Create a NetworkListManager Instance to check the network connection IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)); @@ -284,13 +290,20 @@ static HINTERNET GetInternetSession(BOOL bRetry) &IID_INetworkListManager, (LPVOID*)&pNetworkListManager); if (hr == S_OK) { for (i = 0; i <= WRITE_RETRIES; i++) { - hr = INetworkListManager_GetConnectivity(pNetworkListManager, &Connectivity); + hr = INetworkListManager_get_IsConnectedToInternet(pNetworkListManager, &InternetConnection); + // INetworkListManager may fail with ERROR_SERVICE_DEPENDENCY_FAIL if the DHCP service + // is not running, in which case we must fall back to using InternetGetConnectedState(). + // See https://github.com/pbatard/rufus/issues/1801. + if ((hr == HRESULT_FROM_WIN32(ERROR_SERVICE_DEPENDENCY_FAIL)) && (pfInternetGetConnectedState != NULL)) { + InternetConnection = pfInternetGetConnectedState(&dwFlags, 0) ? VARIANT_TRUE : VARIANT_FALSE; + break; + } if (hr == S_OK || !bRetry) break; Sleep(1000); } } - if (Connectivity == NLM_CONNECTIVITY_DISCONNECTED) { + if (InternetConnection == VARIANT_FALSE) { SetLastError(ERROR_INTERNET_DISCONNECTED); goto out; } diff --git a/src/rufus.rc b/src/rufus.rc index 920f5467..3ae8ba27 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.18.1871" +CAPTION "Rufus 3.18.1872" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -395,8 +395,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,18,1871,0 - PRODUCTVERSION 3,18,1871,0 + FILEVERSION 3,18,1872,0 + PRODUCTVERSION 3,18,1872,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -414,13 +414,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.18.1871" + VALUE "FileVersion", "3.18.1872" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2022 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.18.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.18.1871" + VALUE "ProductVersion", "3.18.1872" END END BLOCK "VarFileInfo"