diff --git a/ChangeLog.txt b/ChangeLog.txt
index 841f17a4..3174c65c 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -5,8 +5,9 @@ o Version 3.16 (2021.10.??)
Fix log not being saved on exit
Add UEFI Shell ISO downloads
Add support for Intel NUC card readers
- Improve Windows version reporting
+ Add Windows 11 extended installation support (disables TPM or Secure Boot requirement)
Improve Windows 11 support
+ Improve Windows version reporting
Speed up clearing of MBR/GPT
o Version 3.15 (2021.08.03)
diff --git a/res/appstore/Package.appxmanifest b/res/appstore/Package.appxmanifest
index 8a7f3742..b59970bf 100644
--- a/res/appstore/Package.appxmanifest
+++ b/res/appstore/Package.appxmanifest
@@ -11,7 +11,7 @@
+ Version="3.16.1832.0" />
Rufus
diff --git a/res/loc/rufus.loc b/res/loc/rufus.loc
index ab995bab..9a72478a 100644
--- a/res/loc/rufus.loc
+++ b/res/loc/rufus.loc
@@ -559,8 +559,9 @@ t MSG_301 "Show application settings"
t MSG_302 "Show information about this application"
t MSG_303 "Show the log"
t MSG_304 "Create a disk image of the selected device"
-t MSG_305 "Use this option to indicate whether you want to use this device to install Windows on another disk, "
- "or if you want to run Windows directly from this drive (Windows To Go)."
+t MSG_305 "Use this option to indicate if you want to run Windows directly from this drive (Windows To Go) or if you "
+ "want to install Windows to a different disk.\r\nIn 'Extended Windows 11 Installation' mode, Rufus patches the "
+ "media so that Windows 11 can be installed on platforms that don't meet the TPM 2.0 or Secure Boot requirements."
# You can see this status message by pressing -- and then selecting START.
# It's the same as MSG_286 but with a process that *may* be faster, hence the name.
t MSG_306 "Fast-zeroing drive: %s"
@@ -581,7 +582,10 @@ t MSG_318 "Default thread priority: %d"
t MSG_319 "Ignore Boot Marker"
t MSG_320 "Refreshing partition layout (%s)..."
t MSG_321 "The image you have selected is an ISOHybrid, but its creators have not made it compatible with ISO/File "
- "copy mode.\nAs a result, DD image writing mode will be enforced."
+ "copy mode.\nAs a result, DD image writing mode will be enforced."
+t MSG_322 "Standard Windows 11 Installation (TPM 2.0 / Secure Boot / 8GB+ RAM)"
+t MSG_323 "Extended Windows 11 Installation (no TPM / no Secure Boot / 8GB- RAM)"
+t MSG_324 "Removing Windows 11 installation restrictions (%s)"
#########################################################################
l "ar-SA" "Arabic (العربية)" 0x0401, 0x0801, 0x0c01, 0x1001, 0x1401, 0x1801, 0x1c01, 0x2001, 0x2401, 0x2801, 0x2c01, 0x3001, 0x3401, 0x3801, 0x3c01, 0x4001
@@ -5009,7 +5013,7 @@ t MSG_303 "Εμφάνιση καταγραφών εφαρμογής (log)"
t MSG_304 "Δημιουργία ειδώλου δίσκου από την επιλεγμένη συσκευή"
t MSG_305 "Επιλέξτε αυτό αν θέλετε να χρησιμοποιήσετε αυτή τη συσκευή για να εγκαταστήσετε τα Windows σε κάποιο δίσκο, ή θέλετε να τα τρέχετε κατευθείαν από την συσκευή (Windows To Go)."
t MSG_306 "Γρήγορος μηδενισμός μονάδας δίσκου: %s"
-t MSG_307 "η διαδικασία ίσως διαρκέσει αρκετά"
+t MSG_307 "η διαδικασία ίσως διαρκέσει αρκετά"
#########################################################################
l "he-IL" "Hebrew (עברית)" 0x040d
diff --git a/src/format.c b/src/format.c
index b016383d..4057835c 100644
--- a/src/format.c
+++ b/src/format.c
@@ -1417,7 +1417,7 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
UpdateProgressWithInfo(OP_FILE_COPY, MSG_267, wim_proc_files + 2 * wim_extra_files, wim_nb_files);
- uprintf("Disable the use of the Windows Recovery Environment using command:");
+ uprintf("Disabling use of the Windows Recovery Environment using command:");
static_sprintf(cmd, "%s\\bcdedit.exe /store %s\\EFI\\Microsoft\\Boot\\BCD /set {default} recoveryenabled no",
sysnative_dir, (use_esp) ? ms_efi : drive_name);
uprintf(cmd);
@@ -1433,6 +1433,80 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
return TRUE;
}
+/*
+ * Edit sources/boot.wim registry to remove Windows 11 install restrictions
+ */
+BOOL RemoveWindows11Restrictions(char drive_letter)
+{
+ BOOL r = FALSE, is_hive_mounted = FALSE;
+ int i;
+ const int wim_index = 2;
+ const char* offline_hive_name = "RUFUS_OFFLINE_HIVE";
+ const char* key_name[] = { "BypassTPMCheck", "BypassSecureBootCheck", "BypassRAMCheck" };
+ char boot_wim_path[] = "#:\\sources\\boot.wim", key_path[64];
+ char* mount_path = NULL;
+ char path[MAX_PATH];
+ HKEY hKey = NULL, hSubKey = NULL;
+ LSTATUS status;
+ DWORD dwDisp, dwVal = 1;
+
+ boot_wim_path[0] = drive_letter;
+
+ PrintInfo(0, MSG_324, lmprintf(MSG_307));
+ uprintf("Mounting '%s'...", boot_wim_path);
+
+ mount_path = WimMountImage(boot_wim_path, wim_index);
+ if (mount_path == NULL)
+ goto out;
+
+ static_sprintf(path, "%s\\Windows\\System32\\config\\SYSTEM", mount_path);
+ if (!MountRegistryHive(HKEY_LOCAL_MACHINE, offline_hive_name, path))
+ goto out;
+ is_hive_mounted = TRUE;
+
+ static_sprintf(key_path, "%s\\Setup", offline_hive_name);
+ status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_path, 0, KEY_READ | KEY_CREATE_SUB_KEY, &hKey);
+ if (status != ERROR_SUCCESS) {
+ SetLastError(status);
+ uprintf("Could not open 'HKLM\\SYSTEM\\Setup' registry key: %s", WindowsErrorString());
+ goto out;
+ }
+
+ status = RegCreateKeyExA(hKey, "LabConfig", 0, NULL, 0,
+ KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_CREATE_SUB_KEY, NULL, &hSubKey, &dwDisp);
+ if (status != ERROR_SUCCESS) {
+ SetLastError(status);
+ uprintf("Could not create 'HKLM\\SYSTEM\\Setup\\LabConfig' registry key: %s", WindowsErrorString());
+ goto out;
+ }
+
+ for (i = 0; i < ARRAYSIZE(key_name); i++) {
+ status = RegSetValueExA(hSubKey, key_name[i], 0, REG_DWORD, (LPBYTE)&dwVal, sizeof(DWORD));
+ if (status != ERROR_SUCCESS) {
+ SetLastError(status);
+ uprintf("Could not set 'HKLM\\SYSTEM\\Setup\\LabConfig\\%s' registry key: %s",
+ key_name[i], WindowsErrorString());
+ goto out;
+ }
+ uprintf("Created 'HKLM\\SYSTEM\\Setup\\LabConfig\\%s' registry key", key_name[i]);
+ }
+ r = TRUE;
+
+out:
+ if (hSubKey != NULL)
+ RegCloseKey(hSubKey);
+ if (hKey != NULL)
+ RegCloseKey(hKey);
+ if (is_hive_mounted)
+ UnmountRegistryHive(HKEY_LOCAL_MACHINE, offline_hive_name);
+ if (mount_path) {
+ uprintf("Unmounting '%s'...", boot_wim_path, wim_index);
+ WimUnmountImage(boot_wim_path, wim_index);
+ }
+ free(mount_path);
+ return r;
+}
+
static void update_progress(const uint64_t processed_bytes)
{
// NB: We don't really care about resetting this value to UINT64_MAX for a new pass.
@@ -1792,7 +1866,7 @@ DWORD WINAPI FormatThread(void* param)
use_large_fat32 = (fs_type == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32));
windows_to_go = (image_options & IMOP_WINTOGO) && (boot_type == BT_IMAGE) && HAS_WINTOGO(img_report) &&
- ComboBox_GetCurItemData(hImageOption);
+ (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO);
large_drive = (SelectedDrive.DiskSize > (1*TB));
if (large_drive)
uprintf("Notice: Large drive detected (may produce short writes)");
@@ -2256,10 +2330,14 @@ DWORD WINAPI FormatThread(void* param)
}
}
if ( (target_type == TT_BIOS) && HAS_WINPE(img_report) ) {
- // Apply WinPe fixup
+ // Apply WinPE fixup
if (!SetupWinPE(drive_name[0]))
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
}
+ if (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_EXTENDED) {
+ if (!RemoveWindows11Restrictions(drive_name[0]))
+ FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_PATCH);
+ }
}
}
UpdateProgress(OP_FINALIZE, -1.0f);
diff --git a/src/rufus.c b/src/rufus.c
index 2994e641..8a0376d9 100755
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -86,7 +86,7 @@ static char szTimer[12] = "00:00:00";
static unsigned int timer;
static char uppercase_select[2][64], uppercase_start[64], uppercase_close[64], uppercase_cancel[64];
-extern HANDLE update_check_thread, apply_wim_thread;
+extern HANDLE update_check_thread, wim_thread;
extern BOOL enable_iso, enable_joliet, enable_rockridge, enable_extra_hashes;
extern BYTE* fido_script;
extern HWND hFidoDlg;
@@ -121,9 +121,9 @@ BOOL advanced_mode_device, advanced_mode_format, allow_dual_uefi_bios, detect_fa
BOOL use_fake_units, preserve_timestamps = FALSE, fast_zeroing = FALSE, app_changed_size = FALSE;
BOOL zero_drive = FALSE, list_non_usb_removable_drives = FALSE, enable_file_indexing, large_drive = FALSE;
BOOL write_as_image = FALSE, write_as_esp = FALSE, installed_uefi_ntfs = FALSE, use_vds = FALSE, ignore_boot_marker = FALSE;
-BOOL windows_to_go_selected = FALSE, appstore_version = FALSE, is_vds_available = TRUE;
+BOOL appstore_version = FALSE, is_vds_available = TRUE;
float fScale = 1.0f;
-int dialog_showing = 0, selection_default = BT_IMAGE, persistence_unit_selection = -1;
+int dialog_showing = 0, selection_default = BT_IMAGE, persistence_unit_selection = -1, imop_win_sel = 0;
int default_fs, fs_type, boot_type, partition_type, target_type; // file system, boot type, partition type, target type
int force_update = 0, default_thread_priority = THREAD_PRIORITY_ABOVE_NORMAL;
char szFolderPath[MAX_PATH], app_dir[MAX_PATH], system_dir[MAX_PATH], temp_dir[MAX_PATH], sysnative_dir[MAX_PATH];
@@ -179,7 +179,7 @@ static void SetAllowedFileSystems(void)
if ((image_path != NULL) && (img_report.has_4GB_file))
break;
if (!HAS_WINDOWS(img_report) || (target_type != TT_BIOS) || allow_dual_uefi_bios) {
- if (!HAS_WINTOGO(img_report) || (!ComboBox_GetCurItemData(hImageOption))) {
+ if (!HAS_WINTOGO(img_report) || (ComboBox_GetCurItemData(hImageOption) != IMOP_WIN_TO_GO)) {
allowed_filesystem[FS_FAT16] = TRUE;
allowed_filesystem[FS_FAT32] = TRUE;
}
@@ -258,7 +258,7 @@ static void SetPartitionSchemeAndTargetSystem(BOOL only_target)
boot_type = (int)ComboBox_GetCurItemData(hBootType);
is_windows_to_go_selected = (boot_type == BT_IMAGE) && (image_path != NULL) && HAS_WINTOGO(img_report) &&
- ComboBox_GetCurItemData(hImageOption);
+ (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO);
// If no device is selected, don't populate anything
if (ComboBox_GetCurSel(hDeviceList) < 0)
return;
@@ -589,7 +589,7 @@ static void SetFSFromISO(void)
int i, fs_tmp, preferred_fs = FS_UNKNOWN;
uint32_t fs_mask = FS_FAT32 | FS_NTFS;
BOOL windows_to_go = (image_options & IMOP_WINTOGO) && (boot_type == BT_IMAGE) &&
- HAS_WINTOGO(img_report) && ComboBox_GetCurItemData(hImageOption);
+ HAS_WINTOGO(img_report) && (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO);
if (image_path == NULL)
return;
@@ -649,7 +649,7 @@ static void SetMBRProps(void)
fs_type = (int)ComboBox_GetCurItemData(hFileSystem);
if ((!mbr_selected_by_user) && ((image_path == NULL) || (boot_type != BT_IMAGE) || (fs_type != FS_NTFS) || HAS_GRUB(img_report) ||
- ((image_options & IMOP_WINTOGO) && ComboBox_GetCurItemData(hImageOption)) )) {
+ ((image_options & IMOP_WINTOGO) && (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO)) )) {
CheckDlgButton(hMainDialog, IDC_RUFUS_MBR, BST_UNCHECKED);
IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0));
return;
@@ -1129,10 +1129,17 @@ static void UpdateImage(BOOL update_image_option_only)
}
ComboBox_ResetContent(hImageOption);
- if (!img_report.is_windows_img)
- IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_117)), FALSE));
- IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_118)), TRUE));
- IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, (img_report.is_windows_img || !windows_to_go_selected) ? 0 : 1));
+
+ if (!img_report.is_windows_img) { // Straight install.wim/install.esd only have Windows To Go option
+ if (img_report.win_version.major == 11) {
+ IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_322)), IMOP_WIN_STANDARD));
+ IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_323)), IMOP_WIN_EXTENDED));
+ } else {
+ IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_117)), IMOP_WIN_STANDARD));
+ }
+ }
+ IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_118)), IMOP_WIN_TO_GO));
+ IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, imop_win_sel));
}
static uint8_t FindArch(const char* filename)
@@ -1226,6 +1233,7 @@ DWORD WINAPI ImageScanThread(LPVOID param)
img_report.is_iso = (BOOLEAN)ExtractISO(image_path, "", TRUE);
img_report.is_bootable_img = IsBootableImage(image_path);
ComboBox_ResetContent(hImageOption);
+ imop_win_sel = 0;
if ((FormatStatus == (ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_CANCELLED)) ||
(img_report.image_size == 0) ||
@@ -1409,7 +1417,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
goto out;
}
- if ((image_options & IMOP_WINTOGO) && ComboBox_GetCurItemData(hImageOption)) {
+ if ((image_options & IMOP_WINTOGO) && (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO)) {
if (fs_type != FS_NTFS) {
// Windows To Go only works for NTFS
MessageBoxExU(hMainDialog, lmprintf(MSG_097, "Windows To Go"), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
@@ -2119,6 +2127,24 @@ out:
return ret;
}
+#ifdef RUFUS_TEST
+extern BOOL RemoveWindows11Restrictions(char drive_letter);
+
+static DWORD WINAPI TestThread(LPVOID param)
+{
+ static BOOL processing = FALSE;
+
+ if (processing) {
+ uprintf("Test thread is already in progress!");
+ ExitThread(1);
+ }
+ processing = TRUE;
+ RemoveWindows11Restrictions('B');
+ processing = FALSE;
+ ExitThread(0);
+}
+#endif
+
/*
* Main dialog callback
*/
@@ -2155,8 +2181,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
case WM_COMMAND:
#ifdef RUFUS_TEST
if (LOWORD(wParam) == IDC_TEST) {
- DWORD DriveIndex = (DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList));
- uprintf("label = '%s'", GetExtFsLabel(DriveIndex, 1));
+ CreateThread(NULL, 0, TestThread, NULL, 0, NULL);
break;
}
#endif
@@ -2333,7 +2358,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
if (HIWORD(wParam) != CBN_SELCHANGE)
break;
SetFileSystemAndClusterSize(NULL);
- windows_to_go_selected = (BOOL)ComboBox_GetCurItemData(hImageOption);
+ imop_win_sel = ComboBox_GetCurSel(hImageOption);
break;
case IDC_PERSISTENCE_SIZE:
if (HIWORD(wParam) == EN_CHANGE) {
@@ -3624,8 +3649,8 @@ relaunch:
WriteSetting32(SETTING_DEFAULT_THREAD_PRIORITY, default_thread_priority - THREAD_PRIORITY_ABOVE_NORMAL);
if (format_thread != NULL)
SetThreadPriority(format_thread, default_thread_priority);
- if (apply_wim_thread != NULL)
- SetThreadPriority(apply_wim_thread, default_thread_priority);
+ if (wim_thread != NULL)
+ SetThreadPriority(wim_thread, default_thread_priority);
}
PrintStatus(STATUS_MSG_TIMEOUT, MSG_318, default_thread_priority);
continue;
diff --git a/src/rufus.h b/src/rufus.h
index ac375197..499766c2 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -292,6 +292,13 @@ enum target_type {
// For the partition types we'll use Microsoft's PARTITION_STYLE_### constants
#define PARTITION_STYLE_SFD PARTITION_STYLE_RAW
+enum image_option_type {
+ IMOP_WIN_STANDARD = 0,
+ IMOP_WIN_EXTENDED,
+ IMOP_WIN_TO_GO,
+ IMOP_MAX
+};
+
enum checksum_type {
CHECKSUM_MD5 = 0,
CHECKSUM_SHA1,
@@ -552,6 +559,8 @@ extern unsigned char* GetResource(HMODULE module, char* name, char* type, const
extern DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc);
extern DWORD RunCommand(const char* cmdline, const char* dir, BOOL log);
extern BOOL CompareGUID(const GUID *guid1, const GUID *guid2);
+extern BOOL MountRegistryHive(const HKEY key, const char* pszHiveName, const char* pszHivePath);
+extern BOOL UnmountRegistryHive(const HKEY key, const char* pszHiveName);
extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue);
extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
extern uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress);
@@ -581,6 +590,8 @@ extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, co
extern BOOL WimExtractFile_API(const char* image, int index, const char* src, const char* dst, BOOL bSilent);
extern BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char* dst, BOOL bSilent);
extern BOOL WimApplyImage(const char* image, int index, const char* dst);
+extern char* WimMountImage(const char* image, int index);
+extern BOOL WimUnmountImage(const char* image, int index);
extern uint8_t IsBootableImage(const char* path);
extern BOOL AppendVHDFooter(const char* vhd_path);
extern int SetWinToGoIndex(void);
@@ -594,7 +605,7 @@ extern BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBy
LPDWORD lpNumberOfBytesWritten, DWORD nNumRetries);
extern BOOL SetThreadAffinity(DWORD_PTR* thread_affinity, size_t num_threads);
extern BOOL HashFile(const unsigned type, const char* path, uint8_t* sum);
-extern BOOL HashBuffer(const unsigned type, const unsigned char* buf, const size_t len, uint8_t* sum);
+extern BOOL HashBuffer(const unsigned type, const uint8_t* buf, const size_t len, uint8_t* sum);
extern BOOL IsFileInDB(const char* path);
extern BOOL IsBufferInDB(const unsigned char* buf, const size_t len);
#define printbits(x) _printbits(sizeof(x), &x, 0)
diff --git a/src/rufus.rc b/src/rufus.rc
index b0c07f5d..6706ee77 100644
--- a/src/rufus.rc
+++ b/src/rufus.rc
@@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES
-CAPTION "Rufus 3.16.1831"
+CAPTION "Rufus 3.16.1832"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@@ -395,8 +395,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,16,1831,0
- PRODUCTVERSION 3,16,1831,0
+ FILEVERSION 3,16,1832,0
+ PRODUCTVERSION 3,16,1832,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -414,13 +414,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
- VALUE "FileVersion", "3.16.1831"
+ VALUE "FileVersion", "3.16.1832"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2021 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-3.16.exe"
VALUE "ProductName", "Rufus"
- VALUE "ProductVersion", "3.16.1831"
+ VALUE "ProductVersion", "3.16.1832"
END
END
BLOCK "VarFileInfo"
diff --git a/src/stdfn.c b/src/stdfn.c
index 035e9a8d..f8661ef3 100644
--- a/src/stdfn.c
+++ b/src/stdfn.c
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include "rufus.h"
#include "missing.h"
@@ -997,3 +998,87 @@ char* GetCurrentMUI(void)
}
return mui_str;
}
+
+/*
+ * From: https://stackoverflow.com/a/40390858/1069307
+ */
+BOOL SetPrivilege(HANDLE hToken, LPCWSTR pwzPrivilegeName, BOOL bEnable)
+{
+ TOKEN_PRIVILEGES tp;
+ LUID luid;
+
+ if (!LookupPrivilegeValue(NULL, pwzPrivilegeName, &luid)) {
+ uprintf("Could not lookup '%S' privilege: %s", pwzPrivilegeName, WindowsErrorString());
+ return FALSE;
+ }
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
+
+ if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
+ uprintf("Could not %s '%S' privilege: %s",
+ bEnable ? "enable" : "disable", pwzPrivilegeName, WindowsErrorString());
+ return FALSE;
+ }
+
+ if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
+ uprintf("Error assigning privileges: %s", WindowsErrorString());
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Mount an offline registry hive located at into \.
+ * should be HKEY_LOCAL_MACHINE or HKEY_USERS.
+ */
+BOOL MountRegistryHive(const HKEY key, const char* pszHiveName, const char* pszHivePath)
+{
+ LSTATUS status;
+ HANDLE token = INVALID_HANDLE_VALUE;
+
+ assert((key == HKEY_LOCAL_MACHINE) || (key == HKEY_USERS));
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) {
+ uprintf("Could not get current process token: %s", WindowsErrorString());
+ return FALSE;
+ }
+
+ // Ignore errors on those in case we can proceed without...
+ SetPrivilege(token, SE_RESTORE_NAME, TRUE);
+ SetPrivilege(token, SE_BACKUP_NAME, TRUE);
+
+ status = RegLoadKeyA(key, pszHiveName, pszHivePath);
+ if (status != ERROR_SUCCESS) {
+ SetLastError(status);
+ uprintf("Could not mount offline registry hive '%s': %s", pszHivePath, WindowsErrorString());
+ } else
+ uprintf("Mounted offline registry hive '%s' to '%s\\%s'",
+ pszHivePath, (key == HKEY_LOCAL_MACHINE) ? "HKLM" : "HKCU", pszHiveName);
+
+ safe_closehandle(token);
+ return (status == ERROR_SUCCESS);
+}
+
+/*
+ * Unmount an offline registry hive.
+ * should be HKEY_LOCAL_MACHINE or HKEY_USERS.
+ */
+BOOL UnmountRegistryHive(const HKEY key, const char* pszHiveName)
+{
+ LSTATUS status;
+
+ assert((key == HKEY_LOCAL_MACHINE) || (key == HKEY_USERS));
+
+ status = RegUnLoadKeyA(key, pszHiveName);
+ if (status != ERROR_SUCCESS) {
+ SetLastError(status);
+ uprintf("Could not unmount offline registry hive: %s", WindowsErrorString());
+ } else
+ uprintf("Unmounted offline registry hive '%s\\%s'",
+ (key == HKEY_LOCAL_MACHINE) ? "HKLM" : "HKCU", pszHiveName);
+
+ return (status == ERROR_SUCCESS);
+}
diff --git a/src/ui.c b/src/ui.c
index 5f480a56..9425df99 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -45,6 +45,7 @@
UINT_PTR UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU;
HIMAGELIST hUpImageList, hDownImageList;
extern BOOL use_vds, appstore_version;
+extern int imop_win_sel;
int update_progress_type = UPT_PERCENT;
int advanced_device_section_height, advanced_format_section_height;
// (empty) check box width, (empty) drop down width, button height (for and without dropdown match)
@@ -273,6 +274,8 @@ void GetFullWidth(HWND hDlg)
// Go through the Image Options for Windows To Go
fw = max(fw, GetTextSize(hImageOption, lmprintf(MSG_117)).cx);
fw = max(fw, GetTextSize(hImageOption, lmprintf(MSG_118)).cx);
+ fw = max(fw, GetTextSize(hImageOption, lmprintf(MSG_322)).cx);
+ fw = max(fw, GetTextSize(hImageOption, lmprintf(MSG_323)).cx);
// Now deal with full length checkbox lines
for (i = 0; i