mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-21 10:25:12 -04:00
[core] enable the direct provision of install.wim/install.esd for Windows To Go
* Also remove the use of 'unattend.xml' to disable the recovery environment (use bcdedit instead) * Also some code cleanup and refactoring
This commit is contained in:
parent
4617f91e3b
commit
34b1d8a3ca
12 changed files with 316 additions and 194 deletions
|
@ -1,11 +0,0 @@
|
||||||
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
|
|
||||||
<unattend xmlns="urn:schemas-microsoft-com:unattend">
|
|
||||||
<settings pass="offlineServicing">
|
|
||||||
<component name="Microsoft-Windows-PartitionManager" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
<SanPolicy>4</SanPolicy>
|
|
||||||
</component>
|
|
||||||
<component name="Microsoft-Windows-PartitionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
<SanPolicy>4</SanPolicy>
|
|
||||||
</component>
|
|
||||||
</settings>
|
|
||||||
</unattend>
|
|
|
@ -1,11 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<unattend xmlns="urn:schemas-microsoft-com:unattend">
|
|
||||||
<settings pass="oobeSystem">
|
|
||||||
<component name="Microsoft-Windows-WinRE-RecoveryAgent" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
<UninstallWindowsRE>true</UninstallWindowsRE>
|
|
||||||
</component>
|
|
||||||
<component name="Microsoft-Windows-WinRE-RecoveryAgent" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
<UninstallWindowsRE>true</UninstallWindowsRE>
|
|
||||||
</component>
|
|
||||||
</settings>
|
|
||||||
</unattend>
|
|
127
src/format.c
127
src/format.c
|
@ -1220,8 +1220,8 @@ out:
|
||||||
// Returns -2 on user cancel, -1 on other error, >=0 on success.
|
// Returns -2 on user cancel, -1 on other error, >=0 on success.
|
||||||
int SetWinToGoIndex(void)
|
int SetWinToGoIndex(void)
|
||||||
{
|
{
|
||||||
char *mounted_iso, *build, image[128];
|
char *mounted_iso, *build, mounted_image_path[128];
|
||||||
char tmp_path[MAX_PATH] = "", xml_file[MAX_PATH] = "";
|
char xml_file[MAX_PATH] = "";
|
||||||
char *install_names[MAX_WININST];
|
char *install_names[MAX_WININST];
|
||||||
StrArray version_name, version_index;
|
StrArray version_name, version_index;
|
||||||
int i, build_nr = 0;
|
int i, build_nr = 0;
|
||||||
|
@ -1230,7 +1230,7 @@ int SetWinToGoIndex(void)
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
wintogo_index = -1;
|
wintogo_index = -1;
|
||||||
wininst_index = 0;
|
wininst_index = 0;
|
||||||
if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck() & 4) == 0) ||
|
if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck(FALSE) & 4) == 0) ||
|
||||||
(ComboBox_GetCurItemData(hFileSystem) != FS_NTFS)) {
|
(ComboBox_GetCurItemData(hFileSystem) != FS_NTFS)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1247,18 +1247,18 @@ int SetWinToGoIndex(void)
|
||||||
wininst_index = 0;
|
wininst_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mount the install.wim image, that resides on the ISO
|
// If we're not using a straigth install.wim, we need to mount the ISO to access it
|
||||||
mounted_iso = MountISO(image_path);
|
if (!img_report.is_windows_img) {
|
||||||
if (mounted_iso == NULL) {
|
mounted_iso = MountISO(image_path);
|
||||||
uprintf("Could not mount ISO for Windows To Go selection");
|
if (mounted_iso == NULL) {
|
||||||
return FALSE;
|
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]);
|
||||||
}
|
}
|
||||||
static_sprintf(image, "%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
|
// Now take a look at the XML file in install.wim to list our versions
|
||||||
if ((GetTempPathU(sizeof(tmp_path), tmp_path) == 0)
|
if ((GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, xml_file) == 0) || (xml_file[0] == 0)) {
|
||||||
|| (GetTempFileNameU(tmp_path, 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
|
// Last ditch effort to get a tmp file - just extract it to the current directory
|
||||||
static_strcpy(xml_file, ".\\RufVXml.tmp");
|
static_strcpy(xml_file, ".\\RufVXml.tmp");
|
||||||
}
|
}
|
||||||
|
@ -1266,7 +1266,8 @@ int SetWinToGoIndex(void)
|
||||||
DeleteFileU(xml_file);
|
DeleteFileU(xml_file);
|
||||||
|
|
||||||
// Must use the Windows WIM API as 7z messes up the XML
|
// Must use the Windows WIM API as 7z messes up the XML
|
||||||
if (!WimExtractFile_API(image, 0, "[1].xml", xml_file)) {
|
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");
|
uprintf("Could not acquire WIM index");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1328,25 +1329,19 @@ int SetWinToGoIndex(void)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
DeleteFileU(xml_file);
|
DeleteFileU(xml_file);
|
||||||
UnMountISO();
|
if (!img_report.is_windows_img)
|
||||||
|
UnMountISO();
|
||||||
return wintogo_index;
|
return wintogo_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://technet.microsoft.com/en-ie/library/jj721578.aspx
|
// http://technet.microsoft.com/en-ie/library/jj721578.aspx
|
||||||
// As opposed to the technet guide above, we no longer set internal drives offline,
|
// 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.
|
// due to people wondering why they can't see them by default and we also use
|
||||||
//#define SET_INTERNAL_DRIVES_OFFLINE
|
// bcdedit rather than 'unattend.xml' to disable the recovery environment.
|
||||||
static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
|
static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
|
||||||
{
|
{
|
||||||
#ifdef SET_INTERNAL_DRIVES_OFFLINE
|
char *mounted_iso, *ms_efi = NULL, mounted_image_path[128], cmd[MAX_PATH];
|
||||||
static char san_policy_path[] = "?:\\san_policy.xml";
|
|
||||||
#endif
|
|
||||||
static char unattend_path[] = "?:\\Windows\\System32\\sysprep\\unattend.xml";
|
|
||||||
char *mounted_iso, *ms_efi = NULL, image[128], cmd[MAX_PATH];
|
|
||||||
unsigned char *buffer;
|
|
||||||
DWORD bufsize;
|
|
||||||
ULONG cluster_size;
|
ULONG cluster_size;
|
||||||
FILE* fd;
|
|
||||||
|
|
||||||
uprintf("Windows To Go mode selected");
|
uprintf("Windows To Go mode selected");
|
||||||
// Additional sanity checks
|
// Additional sanity checks
|
||||||
|
@ -1355,25 +1350,28 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, we need to access the install.wim image, that resides on the ISO
|
if (!img_report.is_windows_img) {
|
||||||
mounted_iso = MountISO(image_path);
|
mounted_iso = MountISO(image_path);
|
||||||
if (mounted_iso == NULL) {
|
if (mounted_iso == NULL) {
|
||||||
uprintf("Could not mount ISO for Windows To Go installation");
|
uprintf("Could not mount ISO for Windows To Go installation");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_ISO_EXTRACT);
|
||||||
return FALSE;
|
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);
|
||||||
}
|
}
|
||||||
static_sprintf(image, "%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
|
// Now we use the WIM API to apply that image
|
||||||
if (!WimApplyImage(image, wintogo_index, drive_name)) {
|
if (!WimApplyImage(img_report.is_windows_img ? image_path : mounted_image_path, wintogo_index, drive_name)) {
|
||||||
uprintf("Failed to apply Windows To Go image");
|
uprintf("Failed to apply Windows To Go image");
|
||||||
if (!IS_ERROR(FormatStatus))
|
if (!IS_ERROR(FormatStatus))
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
|
||||||
UnMountISO();
|
if (!img_report.is_windows_img)
|
||||||
|
UnMountISO();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
UnMountISO();
|
if (!img_report.is_windows_img)
|
||||||
|
UnMountISO();
|
||||||
|
|
||||||
if (use_esp) {
|
if (use_esp) {
|
||||||
uprintf("Setting up EFI System Partition");
|
uprintf("Setting up EFI System Partition");
|
||||||
|
@ -1406,59 +1404,35 @@ static BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We invoke the 'bcdboot' command from the host, as the one from the drive produces problems (#558)
|
// 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
|
// 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'
|
// '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.
|
// 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,
|
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",
|
HAS_BOOTMGR_BIOS(img_report) ? (HAS_BOOTMGR_EFI(img_report) ? "ALL" : "BIOS") : "UEFI",
|
||||||
(use_esp)?ms_efi:drive_name);
|
(use_esp)?ms_efi:drive_name);
|
||||||
uprintf("Enabling boot using command '%s'", cmd);
|
uprintf(cmd);
|
||||||
if (RunCommand(cmd, sysnative_dir, usb_debug) != 0) {
|
if (RunCommand(cmd, sysnative_dir, usb_debug) != 0) {
|
||||||
// Try to continue... but report a failure
|
// Try to continue... but report a failure
|
||||||
uprintf("Failed to enable boot");
|
uprintf("Failed to enable boot");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_ISO_EXTRACT);
|
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);
|
||||||
|
|
||||||
|
uprintf("Disable the 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) {
|
if (use_esp) {
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
AltUnmountVolume(ms_efi, FALSE);
|
AltUnmountVolume(ms_efi, FALSE);
|
||||||
}
|
}
|
||||||
UpdateProgressWithInfo(OP_FILE_COPY, MSG_267, wim_proc_files + 2 * wim_extra_files, wim_nb_files);
|
|
||||||
|
|
||||||
// The following are non fatal if they fail
|
|
||||||
|
|
||||||
#ifdef SET_INTERNAL_DRIVES_OFFLINE
|
|
||||||
uprintf("Applying 'san_policy.xml', to set the target's internal drives offline...");
|
|
||||||
buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_TOGO_SAN_POLICY_XML),
|
|
||||||
_RT_RCDATA, "san_policy.xml", &bufsize, FALSE);
|
|
||||||
san_policy_path[0] = drive_name[0];
|
|
||||||
fd = fopenU(san_policy_path, "wb");
|
|
||||||
if ((fd == NULL) || (fwrite(buffer, 1, bufsize, fd) != bufsize)) {
|
|
||||||
uprintf("Could not write '%s'\n", san_policy_path);
|
|
||||||
if (fd)
|
|
||||||
fclose(fd);
|
|
||||||
} else {
|
|
||||||
fclose(fd);
|
|
||||||
// Can't use the one from the USB (at least for Windows 10 preview), as you'll get
|
|
||||||
// "Error: 0x800401f0 An error occurred while initializing COM security".
|
|
||||||
// On the other hand, using Windows 8.1 dism against Windows 10 doesn't work either
|
|
||||||
// (you get a message about needing to upgrade to latest AIK)...
|
|
||||||
static_sprintf(cmd, "dism /Image:%s\\ /Apply-Unattend:%s", drive_name, san_policy_path);
|
|
||||||
if (RunCommand(cmd, NULL, TRUE) != 0)
|
|
||||||
uprintf("Command '%s' failed to run", cmd);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uprintf("Copying 'unattend.xml', to disable the use of the Windows Recovery Environment...");
|
|
||||||
buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_TOGO_UNATTEND_XML),
|
|
||||||
_RT_RCDATA, "unattend.xml", &bufsize, FALSE);
|
|
||||||
unattend_path[0] = drive_name[0];
|
|
||||||
fd = fopenU(unattend_path, "wb");
|
|
||||||
if ((fd == NULL) || (fwrite(buffer, 1, bufsize, fd) != bufsize))
|
|
||||||
uprintf("Could not write '%s'", unattend_path);
|
|
||||||
if (fd != NULL)
|
|
||||||
fclose(fd);
|
|
||||||
UpdateProgressWithInfo(OP_FILE_COPY, MSG_267, wim_nb_files, wim_nb_files);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2145,17 +2119,18 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
IsFileInDB(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr")?"✓":"✗");
|
IsFileInDB(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr")?"✓":"✗");
|
||||||
if (!CopyFileU(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr", grub4dos_dst, FALSE))
|
if (!CopyFileU(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr", grub4dos_dst, FALSE))
|
||||||
uprintf("Failed to copy file: %s", WindowsErrorString());
|
uprintf("Failed to copy file: %s", WindowsErrorString());
|
||||||
} else if ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso)) {
|
} else if ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso || img_report.is_windows_img)) {
|
||||||
UpdateProgress(OP_FILE_COPY, 0.0f);
|
UpdateProgress(OP_FILE_COPY, 0.0f);
|
||||||
drive_name[2] = 0; // Ensure our drive is something like 'D:'
|
drive_name[2] = 0; // Ensure our drive is something like 'D:'
|
||||||
if (windows_to_go) {
|
if (windows_to_go) {
|
||||||
PrintInfoDebug(0, MSG_268);
|
PrintInfoDebug(0, MSG_268);
|
||||||
if (!SetupWinToGo(DriveIndex, drive_name, (extra_partitions & XP_ESP))) {
|
if (!SetupWinToGo(DriveIndex, drive_name, (extra_partitions & XP_ESP))) {
|
||||||
if (!IS_ERROR(FormatStatus))
|
if (!IS_ERROR(FormatStatus))
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_ISO_EXTRACT);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
assert(!img_report.is_windows_img);
|
||||||
if (!ExtractISO(image_path, drive_name, FALSE)) {
|
if (!ExtractISO(image_path, drive_name, FALSE)) {
|
||||||
if (!IS_ERROR(FormatStatus))
|
if (!IS_ERROR(FormatStatus))
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT);
|
||||||
|
@ -2180,7 +2155,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||||
} else {
|
} else {
|
||||||
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\';
|
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\';
|
||||||
if (!WimExtractFile(img_report.wininst_path[0], 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) {
|
if (!WimExtractFile(img_report.wininst_path[0], 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst, FALSE)) {
|
||||||
uprintf("Failed to setup Win7 EFI boot");
|
uprintf("Failed to setup Win7 EFI boot");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,8 @@ static const char* ldlinux_c32 = "ldlinux.c32";
|
||||||
static const char* md5sum_name[] = { "MD5SUMS", "md5sum.txt" };
|
static const char* md5sum_name[] = { "MD5SUMS", "md5sum.txt" };
|
||||||
static const char* casper_dirname = "/casper";
|
static const char* casper_dirname = "/casper";
|
||||||
static const char* efi_dirname = "/efi/boot";
|
static const char* efi_dirname = "/efi/boot";
|
||||||
static const char* efi_bootname[] = { "bootia32.efi", "bootia64.efi", "bootx64.efi", "bootarm.efi", "bootaa64.efi", "bootebc.efi" };
|
static const char* efi_bootname[MAX_ARCHS] =
|
||||||
|
{ "bootia32.efi", "bootia64.efi", "bootx64.efi", "bootarm.efi", "bootaa64.efi", "bootebc.efi" };
|
||||||
static const char* sources_str = "/sources";
|
static const char* sources_str = "/sources";
|
||||||
static const char* wininst_name[] = { "install.wim", "install.esd", "install.swm" };
|
static const char* wininst_name[] = { "install.wim", "install.esd", "install.swm" };
|
||||||
// We only support GRUB/BIOS (x86) that uses a standard config dir (/boot/grub/i386-pc/)
|
// We only support GRUB/BIOS (x86) that uses a standard config dir (/boot/grub/i386-pc/)
|
||||||
|
@ -249,7 +250,7 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t file_length, const
|
||||||
|
|
||||||
// Check for the EFI boot entries
|
// Check for the EFI boot entries
|
||||||
if (safe_stricmp(psz_dirname, efi_dirname) == 0) {
|
if (safe_stricmp(psz_dirname, efi_dirname) == 0) {
|
||||||
for (i=0; i<ARRAYSIZE(efi_bootname); i++)
|
for (i = 0; i < ARRAYSIZE(efi_bootname); i++)
|
||||||
if (safe_stricmp(psz_basename, efi_bootname[i]) == 0)
|
if (safe_stricmp(psz_basename, efi_bootname[i]) == 0)
|
||||||
img_report.has_efi |= (2 << i); // start at 2 since "bootmgr.efi" is bit 0
|
img_report.has_efi |= (2 << i); // start at 2 since "bootmgr.efi" is bit 0
|
||||||
}
|
}
|
||||||
|
@ -1044,7 +1045,7 @@ out:
|
||||||
if (img_report.has_grub2) {
|
if (img_report.has_grub2) {
|
||||||
// In case we have a GRUB2 based iso, we extract boot/grub/i386-pc/normal.mod to parse its version
|
// In case we have a GRUB2 based iso, we extract boot/grub/i386-pc/normal.mod to parse its version
|
||||||
img_report.grub2_version[0] = 0;
|
img_report.grub2_version[0] = 0;
|
||||||
if ((GetTempPathU(sizeof(path), path) != 0) && (GetTempFileNameU(path, APPLICATION_NAME, 0, path) != 0)) {
|
if (GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, path) != 0) {
|
||||||
size = (size_t)ExtractISOFile(src_iso, "boot/grub/i386-pc/normal.mod", path, FILE_ATTRIBUTE_NORMAL);
|
size = (size_t)ExtractISOFile(src_iso, "boot/grub/i386-pc/normal.mod", path, FILE_ATTRIBUTE_NORMAL);
|
||||||
buf = (char*)calloc(size, 1);
|
buf = (char*)calloc(size, 1);
|
||||||
fd = fopen(path, "rb");
|
fd = fopen(path, "rb");
|
||||||
|
|
|
@ -1130,6 +1130,26 @@ static __inline int _rmdirU(const char* dirname)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __inline BOOL MoveFileU(const char* lpExistingFileName, const char* lpNewFileName)
|
||||||
|
{
|
||||||
|
wconvert(lpExistingFileName);
|
||||||
|
wconvert(lpNewFileName);
|
||||||
|
BOOL ret = MoveFileW(wlpExistingFileName, wlpNewFileName);
|
||||||
|
wfree(lpNewFileName);
|
||||||
|
wfree(lpExistingFileName);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline BOOL MoveFileExU(const char* lpExistingFileName, const char* lpNewFileName, DWORD dwFlags)
|
||||||
|
{
|
||||||
|
wconvert(lpExistingFileName);
|
||||||
|
wconvert(lpNewFileName);
|
||||||
|
BOOL ret = MoveFileExW(wlpExistingFileName, wlpNewFileName, dwFlags);
|
||||||
|
wfree(lpNewFileName);
|
||||||
|
wfree(lpExistingFileName);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// The following expects PropertyBuffer to contain a single Unicode string
|
// The following expects PropertyBuffer to contain a single Unicode string
|
||||||
static __inline BOOL SetupDiGetDeviceRegistryPropertyU(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData,
|
static __inline BOOL SetupDiGetDeviceRegistryPropertyU(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData,
|
||||||
DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize)
|
DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize)
|
||||||
|
|
|
@ -90,8 +90,6 @@
|
||||||
#define IDR_LC_RUFUS_LOC 500
|
#define IDR_LC_RUFUS_LOC 500
|
||||||
#define IDR_XT_HOGGER 501
|
#define IDR_XT_HOGGER 501
|
||||||
#define IDR_UEFI_NTFS 502
|
#define IDR_UEFI_NTFS 502
|
||||||
#define IDR_TOGO_SAN_POLICY_XML 503
|
|
||||||
#define IDR_TOGO_UNATTEND_XML 504
|
|
||||||
#define IDM_SELECT 901
|
#define IDM_SELECT 901
|
||||||
#define IDM_DOWNLOAD 902
|
#define IDM_DOWNLOAD 902
|
||||||
#define IDC_DEVICE 1001
|
#define IDC_DEVICE 1001
|
||||||
|
|
165
src/rufus.c
165
src/rufus.c
|
@ -62,10 +62,11 @@ enum bootcheck_return {
|
||||||
static const char* cmdline_hogger = "rufus.com";
|
static const char* cmdline_hogger = "rufus.com";
|
||||||
static const char* ep_reg = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
|
static const char* ep_reg = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
|
||||||
static const char* vs_reg = "Software\\Microsoft\\VisualStudio";
|
static const char* vs_reg = "Software\\Microsoft\\VisualStudio";
|
||||||
|
static const char* arch_name[MAX_ARCHS] = { "x86_32", "Itanic", "x86_64", "ARM", "ARM64", "EBC" };
|
||||||
static BOOL existing_key = FALSE; // For LGP set/restore
|
static BOOL existing_key = FALSE; // For LGP set/restore
|
||||||
static BOOL size_check = TRUE;
|
static BOOL size_check = TRUE;
|
||||||
static BOOL log_displayed = FALSE;
|
static BOOL log_displayed = FALSE;
|
||||||
static BOOL iso_provided = FALSE;
|
static BOOL img_provided = FALSE;
|
||||||
static BOOL user_notified = FALSE;
|
static BOOL user_notified = FALSE;
|
||||||
static BOOL relaunch = FALSE;
|
static BOOL relaunch = FALSE;
|
||||||
static BOOL dont_display_image_name = FALSE;
|
static BOOL dont_display_image_name = FALSE;
|
||||||
|
@ -118,8 +119,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;
|
BOOL write_as_image = FALSE, write_as_esp = FALSE, installed_uefi_ntfs = FALSE, use_vds = FALSE;
|
||||||
|
BOOL windows_to_go_selected = FALSE;
|
||||||
float fScale = 1.0f;
|
float fScale = 1.0f;
|
||||||
int dialog_showing = 0, selection_default = BT_IMAGE, windows_to_go_selection = 0, persistence_unit_selection = -1;
|
int dialog_showing = 0, selection_default = BT_IMAGE, persistence_unit_selection = -1;
|
||||||
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];
|
||||||
|
@ -315,7 +317,7 @@ static void SetPartitionSchemeAndTargetSystem(BOOL only_target)
|
||||||
preferred_pt = (selected_pt >= 0) ? selected_pt : PARTITION_STYLE_MBR;
|
preferred_pt = (selected_pt >= 0) ? selected_pt : PARTITION_STYLE_MBR;
|
||||||
else if (boot_type == BT_UEFI_NTFS)
|
else if (boot_type == BT_UEFI_NTFS)
|
||||||
preferred_pt = (selected_pt >= 0) ? selected_pt : PARTITION_STYLE_GPT;
|
preferred_pt = (selected_pt >= 0) ? selected_pt : PARTITION_STYLE_GPT;
|
||||||
else if ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso)) {
|
else if ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso || img_report.is_windows_img)) {
|
||||||
if (HAS_WINDOWS(img_report) && img_report.has_efi)
|
if (HAS_WINDOWS(img_report) && img_report.has_efi)
|
||||||
preferred_pt = allow_dual_uefi_bios? PARTITION_STYLE_MBR :
|
preferred_pt = allow_dual_uefi_bios? PARTITION_STYLE_MBR :
|
||||||
((selected_pt >= 0) ? selected_pt : PARTITION_STYLE_GPT);
|
((selected_pt >= 0) ? selected_pt : PARTITION_STYLE_GPT);
|
||||||
|
@ -849,7 +851,8 @@ static void EnableControls(BOOL enable, BOOL remove_checkboxes)
|
||||||
EnableBootOptions(enable, remove_checkboxes);
|
EnableBootOptions(enable, remove_checkboxes);
|
||||||
|
|
||||||
// Finally, only enable the half-size dropdowns if we aren't dealing with a pure DD image
|
// Finally, only enable the half-size dropdowns if we aren't dealing with a pure DD image
|
||||||
enable = ((boot_type == BT_IMAGE) && (image_path != NULL) && (!img_report.is_iso)) ? FALSE : enable;
|
enable = ((boot_type == BT_IMAGE) && (image_path != NULL) &&
|
||||||
|
(!(img_report.is_iso || img_report.is_windows_img))) ? FALSE : enable;
|
||||||
EnableWindow(hPartitionScheme, enable);
|
EnableWindow(hPartitionScheme, enable);
|
||||||
EnableWindow(hTargetSystem, enable);
|
EnableWindow(hTargetSystem, enable);
|
||||||
EnableWindow(GetDlgItem(hMainDialog, IDS_CSM_HELP_TXT), enable);
|
EnableWindow(GetDlgItem(hMainDialog, IDS_CSM_HELP_TXT), enable);
|
||||||
|
@ -1086,25 +1089,101 @@ static void DisplayISOProps(void)
|
||||||
" Because of this, the size required for the target media may be much larger than size of the ISO...");
|
" Because of this, the size required for the target media may be much larger than size of the ISO...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the image name into the Boot selection dropdown
|
// Insert the image name into the Boot selection dropdown and (re)populate the Image option dropdown
|
||||||
static void UpdateImage(void)
|
static void UpdateImage(BOOL update_image_option_only)
|
||||||
{
|
{
|
||||||
assert(image_index != 0);
|
assert(image_index != 0);
|
||||||
|
|
||||||
if (ComboBox_GetItemData(hBootType, image_index) == BT_IMAGE)
|
if (!update_image_option_only) {
|
||||||
ComboBox_DeleteString(hBootType, image_index);
|
if (ComboBox_GetItemData(hBootType, image_index) == BT_IMAGE)
|
||||||
ComboBox_InsertStringU(hBootType, image_index,
|
ComboBox_DeleteString(hBootType, image_index);
|
||||||
(image_path == NULL) ? lmprintf(MSG_281, lmprintf(MSG_280)) : short_image_path);
|
ComboBox_InsertStringU(hBootType, image_index,
|
||||||
ComboBox_SetItemData(hBootType, image_index, BT_IMAGE);
|
(image_path == NULL) ? lmprintf(MSG_281, lmprintf(MSG_280)) : short_image_path);
|
||||||
IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, image_index));
|
ComboBox_SetItemData(hBootType, image_index, BT_IMAGE);
|
||||||
boot_type = (int)ComboBox_GetCurItemData(hBootType);
|
IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, image_index));
|
||||||
SetBootTypeDropdownWidth();
|
boot_type = (int)ComboBox_GetCurItemData(hBootType);
|
||||||
|
SetBootTypeDropdownWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox_ResetContent(hImageOption);
|
||||||
|
if (!img_report.is_windows_img)
|
||||||
|
IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_117)), FALSE));
|
||||||
|
IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_118)), TRUE));
|
||||||
|
IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, (img_report.is_windows_img || !windows_to_go_selected) ? 0 : 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t FindArch(const char* filename)
|
||||||
|
{
|
||||||
|
uint8_t ret = 0;
|
||||||
|
HANDLE hFile = NULL, hFileMapping = NULL;
|
||||||
|
PIMAGE_DOS_HEADER pImageDOSHeader = NULL;
|
||||||
|
// NB: The field we are after is at the same location for 32 and 64-bit
|
||||||
|
// PE headers, so we don't need to care about using PIMAGE_NT_HEADERS[32|64]
|
||||||
|
PIMAGE_NT_HEADERS pImageNTHeader = NULL;
|
||||||
|
|
||||||
|
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", filename, WindowsErrorString());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||||
|
if (hFileMapping == NULL) {
|
||||||
|
uprintf("FindArch: Could not create file mapping: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pImageDOSHeader = (PIMAGE_DOS_HEADER)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
if (pImageDOSHeader == NULL) {
|
||||||
|
uprintf("FindArch: Could not get mapped view address: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (pImageDOSHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||||
|
uprintf("FindArch: DOS header not found");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
pImageNTHeader = (PIMAGE_NT_HEADERS)((uintptr_t)pImageDOSHeader + pImageDOSHeader->e_lfanew);
|
||||||
|
if (pImageNTHeader->Signature != IMAGE_NT_SIGNATURE) {
|
||||||
|
uprintf("FindArch: NT header not found");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (pImageNTHeader->FileHeader.Machine) {
|
||||||
|
case IMAGE_FILE_MACHINE_I386:
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
|
case IMAGE_FILE_MACHINE_IA64:
|
||||||
|
ret = 2;
|
||||||
|
break;
|
||||||
|
case IMAGE_FILE_MACHINE_AMD64:
|
||||||
|
ret = 3;
|
||||||
|
break;
|
||||||
|
case IMAGE_FILE_MACHINE_ARM:
|
||||||
|
ret = 4;
|
||||||
|
break;
|
||||||
|
case IMAGE_FILE_MACHINE_ARM64:
|
||||||
|
ret = 5;
|
||||||
|
break;
|
||||||
|
case IMAGE_FILE_MACHINE_EBC:
|
||||||
|
ret = 6;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (pImageDOSHeader != NULL)
|
||||||
|
UnmapViewOfFile(pImageDOSHeader);
|
||||||
|
safe_closehandle(hFileMapping);
|
||||||
|
safe_closehandle(hFile);
|
||||||
|
assert(ret <= MAX_ARCHS);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The scanning process can be blocking for message processing => use a thread
|
// The scanning process can be blocking for message processing => use a thread
|
||||||
DWORD WINAPI ISOScanThread(LPVOID param)
|
DWORD WINAPI ImageScanThread(LPVOID param)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
uint8_t arch;
|
||||||
|
char tmp_path[MAX_PATH];
|
||||||
|
|
||||||
if (image_path == NULL)
|
if (image_path == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1114,13 +1193,15 @@ DWORD WINAPI ISOScanThread(LPVOID param)
|
||||||
memset(&img_report, 0, sizeof(img_report));
|
memset(&img_report, 0, sizeof(img_report));
|
||||||
img_report.is_iso = (BOOLEAN)ExtractISO(image_path, "", TRUE);
|
img_report.is_iso = (BOOLEAN)ExtractISO(image_path, "", TRUE);
|
||||||
img_report.is_bootable_img = (BOOLEAN)IsBootableImage(image_path);
|
img_report.is_bootable_img = (BOOLEAN)IsBootableImage(image_path);
|
||||||
|
ComboBox_ResetContent(hImageOption);
|
||||||
|
|
||||||
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.is_iso && !img_report.is_bootable_img)) {
|
(img_report.image_size == 0) ||
|
||||||
|
(!img_report.is_iso && !img_report.is_bootable_img && !img_report.is_windows_img)) {
|
||||||
// Failed to scan image
|
// Failed to scan image
|
||||||
SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0);
|
SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0);
|
||||||
safe_free(image_path);
|
safe_free(image_path);
|
||||||
UpdateImage();
|
UpdateImage(FALSE);
|
||||||
SetMBRProps();
|
SetMBRProps();
|
||||||
PopulateProperties();
|
PopulateProperties();
|
||||||
PrintInfoDebug(0, MSG_203);
|
PrintInfoDebug(0, MSG_203);
|
||||||
|
@ -1129,7 +1210,25 @@ DWORD WINAPI ISOScanThread(LPVOID param)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (img_report.is_bootable_img) {
|
if (img_report.is_windows_img) {
|
||||||
|
selection_default = BT_IMAGE;
|
||||||
|
if (GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, tmp_path) != 0) {
|
||||||
|
// Only look at index 1 for now. If people complain, we may look for more.
|
||||||
|
if (WimExtractFile(image_path, 1, "Windows\\Boot\\EFI\\bootmgr.efi", tmp_path, TRUE)) {
|
||||||
|
arch = FindArch(tmp_path);
|
||||||
|
if (arch != 0) {
|
||||||
|
uprintf(" Image contains an %s EFI boot manager", arch_name[arch - 1]);
|
||||||
|
img_report.has_efi = 1 | (1 << arch);
|
||||||
|
img_report.has_bootmgr_efi = TRUE;
|
||||||
|
img_report.wininst_index = 1;
|
||||||
|
} else {
|
||||||
|
uprintf(" Image does not contain an EFI boot manager");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DeleteFileU(tmp_path);
|
||||||
|
}
|
||||||
|
uprintf(" Image is %sa UEFI bootable Windows installation image", img_report.has_efi ? "" : "NOT ");
|
||||||
|
} else if (img_report.is_bootable_img) {
|
||||||
uprintf(" Image is a %sbootable %s image",
|
uprintf(" Image is a %sbootable %s image",
|
||||||
(img_report.compression_type != BLED_COMPRESSION_NONE) ? "compressed " : "", img_report.is_vhd ? "VHD" : "disk");
|
(img_report.compression_type != BLED_COMPRESSION_NONE) ? "compressed " : "", img_report.is_vhd ? "VHD" : "disk");
|
||||||
selection_default = BT_IMAGE;
|
selection_default = BT_IMAGE;
|
||||||
|
@ -1160,13 +1259,13 @@ DWORD WINAPI ISOScanThread(LPVOID param)
|
||||||
i++;
|
i++;
|
||||||
short_image_path = &image_path[i];
|
short_image_path = &image_path[i];
|
||||||
PrintStatus(0, MSG_205, short_image_path);
|
PrintStatus(0, MSG_205, short_image_path);
|
||||||
UpdateImage();
|
|
||||||
uprintf("Using image: %s (%s)", short_image_path, SizeToHumanReadable(img_report.image_size, FALSE, FALSE));
|
uprintf("Using image: %s (%s)", short_image_path, SizeToHumanReadable(img_report.image_size, FALSE, FALSE));
|
||||||
}
|
}
|
||||||
|
UpdateImage(dont_display_image_name);
|
||||||
ToggleImageOptions();
|
ToggleImageOptions();
|
||||||
EnableControls(TRUE, FALSE);
|
EnableControls(TRUE, FALSE);
|
||||||
// Set Target and FS accordingly
|
// Set Target and FS accordingly
|
||||||
if (img_report.is_iso) {
|
if (img_report.is_iso || img_report.is_windows_img) {
|
||||||
IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, image_index));
|
IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, image_index));
|
||||||
SetPartitionSchemeAndTargetSystem(FALSE);
|
SetPartitionSchemeAndTargetSystem(FALSE);
|
||||||
SetFileSystemAndClusterSize(NULL);
|
SetFileSystemAndClusterSize(NULL);
|
||||||
|
@ -1266,7 +1365,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
|
||||||
MessageBoxExU(hMainDialog, lmprintf(MSG_091), lmprintf(MSG_090), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
|
MessageBoxExU(hMainDialog, lmprintf(MSG_091), lmprintf(MSG_090), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (HAS_WIN7_EFI(img_report) && (!WimExtractCheck())) {
|
if (HAS_WIN7_EFI(img_report) && (!WimExtractCheck(FALSE))) {
|
||||||
// Your platform cannot extract files from WIM archives => download 7-zip?
|
// Your platform cannot extract files from WIM archives => download 7-zip?
|
||||||
if (MessageBoxExU(hMainDialog, lmprintf(MSG_102), lmprintf(MSG_101), MB_YESNO|MB_ICONERROR|MB_IS_RTL, selected_langid) == IDYES)
|
if (MessageBoxExU(hMainDialog, lmprintf(MSG_102), lmprintf(MSG_101), MB_YESNO|MB_ICONERROR|MB_IS_RTL, selected_langid) == IDYES)
|
||||||
ShellExecuteA(hMainDialog, "open", SEVENZIP_URL, NULL, NULL, SW_SHOWNORMAL);
|
ShellExecuteA(hMainDialog, "open", SEVENZIP_URL, NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
@ -1680,10 +1779,6 @@ static void InitDialog(HWND hDlg)
|
||||||
// Fill up the boot options dropdown
|
// Fill up the boot options dropdown
|
||||||
SetBootOptions();
|
SetBootOptions();
|
||||||
|
|
||||||
// Fill up the Image Options Windows To Go dropdown
|
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_117)), FALSE));
|
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_118)), TRUE));
|
|
||||||
|
|
||||||
// Fill up the MBR masqueraded disk IDs ("8 disks should be enough for anybody")
|
// Fill up the MBR masqueraded disk IDs ("8 disks should be enough for anybody")
|
||||||
IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, lmprintf(MSG_030, LEFT_TO_RIGHT_EMBEDDING "0x80" POP_DIRECTIONAL_FORMATTING)), 0x80));
|
IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, lmprintf(MSG_030, LEFT_TO_RIGHT_EMBEDDING "0x80" POP_DIRECTIONAL_FORMATTING)), 0x80));
|
||||||
for (i=1; i<=7; i++) {
|
for (i=1; i<=7; i++) {
|
||||||
|
@ -1744,7 +1839,7 @@ static void InitDialog(HWND hDlg)
|
||||||
ToggleImageOptions();
|
ToggleImageOptions();
|
||||||
|
|
||||||
// Process commandline parameters
|
// Process commandline parameters
|
||||||
if (iso_provided) {
|
if (img_provided) {
|
||||||
// Simulate a button click for image selection
|
// Simulate a button click for image selection
|
||||||
PostMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
PostMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
||||||
}
|
}
|
||||||
|
@ -2134,7 +2229,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_selection = ComboBox_GetCurSel(hImageOption);
|
windows_to_go_selected = (BOOL)ComboBox_GetCurItemData(hImageOption);
|
||||||
break;
|
break;
|
||||||
case IDC_PERSISTENCE_SIZE:
|
case IDC_PERSISTENCE_SIZE:
|
||||||
if (HIWORD(wParam) == EN_CHANGE) {
|
if (HIWORD(wParam) == EN_CHANGE) {
|
||||||
|
@ -2260,13 +2355,13 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
EnableControls(FALSE, FALSE);
|
EnableControls(FALSE, FALSE);
|
||||||
DownloadISO();
|
DownloadISO();
|
||||||
} else {
|
} else {
|
||||||
if (iso_provided) {
|
if (img_provided) {
|
||||||
uprintf("\r\nImage provided: '%s'", image_path);
|
uprintf("\r\nImage provided: '%s'", image_path);
|
||||||
iso_provided = FALSE; // One off thing...
|
img_provided = FALSE; // One off thing...
|
||||||
} else {
|
} else {
|
||||||
char* old_image_path = image_path;
|
char* old_image_path = image_path;
|
||||||
// If declared globaly, lmprintf(MSG_036) would be called on each message...
|
// If declared globaly, lmprintf(MSG_036) would be called on each message...
|
||||||
EXT_DECL(img_ext, NULL, __VA_GROUP__("*.iso;*.img;*.vhd;*.usb;*.bz2;*.bzip2;*.gz;*.lzma;*.xz;*.Z;*.zip"),
|
EXT_DECL(img_ext, NULL, __VA_GROUP__("*.iso;*.img;*.vhd;*.usb;*.bz2;*.bzip2;*.gz;*.lzma;*.xz;*.Z;*.zip;*.wim;*.esd"),
|
||||||
__VA_GROUP__(lmprintf(MSG_036)));
|
__VA_GROUP__(lmprintf(MSG_036)));
|
||||||
image_path = FileDialog(FALSE, NULL, &img_ext, 0);
|
image_path = FileDialog(FALSE, NULL, &img_ext, 0);
|
||||||
if (image_path == NULL) {
|
if (image_path == NULL) {
|
||||||
|
@ -2284,7 +2379,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FormatStatus = 0;
|
FormatStatus = 0;
|
||||||
if (CreateThread(NULL, 0, ISOScanThread, NULL, 0, NULL) == NULL) {
|
if (CreateThread(NULL, 0, ImageScanThread, NULL, 0, NULL) == NULL) {
|
||||||
uprintf("Unable to start ISO scanning thread");
|
uprintf("Unable to start ISO scanning thread");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD);
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD);
|
||||||
}
|
}
|
||||||
|
@ -2402,7 +2497,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
case UM_SELECT_ISO:
|
case UM_SELECT_ISO:
|
||||||
select_index = 0;
|
select_index = 0;
|
||||||
iso_provided = TRUE;
|
img_provided = TRUE;
|
||||||
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECT), uppercase_select[0]);
|
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECT), uppercase_select[0]);
|
||||||
SendMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
SendMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -2606,7 +2701,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
safe_free(wbuffer);
|
safe_free(wbuffer);
|
||||||
|
|
||||||
if (image_path != NULL) {
|
if (image_path != NULL) {
|
||||||
iso_provided = TRUE;
|
img_provided = TRUE;
|
||||||
// Simulate image selection click
|
// Simulate image selection click
|
||||||
SendMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
SendMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
||||||
}
|
}
|
||||||
|
@ -3065,7 +3160,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
if (_access(optarg, 0) != -1) {
|
if (_access(optarg, 0) != -1) {
|
||||||
safe_free(image_path);
|
safe_free(image_path);
|
||||||
image_path = safe_strdup(optarg);
|
image_path = safe_strdup(optarg);
|
||||||
iso_provided = TRUE;
|
img_provided = TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("Could not find ISO image '%s'\n", optarg);
|
printf("Could not find ISO image '%s'\n", optarg);
|
||||||
|
@ -3490,7 +3585,7 @@ relaunch:
|
||||||
enable_iso = !enable_iso;
|
enable_iso = !enable_iso;
|
||||||
PrintStatusTimeout(lmprintf(MSG_262), enable_iso);
|
PrintStatusTimeout(lmprintf(MSG_262), enable_iso);
|
||||||
if (image_path != NULL) {
|
if (image_path != NULL) {
|
||||||
iso_provided = TRUE;
|
img_provided = TRUE;
|
||||||
dont_display_image_name = TRUE;
|
dont_display_image_name = TRUE;
|
||||||
SendMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
SendMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
||||||
}
|
}
|
||||||
|
|
10
src/rufus.h
10
src/rufus.h
|
@ -62,6 +62,7 @@
|
||||||
#define DRIVE_INDEX_MAX 0x000000C0
|
#define DRIVE_INDEX_MAX 0x000000C0
|
||||||
#define MIN_DRIVE_SIZE 8 // Minimum size a drive must have, to be formattable (in MB)
|
#define MIN_DRIVE_SIZE 8 // Minimum size a drive must have, to be formattable (in MB)
|
||||||
#define MIN_EXTRA_PART_SIZE (1024*1024) // Minimum size of the extra partition, in bytes
|
#define MIN_EXTRA_PART_SIZE (1024*1024) // Minimum size of the extra partition, in bytes
|
||||||
|
#define MAX_ARCHS 6 // Number of arhitectures we recognize
|
||||||
#define MAX_DRIVES (DRIVE_INDEX_MAX - DRIVE_INDEX_MIN)
|
#define MAX_DRIVES (DRIVE_INDEX_MAX - DRIVE_INDEX_MIN)
|
||||||
#define MAX_TOOLTIPS 128
|
#define MAX_TOOLTIPS 128
|
||||||
#define MAX_SIZE_SUFFIXES 6 // bytes, KB, MB, GB, TB, PB
|
#define MAX_SIZE_SUFFIXES 6 // bytes, KB, MB, GB, TB, PB
|
||||||
|
@ -338,6 +339,7 @@ typedef struct {
|
||||||
BOOLEAN is_iso;
|
BOOLEAN is_iso;
|
||||||
BOOLEAN is_bootable_img;
|
BOOLEAN is_bootable_img;
|
||||||
BOOLEAN is_vhd;
|
BOOLEAN is_vhd;
|
||||||
|
BOOLEAN is_windows_img;
|
||||||
BOOLEAN disable_iso;
|
BOOLEAN disable_iso;
|
||||||
uint16_t winpe;
|
uint16_t winpe;
|
||||||
uint8_t has_efi;
|
uint8_t has_efi;
|
||||||
|
@ -555,10 +557,10 @@ extern char* replace_in_token_data(const char* filename, const char* token, cons
|
||||||
extern char* replace_char(const char* src, const char c, const char* rep);
|
extern char* replace_char(const char* src, const char c, const char* rep);
|
||||||
extern void parse_update(char* buf, size_t len);
|
extern void parse_update(char* buf, size_t len);
|
||||||
extern void* get_data_from_asn1(const uint8_t* buf, size_t buf_len, const char* oid_str, uint8_t asn1_type, size_t* data_len);
|
extern void* get_data_from_asn1(const uint8_t* buf, size_t buf_len, const char* oid_str, uint8_t asn1_type, size_t* data_len);
|
||||||
extern uint8_t WimExtractCheck(void);
|
extern uint8_t WimExtractCheck(BOOL bSilent);
|
||||||
extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst);
|
extern BOOL WimExtractFile(const char* wim_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);
|
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);
|
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 BOOL IsBootableImage(const char* path);
|
extern BOOL IsBootableImage(const char* path);
|
||||||
extern BOOL AppendVHDFooter(const char* vhd_path);
|
extern BOOL AppendVHDFooter(const char* vhd_path);
|
||||||
|
|
14
src/rufus.rc
14
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.12.1690"
|
CAPTION "Rufus 3.12.1691"
|
||||||
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
|
||||||
|
@ -308,8 +308,6 @@ BEGIN
|
||||||
"IDR_FD_EGA18_CPX RCDATA ""../res/freedos/EGA18.CPX""\r\n"
|
"IDR_FD_EGA18_CPX RCDATA ""../res/freedos/EGA18.CPX""\r\n"
|
||||||
"IDR_XT_HOGGER RCDATA ""../res/hogger/hogger.exe""\r\n"
|
"IDR_XT_HOGGER RCDATA ""../res/hogger/hogger.exe""\r\n"
|
||||||
"IDR_UEFI_NTFS RCDATA ""../res/uefi/uefi-ntfs.img""\r\n"
|
"IDR_UEFI_NTFS RCDATA ""../res/uefi/uefi-ntfs.img""\r\n"
|
||||||
"IDR_TOGO_SAN_POLICY_XML RCDATA ""../res/togo/san_policy.xml""\r\n"
|
|
||||||
"IDR_TOGO_UNATTEND_XML RCDATA ""../res/togo/unattend.xml""\r\n"
|
|
||||||
"IDI_LANG_16 RCDATA ""../res/icons/lang-16.png""\r\n"
|
"IDI_LANG_16 RCDATA ""../res/icons/lang-16.png""\r\n"
|
||||||
"IDI_INFO_16 RCDATA ""../res/icons/info-16.png""\r\n"
|
"IDI_INFO_16 RCDATA ""../res/icons/info-16.png""\r\n"
|
||||||
"IDI_SETTINGS_16 RCDATA ""../res/icons/settings-16.png""\r\n"
|
"IDI_SETTINGS_16 RCDATA ""../res/icons/settings-16.png""\r\n"
|
||||||
|
@ -397,8 +395,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 3,12,1690,0
|
FILEVERSION 3,12,1691,0
|
||||||
PRODUCTVERSION 3,12,1690,0
|
PRODUCTVERSION 3,12,1691,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -416,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.12.1690"
|
VALUE "FileVersion", "3.12.1691"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2020 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.12.exe"
|
VALUE "OriginalFilename", "rufus-3.12.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "3.12.1690"
|
VALUE "ProductVersion", "3.12.1691"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -494,8 +492,6 @@ IDR_FD_EGA17_CPX RCDATA "../res/freedos/EGA17.CPX"
|
||||||
IDR_FD_EGA18_CPX RCDATA "../res/freedos/EGA18.CPX"
|
IDR_FD_EGA18_CPX RCDATA "../res/freedos/EGA18.CPX"
|
||||||
IDR_XT_HOGGER RCDATA "../res/hogger/hogger.exe"
|
IDR_XT_HOGGER RCDATA "../res/hogger/hogger.exe"
|
||||||
IDR_UEFI_NTFS RCDATA "../res/uefi/uefi-ntfs.img"
|
IDR_UEFI_NTFS RCDATA "../res/uefi/uefi-ntfs.img"
|
||||||
IDR_TOGO_SAN_POLICY_XML RCDATA "../res/togo/san_policy.xml"
|
|
||||||
IDR_TOGO_UNATTEND_XML RCDATA "../res/togo/unattend.xml"
|
|
||||||
IDI_LANG_16 RCDATA "../res/icons/lang-16.png"
|
IDI_LANG_16 RCDATA "../res/icons/lang-16.png"
|
||||||
IDI_INFO_16 RCDATA "../res/icons/info-16.png"
|
IDI_INFO_16 RCDATA "../res/icons/info-16.png"
|
||||||
IDI_SETTINGS_16 RCDATA "../res/icons/settings-16.png"
|
IDI_SETTINGS_16 RCDATA "../res/icons/settings-16.png"
|
||||||
|
|
27
src/ui.c
27
src/ui.c
|
@ -772,7 +772,8 @@ void ToggleImageOptions(void)
|
||||||
uint8_t entry_image_options = image_options;
|
uint8_t entry_image_options = image_options;
|
||||||
int i, shift = rh;
|
int i, shift = rh;
|
||||||
|
|
||||||
has_wintogo = ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso) && (nWindowsVersion >= WINDOWS_8) && (HAS_WINTOGO(img_report)));
|
has_wintogo = ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso || img_report.is_windows_img) &&
|
||||||
|
(nWindowsVersion >= WINDOWS_8) && (HAS_WINTOGO(img_report)));
|
||||||
has_persistence = ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso) && (HAS_PERSISTENCE(img_report)));
|
has_persistence = ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso) && (HAS_PERSISTENCE(img_report)));
|
||||||
|
|
||||||
assert(popcnt8(image_options) <= 1);
|
assert(popcnt8(image_options) <= 1);
|
||||||
|
@ -784,13 +785,20 @@ void ToggleImageOptions(void)
|
||||||
if ( ((has_wintogo) && !(image_options & IMOP_WINTOGO)) ||
|
if ( ((has_wintogo) && !(image_options & IMOP_WINTOGO)) ||
|
||||||
((!has_wintogo) && (image_options & IMOP_WINTOGO)) ) {
|
((!has_wintogo) && (image_options & IMOP_WINTOGO)) ) {
|
||||||
image_options ^= IMOP_WINTOGO;
|
image_options ^= IMOP_WINTOGO;
|
||||||
// Set the Windows To Go selection in the dropdown
|
if (image_options & IMOP_WINTOGO) {
|
||||||
IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, windows_to_go_selection));
|
// 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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((has_persistence) && !(image_options & IMOP_PERSISTENCE)) ||
|
if (((has_persistence) && !(image_options & IMOP_PERSISTENCE)) ||
|
||||||
((!has_persistence) && (image_options & IMOP_PERSISTENCE))) {
|
((!has_persistence) && (image_options & IMOP_PERSISTENCE))) {
|
||||||
image_options ^= IMOP_PERSISTENCE;
|
image_options ^= IMOP_PERSISTENCE;
|
||||||
|
if (image_options & IMOP_PERSISTENCE) {
|
||||||
|
SetWindowTextU(GetDlgItem(hMainDialog, IDS_IMAGE_OPTION_TXT), lmprintf(MSG_123));
|
||||||
|
TogglePersistenceControls(persistence_size != 0);
|
||||||
|
SetPersistenceSize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ((entry_image_options != 0) && (has_wintogo || has_persistence)) ||
|
if ( ((entry_image_options != 0) && (has_wintogo || has_persistence)) ||
|
||||||
|
@ -815,15 +823,6 @@ void ToggleImageOptions(void)
|
||||||
ShowWindow(GetDlgItem(hMainDialog, image_option_toggle_ids[i][0]),
|
ShowWindow(GetDlgItem(hMainDialog, image_option_toggle_ids[i][0]),
|
||||||
(image_options & image_option_toggle_ids[i][1]) ? SW_SHOW : SW_HIDE);
|
(image_options & image_option_toggle_ids[i][1]) ? SW_SHOW : SW_HIDE);
|
||||||
}
|
}
|
||||||
// Set the dropdown default selection
|
|
||||||
if (image_options & IMOP_WINTOGO) {
|
|
||||||
SetWindowTextU(GetDlgItem(hMainDialog, IDS_IMAGE_OPTION_TXT), image_option_txt);
|
|
||||||
IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, windows_to_go_selection));
|
|
||||||
} else if (image_options & IMOP_PERSISTENCE) {
|
|
||||||
SetWindowTextU(GetDlgItem(hMainDialog, IDS_IMAGE_OPTION_TXT), lmprintf(MSG_123));
|
|
||||||
TogglePersistenceControls(persistence_size != 0);
|
|
||||||
SetPersistenceSize();
|
|
||||||
}
|
|
||||||
// If you don't force a redraw here, all kind of bad UI artifacts happen...
|
// If you don't force a redraw here, all kind of bad UI artifacts happen...
|
||||||
InvalidateRect(hMainDialog, NULL, TRUE);
|
InvalidateRect(hMainDialog, NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
@ -1180,14 +1179,14 @@ void InitProgress(BOOL bOnlyFormat)
|
||||||
nb_slots[OP_FILE_COPY] = 5 + 1;
|
nb_slots[OP_FILE_COPY] = 5 + 1;
|
||||||
break;
|
break;
|
||||||
case BT_IMAGE:
|
case BT_IMAGE:
|
||||||
nb_slots[OP_FILE_COPY] = img_report.is_iso ? -1 : 0;
|
nb_slots[OP_FILE_COPY] = (img_report.is_iso || img_report.is_windows_img) ? -1 : 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
nb_slots[OP_FILE_COPY] = 2 + 1;
|
nb_slots[OP_FILE_COPY] = 2 + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (selection_default == BT_IMAGE && !img_report.is_iso) {
|
if (selection_default == BT_IMAGE && !(img_report.is_iso || img_report.is_windows_img)) {
|
||||||
nb_slots[OP_FORMAT] = -1;
|
nb_slots[OP_FORMAT] = -1;
|
||||||
} else {
|
} else {
|
||||||
nb_slots[OP_ZERO_MBR] = 1;
|
nb_slots[OP_ZERO_MBR] = 1;
|
||||||
|
|
5
src/ui.h
5
src/ui.h
|
@ -74,13 +74,12 @@ 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;
|
extern BOOL advanced_mode_device, advanced_mode_format, force_large_fat32, app_changed_size, windows_to_go_selected;
|
||||||
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];
|
||||||
extern char *short_image_path, image_option_txt[128];
|
extern char *short_image_path, image_option_txt[128];
|
||||||
extern int advanced_device_section_height, advanced_format_section_height;
|
extern int advanced_device_section_height, advanced_format_section_height, persistence_unit_selection;
|
||||||
extern int windows_to_go_selection, persistence_unit_selection;
|
|
||||||
extern int selection_default, cbw, ddw, ddbh, bh, update_progress_type;
|
extern int selection_default, cbw, ddw, ddbh, bh, update_progress_type;
|
||||||
|
|
||||||
extern void SetAccessibleName(HWND hCtrl, const char* name);
|
extern void SetAccessibleName(HWND hCtrl, const char* name);
|
||||||
|
|
111
src/vhd.c
111
src/vhd.c
|
@ -49,6 +49,12 @@
|
||||||
#define VHD_FOOTER_TYPE_DYNAMIC_HARD_DISK 0x00000003
|
#define VHD_FOOTER_TYPE_DYNAMIC_HARD_DISK 0x00000003
|
||||||
#define VHD_FOOTER_TYPE_DIFFER_HARD_DISK 0x00000004
|
#define VHD_FOOTER_TYPE_DIFFER_HARD_DISK 0x00000004
|
||||||
|
|
||||||
|
#define WIM_MAGIC 0x0000004D4957534DULL // "MSWIM\0\0\0"
|
||||||
|
#define WIM_HAS_API_EXTRACT 1
|
||||||
|
#define WIM_HAS_7Z_EXTRACT 2
|
||||||
|
#define WIM_HAS_API_APPLY 4
|
||||||
|
#define WIM_HAS_EXTRACT(r) (r & (WIM_HAS_API_EXTRACT|WIM_HAS_7Z_EXTRACT))
|
||||||
|
|
||||||
#define SECONDS_SINCE_JAN_1ST_2000 946684800
|
#define SECONDS_SINCE_JAN_1ST_2000 946684800
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -92,6 +98,8 @@ typedef struct vhd_footer {
|
||||||
PF_TYPE_DECL(WINAPI, HANDLE, WIMCreateFile, (PWSTR, DWORD, DWORD, DWORD, DWORD, PDWORD));
|
PF_TYPE_DECL(WINAPI, HANDLE, WIMCreateFile, (PWSTR, DWORD, DWORD, DWORD, DWORD, PDWORD));
|
||||||
PF_TYPE_DECL(WINAPI, BOOL, WIMSetTemporaryPath, (HANDLE, PWSTR));
|
PF_TYPE_DECL(WINAPI, BOOL, WIMSetTemporaryPath, (HANDLE, PWSTR));
|
||||||
PF_TYPE_DECL(WINAPI, HANDLE, WIMLoadImage, (HANDLE, DWORD));
|
PF_TYPE_DECL(WINAPI, HANDLE, WIMLoadImage, (HANDLE, DWORD));
|
||||||
|
PF_TYPE_DECL(WINAPI, BOOL, WIMMountImage, (PCWSTR, PCWSTR, DWORD, PCWSTR));
|
||||||
|
PF_TYPE_DECL(WINAPI, BOOL, WIMUnmountImage, (PCWSTR, PCWSTR, DWORD, BOOL));
|
||||||
PF_TYPE_DECL(WINAPI, BOOL, WIMApplyImage, (HANDLE, PCWSTR, DWORD));
|
PF_TYPE_DECL(WINAPI, BOOL, WIMApplyImage, (HANDLE, PCWSTR, DWORD));
|
||||||
PF_TYPE_DECL(WINAPI, BOOL, WIMExtractImagePath, (HANDLE, PWSTR, PWSTR, DWORD));
|
PF_TYPE_DECL(WINAPI, BOOL, WIMExtractImagePath, (HANDLE, PWSTR, PWSTR, DWORD));
|
||||||
PF_TYPE_DECL(WINAPI, BOOL, WIMGetImageInformation, (HANDLE, PVOID, PDWORD));
|
PF_TYPE_DECL(WINAPI, BOOL, WIMGetImageInformation, (HANDLE, PVOID, PDWORD));
|
||||||
|
@ -105,6 +113,7 @@ HANDLE apply_wim_thread = NULL;
|
||||||
extern int default_thread_priority;
|
extern int default_thread_priority;
|
||||||
|
|
||||||
static uint8_t wim_flags = 0;
|
static uint8_t wim_flags = 0;
|
||||||
|
static wchar_t wmount_path[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;
|
||||||
|
@ -268,7 +277,6 @@ BOOL IsCompressedBootableImage(const char* path)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL IsBootableImage(const char* path)
|
BOOL IsBootableImage(const char* path)
|
||||||
{
|
{
|
||||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||||
|
@ -277,7 +285,8 @@ BOOL IsBootableImage(const char* path)
|
||||||
DWORD size;
|
DWORD size;
|
||||||
size_t i;
|
size_t i;
|
||||||
uint32_t checksum, old_checksum;
|
uint32_t checksum, old_checksum;
|
||||||
LARGE_INTEGER ptr;
|
uint64_t wim_magic = 0;
|
||||||
|
LARGE_INTEGER ptr = { 0 };
|
||||||
BOOL is_bootable_img = FALSE;
|
BOOL is_bootable_img = FALSE;
|
||||||
|
|
||||||
uprintf("Disk image analysis:");
|
uprintf("Disk image analysis:");
|
||||||
|
@ -297,6 +306,11 @@ BOOL IsBootableImage(const char* path)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
img_report.image_size = (uint64_t)liImageSize.QuadPart;
|
img_report.image_size = (uint64_t)liImageSize.QuadPart;
|
||||||
|
size = sizeof(wim_magic);
|
||||||
|
SetFilePointerEx(handle, ptr, NULL, FILE_BEGIN);
|
||||||
|
img_report.is_windows_img = ReadFile(handle, &wim_magic, size, &size, NULL) && (wim_magic == WIM_MAGIC);
|
||||||
|
if (img_report.is_windows_img)
|
||||||
|
goto out;
|
||||||
|
|
||||||
size = sizeof(vhd_footer);
|
size = sizeof(vhd_footer);
|
||||||
if ((img_report.compression_type == BLED_COMPRESSION_NONE) && (img_report.image_size >= (512 + size))) {
|
if ((img_report.compression_type == BLED_COMPRESSION_NONE) && (img_report.image_size >= (512 + size))) {
|
||||||
|
@ -335,14 +349,9 @@ out:
|
||||||
return is_bootable_img;
|
return is_bootable_img;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WIM_HAS_API_EXTRACT 1
|
|
||||||
#define WIM_HAS_7Z_EXTRACT 2
|
|
||||||
#define WIM_HAS_API_APPLY 4
|
|
||||||
#define WIM_HAS_EXTRACT(r) (r & (WIM_HAS_API_EXTRACT|WIM_HAS_7Z_EXTRACT))
|
|
||||||
|
|
||||||
// Find out if we have any way to extract/apply WIM files on this platform
|
// Find out if we have any way to extract/apply WIM files on this platform
|
||||||
// Returns a bitfield of the methods we can use (1 = Extract using wimgapi, 2 = Extract using 7-Zip, 4 = Apply using wimgapi)
|
// Returns a bitfield of the methods we can use (1 = Extract using wimgapi, 2 = Extract using 7-Zip, 4 = Apply using wimgapi)
|
||||||
uint8_t WimExtractCheck(void)
|
uint8_t WimExtractCheck(BOOL bSilent)
|
||||||
{
|
{
|
||||||
PF_INIT(WIMCreateFile, Wimgapi);
|
PF_INIT(WIMCreateFile, Wimgapi);
|
||||||
PF_INIT(WIMSetTemporaryPath, Wimgapi);
|
PF_INIT(WIMSetTemporaryPath, Wimgapi);
|
||||||
|
@ -361,19 +370,69 @@ uint8_t WimExtractCheck(void)
|
||||||
if ((wim_flags & WIM_HAS_API_EXTRACT) && pfWIMApplyImage && pfWIMRegisterMessageCallback && pfWIMUnregisterMessageCallback)
|
if ((wim_flags & WIM_HAS_API_EXTRACT) && pfWIMApplyImage && pfWIMRegisterMessageCallback && pfWIMUnregisterMessageCallback)
|
||||||
wim_flags |= WIM_HAS_API_APPLY;
|
wim_flags |= WIM_HAS_API_APPLY;
|
||||||
|
|
||||||
uprintf("WIM extraction method(s) supported: %s%s%s", (wim_flags & WIM_HAS_7Z_EXTRACT)?"7-Zip":
|
suprintf("WIM extraction method(s) supported: %s%s%s", (wim_flags & WIM_HAS_7Z_EXTRACT)?"7-Zip":
|
||||||
((wim_flags & WIM_HAS_API_EXTRACT)?"":"NONE"),
|
((wim_flags & WIM_HAS_API_EXTRACT)?"":"NONE"),
|
||||||
(WIM_HAS_EXTRACT(wim_flags) == (WIM_HAS_API_EXTRACT|WIM_HAS_7Z_EXTRACT))?", ":
|
(WIM_HAS_EXTRACT(wim_flags) == (WIM_HAS_API_EXTRACT|WIM_HAS_7Z_EXTRACT))?", ":
|
||||||
"", (wim_flags & WIM_HAS_API_EXTRACT)?"wimgapi.dll":"");
|
"", (wim_flags & WIM_HAS_API_EXTRACT)?"wimgapi.dll":"");
|
||||||
uprintf("WIM apply method supported: %s", (wim_flags & WIM_HAS_API_APPLY)?"wimgapi.dll":"NONE");
|
suprintf("WIM apply method supported: %s", (wim_flags & WIM_HAS_API_APPLY)?"wimgapi.dll":"NONE");
|
||||||
return wim_flags;
|
return wim_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Looks like Microsoft's idea of "mount" for WIM images is to just *extract* all
|
||||||
|
// files to a mounpoint and pretend it is "mounted", even if you do specify that
|
||||||
|
// you're not planning to change the content. So, yeah, this is both super slow
|
||||||
|
// and super wasteful of space... These calls are a complete waste of time.
|
||||||
|
BOOL WimMountImage(char* pszWimFileName, DWORD dwImageIndex)
|
||||||
|
{
|
||||||
|
BOOL r = FALSE;
|
||||||
|
wconvert(temp_dir);
|
||||||
|
wconvert(pszWimFileName);
|
||||||
|
PF_INIT_OR_OUT(WIMMountImage, Wimgapi);
|
||||||
|
|
||||||
|
if (wmount_path[0] != 0) {
|
||||||
|
uprintf("WimMountImage: An image is already mounted");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (GetTempFileNameW(wtemp_dir, L"Rufus", 0, wmount_path) == 0) {
|
||||||
|
uprintf("WimMountImage: Can not create mount directory");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
DeleteFileW(wmount_path);
|
||||||
|
if (!CreateDirectoryW(wmount_path, 0)) {
|
||||||
|
uprintf("WimMountImage: Can not create mount directory");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = pfWIMMountImage(wmount_path, wpszWimFileName, dwImageIndex, NULL);
|
||||||
|
if (!r)
|
||||||
|
uprintf("Could not mount %S on %S: %s", wpszWimFileName, wmount_path, WindowsErrorString());
|
||||||
|
|
||||||
|
out:
|
||||||
|
wfree(temp_dir);
|
||||||
|
wfree(pszWimFileName);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WimUnmountImage(void)
|
||||||
|
{
|
||||||
|
BOOL r = FALSE;
|
||||||
|
PF_INIT_OR_OUT(WIMUnmountImage, Wimgapi);
|
||||||
|
if (wmount_path[0] == 0) {
|
||||||
|
uprintf("WimUnmountImage: No image is mounted");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
r = pfWIMUnmountImage(wmount_path, NULL, 0, FALSE);
|
||||||
|
if (!r)
|
||||||
|
uprintf("Could not unmount %S: %s", wmount_path, WindowsErrorString());
|
||||||
|
wmount_path[0] = 0;
|
||||||
|
out:
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
// NB: if you want progress from a WIM callback, you must run the WIM API call in its own thread
|
// NB: if you want progress from a WIM callback, you must run the WIM API call in its own thread
|
||||||
// (which we don't do here) as it won't work otherwise. Thanks go to Erwan for figuring this out!
|
// (which we don't do here) as it won't work otherwise. Thanks go to Erwan for figuring this out!
|
||||||
BOOL WimExtractFile_API(const char* image, int index, const char* src, const char* dst)
|
BOOL WimExtractFile_API(const char* image, int index, const char* src, const char* dst, BOOL bSilent)
|
||||||
{
|
{
|
||||||
static char* index_name = "[1].xml";
|
static char* index_name = "[1].xml";
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
|
@ -393,7 +452,7 @@ BOOL WimExtractFile_API(const char* image, int index, const char* src, const cha
|
||||||
PF_INIT_OR_OUT(WIMExtractImagePath, Wimgapi);
|
PF_INIT_OR_OUT(WIMExtractImagePath, Wimgapi);
|
||||||
PF_INIT_OR_OUT(WIMCloseHandle, Wimgapi);
|
PF_INIT_OR_OUT(WIMCloseHandle, Wimgapi);
|
||||||
|
|
||||||
uprintf("Opening: %s:[%d] (API)", image, index);
|
suprintf("Opening: %s:[%d] (API)", image, index);
|
||||||
if (GetTempPathW(ARRAYSIZE(wtemp), wtemp) == 0) {
|
if (GetTempPathW(ARRAYSIZE(wtemp), wtemp) == 0) {
|
||||||
uprintf(" Could not fetch temp path: %s", WindowsErrorString());
|
uprintf(" Could not fetch temp path: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -415,7 +474,7 @@ BOOL WimExtractFile_API(const char* image, int index, const char* src, const cha
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uprintf("Extracting: %s (From %s)", dst, src);
|
suprintf("Extracting: %s (From %s)", dst, src);
|
||||||
if (safe_strcmp(src, index_name) == 0) {
|
if (safe_strcmp(src, index_name) == 0) {
|
||||||
if (!pfWIMGetImageInformation(hWim, &wim_info, &dw)) {
|
if (!pfWIMGetImageInformation(hWim, &wim_info, &dw)) {
|
||||||
uprintf(" Could not access WIM info: %s", WindowsErrorString());
|
uprintf(" Could not access WIM info: %s", WindowsErrorString());
|
||||||
|
@ -424,7 +483,7 @@ BOOL WimExtractFile_API(const char* image, int index, const char* src, const cha
|
||||||
hFile = CreateFileW(wdst, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
|
hFile = CreateFileW(wdst, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
|
||||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if ((hFile == INVALID_HANDLE_VALUE) || (!WriteFile(hFile, wim_info, dw, &dw, NULL))) {
|
if ((hFile == INVALID_HANDLE_VALUE) || (!WriteFile(hFile, wim_info, dw, &dw, NULL))) {
|
||||||
uprintf(" Could not extract file: %s", WindowsErrorString());
|
suprintf(" Could not extract file: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -434,7 +493,7 @@ BOOL WimExtractFile_API(const char* image, int index, const char* src, const cha
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!pfWIMExtractImagePath(hImage, wsrc, wdst, 0)) {
|
if (!pfWIMExtractImagePath(hImage, wsrc, wdst, 0)) {
|
||||||
uprintf(" Could not extract file: %s", WindowsErrorString());
|
suprintf(" Could not extract file: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,7 +501,7 @@ BOOL WimExtractFile_API(const char* image, int index, const char* src, const cha
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if ((hImage != NULL) || (hWim != NULL)) {
|
if ((hImage != NULL) || (hWim != NULL)) {
|
||||||
uprintf("Closing: %s", image);
|
suprintf("Closing: %s", image);
|
||||||
if (hImage != NULL) pfWIMCloseHandle(hImage);
|
if (hImage != NULL) pfWIMCloseHandle(hImage);
|
||||||
if (hWim != NULL) pfWIMCloseHandle(hWim);
|
if (hWim != NULL) pfWIMCloseHandle(hWim);
|
||||||
}
|
}
|
||||||
|
@ -454,7 +513,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract a file from a WIM image using 7-Zip
|
// Extract a file from a WIM image using 7-Zip
|
||||||
BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char* dst)
|
BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char* dst, BOOL bSilent)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -462,7 +521,7 @@ BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char
|
||||||
char tmpdst[MAX_PATH];
|
char tmpdst[MAX_PATH];
|
||||||
char index_prefix[] = "#\\";
|
char index_prefix[] = "#\\";
|
||||||
|
|
||||||
uprintf("Opening: %s:[%d] (7-Zip)", image, index);
|
suprintf("Opening: %s:[%d] (7-Zip)", image, index);
|
||||||
|
|
||||||
if ((image == NULL) || (src == NULL) || (dst == NULL))
|
if ((image == NULL) || (src == NULL) || (dst == NULL))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -471,7 +530,7 @@ BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char
|
||||||
// that this breaks!
|
// that this breaks!
|
||||||
index_prefix[0] = '0' + index;
|
index_prefix[0] = '0' + index;
|
||||||
|
|
||||||
uprintf("Extracting: %s (From %s)", dst, src);
|
suprintf("Extracting: %s (From %s)", dst, src);
|
||||||
|
|
||||||
// 7z has a quirk where the image index MUST be specified if a
|
// 7z has a quirk where the image index MUST be specified if a
|
||||||
// WIM has multiple indexes, but it MUST be removed if there is
|
// WIM has multiple indexes, but it MUST be removed if there is
|
||||||
|
@ -500,13 +559,13 @@ BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n >= 2) {
|
if (n >= 2) {
|
||||||
uprintf(" 7z.exe did not extract %s", tmpdst);
|
suprintf(" 7z.exe did not extract %s", tmpdst);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// coverity[toctou]
|
// coverity[toctou]
|
||||||
if (rename(tmpdst, dst) != 0) {
|
if (!MoveFileExU(tmpdst, dst, MOVEFILE_REPLACE_EXISTING)) {
|
||||||
uprintf(" Could not rename %s to %s: errno %d", tmpdst, dst, errno);
|
uprintf(" Could not rename %s to %s: %s", tmpdst, dst, WindowsErrorString());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,17 +573,17 @@ BOOL WimExtractFile_7z(const char* image, int index, const char* src, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract a file from a WIM image
|
// Extract a file from a WIM image
|
||||||
BOOL WimExtractFile(const char* image, int index, const char* src, const char* dst)
|
BOOL WimExtractFile(const char* image, int index, const char* src, const char* dst, BOOL bSilent)
|
||||||
{
|
{
|
||||||
if ((wim_flags == 0) && (!WIM_HAS_EXTRACT(WimExtractCheck())))
|
if ((wim_flags == 0) && (!WIM_HAS_EXTRACT(WimExtractCheck(TRUE))))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ((image == NULL) || (src == NULL) || (dst == NULL))
|
if ((image == NULL) || (src == NULL) || (dst == NULL))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// Prefer 7-Zip as, unsurprisingly, it's faster than the Microsoft way,
|
// Prefer 7-Zip as, unsurprisingly, it's faster than the Microsoft way,
|
||||||
// but allow fallback if 7-Zip doesn't succeed
|
// but allow fallback if 7-Zip doesn't succeed
|
||||||
return ( ((wim_flags & WIM_HAS_7Z_EXTRACT) && WimExtractFile_7z(image, index, src, dst))
|
return ( ((wim_flags & WIM_HAS_7Z_EXTRACT) && WimExtractFile_7z(image, index, src, dst, bSilent))
|
||||||
|| ((wim_flags & WIM_HAS_API_EXTRACT) && WimExtractFile_API(image, index, src, dst)) );
|
|| ((wim_flags & WIM_HAS_API_EXTRACT) && WimExtractFile_API(image, index, src, dst, bSilent)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply image functionality
|
// Apply image functionality
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue