From afe2bc60f634cf1d417680cefc51b3caeb3cfbf2 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 31 Jul 2015 13:36:28 +0200 Subject: [PATCH] Filesystem: Initialize everything in constructor Not initializing until the filesystem is used is good when a filesystem is constructed and then never used, but nobody does that. This simplifies the code a little and lets all methods be const. --- Source/Core/DiscIO/FileSystemGCWii.cpp | 146 ++++++++++--------------- Source/Core/DiscIO/FileSystemGCWii.h | 17 ++- Source/Core/DiscIO/Filesystem.h | 15 +-- 3 files changed, 74 insertions(+), 104 deletions(-) diff --git a/Source/Core/DiscIO/FileSystemGCWii.cpp b/Source/Core/DiscIO/FileSystemGCWii.cpp index a6e7ee0cd1..813201b7a0 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/FileSystemGCWii.cpp @@ -60,9 +60,58 @@ std::string FileInfoGCWii::GetName() const } FileSystemGCWii::FileSystemGCWii(const Volume* _rVolume, const Partition& partition) - : FileSystem(_rVolume, partition), m_Initialized(false), m_Valid(false), m_offset_shift(0) + : FileSystem(_rVolume, partition), m_Valid(false), m_offset_shift(0) { - m_Valid = DetectFileSystem(); + // Check if this is a GameCube or Wii disc + if (m_rVolume->ReadSwapped(0x18, m_partition) == u32(0x5D1C9EA3)) + { + m_offset_shift = 2; // Wii file system + m_Valid = true; + } + else if (m_rVolume->ReadSwapped(0x1c, m_partition) == u32(0xC2339F3D)) + { + m_offset_shift = 0; // GameCube file system + m_Valid = true; + } + + if (!m_Valid) + return; + + const std::optional fst_offset_unshifted = m_rVolume->ReadSwapped(0x424, m_partition); + const std::optional fst_size_unshifted = m_rVolume->ReadSwapped(0x428, m_partition); + if (!fst_offset_unshifted || !fst_size_unshifted) + return; + const u64 fst_offset = static_cast(*fst_offset_unshifted) << m_offset_shift; + const u64 fst_size = static_cast(*fst_size_unshifted) << m_offset_shift; + if (fst_size < 0xC) + return; + + // 128 MiB is more than the total amount of RAM in a Wii. + // No file system should use anywhere near that much. + static const u32 ARBITRARY_FILE_SYSTEM_SIZE_LIMIT = 128 * 1024 * 1024; + if (fst_size > ARBITRARY_FILE_SYSTEM_SIZE_LIMIT) + { + // Without this check, Dolphin can crash by trying to allocate too much + // memory when loading a disc image with an incorrect FST size. + + ERROR_LOG(DISCIO, "File system is abnormally large! Aborting loading"); + return; + } + + // Read the whole FST + m_file_system_table.resize(fst_size); + if (!m_rVolume->Read(fst_offset, fst_size, m_file_system_table.data(), m_partition)) + return; + + // Create all file info objects + u32 number_of_file_infos = Common::swap32(*((u32*)m_file_system_table.data() + 2)); + const u8* fst_start = m_file_system_table.data(); + const u8* name_table_start = fst_start + (number_of_file_infos * 0xC); + const u8* name_table_end = fst_start + fst_size; + if (name_table_end < name_table_start) + return; + for (u32 i = 0; i < number_of_file_infos; i++) + m_FileInfoVector.emplace_back(m_offset_shift, fst_start + (i * 0xC), name_table_start); } FileSystemGCWii::~FileSystemGCWii() @@ -70,19 +119,13 @@ FileSystemGCWii::~FileSystemGCWii() m_FileInfoVector.clear(); } -const std::vector& FileSystemGCWii::GetFileList() +const std::vector& FileSystemGCWii::GetFileList() const { - if (!m_Initialized) - InitFileSystem(); - return m_FileInfoVector; } -const FileInfo* FileSystemGCWii::FindFileInfo(const std::string& path) +const FileInfo* FileSystemGCWii::FindFileInfo(const std::string& path) const { - if (!m_Initialized) - InitFileSystem(); - if (m_FileInfoVector.empty()) return nullptr; @@ -150,11 +193,8 @@ const FileInfo* FileSystemGCWii::FindFileInfo(const std::string& path, return nullptr; } -const FileInfo* FileSystemGCWii::FindFileInfo(u64 disc_offset) +const FileInfo* FileSystemGCWii::FindFileInfo(u64 disc_offset) const { - if (!m_Initialized) - InitFileSystem(); - for (auto& file_info : m_FileInfoVector) { if ((file_info.GetOffset() <= disc_offset) && @@ -167,11 +207,8 @@ const FileInfo* FileSystemGCWii::FindFileInfo(u64 disc_offset) return nullptr; } -std::string FileSystemGCWii::GetPath(u64 _Address) +std::string FileSystemGCWii::GetPath(u64 _Address) const { - if (!m_Initialized) - InitFileSystem(); - for (size_t i = 0; i < m_FileInfoVector.size(); ++i) { const FileInfoGCWii& file_info = m_FileInfoVector[i]; @@ -185,11 +222,8 @@ std::string FileSystemGCWii::GetPath(u64 _Address) return ""; } -std::string FileSystemGCWii::GetPathFromFSTOffset(size_t file_info_offset) +std::string FileSystemGCWii::GetPathFromFSTOffset(size_t file_info_offset) const { - if (!m_Initialized) - InitFileSystem(); - // Root entry doesn't have a name if (file_info_offset == 0) return ""; @@ -226,11 +260,8 @@ std::string FileSystemGCWii::GetPathFromFSTOffset(size_t file_info_offset) } u64 FileSystemGCWii::ReadFile(const FileInfo* file_info, u8* _pBuffer, u64 _MaxBufferSize, - u64 _OffsetInFile) + u64 _OffsetInFile) const { - if (!m_Initialized) - InitFileSystem(); - if (!file_info || file_info->IsDirectory()) return 0; @@ -248,11 +279,9 @@ u64 FileSystemGCWii::ReadFile(const FileInfo* file_info, u8* _pBuffer, u64 _MaxB return read_length; } -bool FileSystemGCWii::ExportFile(const FileInfo* file_info, const std::string& _rExportFilename) +bool FileSystemGCWii::ExportFile(const FileInfo* file_info, + const std::string& _rExportFilename) const { - if (!m_Initialized) - InitFileSystem(); - if (!file_info || file_info->IsDirectory()) return false; @@ -374,61 +403,4 @@ bool FileSystemGCWii::ExportDOL(const std::string& _rExportFolder) const return false; } -bool FileSystemGCWii::DetectFileSystem() -{ - if (m_rVolume->ReadSwapped(0x18, m_partition) == u32(0x5D1C9EA3)) - { - m_offset_shift = 2; // Wii file system - return true; - } - else if (m_rVolume->ReadSwapped(0x1c, m_partition) == u32(0xC2339F3D)) - { - m_offset_shift = 0; // GameCube file system - return true; - } - - return false; -} - -void FileSystemGCWii::InitFileSystem() -{ - m_Initialized = true; - - const std::optional fst_offset_unshifted = m_rVolume->ReadSwapped(0x424, m_partition); - const std::optional fst_size_unshifted = m_rVolume->ReadSwapped(0x428, m_partition); - if (!fst_offset_unshifted || !fst_size_unshifted) - return; - const u64 fst_offset = static_cast(*fst_offset_unshifted) << m_offset_shift; - const u64 fst_size = static_cast(*fst_size_unshifted) << m_offset_shift; - if (fst_size < 0xC) - return; - - // 128 MiB is more than the total amount of RAM in a Wii. - // No file system should use anywhere near that much. - static const u32 ARBITRARY_FILE_SYSTEM_SIZE_LIMIT = 128 * 1024 * 1024; - if (fst_size > ARBITRARY_FILE_SYSTEM_SIZE_LIMIT) - { - // Without this check, Dolphin can crash by trying to allocate too much - // memory when loading a disc image with an incorrect FST size. - - ERROR_LOG(DISCIO, "File system is abnormally large! Aborting loading"); - return; - } - - // Read the whole FST - m_file_system_table.resize(fst_size); - if (!m_rVolume->Read(fst_offset, fst_size, m_file_system_table.data(), m_partition)) - return; - - // Create all file info objects - u32 number_of_file_infos = Common::swap32(*((u32*)m_file_system_table.data() + 2)); - const u8* fst_start = m_file_system_table.data(); - const u8* name_table_start = fst_start + (number_of_file_infos * 0xC); - const u8* name_table_end = fst_start + fst_size; - if (name_table_end < name_table_start) - return; - for (u32 i = 0; i < number_of_file_infos; i++) - m_FileInfoVector.emplace_back(m_offset_shift, fst_start + (i * 0xC), name_table_start); -} - } // namespace diff --git a/Source/Core/DiscIO/FileSystemGCWii.h b/Source/Core/DiscIO/FileSystemGCWii.h index b4b9fd49c2..ab4af8d0f0 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.h +++ b/Source/Core/DiscIO/FileSystemGCWii.h @@ -51,29 +51,26 @@ public: FileSystemGCWii(const Volume* _rVolume, const Partition& partition); ~FileSystemGCWii() override; bool IsValid() const override { return m_Valid; } - const std::vector& GetFileList() override; - const FileInfo* FindFileInfo(const std::string& path) override; - const FileInfo* FindFileInfo(u64 disc_offset) override; - std::string GetPath(u64 _Address) override; - std::string GetPathFromFSTOffset(size_t file_info_offset) override; + const std::vector& GetFileList() const override; + const FileInfo* FindFileInfo(const std::string& path) const override; + const FileInfo* FindFileInfo(u64 disc_offset) const override; + std::string GetPath(u64 _Address) const override; + std::string GetPathFromFSTOffset(size_t file_info_offset) const override; u64 ReadFile(const FileInfo* file_info, u8* _pBuffer, u64 _MaxBufferSize, - u64 _OffsetInFile) override; - bool ExportFile(const FileInfo* file_info, const std::string& _rExportFilename) override; + u64 _OffsetInFile) const override; + bool ExportFile(const FileInfo* file_info, const std::string& _rExportFilename) const override; bool ExportApploader(const std::string& _rExportFolder) const override; bool ExportDOL(const std::string& _rExportFolder) const override; std::optional GetBootDOLOffset() const override; std::optional GetBootDOLSize(u64 dol_offset) const override; private: - bool m_Initialized; bool m_Valid; u32 m_offset_shift; std::vector m_FileInfoVector; std::vector m_file_system_table; const FileInfo* FindFileInfo(const std::string& path, size_t search_start_offset) const; - bool DetectFileSystem(); - void InitFileSystem(); }; } // namespace diff --git a/Source/Core/DiscIO/Filesystem.h b/Source/Core/DiscIO/Filesystem.h index 99d89f110a..2f1fe2c82d 100644 --- a/Source/Core/DiscIO/Filesystem.h +++ b/Source/Core/DiscIO/Filesystem.h @@ -39,16 +39,17 @@ public: virtual ~FileSystem(); virtual bool IsValid() const = 0; // TODO: Should only return FileInfo, not FileInfoGCWii - virtual const std::vector& GetFileList() = 0; - virtual const FileInfo* FindFileInfo(const std::string& path) = 0; - virtual const FileInfo* FindFileInfo(u64 disc_offset) = 0; + virtual const std::vector& GetFileList() const = 0; + virtual const FileInfo* FindFileInfo(const std::string& path) const = 0; + virtual const FileInfo* FindFileInfo(u64 disc_offset) const = 0; virtual u64 ReadFile(const FileInfo* file_info, u8* _pBuffer, u64 _MaxBufferSize, - u64 _OffsetInFile = 0) = 0; - virtual bool ExportFile(const FileInfo* file_info, const std::string& _rExportFilename) = 0; + u64 _OffsetInFile = 0) const = 0; + virtual bool ExportFile(const FileInfo* file_info, + const std::string& _rExportFilename) const = 0; virtual bool ExportApploader(const std::string& _rExportFolder) const = 0; virtual bool ExportDOL(const std::string& _rExportFolder) const = 0; - virtual std::string GetPath(u64 _Address) = 0; - virtual std::string GetPathFromFSTOffset(size_t file_info_offset) = 0; + virtual std::string GetPath(u64 _Address) const = 0; + virtual std::string GetPathFromFSTOffset(size_t file_info_offset) const = 0; virtual std::optional GetBootDOLOffset() const = 0; virtual std::optional GetBootDOLSize(u64 dol_offset) const = 0;