diff --git a/.github/workflows/vs2022.yml b/.github/workflows/vs2022.yml
index 963477fe..aefd1f61 100644
--- a/.github/workflows/vs2022.yml
+++ b/.github/workflows/vs2022.yml
@@ -50,6 +50,11 @@ jobs:
with:
msbuild-architecture: x64
+ - name: Install UPX
+ uses: crazy-max/ghaction-upx@v3
+ with:
+ install-only: true
+
- name: Set ALPHA
id: set_alpha
shell: bash
@@ -76,6 +81,10 @@ jobs:
move .\${{ matrix.TARGET_PLATFORM }}\Release\rufus.exe .\rufus_${{ matrix.TARGET_PLATFORM }}.exe
move .\${{ matrix.TARGET_PLATFORM }}\Release\rufus.pdb .\rufus_${{ matrix.TARGET_PLATFORM }}.pdb
+ - name: Compress executables
+ if: ${{ matrix.TARGET_PLATFORM != 'arm64' }}
+ run: upx --lzma --best .\rufus_${{ matrix.TARGET_PLATFORM }}.exe
+
- name: Display SHA-256
run: sha256sum ./rufus_${{ matrix.TARGET_PLATFORM }}.exe
diff --git a/.mingw/Makefile.am b/.mingw/Makefile.am
index e8d55d27..a2170674 100644
--- a/.mingw/Makefile.am
+++ b/.mingw/Makefile.am
@@ -20,8 +20,7 @@ TARGET := $(word 1,$(subst -, ,$(TUPLE)))
DEF_SUFFIX := $(if $(TARGET:x86_64=),.def,.def64)
.PHONY: all
-# Ideally, we would also have cfgmgr32-delaylib here, but it doesn't actually delay load... :(
-all: dwmapi-delaylib.lib version-delaylib.lib virtdisk-delaylib.lib wininet-delaylib.lib wintrust-delaylib.lib
+all: crypt32-delaylib.lib dwmapi-delaylib.lib setupapi-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 8174663d..dd62b1df 100644
--- a/.mingw/Makefile.in
+++ b/.mingw/Makefile.in
@@ -368,8 +368,7 @@ uninstall-am:
.PHONY: all
-# Ideally, we would also have cfgmgr32-delaylib here, but it doesn't actually delay load... :(
-all: dwmapi-delaylib.lib version-delaylib.lib virtdisk-delaylib.lib wininet-delaylib.lib wintrust-delaylib.lib
+all: crypt32-delaylib.lib dwmapi-delaylib.lib setupapi-delaylib.lib version-delaylib.lib virtdisk-delaylib.lib wininet-delaylib.lib wintrust-delaylib.lib
%.def64: %.def
$(AM_V_SED) "s/@.*//" $< >$@
diff --git a/.mingw/crypt32.def b/.mingw/crypt32.def
new file mode 100644
index 00000000..6d070db3
--- /dev/null
+++ b/.mingw/crypt32.def
@@ -0,0 +1,14 @@
+EXPORTS
+ CertFindCertificateInStore@24
+ CertGetCertificateChain@32
+ CertGetNameStringA@24
+ CertCloseStore@8
+ CertFreeCertificateContext@4
+ CryptQueryObject@44
+ CryptDecodeObjectEx@32
+ CryptHashCertificate@28
+ CryptMsgGetParam@20
+ CryptMsgClose@4
+ CryptMsgGetParam@20
+ CryptMsgOpenToDecode@24
+ CryptMsgUpdate@16
diff --git a/.mingw/setupapi.def b/.mingw/setupapi.def
new file mode 100644
index 00000000..5707e1cc
--- /dev/null
+++ b/.mingw/setupapi.def
@@ -0,0 +1,20 @@
+EXPORTS
+ CM_Locate_DevNodeA@12
+ CM_Get_DevNode_Registry_PropertyA@24
+ CM_Get_DevNode_Status@16
+ CM_Get_Child@12
+ CM_Get_Parent@12
+ CM_Get_Sibling@12
+ CM_Get_Device_IDA@16
+ CM_Get_Device_ID_ListA@16
+ CM_Get_Device_ID_List_SizeA@12
+ SetupDiGetDeviceInstanceIdA@20
+ SetupDiGetDeviceRegistryPropertyA@28
+ SetupDiGetDeviceRegistryPropertyW@28
+ SetupDiChangeState@8
+ SetupDiGetClassDevsA@16
+ SetupDiSetClassInstallParamsW@16
+ SetupDiEnumDeviceInfo@12
+ SetupDiEnumDeviceInterfaces@20
+ SetupDiDestroyDeviceInfoList@4
+ SetupDiGetDeviceInterfaceDetailA@24
diff --git a/.vs/rufus.vcxproj b/.vs/rufus.vcxproj
index be8d8216..b558e0ea 100644
--- a/.vs/rufus.vcxproj
+++ b/.vs/rufus.vcxproj
@@ -168,7 +168,7 @@
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;virtdisk.dll;wininet.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;%(DelayLoadDLLs)
/BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions)
@@ -200,7 +200,7 @@
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;virtdisk.dll;wininet.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;%(DelayLoadDLLs)
/BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions)
@@ -302,7 +302,7 @@
Windows
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.15063.0\um\arm
/BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions)
- 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)
+ 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)
@@ -336,7 +336,7 @@
Windows
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\arm64
/BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions)
- 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)
+ 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/configure b/configure
index 1399f3a4..ce4d9bb1 100755
--- a/configure
+++ b/configure
@@ -4702,7 +4702,7 @@ fi
printf "%s\n" "enabling Large File Support (ISO support)" >&6; }
AM_CFLAGS="$AM_CFLAGS -D_FILE_OFFSET_BITS=64 -D_OFF_T_ -D_off_t=off64_t -Doff_t=off64_t -Doff32_t=long"
-# check for -Wno-pointer-sign compiler support (GCC >= 4)
+# Check for -Wno-pointer-sign compiler support (GCC >= 4)
saved_CFLAGS="${CFLAGS}"
CFLAGS="$CFLAGS -Wno-pointer-sign"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4725,7 +4725,9 @@ fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS="${saved_CFLAGS}"
-AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -std=gnu11 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags"
+# NB: The DECLSPEC_IMPORT redefinition below is a temporary(?) workaround for MinGW32 delay-loading
+# See https://github.com/pbatard/rufus/pull/2513 as well as https://sourceware.org/bugzilla/show_bug.cgi?id=14339
+AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -UDECLSPEC_IMPORT -DDECLSPEC_IMPORT=__attribute__\(\(visibility\(\\\"hidden\\\"\)\)\) -std=gnu11 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags"
diff --git a/configure.ac b/configure.ac
index 2980290a..7225f028 100644
--- a/configure.ac
+++ b/configure.ac
@@ -57,14 +57,16 @@ fi
AC_MSG_RESULT([enabling Large File Support (ISO support)])
AM_CFLAGS="$AM_CFLAGS -D_FILE_OFFSET_BITS=64 -D_OFF_T_ -D_off_t=off64_t -Doff_t=off64_t -Doff32_t=long"
-# check for -Wno-pointer-sign compiler support (GCC >= 4)
+# Check for -Wno-pointer-sign compiler support (GCC >= 4)
saved_CFLAGS="${CFLAGS}"
CFLAGS="$CFLAGS -Wno-pointer-sign"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
[nopointersign_cflags="-Wno-pointer-sign"], [nopointersign_cflags=""])
CFLAGS="${saved_CFLAGS}"
-AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -std=gnu11 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags"
+# NB: The DECLSPEC_IMPORT redefinition below is a temporary(?) workaround for MinGW32 delay-loading
+# See https://github.com/pbatard/rufus/pull/2513 as well as https://sourceware.org/bugzilla/show_bug.cgi?id=14339
+AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -UDECLSPEC_IMPORT -DDECLSPEC_IMPORT=__attribute__\(\(visibility\(\\\"hidden\\\"\)\)\) -std=gnu11 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags"
AC_SUBST([VISIBILITY_CFLAGS])
AC_SUBST([AM_CFLAGS])
diff --git a/loadcfg.py b/loadcfg.py
new file mode 100644
index 00000000..4476c150
--- /dev/null
+++ b/loadcfg.py
@@ -0,0 +1,63 @@
+#!/bin/env python3
+
+# PE Load Configuration section enabler for MinGW/gcc executables.
+# The PE executable should have a IMAGE_LOAD_CONFIG_DIRECTORY## section
+# in .rdata with a 16-byte IMAGE_DIRECTORY_ENTRY_MARKER marker.
+
+import os
+import sys
+import pefile
+
+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10
+IMAGE_DIRECTORY_ENTRY_MARKER = b"_RUFUS_LOAD_CFG"
+
+if len(sys.argv) < 2:
+ raise RuntimeError("No executable path supplied")
+
+# Create a temp file as our source
+pe_dst = sys.argv[1]
+pe_src = sys.argv[1] + ".tmp"
+os.replace(pe_dst, pe_src)
+
+# Open and parse PE
+pe = pefile.PE(pe_src)
+
+# Find .rdata section
+rdata_section = next(
+ (s for s in pe.sections if s.Name.rstrip(b'\x00') == b'.rdata'),
+ None
+)
+if not rdata_section:
+ raise RuntimeError(".rdata section not found")
+
+# Read the section's raw data to search for the target string
+raw_data = rdata_section.get_data()
+
+# Look for the target data in the raw section data
+offset = raw_data.find(IMAGE_DIRECTORY_ENTRY_MARKER)
+if offset == -1:
+ raise RuntimeError("Load Config marker not found")
+
+# Move past our 16 bytes marker
+offset += 0x10
+# Calculate the RVA and size of the Load Config section
+load_config_rva = rdata_section.VirtualAddress + offset
+print(f"RVA of Load Config: 0x{load_config_rva:X}")
+load_config_size = pe.get_dword_at_rva(load_config_rva)
+if (load_config_size < 0x20):
+ raise RuntimeError("Size of Load Config section is too small")
+print(f"Size of Load Config: 0x{load_config_size:X}")
+
+# Update Load Config directory entry
+pe.OPTIONAL_HEADER.DATA_DIRECTORY[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = load_config_rva
+pe.OPTIONAL_HEADER.DATA_DIRECTORY[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = load_config_size
+
+# Update the checksum
+pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum()
+
+# Write the updated PE file and remove temp
+pe.write(pe_dst)
+os.remove(pe_src)
+
+# Can be validated with `DUMPBIN /LOADCONFIG <.exe>` or `objdump -x <.exe> | grep "Load Configuration"`
+print(f"Successfully enabled Load Config section in '{pe_dst}'")
diff --git a/src/Makefile.am b/src/Makefile.am
index 65a5cf14..fbcef997 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,11 +1,9 @@
SUBDIRS = ../.mingw bled ext2fs ms-sys syslinux/libfat syslinux/libinstaller syslinux/win libcdio/iso9660 libcdio/udf libcdio/driver wimlib ../res/loc
# As far as I can tell, the following libraries are *not* vulnerable to side-loading, so we link using their regular version:
-NONVULNERABLE_LIBS = -lsetupapi -lole32 -lgdi32 -lshlwapi -lcrypt32 -lcomctl32 -luuid -lntdll
+NONVULNERABLE_LIBS = -lole32 -lgdi32 -lshlwapi -lcomctl32 -luuid -lntdll
# The following libraries are vulnerable (or have an unknown vulnerability status), so we link using our delay-loaded replacement:
# See https://github.com/pbatard/rufus/issues/2272
-# Oh, and don't bother trying to delay load cfgmgr32.dll, even with the DECLSPEC_IMPORT __attribute__((visibility("hidden")))
-# override. It just DOESN'T BLOODY WORK and you will waste HOURS on a wild goose chase!!!
-VULNERABLE_LIBS = -ldwmapi-delaylib -lversion-delaylib -lvirtdisk-delaylib -lwininet-delaylib -lwintrust-delaylib
+VULNERABLE_LIBS = -lcrypt32-delaylib -ldwmapi-delaylib -lsetupapi-delaylib -lversion-delaylib -lvirtdisk-delaylib -lwininet-delaylib -lwintrust-delaylib
noinst_PROGRAMS = rufus
diff --git a/src/Makefile.in b/src/Makefile.in
index f219568c..5deb0e19 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -275,12 +275,10 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = ../.mingw bled ext2fs ms-sys syslinux/libfat syslinux/libinstaller syslinux/win libcdio/iso9660 libcdio/udf libcdio/driver wimlib ../res/loc
# As far as I can tell, the following libraries are *not* vulnerable to side-loading, so we link using their regular version:
-NONVULNERABLE_LIBS = -lsetupapi -lole32 -lgdi32 -lshlwapi -lcrypt32 -lcomctl32 -luuid -lntdll
+NONVULNERABLE_LIBS = -lole32 -lgdi32 -lshlwapi -lcomctl32 -luuid -lntdll
# The following libraries are vulnerable (or have an unknown vulnerability status), so we link using our delay-loaded replacement:
# See https://github.com/pbatard/rufus/issues/2272
-# Oh, and don't bother trying to delay load cfgmgr32.dll, even with the DECLSPEC_IMPORT __attribute__((visibility("hidden")))
-# override. It just DOESN'T BLOODY WORK and you will waste HOURS on a wild goose chase!!!
-VULNERABLE_LIBS = -ldwmapi-delaylib -lversion-delaylib -lvirtdisk-delaylib -lwininet-delaylib -lwintrust-delaylib
+VULNERABLE_LIBS = -lcrypt32-delaylib -ldwmapi-delaylib -lsetupapi-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/dev.c b/src/dev.c
index cbecdda2..7734f1b6 100644
--- a/src/dev.c
+++ b/src/dev.c
@@ -49,21 +49,6 @@ extern RUFUS_DRIVE rufus_drive[MAX_DRIVES];
extern BOOL enable_HDDs, enable_VHDs, use_fake_units, enable_vmdk, usb_debug;
extern BOOL list_non_usb_removable_drives, its_a_me_mario;
-/*
- * CfgMgr32.dll interface.
- * Note that, unlike what is the case with other DLLs, delay-loading of cfgmgr32
- * does *not* work with MinGW, so we have to go through direct hooking yet again...
- */
-PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, CHAR*, ULONG, ULONG));
-PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Device_ID_List_SizeA, (PULONG, PCSTR, ULONG));
-PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Device_ID_ListA, (PCSTR, PCHAR, ULONG, ULONG));
-PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Locate_DevNodeA, (PDEVINST, DEVINSTID_A, ULONG));
-PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
-PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
-PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
-PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_DevNode_Status, (PULONG, PULONG, DEVINST, ULONG));
-PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_DevNode_Registry_PropertyA, (DEVINST, ULONG, PULONG, PVOID, PULONG, ULONG));
-
/*
* Get the VID, PID and current device speed
*/
@@ -80,10 +65,7 @@ static BOOL GetUSBProperties(char* parent_path, char* device_id, usb_device_prop
if ((parent_path == NULL) || (device_id == NULL) || (props == NULL))
goto out;
- PF_INIT_OR_OUT(CM_Locate_DevNodeA, CfgMgr32);
- PF_INIT_OR_OUT(CM_Get_DevNode_Registry_PropertyA, CfgMgr32);
-
- cr = pfCM_Locate_DevNodeA(&device_inst, device_id, 0);
+ cr = CM_Locate_DevNodeA(&device_inst, device_id, 0);
if (cr != CR_SUCCESS) {
uprintf("Could not get device instance handle for '%s': CR error %d", device_id, cr);
goto out;
@@ -91,7 +73,7 @@ static BOOL GetUSBProperties(char* parent_path, char* device_id, usb_device_prop
props->port = 0;
size = sizeof(props->port);
- cr = pfCM_Get_DevNode_Registry_PropertyA(device_inst, CM_DRP_ADDRESS, NULL, (PVOID)&props->port, &size, 0);
+ cr = CM_Get_DevNode_Registry_PropertyA(device_inst, CM_DRP_ADDRESS, NULL, (PVOID)&props->port, &size, 0);
if (cr != CR_SUCCESS) {
uprintf("Could not get port for '%s': CR error %d", device_id, cr);
goto out;
@@ -214,8 +196,6 @@ int CycleDevice(int index)
if ((index < 0) || (safe_strlen(rufus_drive[index].id) < 8))
return ERROR_INVALID_PARAMETER;
- PF_INIT_OR_OUT(CM_Get_DevNode_Status, CfgMgr32);
-
// Need DIGCF_ALLCLASSES else disabled devices won't be listed.
dev_info = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (dev_info == INVALID_HANDLE_VALUE) {
@@ -238,7 +218,7 @@ int CycleDevice(int index)
found = TRUE;
// Detect if the device is already disabled
- if (pfCM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS)
+ if (CM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS)
disabled = (dev_status & DN_HAS_PROBLEM) && (problem_code == CM_PROB_DISABLED);
// Disable the device
@@ -287,7 +267,7 @@ int CycleDevice(int index)
// successful, but leave the device in an actual disabled state... So we can end up
// with zombie devices, that are effectively disabled, but that Windows still sees
// as enabled... So we need to detect this.
- if (pfCM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS) {
+ if (CM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS) {
disabled = (dev_status & DN_HAS_PROBLEM) && (problem_code == CM_PROB_DISABLED);
if (disabled)
ret = ERROR_DEVICE_REINITIALIZATION_NEEDED;
@@ -298,7 +278,6 @@ int CycleDevice(int index)
SetupDiDestroyDeviceInfoList(dev_info);
if (!found)
uprintf("Could not find a device to cycle!");
-out:
return ret;
}
@@ -518,14 +497,6 @@ BOOL GetDevices(DWORD devnum)
uint64_t drive_size = 0;
usb_device_props props;
- PF_INIT_OR_OUT(CM_Get_Child, CfgMgr32);
- PF_INIT_OR_OUT(CM_Get_Parent, CfgMgr32);
- PF_INIT_OR_OUT(CM_Get_Sibling, CfgMgr32);
- PF_INIT_OR_OUT(CM_Get_Device_IDA, CfgMgr32);
- PF_INIT_OR_OUT(CM_Get_Device_ID_ListA, CfgMgr32);
- PF_INIT_OR_OUT(CM_Get_Device_ID_List_SizeA, CfgMgr32);
- PF_INIT_OR_OUT(CM_Locate_DevNodeA, CfgMgr32);
-
IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList));
ClearDrives();
StrArrayCreate(&dev_if_path, 128);
@@ -555,19 +526,19 @@ BOOL GetDevices(DWORD devnum)
if (SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) {
// Find the Device IDs for all the children of this hub
- if (pfCM_Get_Child(&device_inst, dev_info_data.DevInst, 0) == CR_SUCCESS) {
+ if (CM_Get_Child(&device_inst, dev_info_data.DevInst, 0) == CR_SUCCESS) {
device_id[0] = 0;
s = StrArrayAdd(&dev_if_path, devint_detail_data->DevicePath, TRUE);
uuprintf(" Hub[%d] = '%s'", s, devint_detail_data->DevicePath);
- if ((s>= 0) && (pfCM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS)) {
+ if ((s>= 0) && (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS)) {
ToUpper(device_id);
if ((k = htab_hash(device_id, &htab_devid)) != 0) {
htab_devid.table[k].data = (void*)(uintptr_t)s;
}
uuprintf(" Found ID[%03d]: %s", k, device_id);
- while (pfCM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) {
+ while (CM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) {
device_id[0] = 0;
- if (pfCM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS) {
+ if (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS) {
ToUpper(device_id);
if ((k = htab_hash(device_id, &htab_devid)) != 0) {
htab_devid.table[k].data = (void*)(uintptr_t)s;
@@ -595,7 +566,7 @@ BOOL GetDevices(DWORD devnum)
// Also compute the uasp_start index
if (strcmp(usbstor_name[s], "UASPSTOR") == 0)
uasp_start = s;
- if (pfCM_Get_Device_ID_List_SizeA(&list_size[s], usbstor_name[s], ulFlags) != CR_SUCCESS)
+ if (CM_Get_Device_ID_List_SizeA(&list_size[s], usbstor_name[s], ulFlags) != CR_SUCCESS)
list_size[s] = 0;
if (list_size[s] != 0)
full_list_size += list_size[s]-1; // remove extra NUL terminator
@@ -630,7 +601,7 @@ BOOL GetDevices(DWORD devnum)
for (s = 0, i = 0; s < ARRAYSIZE(usbstor_name); s++) {
list_start[s] = i;
if (list_size[s] > 1) {
- if (pfCM_Get_Device_ID_ListA(usbstor_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS)
+ if (CM_Get_Device_ID_ListA(usbstor_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS)
continue;
if (usb_debug) {
uprintf("Processing IDs belonging to '%s':", usbstor_name[s]);
@@ -737,17 +708,17 @@ BOOL GetDevices(DWORD devnum)
// a lookup table, but there shouldn't be that many USB storage devices connected...
// NB: Each of these Device IDs should have a child, from which we get the Device Instance match.
for (device_id = devid_list; *device_id != 0; device_id += strlen(device_id) + 1) {
- if (pfCM_Locate_DevNodeA(&parent_inst, device_id, 0) != CR_SUCCESS) {
+ if (CM_Locate_DevNodeA(&parent_inst, device_id, 0) != CR_SUCCESS) {
uuprintf("Could not locate device node for '%s'", device_id);
continue;
}
- if (pfCM_Get_Child(&device_inst, parent_inst, 0) != CR_SUCCESS) {
+ if (CM_Get_Child(&device_inst, parent_inst, 0) != CR_SUCCESS) {
uuprintf("Could not get children of '%s'", device_id);
continue;
}
if (device_inst != dev_info_data.DevInst) {
// Try the siblings
- while (pfCM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) {
+ while (CM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) {
if (device_inst == dev_info_data.DevInst) {
uuprintf("NOTE: Matched instance from sibling for '%s'", device_id);
break;
@@ -788,8 +759,8 @@ BOOL GetDevices(DWORD devnum)
// for UASP devices in ASUS "Turbo Mode" or "Apple Mobile Device USB Driver" for iPods)
// so try to see if we can match the grandparent.
if ( ((uintptr_t)htab_devid.table[j].data == 0)
- && (pfCM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS)
- && (pfCM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) {
+ && (CM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS)
+ && (CM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) {
device_id = str;
method_str = "[GP]";
ToUpper(device_id);
diff --git a/src/net.c b/src/net.c
index 76aadcda..a47f076e 100644
--- a/src/net.c
+++ b/src/net.c
@@ -24,12 +24,6 @@
#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
diff --git a/src/rufus.c b/src/rufus.c
index e5f0df56..5b0b7761 100755
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -22,14 +22,6 @@
#include
#endif
-// Temporary workaround for MinGW32 delay-loading
-// See https://github.com/pbatard/rufus/pull/2513 as well as
-// https://sourceware.org/bugzilla/show_bug.cgi?id=14339
-#if defined(__MINGW32__)
-#undef DECLSPEC_IMPORT
-#define DECLSPEC_IMPORT __attribute__((visibility("hidden")))
-#endif
-
#include
#include
#include
@@ -4219,3 +4211,30 @@ out:
return 0;
}
+
+/*
+ * The following adds a Load Configuration section in .rdata for MinGW, that can then be referenced
+ * by a PE post processing script to emulate the /DEPENDENTLOADFLAG:0x800 behaviour of MSVC.
+ * See https://github.com/pbatard/rufus/blob/master/loadcfg.py for such a script.
+ * Note however that, per https://github.com/pbatard/rufus/issues/2701#issuecomment-2874788564
+ * /DEPENDENTLOADFLAG is far from being the ultimate solution to stop DLL side-loading vulnerabilities...
+ */
+#if defined(__MINGW32__)
+// MinGW produces a warning since we don't use this section in the code => silence it.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-const-variable"
+// Add a 16-byte marker for scripts to easily locate this section.
+static const char _load_config_marker[16] __attribute__((aligned(16))) __attribute__((section(".rdata"))) = "_RUFUS_LOAD_CFG";
+#if defined(_M_AMD64)
+static const IMAGE_LOAD_CONFIG_DIRECTORY64 _load_config __attribute__((aligned(16))) __attribute__((section(".rdata"))) = {
+ .Size = sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64),
+ .DependentLoadFlags = LOAD_LIBRARY_SEARCH_SYSTEM32
+};
+#else
+static const IMAGE_LOAD_CONFIG_DIRECTORY32 _load_config __attribute__((aligned(16))) __attribute__((section(".rdata"))) = {
+ .Size = sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32),
+ .DependentLoadFlags = LOAD_LIBRARY_SEARCH_SYSTEM32
+};
+#endif
+#pragma GCC diagnostic pop
+#endif
diff --git a/src/rufus.h b/src/rufus.h
index 174e2a64..ad884e23 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -58,14 +58,13 @@
#endif
#define COMPANY_NAME "Akeo Consulting"
#define STR_NO_LABEL "NO_LABEL"
-// Yes, there exist characters between these seemingly empty quotes!
-#define LEFT_TO_RIGHT_MARK ""
-#define RIGHT_TO_LEFT_MARK ""
-#define LEFT_TO_RIGHT_EMBEDDING ""
-#define RIGHT_TO_LEFT_EMBEDDING ""
-#define POP_DIRECTIONAL_FORMATTING ""
-#define LEFT_TO_RIGHT_OVERRIDE ""
-#define RIGHT_TO_LEFT_OVERRIDE ""
+#define LEFT_TO_RIGHT_MARK "\u200e"
+#define RIGHT_TO_LEFT_MARK "\u200f"
+#define LEFT_TO_RIGHT_EMBEDDING "\u202a"
+#define RIGHT_TO_LEFT_EMBEDDING "\u202b"
+#define POP_DIRECTIONAL_FORMATTING "\u202c"
+#define LEFT_TO_RIGHT_OVERRIDE "\u202d"
+#define RIGHT_TO_LEFT_OVERRIDE "\u202e"
#define DRIVE_ACCESS_TIMEOUT 15000 // How long we should retry drive access (in ms)
#define DRIVE_ACCESS_RETRIES 150 // How many times we should retry
#define DRIVE_INDEX_MIN 0x00000080
diff --git a/src/rufus.rc b/src/rufus.rc
index d4f1775a..0c24d45b 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.8.2243"
+CAPTION "Rufus 4.8.2244"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@@ -407,8 +407,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 4,8,2243,0
- PRODUCTVERSION 4,8,2243,0
+ FILEVERSION 4,8,2244,0
+ PRODUCTVERSION 4,8,2244,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -426,13 +426,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
- VALUE "FileVersion", "4.8.2243"
+ VALUE "FileVersion", "4.8.2244"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", " 2011-2025 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-4.8.exe"
VALUE "ProductName", "Rufus"
- VALUE "ProductVersion", "4.8.2243"
+ VALUE "ProductVersion", "4.8.2244"
END
END
BLOCK "VarFileInfo"
diff --git a/src/vhd.h b/src/vhd.h
index fccf4ca7..a0ce4182 100644
--- a/src/vhd.h
+++ b/src/vhd.h
@@ -19,12 +19,6 @@
#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
diff --git a/src/xml.c b/src/xml.c
index 91c0c54c..4791788b 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -240,8 +240,8 @@ char *ezxml_decode(char *s, char **ent, char t)
l = (d = (long)(s - r)) + c + (long)(e ? strlen(e) : 0); // new length
r = (r == m) ? strcpy(malloc(l), r) : _realloc(r, l);
e = strchr((s = r + d), ';'); // fix up pointers
- if (!e) return r;
}
+ if (!e) return r;
memmove(s + c, e + 1, strlen(e)); // shift rest of string
strncpy_s(s, c, ent[b], _TRUNCATE); // copy in replacement text