diff --git a/res/grub2/core.img b/res/grub2/core.img index 30d95320..63098ba6 100644 Binary files a/res/grub2/core.img and b/res/grub2/core.img differ diff --git a/res/grub2/readme.txt b/res/grub2/readme.txt index d06ab51b..d62ee615 100644 --- a/res/grub2/readme.txt +++ b/res/grub2/readme.txt @@ -1,14 +1,9 @@ This directory contains the Grub 2.0 boot records that are used by Rufus -* boot.img was compiled from git://git.savannah.gnu.org/grub.git at commit: - 72ec399ad8d6348b6c74ea63d80c79784c8b84ae. - -* core.img was compiled from grub 2.00-22 using the tarballs found at - https://launchpad.net/ubuntu/+source/grub2/2.00-22. - The use of the 2.00-22 source is done for compatibility reasons. - -* This was done on a Debian 7.7.0 x64 system using gcc-multilib 4.7.2, following - the guide from http://pete.akeo.ie/2014/05/compiling-and-installing-grub2-for.html +* boot.img and core.img were compiled from git://git.savannah.gnu.org/grub.git, + commit 72ec399ad8d6348b6c74ea63d80c79784c8b84ae, on a Debian 7.7.0 x64 system. + This was done following the guide from: + http://pete.akeo.ie/2014/05/compiling-and-installing-grub2-for.html. Note that exFAT was not included in core.img in order to keep it under 31.5 KB. * boot.img has been modified to nop the jump @ 0x66 as per grub2's setup.c comments: diff --git a/src/iso.c b/src/iso.c index 888f1e63..69744419 100644 --- a/src/iso.c +++ b/src/iso.c @@ -52,6 +52,12 @@ CdIo_t* cdio_open (const char* psz_source, driver_id_t driver_id) {return NULL;} void cdio_destroy (CdIo_t* p_cdio) {} +typedef struct { + BOOL is_syslinux_cfg; + BOOL is_grub_cfg; + BOOL is_old_c32[NB_OLD_C32]; +} EXTRACT_PROPS; + RUFUS_ISO_REPORT iso_report; int64_t iso_blocking_status = -1; BOOL enable_iso = TRUE, enable_joliet = TRUE, enable_rockridge = TRUE, has_ldlinux_c32; @@ -63,6 +69,7 @@ static const char* ldlinux_name = "ldlinux.sys"; static const char* ldlinux_c32 = "ldlinux.c32"; static const char* efi_dirname = "/efi/boot"; static const char* grub_dirname = "/boot/grub"; // NB: We don't support nonstandard config dir such as AROS' "/boot/pc/grub/" +static const char* grub_cfg = "grub.cfg"; static const char* syslinux_cfg[] = { "isolinux.cfg", "syslinux.cfg", "extlinux.conf"}; static const char dot_isolinux_bin[] = ".\\isolinux.bin"; static const char* isolinux_bin = &dot_isolinux_bin[2]; @@ -122,34 +129,41 @@ static void log_handler (cdio_log_level_t level, const char *message) * Scan and set ISO properties * Returns true if the the current file does not need to be processed further */ -static BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_cfg, BOOL* is_old_c32, - int64_t i_file_length, const char* psz_basename, const char* psz_fullpath) +static BOOL check_iso_props(const char* psz_dirname, int64_t i_file_length, const char* psz_basename, + const char* psz_fullpath, EXTRACT_PROPS *props) { size_t i, j; - // Check for an isolinux/syslinux config file anywhere - *is_syslinux_cfg = FALSE; + memset(props, 0, sizeof(EXTRACT_PROPS)); for (i=0; iis_syslinux_cfg = TRUE; if ((scan_only) && (i == 1) && (safe_stricmp(psz_dirname, efi_dirname) == 0)) iso_report.has_efi_syslinux = TRUE; } } - // Check for a syslinux v5.0+ file anywhere - if (safe_stricmp(psz_basename, ldlinux_c32) == 0) { - has_ldlinux_c32 = TRUE; - } - // Check for an old incompatible c32 file anywhere for (i=0; iis_old_c32[i] = TRUE; } + // Check for the Grub config file + if ((safe_stricmp(psz_dirname, grub_dirname) == 0) && (safe_stricmp(psz_basename, grub_cfg) == 0)) { + if (scan_only) + iso_report.has_grub2 = TRUE; + else + props->is_grub_cfg = TRUE; + } + + if (scan_only) { + // Check for a syslinux v5.0+ file anywhere + if (safe_stricmp(psz_basename, ldlinux_c32) == 0) { + has_ldlinux_c32 = TRUE; + } + // Check for various files in root (psz_dirname = "") if (*psz_dirname == 0) { if (safe_strnicmp(psz_basename, bootmgr_efi_name, safe_strlen(bootmgr_efi_name)-5) == 0) { @@ -174,13 +188,6 @@ static BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_cfg, BOOL if (safe_stricmp(psz_dirname, efi_dirname) == 0) iso_report.has_efi = TRUE; - // Check for the Grub boot directory - // TODO: If there is a need to point to a different config file, as we do with Syslinux, - // see http://www.gnu.org/software/grub/manual/grub.html#Embedded-configuration - // However, this allegedly requires normal.mod (105 KB!) to be in core.img... - if (safe_stricmp(psz_dirname, grub_dirname) == 0) - iso_report.has_grub2 = TRUE; - // Check for PE (XP) specific files in "/i386" or "/minint" for (i=0; iis_syslinux_cfg) { // Maintain a list of all the isolinux/syslinux configs identified so far StrArrayAdd(&config_path, psz_fullpath); } @@ -198,7 +205,7 @@ static BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_cfg, BOOL } for (i=0; iis_old_c32[i]) iso_report.has_old_c32[i] = TRUE; } if (i_file_length >= FOUR_GIGABYTES) @@ -218,10 +225,10 @@ static BOOL check_iso_props(const char* psz_dirname, BOOL* is_syslinux_cfg, BOOL return FALSE; } -static void fix_syslinux(const char* psz_fullpath, const char* psz_path, const char* psz_basename) +static void fix_config(const char* psz_fullpath, const char* psz_path, const char* psz_basename, EXTRACT_PROPS* props) { size_t i, nul_pos; - char *iso_label, *usb_label, *src, *dst; + char *iso_label = NULL, *usb_label = NULL, *src, *dst; nul_pos = safe_strlen(psz_fullpath); src = safe_strdup(psz_fullpath); @@ -230,23 +237,37 @@ static void fix_syslinux(const char* psz_fullpath, const char* psz_path, const c for (i=0; i '%s'\n", src, iso_label, usb_label); - free(iso_label); - free(usb_label); - // Fix dual BIOS + EFI support for tails and other ISOs - if ( (safe_stricmp(psz_path, efi_dirname) == 0) && (safe_stricmp(psz_basename, syslinux_cfg[0]) == 0) && - (!iso_report.has_efi_syslinux) && (dst = safe_strdup(src)) ) { - dst[nul_pos-12] = 's'; dst[nul_pos-11] = 'y'; dst[nul_pos-10] = 's'; - CopyFileA(src, dst, TRUE); - uprintf("Duplicated %s to %s\n", src, dst); - free(dst); + if (props->is_syslinux_cfg) { + // Workaround for isolinux config files requiring an ISO label for kernel + // append that may be different from our USB label. Oh, and these labels + // must have spaces converted to \x20. + iso_label = replace_char(iso_report.label, ' ', "\\x20"); + usb_label = replace_char(iso_report.usb_label, ' ', "\\x20"); + if ((iso_label != NULL) && (usb_label != NULL)) { + if (replace_in_token_data(src, "append", iso_label, usb_label, TRUE) != NULL) + uprintf(" Patched %s: '%s' ⇨ '%s'\n", src, iso_label, usb_label); + // Fix dual BIOS + EFI support for tails and other ISOs + if ( (safe_stricmp(psz_path, efi_dirname) == 0) && (safe_stricmp(psz_basename, syslinux_cfg[0]) == 0) && + (!iso_report.has_efi_syslinux) && (dst = safe_strdup(src)) ) { + dst[nul_pos-12] = 's'; dst[nul_pos-11] = 'y'; dst[nul_pos-10] = 's'; + CopyFileA(src, dst, TRUE); + uprintf("Duplicated %s to %s\n", src, dst); + free(dst); + } + } + } else if (props->is_grub_cfg) { + // Workaround for FreeNAS + iso_label = malloc(MAX_PATH); + usb_label = malloc(MAX_PATH); + if ((iso_label != NULL) && (usb_label != NULL)) { + safe_sprintf(iso_label, MAX_PATH, "cd9660:/dev/iso9660/%s", iso_report.label); + safe_sprintf(usb_label, MAX_PATH, "msdosfs:/dev/msdosfs/%s", iso_report.usb_label); + if (replace_in_token_data(src, "set", iso_label, usb_label, TRUE) != NULL) + uprintf(" Patched %s: '%s' ⇨ '%s'\n", src, iso_label, usb_label); + } } + safe_free(iso_label); + safe_free(usb_label); free(src); } @@ -274,7 +295,8 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha { HANDLE file_handle = NULL; DWORD buf_size, wr_size, err; - BOOL r, is_syslinux_cfg, is_old_c32[NB_OLD_C32], is_identical; + EXTRACT_PROPS props; + BOOL r, is_identical; int i_length; size_t i; char tmp[128], *psz_fullpath = NULL, *psz_sanpath = NULL; @@ -314,13 +336,13 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha } } else { i_file_length = udf_get_file_length(p_udf_dirent); - if (check_iso_props(psz_path, &is_syslinux_cfg, is_old_c32, i_file_length, psz_basename, psz_fullpath)) { + if (check_iso_props(psz_path, i_file_length, psz_basename, psz_fullpath, &props)) { safe_free(psz_fullpath); continue; } print_extracted_file(psz_fullpath, i_file_length); for (i=0; isize; - if (check_iso_props(psz_path, &is_syslinux_cfg, is_old_c32, i_file_length, psz_basename, psz_fullpath)) { + if (check_iso_props(psz_path, i_file_length, psz_basename, psz_fullpath, &props)) { continue; } print_extracted_file(psz_fullpath, i_file_length); for (i=0; i