[md5sum] compute and add md5sum_totalbytes to pre-existing md5sum.txt

This commit is contained in:
Pete Batard 2024-04-04 17:28:00 +01:00
parent dd8314b2f0
commit 5061af2b7c
No known key found for this signature in database
GPG Key ID: 38E0CF5E69EDD671
3 changed files with 152 additions and 12 deletions

153
src/iso.c
View File

@ -124,11 +124,12 @@ static const char* stupid_antivirus = " NOTE: This is usually caused by a poorl
const char* old_c32_name[NB_OLD_C32] = OLD_C32_NAMES;
static const int64_t old_c32_threshold[NB_OLD_C32] = OLD_C32_THRESHOLD;
static uint8_t joliet_level = 0;
static uint32_t md5sum_size = 0;
static uint64_t total_blocks, extra_blocks, nb_blocks, last_nb_blocks;
static BOOL scan_only = FALSE;
static FILE* fd_md5sum = NULL;
static StrArray config_path, isolinux_path;
static char symlinked_syslinux[MAX_PATH];
static char symlinked_syslinux[MAX_PATH], *md5sum_data = NULL, *md5sum_pos = NULL;
// Ensure filenames do not contain invalid FAT32 or NTFS characters
static __inline char* sanitize_filename(char* filename, BOOL* is_identical)
@ -483,6 +484,48 @@ static void fix_config(const char* psz_fullpath, const char* psz_path, const cha
free(src);
}
// Returns TRUE if a path appears in md5sum.txt
static BOOL is_in_md5sum(char* path)
{
BOOL found = FALSE;
char c[3], *p;
// If we are creating the md5sum file from scratch, every file is in it.
if (fd_md5sum != NULL)
return TRUE;
// If we don't have an existing file at this stage, then no file is in it.
if (md5sum_size == 0 || md5sum_data == NULL)
return FALSE;
// We should have a "X:/xyz" path
assert(path[1] == ':' && path[2] == '/');
// Modify the path to have " ./xyz"
c[0] = path[0];
c[1] = path[1];
path[0] = ' ';
path[1] = '.';
// Search for the string in the remainder of the md5sum.txt
// NB: md5sum_data is always NUL terminated.
p = strstr(md5sum_pos, path);
found = (p != NULL);
// If not found in remainder and we have a remainder, loop to search from beginning
if (!found && md5sum_pos != md5sum_data) {
c[2] = *md5sum_pos;
*md5sum_pos = 0;
p = strstr(md5sum_data, path);
*md5sum_pos = c[2];
found = (p != NULL);
}
path[0] = c[0];
path[1] = c[1];
if (found)
md5sum_pos = p + strlen(path);
return found;
}
static void print_extracted_file(char* psz_fullpath, uint64_t file_length)
{
@ -501,6 +544,9 @@ static void print_extracted_file(char* psz_fullpath, uint64_t file_length)
psz_fullpath[nul_pos] = 0;
// ISO9660 cannot handle backslashes
to_unix_path(psz_fullpath);
// Update md5sum_totalbytes as needed
if (is_in_md5sum(psz_fullpath))
md5sum_totalbytes += file_length;
}
// Convert from time_t to FILETIME
@ -630,10 +676,8 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha
goto out;
}
buf_size = (DWORD)MIN(file_length, read);
if (fd_md5sum != NULL) {
md5sum_totalbytes += buf_size;
if (fd_md5sum != NULL)
hash_write[HASH_MD5](&ctx, buf, buf_size);
}
ISO_BLOCKING(r = WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES));
if (!r || (wr_size != buf_size)) {
uprintf(" Error writing file: %s", r ? "Short write detected" : WindowsErrorString());
@ -897,10 +941,8 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
goto out;
}
buf_size = (DWORD)MIN(file_length, ISO_BUFFER_SIZE);
if (fd_md5sum != NULL) {
md5sum_totalbytes += buf_size;
if (fd_md5sum != NULL)
hash_write[HASH_MD5](&ctx, buf, buf_size);
}
ISO_BLOCKING(r = WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES));
if (!r || wr_size != buf_size) {
uprintf(" Error writing file: %s", r ? "Short write detected" : WindowsErrorString());
@ -1083,6 +1125,9 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)
fd_md5sum = fopenU(path, "wb");
if (fd_md5sum == NULL)
uprintf("WARNING: Could not create '%s'", md5sum_name[0]);
} else {
md5sum_size = ReadISOFileToBuffer(src_iso, md5sum_name[0], &md5sum_data);
md5sum_pos = md5sum_data;
}
}
}
@ -1386,6 +1431,9 @@ out:
if (fd_md5sum != NULL) {
uprintf("Created: %s\\%s (%s)", dest_dir, md5sum_name[0], SizeToHumanReadable(ftell(fd_md5sum), FALSE, FALSE));
fclose(fd_md5sum);
} else if (md5sum_data != NULL) {
safe_free(md5sum_data);
md5sum_size = 0;
}
}
iso9660_close(p_iso);
@ -1493,6 +1541,97 @@ out:
return r;
}
/*
* Extract a file to a buffer. Buffer must be freed by the caller.
*/
uint32_t ReadISOFileToBuffer(const char* iso, const char* iso_file, uint8_t** buf)
{
ssize_t read_size;
int64_t file_length;
uint32_t ret = 0, nb_blocks;
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;
*buf = NULL;
// 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");
goto out;
}
p_udf_file = udf_fopen(p_udf_root, iso_file);
if (!p_udf_file) {
uprintf("Could not locate file %s in ISO image", iso_file);
goto out;
}
file_length = udf_get_file_length(p_udf_file);
if (file_length > UINT32_MAX) {
uprintf("Only files smaller than 4 GB are supported");
goto out;
}
nb_blocks = (uint32_t)((file_length + UDF_BLOCKSIZE - 1) / UDF_BLOCKSIZE);
*buf = malloc(nb_blocks * UDF_BLOCKSIZE + 1);
if (*buf == NULL) {
uprintf("Could not allocate buffer for file %s", iso_file);
goto out;
}
read_size = udf_read_block(p_udf_file, *buf, nb_blocks);
if (read_size < 0 || read_size != file_length) {
uprintf("Error reading UDF file %s", iso_file);
goto out;
}
ret = (uint32_t)file_length;
(*buf)[ret] = 0;
goto out;
try_iso:
// Make sure to enable extensions, else we may not match the name of the file we are looking
// for since Rock Ridge may be needed to translate something like 'I386_PC' into 'i386-pc'...
p_iso = iso9660_open_ext(iso, ISO_EXTENSION_MASK);
if (p_iso == NULL) {
uprintf("Unable to open image '%s'", iso);
goto out;
}
p_statbuf = iso9660_ifs_stat_translate(p_iso, iso_file);
if (p_statbuf == NULL) {
uprintf("Could not get ISO-9660 file information for file %s", iso_file);
goto out;
}
file_length = p_statbuf->total_size;
if (file_length > UINT32_MAX) {
uprintf("Only files smaller than 4 GB are supported");
goto out;
}
nb_blocks = (uint32_t)((file_length + ISO_BLOCKSIZE - 1) / ISO_BLOCKSIZE);
*buf = malloc(nb_blocks * ISO_BLOCKSIZE + 1);
if (*buf == NULL) {
uprintf("Could not allocate buffer for file %s", iso_file);
goto out;
}
if (iso9660_iso_seek_read(p_iso, *buf, p_statbuf->lsn, nb_blocks) != nb_blocks * ISO_BLOCKSIZE) {
uprintf("Error reading ISO file %s", iso_file);
goto out;
}
ret = (uint32_t)file_length;
(*buf)[ret] = 0;
out:
iso9660_stat_free(p_statbuf);
udf_dirent_free(p_udf_root);
udf_dirent_free(p_udf_file);
iso9660_close(p_iso);
udf_close(p_udf);
if (ret == 0)
safe_free(*buf);
return ret;
}
uint32_t GetInstallWimVersion(const char* iso)
{
char *wim_path = NULL, buf[UDF_BLOCKSIZE] = { 0 };

View File

@ -729,6 +729,7 @@ extern BOOL ExtractDOS(const char* path);
extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan);
extern BOOL ExtractZip(const char* src_zip, const char* dest_dir);
extern int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file, DWORD attributes);
extern uint32_t ReadISOFileToBuffer(const char* iso, const char* iso_file, uint8_t** buf);
extern BOOL CopySKUSiPolicy(const char* drive_name);
extern BOOL HasEfiImgBootLoaders(void);
extern BOOL DumpFatDir(const char* path, int32_t cluster);

View File

@ -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 4.5.2123"
CAPTION "Rufus 4.5.2124"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -397,8 +397,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,5,2123,0
PRODUCTVERSION 4,5,2123,0
FILEVERSION 4,5,2124,0
PRODUCTVERSION 4,5,2124,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -416,13 +416,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "4.5.2123"
VALUE "FileVersion", "4.5.2124"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "<22> 2011-2024 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-4.5.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "4.5.2123"
VALUE "ProductVersion", "4.5.2124"
END
END
BLOCK "VarFileInfo"