FilesystemPanel: Put partitions in separate folders when extracting all partitions
This commit is contained in:
parent
478c4fd1f3
commit
a59edfe8cf
|
@ -6,15 +6,42 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
#include <locale>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
#include "DiscIO/Enums.h"
|
#include "DiscIO/Enums.h"
|
||||||
#include "DiscIO/Filesystem.h"
|
#include "DiscIO/Filesystem.h"
|
||||||
#include "DiscIO/Volume.h"
|
#include "DiscIO/Volume.h"
|
||||||
|
|
||||||
namespace DiscIO
|
namespace DiscIO
|
||||||
{
|
{
|
||||||
|
std::string DirectoryNameForPartitionType(u32 partition_type)
|
||||||
|
{
|
||||||
|
switch (partition_type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "DATA";
|
||||||
|
case 1:
|
||||||
|
return "UPDATE";
|
||||||
|
case 2:
|
||||||
|
return "CHANNEL";
|
||||||
|
default:
|
||||||
|
const std::string type_as_game_id{static_cast<char>((partition_type >> 24) & 0xFF),
|
||||||
|
static_cast<char>((partition_type >> 16) & 0xFF),
|
||||||
|
static_cast<char>((partition_type >> 8) & 0xFF),
|
||||||
|
static_cast<char>(partition_type & 0xFF)};
|
||||||
|
if (std::all_of(type_as_game_id.cbegin(), type_as_game_id.cend(),
|
||||||
|
[](char c) { return std::isprint(c, std::locale::classic()); }))
|
||||||
|
{
|
||||||
|
return "P-" + type_as_game_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringFromFormat("P%u", partition_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u64 ReadFile(const Volume& volume, const Partition& partition, const FileInfo* file_info,
|
u64 ReadFile(const Volume& volume, const Partition& partition, const FileInfo* file_info,
|
||||||
u8* buffer, u64 max_buffer_size, u64 offset_in_file)
|
u8* buffer, u64 max_buffer_size, u64 offset_in_file)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,8 @@ class FileInfo;
|
||||||
struct Partition;
|
struct Partition;
|
||||||
class Volume;
|
class Volume;
|
||||||
|
|
||||||
|
std::string DirectoryNameForPartitionType(u32 partition_type);
|
||||||
|
|
||||||
u64 ReadFile(const Volume& volume, const Partition& partition, const FileInfo* file_info,
|
u64 ReadFile(const Volume& volume, const Partition& partition, const FileInfo* file_info,
|
||||||
u8* buffer, u64 max_buffer_size, u64 offset_in_file = 0);
|
u8* buffer, u64 max_buffer_size, u64 offset_in_file = 0);
|
||||||
bool ExportData(const Volume& volume, const Partition& partition, u64 offset, u64 size,
|
bool ExportData(const Volume& volume, const Partition& partition, u64 offset, u64 size,
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
}
|
}
|
||||||
virtual std::vector<Partition> GetPartitions() const { return {}; }
|
virtual std::vector<Partition> GetPartitions() const { return {}; }
|
||||||
virtual Partition GetGamePartition() const { return PARTITION_NONE; }
|
virtual Partition GetGamePartition() const { return PARTITION_NONE; }
|
||||||
|
virtual std::optional<u32> GetPartitionType(const Partition& partition) const { return {}; }
|
||||||
std::optional<u64> GetTitleID() const { return GetTitleID(GetGamePartition()); }
|
std::optional<u64> GetTitleID() const { return GetTitleID(GetGamePartition()); }
|
||||||
virtual std::optional<u64> GetTitleID(const Partition& partition) const { return {}; }
|
virtual std::optional<u64> GetTitleID(const Partition& partition) const { return {}; }
|
||||||
virtual const IOS::ES::TicketReader& GetTicket(const Partition& partition) const
|
virtual const IOS::ES::TicketReader& GetTicket(const Partition& partition) const
|
||||||
|
|
|
@ -67,10 +67,11 @@ VolumeWii::VolumeWii(std::unique_ptr<BlobReader> reader)
|
||||||
continue;
|
continue;
|
||||||
const u64 partition_offset = static_cast<u64>(*read_buffer) << 2;
|
const u64 partition_offset = static_cast<u64>(*read_buffer) << 2;
|
||||||
|
|
||||||
// Check if this is the game partition
|
// Read the partition type
|
||||||
const bool is_game_partition =
|
const std::optional<u32> partition_type =
|
||||||
m_game_partition == PARTITION_NONE &&
|
m_pReader->ReadSwapped<u32>(partition_table_offset + (i * 8) + 4);
|
||||||
m_pReader->ReadSwapped<u32>(partition_table_offset + (i * 8) + 4) == u32(0);
|
if (!partition_type)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Read ticket
|
// Read ticket
|
||||||
std::vector<u8> ticket_buffer(sizeof(IOS::ES::Ticket));
|
std::vector<u8> ticket_buffer(sizeof(IOS::ES::Ticket));
|
||||||
|
@ -106,10 +107,11 @@ VolumeWii::VolumeWii(std::unique_ptr<BlobReader> reader)
|
||||||
// We've read everything. Time to store it! (The reason we don't store anything
|
// We've read everything. Time to store it! (The reason we don't store anything
|
||||||
// earlier is because we want to be able to skip adding the partition if an error occurs.)
|
// earlier is because we want to be able to skip adding the partition if an error occurs.)
|
||||||
const Partition partition(partition_offset);
|
const Partition partition(partition_offset);
|
||||||
|
m_partition_types[partition] = *partition_type;
|
||||||
m_partition_keys[partition] = std::move(aes_context);
|
m_partition_keys[partition] = std::move(aes_context);
|
||||||
m_partition_tickets[partition] = std::move(ticket);
|
m_partition_tickets[partition] = std::move(ticket);
|
||||||
m_partition_tmds[partition] = std::move(tmd);
|
m_partition_tmds[partition] = std::move(tmd);
|
||||||
if (is_game_partition)
|
if (m_game_partition == PARTITION_NONE && *partition_type == 0)
|
||||||
m_game_partition = partition;
|
m_game_partition = partition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,6 +187,12 @@ Partition VolumeWii::GetGamePartition() const
|
||||||
return m_game_partition;
|
return m_game_partition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<u32> VolumeWii::GetPartitionType(const Partition& partition) const
|
||||||
|
{
|
||||||
|
auto it = m_partition_types.find(partition);
|
||||||
|
return it != m_partition_types.end() ? it->second : std::optional<u32>();
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<u64> VolumeWii::GetTitleID(const Partition& partition) const
|
std::optional<u64> VolumeWii::GetTitleID(const Partition& partition) const
|
||||||
{
|
{
|
||||||
const IOS::ES::TicketReader& ticket = GetTicket(partition);
|
const IOS::ES::TicketReader& ticket = GetTicket(partition);
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
bool Read(u64 _Offset, u64 _Length, u8* _pBuffer, const Partition& partition) const override;
|
bool Read(u64 _Offset, u64 _Length, u8* _pBuffer, const Partition& partition) const override;
|
||||||
std::vector<Partition> GetPartitions() const override;
|
std::vector<Partition> GetPartitions() const override;
|
||||||
Partition GetGamePartition() const override;
|
Partition GetGamePartition() const override;
|
||||||
|
std::optional<u32> GetPartitionType(const Partition& partition) const override;
|
||||||
std::optional<u64> GetTitleID(const Partition& partition) const override;
|
std::optional<u64> GetTitleID(const Partition& partition) const override;
|
||||||
const IOS::ES::TicketReader& GetTicket(const Partition& partition) const override;
|
const IOS::ES::TicketReader& GetTicket(const Partition& partition) const override;
|
||||||
const IOS::ES::TMDReader& GetTMD(const Partition& partition) const override;
|
const IOS::ES::TMDReader& GetTMD(const Partition& partition) const override;
|
||||||
|
@ -64,6 +65,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<BlobReader> m_pReader;
|
std::unique_ptr<BlobReader> m_pReader;
|
||||||
|
std::map<Partition, u32> m_partition_types;
|
||||||
std::map<Partition, std::unique_ptr<mbedtls_aes_context>> m_partition_keys;
|
std::map<Partition, std::unique_ptr<mbedtls_aes_context>> m_partition_keys;
|
||||||
std::map<Partition, IOS::ES::TicketReader> m_partition_tickets;
|
std::map<Partition, IOS::ES::TicketReader> m_partition_tickets;
|
||||||
std::map<Partition, IOS::ES::TMDReader> m_partition_tmds;
|
std::map<Partition, IOS::ES::TMDReader> m_partition_tmds;
|
||||||
|
|
|
@ -277,6 +277,8 @@ void FilesystemPanel::OnExtractAll(wxCommandEvent& event)
|
||||||
if (extract_path.empty())
|
if (extract_path.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const std::string std_extract_path = WxStrToStr(extract_path);
|
||||||
|
|
||||||
const wxTreeItemId selection = m_tree_ctrl->GetSelection();
|
const wxTreeItemId selection = m_tree_ctrl->GetSelection();
|
||||||
const bool first_item_selected = m_tree_ctrl->GetFirstVisibleItem() == selection;
|
const bool first_item_selected = m_tree_ctrl->GetFirstVisibleItem() == selection;
|
||||||
|
|
||||||
|
@ -290,18 +292,24 @@ void FilesystemPanel::OnExtractAll(wxCommandEvent& event)
|
||||||
while (item.IsOk())
|
while (item.IsOk())
|
||||||
{
|
{
|
||||||
const auto* const partition = static_cast<WiiPartition*>(m_tree_ctrl->GetItemData(item));
|
const auto* const partition = static_cast<WiiPartition*>(m_tree_ctrl->GetItemData(item));
|
||||||
ExtractPartition(WxStrToStr(extract_path), *partition->filesystem);
|
const std::optional<u32> partition_type =
|
||||||
|
*m_opened_iso->GetPartitionType(partition->filesystem->GetPartition());
|
||||||
|
if (partition_type)
|
||||||
|
{
|
||||||
|
const std::string partition_name = DiscIO::DirectoryNameForPartitionType(*partition_type);
|
||||||
|
ExtractPartition(std_extract_path + '/' + partition_name, *partition->filesystem);
|
||||||
|
}
|
||||||
item = m_tree_ctrl->GetNextChild(root, cookie);
|
item = m_tree_ctrl->GetNextChild(root, cookie);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_has_partitions && !first_item_selected)
|
else if (m_has_partitions && !first_item_selected)
|
||||||
{
|
{
|
||||||
const auto* const partition = static_cast<WiiPartition*>(m_tree_ctrl->GetItemData(selection));
|
const auto* const partition = static_cast<WiiPartition*>(m_tree_ctrl->GetItemData(selection));
|
||||||
ExtractPartition(WxStrToStr(extract_path), *partition->filesystem);
|
ExtractPartition(std_extract_path, *partition->filesystem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ExtractPartition(WxStrToStr(extract_path), *m_filesystem);
|
ExtractPartition(std_extract_path, *m_filesystem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue