From 9b3c11122b3bacccac95cea0ff33235d48d48f36 Mon Sep 17 00:00:00 2001 From: Mohmed abdel-fattah Date: Sat, 13 Jul 2024 17:43:40 +0100 Subject: [PATCH] [misc] reinstate delay-loading of wininet and virtdisk DLLs * Per #2272 and #1877, MinGW has issues when delay loading libraries, but it is possible to apply a workaround to alleviate them, by redefining DECLSPEC_IMPORT before including the corresponding headers. * This is a bit more tricky to accomplish for virtdisk, as MinGW's windows.h header does include virtdisk.h on its own (rather than expect a formal include as MSVC does), so we have to prevent the virtdisk.h inclusion first, by defining a macro, and then apply our workaround. * Per https://sourceforge.net/p/mingw-w64/mailman/mingw-w64-public/thread/ea87573f-65ea-44a2-b4bb-ca96c0a136ab%40akeo.ie/#msg58793876 we are hoping that this should be a temporary workaround and that the root cause of the issue will be fixed in binutils. * Closes #2513. --- .mingw/Makefile.am | 2 +- .mingw/Makefile.in | 2 +- .mingw/virtdisk.def | 8 +++ .mingw/wininet.def | 12 ++++ .vs/rufus.vcxproj | 32 +++++----- src/Makefile.am | 4 +- src/Makefile.in | 4 +- src/net.c | 139 ++++++++++++++------------------------------ src/process.c | 2 +- src/rufus.rc | 10 ++-- src/vhd.c | 55 ++++++------------ src/vhd.h | 6 ++ 12 files changed, 117 insertions(+), 159 deletions(-) create mode 100644 .mingw/virtdisk.def create mode 100644 .mingw/wininet.def diff --git a/.mingw/Makefile.am b/.mingw/Makefile.am index cb131d61..ec826d27 100644 --- a/.mingw/Makefile.am +++ b/.mingw/Makefile.am @@ -19,7 +19,7 @@ TARGET := $(word 1,$(subst -, ,$(TUPLE))) DEF_SUFFIX := $(if $(TARGET:x86_64=),.def,.def64) .PHONY: all -all: dwmapi-delaylib.lib version-delaylib.lib wintrust-delaylib.lib +all: dwmapi-delaylib.lib version-delaylib.lib virtdisk-delaylib.lib wininet-delaylib.lib wintrust-delaylib.lib %.def64: %.def $(AM_V_SED) "s/@.*//" $< >$@ diff --git a/.mingw/Makefile.in b/.mingw/Makefile.in index 0dda8fb1..117eb9c4 100644 --- a/.mingw/Makefile.in +++ b/.mingw/Makefile.in @@ -367,7 +367,7 @@ uninstall-am: .PHONY: all -all: dwmapi-delaylib.lib version-delaylib.lib wintrust-delaylib.lib +all: dwmapi-delaylib.lib version-delaylib.lib virtdisk-delaylib.lib wininet-delaylib.lib wintrust-delaylib.lib %.def64: %.def $(AM_V_SED) "s/@.*//" $< >$@ diff --git a/.mingw/virtdisk.def b/.mingw/virtdisk.def new file mode 100644 index 00000000..7fafde83 --- /dev/null +++ b/.mingw/virtdisk.def @@ -0,0 +1,8 @@ +EXPORTS + AttachVirtualDisk@24 + CreateVirtualDisk@36 + DetachVirtualDisk@12 + GetVirtualDiskInformation@16 + GetVirtualDiskPhysicalPath@12 + GetVirtualDiskOperationProgress@12 + OpenVirtualDisk@24 diff --git a/.mingw/wininet.def b/.mingw/wininet.def new file mode 100644 index 00000000..c1ca40d0 --- /dev/null +++ b/.mingw/wininet.def @@ -0,0 +1,12 @@ +EXPORTS + HttpQueryInfoA@20 + HttpOpenRequestA@32 + HttpSendRequestA@20 + InternetCloseHandle@4 + InternetConnectA@32 + InternetCrackUrlA@16 + InternetGetConnectedState@8 + InternetGetLastResponseInfoA@12 + InternetOpenA@20 + InternetReadFile@16 + InternetSetOptionA@16 diff --git a/.vs/rufus.vcxproj b/.vs/rufus.vcxproj index 7266623b..8c9b40f9 100644 --- a/.vs/rufus.vcxproj +++ b/.vs/rufus.vcxproj @@ -133,12 +133,12 @@ /utf-8 $(ExternalCompilerOptions) %(AdditionalOptions) - advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;wintrust.lib;%(AdditionalDependencies) + advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;virtdisk.lib;wininet.lib;wintrust.lib;%(AdditionalDependencies) RequireAdministrator true Windows MachineX86 - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;wintrust.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -162,12 +162,12 @@ /utf-8 $(ExternalCompilerOptions) %(AdditionalOptions) - advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;wintrust.lib;ole32.lib;advapi32.lib;gdi32.lib;shell32.lib;comdlg32.lib;%(AdditionalDependencies) + advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;virtdisk.lib;wininet.lib;wintrust.lib;ole32.lib;advapi32.lib;gdi32.lib;shell32.lib;comdlg32.lib;%(AdditionalDependencies) RequireAdministrator true Windows C:\Program Files (x86)\Windows Kits\10\Lib\10.0.15063.0\um\arm - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -193,12 +193,12 @@ /utf-8 $(ExternalCompilerOptions) %(AdditionalOptions) - advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;wintrust.lib;ole32.lib;advapi32.lib;gdi32.lib;shell32.lib;comdlg32.lib;%(AdditionalDependencies) + advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;virtdisk.lib;wininet.lib;wintrust.lib;ole32.lib;advapi32.lib;gdi32.lib;shell32.lib;comdlg32.lib;%(AdditionalDependencies) RequireAdministrator true Windows C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\arm64 - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -229,12 +229,12 @@ /utf-8 $(ExternalCompilerOptions) %(AdditionalOptions) - advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;wintrust.lib;%(AdditionalDependencies) + advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;virtdisk.lib;wininet.lib;wintrust.lib;%(AdditionalDependencies) RequireAdministrator true Windows MachineX64 - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;wintrust.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -260,13 +260,13 @@ true - advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;wintrust.lib;%(AdditionalDependencies) + advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;virtdisk.lib;wininet.lib;wintrust.lib;%(AdditionalDependencies) RequireAdministrator false Windows MachineX86 /BREPRO %(AdditionalOptions) - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;wintrust.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -292,13 +292,13 @@ true - advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;wintrust.lib;ole32.lib;advapi32.lib;gdi32.lib;shell32.lib;comdlg32.lib;%(AdditionalDependencies) + advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;virtdisk.lib;wininet.lib;wintrust.lib;ole32.lib;advapi32.lib;gdi32.lib;shell32.lib;comdlg32.lib;%(AdditionalDependencies) RequireAdministrator false Windows C:\Program Files (x86)\Windows Kits\10\Lib\10.0.15063.0\um\arm /BREPRO %(AdditionalOptions) - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -326,13 +326,13 @@ true - advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;wintrust.lib;ole32.lib;advapi32.lib;gdi32.lib;shell32.lib;comdlg32.lib;%(AdditionalDependencies) + advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;virtdisk.lib;wininet.lib;wintrust.lib;ole32.lib;advapi32.lib;gdi32.lib;shell32.lib;comdlg32.lib;%(AdditionalDependencies) RequireAdministrator false Windows C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\arm64 /BREPRO %(AdditionalOptions) - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -363,13 +363,13 @@ true - advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;wintrust.lib;%(AdditionalDependencies) + advapi32.lib;comctl32.lib;crypt32.lib;gdi32.lib;ole32.lib;dwmapi.lib;setupapi.lib;shell32.lib;shlwapi.lib;version.lib;virtdisk.lib;wininet.lib;wintrust.lib;%(AdditionalDependencies) RequireAdministrator false Windows MachineX64 /BREPRO %(AdditionalOptions) - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;wintrust.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) diff --git a/src/Makefile.am b/src/Makefile.am index ef0d0436..6d3dc08a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,8 +4,8 @@ NONVULNERABLE_LIBS = -lsetupapi -lole32 -lgdi32 -lshlwapi -lcrypt32 -lcomctl32 - # The following libraries are vulnerable (or have an unknown vulnerability status), so we link using our delay-loaded replacement: # Ideally there would also be virtdisk and wininet as delaylib's below, but the MinGW folks haven't quite sorted out delay-loading # for x86_32 so as soon as you try to call APIs from these, the application will crash! -# See https://github.com/pbatard/rufus/issues/1877#issuecomment-1109683039 as well as https://github.com/pbatard/rufus/issues/2272 -VULNERABLE_LIBS = -ldwmapi-delaylib -lversion-delaylib -lwintrust-delaylib +# See https://github.com/pbatard/rufus/issues/2272 +VULNERABLE_LIBS = -ldwmapi-delaylib -lversion-delaylib -lvirtdisk-delaylib -lwininet-delaylib -lwintrust-delaylib noinst_PROGRAMS = rufus diff --git a/src/Makefile.in b/src/Makefile.in index 70d31a54..003ffb8e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -279,8 +279,8 @@ NONVULNERABLE_LIBS = -lsetupapi -lole32 -lgdi32 -lshlwapi -lcrypt32 -lcomctl32 - # The following libraries are vulnerable (or have an unknown vulnerability status), so we link using our delay-loaded replacement: # Ideally there would also be virtdisk and wininet as delaylib's below, but the MinGW folks haven't quite sorted out delay-loading # for x86_32 so as soon as you try to call APIs from these, the application will crash! -# See https://github.com/pbatard/rufus/issues/1877#issuecomment-1109683039 as well as https://github.com/pbatard/rufus/issues/2272 -VULNERABLE_LIBS = -ldwmapi-delaylib -lversion-delaylib -lwintrust-delaylib +# See https://github.com/pbatard/rufus/issues/2272 +VULNERABLE_LIBS = -ldwmapi-delaylib -lversion-delaylib -lvirtdisk-delaylib -lwininet-delaylib -lwintrust-delaylib AM_V_WINDRES_0 = @echo " RC $@";$(WINDRES) AM_V_WINDRES_1 = $(WINDRES) AM_V_WINDRES_ = $(AM_V_WINDRES_$(AM_DEFAULT_VERBOSITY)) diff --git a/src/net.c b/src/net.c index 682fae89..8e486ca0 100644 --- a/src/net.c +++ b/src/net.c @@ -24,6 +24,12 @@ #endif #include +// Temporary workaround for MinGW32 delay-loading +// See https://github.com/pbatard/rufus/pull/2513 +#if defined(__MINGW32__) +#undef DECLSPEC_IMPORT +#define DECLSPEC_IMPORT __attribute__((visibility("hidden"))) +#endif #include #include #include @@ -113,14 +119,6 @@ static HINTERNET GetInternetSession(const char* user_agent, BOOL bRetry) HINTERNET hSession = NULL; HRESULT hr = S_FALSE; INetworkListManager* pNetworkListManager; - - 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)); hr = CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_ALL, @@ -131,8 +129,8 @@ static HINTERNET GetInternetSession(const char* user_agent, BOOL bRetry) // 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; + if (hr == HRESULT_FROM_WIN32(ERROR_SERVICE_DEPENDENCY_FAIL)) { + InternetConnection = InternetGetConnectedState(&dwFlags, 0) ? VARIANT_TRUE : VARIANT_FALSE; break; } if (hr == S_OK || !bRetry) @@ -147,16 +145,16 @@ static HINTERNET GetInternetSession(const char* user_agent, BOOL bRetry) static_sprintf(default_agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %lu.%lu%s)", rufus_version[0], rufus_version[1], rufus_version[2], WindowsVersion.Major, WindowsVersion.Minor, is_WOW64() ? "; WOW64" : ""); - hSession = pfInternetOpenA((user_agent == NULL) ? default_agent : user_agent, + hSession = InternetOpenA((user_agent == NULL) ? default_agent : user_agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); // Set the timeouts - pfInternetSetOptionA(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); - pfInternetSetOptionA(hSession, INTERNET_OPTION_SEND_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); - pfInternetSetOptionA(hSession, INTERNET_OPTION_RECEIVE_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); + InternetSetOptionA(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); + InternetSetOptionA(hSession, INTERNET_OPTION_SEND_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); + InternetSetOptionA(hSession, INTERNET_OPTION_RECEIVE_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); // Enable gzip and deflate decoding schemes - pfInternetSetOptionA(hSession, INTERNET_OPTION_HTTP_DECODING, (LPVOID)&decodingSupport, sizeof(decodingSupport)); + InternetSetOptionA(hSession, INTERNET_OPTION_HTTP_DECODING, (LPVOID)&decodingSupport, sizeof(decodingSupport)); // Enable HTTP/2 protocol support - pfInternetSetOptionA(hSession, INTERNET_OPTION_ENABLE_HTTP_PROTOCOL, (LPVOID)&dwProtocolSupport, sizeof(dwProtocolSupport)); + InternetSetOptionA(hSession, INTERNET_OPTION_ENABLE_HTTP_PROTOCOL, (LPVOID)&dwProtocolSupport, sizeof(dwProtocolSupport)); out: return hSession; @@ -187,23 +185,6 @@ uint64_t DownloadToFileOrBufferEx(const char* url, const char* file, const char* hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; uint64_t size = 0, total_size = 0; - // Can't link with wininet.lib because of sideloading issues - // And we can't delay-load wininet.dll with MinGW either because the application simply exits on startup... - PF_TYPE_DECL(WINAPI, BOOL, InternetCrackUrlA, (LPCSTR, DWORD, DWORD, LPURL_COMPONENTSA)); - PF_TYPE_DECL(WINAPI, HINTERNET, InternetConnectA, (HINTERNET, LPCSTR, INTERNET_PORT, LPCSTR, LPCSTR, DWORD, DWORD, DWORD_PTR)); - PF_TYPE_DECL(WINAPI, BOOL, InternetReadFile, (HINTERNET, LPVOID, DWORD, LPDWORD)); - PF_TYPE_DECL(WINAPI, BOOL, InternetCloseHandle, (HINTERNET)); - PF_TYPE_DECL(WINAPI, HINTERNET, HttpOpenRequestA, (HINTERNET, LPCSTR, LPCSTR, LPCSTR, LPCSTR, LPCSTR*, DWORD, DWORD_PTR)); - PF_TYPE_DECL(WINAPI, BOOL, HttpSendRequestA, (HINTERNET, LPCSTR, DWORD, LPVOID, DWORD)); - PF_TYPE_DECL(WINAPI, BOOL, HttpQueryInfoA, (HINTERNET, DWORD, LPVOID, LPDWORD, LPDWORD)); - PF_INIT_OR_OUT(InternetCrackUrlA, WinInet); - PF_INIT_OR_OUT(InternetConnectA, WinInet); - PF_INIT_OR_OUT(InternetReadFile, WinInet); - PF_INIT_OR_OUT(InternetCloseHandle, WinInet); - PF_INIT_OR_OUT(HttpOpenRequestA, WinInet); - PF_INIT_OR_OUT(HttpSendRequestA, WinInet); - PF_INIT_OR_OUT(HttpQueryInfoA, WinInet); - ErrorStatus = 0; DownloadStatus = 404; if (hProgressDialog != NULL) @@ -220,7 +201,7 @@ uint64_t DownloadToFileOrBufferEx(const char* url, const char* file, const char* uprintf("Downloading %s", url); } - if ( (!pfInternetCrackUrlA(url, (DWORD)safe_strlen(url), 0, &UrlParts)) + if ( (!InternetCrackUrlA(url, (DWORD)safe_strlen(url), 0, &UrlParts)) || (UrlParts.lpszHostName == NULL) || (UrlParts.lpszUrlPath == NULL)) { uprintf("Unable to decode URL: %s", WindowsErrorString()); goto out; @@ -233,13 +214,13 @@ uint64_t DownloadToFileOrBufferEx(const char* url, const char* file, const char* goto out; } - hConnection = pfInternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); + hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); if (hConnection == NULL) { uprintf("Could not connect to server %s:%d: %s", UrlParts.lpszHostName, UrlParts.nPort, WindowsErrorString()); goto out; } - hRequest = pfHttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, accept_types, + hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, accept_types, INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_HYPERLINK | ((UrlParts.nScheme==INTERNET_SCHEME_HTTPS)?INTERNET_FLAG_SECURE:0), (DWORD_PTR)NULL); @@ -248,14 +229,14 @@ uint64_t DownloadToFileOrBufferEx(const char* url, const char* file, const char* goto out; } - if (!pfHttpSendRequestA(hRequest, request_headers, -1L, NULL, 0)) { + if (!HttpSendRequestA(hRequest, request_headers, -1L, NULL, 0)) { uprintf("Unable to send request: %s", WindowsErrorString()); goto out; } // Get the file size dwSize = sizeof(DownloadStatus); - pfHttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&DownloadStatus, &dwSize, NULL); + HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&DownloadStatus, &dwSize, NULL); if (DownloadStatus != 200) { error_code = ERROR_INTERNET_ITEM_NOT_FOUND; SetLastError(RUFUS_ERROR(error_code)); @@ -263,7 +244,7 @@ uint64_t DownloadToFileOrBufferEx(const char* url, const char* file, const char* goto out; } dwSize = sizeof(strsize); - if (!pfHttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH, (LPVOID)strsize, &dwSize, NULL)) { + if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH, (LPVOID)strsize, &dwSize, NULL)) { uprintf("Unable to retrieve file length: %s", WindowsErrorString()); goto out; } @@ -302,7 +283,7 @@ uint64_t DownloadToFileOrBufferEx(const char* url, const char* file, const char* // User may have cancelled the download if (IS_ERROR(ErrorStatus)) goto out; - if (!pfInternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0)) + if (!InternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0)) break; if (hProgressDialog != NULL) UpdateProgressWithInfo(OP_NOOP, MSG_241, size, total_size); @@ -347,11 +328,11 @@ out: safe_free(*buffer); } if (hRequest) - pfInternetCloseHandle(hRequest); + InternetCloseHandle(hRequest); if (hConnection) - pfInternetCloseHandle(hConnection); + InternetCloseHandle(hConnection); if (hSession) - pfInternetCloseHandle(hSession); + InternetCloseHandle(hSession); SetLastError(error_code); return r ? size : 0; @@ -476,23 +457,6 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) SYSTEMTIME ServerTime, LocalTime; FILETIME FileTime; int64_t local_time = 0, reg_time, server_time, update_interval; - - // Can't link with wininet.lib because of sideloading issues - PF_TYPE_DECL(WINAPI, BOOL, InternetCrackUrlA, (LPCSTR, DWORD, DWORD, LPURL_COMPONENTSA)); - PF_TYPE_DECL(WINAPI, HINTERNET, InternetConnectA, (HINTERNET, LPCSTR, INTERNET_PORT, LPCSTR, LPCSTR, DWORD, DWORD, DWORD_PTR)); - PF_TYPE_DECL(WINAPI, BOOL, InternetReadFile, (HINTERNET, LPVOID, DWORD, LPDWORD)); - PF_TYPE_DECL(WINAPI, BOOL, InternetCloseHandle, (HINTERNET)); - PF_TYPE_DECL(WINAPI, HINTERNET, HttpOpenRequestA, (HINTERNET, LPCSTR, LPCSTR, LPCSTR, LPCSTR, LPCSTR*, DWORD, DWORD_PTR)); - PF_TYPE_DECL(WINAPI, BOOL, HttpSendRequestA, (HINTERNET, LPCSTR, DWORD, LPVOID, DWORD)); - PF_TYPE_DECL(WINAPI, BOOL, HttpQueryInfoA, (HINTERNET, DWORD, LPVOID, LPDWORD, LPDWORD)); - PF_INIT_OR_OUT(InternetCrackUrlA, WinInet); - PF_INIT_OR_OUT(InternetConnectA, WinInet); - PF_INIT_OR_OUT(InternetReadFile, WinInet); - PF_INIT_OR_OUT(InternetCloseHandle, WinInet); - PF_INIT_OR_OUT(HttpOpenRequestA, WinInet); - PF_INIT_OR_OUT(HttpSendRequestA, WinInet); - PF_INIT_OR_OUT(HttpQueryInfoA, WinInet); - verbose = ReadSetting32(SETTING_VERBOSE_UPDATES); // Without this the FileDialog will produce error 0x8001010E when compiled for Vista or later IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)); @@ -530,7 +494,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) PrintInfoDebug(3000, MSG_243); status++; // 1 - if (!pfInternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts)) + if (!InternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts)) goto out; hostname[sizeof(hostname)-1] = 0; @@ -540,7 +504,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) hSession = GetInternetSession(NULL, FALSE); if (hSession == NULL) goto out; - hConnection = pfInternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, + hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); if (hConnection == NULL) goto out; @@ -582,11 +546,11 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) UrlParts.dwUrlPathLength = sizeof(urlpath); for (i=0; i 0); } diff --git a/src/process.c b/src/process.c index 31fc6465..0060c397 100644 --- a/src/process.c +++ b/src/process.c @@ -895,7 +895,7 @@ static BOOL IsProcessRunning(uint64_t pid) PF_INIT_OR_OUT(NtClose, NtDll); - status = PhOpenProcess(&hProcess, PROCESS_QUERY_LIMITED_INFORMATION, (HANDLE)pid); + status = PhOpenProcess(&hProcess, PROCESS_QUERY_LIMITED_INFORMATION, (HANDLE)(uintptr_t)pid); if (!NT_SUCCESS(status) || (hProcess == NULL)) return FALSE; if (GetExitCodeProcess(hProcess, &dwExitCode)) diff --git a/src/rufus.rc b/src/rufus.rc index 007cbedb..38356a1e 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 4.6.2187" +CAPTION "Rufus 4.6.2188" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -397,8 +397,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,6,2187,0 - PRODUCTVERSION 4,6,2187,0 + FILEVERSION 4,6,2188,0 + PRODUCTVERSION 4,6,2188,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -416,13 +416,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.6.2187" + VALUE "FileVersion", "4.6.2188" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "� 2011-2024 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.6.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.6.2187" + VALUE "ProductVersion", "4.6.2188" END END BLOCK "VarFileInfo" diff --git a/src/vhd.c b/src/vhd.c index 627d9423..4ab0236d 100644 --- a/src/vhd.c +++ b/src/vhd.c @@ -17,7 +17,15 @@ * along with this program. If not, see . */ +// MinGW includes virdisk.h in windows.h, but we we don't want that +// because we must apply a delay-loading workaround, and that workaround +// has to apply between the winnt.h include and the virdisk.h include. +// So we define _INC_VIRTDISK, to prevent the virdisk.h include in +// windows.h, and then take care of the workaround (and virtdisk.h +// include) in vhd.h. +#define _INC_VIRTDISK #include +#undef _INC_VIRTDISK #include #include #include @@ -68,9 +76,10 @@ static uint8_t wim_flags = 0; static uint32_t progress_report_mask; static uint64_t progress_offset = 0, progress_total = 100; static wchar_t wmount_path[MAX_PATH] = { 0 }, wmount_track[MAX_PATH] = { 0 }; -static char sevenzip_path[MAX_PATH]; -static BOOL count_files; +static char sevenzip_path[MAX_PATH], physical_path[128] = ""; static int progress_op = OP_FILE_COPY, progress_msg = MSG_267; +static BOOL count_files; +static HANDLE mounted_handle = INVALID_HANDLE_VALUE; static BOOL Get7ZipPath(void) { @@ -897,23 +906,6 @@ BOOL WimApplyImage(const char* image, int index, const char* dst) return dw; } -// VirtDisk API Prototypes since we can't use delay-loading because of MinGW -// See https://github.com/pbatard/rufus/issues/2272#issuecomment-1615976013 -PF_TYPE_DECL(WINAPI, DWORD, CreateVirtualDisk, (PVIRTUAL_STORAGE_TYPE, PCWSTR, - VIRTUAL_DISK_ACCESS_MASK, PSECURITY_DESCRIPTOR, CREATE_VIRTUAL_DISK_FLAG, ULONG, - PCREATE_VIRTUAL_DISK_PARAMETERS, LPOVERLAPPED, PHANDLE)); -PF_TYPE_DECL(WINAPI, DWORD, OpenVirtualDisk, (PVIRTUAL_STORAGE_TYPE, PCWSTR, - VIRTUAL_DISK_ACCESS_MASK, OPEN_VIRTUAL_DISK_FLAG, POPEN_VIRTUAL_DISK_PARAMETERS, PHANDLE)); -PF_TYPE_DECL(WINAPI, DWORD, AttachVirtualDisk, (HANDLE, PSECURITY_DESCRIPTOR, - ATTACH_VIRTUAL_DISK_FLAG, ULONG, PATTACH_VIRTUAL_DISK_PARAMETERS, LPOVERLAPPED)); -PF_TYPE_DECL(WINAPI, DWORD, DetachVirtualDisk, (HANDLE, DETACH_VIRTUAL_DISK_FLAG, ULONG)); -PF_TYPE_DECL(WINAPI, DWORD, GetVirtualDiskPhysicalPath, (HANDLE, PULONG, PWSTR)); -PF_TYPE_DECL(WINAPI, DWORD, GetVirtualDiskOperationProgress, (HANDLE, LPOVERLAPPED, PVIRTUAL_DISK_PROGRESS)); -PF_TYPE_DECL(WINAPI, DWORD, GetVirtualDiskInformation, (HANDLE, PULONG, PGET_VIRTUAL_DISK_INFO, PULONG)); - -static char physical_path[128] = ""; -static HANDLE mounted_handle = INVALID_HANDLE_VALUE; - // Mount an ISO or a VHD/VHDX image and provide its size // Returns the physical path of the mounted image or NULL on error. char* VhdMountImageAndGetSize(const char* path, uint64_t* disk_size) @@ -927,12 +919,6 @@ char* VhdMountImageAndGetSize(const char* path, uint64_t* disk_size) wconvert(path); char *ret = NULL, *ext = NULL; - PF_INIT_OR_OUT(OpenVirtualDisk, VirtDisk); - PF_INIT_OR_OUT(AttachVirtualDisk, VirtDisk); - PF_INIT_OR_OUT(GetVirtualDiskPhysicalPath, VirtDisk); - if (disk_size != NULL) - PF_INIT_OR_OUT(GetVirtualDiskInformation, VirtDisk); - if (wpath == NULL) return NULL; @@ -946,7 +932,7 @@ char* VhdMountImageAndGetSize(const char* path, uint64_t* disk_size) else if (safe_stricmp(ext, ".vhd") == 0) vtype.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_VHD; - r = pfOpenVirtualDisk(&vtype, wpath, VIRTUAL_DISK_ACCESS_READ | VIRTUAL_DISK_ACCESS_GET_INFO, + r = OpenVirtualDisk(&vtype, wpath, VIRTUAL_DISK_ACCESS_READ | VIRTUAL_DISK_ACCESS_GET_INFO, OPEN_VIRTUAL_DISK_FLAG_NONE, NULL, &mounted_handle); if (r != ERROR_SUCCESS) { SetLastError(r); @@ -955,7 +941,7 @@ char* VhdMountImageAndGetSize(const char* path, uint64_t* disk_size) } vparams.Version = ATTACH_VIRTUAL_DISK_VERSION_1; - r = pfAttachVirtualDisk(mounted_handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | + r = AttachVirtualDisk(mounted_handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER, 0, &vparams, NULL); if (r != ERROR_SUCCESS) { SetLastError(r); @@ -963,7 +949,7 @@ char* VhdMountImageAndGetSize(const char* path, uint64_t* disk_size) goto out; } - r = pfGetVirtualDiskPhysicalPath(mounted_handle, &size, wtmp); + r = GetVirtualDiskPhysicalPath(mounted_handle, &size, wtmp); if (r != ERROR_SUCCESS) { SetLastError(r); uprintf("Could not obtain physical path for mounted image '%s': %s", path, WindowsErrorString()); @@ -975,7 +961,7 @@ char* VhdMountImageAndGetSize(const char* path, uint64_t* disk_size) *disk_size = 0; disk_info.Version = GET_VIRTUAL_DISK_INFO_SIZE; size = sizeof(disk_info); - r = pfGetVirtualDiskInformation(mounted_handle, &size, &disk_info, NULL); + r = GetVirtualDiskInformation(mounted_handle, &size, &disk_info, NULL); if (r != ERROR_SUCCESS) { SetLastError(r); uprintf("Could not obtain virtual size of mounted image '%s': %s", path, WindowsErrorString()); @@ -995,12 +981,10 @@ out: void VhdUnmountImage(void) { - PF_INIT_OR_OUT(DetachVirtualDisk, VirtDisk); - if ((mounted_handle == NULL) || (mounted_handle == INVALID_HANDLE_VALUE)) goto out; - pfDetachVirtualDisk(mounted_handle, DETACH_VIRTUAL_DISK_FLAG_NONE, 0); + DetachVirtualDisk(mounted_handle, DETACH_VIRTUAL_DISK_FLAG_NONE, 0); safe_closehandle(mounted_handle); out: physical_path[0] = 0; @@ -1022,9 +1006,6 @@ static DWORD WINAPI VhdSaveImageThread(void* param) OVERLAPPED overlapped = { 0 }; DWORD r = ERROR_NOT_FOUND, flags; - PF_INIT_OR_OUT(CreateVirtualDisk, VirtDisk); - PF_INIT_OR_OUT(GetVirtualDiskOperationProgress, VirtDisk); - assert(img_save->Type == VIRTUAL_STORAGE_TYPE_DEVICE_VHD || img_save->Type == VIRTUAL_STORAGE_TYPE_DEVICE_VHDX); @@ -1052,7 +1033,7 @@ static DWORD WINAPI VhdSaveImageThread(void* param) // CreateVirtualDisk() does not have an overwrite flag... DeleteFileW(wDst); - r = pfCreateVirtualDisk(&vtype, wDst, VIRTUAL_DISK_ACCESS_NONE, NULL, + r = CreateVirtualDisk(&vtype, wDst, VIRTUAL_DISK_ACCESS_NONE, NULL, flags, 0, (PCREATE_VIRTUAL_DISK_PARAMETERS)&vparams, &overlapped, &handle); if (r != ERROR_SUCCESS && r != ERROR_IO_PENDING) { SetLastError(r); @@ -1066,7 +1047,7 @@ static DWORD WINAPI VhdSaveImageThread(void* param) CancelIoEx(handle, &overlapped); goto out; } - if (pfGetVirtualDiskOperationProgress(handle, &overlapped, &vprogress) == ERROR_SUCCESS) { + if (GetVirtualDiskOperationProgress(handle, &overlapped, &vprogress) == ERROR_SUCCESS) { if (vprogress.OperationStatus == ERROR_IO_PENDING) UpdateProgressWithInfo(OP_FORMAT, MSG_261, vprogress.CurrentValue, vprogress.CompletionValue); } diff --git a/src/vhd.h b/src/vhd.h index 45a332b2..75fa1c03 100644 --- a/src/vhd.h +++ b/src/vhd.h @@ -19,6 +19,12 @@ #include #include +// Temporary workaround for MinGW32 delay-loading +// See https://github.com/pbatard/rufus/pull/2513 +#if defined(__MINGW32__) +#undef DECLSPEC_IMPORT +#define DECLSPEC_IMPORT __attribute__((visibility("hidden"))) +#endif #include #pragma once