From 4ebed1eac2be276894a3e0d4991ffb0d37d36d43 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 5 Feb 2020 13:23:49 +0000 Subject: [PATCH] [iso] report usage of UDF symbolic links * These may dramatically increase the size required for extraction so users may want to have some hints about these. * Closes #1446 --- src/iso.c | 21 +++++++++++++-------- src/libcdio/driver/filemode.h | 6 ++++++ src/rufus.c | 8 ++++++-- src/rufus.h | 4 +++- src/rufus.rc | 10 +++++----- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/iso.c b/src/iso.c index 32e3af51..0f9b440b 100644 --- a/src/iso.c +++ b/src/iso.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,10 @@ #define PROGRESS_THRESHOLD 128 #define FOUR_GIGABYTES 4294967296LL +// Needed for UDF symbolic link testing +#define S_IFLNK 0xA000 +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) + // Needed for UDF ISO access CdIo_t* cdio_open (const char* psz_source, driver_id_t driver_id) {return NULL;} void cdio_destroy (CdIo_t* p_cdio) {} @@ -280,11 +285,9 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t file_length, const } if (file_length >= FOUR_GIGABYTES) img_report.has_4GB_file = TRUE; - // Compute projected size needed - total_blocks += file_length / ISO_BLOCKSIZE; - // NB: ISO_BLOCKSIZE = UDF_BLOCKSIZE - if ((file_length != 0) && (file_length % ISO_BLOCKSIZE != 0)) - total_blocks++; + // Compute projected size needed (NB: ISO_BLOCKSIZE = UDF_BLOCKSIZE) + if (file_length != 0) + total_blocks += (file_length + (ISO_BLOCKSIZE - 1)) / ISO_BLOCKSIZE; return TRUE; } return FALSE; @@ -463,6 +466,8 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha if (length < 0) { goto out; } + if (S_ISLNK(udf_get_posix_filemode(p_udf_dirent))) + img_report.has_symlinks = SYMLINKS_UDF; if (udf_is_dir(p_udf_dirent)) { if (!scan_only) { psz_sanpath = sanitize_filename(psz_fullpath, &is_identical); @@ -608,7 +613,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) // a generic list that's unaware of RR extensions is being used, so we prevent that memleak ourselves is_symlink = (p_statbuf->rr.psz_symlink != NULL); if (is_symlink) - img_report.has_symlinks = TRUE; + img_report.has_symlinks = SYMLINKS_RR; if (scan_only) safe_free(p_statbuf->rr.psz_symlink); } else { @@ -769,7 +774,6 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan) } else { uprintf("Extracting files...\n"); IGNORE_RETVAL(_chdirU(app_dir)); -// PrintInfo(0, MSG_231); if (total_blocks == 0) { uprintf("Error: ISO has not been properly scanned.\n"); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN); @@ -803,7 +807,8 @@ try_iso: // Perform our first scan with Joliet disabled (if Rock Ridge is enabled), so that we can find if // there exists a Rock Ridge file with a name > 64 chars or if there are symlinks. If that is the // case then we also disable Joliet during the extract phase. - if ((!enable_joliet) || (enable_rockridge && (scan_only || img_report.has_long_filename || img_report.has_symlinks))) { + if ((!enable_joliet) || (enable_rockridge && (scan_only || img_report.has_long_filename || + (img_report.has_symlinks == SYMLINKS_RR)))) { iso_extension_mask &= ~ISO_EXTENSION_JOLIET; } if (!enable_rockridge) { diff --git a/src/libcdio/driver/filemode.h b/src/libcdio/driver/filemode.h index a06f72c9..1ca462af 100644 --- a/src/libcdio/driver/filemode.h +++ b/src/libcdio/driver/filemode.h @@ -87,6 +87,12 @@ #if !defined S_IFIFO && defined _WIN32 # define S_IFIFO 0x1000 #endif +#if !defined S_IFLNK && defined _WIN32 +#define S_IFLNK 0xA000 +#endif +#if !defined S_IFSOCK && defined _WIN32 +#define S_IFSOCK 0xC000 +#endif #if !defined S_ISBLK && defined S_IFBLK # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) diff --git a/src/rufus.c b/src/rufus.c index 9ce14eb6..ab08def0 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -1073,8 +1073,12 @@ static void DisplayISOProps(void) (img_report.wininst_version >> 16) & 0xff, (img_report.wininst_version >> 8) & 0xff, (img_report.wininst_version >= SPECIAL_WIM_VERSION) ? "+": ""); } - 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, + " Note: This ISO uses symbolic links, which will not be replicated due to file system limitations."); + PRINT_ISO_PROP((img_report.has_symlinks == SYMLINKS_RR), + " Because of this, some features from this image may not work..."); + PRINT_ISO_PROP((img_report.has_symlinks == SYMLINKS_UDF), + " 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 diff --git a/src/rufus.h b/src/rufus.h index 0a5280c3..767c0d8e 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -312,6 +312,8 @@ enum checksum_type { #define HAS_WINTOGO(r) (HAS_BOOTMGR(r) && IS_EFI_BOOTABLE(r) && HAS_WININST(r)) #define HAS_PERSISTENCE(r) ((HAS_SYSLINUX(r) || HAS_GRUB(r)) && !(HAS_WINDOWS(r) || HAS_REACTOS(r) || HAS_KOLIBRIOS(r))) #define IS_FAT(fs) ((fs_type == FS_FAT16) || (fs_type == FS_FAT32)) +#define SYMLINKS_RR 0x01 +#define SYMLINKS_UDF 0x02 typedef struct { char label[192]; // 3*64 to account for UTF-8 @@ -331,9 +333,9 @@ typedef struct { uint16_t winpe; uint8_t has_efi; uint8_t wininst_index; + uint8_t has_symlinks; BOOLEAN has_4GB_file; BOOLEAN has_long_filename; - BOOLEAN has_symlinks; BOOLEAN has_bootmgr; BOOLEAN has_bootmgr_efi; BOOLEAN has_autorun; diff --git a/src/rufus.rc b/src/rufus.rc index 47c04f7f..f055ba2e 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.9.1600" +CAPTION "Rufus 3.9.1601" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -394,8 +394,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,9,1600,0 - PRODUCTVERSION 3,9,1600,0 + FILEVERSION 3,9,1601,0 + PRODUCTVERSION 3,9,1601,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -413,13 +413,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.9.1600" + VALUE "FileVersion", "3.9.1601" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.9.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.9.1600" + VALUE "ProductVersion", "3.9.1601" END END BLOCK "VarFileInfo"