diff --git a/.mingw/Makefile.am b/.mingw/Makefile.am index ec826d27..e8d55d27 100644 --- a/.mingw/Makefile.am +++ b/.mingw/Makefile.am @@ -14,11 +14,13 @@ AM_V_SED = $(AM_V_SED_$(V)) # target arch. Oh, and we can't use 'target_cpu' or AC definitions on account that we are # switching archs when building on our local machine, and don't want to have to go though # a costly reconf each time when we can simply issue a 'make clean'. +# Oh, and to find the number after the @ sign, just have a look at the MinGW .a libraries. TUPLE := $(shell $(CC) -dumpmachine) 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 %.def64: %.def diff --git a/.mingw/Makefile.in b/.mingw/Makefile.in index 117eb9c4..8174663d 100644 --- a/.mingw/Makefile.in +++ b/.mingw/Makefile.in @@ -212,6 +212,7 @@ AM_V_SED = $(AM_V_SED_$(V)) # target arch. Oh, and we can't use 'target_cpu' or AC definitions on account that we are # switching archs when building on our local machine, and don't want to have to go though # a costly reconf each time when we can simply issue a 'make clean'. +# Oh, and to find the number after the @ sign, just have a look at the MinGW .a libraries. TUPLE := $(shell $(CC) -dumpmachine) TARGET := $(word 1,$(subst -, ,$(TUPLE))) DEF_SUFFIX := $(if $(TARGET:x86_64=),.def,.def64) @@ -367,6 +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 %.def64: %.def diff --git a/.mingw/cfgmgr32.def b/.mingw/cfgmgr32.def new file mode 100644 index 00000000..81eca2b3 --- /dev/null +++ b/.mingw/cfgmgr32.def @@ -0,0 +1,10 @@ +EXPORTS + CM_Get_Device_IDA@16 + CM_Get_Device_ID_List_SizeA@12 + CM_Get_Device_ID_ListA@16 + CM_Locate_DevNodeA@12 + CM_Get_Child@12 + CM_Get_Sibling@12 + CM_Get_Parent@12 + CM_Get_DevNode_Status@16 + CM_Get_DevNode_Registry_PropertyA@24 diff --git a/Makefile.am b/Makefile.am index dfc8d20d..e3145a67 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,6 +3,9 @@ TARGET = rufus TAGVER = $(shell git log --oneline | wc -l) SEDCMD = s/^\([ \t]*\)Version="\([0-9]*\)\.\([0-9]*\)\.[0-9]*\.\([0-9]*\)"\(.*\)/\1Version="\2.\3.@@TAGVER@@.\4"\5/ +upx: all + @upx --lzma --best src/$(TARGET)$(EXEEXT) + # This step produces the UPX compressed and signed releases that are made available for public download # NB: UPX v3.09 or later is needed for LZMA compression (http://upx.sourceforge.net/) release: all diff --git a/Makefile.in b/Makefile.in index a3c4e7db..ef78f444 100644 --- a/Makefile.in +++ b/Makefile.in @@ -502,6 +502,9 @@ uninstall-am: pdf-am ps ps-am tags tags-am uninstall uninstall-am +upx: all + @upx --lzma --best src/$(TARGET)$(EXEEXT) + # This step produces the UPX compressed and signed releases that are made available for public download # NB: UPX v3.09 or later is needed for LZMA compression (http://upx.sourceforge.net/) release: all diff --git a/src/Makefile.am b/src/Makefile.am index f9416588..7f68b39b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,9 +2,9 @@ SUBDIRS = ../.mingw bled ext2fs ms-sys syslinux/libfat syslinux/libinstaller sys # 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 # 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/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 noinst_PROGRAMS = rufus diff --git a/src/Makefile.in b/src/Makefile.in index 1b3d4e3c..e3132680 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -276,9 +276,9 @@ SUBDIRS = ../.mingw bled ext2fs ms-sys syslinux/libfat syslinux/libinstaller sys # 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 # 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/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 AM_V_WINDRES_0 = @echo " RC $@";$(WINDRES) AM_V_WINDRES_1 = $(WINDRES) diff --git a/src/dev.c b/src/dev.c index a5768a8f..cbecdda2 100644 --- a/src/dev.c +++ b/src/dev.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Device detection and enumeration - * Copyright © 2014-2024 Pete Batard + * Copyright © 2014-2025 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -49,6 +49,21 @@ 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 */ @@ -65,7 +80,10 @@ static BOOL GetUSBProperties(char* parent_path, char* device_id, usb_device_prop if ((parent_path == NULL) || (device_id == NULL) || (props == NULL)) goto out; - cr = CM_Locate_DevNodeA(&device_inst, device_id, 0); + 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); if (cr != CR_SUCCESS) { uprintf("Could not get device instance handle for '%s': CR error %d", device_id, cr); goto out; @@ -73,7 +91,7 @@ static BOOL GetUSBProperties(char* parent_path, char* device_id, usb_device_prop props->port = 0; size = sizeof(props->port); - cr = CM_Get_DevNode_Registry_PropertyA(device_inst, CM_DRP_ADDRESS, NULL, (PVOID)&props->port, &size, 0); + cr = pfCM_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; @@ -196,6 +214,8 @@ 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) { @@ -218,7 +238,7 @@ int CycleDevice(int index) found = TRUE; // Detect if the device is already disabled - if (CM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS) + if (pfCM_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 @@ -267,7 +287,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 (CM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS) { + if (pfCM_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; @@ -278,6 +298,7 @@ int CycleDevice(int index) SetupDiDestroyDeviceInfoList(dev_info); if (!found) uprintf("Could not find a device to cycle!"); +out: return ret; } @@ -473,7 +494,7 @@ BOOL GetDevices(DWORD devnum) const char* windows_sandbox_vhd_label = "PortableBaseLayer"; // Hash table and String Array used to match a Device ID with the parent hub's Device Interface Path htab_table htab_devid = HTAB_EMPTY; - StrArray dev_if_path; + StrArray dev_if_path = STRARRAY_EMPTY; char letter_name[] = " (?:)"; char drive_name[] = "?:\\"; char setting_name[32]; @@ -497,6 +518,14 @@ 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); @@ -526,19 +555,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 (CM_Get_Child(&device_inst, dev_info_data.DevInst, 0) == CR_SUCCESS) { + if (pfCM_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) && (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS)) { + if ((s>= 0) && (pfCM_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 (CM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) { + while (pfCM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) { device_id[0] = 0; - if (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS) { + if (pfCM_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; @@ -566,7 +595,7 @@ BOOL GetDevices(DWORD devnum) // Also compute the uasp_start index if (strcmp(usbstor_name[s], "UASPSTOR") == 0) uasp_start = s; - if (CM_Get_Device_ID_List_SizeA(&list_size[s], usbstor_name[s], ulFlags) != CR_SUCCESS) + if (pfCM_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 @@ -601,7 +630,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 (CM_Get_Device_ID_ListA(usbstor_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS) + if (pfCM_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]); @@ -708,17 +737,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 (CM_Locate_DevNodeA(&parent_inst, device_id, 0) != CR_SUCCESS) { + if (pfCM_Locate_DevNodeA(&parent_inst, device_id, 0) != CR_SUCCESS) { uuprintf("Could not locate device node for '%s'", device_id); continue; } - if (CM_Get_Child(&device_inst, parent_inst, 0) != CR_SUCCESS) { + if (pfCM_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 (CM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) { + while (pfCM_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; @@ -759,8 +788,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) - && (CM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS) - && (CM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) { + && (pfCM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS) + && (pfCM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) { device_id = str; method_str = "[GP]"; ToUpper(device_id); diff --git a/src/dev.h b/src/dev.h index f7415295..ea610ad5 100644 --- a/src/dev.h +++ b/src/dev.h @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Device detection and enumeration - * Copyright © 2014-2019 Pete Batard + * Copyright © 2014-2025 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,20 +46,6 @@ typedef struct usb_device_props { /* * Windows DDK API definitions. Most of it copied from MinGW's includes */ -typedef DWORD DEVNODE, DEVINST; -typedef DEVNODE *PDEVNODE, *PDEVINST; -typedef DWORD RETURN_TYPE; -typedef RETURN_TYPE CONFIGRET; -typedef CHAR *DEVINSTID_A; - -#ifndef CM_GETIDLIST_FILTER_PRESENT -#define CM_GETIDLIST_FILTER_PRESENT 0x00000100 -#endif - -#ifndef FILE_DEVICE_USB -#define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN -#endif - typedef enum USB_CONNECTION_STATUS { NoDeviceConnected, DeviceConnected, @@ -77,26 +63,16 @@ typedef enum USB_HUB_NODE { UsbMIParent } USB_HUB_NODE; -/* Cfgmgr32.dll interface */ -DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST dnDevInst, CHAR* Buffer, ULONG BufferLen, ULONG ulFlags); -DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(PULONG pulLen, PCSTR pszFilter, ULONG ulFlags); -DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_ID_ListA(PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags); -DECLSPEC_IMPORT CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags); -DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Child(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags); -DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Parent(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags); -DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Sibling(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags); -DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_DevNode_Status(PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst, ULONG ulFlags); - #define USB_HUB_CYCLE_PORT 273 #define USB_GET_NODE_CONNECTION_INFORMATION_EX 274 #define USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 279 #define IOCTL_USB_HUB_CYCLE_PORT \ - CTL_CODE(FILE_DEVICE_USB, USB_HUB_CYCLE_PORT, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, USB_HUB_CYCLE_PORT, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \ - CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 \ - CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, METHOD_BUFFERED, FILE_ANY_ACCESS) + CTL_CODE(FILE_DEVICE_UNKNOWN, USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, METHOD_BUFFERED, FILE_ANY_ACCESS) /* Most of the structures below need to be packed */ #pragma pack(push, 1) diff --git a/src/rufus.c b/src/rufus.c index 5e3d2ce3..ece1bd6c 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -3257,19 +3257,31 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine {0, 0, NULL, 0} }; - // Disable loading system DLLs from the current directory (sideloading mitigation) + // Disable loading system DLLs from the current directory (side-loading mitigation) // PS: You know that official MSDN documentation for SetDllDirectory() that explicitly // indicates that "If the parameter is an empty string (""), the call removes the current - // directory from the default DLL search order"? Yeah, that doesn't work. At all. - // Still, we invoke it, for platforms where the following call might actually work... - SetDllDirectoryA(""); + // directory from the default DLL search order"? Yeah, that doesn't work. At all. And as + // a matter of fact, Microsoft has now altered their doc to remove that part, though it + // is still *currently* being mentioned in their doc for Dynamic-Link Library Security: + // https://web.archive.org/web/20250206201109/https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-security + // So, Microsoft currently offers NO WAY to easily disable the main vulnerability most + // applications suffer from, which is the loading of bloody DLLs from the current/app + // dir, even for executables, like Rufus, that are designed from the get go to NEVER EVER + // rely on any DLLs there, and would like to DISABLE THIS UTTER BULLSHIT OF AN ENTIRELY + // PREVENTABLE SECURITY RISK! The end result of all this is that we have to contend with + // delay loading (*when* it actually works) or direct hooking (when it doesn't) and no + // longer try to bother with a quick and easy side-loading fix that Microsoft has been + // dangling as a lure, for years, but hasn't actually bothered to implement... + // SetDllDirectoryA(""); // For libraries on the KnownDLLs list, the system will always load them from System32. // For other DLLs we link directly to, we can delay load the DLL and use a delay load // hook to load them from System32. Note that, for this to work, something like: // 'somelib.dll;%(DelayLoadDLLs)' must be added to the 'Delay Loaded Dlls' option of - // the linker properties in Visual Studio (which means this won't work with MinGW). - // For all other DLLs, use SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32). + // the linker properties in Visual Studio... which means this won't work with MinGW. + // For all other DLLs, use SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32), + // though this *STILL* does not prevent the Windows default of looking for DLLs in the + // current directories. SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32); uprintf("*** " APPLICATION_NAME " init ***\n"); diff --git a/src/rufus.h b/src/rufus.h index 507e66c4..50fb29fd 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -1,6 +1,6 @@ /* * Rufus: The Reliable USB Formatting Utility - * Copyright © 2011-2024 Pete Batard + * Copyright © 2011-2025 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -690,6 +690,7 @@ typedef struct { uint32_t Index; // Current array size uint32_t Max; // Maximum array size } StrArray; +#define STRARRAY_EMPTY { NULL, 0, 0 }; extern void StrArrayCreate(StrArray* arr, uint32_t initial_size); extern int32_t StrArrayAdd(StrArray* arr, const char* str, BOOL); extern int32_t StrArrayFind(StrArray* arr, const char* str); diff --git a/src/rufus.rc b/src/rufus.rc index 8c8fc306..7d05622c 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.7.2221" +CAPTION "Rufus 4.7.2222" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -399,8 +399,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,7,2221,0 - PRODUCTVERSION 4,7,2221,0 + FILEVERSION 4,7,2222,0 + PRODUCTVERSION 4,7,2222,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -418,13 +418,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.7.2221" + VALUE "FileVersion", "4.7.2222" 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.7.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.7.2221" + VALUE "ProductVersion", "4.7.2222" END END BLOCK "VarFileInfo"