From d06b532150bbf969476f73ea93213c65e203558c Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 17 Jun 2017 12:37:30 +0200 Subject: [PATCH] DiscIO: Move parts of Filesystem to the new file DiscExtractor --- Source/Core/DiscIO/CMakeLists.txt | 1 + Source/Core/DiscIO/DiscExtractor.cpp | 174 ++++++++++++++++++ Source/Core/DiscIO/DiscExtractor.h | 27 +++ Source/Core/DiscIO/DiscIO.vcxproj | 2 + Source/Core/DiscIO/DiscIO.vcxproj.filters | 9 + Source/Core/DiscIO/DiscScrubber.cpp | 9 +- Source/Core/DiscIO/FileSystemGCWii.cpp | 144 --------------- Source/Core/DiscIO/FileSystemGCWii.h | 8 - Source/Core/DiscIO/Filesystem.h | 8 - Source/Core/DiscIO/VolumeGC.cpp | 6 +- Source/Core/DiscIO/VolumeWii.cpp | 5 +- .../ISOProperties/FilesystemPanel.cpp | 53 +++--- 12 files changed, 255 insertions(+), 191 deletions(-) create mode 100644 Source/Core/DiscIO/DiscExtractor.cpp create mode 100644 Source/Core/DiscIO/DiscExtractor.h diff --git a/Source/Core/DiscIO/CMakeLists.txt b/Source/Core/DiscIO/CMakeLists.txt index f54a048f89..b59435efa0 100644 --- a/Source/Core/DiscIO/CMakeLists.txt +++ b/Source/Core/DiscIO/CMakeLists.txt @@ -3,6 +3,7 @@ set(SRCS CISOBlob.cpp WbfsBlob.cpp CompressedBlob.cpp + DiscExtractor.cpp DiscScrubber.cpp DriveBlob.cpp Enums.cpp diff --git a/Source/Core/DiscIO/DiscExtractor.cpp b/Source/Core/DiscIO/DiscExtractor.cpp new file mode 100644 index 0000000000..403e6f6d0a --- /dev/null +++ b/Source/Core/DiscIO/DiscExtractor.cpp @@ -0,0 +1,174 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DiscIO/DiscExtractor.h" + +#include +#include +#include + +#include "Common/CommonTypes.h" +#include "DiscIO/Enums.h" +#include "DiscIO/Filesystem.h" +#include "DiscIO/Volume.h" + +namespace DiscIO +{ +u64 ReadFile(const Volume& volume, const Partition& partition, const FileInfo* file_info, + u8* buffer, u64 max_buffer_size, u64 offset_in_file) +{ + if (!file_info || file_info->IsDirectory()) + return 0; + + if (offset_in_file >= file_info->GetSize()) + return 0; + + u64 read_length = std::min(max_buffer_size, file_info->GetSize() - offset_in_file); + + DEBUG_LOG(DISCIO, "Reading %" PRIx64 " bytes at %" PRIx64 " from file %s. Offset: %" PRIx64 + " Size: %" PRIx32, + read_length, offset_in_file, file_info->GetPath().c_str(), file_info->GetOffset(), + file_info->GetSize()); + + volume.Read(file_info->GetOffset() + offset_in_file, read_length, buffer, partition); + + return read_length; +} + +bool ExportFile(const Volume& volume, const Partition& partition, const FileInfo* file_info, + const std::string& export_filename) +{ + if (!file_info || file_info->IsDirectory()) + return false; + + u64 remaining_size = file_info->GetSize(); + u64 file_offset = file_info->GetOffset(); + + File::IOFile f(export_filename, "wb"); + if (!f) + return false; + + bool result = true; + + while (remaining_size) + { + // Limit read size to 128 MB + size_t read_size = (size_t)std::min(remaining_size, (u64)0x08000000); + + std::vector buffer(read_size); + + result = volume.Read(file_offset, read_size, &buffer[0], partition); + + if (!result) + break; + + f.WriteBytes(&buffer[0], read_size); + + remaining_size -= read_size; + file_offset += read_size; + } + + return result; +} + +bool ExportApploader(const Volume& volume, const Partition& partition, + const std::string& export_folder) +{ + if (!IsDisc(volume.GetVolumeType())) + return false; + + std::optional apploader_size = volume.ReadSwapped(0x2440 + 0x14, partition); + const std::optional trailer_size = volume.ReadSwapped(0x2440 + 0x18, partition); + constexpr u32 header_size = 0x20; + if (!apploader_size || !trailer_size) + return false; + *apploader_size += *trailer_size + header_size; + DEBUG_LOG(DISCIO, "Apploader size -> %x", *apploader_size); + + std::vector buffer(*apploader_size); + if (volume.Read(0x2440, *apploader_size, buffer.data(), partition)) + { + std::string export_name(export_folder + "/apploader.img"); + + File::IOFile apploader_file(export_name, "wb"); + if (apploader_file) + { + apploader_file.WriteBytes(buffer.data(), *apploader_size); + return true; + } + } + + return false; +} + +std::optional GetBootDOLOffset(const Volume& volume, const Partition& partition) +{ + const Platform volume_type = volume.GetVolumeType(); + if (!IsDisc(volume_type)) + return {}; + + std::optional offset = volume.ReadSwapped(0x420, partition); + const u8 offset_shift = volume_type == Platform::WII_DISC ? 2 : 0; + return offset ? static_cast(*offset) << offset_shift : std::optional(); +} + +std::optional GetBootDOLSize(const Volume& volume, const Partition& partition, u64 dol_offset) +{ + if (!IsDisc(volume.GetVolumeType())) + return {}; + + u32 dol_size = 0; + + // Iterate through the 7 code segments + for (u8 i = 0; i < 7; i++) + { + const std::optional offset = volume.ReadSwapped(dol_offset + 0x00 + i * 4, partition); + const std::optional size = volume.ReadSwapped(dol_offset + 0x90 + i * 4, partition); + if (!offset || !size) + return {}; + dol_size = std::max(*offset + *size, dol_size); + } + + // Iterate through the 11 data segments + for (u8 i = 0; i < 11; i++) + { + const std::optional offset = volume.ReadSwapped(dol_offset + 0x1c + i * 4, partition); + const std::optional size = volume.ReadSwapped(dol_offset + 0xac + i * 4, partition); + if (!offset || !size) + return {}; + dol_size = std::max(*offset + *size, dol_size); + } + + return dol_size; +} + +bool ExportDOL(const Volume& volume, const Partition& partition, const std::string& export_folder) +{ + if (!IsDisc(volume.GetVolumeType())) + return false; + + std::optional dol_offset = GetBootDOLOffset(volume, partition); + if (!dol_offset) + return false; + std::optional dol_size = GetBootDOLSize(volume, partition, *dol_offset); + if (!dol_size) + return false; + + std::vector buffer(*dol_size); + if (volume.Read(*dol_offset, *dol_size, buffer.data(), partition)) + { + std::string export_name(export_folder + "/boot.dol"); + + File::IOFile dol_file(export_name, "wb"); + if (dol_file) + { + dol_file.WriteBytes(&buffer[0], *dol_size); + return true; + } + } + + return false; +} + +} // namespace DiscIO diff --git a/Source/Core/DiscIO/DiscExtractor.h b/Source/Core/DiscIO/DiscExtractor.h new file mode 100644 index 0000000000..e5d80a13ce --- /dev/null +++ b/Source/Core/DiscIO/DiscExtractor.h @@ -0,0 +1,27 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "Common/CommonTypes.h" + +namespace DiscIO +{ +class FileInfo; +struct Partition; +class Volume; + +u64 ReadFile(const Volume& volume, const Partition& partition, const FileInfo* file_info, + u8* buffer, u64 max_buffer_size, u64 offset_in_file = 0); +bool ExportFile(const Volume& volume, const Partition& partition, const FileInfo* file_info, + const std::string& export_filename); +bool ExportApploader(const Volume& volume, const Partition& partition, + const std::string& export_folder); +std::optional GetBootDOLOffset(const Volume& volume, const Partition& partition); +std::optional GetBootDOLSize(const Volume& volume, const Partition& partition, u64 dol_offset); +bool ExportDOL(const Volume& volume, const Partition& partition, const std::string& export_folder); + +} // namespace DiscIO diff --git a/Source/Core/DiscIO/DiscIO.vcxproj b/Source/Core/DiscIO/DiscIO.vcxproj index 1bc3994345..3a978ad262 100644 --- a/Source/Core/DiscIO/DiscIO.vcxproj +++ b/Source/Core/DiscIO/DiscIO.vcxproj @@ -39,6 +39,7 @@ + @@ -60,6 +61,7 @@ + diff --git a/Source/Core/DiscIO/DiscIO.vcxproj.filters b/Source/Core/DiscIO/DiscIO.vcxproj.filters index f5c3f00959..3c1f85ca10 100644 --- a/Source/Core/DiscIO/DiscIO.vcxproj.filters +++ b/Source/Core/DiscIO/DiscIO.vcxproj.filters @@ -1,6 +1,9 @@  + + {51cdf366-d3fe-464a-9f89-c9f1592a6f1c} + {3873659a-9a30-4a58-af9e-8dad7d7eb627} @@ -75,6 +78,9 @@ Volume\Blob + + DiscExtractor + @@ -134,6 +140,9 @@ Volume\Blob + + DiscExtractor + diff --git a/Source/Core/DiscIO/DiscScrubber.cpp b/Source/Core/DiscIO/DiscScrubber.cpp index 838df208cf..52d907be69 100644 --- a/Source/Core/DiscIO/DiscScrubber.cpp +++ b/Source/Core/DiscIO/DiscScrubber.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include "DiscIO/DiscScrubber.h" + #include #include #include @@ -14,7 +16,8 @@ #include "Common/CommonTypes.h" #include "Common/File.h" #include "Common/Logging/Log.h" -#include "DiscIO/DiscScrubber.h" + +#include "DiscIO/DiscExtractor.h" #include "DiscIO/Filesystem.h" #include "DiscIO/Volume.h" @@ -200,10 +203,10 @@ bool DiscScrubber::ParsePartitionData(const Partition& partition, PartitionHeade 0x2440 + header->apploader_size + header->apploader_trailer_size); // DOL - const std::optional dol_offset = filesystem->GetBootDOLOffset(); + const std::optional dol_offset = GetBootDOLOffset(*m_disc, partition); if (!dol_offset) return false; - const std::optional dol_size = filesystem->GetBootDOLSize(*dol_offset); + const std::optional dol_size = GetBootDOLSize(*m_disc, partition, *dol_offset); if (!dol_size) return false; header->dol_offset = *dol_offset; diff --git a/Source/Core/DiscIO/FileSystemGCWii.cpp b/Source/Core/DiscIO/FileSystemGCWii.cpp index 615a33888b..cf70c03052 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/FileSystemGCWii.cpp @@ -330,148 +330,4 @@ std::unique_ptr FileSystemGCWii::FindFileInfo(u64 disc_offset) const return nullptr; } -u64 FileSystemGCWii::ReadFile(const FileInfo* file_info, u8* buffer, u64 max_buffer_size, - u64 offset_in_file) const -{ - if (!file_info || file_info->IsDirectory()) - return 0; - - if (offset_in_file >= file_info->GetSize()) - return 0; - - u64 read_length = std::min(max_buffer_size, file_info->GetSize() - offset_in_file); - - DEBUG_LOG(DISCIO, "Reading %" PRIx64 " bytes at %" PRIx64 " from file %s. Offset: %" PRIx64 - " Size: %" PRIx32, - read_length, offset_in_file, file_info->GetPath().c_str(), file_info->GetOffset(), - file_info->GetSize()); - - m_volume->Read(file_info->GetOffset() + offset_in_file, read_length, buffer, m_partition); - return read_length; -} - -bool FileSystemGCWii::ExportFile(const FileInfo* file_info, - const std::string& export_filename) const -{ - if (!file_info || file_info->IsDirectory()) - return false; - - u64 remaining_size = file_info->GetSize(); - u64 file_offset = file_info->GetOffset(); - - File::IOFile f(export_filename, "wb"); - if (!f) - return false; - - bool result = true; - - while (remaining_size) - { - // Limit read size to 128 MB - size_t read_size = (size_t)std::min(remaining_size, (u64)0x08000000); - - std::vector buffer(read_size); - - result = m_volume->Read(file_offset, read_size, &buffer[0], m_partition); - - if (!result) - break; - - f.WriteBytes(&buffer[0], read_size); - - remaining_size -= read_size; - file_offset += read_size; - } - - return result; -} - -bool FileSystemGCWii::ExportApploader(const std::string& export_folder) const -{ - std::optional apploader_size = m_volume->ReadSwapped(0x2440 + 0x14, m_partition); - const std::optional trailer_size = m_volume->ReadSwapped(0x2440 + 0x18, m_partition); - constexpr u32 header_size = 0x20; - if (!apploader_size || !trailer_size) - return false; - *apploader_size += *trailer_size + header_size; - DEBUG_LOG(DISCIO, "Apploader size -> %x", *apploader_size); - - std::vector buffer(*apploader_size); - if (m_volume->Read(0x2440, *apploader_size, buffer.data(), m_partition)) - { - std::string export_name(export_folder + "/apploader.img"); - - File::IOFile apploader_file(export_name, "wb"); - if (apploader_file) - { - apploader_file.WriteBytes(buffer.data(), *apploader_size); - return true; - } - } - - return false; -} - -std::optional FileSystemGCWii::GetBootDOLOffset() const -{ - std::optional offset = m_volume->ReadSwapped(0x420, m_partition); - return offset ? static_cast(*offset) << m_offset_shift : std::optional(); -} - -std::optional FileSystemGCWii::GetBootDOLSize(u64 dol_offset) const -{ - u32 dol_size = 0; - - // Iterate through the 7 code segments - for (u8 i = 0; i < 7; i++) - { - const std::optional offset = - m_volume->ReadSwapped(dol_offset + 0x00 + i * 4, m_partition); - const std::optional size = - m_volume->ReadSwapped(dol_offset + 0x90 + i * 4, m_partition); - if (!offset || !size) - return {}; - dol_size = std::max(*offset + *size, dol_size); - } - - // Iterate through the 11 data segments - for (u8 i = 0; i < 11; i++) - { - const std::optional offset = - m_volume->ReadSwapped(dol_offset + 0x1c + i * 4, m_partition); - const std::optional size = - m_volume->ReadSwapped(dol_offset + 0xac + i * 4, m_partition); - if (!offset || !size) - return {}; - dol_size = std::max(*offset + *size, dol_size); - } - - return dol_size; -} - -bool FileSystemGCWii::ExportDOL(const std::string& export_folder) const -{ - std::optional dol_offset = GetBootDOLOffset(); - if (!dol_offset) - return false; - std::optional dol_size = GetBootDOLSize(*dol_offset); - if (!dol_size) - return false; - - std::vector buffer(*dol_size); - if (m_volume->Read(*dol_offset, *dol_size, buffer.data(), m_partition)) - { - std::string export_name(export_folder + "/boot.dol"); - - File::IOFile dol_file(export_name, "wb"); - if (dol_file) - { - dol_file.WriteBytes(&buffer[0], *dol_size); - return true; - } - } - - return false; -} - } // namespace diff --git a/Source/Core/DiscIO/FileSystemGCWii.h b/Source/Core/DiscIO/FileSystemGCWii.h index ee69bfed94..8e393642bf 100644 --- a/Source/Core/DiscIO/FileSystemGCWii.h +++ b/Source/Core/DiscIO/FileSystemGCWii.h @@ -93,14 +93,6 @@ public: std::unique_ptr FindFileInfo(const std::string& path) const override; std::unique_ptr FindFileInfo(u64 disc_offset) const override; - u64 ReadFile(const FileInfo* file_info, u8* buffer, u64 max_buffer_size, - u64 offset_in_file) const override; - bool ExportFile(const FileInfo* file_info, const std::string& export_filename) const override; - bool ExportApploader(const std::string& export_folder) const override; - bool ExportDOL(const std::string& export_folder) const override; - std::optional GetBootDOLOffset() const override; - std::optional GetBootDOLSize(u64 dol_offset) const override; - private: bool m_valid; u32 m_offset_shift; diff --git a/Source/Core/DiscIO/Filesystem.h b/Source/Core/DiscIO/Filesystem.h index 879c6fbbdd..a5695958b7 100644 --- a/Source/Core/DiscIO/Filesystem.h +++ b/Source/Core/DiscIO/Filesystem.h @@ -120,14 +120,6 @@ public: // Returns nullptr if not found virtual std::unique_ptr FindFileInfo(u64 disc_offset) const = 0; - virtual u64 ReadFile(const FileInfo* file_info, u8* buffer, u64 max_buffer_size, - u64 offset_in_file = 0) const = 0; - virtual bool ExportFile(const FileInfo* file_info, const std::string& export_filename) const = 0; - virtual bool ExportApploader(const std::string& export_folder) const = 0; - virtual bool ExportDOL(const std::string& export_folder) const = 0; - virtual std::optional GetBootDOLOffset() const = 0; - virtual std::optional GetBootDOLSize(u64 dol_offset) const = 0; - virtual const Partition GetPartition() const { return m_partition; } protected: const Volume* const m_volume; diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index af4178682f..1a89917812 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -16,7 +16,9 @@ #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" #include "Common/StringUtil.h" + #include "DiscIO/Blob.h" +#include "DiscIO/DiscExtractor.h" #include "DiscIO/Enums.h" #include "DiscIO/Filesystem.h" #include "DiscIO/Volume.h" @@ -190,8 +192,8 @@ void VolumeGC::LoadBannerFile() const return; } - if (file_size != - file_system->ReadFile(file_info.get(), reinterpret_cast(&banner_file), file_size)) + if (file_size != ReadFile(*this, PARTITION_NONE, file_info.get(), + reinterpret_cast(&banner_file), file_size)) { WARN_LOG(DISCIO, "Could not read opening.bnr."); return; diff --git a/Source/Core/DiscIO/VolumeWii.cpp b/Source/Core/DiscIO/VolumeWii.cpp index 8ccca04409..0379a0c3cd 100644 --- a/Source/Core/DiscIO/VolumeWii.cpp +++ b/Source/Core/DiscIO/VolumeWii.cpp @@ -24,6 +24,7 @@ #include "Common/Swap.h" #include "DiscIO/Blob.h" +#include "DiscIO/DiscExtractor.h" #include "DiscIO/Enums.h" #include "DiscIO/Filesystem.h" #include "DiscIO/Volume.h" @@ -274,8 +275,8 @@ std::map VolumeWii::GetLongNames() const std::vector opening_bnr(NAMES_TOTAL_BYTES); std::unique_ptr file_info = file_system->FindFileInfo("opening.bnr"); - opening_bnr.resize( - file_system->ReadFile(file_info.get(), opening_bnr.data(), opening_bnr.size(), 0x5C)); + opening_bnr.resize(ReadFile(*this, GetGamePartition(), file_info.get(), opening_bnr.data(), + opening_bnr.size(), 0x5C)); return ReadWiiNames(opening_bnr); } diff --git a/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp index 93ee3bdb9d..c375931aae 100644 --- a/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp +++ b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp @@ -25,6 +25,7 @@ #include "Common/CommonPaths.h" #include "Common/FileUtil.h" #include "Common/Logging/Log.h" +#include "DiscIO/DiscExtractor.h" #include "DiscIO/Enums.h" #include "DiscIO/Filesystem.h" #include "DiscIO/Volume.h" @@ -261,32 +262,32 @@ void FilesystemPanel::OnExtractDirectories(wxCommandEvent& event) void FilesystemPanel::OnExtractHeaderData(wxCommandEvent& event) { - DiscIO::FileSystem* file_system = nullptr; const wxString path = wxDirSelector(_("Choose the folder to extract to")); if (path.empty()) return; + DiscIO::Partition partition; if (m_has_partitions) { const auto* const selection_data = m_tree_ctrl->GetItemData(m_tree_ctrl->GetSelection()); - const auto* const partition = static_cast(selection_data); + const auto* const wii_partition = static_cast(selection_data); - file_system = partition->filesystem.get(); + partition = wii_partition->filesystem->GetPartition(); } else { - file_system = m_filesystem.get(); + partition = DiscIO::PARTITION_NONE; } bool ret = false; if (event.GetId() == ID_EXTRACT_APPLOADER) { - ret = file_system->ExportApploader(WxStrToStr(path)); + ret = DiscIO::ExportApploader(*m_opened_iso, partition, WxStrToStr(path)); } else if (event.GetId() == ID_EXTRACT_DOL) { - ret = file_system->ExportDOL(WxStrToStr(path)); + ret = DiscIO::ExportDOL(*m_opened_iso, partition, WxStrToStr(path)); } if (!ret) @@ -366,14 +367,15 @@ void FilesystemPanel::ExtractSingleFile(const wxString& output_file_path) const // Remove "Partition x/" selection_file_path.erase(0, slash_index + 1); - partition->filesystem->ExportFile( - partition->filesystem->FindFileInfo(WxStrToStr(selection_file_path)).get(), - WxStrToStr(output_file_path)); + DiscIO::ExportFile(*m_opened_iso, partition->filesystem->GetPartition(), + partition->filesystem->FindFileInfo(WxStrToStr(selection_file_path)).get(), + WxStrToStr(output_file_path)); } else { - m_filesystem->ExportFile(m_filesystem->FindFileInfo(WxStrToStr(selection_file_path)).get(), - WxStrToStr(output_file_path)); + DiscIO::ExportFile(*m_opened_iso, DiscIO::PARTITION_NONE, + m_filesystem->FindFileInfo(WxStrToStr(selection_file_path)).get(), + WxStrToStr(output_file_path)); } } @@ -400,7 +402,8 @@ void FilesystemPanel::ExtractSingleDirectory(const wxString& output_folder) } static void ExtractDir(const std::string& full_path, const std::string& output_folder, - const DiscIO::FileSystem& file_system, const DiscIO::FileInfo& directory, + const DiscIO::Volume& volume, const DiscIO::Partition partition, + const DiscIO::FileInfo& directory, const std::function& update_progress) { for (const DiscIO::FileInfo& file_info : directory) @@ -416,13 +419,13 @@ static void ExtractDir(const std::string& full_path, const std::string& output_f if (file_info.IsDirectory()) { File::CreateFullPath(output_path); - ExtractDir(path, output_folder, file_system, file_info, update_progress); + ExtractDir(path, output_folder, volume, partition, file_info, update_progress); } else { if (File::Exists(output_path)) NOTICE_LOG(DISCIO, "%s already exists", output_path.c_str()); - else if (!file_system.ExportFile(&file_info, output_path)) + else if (!DiscIO::ExportFile(volume, partition, &file_info, output_path)) ERROR_LOG(DISCIO, "Could not export %s", output_path.c_str()); } } @@ -434,8 +437,8 @@ void FilesystemPanel::ExtractDirectories(const std::string& full_path, { if (full_path.empty()) // Root { - filesystem.ExportApploader(output_folder); - filesystem.ExportDOL(output_folder); + DiscIO::ExportApploader(*m_opened_iso, filesystem.GetPartition(), output_folder); + DiscIO::ExportDOL(*m_opened_iso, filesystem.GetPartition(), output_folder); } std::unique_ptr file_info = filesystem.FindFileInfo(full_path); @@ -448,14 +451,16 @@ void FilesystemPanel::ExtractDirectories(const std::string& full_path, wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | wxPD_SMOOTH); File::CreateFullPath(output_folder + "/" + full_path); - ExtractDir(full_path, output_folder, filesystem, *file_info, [&](const std::string& path) { - dialog.SetTitle(wxString::Format( - "%s : %d%%", dialog_title.c_str(), - static_cast((static_cast(progress) / static_cast(size)) * 100))); - dialog.Update(progress, wxString::Format(_("Extracting %s"), StrToWxStr(path))); - ++progress; - return dialog.WasCancelled(); - }); + ExtractDir( + full_path, output_folder, *m_opened_iso, filesystem.GetPartition(), *file_info, + [&](const std::string& path) { + dialog.SetTitle(wxString::Format( + "%s : %d%%", dialog_title.c_str(), + static_cast((static_cast(progress) / static_cast(size)) * 100))); + dialog.Update(progress, wxString::Format(_("Extracting %s"), StrToWxStr(path))); + ++progress; + return dialog.WasCancelled(); + }); } wxString FilesystemPanel::BuildFilePathFromSelection() const