diff --git a/src/lib/formats/fs_fat.cpp b/src/lib/formats/fs_fat.cpp index f4cd99e36ed..7cea0d6a168 100644 --- a/src/lib/formats/fs_fat.cpp +++ b/src/lib/formats/fs_fat.cpp @@ -66,13 +66,13 @@ 14 2 Reserved sector count (including boot sector) 16 1 Number of FATs (file allocation tables) 17 2 Number of root directory entries - 19 2 Total sectors (bits 0-15) + 19 2 Total sectors (0 if 0x10000 or more) 21 1 Media descriptor 22 2 Sectors per FAT 24 2 Sectors per track 26 2 Number of heads 28 4 Hidden sectors - 32 4 Total sectors (bits 16-47) + 32 4 Total sectors (0 if less than 0x10000) 36 1 Physical drive number 37 1 Current head 38 1 Signature @@ -183,6 +183,7 @@ public: bool is_hidden() const { return (attributes() & 0x02) != 0x00; } bool is_system() const { return (attributes() & 0x04) != 0x00; } bool is_volume_label() const { return (attributes() & 0x08) != 0x00; } + bool is_long_file_name() const { return attributes() == 0x0f; } bool is_subdirectory() const { return (attributes() & 0x10) != 0x00; } bool is_archive() const { return (attributes() & 0x20) != 0x00; } bool is_deleted() const { return m_block.r8(m_offset) == DELETED_FILE_MARKER; } @@ -385,7 +386,7 @@ char fs::fat_image::directory_separator() const std::vector fs::fat_image::volume_meta_description() const { std::vector results; - results.emplace_back(meta_name::name, "UNTITLED", false, [](const meta_value &m) { return m.as_string().size() <= 11; }, "Volume name, up to 11 characters"); + results.emplace_back(meta_name::name, "UNTITLED", false, [](const meta_value &m) { return validate_filename(m.as_string()); }, "Volume name"); results.emplace_back(meta_name::oem_name, "", false, [](const meta_value &m) { return m.as_string().size() <= 8; }, "OEM name, up to 8 characters"); return results; } @@ -500,9 +501,26 @@ impl::impl(fsblk_t &blockdev, fsblk_t::block_t &&boot_sector_block, std::vector< meta_data impl::volume_metadata() { + std::vector root_path; + directory_span::ptr root_dir = find_directory(root_path.begin(), root_path.end()); + assert(root_dir); + + // Get the volume label from the root directory, not the extended BPB (whose name field may not be kept up-to-date even when it exists) meta_data results; - results.set(meta_name::name, m_boot_sector_block.rstr(43, 11)); - results.set(meta_name::oem_name, m_boot_sector_block.rstr(3, 8)); + auto callback = [&results](const directory_entry &dirent) + { + if (dirent.is_volume_label()) + { + results.set(meta_name::name, dirent.name()); + return true; + } + return false; + }; + iterate_directory_entries(*root_dir, callback); + if (!results.has(meta_name::name)) + results.set(meta_name::name, "UNTITLED"); + + results.set(meta_name::oem_name, m_boot_sector_block.rstr(3, 8)); return results; } @@ -534,8 +552,11 @@ std::pair> impl::directory_contents(const std::vec std::vector results; auto callback = [&results](const directory_entry &dirent) { - dir_entry_type entry_type = dirent.is_subdirectory() ? dir_entry_type::dir : dir_entry_type::file; - results.emplace_back(entry_type, dirent.metadata()); + if (!dirent.is_volume_label()) + { + dir_entry_type entry_type = dirent.is_subdirectory() ? dir_entry_type::dir : dir_entry_type::file; + results.emplace_back(entry_type, dirent.metadata()); + } return false; }; iterate_directory_entries(*dir, callback); @@ -713,7 +734,7 @@ void impl::iterate_directory_entries(const directory_span &dir, const std::funct for (u32 index = 0; !done && (index < dirents_per_sector()); index++) { directory_entry dirent(block, index * 32); - if (dirent.raw_stem()[0] != 0x00 && !dirent.is_deleted()) + if (dirent.raw_stem()[0] != 0x00 && !dirent.is_deleted() && !dirent.is_long_file_name()) { // get the filename std::string_view stem = trim_end_spaces(dirent.raw_stem()); diff --git a/src/lib/formats/fsblk.cpp b/src/lib/formats/fsblk.cpp index d766e389bee..0201ca29092 100644 --- a/src/lib/formats/fsblk.cpp +++ b/src/lib/formats/fsblk.cpp @@ -63,7 +63,7 @@ u8 *fsblk_t::iblock_t::offset(const char *function, u32 off, u32 size) const u8 *fsblk_t::iblock_t::rooffset(const char *function, u32 off, u32 size) { if(off + size > m_size) - throw std::out_of_range(util::string_format("block_t::%s out-of-block read access, offset=%d, size=%d, block size=%d\n", function, off, size, m_size)); + throw std::out_of_range(util::string_format("block_t::%s out-of-block read access, offset=%d, size=%d, block size=%d", function, off, size, m_size)); return rodata() + off; } diff --git a/src/lib/formats/fsblk_vec.cpp b/src/lib/formats/fsblk_vec.cpp index 36f11cc9d89..e80cad8c51c 100644 --- a/src/lib/formats/fsblk_vec.cpp +++ b/src/lib/formats/fsblk_vec.cpp @@ -34,7 +34,7 @@ u32 fsblk_vec_t::block_count() const fsblk_t::block_t fsblk_vec_t::get(u32 id) { if(id >= block_count()) - throw std::out_of_range(util::string_format("Block number overflow: requiring block %d on device of size %d (%d bytes, block size %d)\n", id, block_count(), m_data.size(), m_block_size)); + throw std::out_of_range(util::string_format("Block number overflow: requiring block %d on device of size %d (%d bytes, block size %d)", id, block_count(), m_data.size(), m_block_size)); return block_t(new blk_t(m_data.data() + m_block_size*id, m_block_size)); } diff --git a/src/tools/floptool.cpp b/src/tools/floptool.cpp index ba573e0a0cd..f07713eef53 100644 --- a/src/tools/floptool.cpp +++ b/src/tools/floptool.cpp @@ -725,7 +725,7 @@ int CLIB_DECL main(int argc, char *argv[]) return 1; } } catch(const std::exception &err) { - fprintf(stderr, "Error: %s", err.what()); + fprintf(stderr, "Error: %s\n", err.what()); return 1; } }