mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-12 06:39:14 +01:00
DiscIO: Merge WiiWAD into VolumeWAD
These two classes are very similar, so let's merge them.
This commit is contained in:
parent
0f5a4b37ee
commit
34f32898e6
@ -59,6 +59,7 @@ namespace fs = std::filesystem;
|
||||
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
#include "DiscIO/VolumeWad.h"
|
||||
|
||||
static std::vector<std::string> ReadM3UFile(const std::string& m3u_path,
|
||||
const std::string& folder_path)
|
||||
@ -201,7 +202,11 @@ BootParameters::GenerateFromFile(std::vector<std::string> paths,
|
||||
return std::make_unique<BootParameters>(DFF{std::move(path)}, savestate_path);
|
||||
|
||||
if (extension == ".wad")
|
||||
return std::make_unique<BootParameters>(DiscIO::WiiWAD{std::move(path)}, savestate_path);
|
||||
{
|
||||
std::unique_ptr<DiscIO::VolumeWAD> wad = DiscIO::CreateWAD(std::move(path));
|
||||
if (wad)
|
||||
return std::make_unique<BootParameters>(std::move(*wad), savestate_path);
|
||||
}
|
||||
|
||||
PanicAlertT("Could not recognize file %s", path.c_str());
|
||||
return {};
|
||||
@ -466,7 +471,7 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator()(const DiscIO::WiiWAD& wad) const
|
||||
bool operator()(const DiscIO::VolumeWAD& wad) const
|
||||
{
|
||||
SetDefaultDisc();
|
||||
return Boot_WiiWAD(wad);
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "DiscIO/Blob.h"
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
#include "DiscIO/WiiWad.h"
|
||||
#include "DiscIO/VolumeWad.h"
|
||||
|
||||
namespace File
|
||||
{
|
||||
@ -75,7 +75,7 @@ struct BootParameters
|
||||
GenerateFromFile(std::vector<std::string> paths,
|
||||
const std::optional<std::string>& savestate_path = {});
|
||||
|
||||
using Parameters = std::variant<Disc, Executable, DiscIO::WiiWAD, NANDTitle, IPL, DFF>;
|
||||
using Parameters = std::variant<Disc, Executable, DiscIO::VolumeWAD, NANDTitle, IPL, DFF>;
|
||||
BootParameters(Parameters&& parameters_, const std::optional<std::string>& savestate_path_ = {});
|
||||
|
||||
Parameters parameters;
|
||||
@ -108,7 +108,7 @@ private:
|
||||
|
||||
static void UpdateDebugger_MapLoaded();
|
||||
|
||||
static bool Boot_WiiWAD(const DiscIO::WiiWAD& wad);
|
||||
static bool Boot_WiiWAD(const DiscIO::VolumeWAD& wad);
|
||||
static bool BootNANDTitle(u64 title_id);
|
||||
|
||||
static void SetupMSR();
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "Core/IOS/IOS.h"
|
||||
#include "Core/IOS/IOSC.h"
|
||||
#include "Core/WiiUtils.h"
|
||||
#include "DiscIO/WiiWad.h"
|
||||
#include "DiscIO/VolumeWad.h"
|
||||
|
||||
bool CBoot::BootNANDTitle(const u64 title_id)
|
||||
{
|
||||
@ -34,7 +34,7 @@ bool CBoot::BootNANDTitle(const u64 title_id)
|
||||
return es->LaunchTitle(title_id);
|
||||
}
|
||||
|
||||
bool CBoot::Boot_WiiWAD(const DiscIO::WiiWAD& wad)
|
||||
bool CBoot::Boot_WiiWAD(const DiscIO::VolumeWAD& wad)
|
||||
{
|
||||
if (!WiiUtils::InstallWAD(*IOS::HLE::GetIOS(), wad, WiiUtils::InstallType::Temporary))
|
||||
{
|
||||
|
@ -49,7 +49,7 @@
|
||||
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
#include "DiscIO/WiiWad.h"
|
||||
#include "DiscIO/VolumeWad.h"
|
||||
|
||||
SConfig* SConfig::m_Instance;
|
||||
|
||||
@ -888,9 +888,9 @@ struct SetGameMetadata
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator()(const DiscIO::WiiWAD& wad) const
|
||||
bool operator()(const DiscIO::VolumeWAD& wad) const
|
||||
{
|
||||
if (!wad.IsValid() || !wad.GetTMD().IsValid())
|
||||
if (!wad.GetTMD().IsValid())
|
||||
{
|
||||
PanicAlertT("This WAD is not valid.");
|
||||
return false;
|
||||
|
@ -42,13 +42,13 @@
|
||||
#include "DiscIO/Filesystem.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
#include "DiscIO/VolumeFileBlobReader.h"
|
||||
#include "DiscIO/WiiWad.h"
|
||||
#include "DiscIO/VolumeWad.h"
|
||||
|
||||
namespace WiiUtils
|
||||
{
|
||||
static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad)
|
||||
static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad)
|
||||
{
|
||||
if (!wad.IsValid())
|
||||
if (!wad.GetTicket().IsValid() || !wad.GetTMD().IsValid())
|
||||
{
|
||||
PanicAlertT("WAD installation failed: The selected file is not a valid WAD.");
|
||||
return false;
|
||||
@ -110,7 +110,7 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad, InstallType install_type)
|
||||
bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, InstallType install_type)
|
||||
{
|
||||
if (!wad.GetTMD().IsValid())
|
||||
return false;
|
||||
@ -164,8 +164,12 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad, InstallType in
|
||||
|
||||
bool InstallWAD(const std::string& wad_path)
|
||||
{
|
||||
std::unique_ptr<DiscIO::VolumeWAD> wad = DiscIO::CreateWAD(wad_path);
|
||||
if (!wad)
|
||||
return false;
|
||||
|
||||
IOS::HLE::Kernel ios;
|
||||
return InstallWAD(ios, DiscIO::WiiWAD{wad_path}, InstallType::Permanent);
|
||||
return InstallWAD(ios, *wad, InstallType::Permanent);
|
||||
}
|
||||
|
||||
bool UninstallTitle(u64 title_id)
|
||||
@ -734,7 +738,7 @@ UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs,
|
||||
ERROR_LOG(CORE, "Could not find %s", std::string(path).c_str());
|
||||
return UpdateResult::DiscReadFailed;
|
||||
}
|
||||
const DiscIO::WiiWAD wad{std::move(blob)};
|
||||
const DiscIO::VolumeWAD wad{std::move(blob)};
|
||||
return ImportWAD(m_ios, wad) ? UpdateResult::Succeeded : UpdateResult::ImportFailed;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class WiiWAD;
|
||||
class VolumeWAD;
|
||||
}
|
||||
|
||||
namespace IOS::HLE
|
||||
@ -31,8 +31,8 @@ enum class InstallType
|
||||
Temporary,
|
||||
};
|
||||
|
||||
bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad, InstallType type);
|
||||
// Same as the above, but constructs a temporary IOS and WiiWAD instance for importing
|
||||
bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, InstallType type);
|
||||
// Same as the above, but constructs a temporary IOS and VolumeWAD instance for importing
|
||||
// and does a permanent install.
|
||||
bool InstallWAD(const std::string& wad_path);
|
||||
|
||||
|
@ -41,8 +41,6 @@ add_library(discio
|
||||
WbfsBlob.h
|
||||
WiiSaveBanner.cpp
|
||||
WiiSaveBanner.h
|
||||
WiiWad.cpp
|
||||
WiiWad.h
|
||||
)
|
||||
|
||||
target_link_libraries(discio
|
||||
|
@ -57,7 +57,6 @@
|
||||
<ClCompile Include="VolumeWii.cpp" />
|
||||
<ClCompile Include="WbfsBlob.cpp" />
|
||||
<ClCompile Include="WiiSaveBanner.cpp" />
|
||||
<ClCompile Include="WiiWad.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Blob.h" />
|
||||
@ -81,7 +80,6 @@
|
||||
<ClInclude Include="VolumeWii.h" />
|
||||
<ClInclude Include="WbfsBlob.h" />
|
||||
<ClInclude Include="WiiSaveBanner.h" />
|
||||
<ClInclude Include="WiiWad.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
|
@ -30,9 +30,6 @@
|
||||
<ClCompile Include="FileSystemGCWii.cpp">
|
||||
<Filter>FileSystem</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WiiWad.cpp">
|
||||
<Filter>NAND</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NANDImporter.cpp">
|
||||
<Filter>NAND</Filter>
|
||||
</ClCompile>
|
||||
@ -98,9 +95,6 @@
|
||||
<ClInclude Include="FileSystemGCWii.h">
|
||||
<Filter>FileSystem</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WiiWad.h">
|
||||
<Filter>NAND</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NANDImporter.h">
|
||||
<Filter>NAND</Filter>
|
||||
</ClInclude>
|
||||
|
@ -74,6 +74,7 @@ public:
|
||||
{
|
||||
return INVALID_CERT_CHAIN;
|
||||
}
|
||||
virtual std::vector<u8> GetContent(u16 index) const { return {}; }
|
||||
virtual std::vector<u64> GetContentOffsets() const { return {}; }
|
||||
// Returns a non-owning pointer. Returns nullptr if the file system couldn't be read.
|
||||
virtual const FileSystem* GetFileSystem(const Partition& partition) const = 0;
|
||||
|
@ -770,10 +770,7 @@ void VolumeVerifier::Process()
|
||||
|
||||
bool VolumeVerifier::CheckContentIntegrity(const IOS::ES::Content& content)
|
||||
{
|
||||
const u64 padded_size = Common::AlignUp(content.size, 0x40);
|
||||
std::vector<u8> encrypted_data(padded_size);
|
||||
m_volume.Read(m_content_offsets[m_content_index], padded_size, encrypted_data.data(),
|
||||
PARTITION_NONE);
|
||||
std::vector<u8> encrypted_data = m_volume.GetContent(content.index);
|
||||
|
||||
mbedtls_aes_context context;
|
||||
const std::array<u8, 16> key = m_volume.GetTicket(PARTITION_NONE).GetTitleKey();
|
||||
@ -783,8 +780,8 @@ bool VolumeVerifier::CheckContentIntegrity(const IOS::ES::Content& content)
|
||||
iv[0] = static_cast<u8>(content.index >> 8);
|
||||
iv[1] = static_cast<u8>(content.index & 0xFF);
|
||||
|
||||
std::vector<u8> decrypted_data(padded_size);
|
||||
mbedtls_aes_crypt_cbc(&context, MBEDTLS_AES_DECRYPT, padded_size, iv.data(),
|
||||
std::vector<u8> decrypted_data(Common::AlignUp(content.size, 0x40));
|
||||
mbedtls_aes_crypt_cbc(&context, MBEDTLS_AES_DECRYPT, decrypted_data.size(), iv.data(),
|
||||
encrypted_data.data(), decrypted_data.data());
|
||||
|
||||
std::array<u8, 20> sha1;
|
||||
|
@ -61,10 +61,6 @@ VolumeWAD::VolumeWAD(std::unique_ptr<BlobReader> reader) : m_reader(std::move(re
|
||||
Read(m_cert_chain_offset, m_cert_chain_size, m_cert_chain.data());
|
||||
}
|
||||
|
||||
VolumeWAD::~VolumeWAD()
|
||||
{
|
||||
}
|
||||
|
||||
bool VolumeWAD::Read(u64 offset, u64 length, u8* buffer, const Partition& partition) const
|
||||
{
|
||||
if (partition != PARTITION_NONE)
|
||||
@ -118,6 +114,24 @@ const std::vector<u8>& VolumeWAD::GetCertificateChain(const Partition& partition
|
||||
return m_cert_chain;
|
||||
}
|
||||
|
||||
std::vector<u8> VolumeWAD::GetContent(u16 index) const
|
||||
{
|
||||
u64 offset = m_data_offset;
|
||||
for (const IOS::ES::Content& content : m_tmd.GetContents())
|
||||
{
|
||||
const u64 aligned_size = Common::AlignUp(content.size, 0x40);
|
||||
if (content.index == index)
|
||||
{
|
||||
std::vector<u8> data(aligned_size);
|
||||
if (!m_reader->Read(offset, aligned_size, data.data()))
|
||||
return {};
|
||||
return data;
|
||||
}
|
||||
offset += aligned_size;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<u64> VolumeWAD::GetContentOffsets() const
|
||||
{
|
||||
const std::vector<IOS::ES::Content> contents = m_tmd.GetContents();
|
||||
|
@ -28,7 +28,6 @@ class VolumeWAD : public Volume
|
||||
{
|
||||
public:
|
||||
VolumeWAD(std::unique_ptr<BlobReader> reader);
|
||||
~VolumeWAD();
|
||||
bool Read(u64 offset, u64 length, u8* buffer,
|
||||
const Partition& partition = PARTITION_NONE) const override;
|
||||
const FileSystem* GetFileSystem(const Partition& partition = PARTITION_NONE) const override;
|
||||
@ -38,6 +37,7 @@ public:
|
||||
const IOS::ES::TMDReader& GetTMD(const Partition& partition = PARTITION_NONE) const override;
|
||||
const std::vector<u8>&
|
||||
GetCertificateChain(const Partition& partition = PARTITION_NONE) const override;
|
||||
std::vector<u8> GetContent(u16 index) const override;
|
||||
std::vector<u64> GetContentOffsets() const override;
|
||||
std::string GetGameID(const Partition& partition = PARTITION_NONE) const override;
|
||||
std::string GetGameTDBID(const Partition& partition = PARTITION_NONE) const override;
|
||||
|
@ -1,112 +0,0 @@
|
||||
// Copyright 2009 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "Common/Align.h"
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "DiscIO/Blob.h"
|
||||
#include "DiscIO/WiiWad.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::vector<u8> CreateWADEntry(BlobReader& reader, u32 size, u64 offset)
|
||||
{
|
||||
if (size == 0)
|
||||
return {};
|
||||
|
||||
std::vector<u8> buffer(size);
|
||||
|
||||
if (!reader.Read(offset, size, buffer.data()))
|
||||
{
|
||||
ERROR_LOG(DISCIO, "WiiWAD: Could not read from file");
|
||||
PanicAlertT("WiiWAD: Could not read from file");
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool IsWiiWAD(BlobReader& reader)
|
||||
{
|
||||
const std::optional<u32> header_size = reader.ReadSwapped<u32>(0x0);
|
||||
const std::optional<u32> header_type = reader.ReadSwapped<u32>(0x4);
|
||||
return header_size == u32(0x20) &&
|
||||
(header_type == u32(0x49730000) || header_type == u32(0x69620000));
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
WiiWAD::WiiWAD(const std::string& name) : WiiWAD(CreateBlobReader(name))
|
||||
{
|
||||
}
|
||||
|
||||
WiiWAD::WiiWAD(std::unique_ptr<BlobReader> blob_reader) : m_reader(std::move(blob_reader))
|
||||
{
|
||||
if (m_reader)
|
||||
m_valid = ParseWAD();
|
||||
}
|
||||
|
||||
WiiWAD::~WiiWAD() = default;
|
||||
|
||||
bool WiiWAD::ParseWAD()
|
||||
{
|
||||
if (!IsWiiWAD(*m_reader))
|
||||
return false;
|
||||
|
||||
std::optional<u32> certificate_chain_size = m_reader->ReadSwapped<u32>(0x08);
|
||||
std::optional<u32> reserved = m_reader->ReadSwapped<u32>(0x0C);
|
||||
std::optional<u32> ticket_size = m_reader->ReadSwapped<u32>(0x10);
|
||||
std::optional<u32> tmd_size = m_reader->ReadSwapped<u32>(0x14);
|
||||
std::optional<u32> data_app_size = m_reader->ReadSwapped<u32>(0x18);
|
||||
std::optional<u32> footer_size = m_reader->ReadSwapped<u32>(0x1C);
|
||||
if (!certificate_chain_size || !reserved || !ticket_size || !tmd_size || !data_app_size ||
|
||||
!footer_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MAX_LOGLEVEL >= LogTypes::LOG_LEVELS::LDEBUG)
|
||||
DEBUG_ASSERT_MSG(BOOT, *reserved == 0x00, "WiiWAD: Reserved must be 0x00");
|
||||
|
||||
u32 offset = 0x40;
|
||||
m_certificate_chain = CreateWADEntry(*m_reader, *certificate_chain_size, offset);
|
||||
offset += Common::AlignUp(*certificate_chain_size, 0x40);
|
||||
m_ticket.SetBytes(CreateWADEntry(*m_reader, *ticket_size, offset));
|
||||
offset += Common::AlignUp(*ticket_size, 0x40);
|
||||
m_tmd.SetBytes(CreateWADEntry(*m_reader, *tmd_size, offset));
|
||||
offset += Common::AlignUp(*tmd_size, 0x40);
|
||||
m_data_app_offset = offset;
|
||||
m_data_app = CreateWADEntry(*m_reader, *data_app_size, offset);
|
||||
offset += Common::AlignUp(*data_app_size, 0x40);
|
||||
m_footer = CreateWADEntry(*m_reader, *footer_size, offset);
|
||||
offset += Common::AlignUp(*footer_size, 0x40);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<u8> WiiWAD::GetContent(u16 index) const
|
||||
{
|
||||
u64 offset = m_data_app_offset;
|
||||
for (const IOS::ES::Content& content : m_tmd.GetContents())
|
||||
{
|
||||
const u64 aligned_size = Common::AlignUp(content.size, 0x40);
|
||||
if (content.index == index)
|
||||
{
|
||||
std::vector<u8> data(aligned_size);
|
||||
if (!m_reader->Read(offset, aligned_size, data.data()))
|
||||
return {};
|
||||
return data;
|
||||
}
|
||||
offset += aligned_size;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
} // namespace DiscIO
|
@ -1,49 +0,0 @@
|
||||
// Copyright 2009 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/IOS/ES/Formats.h"
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
class BlobReader;
|
||||
|
||||
class WiiWAD
|
||||
{
|
||||
public:
|
||||
explicit WiiWAD(const std::string& name);
|
||||
explicit WiiWAD(std::unique_ptr<BlobReader> blob_reader);
|
||||
WiiWAD(WiiWAD&&) = default;
|
||||
WiiWAD& operator=(WiiWAD&&) = default;
|
||||
~WiiWAD();
|
||||
|
||||
bool IsValid() const { return m_valid; }
|
||||
const std::vector<u8>& GetCertificateChain() const { return m_certificate_chain; }
|
||||
const IOS::ES::TicketReader& GetTicket() const { return m_ticket; }
|
||||
const IOS::ES::TMDReader& GetTMD() const { return m_tmd; }
|
||||
const std::vector<u8>& GetDataApp() const { return m_data_app; }
|
||||
const std::vector<u8>& GetFooter() const { return m_footer; }
|
||||
std::vector<u8> GetContent(u16 index) const;
|
||||
|
||||
private:
|
||||
bool ParseWAD();
|
||||
|
||||
bool m_valid = false;
|
||||
|
||||
std::unique_ptr<BlobReader> m_reader;
|
||||
|
||||
u64 m_data_app_offset = 0;
|
||||
std::vector<u8> m_certificate_chain;
|
||||
IOS::ES::TicketReader m_ticket;
|
||||
IOS::ES::TMDReader m_tmd;
|
||||
std::vector<u8> m_data_app;
|
||||
std::vector<u8> m_footer;
|
||||
};
|
||||
} // namespace DiscIO
|
Loading…
x
Reference in New Issue
Block a user