From 5061af2b7c3a99150e5d25f38c1dce051efeaeaf Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 4 Apr 2024 17:28:00 +0100 Subject: [PATCH 1/2] [md5sum] compute and add md5sum_totalbytes to pre-existing md5sum.txt --- src/iso.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/rufus.h | 1 + src/rufus.rc | 10 ++-- 3 files changed, 152 insertions(+), 12 deletions(-) diff --git a/src/iso.c b/src/iso.c index 02be4c37..5a52be87 100644 --- a/src/iso.c +++ b/src/iso.c @@ -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 }; diff --git a/src/rufus.h b/src/rufus.h index b4f460c7..5cfb2913 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -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); diff --git a/src/rufus.rc b/src/rufus.rc index b829733e..7a5ee892 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 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", "� 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" From 4eda8d9d5c38da0e525cd20ba13b5ea5faea6219 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 4 Apr 2024 17:40:20 +0100 Subject: [PATCH 2/2] [process] add extra exception handling on NtClose() * Also fix a typo in Norwegian translation (Closes #2453). --- res/loc/po/nb-NO.po | 4 ++-- res/loc/rufus.loc | 2 +- src/process.c | 6 +++++- src/rufus.rc | 10 +++++----- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/res/loc/po/nb-NO.po b/res/loc/po/nb-NO.po index 263f6801..10a8af8f 100644 --- a/res/loc/po/nb-NO.po +++ b/res/loc/po/nb-NO.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: 3.22\n" "Report-Msgid-Bugs-To: pete@akeo.ie\n" "POT-Creation-Date: 2023-04-17 13:44+0100\n" -"PO-Revision-Date: 2024-01-10 12:20+0000\n" +"PO-Revision-Date: 2024-04-04 17:38+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: nb_NO\n" @@ -1843,7 +1843,7 @@ msgstr "Lag en lokal brukerkonto med brukernavnet:" #. • MSG_334 msgid "Set regional options to the same values as this user's" -msgstr "Sett regionale instillinger til det samme som den aktive brukerkontoen" +msgstr "Sett regionale innstillinger til det samme som den aktive brukerkontoen" #. • MSG_335 msgid "Disable BitLocker automatic device encryption" diff --git a/res/loc/rufus.loc b/res/loc/rufus.loc index 689e89e2..17278f21 100644 --- a/res/loc/rufus.loc +++ b/res/loc/rufus.loc @@ -9577,7 +9577,7 @@ t MSG_330 "Fjern krav om en Microsoft konto" t MSG_331 "Slå av all datainnsamling (hopp over spørsmålene)" t MSG_332 "Ikke gi Windows To Go tilgang til interne harddisker" t MSG_333 "Lag en lokal brukerkonto med brukernavnet:" -t MSG_334 "Sett regionale instillinger til det samme som den aktive brukerkontoen" +t MSG_334 "Sett regionale innstillinger til det samme som den aktive brukerkontoen" t MSG_335 "Deaktiver BitLocker kryptering av enheten" t MSG_336 "Behold log" t MSG_900 "Rufus er et verktøy som hjelper til med å formatere og lage oppstartbare USB-stasjoner, for eksempel USB-minnepinner, USB-harddisker, og lignende." diff --git a/src/process.c b/src/process.c index 1027ee54..31fc6465 100644 --- a/src/process.c +++ b/src/process.c @@ -556,7 +556,11 @@ static DWORD WINAPI SearchProcessThread(LPVOID param) ); if ((dupHandle != NULL) && (processHandle != NtCurrentProcess())) { - pfNtClose(dupHandle); + TRY_AND_HANDLE( + EXCEPTION_ACCESS_VIOLATION, + { pfNtClose(dupHandle); }, + { continue; } + ); dupHandle = NULL; } diff --git a/src/rufus.rc b/src/rufus.rc index 7a5ee892..f10f7a8c 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 4.5.2124" +CAPTION "Rufus 4.5.2125" 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,2124,0 - PRODUCTVERSION 4,5,2124,0 + FILEVERSION 4,5,2125,0 + PRODUCTVERSION 4,5,2125,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.2124" + VALUE "FileVersion", "4.5.2125" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "� 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.2124" + VALUE "ProductVersion", "4.5.2125" END END BLOCK "VarFileInfo"