[Cleanup] IOS/ES: Remove usages of NANDContentManager

This commit is contained in:
Léo Lam 2017-10-01 17:06:16 +02:00
parent a7e21bca13
commit 63a52fa707
5 changed files with 46 additions and 65 deletions

View File

@ -251,8 +251,10 @@ bool ES::LaunchIOS(u64 ios_title_id)
bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload)
{
const DiscIO::NANDContentLoader& content_loader = AccessContentDevice(title_id);
if (!content_loader.IsValid())
const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
const IOS::ES::TicketReader ticket = FindSignedTicket(title_id);
if (!tmd.IsValid() || !ticket.IsValid())
{
if (title_id == Titles::SYSTEM_MENU)
{
@ -268,22 +270,18 @@ bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload)
return false;
}
if (!content_loader.GetTMD().IsValid() || !content_loader.GetTicket().IsValid())
return false;
// Before launching a title, IOS first reads the TMD and reloads into the specified IOS version,
// even when that version is already running. After it has reloaded, ES_Launch will be called
// again with the reload skipped, and the PPC will be bootstrapped then.
if (!skip_reload)
{
s_title_to_launch = title_id;
const u64 required_ios = content_loader.GetTMD().GetIOSId();
const u64 required_ios = tmd.GetIOSId();
return LaunchTitle(required_ios);
}
m_title_context.Update(content_loader.GetTMD(), content_loader.GetTicket());
INFO_LOG(IOS_ES, "LaunchPPCTitle: Title context changed: %016" PRIx64,
m_title_context.tmd.GetTitleId());
m_title_context.Update(tmd, ticket);
INFO_LOG(IOS_ES, "LaunchPPCTitle: Title context changed: %016" PRIx64, tmd.GetTitleId());
// Note: the UID/GID is also updated for IOS titles, but since we have no guarantee IOS titles
// are installed, we can only do this for PPC titles.
@ -294,7 +292,11 @@ bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload)
return false;
}
return m_ios.BootstrapPPC(content_loader);
IOS::ES::Content content;
if (!tmd.GetContent(tmd.GetBootIndex(), &content))
return false;
return m_ios.BootstrapPPC(GetContentPath(tmd.GetTitleId(), content));
}
void ES::Context::DoState(PointerWrap& p)
@ -310,7 +312,20 @@ void ES::Context::DoState(PointerWrap& p)
void ES::DoState(PointerWrap& p)
{
Device::DoState(p);
p.Do(m_content_table);
for (auto& entry : m_content_table)
{
p.Do(entry.m_opened);
p.Do(entry.m_title_id);
p.Do(entry.m_content);
p.Do(entry.m_position);
p.Do(entry.m_uid);
if (entry.m_opened)
entry.m_opened = entry.m_file.Open(GetContentPath(entry.m_title_id, entry.m_content), "rb");
else
entry.m_file.Close();
}
m_title_context.DoState(p);
for (auto& context : m_contexts)
@ -573,11 +588,6 @@ IPCCommandResult ES::LaunchBC(const IOCtlVRequest& request)
return GetNoReply();
}
const DiscIO::NANDContentLoader& ES::AccessContentDevice(u64 title_id)
{
return DiscIO::NANDContentManager::Access().GetNANDLoader(title_id, Common::FROM_SESSION_ROOT);
}
// This is technically an ioctlv in IOS's ES, but it is an internal API which cannot be
// used from the PowerPC (for unpatched and up-to-date IOSes anyway).
// So we block access to it from the IPC interface.

View File

@ -10,6 +10,7 @@
#include <vector>
#include "Common/CommonTypes.h"
#include "Common/File.h"
#include "Core/IOS/Device.h"
#include "Core/IOS/ES/Formats.h"
#include "Core/IOS/IOS.h"
@ -343,13 +344,11 @@ private:
const IOS::ES::SharedContentMap& map = IOS::ES::SharedContentMap{
Common::FROM_SESSION_ROOT}) const;
// TODO: remove these
const DiscIO::NANDContentLoader& AccessContentDevice(u64 title_id);
// TODO: reuse the FS code.
struct OpenedContent
{
bool m_opened = false;
File::IOFile m_file;
u64 m_title_id = 0;
IOS::ES::Content m_content;
u32 m_position = 0;

View File

@ -23,14 +23,10 @@ namespace Device
s32 ES::OpenContent(const IOS::ES::TMDReader& tmd, u16 content_index, u32 uid)
{
const u64 title_id = tmd.GetTitleId();
const DiscIO::NANDContentLoader& loader = AccessContentDevice(title_id);
if (!loader.IsValid())
return FS_ENOENT;
const DiscIO::NANDContent* content = loader.GetContentByIndex(content_index);
if (!content)
return FS_ENOENT;
IOS::ES::Content content;
if (!tmd.GetContent(content_index, &content))
return ES_EINVAL;
for (size_t i = 0; i < m_content_table.size(); ++i)
{
@ -38,9 +34,12 @@ s32 ES::OpenContent(const IOS::ES::TMDReader& tmd, u16 content_index, u32 uid)
if (entry.m_opened)
continue;
if (!entry.m_file.Open(GetContentPath(title_id, content), "rb"))
return FS_ENOENT;
entry.m_opened = true;
entry.m_position = 0;
entry.m_content = content->m_metadata;
entry.m_content = content;
entry.m_title_id = title_id;
entry.m_uid = uid;
INFO_LOG(IOS_ES, "OpenContent: title ID %016" PRIx64 ", UID 0x%x, CFD %zu", title_id, uid, i);
@ -102,20 +101,14 @@ s32 ES::ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid)
// XXX: make this reuse the FS code... ES just does a simple "IOS_Read" call here
// instead of all this duplicated filesystem logic.
if (entry.m_position + size > entry.m_content.size)
size = static_cast<u32>(entry.m_content.size) - entry.m_position;
if (entry.m_position + size > entry.m_file.GetSize())
size = static_cast<u32>(entry.m_file.GetSize()) - entry.m_position;
const DiscIO::NANDContentLoader& ContentLoader = AccessContentDevice(entry.m_title_id);
// ContentLoader should never be invalid; rContent has been created by it.
if (ContentLoader.IsValid() && ContentLoader.GetTicket().IsValid())
entry.m_file.Seek(entry.m_position, SEEK_SET);
if (!entry.m_file.ReadBytes(buffer, size))
{
const DiscIO::NANDContent* pContent = ContentLoader.GetContentByIndex(entry.m_content.index);
pContent->m_Data->Open();
if (!pContent->m_Data->GetRange(entry.m_position, size, buffer))
{
ERROR_LOG(IOS_ES, "ES: failed to read %u bytes from %u!", size, entry.m_position);
return ES_SHORT_READ;
}
ERROR_LOG(IOS_ES, "ES: failed to read %u bytes from %u!", size, entry.m_position);
return ES_SHORT_READ;
}
entry.m_position += size;
@ -145,15 +138,6 @@ ReturnCode ES::CloseContent(u32 cfd, u32 uid)
if (!entry.m_opened)
return IPC_EINVAL;
// XXX: again, this should be a simple IOS_Close.
const DiscIO::NANDContentLoader& ContentLoader = AccessContentDevice(entry.m_title_id);
// ContentLoader should never be invalid; we shouldn't be here if ES_OPENCONTENT failed before.
if (ContentLoader.IsValid())
{
const DiscIO::NANDContent* content = ContentLoader.GetContentByIndex(entry.m_content.index);
content->m_Data->Close();
}
entry = {};
INFO_LOG(IOS_ES, "CloseContent: CFD %u", cfd);
return IPC_SUCCESS;

View File

@ -54,7 +54,6 @@
#include "Core/IOS/WFS/WFSSRV.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/WiiRoot.h"
#include "DiscIO/NANDContentLoader.h"
namespace IOS
{
@ -275,23 +274,17 @@ u16 Kernel::GetGidForPPC() const
// This corresponds to syscall 0x41, which loads a binary from the NAND and bootstraps the PPC.
// Unlike 0x42, IOS will set up some constants in memory before booting the PPC.
bool Kernel::BootstrapPPC(const DiscIO::NANDContentLoader& content_loader)
bool Kernel::BootstrapPPC(const std::string& boot_content_path)
{
if (!content_loader.IsValid())
return false;
const DolReader dol{boot_content_path};
const auto* content = content_loader.GetContentByIndex(content_loader.GetTMD().GetBootIndex());
if (!content)
return false;
const auto dol_loader = std::make_unique<DolReader>(content->m_Data->Get());
if (!dol_loader->IsValid())
if (!dol.IsValid())
return false;
if (!SetupMemory(m_title_id, MemorySetupType::Full))
return false;
if (!dol_loader->LoadIntoMemory())
if (!dol.LoadIntoMemory())
return false;
// NAND titles start with address translation off at 0x3400 (via the PPC bootstub)

View File

@ -19,11 +19,6 @@
class PointerWrap;
namespace DiscIO
{
class NANDContentLoader;
}
namespace IOS
{
namespace HLE
@ -113,7 +108,7 @@ public:
void SetGidForPPC(u16 gid);
u16 GetGidForPPC() const;
bool BootstrapPPC(const DiscIO::NANDContentLoader& content_loader);
bool BootstrapPPC(const std::string& boot_content_path);
bool BootIOS(u64 ios_title_id);
u32 GetVersion() const;