diff --git a/Source/Core/Core/HW/DVD/FileMonitor.cpp b/Source/Core/Core/HW/DVD/FileMonitor.cpp index f6c984c4fc..980bc5454f 100644 --- a/Source/Core/Core/HW/DVD/FileMonitor.cpp +++ b/Source/Core/Core/HW/DVD/FileMonitor.cpp @@ -88,18 +88,19 @@ void Log(u64 offset, const DiscIO::Partition& partition) if (!s_filesystem) return; - const std::string path = s_filesystem->GetPath(offset); + const DiscIO::FileInfo* file_info = s_filesystem->FindFileInfo(offset); // Do nothing if no file was found at that offset - if (path.empty()) + if (!file_info) return; + const std::string path = s_filesystem->GetPath(file_info->GetOffset()); + // Do nothing if we found the same file again if (s_previous_file == path) return; - const u64 size = s_filesystem->GetFileSize(path); - const std::string size_string = ThousandSeparate(size / 1000, 7); + const std::string size_string = ThousandSeparate(file_info->GetSize() / 1000, 7); const std::string log_string = StringFromFormat("%s kB %s", size_string.c_str(), path.c_str()); if (IsSoundFile(path)) diff --git a/Source/Core/DiscIO/FileSystemGCWii.cpp b/Source/Core/DiscIO/FileSystemGCWii.cpp index f8ddab28fe..d799caf435 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/FileSystemGCWii.cpp @@ -50,31 +50,35 @@ const std::vector& FileSystemGCWii::GetFileList() return m_FileInfoVector; } -const FileInfo* FileSystemGCWii::FindFileInfo(const std::string& _rFullPath) +const FileInfo* FileSystemGCWii::FindFileInfo(const std::string& path) { if (!m_Initialized) InitFileSystem(); for (size_t i = 0; i < m_FileInfoVector.size(); ++i) { - if (!strcasecmp(GetPathFromFSTOffset(i).c_str(), _rFullPath.c_str())) + if (!strcasecmp(GetPathFromFSTOffset(i).c_str(), path.c_str())) return &m_FileInfoVector[i]; } return nullptr; } -u64 FileSystemGCWii::GetFileSize(const std::string& _rFullPath) +const FileInfo* FileSystemGCWii::FindFileInfo(u64 disc_offset) { if (!m_Initialized) InitFileSystem(); - const FileInfo* pFileInfo = FindFileInfo(_rFullPath); + for (auto& file_info : m_FileInfoVector) + { + if ((file_info.GetOffset() <= disc_offset) && + ((file_info.GetOffset() + file_info.GetSize()) > disc_offset)) + { + return &file_info; + } + } - if (pFileInfo != nullptr && !pFileInfo->IsDirectory()) - return pFileInfo->GetSize(); - - return 0; + return nullptr; } std::string FileSystemGCWii::GetPath(u64 _Address) @@ -135,42 +139,39 @@ std::string FileSystemGCWii::GetPathFromFSTOffset(size_t file_info_offset) } } -u64 FileSystemGCWii::ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize, +u64 FileSystemGCWii::ReadFile(const FileInfo* file_info, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile) { if (!m_Initialized) InitFileSystem(); - const FileInfo* pFileInfo = FindFileInfo(_rFullPath); - if (pFileInfo == nullptr) + if (!file_info || file_info->IsDirectory()) return 0; - if (_OffsetInFile >= pFileInfo->GetSize()) + if (_OffsetInFile >= file_info->GetSize()) return 0; - u64 read_length = std::min(_MaxBufferSize, pFileInfo->GetSize() - _OffsetInFile); + u64 read_length = std::min(_MaxBufferSize, file_info->GetSize() - _OffsetInFile); DEBUG_LOG(DISCIO, "Reading %" PRIx64 " bytes at %" PRIx64 " from file %s. Offset: %" PRIx64 " Size: %" PRIx64, - read_length, _OffsetInFile, _rFullPath.c_str(), pFileInfo->GetOffset(), - pFileInfo->GetSize()); + read_length, _OffsetInFile, GetPath(file_info->GetOffset()).c_str(), + file_info->GetOffset(), file_info->GetSize()); - m_rVolume->Read(pFileInfo->GetOffset() + _OffsetInFile, read_length, _pBuffer, m_partition); + m_rVolume->Read(file_info->GetOffset() + _OffsetInFile, read_length, _pBuffer, m_partition); return read_length; } -bool FileSystemGCWii::ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename) +bool FileSystemGCWii::ExportFile(const FileInfo* file_info, const std::string& _rExportFilename) { if (!m_Initialized) InitFileSystem(); - const FileInfo* pFileInfo = FindFileInfo(_rFullPath); - - if (!pFileInfo) + if (!file_info || file_info->IsDirectory()) return false; - u64 remainingSize = pFileInfo->GetSize(); - u64 fileOffset = pFileInfo->GetOffset(); + u64 remainingSize = file_info->GetSize(); + u64 fileOffset = file_info->GetOffset(); File::IOFile f(_rExportFilename, "wb"); if (!f) diff --git a/Source/Core/DiscIO/FileSystemGCWii.h b/Source/Core/DiscIO/FileSystemGCWii.h index 37e972e542..9c31c1bcc8 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.h +++ b/Source/Core/DiscIO/FileSystemGCWii.h @@ -44,12 +44,12 @@ public: bool IsValid() const override { return m_Valid; } const std::vector& GetFileList() override; const FileInfo* FindFileInfo(const std::string& path) override; - u64 GetFileSize(const std::string& _rFullPath) override; + const FileInfo* FindFileInfo(u64 disc_offset) override; std::string GetPath(u64 _Address) override; std::string GetPathFromFSTOffset(size_t file_info_offset) override; - u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize, + u64 ReadFile(const FileInfo* file_info, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile) override; - bool ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename) override; + bool ExportFile(const FileInfo* file_info, const std::string& _rExportFilename) override; bool ExportApploader(const std::string& _rExportFolder) const override; bool ExportDOL(const std::string& _rExportFolder) const override; std::optional GetBootDOLOffset() const override; diff --git a/Source/Core/DiscIO/Filesystem.h b/Source/Core/DiscIO/Filesystem.h index c27d6e9636..22cc9bc47a 100644 --- a/Source/Core/DiscIO/Filesystem.h +++ b/Source/Core/DiscIO/Filesystem.h @@ -40,11 +40,11 @@ public: virtual bool IsValid() const = 0; // TODO: Should only return FileInfo, not FileInfoGCWii virtual const std::vector& GetFileList() = 0; - virtual u64 GetFileSize(const std::string& _rFullPath) = 0; virtual const FileInfo* FindFileInfo(const std::string& path) = 0; - virtual u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize, + virtual const FileInfo* FindFileInfo(u64 disc_offset) = 0; + virtual u64 ReadFile(const FileInfo* file_info, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile = 0) = 0; - virtual bool ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename) = 0; + virtual bool ExportFile(const FileInfo* file_info, const std::string& _rExportFilename) = 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; diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index 39bc029ec2..09f073d075 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -177,7 +177,11 @@ void VolumeGC::LoadBannerFile() const if (!file_system) return; - size_t file_size = static_cast(file_system->GetFileSize("opening.bnr")); + const FileInfo* file_info = file_system->FindFileInfo("opening.bnr"); + if (!file_info) + return; + + size_t file_size = static_cast(file_info->GetSize()); constexpr int BNR1_MAGIC = 0x31524e42; constexpr int BNR2_MAGIC = 0x32524e42; if (file_size != BNR1_SIZE && file_size != BNR2_SIZE) @@ -186,7 +190,11 @@ void VolumeGC::LoadBannerFile() const return; } - file_system->ReadFile("opening.bnr", reinterpret_cast(&banner_file), file_size); + if (file_size != file_system->ReadFile(file_info, reinterpret_cast(&banner_file), file_size)) + { + WARN_LOG(DISCIO, "Could not read opening.bnr."); + return; + } bool is_bnr1; if (banner_file.id == BNR1_MAGIC && file_size == BNR1_SIZE) diff --git a/Source/Core/DiscIO/VolumeWii.cpp b/Source/Core/DiscIO/VolumeWii.cpp index ceb1fa5788..6b1cf6dafa 100644 --- a/Source/Core/DiscIO/VolumeWii.cpp +++ b/Source/Core/DiscIO/VolumeWii.cpp @@ -274,7 +274,8 @@ std::map VolumeWii::GetLongNames() const return {}; std::vector opening_bnr(NAMES_TOTAL_BYTES); - size_t size = file_system->ReadFile("opening.bnr", opening_bnr.data(), opening_bnr.size(), 0x5C); + const FileInfo* file_info = file_system->FindFileInfo("opening.bnr"); + size_t size = file_system->ReadFile(file_info, opening_bnr.data(), opening_bnr.size(), 0x5C); opening_bnr.resize(size); return ReadWiiNames(opening_bnr); } diff --git a/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp index ebad7364ef..cb4e3fd059 100644 --- a/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp +++ b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp @@ -405,12 +405,14 @@ void FilesystemPanel::ExtractSingleFile(const wxString& output_file_path) const // Remove "Partition x/" selection_file_path.erase(0, slash_index + 1); - partition->filesystem->ExportFile(WxStrToStr(selection_file_path), - WxStrToStr(output_file_path)); + partition->filesystem->ExportFile( + partition->filesystem->FindFileInfo(WxStrToStr(selection_file_path)), + WxStrToStr(output_file_path)); } else { - m_filesystem->ExportFile(WxStrToStr(selection_file_path), WxStrToStr(output_file_path)); + m_filesystem->ExportFile(m_filesystem->FindFileInfo(WxStrToStr(selection_file_path)), + WxStrToStr(output_file_path)); } } @@ -456,6 +458,7 @@ void FilesystemPanel::ExtractDirectories(const std::string& full_path, else { // Look for the dir we are going to extract + // TODO: Make this more efficient for (index = 0; index < fst.size(); ++index) { if (filesystem->GetPathFromFSTOffset(index) == full_path) @@ -513,7 +516,7 @@ void FilesystemPanel::ExtractDirectories(const std::string& full_path, StringFromFormat("%s/%s", output_folder.c_str(), path.c_str()); INFO_LOG(DISCIO, "%s", export_name.c_str()); - if (!File::Exists(export_name) && !filesystem->ExportFile(path, export_name)) + if (!File::Exists(export_name) && !filesystem->ExportFile(&fst[index], export_name)) { ERROR_LOG(DISCIO, "Could not export %s", export_name.c_str()); }