DiscIO: Use std::optional in Volume and Blob

This commit is contained in:
JosJuice 2017-06-04 10:33:14 +02:00
parent e23cfc2965
commit c3fa0d6edf
23 changed files with 232 additions and 237 deletions

View File

@ -4,6 +4,7 @@
#include "Core/Boot/Boot.h" #include "Core/Boot/Boot.h"
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -75,21 +76,19 @@ void CBoot::Load_FST(bool is_wii, const DiscIO::IVolume* volume)
if (is_wii) if (is_wii)
shift = 2; shift = 2;
u32 fst_offset = 0; const std::optional<u32> fst_offset = volume->ReadSwapped<u32>(0x0424, partition);
u32 fst_size = 0; const std::optional<u32> fst_size = volume->ReadSwapped<u32>(0x0428, partition);
u32 max_fst_size = 0; const std::optional<u32> max_fst_size = volume->ReadSwapped<u32>(0x042c, partition);
if (!fst_offset || !fst_size || !max_fst_size)
return;
volume->ReadSwapped(0x0424, &fst_offset, partition); u32 arena_high = Common::AlignDown(0x817FFFFF - (*max_fst_size << shift), 0x20);
volume->ReadSwapped(0x0428, &fst_size, partition);
volume->ReadSwapped(0x042c, &max_fst_size, partition);
u32 arena_high = Common::AlignDown(0x817FFFFF - (max_fst_size << shift), 0x20);
Memory::Write_U32(arena_high, 0x00000034); Memory::Write_U32(arena_high, 0x00000034);
// load FST // load FST
DVDRead(*volume, fst_offset << shift, arena_high, fst_size << shift, partition); DVDRead(*volume, *fst_offset << shift, arena_high, *fst_size << shift, partition);
Memory::Write_U32(arena_high, 0x00000038); Memory::Write_U32(arena_high, 0x00000038);
Memory::Write_U32(max_fst_size << shift, 0x0000003c); Memory::Write_U32(*max_fst_size << shift, 0x0000003c);
if (is_wii) if (is_wii)
{ {

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <map> #include <map>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -87,20 +88,16 @@ bool CBoot::RunApploader(bool is_wii, const DiscIO::IVolume& volume)
// Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc, // Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc,
// but the size can differ between discs. Compare with YAGCD chap 13. // but the size can differ between discs. Compare with YAGCD chap 13.
const u32 apploader_offset = 0x2440; constexpr u32 offset = 0x2440;
u32 apploader_entry = 0; const std::optional<u32> entry = volume.ReadSwapped<u32>(offset + 0x10, partition);
u32 apploader_size = 0; const std::optional<u32> size = volume.ReadSwapped<u32>(offset + 0x14, partition);
u32 apploader_trailer = 0; const std::optional<u32> trailer = volume.ReadSwapped<u32>(offset + 0x18, partition);
if (!volume.ReadSwapped(apploader_offset + 0x10, &apploader_entry, partition) || if (!entry || !size || !trailer || *entry == (u32)-1 || *size + *trailer == (u32)-1)
!volume.ReadSwapped(apploader_offset + 0x14, &apploader_size, partition) ||
!volume.ReadSwapped(apploader_offset + 0x18, &apploader_trailer, partition) ||
apploader_entry == (u32)-1 || apploader_size + apploader_trailer == (u32)-1)
{ {
INFO_LOG(BOOT, "Invalid apploader. Your disc image is probably corrupted."); INFO_LOG(BOOT, "Invalid apploader. Your disc image is probably corrupted.");
return false; return false;
} }
DVDRead(volume, apploader_offset + 0x20, 0x01200000, apploader_size + apploader_trailer, DVDRead(volume, offset + 0x20, 0x01200000, *size + *trailer, partition);
partition);
// TODO - Make Apploader(or just RunFunction()) debuggable!!! // TODO - Make Apploader(or just RunFunction()) debuggable!!!
@ -110,7 +107,7 @@ bool CBoot::RunApploader(bool is_wii, const DiscIO::IVolume& volume)
PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0; PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0;
PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4; PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8; PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
RunFunction(apploader_entry); RunFunction(*entry);
const u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0); const u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
const u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4); const u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
const u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8); const u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);

View File

@ -5,6 +5,7 @@
#include <cinttypes> #include <cinttypes>
#include <climits> #include <climits>
#include <memory> #include <memory>
#include <optional>
#include "AudioCommon/AudioCommon.h" #include "AudioCommon/AudioCommon.h"
@ -720,7 +721,8 @@ void SConfig::SetRunningGameMetadata(const DiscIO::IVolume& volume,
const DiscIO::Partition& partition) const DiscIO::Partition& partition)
{ {
SetRunningGameMetadata(volume.GetGameID(partition), volume.GetTitleID(partition).value_or(0), SetRunningGameMetadata(volume.GetGameID(partition), volume.GetTitleID(partition).value_or(0),
volume.GetRevision(partition), Core::TitleDatabase::TitleType::Other); volume.GetRevision(partition).value_or(0),
Core::TitleDatabase::TitleType::Other);
} }
void SConfig::SetRunningGameMetadata(const IOS::ES::TMDReader& tmd) void SConfig::SetRunningGameMetadata(const IOS::ES::TMDReader& tmd)
@ -1117,7 +1119,7 @@ IniFile SConfig::LoadGameIni() const
return LoadGameIni(GetGameID(), m_revision); return LoadGameIni(GetGameID(), m_revision);
} }
IniFile SConfig::LoadDefaultGameIni(const std::string& id, u16 revision) IniFile SConfig::LoadDefaultGameIni(const std::string& id, std::optional<u16> revision)
{ {
IniFile game_ini; IniFile game_ini;
for (const std::string& filename : GetGameIniFilenames(id, revision)) for (const std::string& filename : GetGameIniFilenames(id, revision))
@ -1125,7 +1127,7 @@ IniFile SConfig::LoadDefaultGameIni(const std::string& id, u16 revision)
return game_ini; return game_ini;
} }
IniFile SConfig::LoadLocalGameIni(const std::string& id, u16 revision) IniFile SConfig::LoadLocalGameIni(const std::string& id, std::optional<u16> revision)
{ {
IniFile game_ini; IniFile game_ini;
for (const std::string& filename : GetGameIniFilenames(id, revision)) for (const std::string& filename : GetGameIniFilenames(id, revision))
@ -1133,7 +1135,7 @@ IniFile SConfig::LoadLocalGameIni(const std::string& id, u16 revision)
return game_ini; return game_ini;
} }
IniFile SConfig::LoadGameIni(const std::string& id, u16 revision) IniFile SConfig::LoadGameIni(const std::string& id, std::optional<u16> revision)
{ {
IniFile game_ini; IniFile game_ini;
for (const std::string& filename : GetGameIniFilenames(id, revision)) for (const std::string& filename : GetGameIniFilenames(id, revision))
@ -1144,7 +1146,8 @@ IniFile SConfig::LoadGameIni(const std::string& id, u16 revision)
} }
// Returns all possible filenames in ascending order of priority // Returns all possible filenames in ascending order of priority
std::vector<std::string> SConfig::GetGameIniFilenames(const std::string& id, u16 revision) std::vector<std::string> SConfig::GetGameIniFilenames(const std::string& id,
std::optional<u16> revision)
{ {
std::vector<std::string> filenames; std::vector<std::string> filenames;
@ -1162,7 +1165,8 @@ std::vector<std::string> SConfig::GetGameIniFilenames(const std::string& id, u16
filenames.push_back(id + ".ini"); filenames.push_back(id + ".ini");
// INIs with specific revisions // INIs with specific revisions
filenames.push_back(id + StringFromFormat("r%d", revision) + ".ini"); if (revision)
filenames.push_back(id + StringFromFormat("r%d", *revision) + ".ini");
return filenames; return filenames;
} }

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <limits> #include <limits>
#include <optional>
#include <set> #include <set>
#include <string> #include <string>
#include <utility> #include <utility>
@ -238,11 +239,12 @@ struct SConfig : NonCopyable
IniFile LoadLocalGameIni() const; IniFile LoadLocalGameIni() const;
IniFile LoadGameIni() const; IniFile LoadGameIni() const;
static IniFile LoadDefaultGameIni(const std::string& id, u16 revision); static IniFile LoadDefaultGameIni(const std::string& id, std::optional<u16> revision);
static IniFile LoadLocalGameIni(const std::string& id, u16 revision); static IniFile LoadLocalGameIni(const std::string& id, std::optional<u16> revision);
static IniFile LoadGameIni(const std::string& id, u16 revision); static IniFile LoadGameIni(const std::string& id, std::optional<u16> revision);
static std::vector<std::string> GetGameIniFilenames(const std::string& id, u16 revision); static std::vector<std::string> GetGameIniFilenames(const std::string& id,
std::optional<u16> revision);
std::string m_NANDPath; std::string m_NANDPath;
std::string m_DumpPath; std::string m_DumpPath;

View File

@ -16,6 +16,7 @@
#include <array> #include <array>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -46,13 +47,12 @@ public:
// NOT thread-safe - can't call this from multiple threads. // NOT thread-safe - can't call this from multiple threads.
virtual bool Read(u64 offset, u64 size, u8* out_ptr) = 0; virtual bool Read(u64 offset, u64 size, u8* out_ptr) = 0;
template <typename T> template <typename T>
bool ReadSwapped(u64 offset, T* buffer) std::optional<T> ReadSwapped(u64 offset)
{ {
T temp; T temp;
if (!Read(offset, sizeof(T), reinterpret_cast<u8*>(&temp))) if (!Read(offset, sizeof(T), reinterpret_cast<u8*>(&temp)))
return false; return {};
*buffer = Common::FromBigEndian(temp); return Common::FromBigEndian(temp);
return true;
} }
protected: protected:

View File

@ -7,6 +7,7 @@
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -124,16 +125,18 @@ void DiscScrubber::MarkAsUsedE(u64 partition_data_offset, u64 offset, u64 size)
// Helper functions for reading the BE volume // Helper functions for reading the BE volume
bool DiscScrubber::ReadFromVolume(u64 offset, u32& buffer, const Partition& partition) bool DiscScrubber::ReadFromVolume(u64 offset, u32& buffer, const Partition& partition)
{ {
return m_disc->ReadSwapped(offset, &buffer, partition); std::optional<u32> value = m_disc->ReadSwapped<u32>(offset, partition);
if (value)
buffer = *value;
return value.has_value();
} }
bool DiscScrubber::ReadFromVolume(u64 offset, u64& buffer, const Partition& partition) bool DiscScrubber::ReadFromVolume(u64 offset, u64& buffer, const Partition& partition)
{ {
u32 temp_buffer; std::optional<u32> value = m_disc->ReadSwapped<u32>(offset, partition);
if (!m_disc->ReadSwapped(offset, &temp_buffer, partition)) if (value)
return false; buffer = static_cast<u64>(*value) << 2;
buffer = static_cast<u64>(temp_buffer) << 2; return value.has_value();
return true;
} }
bool DiscScrubber::ParseDisc() bool DiscScrubber::ParseDisc()
@ -197,10 +200,14 @@ bool DiscScrubber::ParsePartitionData(const Partition& partition, PartitionHeade
0x2440 + header->apploader_size + header->apploader_trailer_size); 0x2440 + header->apploader_size + header->apploader_trailer_size);
// DOL // DOL
header->dol_offset = filesystem->GetBootDOLOffset(); const std::optional<u64> dol_offset = filesystem->GetBootDOLOffset();
header->dol_size = filesystem->GetBootDOLSize(header->dol_offset); if (!dol_offset)
if (header->dol_offset == 0 || header->dol_size == 0)
return false; return false;
const std::optional<u64> dol_size = filesystem->GetBootDOLSize(*dol_offset);
if (!dol_size)
return false;
header->dol_offset = *dol_offset;
header->dol_size = *dol_size;
MarkAsUsedE(partition_data_offset, header->dol_offset, header->dol_size); MarkAsUsedE(partition_data_offset, header->dol_offset, header->dol_size);
// FST // FST

View File

@ -6,6 +6,7 @@
#include <cinttypes> #include <cinttypes>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -128,24 +129,23 @@ bool CFileSystemGCWii::ExportFile(const std::string& _rFullPath,
bool CFileSystemGCWii::ExportApploader(const std::string& _rExportFolder) const bool CFileSystemGCWii::ExportApploader(const std::string& _rExportFolder) const
{ {
u32 apploader_size; std::optional<u32> apploader_size = m_rVolume->ReadSwapped<u32>(0x2440 + 0x14, m_partition);
u32 trailer_size; const std::optional<u32> trailer_size = m_rVolume->ReadSwapped<u32>(0x2440 + 0x18, m_partition);
const u32 header_size = 0x20; constexpr u32 header_size = 0x20;
if (!m_rVolume->ReadSwapped(0x2440 + 0x14, &apploader_size, m_partition) || if (!apploader_size || !trailer_size)
!m_rVolume->ReadSwapped(0x2440 + 0x18, &trailer_size, m_partition))
return false; return false;
apploader_size += trailer_size + header_size; *apploader_size += *trailer_size + header_size;
DEBUG_LOG(DISCIO, "Apploader size -> %x", apploader_size); DEBUG_LOG(DISCIO, "Apploader size -> %x", *apploader_size);
std::vector<u8> buffer(apploader_size); std::vector<u8> buffer(*apploader_size);
if (m_rVolume->Read(0x2440, apploader_size, buffer.data(), m_partition)) if (m_rVolume->Read(0x2440, *apploader_size, buffer.data(), m_partition))
{ {
std::string exportName(_rExportFolder + "/apploader.img"); std::string exportName(_rExportFolder + "/apploader.img");
File::IOFile AppFile(exportName, "wb"); File::IOFile AppFile(exportName, "wb");
if (AppFile) if (AppFile)
{ {
AppFile.WriteBytes(buffer.data(), apploader_size); AppFile.WriteBytes(buffer.data(), *apploader_size);
return true; return true;
} }
} }
@ -153,40 +153,38 @@ bool CFileSystemGCWii::ExportApploader(const std::string& _rExportFolder) const
return false; return false;
} }
u64 CFileSystemGCWii::GetBootDOLOffset() const std::optional<u64> CFileSystemGCWii::GetBootDOLOffset() const
{ {
u32 offset = 0; std::optional<u32> offset = m_rVolume->ReadSwapped<u32>(0x420, m_partition);
m_rVolume->ReadSwapped(0x420, &offset, m_partition); return offset ? static_cast<u64>(*offset) << 2 : std::optional<u64>();
return static_cast<u64>(offset) << m_offset_shift;
} }
u32 CFileSystemGCWii::GetBootDOLSize(u64 dol_offset) const std::optional<u32> CFileSystemGCWii::GetBootDOLSize(u64 dol_offset) const
{ {
// The dol_offset value is usually obtained by calling GetBootDOLOffset.
// If GetBootDOLOffset fails by returning 0, GetBootDOLSize should also fail.
if (dol_offset == 0)
return 0;
u32 dol_size = 0; u32 dol_size = 0;
u32 offset = 0;
u32 size = 0;
// Iterate through the 7 code segments // Iterate through the 7 code segments
for (u8 i = 0; i < 7; i++) for (u8 i = 0; i < 7; i++)
{ {
if (!m_rVolume->ReadSwapped(dol_offset + 0x00 + i * 4, &offset, m_partition) || const std::optional<u32> offset =
!m_rVolume->ReadSwapped(dol_offset + 0x90 + i * 4, &size, m_partition)) m_rVolume->ReadSwapped<u32>(dol_offset + 0x00 + i * 4, m_partition);
return 0; const std::optional<u32> size =
dol_size = std::max(offset + size, dol_size); m_rVolume->ReadSwapped<u32>(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 // Iterate through the 11 data segments
for (u8 i = 0; i < 11; i++) for (u8 i = 0; i < 11; i++)
{ {
if (!m_rVolume->ReadSwapped(dol_offset + 0x1c + i * 4, &offset, m_partition) || const std::optional<u32> offset =
!m_rVolume->ReadSwapped(dol_offset + 0xac + i * 4, &size, m_partition)) m_rVolume->ReadSwapped<u32>(dol_offset + 0x1c + i * 4, m_partition);
return 0; const std::optional<u32> size =
dol_size = std::max(offset + size, dol_size); m_rVolume->ReadSwapped<u32>(dol_offset + 0xac + i * 4, m_partition);
if (!offset || !size)
return {};
dol_size = std::max(*offset + *size, dol_size);
} }
return dol_size; return dol_size;
@ -194,21 +192,22 @@ u32 CFileSystemGCWii::GetBootDOLSize(u64 dol_offset) const
bool CFileSystemGCWii::ExportDOL(const std::string& _rExportFolder) const bool CFileSystemGCWii::ExportDOL(const std::string& _rExportFolder) const
{ {
u64 DolOffset = GetBootDOLOffset(); std::optional<u64> dol_offset = GetBootDOLOffset();
u32 DolSize = GetBootDOLSize(DolOffset); if (!dol_offset)
return false;
if (DolOffset == 0 || DolSize == 0) std::optional<u32> dol_size = GetBootDOLSize(*dol_offset);
if (!dol_size)
return false; return false;
std::vector<u8> buffer(DolSize); std::vector<u8> buffer(*dol_size);
if (m_rVolume->Read(DolOffset, DolSize, &buffer[0], m_partition)) if (m_rVolume->Read(*dol_offset, *dol_size, &buffer[0], m_partition))
{ {
std::string exportName(_rExportFolder + "/boot.dol"); std::string exportName(_rExportFolder + "/boot.dol");
File::IOFile DolFile(exportName, "wb"); File::IOFile DolFile(exportName, "wb");
if (DolFile) if (DolFile)
{ {
DolFile.WriteBytes(&buffer[0], DolSize); DolFile.WriteBytes(&buffer[0], *dol_size);
return true; return true;
} }
} }
@ -251,13 +250,12 @@ const SFileInfo* CFileSystemGCWii::FindFileInfo(const std::string& _rFullPath)
bool CFileSystemGCWii::DetectFileSystem() bool CFileSystemGCWii::DetectFileSystem()
{ {
u32 magic_bytes; if (m_rVolume->ReadSwapped<u32>(0x18, m_partition) == u32(0x5D1C9EA3))
if (m_rVolume->ReadSwapped(0x18, &magic_bytes, m_partition) && magic_bytes == 0x5D1C9EA3)
{ {
m_offset_shift = 2; // Wii file system m_offset_shift = 2; // Wii file system
return true; return true;
} }
else if (m_rVolume->ReadSwapped(0x1c, &magic_bytes, m_partition) && magic_bytes == 0xC2339F3D) else if (m_rVolume->ReadSwapped<u32>(0x1c, m_partition) == u32(0xC2339F3D))
{ {
m_offset_shift = 0; // GameCube file system m_offset_shift = 0; // GameCube file system
return true; return true;
@ -271,18 +269,19 @@ void CFileSystemGCWii::InitFileSystem()
m_Initialized = true; m_Initialized = true;
// read the whole FST // read the whole FST
u32 fst_offset_unshifted; const std::optional<u32> fst_offset_unshifted = m_rVolume->ReadSwapped<u32>(0x424, m_partition);
if (!m_rVolume->ReadSwapped(0x424, &fst_offset_unshifted, m_partition)) if (!fst_offset_unshifted)
return; return;
u64 FSTOffset = static_cast<u64>(fst_offset_unshifted) << m_offset_shift; const u64 FSTOffset = static_cast<u64>(*fst_offset_unshifted) << m_offset_shift;
// read all fileinfos // read all fileinfos
u32 name_offset, offset, size; const std::optional<u32> root_name_offset = m_rVolume->ReadSwapped<u32>(FSTOffset, m_partition);
if (!m_rVolume->ReadSwapped(FSTOffset + 0x0, &name_offset, m_partition) || const std::optional<u32> root_offset = m_rVolume->ReadSwapped<u32>(FSTOffset + 0x4, m_partition);
!m_rVolume->ReadSwapped(FSTOffset + 0x4, &offset, m_partition) || const std::optional<u32> root_size = m_rVolume->ReadSwapped<u32>(FSTOffset + 0x8, m_partition);
!m_rVolume->ReadSwapped(FSTOffset + 0x8, &size, m_partition)) if (!root_name_offset || !root_offset || !root_size)
return; return;
SFileInfo root = {name_offset, static_cast<u64>(offset) << m_offset_shift, size}; SFileInfo root = {*root_name_offset, static_cast<u64>(*root_offset) << m_offset_shift,
*root_size};
if (!root.IsDirectory()) if (!root.IsDirectory())
return; return;
@ -307,13 +306,12 @@ void CFileSystemGCWii::InitFileSystem()
for (u32 i = 0; i < root.m_FileSize; i++) for (u32 i = 0; i < root.m_FileSize; i++)
{ {
const u64 read_offset = FSTOffset + (i * 0xC); const u64 read_offset = FSTOffset + (i * 0xC);
name_offset = 0; const std::optional<u32> name_offset = m_rVolume->ReadSwapped<u32>(read_offset, m_partition);
m_rVolume->ReadSwapped(read_offset + 0x0, &name_offset, m_partition); const std::optional<u32> offset = m_rVolume->ReadSwapped<u32>(read_offset + 0x4, m_partition);
offset = 0; const std::optional<u32> size = m_rVolume->ReadSwapped<u32>(read_offset + 0x8, m_partition);
m_rVolume->ReadSwapped(read_offset + 0x4, &offset, m_partition); m_FileInfoVector.emplace_back(name_offset.value_or(0),
size = 0; static_cast<u64>(offset.value_or(0)) << m_offset_shift,
m_rVolume->ReadSwapped(read_offset + 0x8, &size, m_partition); size.value_or(0));
m_FileInfoVector.emplace_back(name_offset, static_cast<u64>(offset) << m_offset_shift, size);
NameTableOffset += 0xC; NameTableOffset += 0xC;
} }

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <cstddef> #include <cstddef>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -31,8 +32,8 @@ public:
bool ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename) override; bool ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename) override;
bool ExportApploader(const std::string& _rExportFolder) const override; bool ExportApploader(const std::string& _rExportFolder) const override;
bool ExportDOL(const std::string& _rExportFolder) const override; bool ExportDOL(const std::string& _rExportFolder) const override;
u64 GetBootDOLOffset() const override; std::optional<u64> GetBootDOLOffset() const override;
u32 GetBootDOLSize(u64 dol_offset) const override; std::optional<u32> GetBootDOLSize(u64 dol_offset) const override;
private: private:
bool m_Initialized; bool m_Initialized;

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -46,8 +47,8 @@ public:
virtual bool ExportApploader(const std::string& _rExportFolder) const = 0; virtual bool ExportApploader(const std::string& _rExportFolder) const = 0;
virtual bool ExportDOL(const std::string& _rExportFolder) const = 0; virtual bool ExportDOL(const std::string& _rExportFolder) const = 0;
virtual std::string GetFileName(u64 _Address) = 0; virtual std::string GetFileName(u64 _Address) = 0;
virtual u64 GetBootDOLOffset() const = 0; virtual std::optional<u64> GetBootDOLOffset() const = 0;
virtual u32 GetBootDOLSize(u64 dol_offset) const = 0; virtual std::optional<u32> GetBootDOLSize(u64 dol_offset) const = 0;
virtual const Partition GetPartition() const { return m_partition; } virtual const Partition GetPartition() const { return m_partition; }
protected: protected:

View File

@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -93,26 +94,25 @@ std::unique_ptr<IVolume> CreateVolumeFromFilename(const std::string& filename)
return nullptr; return nullptr;
// Check for Wii // Check for Wii
u32 wii_magic = 0; const std::optional<u32> wii_magic = reader->ReadSwapped<u32>(0x18);
reader->ReadSwapped(0x18, &wii_magic); if (wii_magic == u32(0x5D1C9EA3))
u32 wii_container_magic = 0; {
reader->ReadSwapped(0x60, &wii_container_magic); const std::optional<u32> wii_container_magic = reader->ReadSwapped<u32>(0x60);
if (wii_magic == 0x5D1C9EA3 && wii_container_magic != 0) if (wii_container_magic == u32(0))
return std::make_unique<CVolumeWiiCrypted>(std::move(reader));
return std::make_unique<CVolumeGC>(std::move(reader)); return std::make_unique<CVolumeGC>(std::move(reader));
if (wii_magic == 0x5D1C9EA3 && wii_container_magic == 0) }
return std::make_unique<CVolumeWiiCrypted>(std::move(reader));
// Check for WAD // Check for WAD
// 0x206962 for boot2 wads // 0x206962 for boot2 wads
u32 wad_magic = 0; const std::optional<u32> wad_magic = reader->ReadSwapped<u32>(0x02);
reader->ReadSwapped(0x02, &wad_magic); if (wad_magic == u32(0x00204973) || wad_magic == u32(0x00206962))
if (wad_magic == 0x00204973 || wad_magic == 0x00206962)
return std::make_unique<CVolumeWAD>(std::move(reader)); return std::make_unique<CVolumeWAD>(std::move(reader));
// Check for GC // Check for GC
u32 gc_magic = 0; const std::optional<u32> gc_magic = reader->ReadSwapped<u32>(0x1C);
reader->ReadSwapped(0x1C, &gc_magic); if (gc_magic == u32(0xC2339F3D))
if (gc_magic == 0xC2339F3D)
return std::make_unique<CVolumeGC>(std::move(reader)); return std::make_unique<CVolumeGC>(std::move(reader));
// No known magic words found // No known magic words found

View File

@ -44,13 +44,12 @@ public:
virtual ~IVolume() {} virtual ~IVolume() {}
virtual bool Read(u64 _Offset, u64 _Length, u8* _pBuffer, const Partition& partition) const = 0; virtual bool Read(u64 _Offset, u64 _Length, u8* _pBuffer, const Partition& partition) const = 0;
template <typename T> template <typename T>
bool ReadSwapped(u64 offset, T* buffer, const Partition& partition) const std::optional<T> ReadSwapped(u64 offset, const Partition& partition) const
{ {
T temp; T temp;
if (!Read(offset, sizeof(T), reinterpret_cast<u8*>(&temp), partition)) if (!Read(offset, sizeof(T), reinterpret_cast<u8*>(&temp), partition))
return false; return {};
*buffer = Common::FromBigEndian(temp); return Common::FromBigEndian(temp);
return true;
} }
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; }
@ -65,8 +64,8 @@ public:
virtual std::string GetGameID(const Partition& partition) const = 0; virtual std::string GetGameID(const Partition& partition) const = 0;
std::string GetMakerID() const { return GetMakerID(GetGamePartition()); } std::string GetMakerID() const { return GetMakerID(GetGamePartition()); }
virtual std::string GetMakerID(const Partition& partition) const = 0; virtual std::string GetMakerID(const Partition& partition) const = 0;
u16 GetRevision() const { return GetRevision(GetGamePartition()); } std::optional<u16> GetRevision() const { return GetRevision(GetGamePartition()); }
virtual u16 GetRevision(const Partition& partition) const = 0; virtual std::optional<u16> GetRevision(const Partition& partition) const = 0;
std::string GetInternalName() const { return GetInternalName(GetGamePartition()); } std::string GetInternalName() const { return GetInternalName(GetGamePartition()); }
virtual std::string GetInternalName(const Partition& partition) const = 0; virtual std::string GetInternalName(const Partition& partition) const = 0;
virtual std::map<Language, std::string> GetShortNames() const { return {}; } virtual std::map<Language, std::string> GetShortNames() const { return {}; }
@ -78,8 +77,8 @@ public:
std::string GetApploaderDate() const { return GetApploaderDate(GetGamePartition()); } std::string GetApploaderDate() const { return GetApploaderDate(GetGamePartition()); }
virtual std::string GetApploaderDate(const Partition& partition) const = 0; virtual std::string GetApploaderDate(const Partition& partition) const = 0;
// 0 is the first disc, 1 is the second disc // 0 is the first disc, 1 is the second disc
u8 GetDiscNumber() const { return GetDiscNumber(GetGamePartition()); } std::optional<u8> GetDiscNumber() const { return GetDiscNumber(GetGamePartition()); }
virtual u8 GetDiscNumber(const Partition& partition) const { return 0; } virtual std::optional<u8> GetDiscNumber(const Partition& partition) const { return 0; }
virtual Platform GetVolumeType() const = 0; virtual Platform GetVolumeType() const = 0;
virtual bool SupportsIntegrityCheck() const { return false; } virtual bool SupportsIntegrityCheck() const { return false; }
virtual bool CheckIntegrity(const Partition& partition) const { return false; } virtual bool CheckIntegrity(const Partition& partition) const { return false; }

View File

@ -8,6 +8,7 @@
#include <locale> #include <locale>
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>

View File

@ -6,6 +6,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -48,7 +49,10 @@ public:
std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override; std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override;
u16 GetRevision(const Partition& partition = PARTITION_NONE) const override { return 0; } std::optional<u16> GetRevision(const Partition& partition = PARTITION_NONE) const override
{
return {};
}
std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override; std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override;
std::map<Language, std::string> GetLongNames() const override; std::map<Language, std::string> GetLongNames() const override;
std::vector<u32> GetBanner(int* width, int* height) const override; std::vector<u32> GetBanner(int* width, int* height) const override;

View File

@ -5,6 +5,7 @@
#include <cstddef> #include <cstddef>
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -57,20 +58,14 @@ std::string CVolumeGC::GetGameID(const Partition& partition) const
Region CVolumeGC::GetRegion() const Region CVolumeGC::GetRegion() const
{ {
u8 country_code; const std::optional<u8> country_code = ReadSwapped<u8>(3, PARTITION_NONE);
if (!ReadSwapped(3, &country_code, PARTITION_NONE)) return country_code ? RegionSwitchGC(*country_code) : Region::UNKNOWN_REGION;
return Region::UNKNOWN_REGION;
return RegionSwitchGC(country_code);
} }
Country CVolumeGC::GetCountry(const Partition& partition) const Country CVolumeGC::GetCountry(const Partition& partition) const
{ {
u8 country_code; const std::optional<u8> country_code = ReadSwapped<u8>(3, partition);
if (!ReadSwapped(3, &country_code, partition)) return country_code ? CountrySwitch(*country_code) : Country::COUNTRY_UNKNOWN;
return Country::COUNTRY_UNKNOWN;
return CountrySwitch(country_code);
} }
std::string CVolumeGC::GetMakerID(const Partition& partition) const std::string CVolumeGC::GetMakerID(const Partition& partition) const
@ -82,13 +77,10 @@ std::string CVolumeGC::GetMakerID(const Partition& partition) const
return DecodeString(makerID); return DecodeString(makerID);
} }
u16 CVolumeGC::GetRevision(const Partition& partition) const std::optional<u16> CVolumeGC::GetRevision(const Partition& partition) const
{ {
u8 revision; std::optional<u8> revision = ReadSwapped<u8>(7, partition);
if (!ReadSwapped(7, &revision, partition)) return revision ? *revision : std::optional<u16>();
return 0;
return revision;
} }
std::string CVolumeGC::GetInternalName(const Partition& partition) const std::string CVolumeGC::GetInternalName(const Partition& partition) const
@ -162,11 +154,9 @@ u64 CVolumeGC::GetRawSize() const
return m_pReader->GetRawSize(); return m_pReader->GetRawSize();
} }
u8 CVolumeGC::GetDiscNumber(const Partition& partition) const std::optional<u8> CVolumeGC::GetDiscNumber(const Partition& partition) const
{ {
u8 disc_number = 0; return ReadSwapped<u8>(6, partition);
ReadSwapped(6, &disc_number, partition);
return disc_number;
} }
Platform CVolumeGC::GetVolumeType() const Platform CVolumeGC::GetVolumeType() const

View File

@ -6,6 +6,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@ -32,7 +33,7 @@ public:
const Partition& partition = PARTITION_NONE) const override; const Partition& partition = PARTITION_NONE) const override;
std::string GetGameID(const Partition& partition = PARTITION_NONE) const override; std::string GetGameID(const Partition& partition = PARTITION_NONE) const override;
std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override; std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override;
u16 GetRevision(const Partition& partition = PARTITION_NONE) const override; std::optional<u16> GetRevision(const Partition& partition = PARTITION_NONE) const override;
std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override; std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override;
std::map<Language, std::string> GetShortNames() const override; std::map<Language, std::string> GetShortNames() const override;
std::map<Language, std::string> GetLongNames() const override; std::map<Language, std::string> GetLongNames() const override;
@ -41,7 +42,7 @@ public:
std::map<Language, std::string> GetDescriptions() const override; std::map<Language, std::string> GetDescriptions() const override;
std::vector<u32> GetBanner(int* width, int* height) const override; std::vector<u32> GetBanner(int* width, int* height) const override;
std::string GetApploaderDate(const Partition& partition = PARTITION_NONE) const override; std::string GetApploaderDate(const Partition& partition = PARTITION_NONE) const override;
u8 GetDiscNumber(const Partition& partition = PARTITION_NONE) const override; std::optional<u8> GetDiscNumber(const Partition& partition = PARTITION_NONE) const override;
Platform GetVolumeType() const override; Platform GetVolumeType() const override;
Region GetRegion() const override; Region GetRegion() const override;

View File

@ -7,6 +7,7 @@
#include <locale> #include <locale>
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -29,11 +30,11 @@ CVolumeWAD::CVolumeWAD(std::unique_ptr<IBlobReader> reader) : m_reader(std::move
_assert_(m_reader); _assert_(m_reader);
// Source: http://wiibrew.org/wiki/WAD_files // Source: http://wiibrew.org/wiki/WAD_files
m_reader->ReadSwapped(0x00, &m_hdr_size); m_hdr_size = m_reader->ReadSwapped<u32>(0x00).value_or(0);
m_reader->ReadSwapped(0x08, &m_cert_size); m_cert_size = m_reader->ReadSwapped<u32>(0x08).value_or(0);
m_reader->ReadSwapped(0x10, &m_tick_size); m_tick_size = m_reader->ReadSwapped<u32>(0x10).value_or(0);
m_reader->ReadSwapped(0x14, &m_tmd_size); m_tmd_size = m_reader->ReadSwapped<u32>(0x14).value_or(0);
m_reader->ReadSwapped(0x18, &m_data_size); m_data_size = m_reader->ReadSwapped<u32>(0x18).value_or(0);
m_offset = Common::AlignUp(m_hdr_size, 0x40) + Common::AlignUp(m_cert_size, 0x40); m_offset = Common::AlignUp(m_hdr_size, 0x40) + Common::AlignUp(m_cert_size, 0x40);
m_tmd_offset = Common::AlignUp(m_hdr_size, 0x40) + Common::AlignUp(m_cert_size, 0x40) + m_tmd_offset = Common::AlignUp(m_hdr_size, 0x40) + Common::AlignUp(m_cert_size, 0x40) +
@ -109,16 +110,13 @@ std::string CVolumeWAD::GetMakerID(const Partition& partition) const
std::optional<u64> CVolumeWAD::GetTitleID(const Partition& partition) const std::optional<u64> CVolumeWAD::GetTitleID(const Partition& partition) const
{ {
u64 title_id; return ReadSwapped<u64>(m_offset + 0x01DC, partition);
if (!ReadSwapped(m_offset + 0x01DC, &title_id, partition))
return {};
return title_id;
} }
u16 CVolumeWAD::GetRevision(const Partition& partition) const std::optional<u16> CVolumeWAD::GetRevision(const Partition& partition) const
{ {
if (!m_tmd.IsValid()) if (!m_tmd.IsValid())
return 0; return {};
return m_tmd.GetTitleVersion(); return m_tmd.GetTitleVersion();
} }

View File

@ -38,7 +38,7 @@ public:
const IOS::ES::TMDReader& GetTMD(const Partition& partition = PARTITION_NONE) const override; const IOS::ES::TMDReader& GetTMD(const Partition& partition = PARTITION_NONE) const override;
std::string GetGameID(const Partition& partition = PARTITION_NONE) const override; std::string GetGameID(const Partition& partition = PARTITION_NONE) const override;
std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override; std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override;
u16 GetRevision(const Partition& partition = PARTITION_NONE) const override; std::optional<u16> GetRevision(const Partition& partition = PARTITION_NONE) const override;
std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override
{ {
return ""; return "";

View File

@ -11,6 +11,7 @@
#include <mbedtls/aes.h> #include <mbedtls/aes.h>
#include <mbedtls/sha1.h> #include <mbedtls/sha1.h>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -38,30 +39,30 @@ CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr<IBlobReader> reader)
// Get tickets, TMDs, and decryption keys for all partitions // Get tickets, TMDs, and decryption keys for all partitions
for (u32 partition_group = 0; partition_group < 4; ++partition_group) for (u32 partition_group = 0; partition_group < 4; ++partition_group)
{ {
u32 number_of_partitions; const std::optional<u32> number_of_partitions =
if (!m_pReader->ReadSwapped(0x40000 + (partition_group * 8), &number_of_partitions)) m_pReader->ReadSwapped<u32>(0x40000 + (partition_group * 8));
if (!number_of_partitions)
continue; continue;
u32 read_buffer; std::optional<u32> read_buffer = m_pReader->ReadSwapped<u32>(0x40000 + (partition_group * 8) + 4);
if (!m_pReader->ReadSwapped(0x40000 + (partition_group * 8) + 4, &read_buffer)) if (!read_buffer)
continue; continue;
const u64 partition_table_offset = (u64)read_buffer << 2; const u64 partition_table_offset = static_cast<u64>(*read_buffer) << 2;
for (u32 i = 0; i < number_of_partitions; i++) for (u32 i = 0; i < number_of_partitions; i++)
{ {
// Read the partition offset // Read the partition offset
if (!m_pReader->ReadSwapped(partition_table_offset + (i * 8), &read_buffer)) read_buffer = m_pReader->ReadSwapped<u32>(partition_table_offset + (i * 8));
if (!read_buffer)
continue; continue;
const u64 partition_offset = (u64)read_buffer << 2; const u64 partition_offset = static_cast<u64>(*read_buffer) << 2;
// Set m_game_partition if this is the game partition // Set m_game_partition if this is the game partition
if (m_game_partition == PARTITION_NONE) if (m_game_partition == PARTITION_NONE)
{ {
u32 partition_type; const std::optional<u32> partition_type =
if (!m_pReader->ReadSwapped(partition_table_offset + (i * 8) + 4, &partition_type)) m_pReader->ReadSwapped<u32>(partition_table_offset + (i * 8) + 4);
continue; if (partition_type == u32(0))
if (partition_type == 0)
m_game_partition = Partition(partition_offset); m_game_partition = Partition(partition_offset);
} }
@ -74,22 +75,20 @@ CVolumeWiiCrypted::CVolumeWiiCrypted(std::unique_ptr<IBlobReader> reader)
continue; continue;
// Read TMD // Read TMD
u32 tmd_size = 0; const std::optional<u32> tmd_size = m_pReader->ReadSwapped<u32>(partition_offset + 0x2a4);
u32 tmd_address = 0; std::optional<u32> tmd_address = m_pReader->ReadSwapped<u32>(partition_offset + 0x2a8);
if (!m_pReader->ReadSwapped(partition_offset + 0x2a4, &tmd_size)) if (!tmd_size || !tmd_address)
continue; continue;
if (!m_pReader->ReadSwapped(partition_offset + 0x2a8, &tmd_address)) *tmd_address <<= 2;
continue; if (!IOS::ES::IsValidTMDSize(*tmd_size))
tmd_address <<= 2;
if (!IOS::ES::IsValidTMDSize(tmd_size))
{ {
// This check is normally done by ES in ES_DiVerify, but that would happen too late // This check is normally done by ES in ES_DiVerify, but that would happen too late
// (after allocating the buffer), so we do the check here. // (after allocating the buffer), so we do the check here.
PanicAlert("Invalid TMD size"); PanicAlert("Invalid TMD size");
continue; continue;
} }
std::vector<u8> tmd_buffer(tmd_size); std::vector<u8> tmd_buffer(*tmd_size);
if (!m_pReader->Read(partition_offset + tmd_address, tmd_size, tmd_buffer.data())) if (!m_pReader->Read(partition_offset + *tmd_address, *tmd_size, tmd_buffer.data()))
continue; continue;
IOS::ES::TMDReader tmd{std::move(tmd_buffer)}; IOS::ES::TMDReader tmd{std::move(tmd_buffer)};
@ -222,19 +221,14 @@ std::string CVolumeWiiCrypted::GetGameID(const Partition& partition) const
Region CVolumeWiiCrypted::GetRegion() const Region CVolumeWiiCrypted::GetRegion() const
{ {
u32 region_code; const std::optional<u32> region_code = m_pReader->ReadSwapped<u32>(0x4E000);
if (!m_pReader->ReadSwapped(0x4E000, &region_code)) return region_code ? static_cast<Region>(*region_code) : Region::UNKNOWN_REGION;
return Region::UNKNOWN_REGION;
return static_cast<Region>(region_code);
} }
Country CVolumeWiiCrypted::GetCountry(const Partition& partition) const Country CVolumeWiiCrypted::GetCountry(const Partition& partition) const
{ {
u8 country_byte; // The 0 that we use as a default value is mapped to COUNTRY_UNKNOWN and UNKNOWN_REGION
if (!ReadSwapped(3, &country_byte, partition)) u8 country_byte = ReadSwapped<u8>(3, partition).value_or(0);
return Country::COUNTRY_UNKNOWN;
const Region region = GetRegion(); const Region region = GetRegion();
if (RegionSwitchWii(country_byte) != region) if (RegionSwitchWii(country_byte) != region)
@ -253,13 +247,10 @@ std::string CVolumeWiiCrypted::GetMakerID(const Partition& partition) const
return DecodeString(makerID); return DecodeString(makerID);
} }
u16 CVolumeWiiCrypted::GetRevision(const Partition& partition) const std::optional<u16> CVolumeWiiCrypted::GetRevision(const Partition& partition) const
{ {
u8 revision; std::optional<u8> revision = ReadSwapped<u8>(7, partition);
if (!ReadSwapped(7, &revision, partition)) return revision ? *revision : std::optional<u16>();
return 0;
return revision;
} }
std::string CVolumeWiiCrypted::GetInternalName(const Partition& partition) const std::string CVolumeWiiCrypted::GetInternalName(const Partition& partition) const
@ -310,11 +301,9 @@ Platform CVolumeWiiCrypted::GetVolumeType() const
return Platform::WII_DISC; return Platform::WII_DISC;
} }
u8 CVolumeWiiCrypted::GetDiscNumber(const Partition& partition) const std::optional<u8> CVolumeWiiCrypted::GetDiscNumber(const Partition& partition) const
{ {
u8 disc_number = 0; return ReadSwapped<u8>(6, partition);
ReadSwapped(6, &disc_number, partition);
return disc_number;
} }
BlobType CVolumeWiiCrypted::GetBlobType() const BlobType CVolumeWiiCrypted::GetBlobType() const

View File

@ -39,12 +39,12 @@ public:
const IOS::ES::TMDReader& GetTMD(const Partition& partition) const override; const IOS::ES::TMDReader& GetTMD(const Partition& partition) const override;
std::string GetGameID(const Partition& partition) const override; std::string GetGameID(const Partition& partition) const override;
std::string GetMakerID(const Partition& partition) const override; std::string GetMakerID(const Partition& partition) const override;
u16 GetRevision(const Partition& partition) const override; std::optional<u16> GetRevision(const Partition& partition) const override;
std::string GetInternalName(const Partition& partition) const override; std::string GetInternalName(const Partition& partition) const override;
std::map<Language, std::string> GetLongNames() const override; std::map<Language, std::string> GetLongNames() const override;
std::vector<u32> GetBanner(int* width, int* height) const override; std::vector<u32> GetBanner(int* width, int* height) const override;
std::string GetApploaderDate(const Partition& partition) const override; std::string GetApploaderDate(const Partition& partition) const override;
u8 GetDiscNumber(const Partition& partition) const override; std::optional<u8> GetDiscNumber(const Partition& partition) const override;
Platform GetVolumeType() const override; Platform GetVolumeType() const override;
bool SupportsIntegrityCheck() const override { return true; } bool SupportsIntegrityCheck() const override { return true; }

View File

@ -4,6 +4,7 @@
#include <cstddef> #include <cstddef>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include "Common/Align.h" #include "Common/Align.h"
@ -36,11 +37,10 @@ std::vector<u8> CreateWADEntry(IBlobReader& reader, u32 size, u64 offset)
bool IsWiiWAD(IBlobReader& reader) bool IsWiiWAD(IBlobReader& reader)
{ {
u32 header_size = 0; const std::optional<u32> header_size = reader.ReadSwapped<u32>(0x0);
u32 header_type = 0; const std::optional<u32> header_type = reader.ReadSwapped<u32>(0x4);
reader.ReadSwapped(0x0, &header_size); return header_size == u32(0x20) &&
reader.ReadSwapped(0x4, &header_type); (header_type == u32(0x49730000) || header_type == u32(0x69620000));
return header_size == 0x20 && (header_type == 0x49730000 || header_type == 0x69620000);
} }
} // Anonymous namespace } // Anonymous namespace
@ -64,34 +64,33 @@ bool WiiWAD::ParseWAD()
if (!IsWiiWAD(*m_reader)) if (!IsWiiWAD(*m_reader))
return false; return false;
u32 certificate_chain_size; std::optional<u32> certificate_chain_size = m_reader->ReadSwapped<u32>(0x08);
u32 reserved; std::optional<u32> reserved = m_reader->ReadSwapped<u32>(0x0C);
u32 ticket_size; std::optional<u32> ticket_size = m_reader->ReadSwapped<u32>(0x10);
u32 tmd_size; std::optional<u32> tmd_size = m_reader->ReadSwapped<u32>(0x14);
u32 data_app_size; std::optional<u32> data_app_size = m_reader->ReadSwapped<u32>(0x18);
u32 footer_size; std::optional<u32> footer_size = m_reader->ReadSwapped<u32>(0x1C);
if (!certificate_chain_size || !reserved || !ticket_size || !tmd_size || !data_app_size ||
if (!m_reader->ReadSwapped(0x08, &certificate_chain_size) || !footer_size)
!m_reader->ReadSwapped(0x0C, &reserved) || !m_reader->ReadSwapped(0x10, &ticket_size) || {
!m_reader->ReadSwapped(0x14, &tmd_size) || !m_reader->ReadSwapped(0x18, &data_app_size) ||
!m_reader->ReadSwapped(0x1C, &footer_size))
return false; return false;
}
if (MAX_LOGLEVEL >= LogTypes::LOG_LEVELS::LDEBUG) if (MAX_LOGLEVEL >= LogTypes::LOG_LEVELS::LDEBUG)
_dbg_assert_msg_(BOOT, reserved == 0x00, "WiiWAD: Reserved must be 0x00"); _dbg_assert_msg_(BOOT, *reserved == 0x00, "WiiWAD: Reserved must be 0x00");
u32 offset = 0x40; u32 offset = 0x40;
m_certificate_chain = CreateWADEntry(*m_reader, certificate_chain_size, offset); m_certificate_chain = CreateWADEntry(*m_reader, *certificate_chain_size, offset);
offset += Common::AlignUp(certificate_chain_size, 0x40); offset += Common::AlignUp(*certificate_chain_size, 0x40);
m_ticket.SetBytes(CreateWADEntry(*m_reader, ticket_size, offset)); m_ticket.SetBytes(CreateWADEntry(*m_reader, *ticket_size, offset));
offset += Common::AlignUp(ticket_size, 0x40); offset += Common::AlignUp(*ticket_size, 0x40);
m_tmd.SetBytes(CreateWADEntry(*m_reader, tmd_size, offset)); m_tmd.SetBytes(CreateWADEntry(*m_reader, *tmd_size, offset));
offset += Common::AlignUp(tmd_size, 0x40); offset += Common::AlignUp(*tmd_size, 0x40);
m_data_app_offset = offset; m_data_app_offset = offset;
m_data_app = CreateWADEntry(*m_reader, data_app_size, offset); m_data_app = CreateWADEntry(*m_reader, *data_app_size, offset);
offset += Common::AlignUp(data_app_size, 0x40); offset += Common::AlignUp(*data_app_size, 0x40);
m_footer = CreateWADEntry(*m_reader, footer_size, offset); m_footer = CreateWADEntry(*m_reader, *footer_size, offset);
offset += Common::AlignUp(footer_size, 0x40); offset += Common::AlignUp(*footer_size, 0x40);
return true; return true;
} }

View File

@ -161,18 +161,17 @@ bool GameFile::TryLoadVolume()
m_game_id = QString::fromStdString(volume->GetGameID()); m_game_id = QString::fromStdString(volume->GetGameID());
std::string maker_id = volume->GetMakerID(); std::string maker_id = volume->GetMakerID();
if (std::optional<u64> title_id = volume->GetTitleID()) m_title_id = volume->GetTitleID().value_or(0);
m_title_id = *title_id;
m_maker = QString::fromStdString(DiscIO::GetCompanyFromID(maker_id)); m_maker = QString::fromStdString(DiscIO::GetCompanyFromID(maker_id));
m_maker_id = QString::fromStdString(maker_id); m_maker_id = QString::fromStdString(maker_id);
m_revision = volume->GetRevision(); m_revision = volume->GetRevision().value_or(0);
m_internal_name = QString::fromStdString(volume->GetInternalName()); m_internal_name = QString::fromStdString(volume->GetInternalName());
m_short_names = ConvertLanguageMap(volume->GetShortNames()); m_short_names = ConvertLanguageMap(volume->GetShortNames());
m_long_names = ConvertLanguageMap(volume->GetLongNames()); m_long_names = ConvertLanguageMap(volume->GetLongNames());
m_short_makers = ConvertLanguageMap(volume->GetShortMakers()); m_short_makers = ConvertLanguageMap(volume->GetShortMakers());
m_long_makers = ConvertLanguageMap(volume->GetLongMakers()); m_long_makers = ConvertLanguageMap(volume->GetLongMakers());
m_descriptions = ConvertLanguageMap(volume->GetDescriptions()); m_descriptions = ConvertLanguageMap(volume->GetDescriptions());
m_disc_number = volume->GetDiscNumber(); m_disc_number = volume->GetDiscNumber().value_or(0);
m_platform = volume->GetVolumeType(); m_platform = volume->GetVolumeType();
m_region = volume->GetRegion(); m_region = volume->GetRegion();
m_country = volume->GetCountry(); m_country = volume->GetCountry();

View File

@ -108,10 +108,9 @@ GameListItem::GameListItem(const std::string& _rFileName, const Core::TitleDatab
m_VolumeSize = volume->GetSize(); m_VolumeSize = volume->GetSize();
m_game_id = volume->GetGameID(); m_game_id = volume->GetGameID();
if (std::optional<u64> title_id = volume->GetTitleID()) m_title_id = volume->GetTitleID().value_or(0);
m_title_id = *title_id; m_disc_number = volume->GetDiscNumber().value_or(0);
m_disc_number = volume->GetDiscNumber(); m_Revision = volume->GetRevision().value_or(0);
m_Revision = volume->GetRevision();
std::vector<u32> buffer = volume->GetBanner(&m_ImageWidth, &m_ImageHeight); std::vector<u32> buffer = volume->GetBanner(&m_ImageWidth, &m_ImageHeight);
ReadVolumeBanner(buffer, m_ImageWidth, m_ImageHeight); ReadVolumeBanner(buffer, m_ImageWidth, m_ImageHeight);

View File

@ -6,6 +6,7 @@
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <optional>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -36,6 +37,12 @@
namespace namespace
{ {
template <typename T>
wxString OptionalToString(std::optional<T> value)
{
return value ? StrToWxStr(std::to_string(*value)) : wxString();
}
wxArrayString GetLanguageChoiceStrings(const std::vector<DiscIO::Language>& languages) wxArrayString GetLanguageChoiceStrings(const std::vector<DiscIO::Language>& languages)
{ {
wxArrayString available_languages; wxArrayString available_languages;
@ -177,7 +184,7 @@ void InfoPanel::LoadISODetails()
m_game_id->SetValue(StrToWxStr(m_opened_iso->GetGameID())); m_game_id->SetValue(StrToWxStr(m_opened_iso->GetGameID()));
m_country->SetValue(GetCountryName(m_opened_iso->GetCountry())); m_country->SetValue(GetCountryName(m_opened_iso->GetCountry()));
m_maker_id->SetValue("0x" + StrToWxStr(m_opened_iso->GetMakerID())); m_maker_id->SetValue("0x" + StrToWxStr(m_opened_iso->GetMakerID()));
m_revision->SetValue(StrToWxStr(std::to_string(m_opened_iso->GetRevision()))); m_revision->SetValue(OptionalToString(m_opened_iso->GetRevision()));
m_date->SetValue(StrToWxStr(m_opened_iso->GetApploaderDate())); m_date->SetValue(StrToWxStr(m_opened_iso->GetApploaderDate()));
if (m_ios_version) if (m_ios_version)
{ {