1
1
Fork 0
mirror of https://github.com/pbatard/rufus.git synced 2024-08-14 23:57:05 +00:00

[togo] add newer install.wim + install.esd support

* With no thanks whatsoever to Microsoft for *NOT* documenting that you need
  to pass flag 0x2000000 to WIMCreateFile() if you want to avoid an open error.
  One has to wonder if Microsoft isn't deliberately adding *BULLSHIT FLAGS*
  that only they know of, to hinder competing third-party tools...
This commit is contained in:
Pete Batard 2019-01-08 18:30:07 +00:00
parent befe2606cf
commit 521034da99
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
7 changed files with 77 additions and 47 deletions

View file

@ -330,6 +330,8 @@ t MSG_126 "Set the partition size units."
t MSG_127 "Do not show this message again" t MSG_127 "Do not show this message again"
t MSG_128 "Important notice about Secure Boot" t MSG_128 "Important notice about Secure Boot"
t MSG_129 "You have just created a media that uses the UEFI:NTFS bootloader. Please remember that, to boot this media, YOU MUST DISABLE SECURE BOOT.\nFor details on why this is necessary, see the 'More Information' button below." t MSG_129 "You have just created a media that uses the UEFI:NTFS bootloader. Please remember that, to boot this media, YOU MUST DISABLE SECURE BOOT.\nFor details on why this is necessary, see the 'More Information' button below."
t MSG_130 "Windows image selection"
t MSG_131 "This ISO contains multiple Windows images.\nPlease select the one you wish to use for installation:"
t MSG_150 "Type of computer you plan to use this bootable drive with. It is your responsibility to determine whether " t MSG_150 "Type of computer you plan to use this bootable drive with. It is your responsibility to determine whether "
"your target is of BIOS or UEFI type before you start creating the drive, as it may fail to boot otherwise." "your target is of BIOS or UEFI type before you start creating the drive, as it may fail to boot otherwise."
# You shouldn't translate 'Legacy Mode' as this is an option that usually appears in English in the UEFI settings. # You shouldn't translate 'Legacy Mode' as this is an option that usually appears in English in the UEFI settings.

View file

@ -61,7 +61,7 @@ static float format_percent = 0.0f;
static int task_number = 0; static int task_number = 0;
extern const int nb_steps[FS_MAX]; extern const int nb_steps[FS_MAX];
extern uint32_t dur_mins, dur_secs; extern uint32_t dur_mins, dur_secs;
static int fs_index = 0, wintogo_index = -1; static int fs_index = 0, wintogo_index = -1, wininst_index = 0;
extern BOOL force_large_fat32, enable_ntfs_compression, lock_drive, zero_drive, fast_zeroing, enable_file_indexing, write_as_image; extern BOOL force_large_fat32, enable_ntfs_compression, lock_drive, zero_drive, fast_zeroing, enable_file_indexing, write_as_image;
uint8_t *grub2_buf = NULL; uint8_t *grub2_buf = NULL;
long grub2_len; long grub2_len;
@ -1298,30 +1298,45 @@ out:
return r; return r;
} }
// Checks which versions of Windows are available in an install.wim image // Checks which versions of Windows are available in an install image
// to set our extraction index. Asks the user to select one if needed. // 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. // 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, image[128];
char tmp_path[MAX_PATH] = "", xml_file[MAX_PATH] = ""; char tmp_path[MAX_PATH] = "", xml_file[MAX_PATH] = "";
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;
BOOL bNonStandard = FALSE; BOOL bNonStandard = FALSE;
// Sanity checks // Sanity checks
wintogo_index = -1; wintogo_index = -1;
wininst_index = 0;
if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck() & 4) == 0) || if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck() & 4) == 0) ||
(ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)) != FS_NTFS)) { (ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)) != FS_NTFS)) {
return FALSE; 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 = SelectionDialog(lmprintf(MSG_130), lmprintf(MSG_131), install_names, img_report.wininst_index);
if (wininst_index < 0)
return -2;
wininst_index--;
if ((wininst_index < 0) || (wininst_index >= MAX_WININST))
wininst_index = 0;
}
// Mount the install.wim image, that resides on the ISO // Mount the install.wim image, that resides on the ISO
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 selection"); uprintf("Could not mount ISO for Windows To Go selection");
return FALSE; return FALSE;
} }
static_sprintf(image, "%s%s", mounted_iso, &img_report.install_wim_path[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 ((GetTempPathU(sizeof(tmp_path), tmp_path) == 0)
@ -1335,7 +1350,7 @@ int SetWinToGoIndex(void)
// 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(image, 0, "[1].xml", xml_file)) {
uprintf("Failed to acquire WIM index"); uprintf("Could not acquire WIM index");
goto out; goto out;
} }
@ -1428,7 +1443,7 @@ static BOOL SetupWinToGo(const char* drive_name, BOOL use_ms_efi)
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(image, "%s%s", mounted_iso, &img_report.install_wim_path[2]); static_sprintf(image, "%s%s", mounted_iso, &img_report.wininst_path[wininst_index][2]);
uprintf("Mounted ISO as '%s'", mounted_iso); 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
@ -2112,7 +2127,7 @@ DWORD WINAPI FormatThread(void* param)
// EFI mode selected, with no 'boot###.efi' but Windows 7 x64's 'bootmgr.efi' (bit #0) // EFI mode selected, with no 'boot###.efi' but Windows 7 x64's 'bootmgr.efi' (bit #0)
if ((tt == TT_UEFI) && HAS_WIN7_EFI(img_report)) { if ((tt == TT_UEFI) && HAS_WIN7_EFI(img_report)) {
PrintInfoDebug(0, MSG_232); PrintInfoDebug(0, MSG_232);
img_report.install_wim_path[0] = drive_name[0]; img_report.wininst_path[0][0] = drive_name[0];
efi_dst[0] = drive_name[0]; efi_dst[0] = drive_name[0];
efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0; efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0;
if (!CreateDirectoryA(efi_dst, 0)) { if (!CreateDirectoryA(efi_dst, 0)) {
@ -2120,7 +2135,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.install_wim_path, 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) { if (!WimExtractFile(img_report.wininst_path[0], 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) {
uprintf("Failed to setup Win7 EFI boot\n"); uprintf("Failed to setup Win7 EFI boot\n");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
} }

View file

@ -77,8 +77,8 @@ static const char* ldlinux_name = "ldlinux.sys";
static const char* ldlinux_c32 = "ldlinux.c32"; static const char* ldlinux_c32 = "ldlinux.c32";
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[] = { "bootia32.efi", "bootia64.efi", "bootx64.efi", "bootarm.efi", "bootaa64.efi", "bootebc.efi" };
static const char* install_wim_path = "/sources"; static const char* sources_str = "/sources";
static const char* install_wim_name[] = { "install.wim", "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/)
// If the disc was mastered properly, GRUB/EFI will take care of itself // If the disc was mastered properly, GRUB/EFI will take care of itself
static const char* grub_dirname = "/boot/grub/i386-pc"; static const char* grub_dirname = "/boot/grub/i386-pc";
@ -223,11 +223,16 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t file_length, const
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
} }
// Check for "install.wim" or "install.swm" in "/sources" // Check for "install.###" in "###/sources/"
if ((install_wim_path != NULL) && (safe_stricmp(psz_dirname, install_wim_path) == 0)) { if (safe_stricmp(&psz_dirname[max(0, safe_strlen(psz_dirname) - strlen(sources_str))], sources_str) == 0) {
for (i=0; i<ARRAYSIZE(install_wim_name); i++) for (i = 0; i < ARRAYSIZE(wininst_name); i++) {
if (safe_stricmp(psz_basename, install_wim_name[i]) == 0) if (safe_stricmp(psz_basename, wininst_name[i]) == 0) {
static_sprintf(img_report.install_wim_path, "?:\\%s\\%s", &install_wim_path[1], install_wim_name[i]); if (img_report.wininst_index < MAX_WININST) {
static_sprintf(img_report.wininst_path[img_report.wininst_index], "?:%s", psz_fullpath);
img_report.wininst_index++;
}
}
}
} }
// Check for PE (XP) specific files in "/i386", "/amd64" or "/minint" // Check for PE (XP) specific files in "/i386", "/amd64" or "/minint"
@ -894,8 +899,8 @@ out:
_unlinkU(tmp_sif); _unlinkU(tmp_sif);
safe_free(tmp); safe_free(tmp);
} }
if (HAS_INSTALL_WIM(img_report)) { if (HAS_WININST(img_report)) {
img_report.install_wim_version = GetInstallWimVersion(src_iso); img_report.wininst_version = GetInstallWimVersion(src_iso);
} }
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
@ -1079,7 +1084,7 @@ uint32_t GetInstallWimVersion(const char* iso)
udf_dirent_t *p_udf_root = NULL, *p_udf_file = NULL; udf_dirent_t *p_udf_root = NULL, *p_udf_file = NULL;
iso9660_stat_t *p_statbuf = NULL; iso9660_stat_t *p_statbuf = NULL;
wim_path = safe_strdup(&img_report.install_wim_path[2]); wim_path = safe_strdup(&img_report.wininst_path[0][2]);
if (wim_path == NULL) if (wim_path == NULL)
goto out; goto out;
// UDF indiscriminately accepts slash or backslash delimiters, // UDF indiscriminately accepts slash or backslash delimiters,

View file

@ -959,6 +959,7 @@ static void CALLBACK BlockingTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD
#define PRINT_ISO_PROP(b, ...) do {if (b) uprintf(__VA_ARGS__);} while(0) #define PRINT_ISO_PROP(b, ...) do {if (b) uprintf(__VA_ARGS__);} while(0)
static void DisplayISOProps(void) static void DisplayISOProps(void)
{ {
static char* inst_str = "[1/#]";
int i; int i;
uprintf("ISO label: '%s'", img_report.label); uprintf("ISO label: '%s'", img_report.label);
@ -993,13 +994,12 @@ static void DisplayISOProps(void)
PRINT_ISO_PROP(HAS_BOOTMGR(img_report), " Uses: Bootmgr (%s)", PRINT_ISO_PROP(HAS_BOOTMGR(img_report), " Uses: Bootmgr (%s)",
HAS_BOOTMGR_BIOS(img_report) ? (HAS_BOOTMGR_EFI(img_report) ? "BIOS and UEFI" : "BIOS only") : "UEFI only"); HAS_BOOTMGR_BIOS(img_report) ? (HAS_BOOTMGR_EFI(img_report) ? "BIOS and UEFI" : "BIOS only") : "UEFI only");
PRINT_ISO_PROP(HAS_WINPE(img_report), " Uses: WinPE %s", (img_report.uses_minint) ? "(with /minint)" : ""); PRINT_ISO_PROP(HAS_WINPE(img_report), " Uses: WinPE %s", (img_report.uses_minint) ? "(with /minint)" : "");
if (HAS_INSTALL_WIM(img_report)) { if (HAS_WININST(img_report)) {
uprintf(" Uses: Install.wim (version %d.%d.%d)", (img_report.install_wim_version >> 24) & 0xff, inst_str[3] = '0' + img_report.wininst_index;
(img_report.install_wim_version >> 16) & 0xff, (img_report.install_wim_version >> 8) & 0xff); uprintf(" Uses: Install.%s%s (version %d.%d.%d%s)", &img_report.wininst_path[0][strlen(img_report.wininst_path[0]) - 3],
// Microsoft somehow managed to make their ESD WIMs incompatible with their own APIs (img_report.wininst_index > 1) ? inst_str : "", (img_report.wininst_version >> 24) & 0xff,
// (yes, EVEN the Windows 10 APIs), so we must filter them out... (img_report.wininst_version >> 16) & 0xff, (img_report.wininst_version >> 8) & 0xff,
if (img_report.install_wim_version >= MAX_WIM_VERSION) (img_report.wininst_version >= SPECIAL_WIM_VERSION) ? "+": "");
uprintf(" Note: This WIM version is NOT compatible with Windows To Go");
} }
PRINT_ISO_PROP(img_report.has_symlinks, " Note: This ISO uses symbolic links, which will not be replicated due to file system limitations."); PRINT_ISO_PROP(img_report.has_symlinks, " Note: This ISO uses symbolic links, which will not be replicated due to file system limitations.");
PRINT_ISO_PROP(img_report.has_symlinks, " Because of this, some features from this image may not work..."); PRINT_ISO_PROP(img_report.has_symlinks, " Because of this, some features from this image may not work...");
@ -1196,7 +1196,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
(!HAS_SYSLINUX(img_report) || (SL_MAJOR(img_report.sl_version) <= 5))) (!HAS_SYSLINUX(img_report) || (SL_MAJOR(img_report.sl_version) <= 5)))
|| ((IS_FAT(fs)) && (!HAS_SYSLINUX(img_report)) && (!allow_dual_uefi_bios) && !IS_EFI_BOOTABLE(img_report) && || ((IS_FAT(fs)) && (!HAS_SYSLINUX(img_report)) && (!allow_dual_uefi_bios) && !IS_EFI_BOOTABLE(img_report) &&
(!HAS_REACTOS(img_report)) && !HAS_KOLIBRIOS(img_report) && (!HAS_GRUB(img_report))) (!HAS_REACTOS(img_report)) && !HAS_KOLIBRIOS(img_report) && (!HAS_GRUB(img_report)))
|| ((IS_FAT(fs)) && (HAS_WINDOWS(img_report) || HAS_INSTALL_WIM(img_report)) && (!allow_dual_uefi_bios)) ) { || ((IS_FAT(fs)) && (HAS_WINDOWS(img_report) || HAS_WININST(img_report)) && (!allow_dual_uefi_bios)) ) {
// Incompatible FS and ISO // Incompatible FS and ISO
MessageBoxExU(hMainDialog, lmprintf(MSG_096), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid); MessageBoxExU(hMainDialog, lmprintf(MSG_096), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
goto out; goto out;

View file

@ -71,6 +71,7 @@
#define MAX_GUID_STRING_LENGTH 40 #define MAX_GUID_STRING_LENGTH 40
#define MAX_GPT_PARTITIONS 128 #define MAX_GPT_PARTITIONS 128
#define MAX_SECTORS_TO_CLEAR 128 // nb sectors to zap when clearing the MBR/GPT (must be >34) #define MAX_SECTORS_TO_CLEAR 128 // nb sectors to zap when clearing the MBR/GPT (must be >34)
#define MAX_WININST 4 // Max number of install[.wim|.esd] we can handle on an image
#define MBR_UEFI_MARKER 0x49464555 // 'U', 'E', 'F', 'I', as a 32 bit little endian longword #define MBR_UEFI_MARKER 0x49464555 // 'U', 'E', 'F', 'I', as a 32 bit little endian longword
#define MORE_INFO_URL 0xFFFF #define MORE_INFO_URL 0xFFFF
#define STATUS_MSG_TIMEOUT 3500 // How long should cheat mode messages appear for on the status bar #define STATUS_MSG_TIMEOUT 3500 // How long should cheat mode messages appear for on the status bar
@ -287,7 +288,7 @@ enum checksum_type {
#define WINPE_I386 0x0007 #define WINPE_I386 0x0007
#define WINPE_AMD64 0x0023 #define WINPE_AMD64 0x0023
#define WINPE_MININT 0x01C0 #define WINPE_MININT 0x01C0
#define MAX_WIM_VERSION 0x000E0000 #define SPECIAL_WIM_VERSION 0x000E0000
#define HAS_KOLIBRIOS(r) (r.has_kolibrios) #define HAS_KOLIBRIOS(r) (r.has_kolibrios)
#define HAS_REACTOS(r) (r.reactos_path[0] != 0) #define HAS_REACTOS(r) (r.reactos_path[0] != 0)
#define HAS_GRUB(r) ((r.has_grub2) || (r.has_grub4dos)) #define HAS_GRUB(r) ((r.has_grub2) || (r.has_grub4dos))
@ -295,33 +296,34 @@ enum checksum_type {
#define HAS_BOOTMGR_BIOS(r) (r.has_bootmgr) #define HAS_BOOTMGR_BIOS(r) (r.has_bootmgr)
#define HAS_BOOTMGR_EFI(r) (r.has_bootmgr_efi) #define HAS_BOOTMGR_EFI(r) (r.has_bootmgr_efi)
#define HAS_BOOTMGR(r) (HAS_BOOTMGR_BIOS(r) || HAS_BOOTMGR_EFI(r)) #define HAS_BOOTMGR(r) (HAS_BOOTMGR_BIOS(r) || HAS_BOOTMGR_EFI(r))
#define HAS_INSTALL_WIM(r) (r.install_wim_path[0] != 0) #define HAS_WININST(r) (r.wininst_index != 0)
#define HAS_WINPE(r) (((r.winpe & WINPE_I386) == WINPE_I386)||((r.winpe & WINPE_AMD64) == WINPE_AMD64)||((r.winpe & WINPE_MININT) == WINPE_MININT)) #define HAS_WINPE(r) (((r.winpe & WINPE_I386) == WINPE_I386)||((r.winpe & WINPE_AMD64) == WINPE_AMD64)||((r.winpe & WINPE_MININT) == WINPE_MININT))
#define HAS_WINDOWS(r) (HAS_BOOTMGR(r) || (r.uses_minint) || HAS_WINPE(r)) #define HAS_WINDOWS(r) (HAS_BOOTMGR(r) || (r.uses_minint) || HAS_WINPE(r))
#define HAS_WIN7_EFI(r) ((r.has_efi == 1) && HAS_INSTALL_WIM(r)) #define HAS_WIN7_EFI(r) ((r.has_efi == 1) && HAS_WININST(r))
#define HAS_EFI_IMG(r) (r.efi_img_path[0] != 0) #define HAS_EFI_IMG(r) (r.efi_img_path[0] != 0)
#define IS_DD_BOOTABLE(r) (r.is_bootable_img) #define IS_DD_BOOTABLE(r) (r.is_bootable_img)
#define IS_EFI_BOOTABLE(r) (r.has_efi != 0) #define IS_EFI_BOOTABLE(r) (r.has_efi != 0)
#define IS_BIOS_BOOTABLE(r) (HAS_BOOTMGR(r) || HAS_SYSLINUX(r) || HAS_WINPE(r) || HAS_GRUB(r) || HAS_REACTOS(r) || HAS_KOLIBRIOS(r)) #define IS_BIOS_BOOTABLE(r) (HAS_BOOTMGR(r) || HAS_SYSLINUX(r) || HAS_WINPE(r) || HAS_GRUB(r) || HAS_REACTOS(r) || HAS_KOLIBRIOS(r))
#define HAS_WINTOGO(r) (HAS_BOOTMGR(r) && IS_EFI_BOOTABLE(r) && HAS_INSTALL_WIM(r) && (r.install_wim_version < MAX_WIM_VERSION)) #define HAS_WINTOGO(r) (HAS_BOOTMGR(r) && IS_EFI_BOOTABLE(r) && HAS_WININST(r))
#define HAS_PERSISTENCE(r) (r.has_casper) #define HAS_PERSISTENCE(r) (r.has_casper)
#define IS_FAT(fs) ((fs == FS_FAT16) || (fs == FS_FAT32)) #define IS_FAT(fs) ((fs == FS_FAT16) || (fs == FS_FAT32))
typedef struct { typedef struct {
char label[192]; /* 3*64 to account for UTF-8 */ char label[192]; // 3*64 to account for UTF-8
char usb_label[192]; /* converted USB label for workaround */ char usb_label[192]; // converted USB label for workaround
char cfg_path[128]; /* path to the ISO's isolinux.cfg */ char cfg_path[128]; // path to the ISO's isolinux.cfg
char reactos_path[128]; /* path to the ISO's freeldr.sys or setupldr.sys */ char reactos_path[128]; // path to the ISO's freeldr.sys or setupldr.sys
char install_wim_path[64]; /* path to install.wim or install.swm */ char wininst_path[MAX_WININST][64]; // path to the Windows install image(s)
char efi_img_path[128]; /* path to an efi.img file */ char efi_img_path[128]; // path to an efi.img file
uint64_t image_size; uint64_t image_size;
uint64_t projected_size; uint64_t projected_size;
int64_t mismatch_size; int64_t mismatch_size;
uint32_t install_wim_version; uint32_t wininst_version;
BOOLEAN is_iso; BOOLEAN is_iso;
BOOLEAN is_bootable_img; BOOLEAN is_bootable_img;
uint16_t winpe; uint16_t winpe;
uint8_t has_efi; uint8_t has_efi;
uint8_t wininst_index;
BOOLEAN has_4GB_file; BOOLEAN has_4GB_file;
BOOLEAN has_long_filename; BOOLEAN has_long_filename;
BOOLEAN has_symlinks; BOOLEAN has_symlinks;

View file

@ -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.5.1436" CAPTION "Rufus 3.5.1437"
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
@ -394,8 +394,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,5,1436,0 FILEVERSION 3,5,1437,0
PRODUCTVERSION 3,5,1436,0 PRODUCTVERSION 3,5,1437,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -413,13 +413,13 @@ BEGIN
VALUE "Comments", "https://akeo.ie" VALUE "Comments", "https://akeo.ie"
VALUE "CompanyName", "Akeo Consulting" VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "3.5.1436" VALUE "FileVersion", "3.5.1437"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2018 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2018 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus-3.5.exe" VALUE "OriginalFilename", "rufus-3.5.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.5.1436" VALUE "ProductVersion", "3.5.1437"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -88,6 +88,7 @@ typedef struct vhd_footer {
// WIM API Prototypes // WIM API Prototypes
#define WIM_GENERIC_READ GENERIC_READ #define WIM_GENERIC_READ GENERIC_READ
#define WIM_OPEN_EXISTING OPEN_EXISTING #define WIM_OPEN_EXISTING OPEN_EXISTING
#define WIM_UNDOCUMENTED_BULLSHIT 0x20000000
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));
@ -396,7 +397,12 @@ BOOL WimExtractFile_API(const char* image, int index, const char* src, const cha
goto out; goto out;
} }
hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING, 0, 0, &dw); // Thanks to dism++ for figuring out that you can use UNDOCUMENTED FLAG 0x20000000
// to open newer install.wim/install.esd images, without running into obnoxious error:
// [0x0000000B] An attempt was made to load a program with an incorrect format.
// No thanks to Microsoft for NOT DOCUMENTING THEIR UTTER BULLSHIT with the WIM API!
hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING,
(img_report.wininst_version >= SPECIAL_WIM_VERSION) ? WIM_UNDOCUMENTED_BULLSHIT : 0, 0, NULL);
if (hWim == NULL) { if (hWim == NULL) {
uprintf(" Could not access image: %s", WindowsErrorString()); uprintf(" Could not access image: %s", WindowsErrorString());
goto out; goto out;
@ -643,7 +649,6 @@ DWORD WINAPI WimProgressCallback(DWORD dwMsgId, WPARAM wParam, LPARAM lParam, PV
static DWORD WINAPI WimApplyImageThread(LPVOID param) static DWORD WINAPI WimApplyImageThread(LPVOID param)
{ {
BOOL r = FALSE; BOOL r = FALSE;
DWORD dw = 0;
HANDLE hWim = NULL; HANDLE hWim = NULL;
HANDLE hImage = NULL; HANDLE hImage = NULL;
wchar_t wtemp[MAX_PATH] = {0}; wchar_t wtemp[MAX_PATH] = {0};
@ -670,7 +675,8 @@ static DWORD WINAPI WimApplyImageThread(LPVOID param)
goto out; goto out;
} }
hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING, 0, 0, &dw); hWim = pfWIMCreateFile(wimage, WIM_GENERIC_READ, WIM_OPEN_EXISTING,
(img_report.wininst_version >= SPECIAL_WIM_VERSION) ? WIM_UNDOCUMENTED_BULLSHIT : 0, 0, NULL);
if (hWim == NULL) { if (hWim == NULL) {
uprintf(" Could not access image: %s", WindowsErrorString()); uprintf(" Could not access image: %s", WindowsErrorString());
goto out; goto out;