[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) bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload)
{ {
const DiscIO::NANDContentLoader& content_loader = AccessContentDevice(title_id); const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id);
if (!content_loader.IsValid()) const IOS::ES::TicketReader ticket = FindSignedTicket(title_id);
if (!tmd.IsValid() || !ticket.IsValid())
{ {
if (title_id == Titles::SYSTEM_MENU) if (title_id == Titles::SYSTEM_MENU)
{ {
@ -268,22 +270,18 @@ bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload)
return false; 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, // 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 // 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. // again with the reload skipped, and the PPC will be bootstrapped then.
if (!skip_reload) if (!skip_reload)
{ {
s_title_to_launch = title_id; s_title_to_launch = title_id;
const u64 required_ios = content_loader.GetTMD().GetIOSId(); const u64 required_ios = tmd.GetIOSId();
return LaunchTitle(required_ios); return LaunchTitle(required_ios);
} }
m_title_context.Update(content_loader.GetTMD(), content_loader.GetTicket()); m_title_context.Update(tmd, ticket);
INFO_LOG(IOS_ES, "LaunchPPCTitle: Title context changed: %016" PRIx64, INFO_LOG(IOS_ES, "LaunchPPCTitle: Title context changed: %016" PRIx64, tmd.GetTitleId());
m_title_context.tmd.GetTitleId());
// Note: the UID/GID is also updated for IOS titles, but since we have no guarantee IOS titles // 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. // 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 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) void ES::Context::DoState(PointerWrap& p)
@ -310,7 +312,20 @@ void ES::Context::DoState(PointerWrap& p)
void ES::DoState(PointerWrap& p) void ES::DoState(PointerWrap& p)
{ {
Device::DoState(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); m_title_context.DoState(p);
for (auto& context : m_contexts) for (auto& context : m_contexts)
@ -573,11 +588,6 @@ IPCCommandResult ES::LaunchBC(const IOCtlVRequest& request)
return GetNoReply(); 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 // 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). // used from the PowerPC (for unpatched and up-to-date IOSes anyway).
// So we block access to it from the IPC interface. // So we block access to it from the IPC interface.

View File

@ -10,6 +10,7 @@
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/File.h"
#include "Core/IOS/Device.h" #include "Core/IOS/Device.h"
#include "Core/IOS/ES/Formats.h" #include "Core/IOS/ES/Formats.h"
#include "Core/IOS/IOS.h" #include "Core/IOS/IOS.h"
@ -343,13 +344,11 @@ private:
const IOS::ES::SharedContentMap& map = IOS::ES::SharedContentMap{ const IOS::ES::SharedContentMap& map = IOS::ES::SharedContentMap{
Common::FROM_SESSION_ROOT}) const; Common::FROM_SESSION_ROOT}) const;
// TODO: remove these
const DiscIO::NANDContentLoader& AccessContentDevice(u64 title_id);
// TODO: reuse the FS code. // TODO: reuse the FS code.
struct OpenedContent struct OpenedContent
{ {
bool m_opened = false; bool m_opened = false;
File::IOFile m_file;
u64 m_title_id = 0; u64 m_title_id = 0;
IOS::ES::Content m_content; IOS::ES::Content m_content;
u32 m_position = 0; 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) s32 ES::OpenContent(const IOS::ES::TMDReader& tmd, u16 content_index, u32 uid)
{ {
const u64 title_id = tmd.GetTitleId(); const u64 title_id = tmd.GetTitleId();
const DiscIO::NANDContentLoader& loader = AccessContentDevice(title_id);
if (!loader.IsValid()) IOS::ES::Content content;
return FS_ENOENT; if (!tmd.GetContent(content_index, &content))
return ES_EINVAL;
const DiscIO::NANDContent* content = loader.GetContentByIndex(content_index);
if (!content)
return FS_ENOENT;
for (size_t i = 0; i < m_content_table.size(); ++i) 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) if (entry.m_opened)
continue; continue;
if (!entry.m_file.Open(GetContentPath(title_id, content), "rb"))
return FS_ENOENT;
entry.m_opened = true; entry.m_opened = true;
entry.m_position = 0; entry.m_position = 0;
entry.m_content = content->m_metadata; entry.m_content = content;
entry.m_title_id = title_id; entry.m_title_id = title_id;
entry.m_uid = uid; entry.m_uid = uid;
INFO_LOG(IOS_ES, "OpenContent: title ID %016" PRIx64 ", UID 0x%x, CFD %zu", title_id, uid, i); INFO_LOG(IOS_ES, "OpenContent: title ID %016" PRIx64 ", UID 0x%x, CFD %zu", title_id, uid, i);
@ -102,21 +101,15 @@ 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 // XXX: make this reuse the FS code... ES just does a simple "IOS_Read" call here
// instead of all this duplicated filesystem logic. // instead of all this duplicated filesystem logic.
if (entry.m_position + size > entry.m_content.size) if (entry.m_position + size > entry.m_file.GetSize())
size = static_cast<u32>(entry.m_content.size) - entry.m_position; size = static_cast<u32>(entry.m_file.GetSize()) - entry.m_position;
const DiscIO::NANDContentLoader& ContentLoader = AccessContentDevice(entry.m_title_id); entry.m_file.Seek(entry.m_position, SEEK_SET);
// ContentLoader should never be invalid; rContent has been created by it. if (!entry.m_file.ReadBytes(buffer, size))
if (ContentLoader.IsValid() && ContentLoader.GetTicket().IsValid())
{
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); ERROR_LOG(IOS_ES, "ES: failed to read %u bytes from %u!", size, entry.m_position);
return ES_SHORT_READ; return ES_SHORT_READ;
} }
}
entry.m_position += size; entry.m_position += size;
return size; return size;
@ -145,15 +138,6 @@ ReturnCode ES::CloseContent(u32 cfd, u32 uid)
if (!entry.m_opened) if (!entry.m_opened)
return IPC_EINVAL; 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 = {}; entry = {};
INFO_LOG(IOS_ES, "CloseContent: CFD %u", cfd); INFO_LOG(IOS_ES, "CloseContent: CFD %u", cfd);
return IPC_SUCCESS; return IPC_SUCCESS;

View File

@ -54,7 +54,6 @@
#include "Core/IOS/WFS/WFSSRV.h" #include "Core/IOS/WFS/WFSSRV.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
#include "Core/WiiRoot.h" #include "Core/WiiRoot.h"
#include "DiscIO/NANDContentLoader.h"
namespace IOS 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. // 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. // 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()) const DolReader dol{boot_content_path};
return false;
const auto* content = content_loader.GetContentByIndex(content_loader.GetTMD().GetBootIndex()); if (!dol.IsValid())
if (!content)
return false;
const auto dol_loader = std::make_unique<DolReader>(content->m_Data->Get());
if (!dol_loader->IsValid())
return false; return false;
if (!SetupMemory(m_title_id, MemorySetupType::Full)) if (!SetupMemory(m_title_id, MemorySetupType::Full))
return false; return false;
if (!dol_loader->LoadIntoMemory()) if (!dol.LoadIntoMemory())
return false; return false;
// NAND titles start with address translation off at 0x3400 (via the PPC bootstub) // NAND titles start with address translation off at 0x3400 (via the PPC bootstub)

View File

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