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 |     Fix log not being saved on exit | ||||||
|     Add UEFI Shell ISO downloads |     Add UEFI Shell ISO downloads | ||||||
|     Add support for Intel NUC card readers |     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 11 support | ||||||
|  |     Improve Windows version reporting | ||||||
|     Speed up clearing of MBR/GPT |     Speed up clearing of MBR/GPT | ||||||
| 
 | 
 | ||||||
| o Version 3.15 (2021.08.03) | o Version 3.15 (2021.08.03) | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ | ||||||
|   <Identity |   <Identity | ||||||
|     Name="19453.net.Rufus" |     Name="19453.net.Rufus" | ||||||
|     Publisher="CN=7AC86D13-3E5A-491A-ADD5-80095C212740" |     Publisher="CN=7AC86D13-3E5A-491A-ADD5-80095C212740" | ||||||
|     Version="3.16.1831.0" /> |     Version="3.16.1832.0" /> | ||||||
| 
 | 
 | ||||||
|   <Properties> |   <Properties> | ||||||
|     <DisplayName>Rufus</DisplayName> |     <DisplayName>Rufus</DisplayName> | ||||||
|  |  | ||||||
|  | @ -559,8 +559,9 @@ t MSG_301 "Show application settings" | ||||||
| t MSG_302 "Show information about this application" | t MSG_302 "Show information about this application" | ||||||
| t MSG_303 "Show the log" | t MSG_303 "Show the log" | ||||||
| t MSG_304 "Create a disk image of the selected device" | 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, " | t MSG_305 "Use this option to indicate if you want to run Windows directly from this drive (Windows To Go) or if you " | ||||||
| 	"or if you want to run Windows directly from this drive (Windows To Go)." | 	"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. | # 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. | # 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" | t MSG_306 "Fast-zeroing drive: %s" | ||||||
|  | @ -582,6 +583,9 @@ t MSG_319 "Ignore Boot Marker" | ||||||
| t MSG_320 "Refreshing partition layout (%s)..." | 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 " | 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 | l "ar-SA" "Arabic (العربية)" 0x0401, 0x0801, 0x0c01, 0x1001, 0x1401, 0x1801, 0x1c01, 0x2001, 0x2401, 0x2801, 0x2c01, 0x3001, 0x3401, 0x3801, 0x3c01, 0x4001 | ||||||
|  |  | ||||||
							
								
								
									
										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); | 	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", | 	static_sprintf(cmd, "%s\\bcdedit.exe /store %s\\EFI\\Microsoft\\Boot\\BCD /set {default} recoveryenabled no", | ||||||
| 		sysnative_dir, (use_esp) ? ms_efi : drive_name); | 		sysnative_dir, (use_esp) ? ms_efi : drive_name); | ||||||
| 	uprintf(cmd); | 	uprintf(cmd); | ||||||
|  | @ -1433,6 +1433,80 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp) | ||||||
| 	return TRUE; | 	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) | 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.
 | 	// 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)); | 	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) && | 	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)); | 	large_drive = (SelectedDrive.DiskSize > (1*TB)); | ||||||
| 	if (large_drive) | 	if (large_drive) | ||||||
| 		uprintf("Notice: Large drive detected (may produce short writes)"); | 		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) ) { | 				if ( (target_type == TT_BIOS) && HAS_WINPE(img_report) ) { | ||||||
| 					// Apply WinPe fixup
 | 					// Apply WinPE fixup
 | ||||||
| 					if (!SetupWinPE(drive_name[0])) | 					if (!SetupWinPE(drive_name[0])) | ||||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | 						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); | 		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 unsigned int timer; | ||||||
| static char uppercase_select[2][64], uppercase_start[64], uppercase_close[64], uppercase_cancel[64]; | 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 BOOL enable_iso, enable_joliet, enable_rockridge, enable_extra_hashes; | ||||||
| extern BYTE* fido_script; | extern BYTE* fido_script; | ||||||
| extern HWND hFidoDlg; | 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 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 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 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; | 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 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; | 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]; | 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)) | 		if ((image_path != NULL) && (img_report.has_4GB_file)) | ||||||
| 			break; | 			break; | ||||||
| 		if (!HAS_WINDOWS(img_report) || (target_type != TT_BIOS) || allow_dual_uefi_bios) { | 		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_FAT16] = TRUE; | ||||||
| 				allowed_filesystem[FS_FAT32] = TRUE; | 				allowed_filesystem[FS_FAT32] = TRUE; | ||||||
| 			} | 			} | ||||||
|  | @ -258,7 +258,7 @@ static void SetPartitionSchemeAndTargetSystem(BOOL only_target) | ||||||
| 
 | 
 | ||||||
| 	boot_type = (int)ComboBox_GetCurItemData(hBootType); | 	boot_type = (int)ComboBox_GetCurItemData(hBootType); | ||||||
| 	is_windows_to_go_selected = (boot_type == BT_IMAGE) && (image_path != NULL) && HAS_WINTOGO(img_report) && | 	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 no device is selected, don't populate anything
 | ||||||
| 	if (ComboBox_GetCurSel(hDeviceList) < 0) | 	if (ComboBox_GetCurSel(hDeviceList) < 0) | ||||||
| 		return; | 		return; | ||||||
|  | @ -589,7 +589,7 @@ static void SetFSFromISO(void) | ||||||
| 	int i, fs_tmp, preferred_fs = FS_UNKNOWN; | 	int i, fs_tmp, preferred_fs = FS_UNKNOWN; | ||||||
| 	uint32_t fs_mask = FS_FAT32 | FS_NTFS; | 	uint32_t fs_mask = FS_FAT32 | FS_NTFS; | ||||||
| 	BOOL windows_to_go = (image_options & IMOP_WINTOGO) && (boot_type == BT_IMAGE) && | 	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) | 	if (image_path == NULL) | ||||||
| 		return; | 		return; | ||||||
|  | @ -649,7 +649,7 @@ static void SetMBRProps(void) | ||||||
| 	fs_type = (int)ComboBox_GetCurItemData(hFileSystem); | 	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) || | 	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); | 		CheckDlgButton(hMainDialog, IDC_RUFUS_MBR, BST_UNCHECKED); | ||||||
| 		IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0)); | 		IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0)); | ||||||
| 		return; | 		return; | ||||||
|  | @ -1129,10 +1129,17 @@ static void UpdateImage(BOOL update_image_option_only) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ComboBox_ResetContent(hImageOption); | 	ComboBox_ResetContent(hImageOption); | ||||||
| 	if (!img_report.is_windows_img) | 
 | ||||||
| 		IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_117)), FALSE)); | 	if (!img_report.is_windows_img) {	// Straight install.wim/install.esd only have Windows To Go option
 | ||||||
| 	IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_118)), TRUE)); | 		if (img_report.win_version.major == 11) { | ||||||
| 	IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, (img_report.is_windows_img || !windows_to_go_selected) ? 0 : 1)); | 			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) | 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_iso = (BOOLEAN)ExtractISO(image_path, "", TRUE); | ||||||
| 	img_report.is_bootable_img = IsBootableImage(image_path); | 	img_report.is_bootable_img = IsBootableImage(image_path); | ||||||
| 	ComboBox_ResetContent(hImageOption); | 	ComboBox_ResetContent(hImageOption); | ||||||
|  | 	imop_win_sel = 0; | ||||||
| 
 | 
 | ||||||
| 	if ((FormatStatus == (ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_CANCELLED)) || | 	if ((FormatStatus == (ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_CANCELLED)) || | ||||||
| 		(img_report.image_size == 0) || | 		(img_report.image_size == 0) || | ||||||
|  | @ -1409,7 +1417,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param) | ||||||
| 				goto out; | 				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) { | 			if (fs_type != FS_NTFS) { | ||||||
| 				// Windows To Go only works for 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); | 				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; | 	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 |  * Main dialog callback | ||||||
|  */ |  */ | ||||||
|  | @ -2155,8 +2181,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 	case WM_COMMAND: | 	case WM_COMMAND: | ||||||
| #ifdef RUFUS_TEST | #ifdef RUFUS_TEST | ||||||
| 		if (LOWORD(wParam) == IDC_TEST) { | 		if (LOWORD(wParam) == IDC_TEST) { | ||||||
| 			DWORD DriveIndex = (DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList)); | 			CreateThread(NULL, 0, TestThread, NULL, 0, NULL); | ||||||
| 			uprintf("label = '%s'", GetExtFsLabel(DriveIndex, 1)); |  | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
|  | @ -2333,7 +2358,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 			if (HIWORD(wParam) != CBN_SELCHANGE) | 			if (HIWORD(wParam) != CBN_SELCHANGE) | ||||||
| 				break; | 				break; | ||||||
| 			SetFileSystemAndClusterSize(NULL); | 			SetFileSystemAndClusterSize(NULL); | ||||||
| 			windows_to_go_selected = (BOOL)ComboBox_GetCurItemData(hImageOption); | 			imop_win_sel = ComboBox_GetCurSel(hImageOption); | ||||||
| 			break; | 			break; | ||||||
| 		case IDC_PERSISTENCE_SIZE: | 		case IDC_PERSISTENCE_SIZE: | ||||||
| 			if (HIWORD(wParam) == EN_CHANGE) { | 			if (HIWORD(wParam) == EN_CHANGE) { | ||||||
|  | @ -3624,8 +3649,8 @@ relaunch: | ||||||
| 				WriteSetting32(SETTING_DEFAULT_THREAD_PRIORITY, default_thread_priority - THREAD_PRIORITY_ABOVE_NORMAL); | 				WriteSetting32(SETTING_DEFAULT_THREAD_PRIORITY, default_thread_priority - THREAD_PRIORITY_ABOVE_NORMAL); | ||||||
| 				if (format_thread != NULL) | 				if (format_thread != NULL) | ||||||
| 					SetThreadPriority(format_thread, default_thread_priority); | 					SetThreadPriority(format_thread, default_thread_priority); | ||||||
| 				if (apply_wim_thread != NULL) | 				if (wim_thread != NULL) | ||||||
| 					SetThreadPriority(apply_wim_thread, default_thread_priority); | 					SetThreadPriority(wim_thread, default_thread_priority); | ||||||
| 			} | 			} | ||||||
| 			PrintStatus(STATUS_MSG_TIMEOUT, MSG_318, default_thread_priority); | 			PrintStatus(STATUS_MSG_TIMEOUT, MSG_318, default_thread_priority); | ||||||
| 			continue; | 			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
 | // For the partition types we'll use Microsoft's PARTITION_STYLE_### constants
 | ||||||
| #define PARTITION_STYLE_SFD PARTITION_STYLE_RAW | #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 { | enum checksum_type { | ||||||
| 	CHECKSUM_MD5 = 0, | 	CHECKSUM_MD5 = 0, | ||||||
| 	CHECKSUM_SHA1, | 	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 GetResourceSize(HMODULE module, char* name, char* type, const char* desc); | ||||||
| extern DWORD RunCommand(const char* cmdline, const char* dir, BOOL log); | extern DWORD RunCommand(const char* cmdline, const char* dir, BOOL log); | ||||||
| extern BOOL CompareGUID(const GUID *guid1, const GUID *guid2); | 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 BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue); | ||||||
| extern LONG GetEntryWidth(HWND hDropDown, const char* entry); | extern LONG GetEntryWidth(HWND hDropDown, const char* entry); | ||||||
| extern uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress); | 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_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 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 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 uint8_t IsBootableImage(const char* path); | ||||||
| extern BOOL AppendVHDFooter(const char* vhd_path); | extern BOOL AppendVHDFooter(const char* vhd_path); | ||||||
| extern int SetWinToGoIndex(void); | extern int SetWinToGoIndex(void); | ||||||
|  | @ -594,7 +605,7 @@ extern BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBy | ||||||
| 	LPDWORD lpNumberOfBytesWritten, DWORD nNumRetries); | 	LPDWORD lpNumberOfBytesWritten, DWORD nNumRetries); | ||||||
| extern BOOL SetThreadAffinity(DWORD_PTR* thread_affinity, size_t num_threads); | 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 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 IsFileInDB(const char* path); | ||||||
| extern BOOL IsBufferInDB(const unsigned char* buf, const size_t len); | extern BOOL IsBufferInDB(const unsigned char* buf, const size_t len); | ||||||
| #define printbits(x) _printbits(sizeof(x), &x, 0) | #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 | 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.16.1831" | CAPTION "Rufus 3.16.1832" | ||||||
| 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 | ||||||
|  | @ -395,8 +395,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 3,16,1831,0 |  FILEVERSION 3,16,1832,0 | ||||||
|  PRODUCTVERSION 3,16,1831,0 |  PRODUCTVERSION 3,16,1832,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -414,13 +414,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.16.1831" |             VALUE "FileVersion", "3.16.1832" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2021 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2021 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.16.exe" |             VALUE "OriginalFilename", "rufus-3.16.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "3.16.1831" |             VALUE "ProductVersion", "3.16.1832" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
							
								
								
									
										85
									
								
								src/stdfn.c
									
										
									
									
									
								
							
							
						
						
									
										85
									
								
								src/stdfn.c
									
										
									
									
									
								
							|  | @ -24,6 +24,7 @@ | ||||||
| #include <windows.h> | #include <windows.h> | ||||||
| #include <sddl.h> | #include <sddl.h> | ||||||
| #include <gpedit.h> | #include <gpedit.h> | ||||||
|  | #include <assert.h> | ||||||
| 
 | 
 | ||||||
| #include "rufus.h" | #include "rufus.h" | ||||||
| #include "missing.h" | #include "missing.h" | ||||||
|  | @ -997,3 +998,87 @@ char* GetCurrentMUI(void) | ||||||
| 	} | 	} | ||||||
| 	return mui_str; | 	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; | UINT_PTR UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU; | ||||||
| HIMAGELIST hUpImageList, hDownImageList; | HIMAGELIST hUpImageList, hDownImageList; | ||||||
| extern BOOL use_vds, appstore_version; | extern BOOL use_vds, appstore_version; | ||||||
|  | extern int imop_win_sel; | ||||||
| int update_progress_type = UPT_PERCENT; | int update_progress_type = UPT_PERCENT; | ||||||
| int advanced_device_section_height, advanced_format_section_height; | int advanced_device_section_height, advanced_format_section_height; | ||||||
| // (empty) check box width, (empty) drop down width, button height (for and without dropdown match)
 | // (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
 | 	// 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_117)).cx); | ||||||
| 	fw = max(fw, GetTextSize(hImageOption, lmprintf(MSG_118)).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
 | 	// Now deal with full length checkbox lines
 | ||||||
| 	for (i = 0; i<ARRAYSIZE(full_width_checkboxes); i++) | 	for (i = 0; i<ARRAYSIZE(full_width_checkboxes); i++) | ||||||
|  | @ -790,7 +793,7 @@ void ToggleImageOptions(void) | ||||||
| 		image_options ^= IMOP_WINTOGO; | 		image_options ^= IMOP_WINTOGO; | ||||||
| 		if (image_options & IMOP_WINTOGO) { | 		if (image_options & IMOP_WINTOGO) { | ||||||
| 			// Set the Windows To Go selection in the dropdown
 | 			// 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 HWND hMultiToolbar, hSaveToolbar, hHashToolbar, hAdvancedDeviceToolbar, hAdvancedFormatToolbar; | ||||||
| extern HFONT hInfoFont; | extern HFONT hInfoFont; | ||||||
| extern UINT_PTR UM_LANGUAGE_MENU_MAX; | 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 loc_cmd* selected_locale; | ||||||
| extern uint64_t persistence_size; | extern uint64_t persistence_size; | ||||||
| extern const char *sfd_name, *flash_type[BADLOCKS_PATTERN_TYPES]; | 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*)); | PF_TYPE_DECL(RPC_ENTRY, RPC_STATUS, UuidCreate, (UUID __RPC_FAR*)); | ||||||
| 
 | 
 | ||||||
| uint32_t wim_nb_files, wim_proc_files, wim_extra_files; | 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 int default_thread_priority; | ||||||
| extern BOOL ignore_boot_marker; | extern BOOL ignore_boot_marker; | ||||||
| 
 | 
 | ||||||
| static uint8_t wim_flags = 0; | 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 char sevenzip_path[MAX_PATH]; | ||||||
| static const char conectix_str[] = VHD_FOOTER_COOKIE; | static const char conectix_str[] = VHD_FOOTER_COOKIE; | ||||||
| static BOOL count_files; | static BOOL count_files; | ||||||
|  | // Apply/Mount image functionality
 | ||||||
|  | static const char *_image, *_dst; | ||||||
|  | static int _index; | ||||||
| 
 | 
 | ||||||
| static BOOL Get7ZipPath(void) | static BOOL Get7ZipPath(void) | ||||||
| { | { | ||||||
|  | @ -381,55 +384,115 @@ uint8_t WimExtractCheck(BOOL bSilent) | ||||||
| 	return wim_flags; | 	return wim_flags; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Looks like Microsoft's idea of "mount" for WIM images is to just *extract* all
 | // Looks like Microsoft's idea of "mount" for WIM images involves the creation
 | ||||||
| // files to a mounpoint and pretend it is "mounted", even if you do specify that
 | // of a as many virtual junctions as there exist directories on the image...
 | ||||||
| // you're not planning to change the content. So, yeah, this is both super slow
 | // So, yeah, this is both very slow and wasteful of space.
 | ||||||
| // and super wasteful of space... These calls are a complete waste of time.
 | static DWORD WINAPI WimMountImageThread(LPVOID param) | ||||||
| BOOL WimMountImage(char* pszWimFileName, DWORD dwImageIndex) |  | ||||||
| { | { | ||||||
| 	BOOL r = FALSE; | 	BOOL r = FALSE; | ||||||
| 	wconvert(temp_dir); | 	wconvert(temp_dir); | ||||||
| 	wconvert(pszWimFileName); | 	wchar_t* wimage = utf8_to_wchar(_image); | ||||||
| 	PF_INIT_OR_OUT(WIMMountImage, Wimgapi); | 	PF_INIT_OR_OUT(WIMMountImage, Wimgapi); | ||||||
| 
 | 
 | ||||||
| 	if (wmount_path[0] != 0) { | 	if (wmount_path[0] != 0) { | ||||||
| 		uprintf("WimMountImage: An image is already mounted"); | 		uprintf("WimMountImage: An image is already mounted"); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	if (GetTempFileNameW(wtemp_dir, L"Rufus", 0, wmount_path) == 0) { | 	if (GetTempFileNameW(wtemp_dir, L"Ruf", 0, wmount_path) == 0) { | ||||||
| 		uprintf("WimMountImage: Can not create mount directory"); | 		uprintf("WimMountImage: Can not generate mount directory: %s", WindowsErrorString()); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	DeleteFileW(wmount_path); | 	DeleteFileW(wmount_path); | ||||||
| 	if (!CreateDirectoryW(wmount_path, 0)) { | 	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; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	r = pfWIMMountImage(wmount_path, wpszWimFileName, dwImageIndex, NULL); | 	r = pfWIMMountImage(wmount_path, wimage, _index, wmount_track); | ||||||
| 	if (!r) | 	if (!r) { | ||||||
| 		uprintf("Could not mount %S on %S: %s", wpszWimFileName, wmount_path, WindowsErrorString()); | 		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: | out: | ||||||
| 	wfree(temp_dir); | 	wfree(temp_dir); | ||||||
| 	wfree(pszWimFileName); | 	safe_free(wimage); | ||||||
| 	return r; | 	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; | 	BOOL r = FALSE; | ||||||
|  | 	wchar_t* wimage = utf8_to_wchar(_image); | ||||||
| 	PF_INIT_OR_OUT(WIMUnmountImage, Wimgapi); | 	PF_INIT_OR_OUT(WIMUnmountImage, Wimgapi); | ||||||
|  | 
 | ||||||
| 	if (wmount_path[0] == 0) { | 	if (wmount_path[0] == 0) { | ||||||
| 		uprintf("WimUnmountImage: No image is mounted"); | 		uprintf("WimUnmountImage: No image is mounted"); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	r = pfWIMUnmountImage(wmount_path, NULL, 0, FALSE); | 	r = pfWIMUnmountImage(wmount_path, wimage, _index, TRUE); | ||||||
| 	if (!r) | 	if (!r) { | ||||||
| 		uprintf("Could not unmount %S: %s", wmount_path, WindowsErrorString()); | 		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; | 	wmount_path[0] = 0; | ||||||
|  | 	RemoveDirectoryW(wmount_track); | ||||||
|  | 	wmount_track[0] = 0; | ||||||
| out: | 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)
 | // 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)) ); | 		  || ((wim_flags & WIM_HAS_API_EXTRACT) && WimExtractFile_API(image, index, src, dst, bSilent)) ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Apply image functionality
 | // From https://docs.microsoft.com/en-us/previous-versions/msdn10/dd834960(v=msdn.10)
 | ||||||
| static const char *_image, *_dst; | // as well as https://msfn.org/board/topic/150700-wimgapi-wimmountimage-progressbar/
 | ||||||
| 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/
 |  | ||||||
| enum WIMMessage { | enum WIMMessage { | ||||||
| 	WIM_MSG = WM_APP + 0x1476, | 	WIM_MSG = WM_APP + 0x1476, | ||||||
| 	WIM_MSG_TEXT, | 	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)
 | // 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
 | // To get progress, we must run this call within its own thread
 | ||||||
| static DWORD WINAPI WimApplyImageThread(LPVOID param) | static DWORD WINAPI WimApplyImageThread(LPVOID param) | ||||||
| { | { | ||||||
|  | @ -800,15 +859,15 @@ BOOL WimApplyImage(const char* image, int index, const char* dst) | ||||||
| 	_index = index; | 	_index = index; | ||||||
| 	_dst = dst; | 	_dst = dst; | ||||||
| 
 | 
 | ||||||
| 	apply_wim_thread = CreateThread(NULL, 0, WimApplyImageThread, NULL, 0, NULL); | 	wim_thread = CreateThread(NULL, 0, WimApplyImageThread, NULL, 0, NULL); | ||||||
| 	if (apply_wim_thread == NULL) { | 	if (wim_thread == NULL) { | ||||||
| 		uprintf("Unable to start apply-image thread"); | 		uprintf("Unable to start apply-image thread"); | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 	} | 	} | ||||||
| 	SetThreadPriority(apply_wim_thread, default_thread_priority); | 	SetThreadPriority(wim_thread, default_thread_priority); | ||||||
| 	WaitForSingleObject(apply_wim_thread, INFINITE); | 	WaitForSingleObject(wim_thread, INFINITE); | ||||||
| 	if (!GetExitCodeThread(apply_wim_thread, &dw)) | 	if (!GetExitCodeThread(wim_thread, &dw)) | ||||||
| 		dw = 0; | 		dw = 0; | ||||||
| 	apply_wim_thread = NULL; | 	wim_thread = NULL; | ||||||
| 	return dw; | 	return dw; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue