From 1b6506f4e8efb75ad075903a1f28581091a5806b Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 20 Jun 2017 17:31:50 +0200 Subject: [PATCH] DiscExtractor: Add support for more things to extract --- Source/Core/DiscIO/DiscExtractor.cpp | 143 +++++++++++++++++- Source/Core/DiscIO/DiscExtractor.h | 22 +++ .../ISOProperties/FilesystemPanel.cpp | 2 +- 3 files changed, 164 insertions(+), 3 deletions(-) diff --git a/Source/Core/DiscIO/DiscExtractor.cpp b/Source/Core/DiscIO/DiscExtractor.cpp index d0d7500897..f5dd28d9a5 100644 --- a/Source/Core/DiscIO/DiscExtractor.cpp +++ b/Source/Core/DiscIO/DiscExtractor.cpp @@ -103,6 +103,92 @@ void ExportDirectory(const Volume& volume, const Partition partition, const File } } +bool ExportWiiUnencryptedHeader(const Volume& volume, const std::string& export_filename) +{ + if (volume.GetVolumeType() != Platform::WII_DISC) + return false; + + return ExportData(volume, PARTITION_NONE, 0, 0x100, export_filename); +} + +bool ExportWiiRegionData(const Volume& volume, const std::string& export_filename) +{ + if (volume.GetVolumeType() != Platform::WII_DISC) + return false; + + return ExportData(volume, PARTITION_NONE, 0x4E000, 0x20, export_filename); +} + +bool ExportTicket(const Volume& volume, const Partition& partition, + const std::string& export_filename) +{ + if (volume.GetVolumeType() != Platform::WII_DISC) + return false; + + return ExportData(volume, PARTITION_NONE, partition.offset, 0x2a4, export_filename); +} + +bool ExportTMD(const Volume& volume, const Partition& partition, const std::string& export_filename) +{ + if (volume.GetVolumeType() != Platform::WII_DISC) + return false; + + std::optional size = volume.ReadSwapped(partition.offset + 0x2a4, PARTITION_NONE); + std::optional offset = volume.ReadSwapped(partition.offset + 0x2a8, PARTITION_NONE); + if (!size || !offset) + return false; + + const u64 actual_offset = partition.offset + (static_cast(*offset) << 2); + return ExportData(volume, PARTITION_NONE, actual_offset, *size, export_filename); +} + +bool ExportCertificateChain(const Volume& volume, const Partition& partition, + const std::string& export_filename) +{ + if (volume.GetVolumeType() != Platform::WII_DISC) + return false; + + std::optional size = volume.ReadSwapped(partition.offset + 0x2ac, PARTITION_NONE); + std::optional offset = volume.ReadSwapped(partition.offset + 0x2b0, PARTITION_NONE); + if (!size || !offset) + return false; + + const u64 actual_offset = partition.offset + (static_cast(*offset) << 2); + return ExportData(volume, PARTITION_NONE, actual_offset, *size, export_filename); +} + +bool ExportH3Hashes(const Volume& volume, const Partition& partition, + const std::string& export_filename) +{ + if (volume.GetVolumeType() != Platform::WII_DISC) + return false; + + std::optional offset = volume.ReadSwapped(partition.offset + 0x2b4, PARTITION_NONE); + if (!offset) + return false; + + const u64 actual_offset = partition.offset + (static_cast(*offset) << 2); + return ExportData(volume, PARTITION_NONE, actual_offset, 0x18000, export_filename); +} + +bool ExportHeader(const Volume& volume, const Partition& partition, + const std::string& export_filename) +{ + if (!IsDisc(volume.GetVolumeType())) + return false; + + return ExportData(volume, partition, 0, 0x440, export_filename); +} + +bool ExportBI2Data(const Volume& volume, const Partition& partition, + const std::string& export_filename) +{ + if (!IsDisc(volume.GetVolumeType())) + return false; + + return ExportData(volume, partition, 0x440, 0x2000, export_filename); +} + bool ExportApploader(const Volume& volume, const Partition& partition, const std::string& export_filename) { @@ -176,12 +262,65 @@ bool ExportDOL(const Volume& volume, const Partition& partition, const std::stri return ExportData(volume, partition, *dol_offset, *dol_size, export_filename); } +std::optional GetFSTOffset(const Volume& volume, const Partition& partition) +{ + const Platform volume_type = volume.GetVolumeType(); + if (!IsDisc(volume_type)) + return {}; + + const std::optional offset = volume.ReadSwapped(0x424, partition); + const u8 offset_shift = volume_type == Platform::WII_DISC ? 2 : 0; + return offset ? static_cast(*offset) << offset_shift : std::optional(); +} + +std::optional GetFSTSize(const Volume& volume, const Partition& partition) +{ + const Platform volume_type = volume.GetVolumeType(); + if (!IsDisc(volume_type)) + return {}; + + const std::optional size = volume.ReadSwapped(0x428, partition); + const u8 offset_shift = volume_type == Platform::WII_DISC ? 2 : 0; + return size ? static_cast(*size) << offset_shift : std::optional(); +} + +bool ExportFST(const Volume& volume, const Partition& partition, const std::string& export_filename) +{ + if (!IsDisc(volume.GetVolumeType())) + return false; + + const std::optional fst_offset = GetFSTOffset(volume, partition); + const std::optional fst_size = GetFSTSize(volume, partition); + if (!fst_offset || !fst_size) + return false; + + return ExportData(volume, partition, *fst_offset, *fst_size, export_filename); +} + bool ExportSystemData(const Volume& volume, const Partition& partition, const std::string& export_folder) { bool success = true; - success &= ExportApploader(volume, partition, export_folder + "/apploader.img"); - success &= ExportDOL(volume, partition, export_folder + "/boot.dol"); + + File::CreateFullPath(export_folder + "/sys/"); + success &= ExportHeader(volume, partition, export_folder + "/sys/boot.bin"); + success &= ExportBI2Data(volume, partition, export_folder + "/sys/bi2.bin"); + success &= ExportApploader(volume, partition, export_folder + "/sys/apploader.img"); + success &= ExportDOL(volume, partition, export_folder + "/sys/main.dol"); + success &= ExportFST(volume, partition, export_folder + "/sys/fst.bin"); + + if (volume.GetVolumeType() == Platform::WII_DISC) + { + File::CreateFullPath(export_folder + "/disc/"); + success &= ExportWiiUnencryptedHeader(volume, export_folder + "/disc/header.bin"); + success &= ExportWiiRegionData(volume, export_folder + "/disc/region.bin"); + + success &= ExportTicket(volume, partition, export_folder + "/ticket.bin"); + success &= ExportTMD(volume, partition, export_folder + "/tmd.bin"); + success &= ExportCertificateChain(volume, partition, export_folder + "/cert.bin"); + success &= ExportH3Hashes(volume, partition, export_folder + "/h3.bin"); + } + return success; } diff --git a/Source/Core/DiscIO/DiscExtractor.h b/Source/Core/DiscIO/DiscExtractor.h index c2db7f7a46..aa4d2ea3c5 100644 --- a/Source/Core/DiscIO/DiscExtractor.h +++ b/Source/Core/DiscIO/DiscExtractor.h @@ -30,12 +30,34 @@ void ExportDirectory(const Volume& volume, const Partition partition, const File const std::string& export_folder, const std::function& update_progress); +// To export everything listed below, you can use ExportSystemData + +bool ExportWiiUnencryptedHeader(const Volume& volume, const std::string& export_filename); +bool ExportWiiRegionData(const Volume& volume, const std::string& export_filename); + +bool ExportTicket(const Volume& volume, const Partition& partition, + const std::string& export_filename); +bool ExportTMD(const Volume& volume, const Partition& partition, + const std::string& export_filename); +bool ExportCertificateChain(const Volume& volume, const Partition& partition, + const std::string& export_filename); +bool ExportH3Hashes(const Volume& volume, const Partition& partition, + const std::string& export_filename); + +bool ExportHeader(const Volume& volume, const Partition& partition, + const std::string& export_filename); +bool ExportBI2Data(const Volume& volume, const Partition& partition, + const std::string& export_filename); bool ExportApploader(const Volume& volume, const Partition& partition, const std::string& export_filename); 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_filename); +std::optional GetFSTOffset(const Volume& volume, const Partition& partition); +std::optional GetFSTSize(const Volume& volume, const Partition& partition); +bool ExportFST(const Volume& volume, const Partition& partition, + const std::string& export_filename); bool ExportSystemData(const Volume& volume, const Partition& partition, const std::string& export_folder); diff --git a/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp index d0da889c47..4369d2ee3f 100644 --- a/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp +++ b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp @@ -382,7 +382,7 @@ void FilesystemPanel::ExtractDirectories(const std::string& full_path, void FilesystemPanel::ExtractPartition(const std::string& output_folder, const DiscIO::FileSystem& filesystem) { - ExtractDirectories("", output_folder, filesystem); + ExtractDirectories("", output_folder + "/files", filesystem); DiscIO::ExportSystemData(*m_opened_iso, filesystem.GetPartition(), output_folder); }