[iso] disable To Go mode for Windows 10 ESD ISOs

* Microsoft somehow managed to make their ESD WIMs incompatible with their own APIs
  (yes, EVEN the Windows 10 WIM API), so we must filter them out...
This commit is contained in:
Pete Batard 2015-08-27 18:22:27 +01:00
parent dd5d6faed3
commit cc10821361
4 changed files with 101 additions and 6 deletions

View File

@ -52,6 +52,8 @@
CdIo_t* cdio_open (const char* psz_source, driver_id_t driver_id) {return NULL;}
void cdio_destroy (CdIo_t* p_cdio) {}
uint32_t GetInstallWimVersion(const char* iso);
typedef struct {
BOOLEAN is_syslinux_cfg;
BOOLEAN is_grub_cfg;
@ -839,6 +841,9 @@ out:
_unlink(tmp_sif);
safe_free(tmp);
}
if (HAS_INSTALL_WIM(iso_report)) {
iso_report.install_wim_version = GetInstallWimVersion(src_iso);
}
if (iso_report.has_grub2) {
// In case we have a GRUB2 based iso, we extract boot/grub/i386-pc/normal.mod to parse its version
iso_report.grub2_version[0] = 0;
@ -1008,6 +1013,74 @@ out:
return r;
}
uint32_t GetInstallWimVersion(const char* iso)
{
char *wim_path = NULL, *p, buf[UDF_BLOCKSIZE] = { 0 };
uint32_t* wim_header = (uint32_t*)buf, r = 0xffffffff;
iso9660_t* p_iso = NULL;
udf_t* p_udf = NULL;
udf_dirent_t *p_udf_root = NULL, *p_udf_file = NULL;
iso9660_stat_t *p_statbuf = NULL;
wim_path = safe_strdup(&iso_report.install_wim_path[2]);
for (p = wim_path; p != 0; p++)
if (*p == '\\') *p = '/';
/* First try to open as UDF - fallback to ISO if it failed */
p_udf = udf_open(iso);
if (p_udf == NULL)
goto try_iso;
p_udf_root = udf_get_root(p_udf, true, 0);
if (p_udf_root == NULL) {
uprintf("Could not locate UDF root directory\n");
goto out;
}
p_udf_file = udf_fopen(p_udf_root, wim_path);
if (!p_udf_file) {
uprintf("Could not locate file %s in ISO image\n", wim_path);
goto out;
}
if (udf_read_block(p_udf_file, buf, 1) != UDF_BLOCKSIZE) {
uprintf("Error reading UDF file %s\n", wim_path);
goto out;
}
r = wim_header[3];
goto out;
try_iso:
p_iso = iso9660_open(iso);
if (p_iso == NULL) {
uprintf("Unable to open image '%s'.\n", iso);
goto out;
}
p_statbuf = iso9660_ifs_stat_translate(p_iso, wim_path);
if (p_statbuf == NULL) {
uprintf("Could not get ISO-9660 file information for file %s\n", wim_path);
goto out;
}
if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn, 1) != ISO_BLOCKSIZE) {
uprintf("Error reading ISO9660 file %s at LSN %lu\n", wim_path, (long unsigned int)p_statbuf->lsn);
goto out;
}
r = wim_header[3];
out:
if (p_statbuf != NULL)
safe_free(p_statbuf->rr.psz_symlink);
safe_free(p_statbuf);
if (p_udf_root != NULL)
udf_dirent_free(p_udf_root);
if (p_udf_file != NULL)
udf_dirent_free(p_udf_file);
if (p_iso != NULL)
iso9660_close(p_iso);
if (p_udf != NULL)
udf_close(p_udf);
safe_free(wim_path);
return bswap_32(r);
}
/*
* The following is used for native ISO mounting in Windows 8 or later
*/

View File

@ -1002,6 +1002,14 @@ static void DisplayISOProps(void)
uprintf(" Uses KolibriOS: %s", YesNo(iso_report.has_kolibrios));
uprintf(" Uses ReactOS: %s", YesNo(IS_REACTOS(iso_report)));
uprintf(" Uses WinPE: %s%s", YesNo(IS_WINPE(iso_report.winpe)), (iso_report.uses_minint) ? " (with /minint)" : "");
if (HAS_INSTALL_WIM(iso_report)) {
uprintf(" Uses Install.wim: Yes (version %d.%d.%d)", (iso_report.install_wim_version >> 24) & 0xff,
(iso_report.install_wim_version >> 16) & 0xff, (iso_report.install_wim_version >> 8) & 0xff);
// Microsoft somehow managed to make their ESD WIMs incompatible with their own APIs
// (yes, EVEN the Windows 10 APIs), so we must filter them out...
if (iso_report.install_wim_version >= MAX_WIM_VERSION)
uprintf(" Note: This WIM version is NOT compatible with Windows To Go");
}
// We don't support ToGo on Windows 7 or earlier, for lack of ISO mount capabilities
// TODO: add install.wim extraction workaround for Windows 7

View File

@ -242,9 +242,10 @@ typedef struct {
/* ISO details that the application may want */
#define WINPE_MININT 0x2A
#define WINPE_I386 0x15
#define MAX_WIM_VERSION 0x000E0000
#define HAS_SYSLINUX(r) (r.sl_version != 0)
#define HAS_INSTALL_WIM(r) (r.install_wim_path[0] != 0)
#define HAS_TOGO(r) (r.has_bootmgr && r.has_efi && HAS_INSTALL_WIM(r))
#define HAS_TOGO(r) (r.has_bootmgr && r.has_efi && HAS_INSTALL_WIM(r) && (r.install_wim_version < MAX_WIM_VERSION))
#define IS_WINPE(r) (((r & WINPE_MININT) == WINPE_MININT)||(( r & WINPE_I386) == WINPE_I386))
#define IS_WIN7_EFI(r) ((r.has_efi == 1) && HAS_INSTALL_WIM(r))
#define IS_REACTOS(r) (r.reactos_path[0] != 0)
@ -258,6 +259,7 @@ typedef struct {
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 */
uint64_t projected_size;
uint32_t install_wim_version;
uint8_t winpe;
uint8_t has_efi;
BOOLEAN has_4GB_file;
@ -461,6 +463,18 @@ static __inline void *_reallocf(void *ptr, size_t size) {
return ret;
}
static __inline uint16_t bswap_16(uint16_t x) {
return (x >> 8) | (x << 8);
}
static __inline uint32_t bswap_32(uint32_t x) {
return (bswap_16(x & 0xffff) << 16) | (bswap_16(x >> 16));
}
static __inline uint64_t bswap_64(uint64_t x) {
return (((uint64_t) bswap_32(x & 0xffffffffull)) << 32) | (bswap_32(x >> 32));
}
/* Hash tables */
typedef struct htab_entry {
uint32_t used;

View File

@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 2.3.704"
CAPTION "Rufus 2.3.705"
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@ -317,8 +317,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,3,704,0
PRODUCTVERSION 2,3,704,0
FILEVERSION 2,3,705,0
PRODUCTVERSION 2,3,705,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -335,13 +335,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "2.3.704"
VALUE "FileVersion", "2.3.705"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "2.3.704"
VALUE "ProductVersion", "2.3.705"
END
END
BLOCK "VarFileInfo"