1
1
Fork 0
mirror of https://github.com/pbatard/rufus.git synced 2024-08-14 23:57:05 +00:00

[misc] improve Windows version detection

* Also use actual Windows major.minor when checking for updates
This commit is contained in:
Pete Batard 2023-04-17 13:33:05 +01:00
parent 6280e8020a
commit e5f90282ed
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
10 changed files with 83 additions and 77 deletions

View file

@ -73,7 +73,7 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryVolumeInformationFile, (HANDLE, PIO_STATUS_
*/ */
RUFUS_DRIVE_INFO SelectedDrive; RUFUS_DRIVE_INFO SelectedDrive;
extern BOOL write_as_esp; extern BOOL write_as_esp;
extern int nWindowsVersion, nWindowsBuildNumber; extern windows_version_t WindowsVersion;
uint64_t partition_offset[PI_MAX]; uint64_t partition_offset[PI_MAX];
uint64_t persistence_size = 0; uint64_t persistence_size = 0;
@ -1592,7 +1592,7 @@ BOOL ToggleEsp(DWORD DriveIndex, uint64_t PartitionOffset)
{ 0x0c, { 'F', 'A', 'T', '3', '2', ' ', ' ', ' ' } }, { 0x0c, { 'F', 'A', 'T', '3', '2', ' ', ' ', ' ' } },
}; };
if ((PartitionOffset == 0) && (nWindowsVersion < WINDOWS_10)) { if ((PartitionOffset == 0) && (WindowsVersion.Version < WINDOWS_10)) {
uprintf("ESP toggling is only available for Windows 10 or later"); uprintf("ESP toggling is only available for Windows 10 or later");
return FALSE; return FALSE;
} }
@ -2318,7 +2318,7 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
// Having the ESP up front may help (and is the Microsoft recommended way) but this // Having the ESP up front may help (and is the Microsoft recommended way) but this
// is only achievable if we can mount more than one partition at once, which means // is only achievable if we can mount more than one partition at once, which means
// either fixed drive or Windows 10 1703 or later. // either fixed drive or Windows 10 1703 or later.
if (((SelectedDrive.MediaType == FixedMedia) || (nWindowsBuildNumber > 15000)) && if (((SelectedDrive.MediaType == FixedMedia) || (WindowsVersion.BuildNumber > 15000)) &&
(extra_partitions & XP_ESP)) { (extra_partitions & XP_ESP)) {
assert(partition_style == PARTITION_STYLE_GPT); assert(partition_style == PARTITION_STYLE_GPT);
extra_part_name = L"EFI System Partition"; extra_part_name = L"EFI System Partition";

View file

@ -1423,7 +1423,7 @@ DWORD WINAPI FormatThread(void* param)
BOOL ret, use_large_fat32, windows_to_go, actual_lock_drive = lock_drive, write_as_ext = FALSE; BOOL ret, use_large_fat32, windows_to_go, actual_lock_drive = lock_drive, write_as_ext = FALSE;
// Windows 11 and VDS (which I suspect is what fmifs.dll's FormatEx() is now calling behind the scenes) // Windows 11 and VDS (which I suspect is what fmifs.dll's FormatEx() is now calling behind the scenes)
// require us to unlock the physical drive to format the drive, else access denied is returned. // require us to unlock the physical drive to format the drive, else access denied is returned.
BOOL need_logical = FALSE, must_unlock_physical = (use_vds || nWindowsVersion >= WINDOWS_11); BOOL need_logical = FALSE, must_unlock_physical = (use_vds || WindowsVersion.Version >= WINDOWS_11);
DWORD cr, DriveIndex = (DWORD)(uintptr_t)param, ClusterSize, Flags; DWORD cr, DriveIndex = (DWORD)(uintptr_t)param, ClusterSize, Flags;
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
HANDLE hLogicalVolume = INVALID_HANDLE_VALUE; HANDLE hLogicalVolume = INVALID_HANDLE_VALUE;
@ -1462,7 +1462,7 @@ DWORD WINAPI FormatThread(void* param)
actual_lock_drive = FALSE; actual_lock_drive = FALSE;
// Windows 11 is a lot more proactive in locking ESPs and MSRs than previous versions // Windows 11 is a lot more proactive in locking ESPs and MSRs than previous versions
// were, meaning that we also can't lock the drive without incurring errors... // were, meaning that we also can't lock the drive without incurring errors...
if ((nWindowsVersion >= WINDOWS_11) && extra_partitions) if ((WindowsVersion.Version >= WINDOWS_11) && extra_partitions)
actual_lock_drive = FALSE; actual_lock_drive = FALSE;
// Fixed drives + ext2/ext3 don't play nice and require the same handling as ESPs // Fixed drives + ext2/ext3 don't play nice and require the same handling as ESPs
write_as_ext = IS_EXT(fs_type) && (GetDriveTypeFromIndex(DriveIndex) == DRIVE_FIXED); write_as_ext = IS_EXT(fs_type) && (GetDriveTypeFromIndex(DriveIndex) == DRIVE_FIXED);

View file

@ -309,7 +309,7 @@ static HINTERNET GetInternetSession(BOOL bRetry)
} }
static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)",
rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[0], rufus_version[1], rufus_version[2],
nWindowsVersion >> 4, nWindowsVersion & 0x0F, is_x64() ? "; WOW64" : ""); WindowsVersion.Major, WindowsVersion.Minor, is_x64() ? "; WOW64" : "");
hSession = pfInternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); hSession = pfInternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
// Set the timeouts // Set the timeouts
pfInternetSetOptionA(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout)); pfInternetSetOptionA(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout));
@ -631,7 +631,6 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
char agent[64], hostname[64], urlpath[128], sigpath[256]; char agent[64], hostname[64], urlpath[128], sigpath[256];
DWORD dwSize, dwDownloaded, dwTotalSize, dwStatus; DWORD dwSize, dwDownloaded, dwTotalSize, dwStatus;
BYTE *sig = NULL; BYTE *sig = NULL;
OSVERSIONINFOA os_version = { sizeof(OSVERSIONINFOA), 0, 0, 0, 0, "" };
HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL; HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL;
URL_COMPONENTSA UrlParts = { sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, URL_COMPONENTSA UrlParts = { sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0,
hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1 }; hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1 };
@ -692,22 +691,18 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
PrintInfoDebug(3000, MSG_243); PrintInfoDebug(3000, MSG_243);
status++; // 1 status++; // 1
if (!GetVersionExA(&os_version)) {
uprintf("Could not read Windows version - Check for updates cancelled.");
goto out;
}
if (!pfInternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts)) if (!pfInternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts))
goto out; goto out;
hostname[sizeof(hostname)-1] = 0; hostname[sizeof(hostname)-1] = 0;
static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)", static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %d.%d%s)",
rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[0], rufus_version[1], rufus_version[2],
nWindowsVersion >> 4, nWindowsVersion & 0x0F, is_x64() ? "; WOW64" : ""); WindowsVersion.Major, WindowsVersion.Minor, is_x64() ? "; WOW64" : "");
hSession = GetInternetSession(FALSE); hSession = GetInternetSession(FALSE);
if (hSession == NULL) if (hSession == NULL)
goto out; goto out;
hConnection = pfInternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); hConnection = pfInternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort,
NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL);
if (hConnection == NULL) if (hConnection == NULL)
goto out; goto out;
@ -723,7 +718,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
max_channel = releases_only ? 1 : (int)ARRAYSIZE(channel) - 1; max_channel = releases_only ? 1 : (int)ARRAYSIZE(channel) - 1;
#endif #endif
vuprintf("Using %s for the update check", RUFUS_URL); vuprintf("Using %s for the update check", RUFUS_URL);
for (k=0; (k<max_channel) && (!found_new_version); k++) { for (k = 0; (k < max_channel) && (!found_new_version); k++) {
// Free any previous buffers we might have used // Free any previous buffers we might have used
safe_free(buf); safe_free(buf);
safe_free(sig); safe_free(sig);
@ -734,7 +729,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
// look for rufus_win_x64_6.2.ver (Win8 x64) but only get a match for rufus_win_x64_6.ver (Vista x64 or later) // look for rufus_win_x64_6.2.ver (Win8 x64) but only get a match for rufus_win_x64_6.ver (Vista x64 or later)
// This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups. // This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups.
static_sprintf(urlpath, "%s%s%s_win_%s_%lu.%lu.ver", APPLICATION_NAME, (k == 0) ? "": "_", static_sprintf(urlpath, "%s%s%s_win_%s_%lu.%lu.ver", APPLICATION_NAME, (k == 0) ? "": "_",
(k == 0) ? "" : channel[k], GetAppArchName(), os_version.dwMajorVersion, os_version.dwMinorVersion); (k == 0) ? "" : channel[k], GetAppArchName(), WindowsVersion.Major, WindowsVersion.Minor);
vuprintf("Base update check: %s", urlpath); vuprintf("Base update check: %s", urlpath);
for (i = 0, j = (int)safe_strlen(urlpath) - 5; (j > 0) && (i < ARRAYSIZE(verpos)); j--) { for (i = 0, j = (int)safe_strlen(urlpath) - 5; (j > 0) && (i < ARRAYSIZE(verpos)); j--) {
if ((urlpath[j] == '.') || (urlpath[j] == '_')) { if ((urlpath[j] == '.') || (urlpath[j] == '_')) {
@ -825,8 +820,8 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
vuprintf(" url: %s", update.download_url); vuprintf(" url: %s", update.download_url);
found_new_version = ((to_uint64_t(update.version) > to_uint64_t(rufus_version)) || (force_update)) found_new_version = ((to_uint64_t(update.version) > to_uint64_t(rufus_version)) || (force_update))
&& ((os_version.dwMajorVersion > update.platform_min[0]) && ((WindowsVersion.Major > update.platform_min[0])
|| ((os_version.dwMajorVersion == update.platform_min[0]) && (os_version.dwMinorVersion >= update.platform_min[1]))); || ((WindowsVersion.Major == update.platform_min[0]) && (WindowsVersion.Minor >= update.platform_min[1])));
uprintf("N%sew %s version found%c", found_new_version ? "" : "o n", channel[k], found_new_version ? '!' : '.'); uprintf("N%sew %s version found%c", found_new_version ? "" : "o n", channel[k], found_new_version ? '!' : '.');
} }

View file

@ -226,10 +226,10 @@ static void SetBootOptions(void)
IGNORE_RETVAL(ComboBox_ResetContent(hBootType)); IGNORE_RETVAL(ComboBox_ResetContent(hBootType));
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, lmprintf(MSG_279)), BT_NON_BOOTABLE)); IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, lmprintf(MSG_279)), BT_NON_BOOTABLE));
if (nWindowsVersion < WINDOWS_10) // The diskcopy.dll along with its MS-DOS floppy image was removed in Windows 10 if (WindowsVersion.Version < WINDOWS_10) // The diskcopy.dll along with its MS-DOS floppy image was removed in Windows 10
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "MS-DOS"), BT_MSDOS)); IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "MS-DOS"), BT_MSDOS));
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), BT_FREEDOS)); IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), BT_FREEDOS));
image_index = (nWindowsVersion < WINDOWS_10) ? 3 : 2; image_index = (WindowsVersion.Version < WINDOWS_10) ? 3 : 2;
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType,
(image_path == NULL) ? lmprintf(MSG_281, lmprintf(MSG_280)) : short_image_path), BT_IMAGE)); (image_path == NULL) ? lmprintf(MSG_281, lmprintf(MSG_280)) : short_image_path), BT_IMAGE));
@ -411,12 +411,12 @@ static BOOL IsRefsAvailable(MEDIA_TYPE MediaType)
if (MediaType != FixedMedia) if (MediaType != FixedMedia)
return FALSE; return FALSE;
if (nWindowsVersion < WINDOWS_8_1 || nWindowsBuildNumber <= 0) if (WindowsVersion.Version < WINDOWS_8_1 || WindowsVersion.BuildNumber <= 0)
return FALSE; return FALSE;
// Per https://gist.github.com/0xbadfca11/da0598e47dd643d933dc // Per https://gist.github.com/0xbadfca11/da0598e47dd643d933dc
if (nWindowsBuildNumber < 16226) if (WindowsVersion.BuildNumber < 16226)
return TRUE; return TRUE;
switch (nWindowsEdition) { switch (WindowsVersion.Edition) {
case 0x0000000A: // Enterprise Server case 0x0000000A: // Enterprise Server
case 0x0000001B: // Enterprise N case 0x0000001B: // Enterprise N
case 0x00000046: // Enterprise E case 0x00000046: // Enterprise E
@ -1494,7 +1494,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
goto out; goto out;
} }
if (SelectedDrive.MediaType != FixedMedia) { if (SelectedDrive.MediaType != FixedMedia) {
if ((target_type == TT_UEFI) && (partition_type == PARTITION_STYLE_GPT) && (nWindowsBuildNumber < 15000)) { if ((target_type == TT_UEFI) && (partition_type == PARTITION_STYLE_GPT) && (WindowsVersion.BuildNumber < 15000)) {
// Up to Windows 10 Creators Update (1703), we were screwed, since we need access to 2 partitions at the same time. // Up to Windows 10 Creators Update (1703), we were screwed, since we need access to 2 partitions at the same time.
// Thankfully, the newer Windows allow mounting multiple partitions on the same REMOVABLE drive. // Thankfully, the newer Windows allow mounting multiple partitions on the same REMOVABLE drive.
MessageBoxExU(hMainDialog, lmprintf(MSG_198), lmprintf(MSG_190), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); MessageBoxExU(hMainDialog, lmprintf(MSG_198), lmprintf(MSG_190), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
@ -1511,7 +1511,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
default: default:
break; break;
} }
if ((nWindowsVersion >= WINDOWS_8) && IS_WINDOWS_1X(img_report)) { if ((WindowsVersion.Version >= WINDOWS_8) && IS_WINDOWS_1X(img_report)) {
StrArray options; StrArray options;
int arch = _log2(img_report.has_efi >> 1); int arch = _log2(img_report.has_efi >> 1);
uint8_t map[8] = { 0 }, b = 1; uint8_t map[8] = { 0 }, b = 1;
@ -1573,7 +1573,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
MessageBoxExU(hMainDialog, lmprintf(MSG_100), lmprintf(MSG_099), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid); MessageBoxExU(hMainDialog, lmprintf(MSG_100), lmprintf(MSG_099), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid);
goto out; goto out;
} }
if ((nWindowsVersion >= WINDOWS_8) && IS_WINDOWS_1X(img_report) && (!is_windows_to_go)) { if ((WindowsVersion.Version >= WINDOWS_8) && IS_WINDOWS_1X(img_report) && (!is_windows_to_go)) {
StrArray options; StrArray options;
int arch = _log2(img_report.has_efi >> 1); int arch = _log2(img_report.has_efi >> 1);
uint8_t map[8] = { 0 }, b = 1; uint8_t map[8] = { 0 }, b = 1;
@ -2041,7 +2041,7 @@ static void InitDialog(HWND hDlg)
free(buf); free(buf);
} }
} }
uprintf("Windows version: %s", WindowsVersionStr); uprintf("Windows version: %s", WindowsVersion.VersionStr);
uprintf("Syslinux versions: %s%s, %s%s", embedded_sl_version_str[0], embedded_sl_version_ext[0], uprintf("Syslinux versions: %s%s, %s%s", embedded_sl_version_str[0], embedded_sl_version_ext[0],
embedded_sl_version_str[1], embedded_sl_version_ext[1]); embedded_sl_version_str[1], embedded_sl_version_ext[1]);
uprintf("Grub versions: %s, %s", GRUB4DOS_VERSION, GRUB2_PACKAGE_VERSION); uprintf("Grub versions: %s, %s", GRUB4DOS_VERSION, GRUB2_PACKAGE_VERSION);
@ -2453,7 +2453,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
nHeight = DialogRect.bottom - DialogRect.top; nHeight = DialogRect.bottom - DialogRect.top;
GetWindowRect(hDlg, &DialogRect); GetWindowRect(hDlg, &DialogRect);
offset = GetSystemMetrics(SM_CXBORDER); offset = GetSystemMetrics(SM_CXBORDER);
if (nWindowsVersion >= WINDOWS_10) { if (WindowsVersion.Version >= WINDOWS_10) {
// See https://stackoverflow.com/a/42491227/1069307 // See https://stackoverflow.com/a/42491227/1069307
// I agree with Stephen Hazel: Whoever at Microsoft thought it would be a great idea to // I agree with Stephen Hazel: Whoever at Microsoft thought it would be a great idea to
// add a *FRIGGING INVISIBLE BORDER* in Windows 10 should face the harshest punishment! // add a *FRIGGING INVISIBLE BORDER* in Windows 10 should face the harshest punishment!
@ -2925,7 +2925,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
// The things one must do to get an ellipsis and text alignment on the status bar... // The things one must do to get an ellipsis and text alignment on the status bar...
if (wParam == IDC_STATUS) { if (wParam == IDC_STATUS) {
pDI = (DRAWITEMSTRUCT*)lParam; pDI = (DRAWITEMSTRUCT*)lParam;
if (nWindowsVersion >= WINDOWS_10) if (WindowsVersion.Version >= WINDOWS_10)
pDI->rcItem.top += (int)(1.0f * fScale); pDI->rcItem.top += (int)(1.0f * fScale);
else if (fScale >= 1.49f) else if (fScale >= 1.49f)
pDI->rcItem.top -= (int)(1.5f * fScale); pDI->rcItem.top -= (int)(1.5f * fScale);
@ -3207,7 +3207,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
if (BlockingProcess.Index > 0) { if (BlockingProcess.Index > 0) {
ListDialog(lmprintf(MSG_042), lmprintf(MSG_055), BlockingProcess.String, BlockingProcess.Index); ListDialog(lmprintf(MSG_042), lmprintf(MSG_055), BlockingProcess.String, BlockingProcess.Index);
} else { } else {
if (nWindowsVersion >= WINDOWS_10) { if (WindowsVersion.Version >= WINDOWS_10) {
// Try to detect if 'Controlled Folder Access' is enabled on Windows 10 or later. See also: // Try to detect if 'Controlled Folder Access' is enabled on Windows 10 or later. See also:
// http://www.winhelponline.com/blog/use-controlled-folder-access-windows-10-windows-defender // http://www.winhelponline.com/blog/use-controlled-folder-access-windows-10-windows-defender
char cmdline[256]; char cmdline[256];
@ -3402,6 +3402,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
uprintf("*** " APPLICATION_NAME " init ***\n"); uprintf("*** " APPLICATION_NAME " init ***\n");
its_a_me_mario = GetUserNameA((char*)(uintptr_t)&u, &size) && (u == 7104878); its_a_me_mario = GetUserNameA((char*)(uintptr_t)&u, &size) && (u == 7104878);
// coverity[pointless_string_compare] // coverity[pointless_string_compare]
// TODO: We'll need to change this when/if we switch to x86_64 default binary
is_x86_32 = (strcmp(APPLICATION_ARCH, "x86") == 0); is_x86_32 = (strcmp(APPLICATION_ARCH, "x86") == 0);
// Retrieve various app & system directories. // Retrieve various app & system directories.
@ -3678,20 +3679,22 @@ skip_args_processing:
selected_langid = get_language_id(selected_locale); selected_langid = get_language_id(selected_locale);
// Set the Windows version // Set the Windows version
GetWindowsVersion(); GetWindowsVersion(&WindowsVersion);
// Force a version if specified as parameter, but without allowing folks running // Force a version if specified as parameter, but without allowing folks running
// a version of Windows we no longer support to use the option as a bypass! // a version of Windows we no longer support to use the option as a bypass!
if (nWindowsVersion > WINDOWS_7 && forced_windows_version != 0) if (WindowsVersion.Version > WINDOWS_7 && forced_windows_version != 0)
nWindowsVersion = forced_windows_version; WindowsVersion.Version = forced_windows_version;
// ...and nothing of value was lost // ...and nothing of value was lost
if (nWindowsVersion <= WINDOWS_7) { if (WindowsVersion.Version <= WINDOWS_7) {
// Load the translation before we print the error // Load the translation before we print the error
get_loc_data_file(loc_file, selected_locale); get_loc_data_file(loc_file, selected_locale);
right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT); right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT);
// Set MB_SYSTEMMODAL to prevent Far Manager from stealing focus... // Set MB_SYSTEMMODAL to prevent Far Manager from stealing focus...
MessageBoxExU(NULL, MessageBoxExU(NULL,
lmprintf(MSG_294, (nWindowsVersion == WINDOWS_7) ? 3 : 2, (nWindowsVersion == WINDOWS_7) ? 22 : 18), lmprintf(MSG_294,
(WindowsVersion.Version == WINDOWS_7) ? 3 : 2,
(WindowsVersion.Version == WINDOWS_7) ? 22 : 18),
lmprintf(MSG_293), MB_ICONSTOP | MB_IS_RTL | MB_SYSTEMMODAL, selected_langid); lmprintf(MSG_293), MB_ICONSTOP | MB_IS_RTL | MB_SYSTEMMODAL, selected_langid);
goto out; goto out;
} }

View file

@ -478,8 +478,7 @@ typedef enum TASKBAR_PROGRESS_FLAGS
/* Windows versions */ /* Windows versions */
enum WindowsVersion { enum WindowsVersion {
WINDOWS_UNDEFINED = -1, WINDOWS_UNDEFINED = 0,
WINDOWS_UNSUPPORTED = 0,
WINDOWS_XP = 0x51, WINDOWS_XP = 0x51,
WINDOWS_2003 = 0x52, // Also XP_64 WINDOWS_2003 = 0x52, // Also XP_64
WINDOWS_VISTA = 0x60, // Also Server 2008 WINDOWS_VISTA = 0x60, // Also Server 2008
@ -489,7 +488,7 @@ enum WindowsVersion {
WINDOWS_10_PREVIEW1 = 0x64, WINDOWS_10_PREVIEW1 = 0x64,
WINDOWS_10 = 0xA0, // Also Server 2016, also Server 2019 WINDOWS_10 = 0xA0, // Also Server 2016, also Server 2019
WINDOWS_11 = 0xB0, // Also Server 2022 WINDOWS_11 = 0xB0, // Also Server 2022
WINDOWS_MAX WINDOWS_MAX = 0xFFFF,
}; };
enum ArchType { enum ArchType {
@ -506,6 +505,15 @@ enum ArchType {
ARCH_MAX ARCH_MAX
}; };
typedef struct {
DWORD Version;
DWORD Major;
DWORD Minor;
DWORD BuildNumber;
DWORD Edition;
char VersionStr[128];
} windows_version_t;
// Windows User Experience (unattend.xml) flags and masks // Windows User Experience (unattend.xml) flags and masks
#define UNATTEND_SECUREBOOT_TPM_MINRAM 0x00001 #define UNATTEND_SECUREBOOT_TPM_MINRAM 0x00001
#define UNATTEND_NO_ONLINE_ACCOUNT 0x00004 #define UNATTEND_NO_ONLINE_ACCOUNT 0x00004
@ -545,17 +553,17 @@ extern uint64_t persistence_size;
extern size_t ubuffer_pos; extern size_t ubuffer_pos;
extern const int nb_steps[FS_MAX]; extern const int nb_steps[FS_MAX];
extern float fScale; extern float fScale;
extern int nWindowsVersion, nWindowsBuildNumber, nWindowsEdition, dialog_showing, force_update; extern windows_version_t WindowsVersion;
extern int fs_type, boot_type, partition_type, target_type; extern int dialog_showing, force_update, fs_type, boot_type, partition_type, target_type;
extern unsigned long syslinux_ldlinux_len[2]; extern unsigned long syslinux_ldlinux_len[2];
extern char WindowsVersionStr[128], ubuffer[UBUFFER_SIZE], embedded_sl_version_str[2][12]; extern char ubuffer[UBUFFER_SIZE], embedded_sl_version_str[2][12];
extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH], temp_dir[MAX_PATH], system_dir[MAX_PATH], sysnative_dir[MAX_PATH]; extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH], temp_dir[MAX_PATH], system_dir[MAX_PATH], sysnative_dir[MAX_PATH];
extern char app_data_dir[MAX_PATH], *image_path, *fido_url; extern char app_data_dir[MAX_PATH], *image_path, *fido_url;
/* /*
* Shared prototypes * Shared prototypes
*/ */
extern void GetWindowsVersion(void); extern void GetWindowsVersion(windows_version_t* WindowsVersion);
extern BOOL is_x64(void); extern BOOL is_x64(void);
extern const char* GetAppArchName(void); extern const char* GetAppArchName(void);
extern const char* WindowsErrorString(void); extern const char* WindowsErrorString(void);

View file

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326 IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 3.23.2020" CAPTION "Rufus 3.23.2021"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0 FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -392,8 +392,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,23,2020,0 FILEVERSION 3,23,2021,0
PRODUCTVERSION 3,23,2020,0 PRODUCTVERSION 3,23,2021,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -411,13 +411,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie" VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting" VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "3.23.2020" VALUE "FileVersion", "3.23.2021"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-3.23.exe" VALUE "OriginalFilename", "rufus-3.23.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.23.2020" VALUE "ProductVersion", "3.23.2021"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -1,7 +1,7 @@
/* /*
* Rufus: The Reliable USB Formatting Utility * Rufus: The Reliable USB Formatting Utility
* Standard Windows function calls * Standard Windows function calls
* Copyright © 2013-2022 Pete Batard <pete@akeo.ie> * Copyright © 2013-2023 Pete Batard <pete@akeo.ie>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -34,10 +34,7 @@
#include "settings.h" #include "settings.h"
int nWindowsVersion = WINDOWS_UNDEFINED; windows_version_t WindowsVersion = { 0 };
int nWindowsBuildNumber = -1;
int nWindowsEdition = 0;
char WindowsVersionStr[128] = "Windows ";
/* /*
* Hash table functions - modified From glibc 2.3.2: * Hash table functions - modified From glibc 2.3.2:
@ -339,7 +336,7 @@ static const char* GetEdition(DWORD ProductType)
/* /*
* Modified from smartmontools' os_win32.cpp * Modified from smartmontools' os_win32.cpp
*/ */
void GetWindowsVersion(void) void GetWindowsVersion(windows_version_t* WindowsVersion)
{ {
OSVERSIONINFOEXA vi, vi2; OSVERSIONINFOEXA vi, vi2;
DWORD dwProductType = 0; DWORD dwProductType = 0;
@ -347,12 +344,12 @@ void GetWindowsVersion(void)
const char* w64 = "32 bit"; const char* w64 = "32 bit";
char *vptr; char *vptr;
size_t vlen; size_t vlen;
unsigned major, minor; DWORD major = 0, minor = 0;
ULONGLONG major_equal, minor_equal; ULONGLONG major_equal, minor_equal;
BOOL ws; BOOL ws;
nWindowsVersion = WINDOWS_UNDEFINED; memset(WindowsVersion, 0, sizeof(windows_version_t));
static_strcpy(WindowsVersionStr, "Windows Undefined"); static_strcpy(WindowsVersion->VersionStr, "Windows Undefined");
memset(&vi, 0, sizeof(vi)); memset(&vi, 0, sizeof(vi));
vi.dwOSVersionInfoSize = sizeof(vi); vi.dwOSVersionInfoSize = sizeof(vi);
@ -397,8 +394,8 @@ void GetWindowsVersion(void)
if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) { if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
ws = (vi.wProductType <= VER_NT_WORKSTATION); ws = (vi.wProductType <= VER_NT_WORKSTATION);
nWindowsVersion = vi.dwMajorVersion << 4 | vi.dwMinorVersion; WindowsVersion->Version = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
switch (nWindowsVersion) { switch (WindowsVersion->Version) {
case WINDOWS_XP: w = "XP"; case WINDOWS_XP: w = "XP";
break; break;
case WINDOWS_2003: w = (ws ? "XP_64" : (!GetSystemMetrics(89) ? "Server 2003" : "Server 2003_R2")); case WINDOWS_2003: w = (ws ? "XP_64" : (!GetSystemMetrics(89) ? "Server 2003" : "Server 2003_R2"));
@ -419,26 +416,29 @@ void GetWindowsVersion(void)
w = (ws ? "10" : ((vi.dwBuildNumber < 17763) ? "Server 2016" : "Server 2019")); w = (ws ? "10" : ((vi.dwBuildNumber < 17763) ? "Server 2016" : "Server 2019"));
break; break;
} }
nWindowsVersion = WINDOWS_11; WindowsVersion->Version = WINDOWS_11;
major = 11;
// Fall through // Fall through
case WINDOWS_11: w = (ws ? "11" : "Server 2022"); case WINDOWS_11: w = (ws ? "11" : "Server 2022");
break; break;
default: default:
if (nWindowsVersion < WINDOWS_XP) if (WindowsVersion->Version < WINDOWS_XP)
nWindowsVersion = WINDOWS_UNSUPPORTED; WindowsVersion->Version = WINDOWS_UNDEFINED;
else else
w = "12 or later"; w = "12 or later";
break; break;
} }
} }
} }
WindowsVersion->Major = major;
WindowsVersion->Minor = minor;
if (is_x64()) if (is_x64())
w64 = "64-bit"; w64 = "64-bit";
GetProductInfo(vi.dwMajorVersion, vi.dwMinorVersion, vi.wServicePackMajor, vi.wServicePackMinor, &dwProductType); GetProductInfo(vi.dwMajorVersion, vi.dwMinorVersion, vi.wServicePackMajor, vi.wServicePackMinor, &dwProductType);
vptr = &WindowsVersionStr[sizeof("Windows ") - 1]; vptr = &WindowsVersion->VersionStr[sizeof("Windows ") - 1];
vlen = sizeof(WindowsVersionStr) - sizeof("Windows ") - 1; vlen = sizeof(WindowsVersion->VersionStr) - sizeof("Windows ") - 1;
if (!w) if (!w)
safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??"), safe_sprintf(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??"),
(unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64); (unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64);
@ -450,18 +450,18 @@ void GetWindowsVersion(void)
safe_sprintf(vptr, vlen, "%s%s%s, %s", safe_sprintf(vptr, vlen, "%s%s%s, %s",
w, (dwProductType != 0) ? " " : "", GetEdition(dwProductType), w64); w, (dwProductType != 0) ? " " : "", GetEdition(dwProductType), w64);
nWindowsEdition = (int)dwProductType; WindowsVersion->Edition = (int)dwProductType;
// Add the build number (including UBR if available) for Windows 8.0 and later // Add the build number (including UBR if available) for Windows 8.0 and later
nWindowsBuildNumber = vi.dwBuildNumber; WindowsVersion->BuildNumber = vi.dwBuildNumber;
if (nWindowsVersion >= 0x62) { if (WindowsVersion->Version >= WINDOWS_8) {
int nUbr = ReadRegistryKey32(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion\\UBR"); int nUbr = ReadRegistryKey32(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion\\UBR");
vptr = &WindowsVersionStr[safe_strlen(WindowsVersionStr)]; vptr = &WindowsVersion->VersionStr[safe_strlen(WindowsVersion->VersionStr)];
vlen = sizeof(WindowsVersionStr) - safe_strlen(WindowsVersionStr) - 1; vlen = sizeof(WindowsVersion->VersionStr) - safe_strlen(WindowsVersion->VersionStr) - 1;
if (nUbr > 0) if (nUbr > 0)
safe_sprintf(vptr, vlen, " (Build %d.%d)", nWindowsBuildNumber, nUbr); safe_sprintf(vptr, vlen, " (Build %d.%d)", WindowsVersion->BuildNumber, nUbr);
else else
safe_sprintf(vptr, vlen, " (Build %d)", nWindowsBuildNumber); safe_sprintf(vptr, vlen, " (Build %d)", WindowsVersion->BuildNumber);
} }
} }

View file

@ -1640,7 +1640,7 @@ void SetFidoCheck(void)
return; return;
} }
if (nWindowsVersion < WINDOWS_8) { if (WindowsVersion.Version < WINDOWS_8) {
ubprintf("Notice: The ISO download feature has been deactivated because " ubprintf("Notice: The ISO download feature has been deactivated because "
"your version of Windows is too old."); "your version of Windows is too old.");
return; return;

View file

@ -1,7 +1,7 @@
/* /*
* Rufus: The Reliable USB Formatting Utility * Rufus: The Reliable USB Formatting Utility
* UI-related function calls * UI-related function calls
* Copyright © 2018-2022 Pete Batard <pete@akeo.ie> * Copyright © 2018-2023 Pete Batard <pete@akeo.ie>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -123,7 +123,7 @@ void GetBasicControlsWidth(HWND hDlg)
sz.cy = rc.bottom; sz.cy = rc.bottom;
// TODO: figure out the specifics of each Windows version // TODO: figure out the specifics of each Windows version
if (nWindowsVersion == WINDOWS_10) { if (WindowsVersion.Version == WINDOWS_10) {
checkbox_internal_spacing = 10; checkbox_internal_spacing = 10;
dropdown_internal_spacing = 13; dropdown_internal_spacing = 13;
} }
@ -779,7 +779,7 @@ void ToggleImageOptions(void)
int i, shift = rh; int i, shift = rh;
has_wintogo = ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso || img_report.is_windows_img) && has_wintogo = ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso || img_report.is_windows_img) &&
(nWindowsVersion >= WINDOWS_8) && (HAS_WINTOGO(img_report))); (WindowsVersion.Version >= WINDOWS_8) && (HAS_WINTOGO(img_report)));
has_persistence = ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso) && (HAS_PERSISTENCE(img_report))); has_persistence = ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso) && (HAS_PERSISTENCE(img_report)));
assert(popcnt8(image_options) <= 1); assert(popcnt8(image_options) <= 1);

View file

@ -430,7 +430,7 @@ BOOL PopulateWindowsVersion(void)
memset(&img_report.win_version, 0, sizeof(img_report.win_version)); memset(&img_report.win_version, 0, sizeof(img_report.win_version));
if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck(TRUE) & 4) == 0)) if ((WindowsVersion.Version < WINDOWS_8) || ((WimExtractCheck(TRUE) & 4) == 0))
return FALSE; return FALSE;
// If we're not using a straight install.wim, we need to mount the ISO to access it // If we're not using a straight install.wim, we need to mount the ISO to access it
@ -486,7 +486,7 @@ int SetWinToGoIndex(void)
// Sanity checks // Sanity checks
wintogo_index = -1; wintogo_index = -1;
wininst_index = 0; wininst_index = 0;
if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck(FALSE) & 4) == 0) || if ((WindowsVersion.Version < WINDOWS_8) || ((WimExtractCheck(FALSE) & 4) == 0) ||
(ComboBox_GetCurItemData(hFileSystem) != FS_NTFS)) { (ComboBox_GetCurItemData(hFileSystem) != FS_NTFS)) {
return -1; return -1;
} }
@ -606,7 +606,7 @@ BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
uprintf("Windows To Go mode selected"); uprintf("Windows To Go mode selected");
// Additional sanity checks // Additional sanity checks
if ((use_esp) && (SelectedDrive.MediaType != FixedMedia) && (nWindowsBuildNumber < 15000)) { if ((use_esp) && (SelectedDrive.MediaType != FixedMedia) && (WindowsVersion.BuildNumber < 15000)) {
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_SUPPORTED; FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_SUPPORTED;
return FALSE; return FALSE;
} }