mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[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.
This commit is contained in:
parent
a10b8e8c54
commit
b043db33e6
11 changed files with 334 additions and 68 deletions
|
@ -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)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<Identity
|
||||
Name="19453.net.Rufus"
|
||||
Publisher="CN=7AC86D13-3E5A-491A-ADD5-80095C212740"
|
||||
Version="3.16.1831.0" />
|
||||
Version="3.16.1832.0" />
|
||||
|
||||
<Properties>
|
||||
<DisplayName>Rufus</DisplayName>
|
||||
|
|
|
@ -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 <Ctrl>-<Alt>-<Z> 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
|
||||
|
|
84
src/format.c
84
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);
|
||||
|
|
59
src/rufus.c
59
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;
|
||||
|
|
13
src/rufus.h
13
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)
|
||||
|
|
10
src/rufus.rc
10
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"
|
||||
|
|
85
src/stdfn.c
85
src/stdfn.c
|
@ -24,6 +24,7 @@
|
|||
#include <windows.h>
|
||||
#include <sddl.h>
|
||||
#include <gpedit.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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 <pszHivePath> into <key>\<pszHiveName>.
|
||||
* <key> 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.
|
||||
* <key> 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);
|
||||
}
|
||||
|
|
5
src/ui.c
5
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<ARRAYSIZE(full_width_checkboxes); i++)
|
||||
|
@ -790,7 +793,7 @@ void ToggleImageOptions(void)
|
|||
image_options ^= IMOP_WINTOGO;
|
||||
if (image_options & IMOP_WINTOGO) {
|
||||
// Set the Windows To Go selection in the dropdown
|
||||
IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, (img_report.is_windows_img || !windows_to_go_selected) ? 0 : 1));
|
||||
IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, imop_win_sel));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
src/ui.h
2
src/ui.h
|
@ -74,7 +74,7 @@ enum update_progress_type {
|
|||
extern HWND hMultiToolbar, hSaveToolbar, hHashToolbar, hAdvancedDeviceToolbar, hAdvancedFormatToolbar;
|
||||
extern HFONT hInfoFont;
|
||||
extern UINT_PTR UM_LANGUAGE_MENU_MAX;
|
||||
extern BOOL advanced_mode_device, advanced_mode_format, force_large_fat32, app_changed_size, windows_to_go_selected;
|
||||
extern BOOL advanced_mode_device, advanced_mode_format, force_large_fat32, app_changed_size;
|
||||
extern loc_cmd* selected_locale;
|
||||
extern uint64_t persistence_size;
|
||||
extern const char *sfd_name, *flash_type[BADLOCKS_PATTERN_TYPES];
|
||||
|
|
127
src/vhd.c
127
src/vhd.c
|
@ -109,15 +109,18 @@ PF_TYPE_DECL(WINAPI, DWORD, WIMUnregisterMessageCallback, (HANDLE, FARPROC));
|
|||
PF_TYPE_DECL(RPC_ENTRY, RPC_STATUS, UuidCreate, (UUID __RPC_FAR*));
|
||||
|
||||
uint32_t wim_nb_files, wim_proc_files, wim_extra_files;
|
||||
HANDLE apply_wim_thread = NULL;
|
||||
HANDLE wim_thread = NULL;
|
||||
extern int default_thread_priority;
|
||||
extern BOOL ignore_boot_marker;
|
||||
|
||||
static uint8_t wim_flags = 0;
|
||||
static wchar_t wmount_path[MAX_PATH] = { 0 };
|
||||
static wchar_t wmount_path[MAX_PATH] = { 0 }, wmount_track[MAX_PATH] = { 0 };
|
||||
static char sevenzip_path[MAX_PATH];
|
||||
static const char conectix_str[] = VHD_FOOTER_COOKIE;
|
||||
static BOOL count_files;
|
||||
// Apply/Mount image functionality
|
||||
static const char *_image, *_dst;
|
||||
static int _index;
|
||||
|
||||
static BOOL Get7ZipPath(void)
|
||||
{
|
||||
|
@ -381,55 +384,115 @@ uint8_t WimExtractCheck(BOOL bSilent)
|
|||
return wim_flags;
|
||||
}
|
||||
|
||||
// Looks like Microsoft's idea of "mount" for WIM images is to just *extract* all
|
||||
// files to a mounpoint and pretend it is "mounted", even if you do specify that
|
||||
// you're not planning to change the content. So, yeah, this is both super slow
|
||||
// and super wasteful of space... These calls are a complete waste of time.
|
||||
BOOL WimMountImage(char* pszWimFileName, DWORD dwImageIndex)
|
||||
// Looks like Microsoft's idea of "mount" for WIM images involves the creation
|
||||
// of a as many virtual junctions as there exist directories on the image...
|
||||
// So, yeah, this is both very slow and wasteful of space.
|
||||
static DWORD WINAPI WimMountImageThread(LPVOID param)
|
||||
{
|
||||
BOOL r = FALSE;
|
||||
wconvert(temp_dir);
|
||||
wconvert(pszWimFileName);
|
||||
wchar_t* wimage = utf8_to_wchar(_image);
|
||||
PF_INIT_OR_OUT(WIMMountImage, Wimgapi);
|
||||
|
||||
if (wmount_path[0] != 0) {
|
||||
uprintf("WimMountImage: An image is already mounted");
|
||||
goto out;
|
||||
}
|
||||
if (GetTempFileNameW(wtemp_dir, L"Rufus", 0, wmount_path) == 0) {
|
||||
uprintf("WimMountImage: Can not create mount directory");
|
||||
if (GetTempFileNameW(wtemp_dir, L"Ruf", 0, wmount_path) == 0) {
|
||||
uprintf("WimMountImage: Can not generate mount directory: %s", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
DeleteFileW(wmount_path);
|
||||
if (!CreateDirectoryW(wmount_path, 0)) {
|
||||
uprintf("WimMountImage: Can not create mount directory");
|
||||
uprintf("WimMountImage: Can not create mount directory '%S': %s", wmount_path, WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
if (GetTempFileNameW(wtemp_dir, L"Ruf", 0, wmount_track) == 0) {
|
||||
uprintf("WimMountImage: Can not generate tracking directory: %s", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
DeleteFileW(wmount_track);
|
||||
if (!CreateDirectoryW(wmount_track, 0)) {
|
||||
uprintf("WimMountImage: Can not create tracking directory '%S': %s", wmount_track, WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = pfWIMMountImage(wmount_path, wpszWimFileName, dwImageIndex, NULL);
|
||||
if (!r)
|
||||
uprintf("Could not mount %S on %S: %s", wpszWimFileName, wmount_path, WindowsErrorString());
|
||||
r = pfWIMMountImage(wmount_path, wimage, _index, wmount_track);
|
||||
if (!r) {
|
||||
uprintf("Could not mount '%S [%d]' on '%S': %s", wimage, _index, wmount_path, WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
uprintf("mounted '%S [%d]' on '%S'", wimage, _index, wmount_path);
|
||||
|
||||
out:
|
||||
wfree(temp_dir);
|
||||
wfree(pszWimFileName);
|
||||
return r;
|
||||
safe_free(wimage);
|
||||
ExitThread((DWORD)r);
|
||||
}
|
||||
|
||||
BOOL WimUnmountImage(void)
|
||||
// Returns the temporary mount path on success, NULL on error.
|
||||
// Returned path must be freed by the caller.
|
||||
char* WimMountImage(const char* image, int index)
|
||||
{
|
||||
DWORD dw = 0;
|
||||
_image = image;
|
||||
_index = index;
|
||||
|
||||
wim_thread = CreateThread(NULL, 0, WimMountImageThread, NULL, 0, NULL);
|
||||
if (wim_thread == NULL) {
|
||||
uprintf("Unable to start mount-image thread");
|
||||
return NULL;
|
||||
}
|
||||
SetThreadPriority(wim_thread, default_thread_priority);
|
||||
WaitForSingleObject(wim_thread, INFINITE);
|
||||
if (!GetExitCodeThread(wim_thread, &dw))
|
||||
dw = 0;
|
||||
wim_thread = NULL;
|
||||
return (dw) ? wchar_to_utf8(wmount_path) : NULL;
|
||||
}
|
||||
|
||||
static DWORD WINAPI WimUnmountImageThread(LPVOID param)
|
||||
{
|
||||
BOOL r = FALSE;
|
||||
wchar_t* wimage = utf8_to_wchar(_image);
|
||||
PF_INIT_OR_OUT(WIMUnmountImage, Wimgapi);
|
||||
|
||||
if (wmount_path[0] == 0) {
|
||||
uprintf("WimUnmountImage: No image is mounted");
|
||||
goto out;
|
||||
}
|
||||
r = pfWIMUnmountImage(wmount_path, NULL, 0, FALSE);
|
||||
if (!r)
|
||||
uprintf("Could not unmount %S: %s", wmount_path, WindowsErrorString());
|
||||
r = pfWIMUnmountImage(wmount_path, wimage, _index, TRUE);
|
||||
if (!r) {
|
||||
uprintf("Could not unmount '%S': %s", wmount_path, WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
uprintf("Unmounted '%S [%d]'", wmount_path, _index);
|
||||
RemoveDirectoryW(wmount_path);
|
||||
wmount_path[0] = 0;
|
||||
RemoveDirectoryW(wmount_track);
|
||||
wmount_track[0] = 0;
|
||||
out:
|
||||
return r;
|
||||
safe_free(wimage);
|
||||
ExitThread((DWORD)r);
|
||||
}
|
||||
|
||||
BOOL WimUnmountImage(const char* image, int index)
|
||||
{
|
||||
DWORD dw = 0;
|
||||
_image = image;
|
||||
_index = index;
|
||||
|
||||
wim_thread = CreateThread(NULL, 0, WimUnmountImageThread, NULL, 0, NULL);
|
||||
if (wim_thread == NULL) {
|
||||
uprintf("Unable to start unmount-image thread");
|
||||
return FALSE;
|
||||
}
|
||||
SetThreadPriority(wim_thread, default_thread_priority);
|
||||
WaitForSingleObject(wim_thread, INFINITE);
|
||||
if (!GetExitCodeThread(wim_thread, &dw))
|
||||
dw = 0;
|
||||
wim_thread = NULL;
|
||||
return dw;
|
||||
}
|
||||
|
||||
// Extract a file from a WIM image using wimgapi.dll (Windows 7 or later)
|
||||
|
@ -589,12 +652,8 @@ BOOL WimExtractFile(const char* image, int index, const char* src, const char* d
|
|||
|| ((wim_flags & WIM_HAS_API_EXTRACT) && WimExtractFile_API(image, index, src, dst, bSilent)) );
|
||||
}
|
||||
|
||||
// Apply image functionality
|
||||
static const char *_image, *_dst;
|
||||
static int _index;
|
||||
|
||||
// From http://msdn.microsoft.com/en-us/library/windows/desktop/dd834960.aspx
|
||||
// as well as http://www.msfn.org/board/topic/150700-wimgapi-wimmountimage-progressbar/
|
||||
// From https://docs.microsoft.com/en-us/previous-versions/msdn10/dd834960(v=msdn.10)
|
||||
// as well as https://msfn.org/board/topic/150700-wimgapi-wimmountimage-progressbar/
|
||||
enum WIMMessage {
|
||||
WIM_MSG = WM_APP + 0x1476,
|
||||
WIM_MSG_TEXT,
|
||||
|
@ -700,7 +759,7 @@ DWORD WINAPI WimProgressCallback(DWORD dwMsgId, WPARAM wParam, LPARAM lParam, PV
|
|||
}
|
||||
|
||||
// Apply a WIM image using wimgapi.dll (Windows 7 or later)
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd851944.aspx
|
||||
// https://docs.microsoft.com/en-us/previous-versions/msdn10/dd851944(v=msdn.10)
|
||||
// To get progress, we must run this call within its own thread
|
||||
static DWORD WINAPI WimApplyImageThread(LPVOID param)
|
||||
{
|
||||
|
@ -800,15 +859,15 @@ BOOL WimApplyImage(const char* image, int index, const char* dst)
|
|||
_index = index;
|
||||
_dst = dst;
|
||||
|
||||
apply_wim_thread = CreateThread(NULL, 0, WimApplyImageThread, NULL, 0, NULL);
|
||||
if (apply_wim_thread == NULL) {
|
||||
wim_thread = CreateThread(NULL, 0, WimApplyImageThread, NULL, 0, NULL);
|
||||
if (wim_thread == NULL) {
|
||||
uprintf("Unable to start apply-image thread");
|
||||
return FALSE;
|
||||
}
|
||||
SetThreadPriority(apply_wim_thread, default_thread_priority);
|
||||
WaitForSingleObject(apply_wim_thread, INFINITE);
|
||||
if (!GetExitCodeThread(apply_wim_thread, &dw))
|
||||
SetThreadPriority(wim_thread, default_thread_priority);
|
||||
WaitForSingleObject(wim_thread, INFINITE);
|
||||
if (!GetExitCodeThread(wim_thread, &dw))
|
||||
dw = 0;
|
||||
apply_wim_thread = NULL;
|
||||
wim_thread = NULL;
|
||||
return dw;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue