From b043db33e616c83f889b4d281ec5b5a3cede0e2d Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Fri, 8 Oct 2021 19:22:33 +0100 Subject: [PATCH] [core] add option to bypass TPM 2.0/Secure Boot/RAM requirements for Windows 11 ISOs * If 'Extended Windows 11 Installation' mode is selected, the system registry hive of 'sources\boot.wim' is patched to add the Setup\LabConfig registry keys that bypass the TPM 2.0/Secure Boot/8GB+ RAM Windows 11 system requirements. --- ChangeLog.txt | 3 +- res/appstore/Package.appxmanifest | 2 +- res/loc/rufus.loc | 12 ++- src/format.c | 84 +++++++++++++++++++- src/rufus.c | 59 ++++++++++---- src/rufus.h | 13 ++- src/rufus.rc | 10 +-- src/stdfn.c | 85 ++++++++++++++++++++ src/ui.c | 5 +- src/ui.h | 2 +- src/vhd.c | 127 ++++++++++++++++++++++-------- 11 files changed, 334 insertions(+), 68 deletions(-) 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