diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml
index 043e9caa..f30e4f95 100644
--- a/.github/workflows/coverity.yml
+++ b/.github/workflows/coverity.yml
@@ -23,7 +23,7 @@ env:
 
 jobs:
   Coverity-Build:
-    runs-on: windows-latest
+    runs-on: windows-2022
 
     steps:
     - name: Checkout repository
diff --git a/.vs/rufus.vcxproj b/.vs/rufus.vcxproj
index 11b65194..bb244d38 100644
--- a/.vs/rufus.vcxproj
+++ b/.vs/rufus.vcxproj
@@ -373,7 +373,6 @@
     
     
     
-    
   
   
     
@@ -406,7 +405,6 @@
     
     
     
-    
   
   
     
diff --git a/.vs/rufus.vcxproj.filters b/.vs/rufus.vcxproj.filters
index d42d2867..37f31fcb 100644
--- a/.vs/rufus.vcxproj.filters
+++ b/.vs/rufus.vcxproj.filters
@@ -90,9 +90,6 @@
     
       Source Files
     
-    
-      Source Files
-    
   
   
     
@@ -185,9 +182,6 @@
     
       Header Files
     
-    
-      Header Files
-    
   
   
     
diff --git a/src/Makefile.am b/src/Makefile.am
index 7a461b6c..b7e2bb07 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,7 +15,7 @@ AM_V_WINDRES   = $(AM_V_WINDRES_$(V))
 	$(AM_V_WINDRES) $(AM_RCFLAGS) -i $< -o $@
 
 rufus_SOURCES = badblocks.c checksum.c dev.c dos.c dos_locale.c drive.c format.c format_ext.c format_fat32.c icon.c iso.c localization.c \
-	net.c parser.c pki.c process.c re.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c ui.c vhd.c wue.c
+	net.c parser.c pki.c process.c re.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c ui.c vhd.c
 rufus_CFLAGS = -I$(srcdir)/ms-sys/inc -I$(srcdir)/syslinux/libfat -I$(srcdir)/syslinux/libinstaller -I$(srcdir)/syslinux/win -I$(srcdir)/libcdio $(AM_CFLAGS) \
 	-DEXT2_FLAT_INCLUDES=0 -DSOLUTION=rufus
 rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows -L ../.mingw
diff --git a/src/Makefile.in b/src/Makefile.in
index 2a1be230..6ee3ec59 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -98,7 +98,7 @@ am_rufus_OBJECTS = rufus-badblocks.$(OBJEXT) rufus-checksum.$(OBJEXT) \
 	rufus-rufus.$(OBJEXT) rufus-smart.$(OBJEXT) \
 	rufus-stdfn.$(OBJEXT) rufus-stdio.$(OBJEXT) \
 	rufus-stdlg.$(OBJEXT) rufus-syslinux.$(OBJEXT) \
-	rufus-ui.$(OBJEXT) rufus-vhd.$(OBJEXT) rufus-wue.$(OBJEXT)
+	rufus-ui.$(OBJEXT) rufus-vhd.$(OBJEXT)
 rufus_OBJECTS = $(am_rufus_OBJECTS)
 am__DEPENDENCIES_1 =
 rufus_DEPENDENCIES = rufus_rc.o bled/libbled.a ext2fs/libext2fs.a \
@@ -282,7 +282,7 @@ AM_V_WINDRES_1 = $(WINDRES)
 AM_V_WINDRES_ = $(AM_V_WINDRES_$(AM_DEFAULT_VERBOSITY))
 AM_V_WINDRES = $(AM_V_WINDRES_$(V))
 rufus_SOURCES = badblocks.c checksum.c dev.c dos.c dos_locale.c drive.c format.c format_ext.c format_fat32.c icon.c iso.c localization.c \
-	net.c parser.c pki.c process.c re.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c ui.c vhd.c wue.c
+	net.c parser.c pki.c process.c re.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c ui.c vhd.c
 
 rufus_CFLAGS = -I$(srcdir)/ms-sys/inc -I$(srcdir)/syslinux/libfat -I$(srcdir)/syslinux/libinstaller -I$(srcdir)/syslinux/win -I$(srcdir)/libcdio $(AM_CFLAGS) \
 	-DEXT2_FLAT_INCLUDES=0 -DSOLUTION=rufus
@@ -495,12 +495,6 @@ rufus-vhd.o: vhd.c
 rufus-vhd.obj: vhd.c
 	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-vhd.obj `if test -f 'vhd.c'; then $(CYGPATH_W) 'vhd.c'; else $(CYGPATH_W) '$(srcdir)/vhd.c'; fi`
 
-rufus-wue.o: wue.c
-	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-wue.o `test -f 'wue.c' || echo '$(srcdir)/'`wue.c
-
-rufus-wue.obj: wue.c
-	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-wue.obj `if test -f 'wue.c'; then $(CYGPATH_W) 'wue.c'; else $(CYGPATH_W) '$(srcdir)/wue.c'; fi`
-
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run 'make' without going through this Makefile.
 # To change the values of 'make' variables: instead of editing Makefiles,
diff --git a/src/format.c b/src/format.c
index c2383a37..c99a2ab6 100644
--- a/src/format.c
+++ b/src/format.c
@@ -44,7 +44,6 @@
 #include "localization.h"
 
 #include "br.h"
-#include "wue.h"
 #include "fat16.h"
 #include "fat32.h"
 #include "ntfs.h"
@@ -66,14 +65,18 @@ const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT",
 DWORD FormatStatus = 0, LastWriteError = 0;
 badblocks_report report = { 0 };
 static float format_percent = 0.0f;
-static int task_number = 0, actual_fs_type;
+static int task_number = 0;
 static unsigned int sec_buf_pos = 0;
 extern const int nb_steps[FS_MAX];
 extern uint32_t dur_mins, dur_secs;
 extern uint32_t wim_nb_files, wim_proc_files, wim_extra_files;
+static int actual_fs_type, wintogo_index = -1, wininst_index = 0;
+extern int unattend_xml_flags;
 extern BOOL force_large_fat32, enable_ntfs_compression, lock_drive, zero_drive, fast_zeroing, enable_file_indexing;
 extern BOOL write_as_image, use_vds, write_as_esp, is_vds_available;
 extern const grub_patch_t grub_patch[2];
+extern char* unattend_xml_path;
+extern const char* bypass_name[4];
 uint8_t *grub2_buf = NULL, *sec_buf = NULL;
 long grub2_len;
 
@@ -661,7 +664,7 @@ out:
 	return r;
 }
 
-BOOL FormatPartition(DWORD DriveIndex, uint64_t PartitionOffset, DWORD UnitAllocationSize, USHORT FSType, LPCSTR Label, DWORD Flags)
+static BOOL FormatPartition(DWORD DriveIndex, uint64_t PartitionOffset, DWORD UnitAllocationSize, USHORT FSType, LPCSTR Label, DWORD Flags)
 {
 	if ((DriveIndex < 0x80) || (DriveIndex > 0x100) || (FSType >= FS_MAX) ||
 		((UnitAllocationSize != 0) && (!IS_POWER_OF_2(UnitAllocationSize)))) {
@@ -1107,6 +1110,557 @@ BOOL WritePBR(HANDLE hLogicalVolume)
 	return FALSE;
 }
 
+/*
+ * Setup WinPE for bootable USB
+ */
+static BOOL SetupWinPE(char drive_letter)
+{
+	char src[64], dst[32];
+	const char* basedir[3] = { "i386", "amd64", "minint" };
+	const char* patch_str_org[2] = { "\\minint\\txtsetup.sif", "\\minint\\system32\\" };
+	const char* patch_str_rep[2][2] = { { "\\i386\\txtsetup.sif", "\\i386\\system32\\" } ,
+										{ "\\amd64\\txtsetup.sif", "\\amd64\\system32\\" } };
+	const char *win_nt_bt_org = "$win_nt$.~bt";
+	const char *rdisk_zero = "rdisk(0)";
+	const LARGE_INTEGER liZero = { {0, 0} };
+	char setupsrcdev[64];
+	HANDLE handle = INVALID_HANDLE_VALUE;
+	DWORD i, j, size, rw_size, index = 0;
+	BOOL r = FALSE;
+	char* buffer = NULL;
+
+	if ((img_report.winpe & WINPE_AMD64) == WINPE_AMD64)
+		index = 1;
+	else if ((img_report.winpe & WINPE_MININT) == WINPE_MININT)
+		index = 2;
+	// Allow other values than harddisk 1, as per user choice for disk ID
+	static_sprintf(setupsrcdev, "SetupSourceDevice = \"\\device\\harddisk%d\\partition1\"",
+		ComboBox_GetCurSel(hDiskID));
+	// Copy of ntdetect.com in root
+	static_sprintf(src, "%c:\\%s\\ntdetect.com", toupper(drive_letter), basedir[2*(index/2)]);
+	static_sprintf(dst, "%c:\\ntdetect.com", toupper(drive_letter));
+	CopyFileA(src, dst, TRUE);
+	if (!img_report.uses_minint) {
+		// Create a copy of txtsetup.sif, as we want to keep the i386/amd64 files unmodified
+		static_sprintf(src, "%c:\\%s\\txtsetup.sif", toupper(drive_letter), basedir[index]);
+		static_sprintf(dst, "%c:\\txtsetup.sif", toupper(drive_letter));
+		if (!CopyFileA(src, dst, TRUE)) {
+			uprintf("Did not copy %s as %s: %s\n", src, dst, WindowsErrorString());
+		}
+		if (insert_section_data(dst, "[SetupData]", setupsrcdev, FALSE) == NULL) {
+			uprintf("Failed to add SetupSourceDevice in %s\n", dst);
+			goto out;
+		}
+		uprintf("Successfully added '%s' to %s\n", setupsrcdev, dst);
+	}
+
+	static_sprintf(src, "%c:\\%s\\setupldr.bin", toupper(drive_letter),  basedir[2*(index/2)]);
+	static_sprintf(dst, "%c:\\BOOTMGR", toupper(drive_letter));
+	if (!CopyFileA(src, dst, TRUE)) {
+		uprintf("Did not copy %s as %s: %s\n", src, dst, WindowsErrorString());
+	}
+
+	// \minint with /minint option doesn't require further processing => return true
+	// \minint and no \i386 without /minint is unclear => return error
+	if (img_report.winpe&WINPE_MININT) {
+		if (img_report.uses_minint) {
+			uprintf("Detected \\minint directory with /minint option: nothing to patch\n");
+			r = TRUE;
+		} else if (!(img_report.winpe&(WINPE_I386|WINPE_AMD64))) {
+			uprintf("Detected \\minint directory only but no /minint option: not sure what to do\n");
+		}
+		goto out;
+	}
+
+	// At this stage we only handle \i386
+	handle = CreateFileA(dst, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,
+		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	if (handle == INVALID_HANDLE_VALUE) {
+		uprintf("Could not open %s for patching: %s\n", dst, WindowsErrorString());
+		goto out;
+	}
+	size = GetFileSize(handle, NULL);
+	if (size == INVALID_FILE_SIZE) {
+		uprintf("Could not get size for file %s: %s\n", dst, WindowsErrorString());
+		goto out;
+	}
+	buffer = (char*)malloc(size);
+	if (buffer == NULL)
+		goto out;
+	if ((!ReadFile(handle, buffer, size, &rw_size, NULL)) || (size != rw_size)) {
+		uprintf("Could not read file %s: %s\n", dst, WindowsErrorString());
+		goto out;
+	}
+	if (!SetFilePointerEx(handle, liZero, NULL, FILE_BEGIN)) {
+		uprintf("Could not rewind file %s: %s\n", dst, WindowsErrorString());
+		goto out;
+	}
+
+	// Patch setupldr.bin
+	uprintf("Patching file %s\n", dst);
+	// Remove CRC check for 32 bit part of setupldr.bin from Win2k3
+	if ((size > 0x2061) && (buffer[0x2060] == 0x74) && (buffer[0x2061] == 0x03)) {
+		buffer[0x2060] = 0xeb;
+		buffer[0x2061] = 0x1a;
+		uprintf("  0x00002060: 0x74 0x03 -> 0xEB 0x1A (disable Win2k3 CRC check)\n");
+	}
+	for (i=1; i '%s'\n", i, &buffer[i], patch_str_rep[index][j]);
+				strcpy(&buffer[i], patch_str_rep[index][j]);
+				i += (DWORD)max(strlen(patch_str_org[j]), strlen(patch_str_rep[index][j]));	// in case org is a substring of rep
+			}
+		}
+	}
+
+	if (!img_report.uses_minint) {
+		// Additional setupldr.bin/bootmgr patching
+		for (i=0; i rdisk(#) disk masquerading
+			// NB: only the first one seems to be needed
+			if (safe_strnicmp(&buffer[i], rdisk_zero, strlen(rdisk_zero)-1) == 0) {
+				buffer[i+6] = 0x30 + ComboBox_GetCurSel(hDiskID);
+				uprintf("  0x%08X: '%s' -> 'rdisk(%c)'\n", i, rdisk_zero, buffer[i+6]);
+			}
+			// $WIN_NT$_~BT -> i386/amd64
+			if (safe_strnicmp(&buffer[i], win_nt_bt_org, strlen(win_nt_bt_org)-1) == 0) {
+				uprintf("  0x%08X: '%s' -> '%s%s'\n", i, &buffer[i], basedir[index], &buffer[i+strlen(win_nt_bt_org)]);
+				strcpy(&buffer[i], basedir[index]);
+				// This ensures that we keep the terminator backslash
+				buffer[i+strlen(basedir[index])] = buffer[i+strlen(win_nt_bt_org)];
+				buffer[i+strlen(basedir[index])+1] = 0;
+			}
+		}
+	}
+
+	if (!WriteFileWithRetry(handle, buffer, size, &rw_size, WRITE_RETRIES)) {
+		uprintf("Could not write patched file: %s\n", WindowsErrorString());
+		goto out;
+	}
+	r = TRUE;
+
+out:
+	safe_closehandle(handle);
+	safe_free(buffer);
+	return r;
+}
+
+// Checks which versions of Windows are available in an install image
+// to set our extraction index. Asks the user to select one if needed.
+// Returns -2 on user cancel, -1 on other error, >=0 on success.
+int SetWinToGoIndex(void)
+{
+	char *mounted_iso, *val, mounted_image_path[128];
+	char xml_file[MAX_PATH] = "";
+	char *install_names[MAX_WININST];
+	StrArray version_name, version_index;
+	int i;
+	BOOL bNonStandard = FALSE;
+
+	// Sanity checks
+	wintogo_index = -1;
+	wininst_index = 0;
+	if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck(FALSE) & 4) == 0) ||
+		(ComboBox_GetCurItemData(hFileSystem) != FS_NTFS)) {
+		return -1;
+	}
+
+	// If we have multiple windows install images, ask the user the one to use
+	if (img_report.wininst_index > 1) {
+		for (i = 0; i < img_report.wininst_index; i++)
+			install_names[i] = &img_report.wininst_path[i][2];
+		wininst_index = _log2(SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_130),
+			lmprintf(MSG_131), install_names, img_report.wininst_index, 1));
+		if (wininst_index < 0)
+			return -2;
+		if (wininst_index >= MAX_WININST)
+			wininst_index = 0;
+	}
+
+	// If we're not using a straight install.wim, we need to mount the ISO to access it
+	if (!img_report.is_windows_img) {
+		mounted_iso = MountISO(image_path);
+		if (mounted_iso == NULL) {
+			uprintf("Could not mount ISO for Windows To Go selection");
+			return FALSE;
+		}
+		static_sprintf(mounted_image_path, "%s%s", mounted_iso, &img_report.wininst_path[wininst_index][2]);
+	}
+
+	// Now take a look at the XML file in install.wim to list our versions
+	if ((GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, xml_file) == 0) || (xml_file[0] == 0)) {
+		// Last ditch effort to get a tmp file - just extract it to the current directory
+		static_strcpy(xml_file, ".\\RufVXml.tmp");
+	}
+	// GetTempFileName() may leave a file behind
+	DeleteFileU(xml_file);
+
+	// Must use the Windows WIM API as 7z messes up the XML
+	if (!WimExtractFile_API(img_report.is_windows_img ? image_path : mounted_image_path,
+		0, "[1].xml", xml_file, FALSE)) {
+		uprintf("Could not acquire WIM index");
+		goto out;
+	}
+
+	StrArrayCreate(&version_name, 16);
+	StrArrayCreate(&version_index, 16);
+	for (i = 0; StrArrayAdd(&version_index, get_token_data_file_indexed("IMAGE INDEX", xml_file, i + 1), FALSE) >= 0; i++) {
+		// Some people are apparently creating *unofficial* Windows ISOs that don't have DISPLAYNAME elements.
+		// If we are parsing such an ISO, try to fall back to using DESCRIPTION. Of course, since we don't use
+		// a formal XML parser, if an ISO mixes entries with both DISPLAYNAME and DESCRIPTION and others with
+		// only DESCRIPTION, the version names we report will be wrong.
+		// But hey, there's only so far I'm willing to go to help people who, not content to have demonstrated
+		// their utter ignorance on development matters, are also trying to lecture experienced developers
+		// about specific "noob mistakes"... that don't exist in the code they are trying to criticize.
+		if (StrArrayAdd(&version_name, get_token_data_file_indexed("DISPLAYNAME", xml_file, i + 1), FALSE) < 0) {
+			bNonStandard = TRUE;
+			if (StrArrayAdd(&version_name, get_token_data_file_indexed("DESCRIPTION", xml_file, i + 1), FALSE) < 0) {
+				uprintf("Warning: Could not find a description for image index %d", i + 1);
+				StrArrayAdd(&version_name, "Unknown Windows Version", TRUE);
+			}
+		}
+	}
+	if (bNonStandard)
+		uprintf("Warning: Nonstandard Windows image (missing  entries)");
+
+	if (i > 1)
+		// NB: _log2 returns -2 if SelectionDialog() returns negative (user cancelled)
+		i = _log2(SelectionDialog(BS_AUTORADIOBUTTON,
+			lmprintf(MSG_291), lmprintf(MSG_292), version_name.String, i, 1)) + 1;
+	if (i < 0)
+		wintogo_index = -2;	// Cancelled by the user
+	else if (i == 0)
+		wintogo_index = 1;
+	else
+		wintogo_index = atoi(version_index.String[i - 1]);
+	if (i > 0) {
+		// Get the version data from the XML index
+		val = get_token_data_file_indexed("MAJOR", xml_file, i);
+		img_report.win_version.major = (uint16_t)safe_atoi(val);
+		free(val);
+		val = get_token_data_file_indexed("MINOR", xml_file, i);
+		img_report.win_version.minor = (uint16_t)safe_atoi(val);
+		free(val);
+		val = get_token_data_file_indexed("BUILD", xml_file, i);
+		img_report.win_version.build = (uint16_t)safe_atoi(val);
+		free(val);
+		val = get_token_data_file_indexed("SPBUILD", xml_file, i);
+		img_report.win_version.revision = (uint16_t)safe_atoi(val);
+		free(val);
+		if ((img_report.win_version.major == 10) && (img_report.win_version.build > 20000))
+			img_report.win_version.major = 11;
+		// If we couldn't obtain the major and build, we have a problem
+		if (img_report.win_version.major == 0 || img_report.win_version.build == 0)
+			uprintf("Warning: Could not obtain version information from XML index (Nonstandard Windows image?)");
+		uprintf("Will use '%s' (Build: %d, Index %s) for Windows To Go",
+			version_name.String[i - 1], img_report.win_version.build, version_index.String[i - 1]);
+		// Need Windows 10 Creator Update or later for boot on REMOVABLE to work
+		if ((img_report.win_version.build < 15000) && (SelectedDrive.MediaType != FixedMedia)) {
+			if (MessageBoxExU(hMainDialog, lmprintf(MSG_098), lmprintf(MSG_190),
+				MB_YESNO | MB_ICONWARNING | MB_IS_RTL, selected_langid) != IDYES)
+				wintogo_index = -2;
+		}
+		// Display a notice about WppRecorder.sys for 1809 ISOs
+		if (img_report.win_version.build == 17763) {
+			notification_info more_info;
+			more_info.id = MORE_INFO_URL;
+			more_info.url = WPPRECORDER_MORE_INFO_URL;
+			Notification(MSG_INFO, NULL, &more_info, lmprintf(MSG_128, "Windows To Go"), lmprintf(MSG_133));
+		}
+	}
+	StrArrayDestroy(&version_name);
+	StrArrayDestroy(&version_index);
+
+out:
+	DeleteFileU(xml_file);
+	if (!img_report.is_windows_img)
+		UnMountISO();
+	return wintogo_index;
+}
+
+// https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-8.1-and-8/jj721578(v=ws.11)
+// As opposed to the technet guide above, we don't set internal drives offline,
+// due to people wondering why they can't see them by default and we also use
+// bcdedit rather than 'unattend.xml' to disable the recovery environment.
+static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
+{
+	char *mounted_iso, *ms_efi = NULL, mounted_image_path[128], cmd[MAX_PATH];
+	ULONG cluster_size;
+
+	uprintf("Windows To Go mode selected");
+	// Additional sanity checks
+	if ((use_esp) && (SelectedDrive.MediaType != FixedMedia) && (nWindowsBuildNumber < 15000)) {
+		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED;
+		return FALSE;
+	}
+
+	if (!img_report.is_windows_img) {
+		mounted_iso = MountISO(image_path);
+		if (mounted_iso == NULL) {
+			uprintf("Could not mount ISO for Windows To Go installation");
+			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_ISO_EXTRACT);
+			return FALSE;
+		}
+		static_sprintf(mounted_image_path, "%s%s", mounted_iso, &img_report.wininst_path[wininst_index][2]);
+		uprintf("Mounted ISO as '%s'", mounted_iso);
+	}
+
+	// Now we use the WIM API to apply that image
+	if (!WimApplyImage(img_report.is_windows_img ? image_path : mounted_image_path, wintogo_index, drive_name)) {
+		uprintf("Failed to apply Windows To Go image");
+		if (!IS_ERROR(FormatStatus))
+			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
+		if (!img_report.is_windows_img)
+			UnMountISO();
+		return FALSE;
+	}
+	if (!img_report.is_windows_img)
+		UnMountISO();
+
+	if (use_esp) {
+		uprintf("Setting up EFI System Partition");
+		// According to Ubuntu (https://bugs.launchpad.net/ubuntu/+source/partman-efi/+bug/811485) you want to use FAT32.
+		// However, you have to be careful that the cluster size needs to be greater or equal to the sector size, which
+		// in turn has an impact on the minimum EFI partition size we can create (see ms_efi_size_MB in drive.c)
+		if (SelectedDrive.SectorSize <= 1024)
+			cluster_size = 1024;
+		else if (SelectedDrive.SectorSize <= 4096)
+			cluster_size = 4096;
+		else	// Go for broke
+			cluster_size = (ULONG)SelectedDrive.SectorSize;
+		// Boy do you *NOT* want to specify a label here, and spend HOURS figuring out why your EFI partition cannot boot...
+		// Also, we use the Large FAT32 facility Microsoft APIs are *UTTERLY USELESS* for achieving what we want:
+		// VDS cannot list ESP volumes (talk about allegedly improving on the old disk and volume APIs, only to
+		// completely neuter it) and IVdsDiskPartitionMF::FormatPartitionEx(), which is what you are supposed to
+		// use for ESPs, explicitly states: "This method cannot be used to format removable media."
+		if (!FormatPartition(DriveIndex, partition_offset[PI_ESP], cluster_size, FS_FAT32, "",
+			FP_QUICK | FP_FORCE | FP_LARGE_FAT32 | FP_NO_BOOT)) {
+			uprintf("Could not format EFI System Partition");
+			return FALSE;
+		}
+		Sleep(200);
+		// Need to have the ESP mounted to invoke bcdboot
+		ms_efi = AltMountVolume(DriveIndex, partition_offset[PI_ESP], FALSE);
+		if (ms_efi == NULL) {
+			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER);
+			return FALSE;
+		}
+	}
+
+	// We invoke the 'bcdboot' command from the host, as the one from the drive produces problems (#558)
+	// and of course, we couldn't invoke an ARM64 'bcdboot' binary on an x86 host anyway...
+	// Also, since Rufus should (usually) be running as a 32 bit app, on 64 bit systems, we need to use
+	// 'C:\Windows\Sysnative' and not 'C:\Windows\System32' to invoke bcdboot, as 'C:\Windows\System32'
+	// will get converted to 'C:\Windows\SysWOW64' behind the scenes, and there is no bcdboot.exe there.
+	uprintf("Enabling boot using command:");
+	static_sprintf(cmd, "%s\\bcdboot.exe %s\\Windows /v /f %s /s %s", sysnative_dir, drive_name,
+		HAS_BOOTMGR_BIOS(img_report) ? (HAS_BOOTMGR_EFI(img_report) ? "ALL" : "BIOS") : "UEFI",
+		(use_esp)?ms_efi:drive_name);
+	uprintf(cmd);
+	if (RunCommand(cmd, sysnative_dir, usb_debug) != 0) {
+		// Try to continue... but report a failure
+		uprintf("Failed to enable boot");
+		FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_ISO_EXTRACT);
+	}
+
+	UpdateProgressWithInfo(OP_FILE_COPY, MSG_267, wim_proc_files + 2 * wim_extra_files, wim_nb_files);
+
+	// Setting internal drives offline for Windows To Go is crucial if, for instance, you are using ReFS
+	// on Windows 10 (therefore ReFS v3.4) and don't want a Windows 11 To Go boot to automatically
+	// "upgrade" the ReFS version on all drives to v3.7, thereby preventing you from being able to mount
+	// those volumes back on Windows 10 ever again. Yes, I have been stung by this Microsoft bullshit!
+	// See: https://gist.github.com/0xbadfca11/da0598e47dd643d933dc#Mountability
+	if (unattend_xml_flags & UNATTEND_OFFLINE_INTERNAL_DRIVES) {
+		uprintf("Setting the target's internal drives offline using command:");
+		// This applies the "offlineServicing" section of the unattend.xml (while ignoring the other sections)
+		static_sprintf(cmd, "dism /Image:%s\\ /Apply-Unattend:%s", drive_name, unattend_xml_path);
+		uprintf(cmd);
+		RunCommand(cmd, NULL, usb_debug);
+	}
+
+	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);
+	RunCommand(cmd, sysnative_dir, usb_debug);
+
+	UpdateProgressWithInfo(OP_FILE_COPY, MSG_267, wim_nb_files, wim_nb_files);
+
+	if (use_esp) {
+		Sleep(200);
+		AltUnmountVolume(ms_efi, FALSE);
+	}
+
+	return TRUE;
+}
+
+/*
+ * Add unattend.xml to 'sources\boot.wim' (install) or 'Windows\Panther\' (Windows To Go)
+ * NB: Work with a copy of unattend_xml_flags as a paremeter since we will modify it.
+ */
+BOOL ApplyWindowsCustomization(char drive_letter, int flags)
+{
+	BOOL r = FALSE, is_hive_mounted = FALSE;
+	int i;
+	const int wim_index = 2;
+	const char* offline_hive_name = "RUFUS_OFFLINE_HIVE";
+	char boot_wim_path[] = "?:\\sources\\boot.wim", key_path[64];
+	char appraiserres_dll_src[] = "?:\\sources\\appraiserres.dll";
+	char appraiserres_dll_dst[] = "?:\\sources\\appraiserres.bak";
+	char *mount_path = NULL, path[MAX_PATH];
+	HKEY hKey = NULL, hSubKey = NULL;
+	LSTATUS status;
+	DWORD dwDisp, dwVal = 1;
+
+	assert(unattend_xml_path != NULL);
+	uprintf("Applying Windows customization:");
+	if (flags & UNATTEND_WINDOWS_TO_GO) {
+		static_sprintf(path, "%c:\\Windows\\Panther", drive_letter);
+		if (!CreateDirectoryA(path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
+			uprintf("Could not create '%s' : %s", path, WindowsErrorString());
+			goto out;
+		}
+		static_sprintf(path, "%c:\\Windows\\Panther\\unattend.xml", drive_letter);
+		if (!CopyFileA(unattend_xml_path, path, TRUE)) {
+			uprintf("Could not create '%s' : %s", path, WindowsErrorString());
+			goto out;
+		}
+		uprintf("Added '%s'", path);
+	} else {
+		boot_wim_path[0] = drive_letter;
+		if (flags & UNATTEND_WINPE_SETUP_MASK) {
+			// Create a backup of sources\appraiserres.dll and then create an empty file to
+			// allow in-place upgrades without TPM/SB. Note that we need to create an empty,
+			// appraiserres.dll otherwise setup.exe extracts its own.
+			appraiserres_dll_src[0] = drive_letter;
+			appraiserres_dll_dst[0] = drive_letter;
+			if (!MoveFileExU(appraiserres_dll_src, appraiserres_dll_dst, MOVEFILE_REPLACE_EXISTING))
+				uprintf("Could not rename '%s': %s", appraiserres_dll_src, WindowsErrorString());
+			else
+				CloseHandle(CreateFileU(appraiserres_dll_src, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
+					NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
+			uprintf("Renamed '%s' → '%s'", appraiserres_dll_src, appraiserres_dll_dst);
+		}
+
+		UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 0, PATCH_PROGRESS_TOTAL);
+		// We only need to mount boot.wim if we have windowsPE data to deal with. If
+		// not, we can just copy our unattend.xml in \sources\$OEM$\$$\Panther\.
+		if (flags & UNATTEND_WINPE_SETUP_MASK) {
+			uprintf("Mounting '%s'...", boot_wim_path);
+			mount_path = WimMountImage(boot_wim_path, wim_index);
+			if (mount_path == NULL)
+				goto out;
+		}
+
+		if (flags & UNATTEND_SECUREBOOT_TPM_MINRAM) {
+			// Try to create the registry keys directly, and fallback to using unattend
+			// if that fails (which the Windows Store version is expected to do).
+			static_sprintf(path, "%s\\Windows\\System32\\config\\SYSTEM", mount_path);
+			if (!MountRegistryHive(HKEY_LOCAL_MACHINE, offline_hive_name, path)) {
+				uprintf("Falling back to creating the registry keys through unattend.xml");
+				goto copy_unattend;
+			}
+			UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 101, PATCH_PROGRESS_TOTAL);
+			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 copy_unattend;
+			}
+
+			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 copy_unattend;
+			}
+
+			for (i = 0; i < ARRAYSIZE(bypass_name); i++) {
+				status = RegSetValueExA(hSubKey, bypass_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",
+						bypass_name[i], WindowsErrorString());
+					goto copy_unattend;
+				}
+				uprintf("Created 'HKLM\\SYSTEM\\Setup\\LabConfig\\%s' registry key", bypass_name[i]);
+			}
+			// We were successfull in creating the keys so disable the windowsPE section from unattend.xml
+			// We do this by replacing '' with ''
+			// (provided that the registry key creation was the only item for this pass)
+			if ((flags & UNATTEND_WINPE_SETUP_MASK) == UNATTEND_SECUREBOOT_TPM_MINRAM) {
+				if (replace_in_token_data(unattend_xml_path, " entries from windowsPE (and only windowsPE).
+				assert(FALSE);
+			}
+			UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 102, PATCH_PROGRESS_TOTAL);
+		}
+
+copy_unattend:
+		if (flags & UNATTEND_WINPE_SETUP_MASK) {
+			// If we have a windowsPE section, copy the answer files to the root of boot.wim as
+			// Autounattend.xml. This also results in that file being automatically copied over
+			// to %WINDIR%\Panther\unattend.xml for later passes processing.
+			assert(mount_path != NULL);
+			static_sprintf(path, "%s\\Autounattend.xml", mount_path);
+			if (!CopyFileU(unattend_xml_path, path, TRUE)) {
+				uprintf("Could not create boot.wim 'Autounattend.xml': %s", WindowsErrorString());
+				goto out;
+			}
+			uprintf("Added 'Autounattend.xml' to '%s'", boot_wim_path);
+		} else {
+			// If there is no windowsPE section in our unattend, then copying it as Autounattend.xml on
+			// the root of boot.wim will not work as Windows Setup does *NOT* carry Autounattend.xml into
+			// %WINDIR%\Panther\unattend.xml then (See: https://github.com/pbatard/rufus/issues/1981).
+			// So instead, copy it to \sources\$OEM$\$$\Panther\unattend.xml on the media, as the content
+			// of \sources\$OEM$\$$\* will get copied into %WINDIR%\ during the file copy phase.
+			static_sprintf(path, "%c:\\sources\\$OEM$\\$$\\Panther", drive_letter);
+			i = SHCreateDirectoryExA(NULL, path, NULL);
+			if (i != ERROR_SUCCESS) {
+				SetLastError(i);
+				uprintf("Error: Could not create directory '%s': %s", path, WindowsErrorString());
+				goto out;
+			}
+			static_sprintf(path, "%c:\\sources\\$OEM$\\$$\\Panther\\unattend.xml", drive_letter);
+			if (!CopyFileU(unattend_xml_path, path, TRUE)) {
+				uprintf("Could not create '%s': %s", path, WindowsErrorString());
+				goto out;
+			}
+			uprintf("Created '%s'", path);
+		}
+		UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 103, PATCH_PROGRESS_TOTAL);
+	}
+	r = TRUE;
+
+out:
+	if (hSubKey != NULL)
+		RegCloseKey(hSubKey);
+	if (hKey != NULL)
+		RegCloseKey(hKey);
+	if (is_hive_mounted) {
+		UnmountRegistryHive(HKEY_LOCAL_MACHINE, offline_hive_name);
+		UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 104, PATCH_PROGRESS_TOTAL);
+	}
+	if (mount_path) {
+		uprintf("Unmounting '%s'...", boot_wim_path, wim_index);
+		WimUnmountImage(boot_wim_path, wim_index);
+		UpdateProgressWithInfo(OP_PATCH, MSG_325, PATCH_PROGRESS_TOTAL, PATCH_PROGRESS_TOTAL);
+	}
+	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.
diff --git a/src/format.h b/src/format.h
index 8bc514e8..398b60a6 100644
--- a/src/format.h
+++ b/src/format.h
@@ -16,8 +16,6 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see .
  */
-
-#include 
 #include 
 #include 	// for MEDIA_TYPE
 
@@ -114,5 +112,3 @@ typedef BOOLEAN (WINAPI* EnableVolumeCompression_t)(
 BOOL WritePBR(HANDLE hLogicalDrive);
 BOOL FormatLargeFAT32(DWORD DriveIndex, uint64_t PartitionOffset, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags);
 BOOL FormatExtFs(DWORD DriveIndex, uint64_t PartitionOffset, DWORD BlockSize, LPCSTR FSName, LPCSTR Label, DWORD Flags);
-BOOL FormatPartition(DWORD DriveIndex, uint64_t PartitionOffset, DWORD UnitAllocationSize, USHORT FSType, LPCSTR Label, DWORD Flags);
-DWORD WINAPI FormatThread(void* param);
diff --git a/src/missing.h b/src/missing.h
index 17bdc605..a204d1b0 100644
--- a/src/missing.h
+++ b/src/missing.h
@@ -115,39 +115,11 @@ static __inline int _log2(register int val)
 	return ret;
 }
 
-/// 
-/// Remaps bits from a byte according to an 8x8 bit matrix.
-/// 
-/// The byte to remap.
-/// An 8-byte array where each byte has a single bit set to the position to remap to.
-/// Indicates whether the reverse mapping operation should be applied.
-/// The remapped byte data.
+// Remap bits from a byte according to an 8x8 bit matrix
 static __inline uint8_t remap8(uint8_t src, uint8_t* map, const BOOL reverse)
 {
 	uint8_t i, m = 1, r = 0;
-	for (i = 0, m = 1; i < (sizeof(src) * 8); i++, m <<= 1) {
-		if (reverse) {
-			if (src & map[i])
-				r |= m;
-		} else {
-			if (src & m)
-				r |= map[i];
-		}
-	}
-	return r;
-}
-
-/// 
-/// Remaps bits from a 16-bit word according to a 16x16 bit matrix.
-/// 
-/// The word to remap.
-/// A 16-word array where each word has a single bit set to the position to remap to.
-/// Indicates whether the reverse mapping operation should be applied.
-/// The remapped byte data.
-static __inline uint16_t remap16(uint16_t src, uint16_t* map, const BOOL reverse)
-{
-	uint16_t i, m = 1, r = 0;
-	for (i = 0, m = 1; i < (sizeof(src) * 8); i++, m <<= 1) {
+	for (i = 0, m = 1; i < 8; i++, m <<= 1) {
 		if (reverse) {
 			if (src & map[i])
 				r |= m;
diff --git a/src/rufus.c b/src/rufus.c
index 823b0479..35bd9372 100755
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -39,7 +39,6 @@
 #include 
 
 #include "rufus.h"
-#include "format.h"
 #include "missing.h"
 #include "resource.h"
 #include "msapi_utf8.h"
@@ -47,7 +46,6 @@
 
 #include "ui.h"
 #include "re.h"
-#include "wue.h"
 #include "drive.h"
 #include "settings.h"
 #include "bled/bled.h"
@@ -80,7 +78,7 @@ static BOOL app_changed_label = FALSE;
 static BOOL allowed_filesystem[FS_MAX] = { 0 };
 static int64_t last_iso_blocking_status;
 static int selected_pt = -1, selected_fs = FS_UNKNOWN, preselected_fs = FS_UNKNOWN;
-static int image_index = 0, select_index = 0;
+static int image_index = 0, select_index = 0, unattend_xml_mask = UNATTEND_DEFAULT_SELECTION_MASK;
 static RECT relaunch_rc = { -65536, -65536, 0, 0};
 static UINT uMBRChecked = BST_UNCHECKED;
 static HANDLE format_thread = NULL;
@@ -127,7 +125,7 @@ BOOL write_as_image = FALSE, write_as_esp = FALSE, use_vds = FALSE, ignore_boot_
 BOOL appstore_version = FALSE, is_vds_available = TRUE;
 float fScale = 1.0f;
 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;
+int default_fs, fs_type, boot_type, partition_type, target_type, unattend_xml_flags = 0;
 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 app_data_dir[MAX_PATH], user_dir[MAX_PATH];
@@ -135,11 +133,12 @@ char embedded_sl_version_str[2][12] = { "?.??", "?.??" };
 char embedded_sl_version_ext[2][32];
 char ClusterSizeLabel[MAX_CLUSTER_SIZES][64];
 char msgbox[1024], msgbox_title[32], *ini_file = NULL, *image_path = NULL, *short_image_path;
-char *archive_path = NULL, image_option_txt[128], *fido_url = NULL;
+char *archive_path = NULL, image_option_txt[128], *fido_url = NULL, *unattend_xml_path = NULL;
 StrArray BlockingProcess, ImageList;
 // Number of steps for each FS for FCC_STRUCTURE_PROGRESS
 const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10, 1, 1, 1, 1 };
 const char* flash_type[BADLOCKS_PATTERN_TYPES] = { "SLC", "MLC", "TLC" };
+const char* bypass_name[] = { "BypassTPMCheck", "BypassSecureBootCheck", "BypassRAMCheck" };
 RUFUS_DRIVE rufus_drive[MAX_DRIVES] = { 0 };
 
 // TODO: Remember to update copyright year in stdlg's AboutCallback() WM_INITDIALOG,
@@ -1176,12 +1175,7 @@ static void UpdateImage(BOOL update_image_option_only)
 	IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, imop_win_sel));
 }
 
-/// 
-/// Parse a PE executable file and return its CPU architecture.
-/// 
-/// The path of the PE executable to parse.
-/// An enum ArchType value (as defined in rufus.h)
-static uint8_t FindArch(const char* path)
+static uint8_t FindArch(const char* filename)
 {
 	uint8_t ret = ARCH_UNKNOWN;
 	HANDLE hFile = NULL, hFileMapping = NULL;
@@ -1190,9 +1184,9 @@ static uint8_t FindArch(const char* path)
 	// PE headers, so we don't need to care about using PIMAGE_NT_HEADERS[32|64]
 	PIMAGE_NT_HEADERS pImageNTHeader = NULL;
 
-	hFile = CreateFileU(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+	hFile = CreateFileU(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 	if (hFile == NULL) {
-		uprintf("FindArch: Could not open file '%s': %s", path, WindowsErrorString());
+		uprintf("FindArch: Could not open file '%s': %s", filename, WindowsErrorString());
 		return 0;
 	}
 
@@ -1256,6 +1250,172 @@ out:
 	return ret;
 }
 
+/// 
+/// Create an installation answer file containing the sections specified by the flags.
+/// 
+/// The processor architecture of the Windows image being used.
+/// A bitmask representing the sections to enable.
+/// See "Windows User Experience flags and masks" from in rufus.h
+/// The path of a newly created answer file on success or NULL on error.
+static char* CreateUnattendXml(int arch, int flags)
+{
+	static char path[MAX_PATH];
+	FILE* fd;
+	int i, order;
+	const char* xml_arch_names[5] = { "x86", "amd64", "arm", "arm64" };
+	unattend_xml_flags = flags;
+	if (arch < ARCH_X86_32 || arch >= ARCH_ARM_64 || flags == 0)
+		return NULL;
+	arch--;
+	// coverity[swapped_arguments]
+	if (GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, path) == 0)
+		return NULL;
+	fd = fopen(path, "w");
+	if (fd == NULL)
+		return NULL;
+
+	fprintf(fd, "\n");
+	fprintf(fd, "\n");
+
+	// This part produces the unbecoming display of a command prompt window during initial setup as well
+	// as alters the layout and options of the initial Windows installer screens, which may scare users.
+	// So, in format.c, we'll try to insert the registry keys directly and drop this section. However,
+	// because Microsoft prevents Store apps from editing an offline registry, we do need this fallback.
+	if (flags & UNATTEND_WINPE_SETUP_MASK) {
+		order = 1;
+		fprintf(fd, "  \n");
+		fprintf(fd, "    \n", xml_arch_names[arch]);
+		// WinPE will complain if we don't provide a product key. *Any* product key. This is soooo idiotic...
+		fprintf(fd, "      \n");
+		fprintf(fd, "        \n");
+		fprintf(fd, "          \n");
+		fprintf(fd, "        \n");
+		fprintf(fd, "      \n");
+		if (flags & UNATTEND_SECUREBOOT_TPM_MINRAM) {
+			fprintf(fd, "      \n");
+			for (i = 0; i < ARRAYSIZE(bypass_name); i++) {
+				fprintf(fd, "        \n");
+				fprintf(fd, "          %d\n", order++);
+				fprintf(fd, "          reg add HKLM\\SYSTEM\\Setup\\LabConfig /v %s /t REG_DWORD /d 1 /f\n", bypass_name[i]);
+				fprintf(fd, "        \n");
+			}
+			fprintf(fd, "      \n");
+		}
+		fprintf(fd, "    \n");
+		fprintf(fd, "  \n");
+	}
+
+	if (flags & UNATTEND_SPECIALIZE_DEPLOYMENT_MASK) {
+		order = 1;
+		fprintf(fd, "  \n");
+		fprintf(fd, "    \n", xml_arch_names[arch]);
+		fprintf(fd, "      \n");
+		// This part was picked from https://github.com/AveYo/MediaCreationTool.bat/blob/main/bypass11/AutoUnattend.xml
+		if (flags & UNATTEND_NO_ONLINE_ACCOUNT) {
+			fprintf(fd, "        \n");
+			fprintf(fd, "          %d\n", order++);
+			fprintf(fd, "          reg add HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OOBE /v BypassNRO /t REG_DWORD /d 1 /f\n");
+			fprintf(fd, "        \n");
+		}
+		fprintf(fd, "      \n");
+		fprintf(fd, "    \n");
+		fprintf(fd, "  \n");
+	}
+
+	if (flags & UNATTEND_OOBE_MASK) {
+		order = 1;
+		fprintf(fd, "  \n");
+		if (flags & UNATTEND_OOBE_SHELL_SETUP_MASK) {
+			fprintf(fd, "    \n", xml_arch_names[arch]);
+			// https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-oobe-protectyourpc
+			// It is really super insidous of Microsoft to call this option "ProtectYourPC", when it's really only about
+			// data collection. But of course, if it was called "AllowDataCollection", everyone would turn it off...
+			if (flags & UNATTEND_NO_DATA_COLLECTION) {
+				fprintf(fd, "      \n");
+				fprintf(fd, "        3\n");
+				fprintf(fd, "      \n");
+			}
+			if (flags & UNATTEND_DUPLICATE_USER) {
+				order = 1;
+				char username[128] = { 0 };
+				DWORD size = sizeof(username);
+				if (GetUserNameU(username, &size) && username[0] != 0) {
+					// If we create a local account in unattend.xml, then we can get Windows 11
+					// 22H2 to skip MSA even if the network is connected during installation.
+					fprintf(fd, "      \n");
+					fprintf(fd, "        \n");
+					fprintf(fd, "          \n");
+					fprintf(fd, "            %s\n", username);
+					fprintf(fd, "            %s\n", username);
+					fprintf(fd, "            Administrators;Power Users\n");
+					// Sets an empty password for the account (which, in Microsoft's convoluted ways,
+					// needs to be initialized to the Base64 encoded UTF-16 string "Password").
+					// The use of an empty password has both the advantage of not having to ask users
+					// to type in a password in Rufus (which they might be weary of) as well as allowing
+					// automated logon during setup.
+					fprintf(fd, "            \n");
+					fprintf(fd, "              UABhAHMAcwB3AG8AcgBkAA==\n");
+					fprintf(fd, "              false\n");
+					fprintf(fd, "            \n");
+					fprintf(fd, "          \n");
+					fprintf(fd, "        \n");
+					fprintf(fd, "      \n");
+					// Since we set a blank password, we'll ask the user to change it at next logon.
+					fprintf(fd, "      \n");
+					fprintf(fd, "        \n");
+					fprintf(fd, "          %d\n", order++);
+					fprintf(fd, "          net user "%s" /logonpasswordchg:yes\n", username);
+					fprintf(fd, "        \n");
+					fprintf(fd, "      \n");
+				} else {
+					uprintf("Warning: Could not retreive current user name. Local Account was not created");
+				}
+			}
+			fprintf(fd, "    \n");
+		}
+		if (flags & UNATTEND_OOBE_INTERNATIONAL_MASK) {
+			fprintf(fd, "    \n", xml_arch_names[arch]);
+			// What a frigging mess retreiving and trying to match the various locales
+			// Microsoft has made. And, *NO*, the new User Language Settings have not
+			// improved things in the slightest. They made it much worse for developers!
+			fprintf(fd, "      %s\n",
+				ReadRegistryKeyStr(REGKEY_HKCU, "Keyboard Layout\\Preload\\1"));
+			fprintf(fd, "      %s\n", ToLocaleName(GetSystemDefaultLCID()));
+			fprintf(fd, "      %s\n", ToLocaleName(GetUserDefaultLCID()));
+			fprintf(fd, "      %s\n", ToLocaleName(GetUserDefaultUILanguage()));
+			fprintf(fd, "      %s\n",
+				// NB: Officially, this is a REG_MULTI_SZ string
+				ReadRegistryKeyStr(REGKEY_HKLM, "SYSTEM\\CurrentControlSet\\Control\\Nls\\Language\\InstallLanguageFallback"));
+			fprintf(fd, "    \n");
+		}
+		fprintf(fd, "  \n");
+	}
+
+	if (flags & UNATTEND_OFFLINE_SERVICING_MASK) {
+		fprintf(fd, "  \n");
+		if (flags & UNATTEND_OFFLINE_INTERNAL_DRIVES) {
+			fprintf(fd, "    \n", xml_arch_names[arch]);
+			fprintf(fd, "      4\n");
+			fprintf(fd, "    \n");
+		}
+		fprintf(fd, "  \n");
+	}
+
+	fprintf(fd, "\n");
+	fclose(fd);
+	return path;
+}
+
 // The scanning process can be blocking for message processing => use a thread
 DWORD WINAPI ImageScanThread(LPVOID param)
 {
diff --git a/src/rufus.h b/src/rufus.h
index 2bfc6554..c9afd527 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -637,6 +637,7 @@ extern char* WimMountImage(const char* image, int index);
 extern BOOL WimUnmountImage(const char* image, int index);
 extern int8_t IsBootableImage(const char* path);
 extern BOOL AppendVHDFooter(const char* vhd_path);
+extern int SetWinToGoIndex(void);
 extern int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid);
 extern char* GetSignatureName(const char* path, const char* country_code, BOOL bSilent);
 extern uint64_t GetSignatureTimeStamp(const char* path);
@@ -669,6 +670,7 @@ extern HANDLE CreatePreallocatedFile(const char* lpFileName, DWORD dwDesiredAcce
 	DWORD dwFlagsAndAttributes, LONGLONG fileSize);
 #define GetTextWidth(hDlg, id) GetTextSize(GetDlgItem(hDlg, id), NULL).cx
 
+DWORD WINAPI FormatThread(void* param);
 DWORD WINAPI SaveImageThread(void* param);
 DWORD WINAPI SumThread(void* param);
 
diff --git a/src/rufus.rc b/src/rufus.rc
index 7ddab87c..0f5c0577 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.20.1923"
+CAPTION "Rufus 3.20.1921"
 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,20,1923,0
- PRODUCTVERSION 3,20,1923,0
+ FILEVERSION 3,20,1921,0
+ PRODUCTVERSION 3,20,1921,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.20.1923"
+            VALUE "FileVersion", "3.20.1921"
             VALUE "InternalName", "Rufus"
             VALUE "LegalCopyright", "© 2011-2022 Pete Batard (GPL v3)"
             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
             VALUE "OriginalFilename", "rufus-3.20.exe"
             VALUE "ProductName", "Rufus"
-            VALUE "ProductVersion", "3.20.1923"
+            VALUE "ProductVersion", "3.20.1921"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/src/wue.c b/src/wue.c
deleted file mode 100644
index c978600a..00000000
--- a/src/wue.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * Rufus: The Reliable USB Formatting Utility
- * Windows User Experience
- * Copyright © 2022 Pete Batard 
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "rufus.h"
-#include "drive.h"
-#include "format.h"
-#include "missing.h"
-#include "resource.h"
-#include "registry.h"
-#include "msapi_utf8.h"
-#include "localization.h"
-
- /* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */
-#ifdef _CRTDBG_MAP_ALLOC
-#include 
-#include 
-#endif
-
-const char* bypass_name[] = { "BypassTPMCheck", "BypassSecureBootCheck", "BypassRAMCheck" };
-
-int unattend_xml_flags = 0, wintogo_index = -1, wininst_index = 0;
-int unattend_xml_mask = UNATTEND_DEFAULT_SELECTION_MASK;
-char* unattend_xml_path = NULL;
-
-extern uint32_t wim_nb_files, wim_proc_files, wim_extra_files;
-
- /// 
- /// Create an installation answer file containing the sections specified by the flags.
- /// 
- /// The processor architecture of the Windows image being used.
- /// A bitmask representing the sections to enable.
- /// See "Windows User Experience flags and masks" from rufus.h
- /// The path of a newly created answer file on success or NULL on error.
-char* CreateUnattendXml(int arch, int flags)
-{
-	static char path[MAX_PATH];
-	FILE* fd;
-	int i, order;
-	const char* xml_arch_names[5] = { "x86", "amd64", "arm", "arm64" };
-	unattend_xml_flags = flags;
-	if (arch < ARCH_X86_32 || arch > ARCH_ARM_64 || flags == 0)
-		return NULL;
-	arch--;
-	// coverity[swapped_arguments]
-	if (GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, path) == 0)
-		return NULL;
-	fd = fopen(path, "w");
-	if (fd == NULL)
-		return NULL;
-
-	fprintf(fd, "\n");
-	fprintf(fd, "\n");
-
-	// This part produces the unbecoming display of a command prompt window during initial setup as well
-	// as alters the layout and options of the initial Windows installer screens, which may scare users.
-	// So, in format.c, we'll try to insert the registry keys directly and drop this section. However,
-	// because Microsoft prevents Store apps from editing an offline registry, we do need this fallback.
-	if (flags & UNATTEND_WINPE_SETUP_MASK) {
-		order = 1;
-		fprintf(fd, "  \n");
-		fprintf(fd, "    \n", xml_arch_names[arch]);
-		// WinPE will complain if we don't provide a product key. *Any* product key. This is soooo idiotic...
-		fprintf(fd, "      \n");
-		fprintf(fd, "        \n");
-		fprintf(fd, "          \n");
-		fprintf(fd, "        \n");
-		fprintf(fd, "      \n");
-		if (flags & UNATTEND_SECUREBOOT_TPM_MINRAM) {
-			fprintf(fd, "      \n");
-			for (i = 0; i < ARRAYSIZE(bypass_name); i++) {
-				fprintf(fd, "        \n");
-				fprintf(fd, "          %d\n", order++);
-				fprintf(fd, "          reg add HKLM\\SYSTEM\\Setup\\LabConfig /v %s /t REG_DWORD /d 1 /f\n", bypass_name[i]);
-				fprintf(fd, "        \n");
-			}
-			fprintf(fd, "      \n");
-		}
-		fprintf(fd, "    \n");
-		fprintf(fd, "  \n");
-	}
-
-	if (flags & UNATTEND_SPECIALIZE_DEPLOYMENT_MASK) {
-		order = 1;
-		fprintf(fd, "  \n");
-		fprintf(fd, "    \n", xml_arch_names[arch]);
-		fprintf(fd, "      \n");
-		// This part was picked from https://github.com/AveYo/MediaCreationTool.bat/blob/main/bypass11/AutoUnattend.xml
-		if (flags & UNATTEND_NO_ONLINE_ACCOUNT) {
-			fprintf(fd, "        \n");
-			fprintf(fd, "          %d\n", order++);
-			fprintf(fd, "          reg add HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OOBE /v BypassNRO /t REG_DWORD /d 1 /f\n");
-			fprintf(fd, "        \n");
-		}
-		fprintf(fd, "      \n");
-		fprintf(fd, "    \n");
-		fprintf(fd, "  \n");
-	}
-
-	if (flags & UNATTEND_OOBE_MASK) {
-		order = 1;
-		fprintf(fd, "  \n");
-		if (flags & UNATTEND_OOBE_SHELL_SETUP_MASK) {
-			fprintf(fd, "    \n", xml_arch_names[arch]);
-			// https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-oobe-protectyourpc
-			// It is really super insidous of Microsoft to call this option "ProtectYourPC", when it's really only about
-			// data collection. But of course, if it was called "AllowDataCollection", everyone would turn it off...
-			if (flags & UNATTEND_NO_DATA_COLLECTION) {
-				fprintf(fd, "      \n");
-				fprintf(fd, "        3\n");
-				fprintf(fd, "      \n");
-			}
-			if (flags & UNATTEND_DUPLICATE_USER) {
-				order = 1;
-				char username[128] = { 0 };
-				DWORD size = sizeof(username);
-				if (GetUserNameU(username, &size) && username[0] != 0) {
-					// If we create a local account in unattend.xml, then we can get Windows 11
-					// 22H2 to skip MSA even if the network is connected during installation.
-					fprintf(fd, "      \n");
-					fprintf(fd, "        \n");
-					fprintf(fd, "          \n");
-					fprintf(fd, "            %s\n", username);
-					fprintf(fd, "            %s\n", username);
-					fprintf(fd, "            Administrators;Power Users\n");
-					// Sets an empty password for the account (which, in Microsoft's convoluted ways,
-					// needs to be initialized to the Base64 encoded UTF-16 string "Password").
-					// The use of an empty password has both the advantage of not having to ask users
-					// to type in a password in Rufus (which they might be weary of) as well as allowing
-					// automated logon during setup.
-					fprintf(fd, "            \n");
-					fprintf(fd, "              UABhAHMAcwB3AG8AcgBkAA==\n");
-					fprintf(fd, "              false\n");
-					fprintf(fd, "            \n");
-					fprintf(fd, "          \n");
-					fprintf(fd, "        \n");
-					fprintf(fd, "      \n");
-					// Since we set a blank password, we'll ask the user to change it at next logon.
-					fprintf(fd, "      \n");
-					fprintf(fd, "        \n");
-					fprintf(fd, "          %d\n", order++);
-					fprintf(fd, "          net user "%s" /logonpasswordchg:yes\n", username);
-					fprintf(fd, "        \n");
-					fprintf(fd, "      \n");
-				} else {
-					uprintf("Warning: Could not retreive current user name. Local Account was not created");
-				}
-			}
-			fprintf(fd, "    \n");
-		}
-		if (flags & UNATTEND_OOBE_INTERNATIONAL_MASK) {
-			fprintf(fd, "    \n", xml_arch_names[arch]);
-			// What a frigging mess retreiving and trying to match the various locales
-			// Microsoft has made. And, *NO*, the new User Language Settings have not
-			// improved things in the slightest. They made it much worse for developers!
-			fprintf(fd, "      %s\n",
-				ReadRegistryKeyStr(REGKEY_HKCU, "Keyboard Layout\\Preload\\1"));
-			fprintf(fd, "      %s\n", ToLocaleName(GetSystemDefaultLCID()));
-			fprintf(fd, "      %s\n", ToLocaleName(GetUserDefaultLCID()));
-			fprintf(fd, "      %s\n", ToLocaleName(GetUserDefaultUILanguage()));
-			fprintf(fd, "      %s\n",
-				// NB: Officially, this is a REG_MULTI_SZ string
-				ReadRegistryKeyStr(REGKEY_HKLM, "SYSTEM\\CurrentControlSet\\Control\\Nls\\Language\\InstallLanguageFallback"));
-			fprintf(fd, "    \n");
-		}
-		fprintf(fd, "  \n");
-	}
-
-	if (flags & UNATTEND_OFFLINE_SERVICING_MASK) {
-		fprintf(fd, "  \n");
-		if (flags & UNATTEND_OFFLINE_INTERNAL_DRIVES) {
-			fprintf(fd, "    \n", xml_arch_names[arch]);
-			fprintf(fd, "      4\n");
-			fprintf(fd, "    \n");
-		}
-		fprintf(fd, "  \n");
-	}
-
-	fprintf(fd, "\n");
-	fclose(fd);
-	return path;
-}
-
-/// 
-/// Setup and patch WinPE for Windows XP bootable USBs.
-/// 
-/// The letter identifying the target drive.
-/// TRUE on success, FALSE on error.
-BOOL SetupWinPE(char drive_letter)
-{
-	char src[64], dst[32];
-	const char* basedir[3] = { "i386", "amd64", "minint" };
-	const char* patch_str_org[2] = { "\\minint\\txtsetup.sif", "\\minint\\system32\\" };
-	const char* patch_str_rep[2][2] = { { "\\i386\\txtsetup.sif", "\\i386\\system32\\" } ,
-										{ "\\amd64\\txtsetup.sif", "\\amd64\\system32\\" } };
-	const char* win_nt_bt_org = "$win_nt$.~bt";
-	const char* rdisk_zero = "rdisk(0)";
-	const LARGE_INTEGER liZero = { {0, 0} };
-	char setupsrcdev[64];
-	HANDLE handle = INVALID_HANDLE_VALUE;
-	DWORD i, j, size, rw_size, index = 0;
-	BOOL r = FALSE;
-	char* buffer = NULL;
-
-	if ((img_report.winpe & WINPE_AMD64) == WINPE_AMD64)
-		index = 1;
-	else if ((img_report.winpe & WINPE_MININT) == WINPE_MININT)
-		index = 2;
-	// Allow other values than harddisk 1, as per user choice for disk ID
-	static_sprintf(setupsrcdev, "SetupSourceDevice = \"\\device\\harddisk%d\\partition1\"",
-		ComboBox_GetCurSel(hDiskID));
-	// Copy of ntdetect.com in root
-	static_sprintf(src, "%c:\\%s\\ntdetect.com", toupper(drive_letter), basedir[2 * (index / 2)]);
-	static_sprintf(dst, "%c:\\ntdetect.com", toupper(drive_letter));
-	CopyFileA(src, dst, TRUE);
-	if (!img_report.uses_minint) {
-		// Create a copy of txtsetup.sif, as we want to keep the i386/amd64 files unmodified
-		static_sprintf(src, "%c:\\%s\\txtsetup.sif", toupper(drive_letter), basedir[index]);
-		static_sprintf(dst, "%c:\\txtsetup.sif", toupper(drive_letter));
-		if (!CopyFileA(src, dst, TRUE)) {
-			uprintf("Did not copy %s as %s: %s\n", src, dst, WindowsErrorString());
-		}
-		if (insert_section_data(dst, "[SetupData]", setupsrcdev, FALSE) == NULL) {
-			uprintf("Failed to add SetupSourceDevice in %s\n", dst);
-			goto out;
-		}
-		uprintf("Successfully added '%s' to %s\n", setupsrcdev, dst);
-	}
-
-	static_sprintf(src, "%c:\\%s\\setupldr.bin", toupper(drive_letter), basedir[2 * (index / 2)]);
-	static_sprintf(dst, "%c:\\BOOTMGR", toupper(drive_letter));
-	if (!CopyFileA(src, dst, TRUE)) {
-		uprintf("Did not copy %s as %s: %s\n", src, dst, WindowsErrorString());
-	}
-
-	// \minint with /minint option doesn't require further processing => return true
-	// \minint and no \i386 without /minint is unclear => return error
-	if (img_report.winpe & WINPE_MININT) {
-		if (img_report.uses_minint) {
-			uprintf("Detected \\minint directory with /minint option: nothing to patch\n");
-			r = TRUE;
-		} else if (!(img_report.winpe & (WINPE_I386 | WINPE_AMD64))) {
-			uprintf("Detected \\minint directory only but no /minint option: not sure what to do\n");
-		}
-		goto out;
-	}
-
-	// At this stage we only handle \i386
-	handle = CreateFileA(dst, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
-		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-	if (handle == INVALID_HANDLE_VALUE) {
-		uprintf("Could not open %s for patching: %s\n", dst, WindowsErrorString());
-		goto out;
-	}
-	size = GetFileSize(handle, NULL);
-	if (size == INVALID_FILE_SIZE) {
-		uprintf("Could not get size for file %s: %s\n", dst, WindowsErrorString());
-		goto out;
-	}
-	buffer = (char*)malloc(size);
-	if (buffer == NULL)
-		goto out;
-	if ((!ReadFile(handle, buffer, size, &rw_size, NULL)) || (size != rw_size)) {
-		uprintf("Could not read file %s: %s\n", dst, WindowsErrorString());
-		goto out;
-	}
-	if (!SetFilePointerEx(handle, liZero, NULL, FILE_BEGIN)) {
-		uprintf("Could not rewind file %s: %s\n", dst, WindowsErrorString());
-		goto out;
-	}
-
-	// Patch setupldr.bin
-	uprintf("Patching file %s\n", dst);
-	// Remove CRC check for 32 bit part of setupldr.bin from Win2k3
-	if ((size > 0x2061) && (buffer[0x2060] == 0x74) && (buffer[0x2061] == 0x03)) {
-		buffer[0x2060] = 0xeb;
-		buffer[0x2061] = 0x1a;
-		uprintf("  0x00002060: 0x74 0x03 -> 0xEB 0x1A (disable Win2k3 CRC check)\n");
-	}
-	for (i = 1; i < size - 32; i++) {
-		for (j = 0; j < ARRAYSIZE(patch_str_org); j++) {
-			if (safe_strnicmp(&buffer[i], patch_str_org[j], strlen(patch_str_org[j]) - 1) == 0) {
-				assert(index < 2);
-				uprintf("  0x%08X: '%s' -> '%s'\n", i, &buffer[i], patch_str_rep[index][j]);
-				strcpy(&buffer[i], patch_str_rep[index][j]);
-				i += (DWORD)max(strlen(patch_str_org[j]), strlen(patch_str_rep[index][j]));	// in case org is a substring of rep
-			}
-		}
-	}
-
-	if (!img_report.uses_minint) {
-		// Additional setupldr.bin/bootmgr patching
-		for (i = 0; i < size - 32; i++) {
-			// rdisk(0) -> rdisk(#) disk masquerading
-			// NB: only the first one seems to be needed
-			if (safe_strnicmp(&buffer[i], rdisk_zero, strlen(rdisk_zero) - 1) == 0) {
-				buffer[i + 6] = 0x30 + ComboBox_GetCurSel(hDiskID);
-				uprintf("  0x%08X: '%s' -> 'rdisk(%c)'\n", i, rdisk_zero, buffer[i + 6]);
-			}
-			// $WIN_NT$_~BT -> i386/amd64
-			if (safe_strnicmp(&buffer[i], win_nt_bt_org, strlen(win_nt_bt_org) - 1) == 0) {
-				uprintf("  0x%08X: '%s' -> '%s%s'\n", i, &buffer[i], basedir[index], &buffer[i + strlen(win_nt_bt_org)]);
-				strcpy(&buffer[i], basedir[index]);
-				// This ensures that we keep the terminator backslash
-				buffer[i + strlen(basedir[index])] = buffer[i + strlen(win_nt_bt_org)];
-				buffer[i + strlen(basedir[index]) + 1] = 0;
-			}
-		}
-	}
-
-	if (!WriteFileWithRetry(handle, buffer, size, &rw_size, WRITE_RETRIES)) {
-		uprintf("Could not write patched file: %s\n", WindowsErrorString());
-		goto out;
-	}
-	r = TRUE;
-
-out:
-	safe_closehandle(handle);
-	safe_free(buffer);
-	return r;
-}
-
-/// 
-/// Checks which versions of Windows are available in an install image
-/// to set our extraction index. Asks the user to select one if needed.
-/// 
-/// (none)
-/// -2 on user cancel, -1 on other error, >=0 on success.
-int SetWinToGoIndex(void)
-{
-	char* mounted_iso, * val, mounted_image_path[128];
-	char xml_file[MAX_PATH] = "";
-	char* install_names[MAX_WININST];
-	StrArray version_name, version_index;
-	int i;
-	BOOL bNonStandard = FALSE;
-
-	// Sanity checks
-	wintogo_index = -1;
-	wininst_index = 0;
-	if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck(FALSE) & 4) == 0) ||
-		(ComboBox_GetCurItemData(hFileSystem) != FS_NTFS)) {
-		return -1;
-	}
-
-	// If we have multiple windows install images, ask the user the one to use
-	if (img_report.wininst_index > 1) {
-		for (i = 0; i < img_report.wininst_index; i++)
-			install_names[i] = &img_report.wininst_path[i][2];
-		wininst_index = _log2(SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_130),
-			lmprintf(MSG_131), install_names, img_report.wininst_index, 1));
-		if (wininst_index < 0)
-			return -2;
-		if (wininst_index >= MAX_WININST)
-			wininst_index = 0;
-	}
-
-	// If we're not using a straight install.wim, we need to mount the ISO to access it
-	if (!img_report.is_windows_img) {
-		mounted_iso = MountISO(image_path);
-		if (mounted_iso == NULL) {
-			uprintf("Could not mount ISO for Windows To Go selection");
-			return FALSE;
-		}
-		static_sprintf(mounted_image_path, "%s%s", mounted_iso, &img_report.wininst_path[wininst_index][2]);
-	}
-
-	// Now take a look at the XML file in install.wim to list our versions
-	if ((GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, xml_file) == 0) || (xml_file[0] == 0)) {
-		// Last ditch effort to get a tmp file - just extract it to the current directory
-		static_strcpy(xml_file, ".\\RufVXml.tmp");
-	}
-	// GetTempFileName() may leave a file behind
-	DeleteFileU(xml_file);
-
-	// Must use the Windows WIM API as 7z messes up the XML
-	if (!WimExtractFile_API(img_report.is_windows_img ? image_path : mounted_image_path,
-		0, "[1].xml", xml_file, FALSE)) {
-		uprintf("Could not acquire WIM index");
-		goto out;
-	}
-
-	StrArrayCreate(&version_name, 16);
-	StrArrayCreate(&version_index, 16);
-	for (i = 0; StrArrayAdd(&version_index, get_token_data_file_indexed("IMAGE INDEX", xml_file, i + 1), FALSE) >= 0; i++) {
-		// Some people are apparently creating *unofficial* Windows ISOs that don't have DISPLAYNAME elements.
-		// If we are parsing such an ISO, try to fall back to using DESCRIPTION. Of course, since we don't use
-		// a formal XML parser, if an ISO mixes entries with both DISPLAYNAME and DESCRIPTION and others with
-		// only DESCRIPTION, the version names we report will be wrong.
-		// But hey, there's only so far I'm willing to go to help people who, not content to have demonstrated
-		// their utter ignorance on development matters, are also trying to lecture experienced developers
-		// about specific "noob mistakes"... that don't exist in the code they are trying to criticize.
-		if (StrArrayAdd(&version_name, get_token_data_file_indexed("DISPLAYNAME", xml_file, i + 1), FALSE) < 0) {
-			bNonStandard = TRUE;
-			if (StrArrayAdd(&version_name, get_token_data_file_indexed("DESCRIPTION", xml_file, i + 1), FALSE) < 0) {
-				uprintf("Warning: Could not find a description for image index %d", i + 1);
-				StrArrayAdd(&version_name, "Unknown Windows Version", TRUE);
-			}
-		}
-	}
-	if (bNonStandard)
-		uprintf("Warning: Nonstandard Windows image (missing  entries)");
-
-	if (i > 1)
-		// NB: _log2 returns -2 if SelectionDialog() returns negative (user cancelled)
-		i = _log2(SelectionDialog(BS_AUTORADIOBUTTON,
-			lmprintf(MSG_291), lmprintf(MSG_292), version_name.String, i, 1)) + 1;
-	if (i < 0)
-		wintogo_index = -2;	// Cancelled by the user
-	else if (i == 0)
-		wintogo_index = 1;
-	else
-		wintogo_index = atoi(version_index.String[i - 1]);
-	if (i > 0) {
-		// Get the version data from the XML index
-		val = get_token_data_file_indexed("MAJOR", xml_file, i);
-		img_report.win_version.major = (uint16_t)safe_atoi(val);
-		free(val);
-		val = get_token_data_file_indexed("MINOR", xml_file, i);
-		img_report.win_version.minor = (uint16_t)safe_atoi(val);
-		free(val);
-		val = get_token_data_file_indexed("BUILD", xml_file, i);
-		img_report.win_version.build = (uint16_t)safe_atoi(val);
-		free(val);
-		val = get_token_data_file_indexed("SPBUILD", xml_file, i);
-		img_report.win_version.revision = (uint16_t)safe_atoi(val);
-		free(val);
-		if ((img_report.win_version.major == 10) && (img_report.win_version.build > 20000))
-			img_report.win_version.major = 11;
-		// If we couldn't obtain the major and build, we have a problem
-		if (img_report.win_version.major == 0 || img_report.win_version.build == 0)
-			uprintf("Warning: Could not obtain version information from XML index (Nonstandard Windows image?)");
-		uprintf("Will use '%s' (Build: %d, Index %s) for Windows To Go",
-			version_name.String[i - 1], img_report.win_version.build, version_index.String[i - 1]);
-		// Need Windows 10 Creator Update or later for boot on REMOVABLE to work
-		if ((img_report.win_version.build < 15000) && (SelectedDrive.MediaType != FixedMedia)) {
-			if (MessageBoxExU(hMainDialog, lmprintf(MSG_098), lmprintf(MSG_190),
-				MB_YESNO | MB_ICONWARNING | MB_IS_RTL, selected_langid) != IDYES)
-				wintogo_index = -2;
-		}
-		// Display a notice about WppRecorder.sys for 1809 ISOs
-		if (img_report.win_version.build == 17763) {
-			notification_info more_info;
-			more_info.id = MORE_INFO_URL;
-			more_info.url = WPPRECORDER_MORE_INFO_URL;
-			Notification(MSG_INFO, NULL, &more_info, lmprintf(MSG_128, "Windows To Go"), lmprintf(MSG_133));
-		}
-	}
-	StrArrayDestroy(&version_name);
-	StrArrayDestroy(&version_index);
-
-out:
-	DeleteFileU(xml_file);
-	if (!img_report.is_windows_img)
-		UnMountISO();
-	return wintogo_index;
-}
-
-/// 
-/// Setup a Windows To Go drive according to the official Microsoft instructions detailed at:
-/// https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-8.1-and-8/jj721578(v=ws.11).
-/// Note that as opposed to the technet guide above we use bcdedit rather than 'unattend.xml'
-/// to disable the recovery environment.
-/// 
-/// The Rufus drive index for the target media.
-/// The path of the target media.
-/// Whether to create an ESP on the target media.
-/// TRUE on success, FALSE on error.
-BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
-{
-	char* mounted_iso, * ms_efi = NULL, mounted_image_path[128], cmd[MAX_PATH];
-	ULONG cluster_size;
-
-	uprintf("Windows To Go mode selected");
-	// Additional sanity checks
-	if ((use_esp) && (SelectedDrive.MediaType != FixedMedia) && (nWindowsBuildNumber < 15000)) {
-		FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_SUPPORTED;
-		return FALSE;
-	}
-
-	if (!img_report.is_windows_img) {
-		mounted_iso = MountISO(image_path);
-		if (mounted_iso == NULL) {
-			uprintf("Could not mount ISO for Windows To Go installation");
-			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_ISO_EXTRACT);
-			return FALSE;
-		}
-		static_sprintf(mounted_image_path, "%s%s", mounted_iso, &img_report.wininst_path[wininst_index][2]);
-		uprintf("Mounted ISO as '%s'", mounted_iso);
-	}
-
-	// Now we use the WIM API to apply that image
-	if (!WimApplyImage(img_report.is_windows_img ? image_path : mounted_image_path, wintogo_index, drive_name)) {
-		uprintf("Failed to apply Windows To Go image");
-		if (!IS_ERROR(FormatStatus))
-			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_ISO_EXTRACT);
-		if (!img_report.is_windows_img)
-			UnMountISO();
-		return FALSE;
-	}
-	if (!img_report.is_windows_img)
-		UnMountISO();
-
-	if (use_esp) {
-		uprintf("Setting up EFI System Partition");
-		// According to Ubuntu (https://bugs.launchpad.net/ubuntu/+source/partman-efi/+bug/811485) you want to use FAT32.
-		// However, you have to be careful that the cluster size needs to be greater or equal to the sector size, which
-		// in turn has an impact on the minimum EFI partition size we can create (see ms_efi_size_MB in drive.c)
-		if (SelectedDrive.SectorSize <= 1024)
-			cluster_size = 1024;
-		else if (SelectedDrive.SectorSize <= 4096)
-			cluster_size = 4096;
-		else	// Go for broke
-			cluster_size = (ULONG)SelectedDrive.SectorSize;
-		// Boy do you *NOT* want to specify a label here, and spend HOURS figuring out why your EFI partition cannot boot...
-		// Also, we use the Large FAT32 facility Microsoft APIs are *UTTERLY USELESS* for achieving what we want:
-		// VDS cannot list ESP volumes (talk about allegedly improving on the old disk and volume APIs, only to
-		// completely neuter it) and IVdsDiskPartitionMF::FormatPartitionEx(), which is what you are supposed to
-		// use for ESPs, explicitly states: "This method cannot be used to format removable media."
-		if (!FormatPartition(DriveIndex, partition_offset[PI_ESP], cluster_size, FS_FAT32, "",
-			FP_QUICK | FP_FORCE | FP_LARGE_FAT32 | FP_NO_BOOT)) {
-			uprintf("Could not format EFI System Partition");
-			return FALSE;
-		}
-		Sleep(200);
-		// Need to have the ESP mounted to invoke bcdboot
-		ms_efi = AltMountVolume(DriveIndex, partition_offset[PI_ESP], FALSE);
-		if (ms_efi == NULL) {
-			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_ASSIGN_LETTER);
-			return FALSE;
-		}
-	}
-
-	// We invoke the 'bcdboot' command from the host, as the one from the drive produces problems (#558)
-	// and of course, we couldn't invoke an ARM64 'bcdboot' binary on an x86 host anyway...
-	// Also, since Rufus should (usually) be running as a 32 bit app, on 64 bit systems, we need to use
-	// 'C:\Windows\Sysnative' and not 'C:\Windows\System32' to invoke bcdboot, as 'C:\Windows\System32'
-	// will get converted to 'C:\Windows\SysWOW64' behind the scenes, and there is no bcdboot.exe there.
-	uprintf("Enabling boot using command:");
-	static_sprintf(cmd, "%s\\bcdboot.exe %s\\Windows /v /f %s /s %s", sysnative_dir, drive_name,
-		HAS_BOOTMGR_BIOS(img_report) ? (HAS_BOOTMGR_EFI(img_report) ? "ALL" : "BIOS") : "UEFI",
-		(use_esp) ? ms_efi : drive_name);
-	uprintf(cmd);
-	if (RunCommand(cmd, sysnative_dir, usb_debug) != 0) {
-		// Try to continue... but report a failure
-		uprintf("Failed to enable boot");
-		FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_ISO_EXTRACT);
-	}
-
-	UpdateProgressWithInfo(OP_FILE_COPY, MSG_267, wim_proc_files + 2 * wim_extra_files, wim_nb_files);
-
-	// Setting internal drives offline for Windows To Go is crucial if, for instance, you are using ReFS
-	// on Windows 10 (therefore ReFS v3.4) and don't want a Windows 11 To Go boot to automatically
-	// "upgrade" the ReFS version on all drives to v3.7, thereby preventing you from being able to mount
-	// those volumes back on Windows 10 ever again. Yes, I have been stung by this Microsoft bullshit!
-	// See: https://gist.github.com/0xbadfca11/da0598e47dd643d933dc#Mountability
-	if (unattend_xml_flags & UNATTEND_OFFLINE_INTERNAL_DRIVES) {
-		uprintf("Setting the target's internal drives offline using command:");
-		// This applies the "offlineServicing" section of the unattend.xml (while ignoring the other sections)
-		static_sprintf(cmd, "dism /Image:%s\\ /Apply-Unattend:%s", drive_name, unattend_xml_path);
-		uprintf(cmd);
-		RunCommand(cmd, NULL, usb_debug);
-	}
-
-	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);
-	RunCommand(cmd, sysnative_dir, usb_debug);
-
-	UpdateProgressWithInfo(OP_FILE_COPY, MSG_267, wim_nb_files, wim_nb_files);
-
-	if (use_esp) {
-		Sleep(200);
-		AltUnmountVolume(ms_efi, FALSE);
-	}
-
-	return TRUE;
-}
-
-/// 
-/// Add unattend.xml to 'sources\boot.wim' (install) or 'Windows\Panther\' (Windows To Go).
-/// 
-/// The letter of the drive where the \sources\boot.wim image resides.
-/// A bitmap of unattend flags to apply.
-/// TRUE on success, FALSE on error.
-BOOL ApplyWindowsCustomization(char drive_letter, int flags)
-// NB: Work with a copy of unattend_xml_flags as a paremeter since we will modify it.
-{
-	BOOL r = FALSE, is_hive_mounted = FALSE;
-	int i;
-	const int wim_index = 2;
-	const char* offline_hive_name = "RUFUS_OFFLINE_HIVE";
-	char boot_wim_path[] = "?:\\sources\\boot.wim", key_path[64];
-	char appraiserres_dll_src[] = "?:\\sources\\appraiserres.dll";
-	char appraiserres_dll_dst[] = "?:\\sources\\appraiserres.bak";
-	char* mount_path = NULL, path[MAX_PATH];
-	HKEY hKey = NULL, hSubKey = NULL;
-	LSTATUS status;
-	DWORD dwDisp, dwVal = 1;
-
-	assert(unattend_xml_path != NULL);
-	uprintf("Applying Windows customization:");
-	if (flags & UNATTEND_WINDOWS_TO_GO) {
-		static_sprintf(path, "%c:\\Windows\\Panther", drive_letter);
-		if (!CreateDirectoryA(path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
-			uprintf("Could not create '%s' : %s", path, WindowsErrorString());
-			goto out;
-		}
-		static_sprintf(path, "%c:\\Windows\\Panther\\unattend.xml", drive_letter);
-		if (!CopyFileA(unattend_xml_path, path, TRUE)) {
-			uprintf("Could not create '%s' : %s", path, WindowsErrorString());
-			goto out;
-		}
-		uprintf("Added '%s'", path);
-	} else {
-		boot_wim_path[0] = drive_letter;
-		if (flags & UNATTEND_WINPE_SETUP_MASK) {
-			// Create a backup of sources\appraiserres.dll and then create an empty file to
-			// allow in-place upgrades without TPM/SB. Note that we need to create an empty,
-			// appraiserres.dll otherwise setup.exe extracts its own.
-			appraiserres_dll_src[0] = drive_letter;
-			appraiserres_dll_dst[0] = drive_letter;
-			if (!MoveFileExU(appraiserres_dll_src, appraiserres_dll_dst, MOVEFILE_REPLACE_EXISTING))
-				uprintf("Could not rename '%s': %s", appraiserres_dll_src, WindowsErrorString());
-			else
-				CloseHandle(CreateFileU(appraiserres_dll_src, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
-					NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
-			uprintf("Renamed '%s' → '%s'", appraiserres_dll_src, appraiserres_dll_dst);
-		}
-
-		UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 0, PATCH_PROGRESS_TOTAL);
-		// We only need to mount boot.wim if we have windowsPE data to deal with. If
-		// not, we can just copy our unattend.xml in \sources\$OEM$\$$\Panther\.
-		if (flags & UNATTEND_WINPE_SETUP_MASK) {
-			uprintf("Mounting '%s'...", boot_wim_path);
-			mount_path = WimMountImage(boot_wim_path, wim_index);
-			if (mount_path == NULL)
-				goto out;
-		}
-
-		if (flags & UNATTEND_SECUREBOOT_TPM_MINRAM) {
-			// Try to create the registry keys directly, and fallback to using unattend
-			// if that fails (which the Windows Store version is expected to do).
-			static_sprintf(path, "%s\\Windows\\System32\\config\\SYSTEM", mount_path);
-			if (!MountRegistryHive(HKEY_LOCAL_MACHINE, offline_hive_name, path)) {
-				uprintf("Falling back to creating the registry keys through unattend.xml");
-				goto copy_unattend;
-			}
-			UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 101, PATCH_PROGRESS_TOTAL);
-			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 copy_unattend;
-			}
-
-			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 copy_unattend;
-			}
-
-			for (i = 0; i < ARRAYSIZE(bypass_name); i++) {
-				status = RegSetValueExA(hSubKey, bypass_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",
-						bypass_name[i], WindowsErrorString());
-					goto copy_unattend;
-				}
-				uprintf("Created 'HKLM\\SYSTEM\\Setup\\LabConfig\\%s' registry key", bypass_name[i]);
-			}
-			// We were successfull in creating the keys so disable the windowsPE section from unattend.xml
-			// We do this by replacing '' with ''
-			// (provided that the registry key creation was the only item for this pass)
-			if ((flags & UNATTEND_WINPE_SETUP_MASK) == UNATTEND_SECUREBOOT_TPM_MINRAM) {
-				if (replace_in_token_data(unattend_xml_path, " entries from windowsPE (and only windowsPE).
-				assert(FALSE);
-			}
-			UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 102, PATCH_PROGRESS_TOTAL);
-		}
-
-	copy_unattend:
-		if (flags & UNATTEND_WINPE_SETUP_MASK) {
-			// If we have a windowsPE section, copy the answer files to the root of boot.wim as
-			// Autounattend.xml. This also results in that file being automatically copied over
-			// to %WINDIR%\Panther\unattend.xml for later passes processing.
-			assert(mount_path != NULL);
-			static_sprintf(path, "%s\\Autounattend.xml", mount_path);
-			if (!CopyFileU(unattend_xml_path, path, TRUE)) {
-				uprintf("Could not create boot.wim 'Autounattend.xml': %s", WindowsErrorString());
-				goto out;
-			}
-			uprintf("Added 'Autounattend.xml' to '%s'", boot_wim_path);
-		} else {
-			// If there is no windowsPE section in our unattend, then copying it as Autounattend.xml on
-			// the root of boot.wim will not work as Windows Setup does *NOT* carry Autounattend.xml into
-			// %WINDIR%\Panther\unattend.xml then (See: https://github.com/pbatard/rufus/issues/1981).
-			// So instead, copy it to \sources\$OEM$\$$\Panther\unattend.xml on the media, as the content
-			// of \sources\$OEM$\$$\* will get copied into %WINDIR%\ during the file copy phase.
-			static_sprintf(path, "%c:\\sources\\$OEM$\\$$\\Panther", drive_letter);
-			i = SHCreateDirectoryExA(NULL, path, NULL);
-			if (i != ERROR_SUCCESS) {
-				SetLastError(i);
-				uprintf("Error: Could not create directory '%s': %s", path, WindowsErrorString());
-				goto out;
-			}
-			static_sprintf(path, "%c:\\sources\\$OEM$\\$$\\Panther\\unattend.xml", drive_letter);
-			if (!CopyFileU(unattend_xml_path, path, TRUE)) {
-				uprintf("Could not create '%s': %s", path, WindowsErrorString());
-				goto out;
-			}
-			uprintf("Created '%s'", path);
-		}
-		UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 103, PATCH_PROGRESS_TOTAL);
-	}
-	r = TRUE;
-
-out:
-	if (hSubKey != NULL)
-		RegCloseKey(hSubKey);
-	if (hKey != NULL)
-		RegCloseKey(hKey);
-	if (is_hive_mounted) {
-		UnmountRegistryHive(HKEY_LOCAL_MACHINE, offline_hive_name);
-		UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 104, PATCH_PROGRESS_TOTAL);
-	}
-	if (mount_path) {
-		uprintf("Unmounting '%s'...", boot_wim_path, wim_index);
-		WimUnmountImage(boot_wim_path, wim_index);
-		UpdateProgressWithInfo(OP_PATCH, MSG_325, PATCH_PROGRESS_TOTAL, PATCH_PROGRESS_TOTAL);
-	}
-	free(mount_path);
-	return r;
-}
diff --git a/src/wue.h b/src/wue.h
deleted file mode 100644
index 5b56ac32..00000000
--- a/src/wue.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Rufus: The Reliable USB Formatting Utility
- * Windows User Experience
- * Copyright © 2022 Pete Batard 
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see .
- */
-
-#include 
-
-#pragma once
-
-extern int unattend_xml_flags, unattend_xml_mask;
-extern int wintogo_index, wininst_index;
-extern char* unattend_xml_path;
-
-char* CreateUnattendXml(int arch, int flags);
-BOOL ApplyWindowsCustomization(char drive_letter, int flags);
-int SetWinToGoIndex(void);
-BOOL SetupWinPE(char drive_letter);
-BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp);