Remove NANDContentManager

This commit is contained in:
Léo Lam 2017-10-01 18:48:50 +02:00
parent c03aa78c8f
commit 346ca009f9
20 changed files with 3 additions and 452 deletions

View File

@ -46,7 +46,6 @@
#include "Core/PowerPC/PowerPC.h"
#include "DiscIO/Enums.h"
#include "DiscIO/NANDContentLoader.h"
#include "DiscIO/Volume.h"
BootParameters::BootParameters(Parameters&& parameters_) : parameters(std::move(parameters_))

View File

@ -20,7 +20,6 @@
#include "Core/IOS/IOS.h"
#include "Core/WiiUtils.h"
#include "DiscIO/NANDContentLoader.h"
#include "DiscIO/WiiWad.h"
bool CBoot::BootNANDTitle(const u64 title_id)

View File

@ -43,7 +43,6 @@
#include "VideoCommon/HiresTextures.h"
#include "DiscIO/Enums.h"
#include "DiscIO/NANDContentLoader.h"
#include "DiscIO/Volume.h"
#include "DiscIO/WiiWad.h"

View File

@ -27,7 +27,6 @@
#include "Core/IOS/ES/Formats.h"
#include "Core/IOS/IOSC.h"
#include "Core/ec_wii.h"
#include "DiscIO/NANDContentLoader.h"
namespace IOS
{
@ -218,11 +217,6 @@ bool ES::LaunchTitle(u64 title_id, bool skip_reload)
NOTICE_LOG(IOS_ES, "Launching title %016" PRIx64 "...", title_id);
// ES_Launch should probably reset the whole state, which at least means closing all open files.
// leaving them open through ES_Launch may cause hangs and other funky behavior
// (supposedly when trying to re-open those files).
DiscIO::NANDContentManager::Access().ClearCache();
u32 device_id;
if (title_id == Titles::SHOP &&
(GetDeviceId(&device_id) != IPC_SUCCESS || device_id == DEFAULT_WII_DEVICE_ID))
@ -401,8 +395,6 @@ ReturnCode ES::Close(u32 fd)
INFO_LOG(IOS_ES, "ES: Close");
m_is_active = false;
// clear the NAND content cache to make sure nothing remains open.
DiscIO::NANDContentManager::Access().ClearCache();
return IPC_SUCCESS;
}
@ -658,9 +650,6 @@ s32 ES::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& tic
if (!tmd_file.WriteBytes(tmd_bytes.data(), tmd_bytes.size()))
ERROR_LOG(IOS_ES, "DIVerify failed to write disc TMD to NAND.");
}
// DI_VERIFY writes to title.tmd, which is read and cached inside the NAND Content Manager.
// clear the cache to avoid content access mismatches.
DiscIO::NANDContentManager::Access().ClearCache();
if (!UpdateUIDAndGID(*GetIOS(), m_title_context.tmd))
{

View File

@ -18,11 +18,6 @@
class PointerWrap;
namespace DiscIO
{
class NANDContentLoader;
}
namespace IOS
{
namespace HLE

View File

@ -12,7 +12,6 @@
#include "Common/MsgHandler.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h"
#include "DiscIO/NANDContentLoader.h"
namespace IOS
{

View File

@ -22,7 +22,6 @@
#include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h"
#include "Core/ec_wii.h"
#include "DiscIO/NANDContentLoader.h"
namespace IOS
{
@ -506,8 +505,6 @@ ReturnCode ES::DeleteTitle(u64 title_id)
ERROR_LOG(IOS_ES, "DeleteTitle: Failed to delete title directory: %s", title_dir.c_str());
return FS_EACCESS;
}
// XXX: ugly, but until we drop NANDContentManager everywhere, this is going to be needed.
DiscIO::NANDContentManager::Access().ClearCache();
return IPC_SUCCESS;
}

View File

@ -17,7 +17,6 @@
#include "Core/Core.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/ES/Formats.h"
#include "DiscIO/NANDContentLoader.h"
namespace IOS
{

View File

@ -19,7 +19,6 @@
#include "Core/IOS/ES/ES.h"
#include "Core/IOS/ES/Formats.h"
#include "Core/IOS/WFS/WFSSRV.h"
#include "DiscIO/NANDContentLoader.h"
namespace
{

View File

@ -38,7 +38,6 @@
#include "DiscIO/DiscExtractor.h"
#include "DiscIO/Enums.h"
#include "DiscIO/Filesystem.h"
#include "DiscIO/NANDContentLoader.h"
#include "DiscIO/Volume.h"
#include "DiscIO/VolumeFileBlobReader.h"
#include "DiscIO/VolumeWii.h"
@ -129,10 +128,7 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad)
return false;
}
const bool result = ImportWAD(ios, wad);
DiscIO::NANDContentManager::Access().ClearCache();
return result;
return ImportWAD(ios, wad);
}
bool InstallWAD(const std::string& wad_path)
@ -695,17 +691,13 @@ UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs,
UpdateResult DoOnlineUpdate(UpdateCallback update_callback, const std::string& region)
{
OnlineSystemUpdater updater{std::move(update_callback), region};
const UpdateResult result = updater.DoOnlineUpdate();
DiscIO::NANDContentManager::Access().ClearCache();
return result;
return updater.DoOnlineUpdate();
}
UpdateResult DoDiscUpdate(UpdateCallback update_callback, const std::string& image_path)
{
DiscSystemUpdater updater{std::move(update_callback), image_path};
const UpdateResult result = updater.DoDiscUpdate();
DiscIO::NANDContentManager::Access().ClearCache();
return result;
return updater.DoDiscUpdate();
}
NANDCheckResult CheckNAND(IOS::HLE::Kernel& ios)

View File

@ -11,7 +11,6 @@ set(SRCS
FileBlob.cpp
FileSystemGCWii.cpp
Filesystem.cpp
NANDContentLoader.cpp
NANDImporter.cpp
TGCBlob.cpp
Volume.cpp

View File

@ -47,7 +47,6 @@
<ClCompile Include="FileBlob.cpp" />
<ClCompile Include="Filesystem.cpp" />
<ClCompile Include="FileSystemGCWii.cpp" />
<ClCompile Include="NANDContentLoader.cpp" />
<ClCompile Include="NANDImporter.cpp" />
<ClCompile Include="TGCBlob.cpp" />
<ClCompile Include="Volume.cpp" />
@ -70,7 +69,6 @@
<ClInclude Include="FileBlob.h" />
<ClInclude Include="Filesystem.h" />
<ClInclude Include="FileSystemGCWii.h" />
<ClInclude Include="NANDContentLoader.h" />
<ClInclude Include="NANDImporter.h" />
<ClInclude Include="TGCBlob.h" />
<ClInclude Include="Volume.h" />

View File

@ -33,9 +33,6 @@
<ClCompile Include="WiiWad.cpp">
<Filter>NAND</Filter>
</ClCompile>
<ClCompile Include="NANDContentLoader.cpp">
<Filter>NAND</Filter>
</ClCompile>
<ClCompile Include="NANDImporter.cpp">
<Filter>NAND</Filter>
</ClCompile>
@ -98,9 +95,6 @@
<ClInclude Include="WiiWad.h">
<Filter>NAND</Filter>
</ClInclude>
<ClInclude Include="NANDContentLoader.h">
<Filter>NAND</Filter>
</ClInclude>
<ClInclude Include="NANDImporter.h">
<Filter>NAND</Filter>
</ClInclude>

View File

@ -1,268 +0,0 @@
// Copyright 2009 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "DiscIO/NANDContentLoader.h"
#include <algorithm>
#include <array>
#include <cinttypes>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <functional>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "Common/Align.h"
#include "Common/CommonTypes.h"
#include "Common/Crypto/AES.h"
#include "Common/File.h"
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/NandPaths.h"
#include "Common/StringUtil.h"
#include "Common/Swap.h"
// TODO: kill this dependency.
#include "Core/IOS/ES/Formats.h"
#include "DiscIO/WiiWad.h"
namespace DiscIO
{
NANDContentData::~NANDContentData() = default;
NANDContentDataFile::NANDContentDataFile(const std::string& filename) : m_filename{filename}
{
}
NANDContentDataFile::~NANDContentDataFile() = default;
void NANDContentDataFile::EnsureOpen()
{
if (!m_file)
m_file = std::make_unique<File::IOFile>(m_filename, "rb");
else if (!m_file->IsOpen())
m_file->Open(m_filename, "rb");
}
void NANDContentDataFile::Open()
{
EnsureOpen();
}
std::vector<u8> NANDContentDataFile::Get()
{
EnsureOpen();
if (!m_file->IsGood())
return {};
u64 size = m_file->GetSize();
if (size == 0)
return {};
std::vector<u8> result(size);
m_file->ReadBytes(result.data(), result.size());
return result;
}
bool NANDContentDataFile::GetRange(u32 start, u32 size, u8* buffer)
{
EnsureOpen();
if (!m_file->IsGood())
return false;
if (!m_file->Seek(start, SEEK_SET))
return false;
return m_file->ReadBytes(buffer, static_cast<size_t>(size));
}
void NANDContentDataFile::Close()
{
if (m_file && m_file->IsOpen())
m_file->Close();
}
bool NANDContentDataBuffer::GetRange(u32 start, u32 size, u8* buffer)
{
if (start + size > m_buffer.size())
return false;
std::copy_n(&m_buffer[start], size, buffer);
return true;
}
NANDContentLoader::NANDContentLoader(const std::string& content_name, Common::FromWhichRoot from)
: m_root(from)
{
m_Valid = Initialize(content_name);
}
NANDContentLoader::~NANDContentLoader()
{
}
bool NANDContentLoader::IsValid() const
{
return m_Valid;
}
const NANDContent* NANDContentLoader::GetContentByID(u32 id) const
{
const auto iterator = std::find_if(m_Content.begin(), m_Content.end(), [id](const auto& content) {
return content.m_metadata.id == id;
});
return iterator != m_Content.end() ? &*iterator : nullptr;
}
const NANDContent* NANDContentLoader::GetContentByIndex(int index) const
{
for (auto& Content : m_Content)
{
if (Content.m_metadata.index == index)
{
return &Content;
}
}
return nullptr;
}
bool NANDContentLoader::Initialize(const std::string& name)
{
if (name.empty())
return false;
m_Path = name;
WiiWAD wad(name);
std::vector<u8> data_app;
if (wad.IsValid())
{
m_IsWAD = true;
m_ticket = wad.GetTicket();
m_tmd = wad.GetTMD();
data_app = wad.GetDataApp();
}
else
{
std::string tmd_filename(m_Path);
if (tmd_filename.back() == '/')
tmd_filename += "title.tmd";
else
m_Path = tmd_filename.substr(0, tmd_filename.find("title.tmd"));
File::IOFile tmd_file(tmd_filename, "rb");
if (!tmd_file)
{
WARN_LOG(DISCIO, "CreateFromDirectory: error opening %s", tmd_filename.c_str());
return false;
}
std::vector<u8> bytes(tmd_file.GetSize());
tmd_file.ReadBytes(bytes.data(), bytes.size());
m_tmd.SetBytes(std::move(bytes));
m_ticket = FindSignedTicket(m_tmd.GetTitleId());
}
InitializeContentEntries(data_app);
return true;
}
void NANDContentLoader::InitializeContentEntries(const std::vector<u8>& data_app)
{
if (!m_ticket.IsValid())
{
ERROR_LOG(IOS_ES, "No valid ticket for title %016" PRIx64, m_tmd.GetTitleId());
return;
}
const std::vector<IOS::ES::Content> contents = m_tmd.GetContents();
m_Content.resize(contents.size());
u32 data_app_offset = 0;
const std::array<u8, 16> title_key = m_ticket.GetTitleKey();
IOS::ES::SharedContentMap shared_content{m_root};
for (size_t i = 0; i < contents.size(); ++i)
{
const auto& content = contents.at(i);
if (m_IsWAD)
{
// The content index is used as IV (2 bytes); the remaining 14 bytes are zeroes.
std::array<u8, 16> iv{};
iv[0] = static_cast<u8>(content.index >> 8) & 0xFF;
iv[1] = static_cast<u8>(content.index) & 0xFF;
u32 rounded_size = Common::AlignUp(static_cast<u32>(content.size), 0x40);
m_Content[i].m_Data = std::make_unique<NANDContentDataBuffer>(Common::AES::Decrypt(
title_key.data(), iv.data(), &data_app[data_app_offset], rounded_size));
data_app_offset += rounded_size;
}
else
{
std::string filename;
if (content.IsShared())
filename = *shared_content.GetFilenameFromSHA1(content.sha1);
else
filename = StringFromFormat("%s/%08x.app", m_Path.c_str(), content.id);
m_Content[i].m_Data = std::make_unique<NANDContentDataFile>(filename);
}
m_Content[i].m_metadata = std::move(content);
}
}
NANDContentManager::~NANDContentManager()
{
}
const NANDContentLoader& NANDContentManager::GetNANDLoader(const std::string& content_path,
Common::FromWhichRoot from)
{
auto it = m_map.find(content_path);
if (it != m_map.end())
return *it->second;
return *m_map
.emplace_hint(it, std::make_pair(content_path, std::make_unique<NANDContentLoader>(
content_path, from)))
->second;
}
const NANDContentLoader& NANDContentManager::GetNANDLoader(u64 title_id, Common::FromWhichRoot from)
{
std::string path = Common::GetTitleContentPath(title_id, from);
return GetNANDLoader(path, from);
}
void NANDContentManager::ClearCache()
{
m_map.clear();
}
IOS::ES::TicketReader FindSignedTicket(u64 title_id)
{
std::string ticket_filename = Common::GetTicketFileName(title_id, Common::FROM_CONFIGURED_ROOT);
File::IOFile ticket_file(ticket_filename, "rb");
if (!ticket_file)
{
return IOS::ES::TicketReader{};
}
std::vector<u8> signed_ticket(ticket_file.GetSize());
if (!ticket_file.ReadBytes(signed_ticket.data(), signed_ticket.size()))
{
return IOS::ES::TicketReader{};
}
return IOS::ES::TicketReader{std::move(signed_ticket)};
}
} // namespace end

View File

@ -1,126 +0,0 @@
// Copyright 2009 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <cstddef>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "Common/CommonTypes.h"
#include "Common/NandPaths.h"
#include "Core/IOS/ES/Formats.h"
namespace File
{
class IOFile;
}
namespace DiscIO
{
enum class Region;
// TODO: move some of these to Core/IOS/ES.
IOS::ES::TicketReader FindSignedTicket(u64 title_id);
class NANDContentData
{
public:
virtual ~NANDContentData() = 0;
virtual void Open() {}
virtual std::vector<u8> Get() = 0;
virtual bool GetRange(u32 start, u32 size, u8* buffer) = 0;
virtual void Close() {}
};
class NANDContentDataFile final : public NANDContentData
{
public:
explicit NANDContentDataFile(const std::string& filename);
~NANDContentDataFile();
void Open() override;
std::vector<u8> Get() override;
bool GetRange(u32 start, u32 size, u8* buffer) override;
void Close() override;
private:
void EnsureOpen();
const std::string m_filename;
std::unique_ptr<File::IOFile> m_file;
};
class NANDContentDataBuffer final : public NANDContentData
{
public:
explicit NANDContentDataBuffer(const std::vector<u8>& buffer) : m_buffer(buffer) {}
std::vector<u8> Get() override { return m_buffer; }
bool GetRange(u32 start, u32 size, u8* buffer) override;
private:
const std::vector<u8> m_buffer;
};
struct NANDContent
{
IOS::ES::Content m_metadata;
std::unique_ptr<NANDContentData> m_Data;
};
// Instances of this class must be created by NANDContentManager
class NANDContentLoader final
{
public:
explicit NANDContentLoader(const std::string& content_name, Common::FromWhichRoot from);
~NANDContentLoader();
bool IsValid() const;
const NANDContent* GetContentByID(u32 id) const;
const NANDContent* GetContentByIndex(int index) const;
const IOS::ES::TMDReader& GetTMD() const { return m_tmd; }
const IOS::ES::TicketReader& GetTicket() const { return m_ticket; }
const std::vector<NANDContent>& GetContent() const { return m_Content; }
private:
bool Initialize(const std::string& name);
void InitializeContentEntries(const std::vector<u8>& data_app);
bool m_Valid = false;
bool m_IsWAD = false;
Common::FromWhichRoot m_root;
std::string m_Path;
IOS::ES::TMDReader m_tmd;
IOS::ES::TicketReader m_ticket;
std::vector<NANDContent> m_Content;
};
// we open the NAND Content files too often... let's cache them
class NANDContentManager
{
public:
static NANDContentManager& Access()
{
static NANDContentManager instance;
return instance;
}
const NANDContentLoader& GetNANDLoader(const std::string& content_path,
Common::FromWhichRoot from = Common::FROM_CONFIGURED_ROOT);
const NANDContentLoader& GetNANDLoader(u64 title_id,
Common::FromWhichRoot from = Common::FROM_CONFIGURED_ROOT);
void ClearCache();
private:
NANDContentManager() {}
~NANDContentManager();
NANDContentManager(NANDContentManager const&) = delete;
void operator=(NANDContentManager const&) = delete;
std::unordered_map<std::string, std::unique_ptr<NANDContentLoader>> m_map;
};
}

View File

@ -17,7 +17,6 @@
#include "Common/StringUtil.h"
#include "Common/Swap.h"
#include "Core/IOS/ES/Formats.h"
#include "DiscIO/NANDContentLoader.h"
namespace DiscIO
{
@ -44,9 +43,6 @@ void NANDImporter::ImportNANDBin(const std::string& path_to_bin,
ProcessEntry(0, nand_root);
ExportKeys(nand_root);
ExtractCertificates(nand_root);
// We have to clear the cache so the new NAND takes effect
DiscIO::NANDContentManager::Access().ClearCache();
}
bool NANDImporter::ReadNANDBin(const std::string& path_to_bin)

View File

@ -14,10 +14,6 @@
#include "Core/IOS/ES/Formats.h"
#include "DiscIO/Volume.h"
// --- this volume type is used for Wad files ---
// Some of this code might look redundant with the NANDContentLoader class, however,
// We do not do any decryption here, we do raw read, so things are -Faster-
namespace DiscIO
{
class BlobReader;

View File

@ -18,7 +18,6 @@
#include "Core/WiiUtils.h"
#include "DiscIO/Blob.h"
#include "DiscIO/Enums.h"
#include "DiscIO/NANDContentLoader.h"
#include "DiscIO/Volume.h"
#include "DolphinQt2/GameList/GameFile.h"
#include "DolphinQt2/Resources.h"

View File

@ -18,7 +18,6 @@
#include "Common/FileUtil.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "DiscIO/NANDContentLoader.h"
#include "DolphinWX/Config/ConfigMain.h"
#include "DolphinWX/Frame.h"
#include "DolphinWX/WxEventUtils.h"
@ -202,8 +201,6 @@ void PathConfigPane::OnNANDRootChanged(wxCommandEvent& event)
File::SetUserPath(D_WIIROOT_IDX, nand_path);
m_nand_root_dirpicker->SetPath(StrToWxStr(nand_path));
DiscIO::NANDContentManager::Access().ClearCache();
wxCommandEvent update_event{DOLPHIN_EVT_UPDATE_LOAD_WII_MENU_ITEM, GetId()};
update_event.SetEventObject(this);
AddPendingEvent(update_event);

View File

@ -60,7 +60,6 @@
#include "Core/WiiUtils.h"
#include "DiscIO/Enums.h"
#include "DiscIO/NANDContentLoader.h"
#include "DiscIO/NANDImporter.h"
#include "DiscIO/VolumeWad.h"