mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
IOS/ES: Split ESDevice into ESCore and ESDevice.
ESCore implements the core functionality that can also be used outside of emulation. ESDevice implements the IOS device and is only available during emulation.
This commit is contained in:
@@ -160,7 +160,7 @@ JNIEXPORT jboolean JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_utils_WiiUtils_isSystemMenuInstalled(JNIEnv* env, jclass)
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
const auto tmd = ios.GetES()->FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
const auto tmd = ios.GetESCore().FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
|
||||
return tmd.IsValid();
|
||||
}
|
||||
@@ -169,7 +169,7 @@ JNIEXPORT jboolean JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_utils_WiiUtils_isSystemMenuvWii(JNIEnv* env, jclass)
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
const auto tmd = ios.GetES()->FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
const auto tmd = ios.GetESCore().FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
|
||||
return tmd.IsvWii();
|
||||
}
|
||||
@@ -178,7 +178,7 @@ JNIEXPORT jstring JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_utils_WiiUtils_getSystemMenuVersion(JNIEnv* env, jclass)
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
const auto tmd = ios.GetES()->FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
const auto tmd = ios.GetESCore().FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
|
||||
if (!tmd.IsValid())
|
||||
{
|
||||
|
||||
@@ -690,8 +690,8 @@ void UpdateStateFlags(std::function<void(StateFlags*)> update_function)
|
||||
|
||||
void CreateSystemMenuTitleDirs()
|
||||
{
|
||||
const auto es = IOS::HLE::GetIOS()->GetES();
|
||||
es->CreateTitleDirectories(Titles::SYSTEM_MENU, IOS::SYSMENU_GID);
|
||||
const auto& es = IOS::HLE::GetIOS()->GetESCore();
|
||||
es.CreateTitleDirectories(Titles::SYSTEM_MENU, IOS::SYSMENU_GID);
|
||||
}
|
||||
|
||||
void AddRiivolutionPatches(BootParameters* boot_params,
|
||||
|
||||
@@ -595,7 +595,7 @@ bool CBoot::EmulatedBS2_Wii(Core::System& system, const Core::CPUThreadGuard& gu
|
||||
|
||||
// Warning: This call will set incorrect running game metadata if our volume parameter
|
||||
// doesn't point to the same disc as the one that's inserted in the emulated disc drive!
|
||||
IOS::HLE::GetIOS()->GetES()->DIVerify(tmd, volume.GetTicket(partition));
|
||||
IOS::HLE::GetIOS()->GetESDevice()->DIVerify(tmd, volume.GetTicket(partition));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ bool CBoot::BootNANDTitle(Core::System& system, const u64 title_id)
|
||||
state->type = 0x04; // TYPE_NANDBOOT
|
||||
});
|
||||
|
||||
auto es = IOS::HLE::GetIOS()->GetES();
|
||||
const IOS::ES::TicketReader ticket = es->FindSignedTicket(title_id);
|
||||
auto es = IOS::HLE::GetIOS()->GetESDevice();
|
||||
const IOS::ES::TicketReader ticket = es->GetCore().FindSignedTicket(title_id);
|
||||
auto console_type = IOS::HLE::IOSC::ConsoleType::Retail;
|
||||
if (ticket.IsValid())
|
||||
console_type = ticket.GetConsoleType();
|
||||
|
||||
@@ -286,7 +286,7 @@ struct SetGameMetadata
|
||||
bool operator()(const BootParameters::NANDTitle& nand_title) const
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
const IOS::ES::TMDReader tmd = ios.GetES()->FindInstalledTMD(nand_title.id);
|
||||
const IOS::ES::TMDReader tmd = ios.GetESCore().FindInstalledTMD(nand_title.id);
|
||||
if (!tmd.IsValid() || !IOS::ES::IsChannel(nand_title.id))
|
||||
{
|
||||
PanicAlertFmtT("This title cannot be booted.");
|
||||
|
||||
@@ -553,7 +553,7 @@ CopyResult Import(const std::string& data_bin_path, std::function<bool()> can_ov
|
||||
return CopyResult::CorruptedSource;
|
||||
}
|
||||
|
||||
if (!WiiUtils::EnsureTMDIsImported(*ios.GetFS(), *ios.GetES(), header->tid))
|
||||
if (!WiiUtils::EnsureTMDIsImported(*ios.GetFS(), ios.GetESCore(), header->tid))
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "WiiSave::Import: Failed to find or import TMD for title {:16x}",
|
||||
header->tid);
|
||||
@@ -585,7 +585,7 @@ size_t ExportAll(std::string_view export_path)
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
size_t exported_save_count = 0;
|
||||
for (const u64 title : ios.GetES()->GetInstalledTitles())
|
||||
for (const u64 title : ios.GetESCore().GetInstalledTitles())
|
||||
{
|
||||
if (Export(title, export_path, &ios) == CopyResult::Success)
|
||||
++exported_save_count;
|
||||
|
||||
@@ -736,7 +736,8 @@ std::optional<IPCReply> DIDevice::IOCtlV(const IOCtlVRequest& request)
|
||||
const std::vector<u8>& raw_tmd = tmd.GetBytes();
|
||||
memory.CopyToEmu(request.io_vectors[0].address, raw_tmd.data(), raw_tmd.size());
|
||||
|
||||
ReturnCode es_result = m_ios.GetES()->DIVerify(tmd, dvd_thread.GetTicket(m_current_partition));
|
||||
ReturnCode es_result = GetEmulationKernel().GetESDevice()->DIVerify(
|
||||
tmd, dvd_thread.GetTicket(m_current_partition));
|
||||
memory.Write_U32(es_result, request.io_vectors[1].address);
|
||||
|
||||
return_value = DIResult::Success;
|
||||
|
||||
@@ -81,7 +81,7 @@ constexpr SystemTimers::TimeBaseTick GetESBootTicks(u32 ios_version)
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ESDevice::ESDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
|
||||
ESCore::ESCore(Kernel& ios) : m_ios(ios)
|
||||
{
|
||||
for (const auto& directory : s_directories_to_create)
|
||||
{
|
||||
@@ -101,13 +101,19 @@ ESDevice::ESDevice(Kernel& ios, const std::string& device_name) : Device(ios, de
|
||||
}
|
||||
|
||||
FinishAllStaleImports();
|
||||
}
|
||||
|
||||
ESCore::~ESCore() = default;
|
||||
|
||||
ESDevice::ESDevice(EmulationKernel& ios, ESCore& core, const std::string& device_name)
|
||||
: EmulationDevice(ios, device_name), m_core(core)
|
||||
{
|
||||
if (Core::IsRunningAndStarted())
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = ios.GetSystem();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
core_timing.RemoveEvent(s_finish_init_event);
|
||||
core_timing.ScheduleEvent(GetESBootTicks(m_ios.GetVersion()), s_finish_init_event);
|
||||
core_timing.ScheduleEvent(GetESBootTicks(ios.GetVersion()), s_finish_init_event);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -115,19 +121,23 @@ ESDevice::ESDevice(Kernel& ios, const std::string& device_name) : Device(ios, de
|
||||
}
|
||||
}
|
||||
|
||||
ESDevice::~ESDevice() = default;
|
||||
|
||||
void ESDevice::InitializeEmulationState()
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
s_finish_init_event = core_timing.RegisterEvent(
|
||||
"IOS-ESFinishInit", [](Core::System& system_, u64, s64) { GetIOS()->GetES()->FinishInit(); });
|
||||
s_finish_init_event =
|
||||
core_timing.RegisterEvent("IOS-ESFinishInit", [](Core::System& system_, u64, s64) {
|
||||
GetIOS()->GetESDevice()->FinishInit();
|
||||
});
|
||||
s_reload_ios_for_ppc_launch_event = core_timing.RegisterEvent(
|
||||
"IOS-ESReloadIOSForPPCLaunch", [](Core::System& system_, u64 ios_id, s64) {
|
||||
GetIOS()->GetES()->LaunchTitle(ios_id, HangPPC::Yes);
|
||||
GetIOS()->GetESDevice()->LaunchTitle(ios_id, HangPPC::Yes);
|
||||
});
|
||||
s_bootstrap_ppc_for_launch_event =
|
||||
core_timing.RegisterEvent("IOS-ESBootstrapPPCForLaunch", [](Core::System& system_, u64, s64) {
|
||||
GetIOS()->GetES()->BootstrapPPC();
|
||||
GetIOS()->GetESDevice()->BootstrapPPC();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -140,13 +150,13 @@ void ESDevice::FinalizeEmulationState()
|
||||
|
||||
void ESDevice::FinishInit()
|
||||
{
|
||||
m_ios.InitIPC();
|
||||
GetEmulationKernel().InitIPC();
|
||||
|
||||
std::optional<u64> pending_launch_title_id;
|
||||
|
||||
{
|
||||
const auto launch_file =
|
||||
m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, LAUNCH_FILE_PATH, FS::Mode::Read);
|
||||
const auto launch_file = GetEmulationKernel().GetFS()->OpenFile(
|
||||
PID_KERNEL, PID_KERNEL, LAUNCH_FILE_PATH, FS::Mode::Read);
|
||||
if (launch_file)
|
||||
{
|
||||
u64 id;
|
||||
@@ -202,7 +212,7 @@ IPCReply ESDevice::GetTitleDirectory(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 1))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
@@ -215,7 +225,7 @@ IPCReply ESDevice::GetTitleDirectory(const IOCtlVRequest& request)
|
||||
return IPCReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::GetTitleId(u64* title_id) const
|
||||
ReturnCode ESCore::GetTitleId(u64* title_id) const
|
||||
{
|
||||
if (!m_title_context.active)
|
||||
return ES_EINVAL;
|
||||
@@ -229,11 +239,11 @@ IPCReply ESDevice::GetTitleId(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
u64 title_id;
|
||||
const ReturnCode ret = GetTitleId(&title_id);
|
||||
const ReturnCode ret = m_core.GetTitleId(&title_id);
|
||||
if (ret != IPC_SUCCESS)
|
||||
return IPCReply(ret);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
memory.Write_U64(title_id, request.io_vectors[0].address);
|
||||
@@ -284,23 +294,23 @@ IPCReply ESDevice::SetUID(u32 uid, const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != 8)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
|
||||
const s32 ret = CheckIsAllowedToSetUID(m_ios, uid, m_title_context.tmd);
|
||||
const s32 ret = CheckIsAllowedToSetUID(GetEmulationKernel(), uid, m_core.m_title_context.tmd);
|
||||
if (ret < 0)
|
||||
{
|
||||
ERROR_LOG_FMT(IOS_ES, "SetUID: Permission check failed with error {}", ret);
|
||||
return IPCReply(ret);
|
||||
}
|
||||
|
||||
const auto tmd = FindInstalledTMD(title_id);
|
||||
const auto tmd = m_core.FindInstalledTMD(title_id);
|
||||
if (!tmd.IsValid())
|
||||
return IPCReply(FS_ENOENT);
|
||||
|
||||
if (!UpdateUIDAndGID(m_ios, tmd))
|
||||
if (!UpdateUIDAndGID(GetEmulationKernel(), tmd))
|
||||
{
|
||||
ERROR_LOG_FMT(IOS_ES, "SetUID: Failed to get UID for title {:016x}", title_id);
|
||||
return IPCReply(ES_SHORT_READ);
|
||||
@@ -311,13 +321,13 @@ IPCReply ESDevice::SetUID(u32 uid, const IOCtlVRequest& request)
|
||||
|
||||
bool ESDevice::LaunchTitle(u64 title_id, HangPPC hang_ppc)
|
||||
{
|
||||
m_title_context.Clear();
|
||||
m_core.m_title_context.Clear();
|
||||
INFO_LOG_FMT(IOS_ES, "ES_Launch: Title context changed: (none)");
|
||||
|
||||
NOTICE_LOG_FMT(IOS_ES, "Launching title {:016x}...", title_id);
|
||||
|
||||
if ((title_id == Titles::SHOP || title_id == Titles::KOREAN_SHOP) &&
|
||||
m_ios.GetIOSC().IsUsingDefaultId())
|
||||
GetEmulationKernel().GetIOSC().IsUsingDefaultId())
|
||||
{
|
||||
ERROR_LOG_FMT(IOS_ES, "Refusing to launch the shop channel with default device credentials");
|
||||
CriticalAlertFmtT(
|
||||
@@ -358,12 +368,12 @@ bool ESDevice::LaunchIOS(u64 ios_title_id, HangPPC hang_ppc)
|
||||
// so only have this check for MIOS (for which having the binary is *required*).
|
||||
if (ios_title_id == Titles::MIOS)
|
||||
{
|
||||
const ES::TMDReader tmd = FindInstalledTMD(ios_title_id);
|
||||
const ES::TicketReader ticket = FindSignedTicket(ios_title_id);
|
||||
const ES::TMDReader tmd = m_core.FindInstalledTMD(ios_title_id);
|
||||
const ES::TicketReader ticket = m_core.FindSignedTicket(ios_title_id);
|
||||
ES::Content content;
|
||||
if (!tmd.IsValid() || !ticket.IsValid() || !tmd.GetContent(tmd.GetBootIndex(), &content) ||
|
||||
!m_ios.BootIOS(Core::System::GetInstance(), ios_title_id, hang_ppc,
|
||||
GetContentPath(ios_title_id, content)))
|
||||
!GetEmulationKernel().BootIOS(GetSystem(), ios_title_id, hang_ppc,
|
||||
m_core.GetContentPath(ios_title_id, content)))
|
||||
{
|
||||
PanicAlertFmtT("Could not launch IOS {0:016x} because it is missing from the NAND.\n"
|
||||
"The emulated software will likely hang now.",
|
||||
@@ -373,12 +383,12 @@ bool ESDevice::LaunchIOS(u64 ios_title_id, HangPPC hang_ppc)
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_ios.BootIOS(Core::System::GetInstance(), ios_title_id, hang_ppc);
|
||||
return GetEmulationKernel().BootIOS(GetSystem(), ios_title_id, hang_ppc);
|
||||
}
|
||||
|
||||
s32 ESDevice::WriteLaunchFile(const ES::TMDReader& tmd, Ticks ticks)
|
||||
{
|
||||
m_ios.GetFSDevice()->DeleteFile(PID_KERNEL, PID_KERNEL, SPACE_FILE_PATH, ticks);
|
||||
GetEmulationKernel().GetFSDevice()->DeleteFile(PID_KERNEL, PID_KERNEL, SPACE_FILE_PATH, ticks);
|
||||
|
||||
std::vector<u8> launch_data(sizeof(u64) + sizeof(ES::TicketView));
|
||||
const u64 title_id = tmd.GetTitleId();
|
||||
@@ -393,8 +403,8 @@ bool ESDevice::LaunchPPCTitle(u64 title_id)
|
||||
{
|
||||
u64 ticks = 0;
|
||||
|
||||
const ES::TMDReader tmd = FindInstalledTMD(title_id, &ticks);
|
||||
const ES::TicketReader ticket = FindSignedTicket(title_id);
|
||||
const ES::TMDReader tmd = m_core.FindInstalledTMD(title_id, &ticks);
|
||||
const ES::TicketReader ticket = m_core.FindSignedTicket(title_id);
|
||||
|
||||
if (!tmd.IsValid() || !ticket.IsValid())
|
||||
{
|
||||
@@ -412,7 +422,7 @@ bool ESDevice::LaunchPPCTitle(u64 title_id)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
|
||||
// Before launching a title, IOS first reads the TMD and reloads into the specified IOS version,
|
||||
@@ -422,7 +432,7 @@ bool ESDevice::LaunchPPCTitle(u64 title_id)
|
||||
// To keep track of the PPC title launch, a temporary launch file (LAUNCH_FILE_PATH) is used
|
||||
// to store the title ID of the title to launch and its TMD.
|
||||
// The launch file not existing means an IOS reload is required.
|
||||
if (const auto launch_file_fd = m_ios.GetFSDevice()->Open(
|
||||
if (const auto launch_file_fd = GetEmulationKernel().GetFSDevice()->Open(
|
||||
PID_KERNEL, PID_KERNEL, LAUNCH_FILE_PATH, FS::Mode::Read, {}, &ticks);
|
||||
launch_file_fd.Get() < 0)
|
||||
{
|
||||
@@ -442,17 +452,17 @@ bool ESDevice::LaunchPPCTitle(u64 title_id)
|
||||
|
||||
// Otherwise, assume that the PPC title can now be launched directly.
|
||||
// Unlike IOS, we won't bother checking the title ID in the launch file. (It's not useful.)
|
||||
m_ios.GetFSDevice()->DeleteFile(PID_KERNEL, PID_KERNEL, LAUNCH_FILE_PATH, &ticks);
|
||||
GetEmulationKernel().GetFSDevice()->DeleteFile(PID_KERNEL, PID_KERNEL, LAUNCH_FILE_PATH, &ticks);
|
||||
WriteSystemFile(SPACE_FILE_PATH, std::vector<u8>(SPACE_FILE_SIZE), &ticks);
|
||||
|
||||
m_title_context.Update(tmd, ticket, DiscIO::Platform::WiiWAD);
|
||||
m_core.m_title_context.Update(tmd, ticket, DiscIO::Platform::WiiWAD);
|
||||
INFO_LOG_FMT(IOS_ES, "LaunchPPCTitle: Title context changed: {:016x}", 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.
|
||||
if (!UpdateUIDAndGID(m_ios, m_title_context.tmd))
|
||||
if (!UpdateUIDAndGID(GetEmulationKernel(), m_core.m_title_context.tmd))
|
||||
{
|
||||
m_title_context.Clear();
|
||||
m_core.m_title_context.Clear();
|
||||
INFO_LOG_FMT(IOS_ES, "LaunchPPCTitle: Title context changed: (none)");
|
||||
return false;
|
||||
}
|
||||
@@ -461,7 +471,7 @@ bool ESDevice::LaunchPPCTitle(u64 title_id)
|
||||
if (!tmd.GetContent(tmd.GetBootIndex(), &content))
|
||||
return false;
|
||||
|
||||
m_pending_ppc_boot_content_path = GetContentPath(tmd.GetTitleId(), content);
|
||||
m_pending_ppc_boot_content_path = m_core.GetContentPath(tmd.GetTitleId(), content);
|
||||
if (!Core::IsRunningAndStarted())
|
||||
return BootstrapPPC();
|
||||
|
||||
@@ -473,12 +483,12 @@ bool ESDevice::LaunchPPCTitle(u64 title_id)
|
||||
bool ESDevice::BootstrapPPC()
|
||||
{
|
||||
const bool result =
|
||||
m_ios.BootstrapPPC(Core::System::GetInstance(), m_pending_ppc_boot_content_path);
|
||||
GetEmulationKernel().BootstrapPPC(GetSystem(), m_pending_ppc_boot_content_path);
|
||||
m_pending_ppc_boot_content_path = {};
|
||||
return result;
|
||||
}
|
||||
|
||||
void ESDevice::Context::DoState(PointerWrap& p)
|
||||
void ESCore::Context::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(uid);
|
||||
p.Do(gid);
|
||||
@@ -492,7 +502,7 @@ void ESDevice::DoState(PointerWrap& p)
|
||||
{
|
||||
Device::DoState(p);
|
||||
|
||||
for (auto& entry : m_content_table)
|
||||
for (auto& entry : m_core.m_content_table)
|
||||
{
|
||||
p.Do(entry.m_opened);
|
||||
p.Do(entry.m_title_id);
|
||||
@@ -501,7 +511,7 @@ void ESDevice::DoState(PointerWrap& p)
|
||||
p.Do(entry.m_uid);
|
||||
}
|
||||
|
||||
m_title_context.DoState(p);
|
||||
m_core.m_title_context.DoState(p);
|
||||
|
||||
for (auto& context : m_contexts)
|
||||
context.DoState(p);
|
||||
@@ -702,7 +712,7 @@ std::optional<IPCReply> ESDevice::IOCtlV(const IOCtlVRequest& request)
|
||||
case IOCTL_ES_UNKNOWN_42:
|
||||
PanicAlertFmt("IOS-ES: Unimplemented ioctlv {:#x} ({} in vectors, {} io vectors)",
|
||||
request.request, request.in_vectors.size(), request.io_vectors.size());
|
||||
request.DumpUnknown(Core::System::GetInstance(), GetDeviceName(), Common::Log::LogType::IOS_ES,
|
||||
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_ES,
|
||||
Common::Log::LogLevel::LERROR);
|
||||
return IPCReply(IPC_EINVAL);
|
||||
|
||||
@@ -718,7 +728,7 @@ IPCReply ESDevice::GetConsumption(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
// This is at least what crediar's ES module does
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(0, request.io_vectors[1].address);
|
||||
INFO_LOG_FMT(IOS_ES, "IOCTL_ES_GETCONSUMPTION");
|
||||
@@ -730,7 +740,7 @@ std::optional<IPCReply> ESDevice::Launch(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(2, 0))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
@@ -765,7 +775,7 @@ std::optional<IPCReply> ESDevice::LaunchBC(const IOCtlVRequest& request)
|
||||
|
||||
// Here, IOS checks the clock speed and prevents ioctlv 0x25 from being used in GC mode.
|
||||
// An alternative way to do this is to check whether the current active IOS is MIOS.
|
||||
if (m_ios.GetVersion() == 0x101)
|
||||
if (GetEmulationKernel().GetVersion() == 0x101)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
if (!LaunchTitle(0x0000000100000100))
|
||||
@@ -808,7 +818,7 @@ static ReturnCode WriteTmdForDiVerify(FS::FileSystem* fs, const ES::TMDReader& t
|
||||
|
||||
ReturnCode ESDevice::DIVerify(const ES::TMDReader& tmd, const ES::TicketReader& ticket)
|
||||
{
|
||||
m_title_context.Clear();
|
||||
m_core.m_title_context.Clear();
|
||||
INFO_LOG_FMT(IOS_ES, "ES_DIVerify: Title context changed: (none)");
|
||||
|
||||
if (!tmd.IsValid() || !ticket.IsValid())
|
||||
@@ -817,14 +827,14 @@ ReturnCode ESDevice::DIVerify(const ES::TMDReader& tmd, const ES::TicketReader&
|
||||
if (tmd.GetTitleId() != ticket.GetTitleId())
|
||||
return ES_EINVAL;
|
||||
|
||||
m_title_context.Update(tmd, ticket, DiscIO::Platform::WiiDisc);
|
||||
m_core.m_title_context.Update(tmd, ticket, DiscIO::Platform::WiiDisc);
|
||||
INFO_LOG_FMT(IOS_ES, "ES_DIVerify: Title context changed: {:016x}", tmd.GetTitleId());
|
||||
|
||||
// XXX: We are supposed to verify the TMD and ticket here, but cannot because
|
||||
// this may cause issues with custom/patched games.
|
||||
|
||||
const auto fs = m_ios.GetFS();
|
||||
if (!FindInstalledTMD(tmd.GetTitleId()).IsValid())
|
||||
const auto fs = GetEmulationKernel().GetFS();
|
||||
if (!m_core.FindInstalledTMD(tmd.GetTitleId()).IsValid())
|
||||
{
|
||||
if (const ReturnCode ret = WriteTmdForDiVerify(fs.get(), tmd))
|
||||
{
|
||||
@@ -833,7 +843,7 @@ ReturnCode ESDevice::DIVerify(const ES::TMDReader& tmd, const ES::TicketReader&
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateUIDAndGID(*GetIOS(), m_title_context.tmd))
|
||||
if (!UpdateUIDAndGID(GetEmulationKernel(), m_core.m_title_context.tmd))
|
||||
{
|
||||
return ES_SHORT_READ;
|
||||
}
|
||||
@@ -842,12 +852,12 @@ ReturnCode ESDevice::DIVerify(const ES::TMDReader& tmd, const ES::TicketReader&
|
||||
// Might already exist, so we only need to check whether the second operation succeeded.
|
||||
constexpr FS::Modes data_dir_modes{FS::Mode::ReadWrite, FS::Mode::None, FS::Mode::None};
|
||||
fs->CreateDirectory(PID_KERNEL, PID_KERNEL, data_dir, 0, data_dir_modes);
|
||||
return FS::ConvertResult(
|
||||
fs->SetMetadata(0, data_dir, m_ios.GetUidForPPC(), m_ios.GetGidForPPC(), 0, data_dir_modes));
|
||||
return FS::ConvertResult(fs->SetMetadata(0, data_dir, GetEmulationKernel().GetUidForPPC(),
|
||||
GetEmulationKernel().GetGidForPPC(), 0, data_dir_modes));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::CheckStreamKeyPermissions(const u32 uid, const u8* ticket_view,
|
||||
const ES::TMDReader& tmd) const
|
||||
ReturnCode ESCore::CheckStreamKeyPermissions(const u32 uid, const u8* ticket_view,
|
||||
const ES::TMDReader& tmd) const
|
||||
{
|
||||
const u32 title_flags = tmd.GetTitleFlags();
|
||||
// Only allow using this function with some titles (WFS titles).
|
||||
@@ -889,8 +899,8 @@ ReturnCode ESDevice::CheckStreamKeyPermissions(const u32 uid, const u8* ticket_v
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::SetUpStreamKey(const u32 uid, const u8* ticket_view, const ES::TMDReader& tmd,
|
||||
u32* handle)
|
||||
ReturnCode ESCore::SetUpStreamKey(const u32 uid, const u8* ticket_view, const ES::TMDReader& tmd,
|
||||
u32* handle)
|
||||
{
|
||||
ReturnCode ret = CheckStreamKeyPermissions(uid, ticket_view, tmd);
|
||||
if (ret != IPC_SUCCESS)
|
||||
@@ -952,7 +962,7 @@ IPCReply ESDevice::SetUpStreamKey(const Context& context, const IOCtlVRequest& r
|
||||
return IPCReply(ES_EINVAL);
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
std::vector<u8> tmd_bytes(request.in_vectors[1].size);
|
||||
@@ -963,8 +973,8 @@ IPCReply ESDevice::SetUpStreamKey(const Context& context, const IOCtlVRequest& r
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
u32 handle;
|
||||
const ReturnCode ret =
|
||||
SetUpStreamKey(context.uid, memory.GetPointer(request.in_vectors[0].address), tmd, &handle);
|
||||
const ReturnCode ret = m_core.SetUpStreamKey(
|
||||
context.uid, memory.GetPointer(request.in_vectors[0].address), tmd, &handle);
|
||||
memory.Write_U32(handle, request.io_vectors[0].address);
|
||||
return IPCReply(ret);
|
||||
}
|
||||
@@ -974,13 +984,13 @@ IPCReply ESDevice::DeleteStreamKey(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u32))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u32 handle = memory.Read_U32(request.in_vectors[0].address);
|
||||
return IPCReply(m_ios.GetIOSC().DeleteObject(handle, PID_ES));
|
||||
return IPCReply(GetEmulationKernel().GetIOSC().DeleteObject(handle, PID_ES));
|
||||
}
|
||||
|
||||
bool ESDevice::IsActiveTitlePermittedByTicket(const u8* ticket_view) const
|
||||
bool ESCore::IsActiveTitlePermittedByTicket(const u8* ticket_view) const
|
||||
{
|
||||
if (!m_title_context.active)
|
||||
return false;
|
||||
@@ -993,7 +1003,7 @@ bool ESDevice::IsActiveTitlePermittedByTicket(const u8* ticket_view) const
|
||||
return title_identifier && (title_identifier & ~permitted_title_mask) == permitted_title_id;
|
||||
}
|
||||
|
||||
bool ESDevice::IsIssuerCorrect(VerifyContainerType type, const ES::CertReader& issuer_cert) const
|
||||
bool ESCore::IsIssuerCorrect(VerifyContainerType type, const ES::CertReader& issuer_cert) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@@ -1010,7 +1020,7 @@ bool ESDevice::IsIssuerCorrect(VerifyContainerType type, const ES::CertReader& i
|
||||
|
||||
static const std::string CERT_STORE_PATH = "/sys/cert.sys";
|
||||
|
||||
ReturnCode ESDevice::ReadCertStore(std::vector<u8>* buffer) const
|
||||
ReturnCode ESCore::ReadCertStore(std::vector<u8>* buffer) const
|
||||
{
|
||||
const auto store_file =
|
||||
m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, CERT_STORE_PATH, FS::Mode::Read);
|
||||
@@ -1023,7 +1033,7 @@ ReturnCode ESDevice::ReadCertStore(std::vector<u8>* buffer) const
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::WriteNewCertToStore(const ES::CertReader& cert)
|
||||
ReturnCode ESCore::WriteNewCertToStore(const ES::CertReader& cert)
|
||||
{
|
||||
// Read the current store to determine if the new cert needs to be written.
|
||||
std::vector<u8> current_store;
|
||||
@@ -1048,9 +1058,9 @@ ReturnCode ESDevice::WriteNewCertToStore(const ES::CertReader& cert)
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
|
||||
const ES::SignedBlobReader& signed_blob,
|
||||
const std::vector<u8>& cert_chain, u32* issuer_handle_out)
|
||||
ReturnCode ESCore::VerifyContainer(VerifyContainerType type, VerifyMode mode,
|
||||
const ES::SignedBlobReader& signed_blob,
|
||||
const std::vector<u8>& cert_chain, u32* issuer_handle_out)
|
||||
{
|
||||
if (!signed_blob.IsSignatureValid())
|
||||
return ES_EINVAL;
|
||||
@@ -1144,9 +1154,9 @@ ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::VerifyContainer(VerifyContainerType type, VerifyMode mode,
|
||||
const ES::CertReader& cert, const std::vector<u8>& cert_chain,
|
||||
u32 certificate_iosc_handle)
|
||||
ReturnCode ESCore::VerifyContainer(VerifyContainerType type, VerifyMode mode,
|
||||
const ES::CertReader& cert, const std::vector<u8>& cert_chain,
|
||||
u32 certificate_iosc_handle)
|
||||
{
|
||||
IOSC::Handle issuer_handle;
|
||||
ReturnCode ret = VerifyContainer(type, mode, cert, cert_chain, &issuer_handle);
|
||||
|
||||
@@ -37,22 +37,17 @@ struct TitleContext
|
||||
bool first_change = true;
|
||||
};
|
||||
|
||||
class ESDevice final : public Device
|
||||
class ESDevice;
|
||||
|
||||
class ESCore final
|
||||
{
|
||||
public:
|
||||
ESDevice(Kernel& ios, const std::string& device_name);
|
||||
|
||||
static void InitializeEmulationState();
|
||||
static void FinalizeEmulationState();
|
||||
|
||||
ReturnCode DIVerify(const ES::TMDReader& tmd, const ES::TicketReader& ticket);
|
||||
bool LaunchTitle(u64 title_id, HangPPC hang_ppc = HangPPC::No);
|
||||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
||||
std::optional<IPCReply> Close(u32 fd) override;
|
||||
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
|
||||
explicit ESCore(Kernel& ios);
|
||||
ESCore(const ESCore& other) = delete;
|
||||
ESCore(ESCore&& other) = delete;
|
||||
ESCore& operator=(const ESCore& other) = delete;
|
||||
ESCore& operator=(ESCore&& other) = delete;
|
||||
~ESCore();
|
||||
|
||||
struct TitleImportExportContext
|
||||
{
|
||||
@@ -83,12 +78,6 @@ public:
|
||||
s32 ipc_fd = -1;
|
||||
};
|
||||
|
||||
enum class CheckContentHashes : bool
|
||||
{
|
||||
Yes = true,
|
||||
No = false,
|
||||
};
|
||||
|
||||
ES::TMDReader FindImportTMD(u64 title_id, Ticks ticks = {}) const;
|
||||
ES::TMDReader FindInstalledTMD(u64 title_id, Ticks ticks = {}) const;
|
||||
ES::TicketReader FindSignedTicket(u64 title_id,
|
||||
@@ -101,6 +90,12 @@ public:
|
||||
// Get titles for which there is a ticket (in /ticket).
|
||||
std::vector<u64> GetTitlesWithTickets() const;
|
||||
|
||||
enum class CheckContentHashes : bool
|
||||
{
|
||||
Yes = true,
|
||||
No = false,
|
||||
};
|
||||
|
||||
std::vector<ES::Content>
|
||||
GetStoredContentsFromTMD(const ES::TMDReader& tmd,
|
||||
CheckContentHashes check_content_hashes = CheckContentHashes::No) const;
|
||||
@@ -186,6 +181,71 @@ public:
|
||||
const ES::CertReader& certificate, const std::vector<u8>& cert_chain,
|
||||
u32 certificate_iosc_handle);
|
||||
|
||||
private:
|
||||
// Start a title import.
|
||||
bool InitImport(const ES::TMDReader& tmd);
|
||||
// Clean up the import content directory and move it back to /title.
|
||||
bool FinishImport(const ES::TMDReader& tmd);
|
||||
// Write a TMD for a title in /import atomically.
|
||||
bool WriteImportTMD(const ES::TMDReader& tmd);
|
||||
// Finish stale imports and clear the import directory.
|
||||
void FinishStaleImport(u64 title_id);
|
||||
void FinishAllStaleImports();
|
||||
|
||||
std::string GetContentPath(u64 title_id, const ES::Content& content, Ticks ticks = {}) const;
|
||||
|
||||
bool IsActiveTitlePermittedByTicket(const u8* ticket_view) const;
|
||||
|
||||
bool IsIssuerCorrect(VerifyContainerType type, const ES::CertReader& issuer_cert) const;
|
||||
ReturnCode ReadCertStore(std::vector<u8>* buffer) const;
|
||||
ReturnCode WriteNewCertToStore(const ES::CertReader& cert);
|
||||
|
||||
ReturnCode CheckStreamKeyPermissions(u32 uid, const u8* ticket_view,
|
||||
const ES::TMDReader& tmd) const;
|
||||
|
||||
struct OpenedContent
|
||||
{
|
||||
bool m_opened = false;
|
||||
u64 m_fd = 0;
|
||||
u64 m_title_id = 0;
|
||||
ES::Content m_content{};
|
||||
u32 m_uid = 0;
|
||||
};
|
||||
|
||||
Kernel& m_ios;
|
||||
|
||||
using ContentTable = std::array<OpenedContent, 16>;
|
||||
ContentTable m_content_table;
|
||||
|
||||
TitleContext m_title_context{};
|
||||
|
||||
friend class ESDevice;
|
||||
};
|
||||
|
||||
class ESDevice final : public EmulationDevice
|
||||
{
|
||||
public:
|
||||
ESDevice(EmulationKernel& ios, ESCore& core, const std::string& device_name);
|
||||
ESDevice(const ESDevice& other) = delete;
|
||||
ESDevice(ESDevice&& other) = delete;
|
||||
ESDevice& operator=(const ESDevice& other) = delete;
|
||||
ESDevice& operator=(ESDevice&& other) = delete;
|
||||
~ESDevice();
|
||||
|
||||
static void InitializeEmulationState();
|
||||
static void FinalizeEmulationState();
|
||||
|
||||
ReturnCode DIVerify(const ES::TMDReader& tmd, const ES::TicketReader& ticket);
|
||||
bool LaunchTitle(u64 title_id, HangPPC hang_ppc = HangPPC::No);
|
||||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
||||
std::optional<IPCReply> Close(u32 fd) override;
|
||||
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
|
||||
|
||||
ESCore& GetCore() const { return m_core; }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -261,6 +321,7 @@ private:
|
||||
};
|
||||
|
||||
// ES can only have 3 contexts at one time.
|
||||
using Context = ESCore::Context;
|
||||
using ContextArray = std::array<Context, 3>;
|
||||
|
||||
// Title management
|
||||
@@ -348,47 +409,15 @@ private:
|
||||
|
||||
bool LaunchIOS(u64 ios_title_id, HangPPC hang_ppc);
|
||||
bool LaunchPPCTitle(u64 title_id);
|
||||
bool IsActiveTitlePermittedByTicket(const u8* ticket_view) const;
|
||||
|
||||
ReturnCode CheckStreamKeyPermissions(u32 uid, const u8* ticket_view,
|
||||
const ES::TMDReader& tmd) const;
|
||||
|
||||
bool IsIssuerCorrect(VerifyContainerType type, const ES::CertReader& issuer_cert) const;
|
||||
ReturnCode ReadCertStore(std::vector<u8>* buffer) const;
|
||||
ReturnCode WriteNewCertToStore(const ES::CertReader& cert);
|
||||
|
||||
// Start a title import.
|
||||
bool InitImport(const ES::TMDReader& tmd);
|
||||
// Clean up the import content directory and move it back to /title.
|
||||
bool FinishImport(const ES::TMDReader& tmd);
|
||||
// Write a TMD for a title in /import atomically.
|
||||
bool WriteImportTMD(const ES::TMDReader& tmd);
|
||||
// Finish stale imports and clear the import directory.
|
||||
void FinishStaleImport(u64 title_id);
|
||||
void FinishAllStaleImports();
|
||||
|
||||
void FinishInit();
|
||||
|
||||
std::string GetContentPath(u64 title_id, const ES::Content& content, Ticks ticks = {}) const;
|
||||
|
||||
s32 WriteSystemFile(const std::string& path, const std::vector<u8>& data, Ticks ticks = {});
|
||||
s32 WriteLaunchFile(const ES::TMDReader& tmd, Ticks ticks = {});
|
||||
bool BootstrapPPC();
|
||||
|
||||
struct OpenedContent
|
||||
{
|
||||
bool m_opened = false;
|
||||
u64 m_fd = 0;
|
||||
u64 m_title_id = 0;
|
||||
ES::Content m_content{};
|
||||
u32 m_uid = 0;
|
||||
};
|
||||
|
||||
using ContentTable = std::array<OpenedContent, 16>;
|
||||
ContentTable m_content_table;
|
||||
|
||||
ESCore& m_core;
|
||||
ContextArray m_contexts;
|
||||
TitleContext m_title_context{};
|
||||
std::string m_pending_ppc_boot_content_path;
|
||||
};
|
||||
} // namespace IOS::HLE
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace IOS::HLE
|
||||
{
|
||||
ReturnCode ESDevice::GetDeviceId(u32* device_id) const
|
||||
ReturnCode ESCore::GetDeviceId(u32* device_id) const
|
||||
{
|
||||
*device_id = m_ios.GetIOSC().GetDeviceId();
|
||||
INFO_LOG_FMT(IOS_ES, "GetDeviceId: {:08X}", *device_id);
|
||||
@@ -32,11 +32,11 @@ IPCReply ESDevice::GetDeviceId(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
u32 device_id;
|
||||
const ReturnCode ret = GetDeviceId(&device_id);
|
||||
const ReturnCode ret = m_core.GetDeviceId(&device_id);
|
||||
if (ret != IPC_SUCCESS)
|
||||
return IPCReply(ret);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(device_id, request.io_vectors[0].address);
|
||||
return IPCReply(IPC_SUCCESS);
|
||||
@@ -47,7 +47,7 @@ IPCReply ESDevice::Encrypt(u32 uid, const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(3, 2))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
u32 keyIndex = memory.Read_U32(request.in_vectors[0].address);
|
||||
u8* source = memory.GetPointer(request.in_vectors[2].address);
|
||||
@@ -57,7 +57,8 @@ IPCReply ESDevice::Encrypt(u32 uid, const IOCtlVRequest& request)
|
||||
|
||||
// TODO: Check whether the active title is allowed to encrypt.
|
||||
|
||||
const ReturnCode ret = m_ios.GetIOSC().Encrypt(keyIndex, iv, source, size, destination, PID_ES);
|
||||
const ReturnCode ret =
|
||||
GetEmulationKernel().GetIOSC().Encrypt(keyIndex, iv, source, size, destination, PID_ES);
|
||||
return IPCReply(ret);
|
||||
}
|
||||
|
||||
@@ -66,7 +67,7 @@ IPCReply ESDevice::Decrypt(u32 uid, const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(3, 2))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
u32 keyIndex = memory.Read_U32(request.in_vectors[0].address);
|
||||
u8* source = memory.GetPointer(request.in_vectors[2].address);
|
||||
@@ -76,7 +77,8 @@ IPCReply ESDevice::Decrypt(u32 uid, const IOCtlVRequest& request)
|
||||
|
||||
// TODO: Check whether the active title is allowed to decrypt.
|
||||
|
||||
const ReturnCode ret = m_ios.GetIOSC().Decrypt(keyIndex, iv, source, size, destination, PID_ES);
|
||||
const ReturnCode ret =
|
||||
GetEmulationKernel().GetIOSC().Decrypt(keyIndex, iv, source, size, destination, PID_ES);
|
||||
return IPCReply(ret);
|
||||
}
|
||||
|
||||
@@ -100,9 +102,9 @@ IPCReply ESDevice::GetDeviceCertificate(const IOCtlVRequest& request)
|
||||
|
||||
INFO_LOG_FMT(IOS_ES, "IOCTL_ES_GETDEVICECERT");
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const IOS::CertECC cert = m_ios.GetIOSC().GetDeviceCertificate();
|
||||
const IOS::CertECC cert = GetEmulationKernel().GetIOSC().GetDeviceCertificate();
|
||||
memory.CopyToEmu(request.io_vectors[0].address, &cert, sizeof(cert));
|
||||
return IPCReply(IPC_SUCCESS);
|
||||
}
|
||||
@@ -113,22 +115,23 @@ IPCReply ESDevice::Sign(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
INFO_LOG_FMT(IOS_ES, "IOCTL_ES_SIGN");
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
u8* ap_cert_out = memory.GetPointer(request.io_vectors[1].address);
|
||||
u8* data = memory.GetPointer(request.in_vectors[0].address);
|
||||
u32 data_size = request.in_vectors[0].size;
|
||||
u8* sig_out = memory.GetPointer(request.io_vectors[0].address);
|
||||
|
||||
if (!m_title_context.active)
|
||||
if (!m_core.m_title_context.active)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
m_ios.GetIOSC().Sign(sig_out, ap_cert_out, m_title_context.tmd.GetTitleId(), data, data_size);
|
||||
GetEmulationKernel().GetIOSC().Sign(sig_out, ap_cert_out, m_core.m_title_context.tmd.GetTitleId(),
|
||||
data, data_size);
|
||||
return IPCReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::VerifySign(const std::vector<u8>& hash, const std::vector<u8>& ecc_signature,
|
||||
const std::vector<u8>& certs_bytes)
|
||||
ReturnCode ESCore::VerifySign(const std::vector<u8>& hash, const std::vector<u8>& ecc_signature,
|
||||
const std::vector<u8>& certs_bytes)
|
||||
{
|
||||
const std::map<std::string, ES::CertReader> certs = ES::ParseCertChain(certs_bytes);
|
||||
if (certs.empty())
|
||||
@@ -205,7 +208,7 @@ IPCReply ESDevice::VerifySign(const IOCtlVRequest& request)
|
||||
if (request.in_vectors[1].size != sizeof(Common::ec::Signature))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
std::vector<u8> hash(request.in_vectors[0].size);
|
||||
@@ -217,6 +220,6 @@ IPCReply ESDevice::VerifySign(const IOCtlVRequest& request)
|
||||
std::vector<u8> certs(request.in_vectors[2].size);
|
||||
memory.CopyFromEmu(certs.data(), request.in_vectors[2].address, certs.size());
|
||||
|
||||
return IPCReply(VerifySign(hash, ecc_signature, certs));
|
||||
return IPCReply(m_core.VerifySign(hash, ecc_signature, certs));
|
||||
}
|
||||
} // namespace IOS::HLE
|
||||
|
||||
@@ -38,18 +38,18 @@ static ES::TMDReader FindTMD(FSDevice& fs, const std::string& tmd_path, Ticks ti
|
||||
return ES::TMDReader{std::move(tmd_bytes)};
|
||||
}
|
||||
|
||||
ES::TMDReader ESDevice::FindImportTMD(u64 title_id, Ticks ticks) const
|
||||
ES::TMDReader ESCore::FindImportTMD(u64 title_id, Ticks ticks) const
|
||||
{
|
||||
return FindTMD(*m_ios.GetFSDevice(), Common::GetImportTitlePath(title_id) + "/content/title.tmd",
|
||||
ticks);
|
||||
}
|
||||
|
||||
ES::TMDReader ESDevice::FindInstalledTMD(u64 title_id, Ticks ticks) const
|
||||
ES::TMDReader ESCore::FindInstalledTMD(u64 title_id, Ticks ticks) const
|
||||
{
|
||||
return FindTMD(*m_ios.GetFSDevice(), Common::GetTMDFileName(title_id), ticks);
|
||||
}
|
||||
|
||||
ES::TicketReader ESDevice::FindSignedTicket(u64 title_id, std::optional<u8> desired_version) const
|
||||
ES::TicketReader ESCore::FindSignedTicket(u64 title_id, std::optional<u8> desired_version) const
|
||||
{
|
||||
std::string path = desired_version == 1 ? Common::GetV1TicketFileName(title_id) :
|
||||
Common::GetTicketFileName(title_id);
|
||||
@@ -125,17 +125,17 @@ static std::vector<u64> GetTitlesInTitleOrImport(FS::FileSystem* fs, const std::
|
||||
return title_ids;
|
||||
}
|
||||
|
||||
std::vector<u64> ESDevice::GetInstalledTitles() const
|
||||
std::vector<u64> ESCore::GetInstalledTitles() const
|
||||
{
|
||||
return GetTitlesInTitleOrImport(m_ios.GetFS().get(), "/title");
|
||||
}
|
||||
|
||||
std::vector<u64> ESDevice::GetTitleImports() const
|
||||
std::vector<u64> ESCore::GetTitleImports() const
|
||||
{
|
||||
return GetTitlesInTitleOrImport(m_ios.GetFS().get(), "/import");
|
||||
}
|
||||
|
||||
std::vector<u64> ESDevice::GetTitlesWithTickets() const
|
||||
std::vector<u64> ESCore::GetTitlesWithTickets() const
|
||||
{
|
||||
const auto fs = m_ios.GetFS();
|
||||
const auto entries = fs->ReadDirectory(PID_KERNEL, PID_KERNEL, "/ticket");
|
||||
@@ -179,8 +179,8 @@ std::vector<u64> ESDevice::GetTitlesWithTickets() const
|
||||
}
|
||||
|
||||
std::vector<ES::Content>
|
||||
ESDevice::GetStoredContentsFromTMD(const ES::TMDReader& tmd,
|
||||
CheckContentHashes check_content_hashes) const
|
||||
ESCore::GetStoredContentsFromTMD(const ES::TMDReader& tmd,
|
||||
CheckContentHashes check_content_hashes) const
|
||||
{
|
||||
if (!tmd.IsValid())
|
||||
return {};
|
||||
@@ -216,7 +216,7 @@ ESDevice::GetStoredContentsFromTMD(const ES::TMDReader& tmd,
|
||||
return stored_contents;
|
||||
}
|
||||
|
||||
u32 ESDevice::GetSharedContentsCount() const
|
||||
u32 ESCore::GetSharedContentsCount() const
|
||||
{
|
||||
const auto entries = m_ios.GetFS()->ReadDirectory(PID_KERNEL, PID_KERNEL, "/shared1");
|
||||
return static_cast<u32>(
|
||||
@@ -226,7 +226,7 @@ u32 ESDevice::GetSharedContentsCount() const
|
||||
}));
|
||||
}
|
||||
|
||||
std::vector<std::array<u8, 20>> ESDevice::GetSharedContents() const
|
||||
std::vector<std::array<u8, 20>> ESCore::GetSharedContents() const
|
||||
{
|
||||
const ES::SharedContentMap map{m_ios.GetFSDevice()};
|
||||
return map.GetHashes();
|
||||
@@ -253,7 +253,7 @@ constexpr FS::Modes title_dir_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS
|
||||
constexpr FS::Modes content_dir_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None};
|
||||
constexpr FS::Modes data_dir_modes{FS::Mode::ReadWrite, FS::Mode::None, FS::Mode::None};
|
||||
|
||||
bool ESDevice::CreateTitleDirectories(u64 title_id, u16 group_id) const
|
||||
bool ESCore::CreateTitleDirectories(u64 title_id, u16 group_id) const
|
||||
{
|
||||
const auto fs = m_ios.GetFS();
|
||||
|
||||
@@ -289,7 +289,7 @@ bool ESDevice::CreateTitleDirectories(u64 title_id, u16 group_id) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ESDevice::InitImport(const ES::TMDReader& tmd)
|
||||
bool ESCore::InitImport(const ES::TMDReader& tmd)
|
||||
{
|
||||
if (!CreateTitleDirectories(tmd.GetTitleId(), tmd.GetGroupId()))
|
||||
return false;
|
||||
@@ -321,7 +321,7 @@ bool ESDevice::InitImport(const ES::TMDReader& tmd)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ESDevice::FinishImport(const ES::TMDReader& tmd)
|
||||
bool ESCore::FinishImport(const ES::TMDReader& tmd)
|
||||
{
|
||||
const auto fs = m_ios.GetFS();
|
||||
const u64 title_id = tmd.GetTitleId();
|
||||
@@ -354,7 +354,7 @@ bool ESDevice::FinishImport(const ES::TMDReader& tmd)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ESDevice::WriteImportTMD(const ES::TMDReader& tmd)
|
||||
bool ESCore::WriteImportTMD(const ES::TMDReader& tmd)
|
||||
{
|
||||
const auto fs = m_ios.GetFS();
|
||||
const std::string tmd_path = "/tmp/title.tmd";
|
||||
@@ -369,7 +369,7 @@ bool ESDevice::WriteImportTMD(const ES::TMDReader& tmd)
|
||||
return fs->Rename(PID_KERNEL, PID_KERNEL, tmd_path, dest) == FS::ResultCode::Success;
|
||||
}
|
||||
|
||||
void ESDevice::FinishStaleImport(u64 title_id)
|
||||
void ESCore::FinishStaleImport(u64 title_id)
|
||||
{
|
||||
const auto fs = m_ios.GetFS();
|
||||
const auto import_tmd = FindImportTMD(title_id);
|
||||
@@ -385,15 +385,15 @@ void ESDevice::FinishStaleImport(u64 title_id)
|
||||
}
|
||||
}
|
||||
|
||||
void ESDevice::FinishAllStaleImports()
|
||||
void ESCore::FinishAllStaleImports()
|
||||
{
|
||||
const std::vector<u64> titles = GetTitleImports();
|
||||
for (const u64& title_id : titles)
|
||||
FinishStaleImport(title_id);
|
||||
}
|
||||
|
||||
std::string ESDevice::GetContentPath(const u64 title_id, const ES::Content& content,
|
||||
Ticks ticks) const
|
||||
std::string ESCore::GetContentPath(const u64 title_id, const ES::Content& content,
|
||||
Ticks ticks) const
|
||||
{
|
||||
if (content.IsShared())
|
||||
{
|
||||
@@ -406,7 +406,7 @@ std::string ESDevice::GetContentPath(const u64 title_id, const ES::Content& cont
|
||||
|
||||
s32 ESDevice::WriteSystemFile(const std::string& path, const std::vector<u8>& data, Ticks ticks)
|
||||
{
|
||||
auto& fs = *m_ios.GetFSDevice();
|
||||
auto& fs = *GetEmulationKernel().GetFSDevice();
|
||||
const std::string tmp_path = "/tmp/" + PathToFileName(path);
|
||||
|
||||
auto result = fs.CreateFile(PID_KERNEL, PID_KERNEL, tmp_path, {},
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
namespace IOS::HLE
|
||||
{
|
||||
s32 ESDevice::OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid, Ticks ticks)
|
||||
s32 ESCore::OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid, Ticks ticks)
|
||||
{
|
||||
const u64 title_id = tmd.GetTitleId();
|
||||
|
||||
@@ -57,17 +57,17 @@ IPCReply ESDevice::OpenContent(u32 uid, const IOCtlVRequest& request)
|
||||
return ES_EINVAL;
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
const u32 content_index = memory.Read_U32(request.in_vectors[2].address);
|
||||
// TODO: check the ticket view, check permissions.
|
||||
|
||||
const auto tmd = FindInstalledTMD(title_id, ticks);
|
||||
const auto tmd = m_core.FindInstalledTMD(title_id, ticks);
|
||||
if (!tmd.IsValid())
|
||||
return FS_ENOENT;
|
||||
|
||||
return OpenContent(tmd, content_index, uid, ticks);
|
||||
return m_core.OpenContent(tmd, content_index, uid, ticks);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -77,24 +77,24 @@ IPCReply ESDevice::OpenActiveTitleContent(u32 caller_uid, const IOCtlVRequest& r
|
||||
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u32))
|
||||
return ES_EINVAL;
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u32 content_index = memory.Read_U32(request.in_vectors[0].address);
|
||||
|
||||
if (!m_title_context.active)
|
||||
if (!m_core.m_title_context.active)
|
||||
return ES_EINVAL;
|
||||
|
||||
ES::UIDSys uid_map{m_ios.GetFSDevice()};
|
||||
const u32 uid = uid_map.GetOrInsertUIDForTitle(m_title_context.tmd.GetTitleId());
|
||||
ES::UIDSys uid_map{GetEmulationKernel().GetFSDevice()};
|
||||
const u32 uid = uid_map.GetOrInsertUIDForTitle(m_core.m_title_context.tmd.GetTitleId());
|
||||
ticks.Add(uid_map.GetTicks());
|
||||
if (caller_uid != 0 && caller_uid != uid)
|
||||
return ES_EACCES;
|
||||
|
||||
return OpenContent(m_title_context.tmd, content_index, caller_uid, ticks);
|
||||
return m_core.OpenContent(m_core.m_title_context.tmd, content_index, caller_uid, ticks);
|
||||
});
|
||||
}
|
||||
|
||||
s32 ESDevice::ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid, Ticks ticks)
|
||||
s32 ESCore::ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid, Ticks ticks)
|
||||
{
|
||||
if (cfd >= m_content_table.size())
|
||||
return ES_EINVAL;
|
||||
@@ -114,7 +114,7 @@ IPCReply ESDevice::ReadContent(u32 uid, const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != sizeof(u32))
|
||||
return ES_EINVAL;
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u32 cfd = memory.Read_U32(request.in_vectors[0].address);
|
||||
const u32 size = request.io_vectors[0].size;
|
||||
@@ -122,11 +122,11 @@ IPCReply ESDevice::ReadContent(u32 uid, const IOCtlVRequest& request)
|
||||
|
||||
INFO_LOG_FMT(IOS_ES, "ReadContent(uid={:#x}, cfd={}, size={}, addr={:08x})", uid, cfd, size,
|
||||
addr);
|
||||
return ReadContent(cfd, memory.GetPointer(addr), size, uid, ticks);
|
||||
return m_core.ReadContent(cfd, memory.GetPointer(addr), size, uid, ticks);
|
||||
});
|
||||
}
|
||||
|
||||
s32 ESDevice::CloseContent(u32 cfd, u32 uid, Ticks ticks)
|
||||
s32 ESCore::CloseContent(u32 cfd, u32 uid, Ticks ticks)
|
||||
{
|
||||
if (cfd >= m_content_table.size())
|
||||
return ES_EINVAL;
|
||||
@@ -149,14 +149,14 @@ IPCReply ESDevice::CloseContent(u32 uid, const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u32))
|
||||
return ES_EINVAL;
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u32 cfd = memory.Read_U32(request.in_vectors[0].address);
|
||||
return CloseContent(cfd, uid, ticks);
|
||||
return m_core.CloseContent(cfd, uid, ticks);
|
||||
});
|
||||
}
|
||||
|
||||
s32 ESDevice::SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid, Ticks ticks)
|
||||
s32 ESCore::SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid, Ticks ticks)
|
||||
{
|
||||
if (cfd >= m_content_table.size())
|
||||
return ES_EINVAL;
|
||||
@@ -176,13 +176,13 @@ IPCReply ESDevice::SeekContent(u32 uid, const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(3, 0))
|
||||
return ES_EINVAL;
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u32 cfd = memory.Read_U32(request.in_vectors[0].address);
|
||||
const u32 offset = memory.Read_U32(request.in_vectors[1].address);
|
||||
const auto mode = static_cast<SeekMode>(memory.Read_U32(request.in_vectors[2].address));
|
||||
|
||||
return SeekContent(cfd, offset, mode, uid, ticks);
|
||||
return m_core.SeekContent(cfd, offset, mode, uid, ticks);
|
||||
});
|
||||
}
|
||||
} // namespace IOS::HLE
|
||||
|
||||
@@ -21,8 +21,8 @@ IPCReply ESDevice::GetStoredContentsCount(const ES::TMDReader& tmd, const IOCtlV
|
||||
if (request.io_vectors[0].size != sizeof(u32) || !tmd.IsValid())
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
const u16 num_contents = static_cast<u16>(GetStoredContentsFromTMD(tmd).size());
|
||||
auto& system = Core::System::GetInstance();
|
||||
const u16 num_contents = static_cast<u16>(m_core.GetStoredContentsFromTMD(tmd).size());
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(num_contents, request.io_vectors[0].address);
|
||||
|
||||
@@ -38,7 +38,7 @@ IPCReply ESDevice::GetStoredContents(const ES::TMDReader& tmd, const IOCtlVReque
|
||||
if (!tmd.IsValid())
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
if (request.in_vectors[1].size != sizeof(u32) ||
|
||||
request.io_vectors[0].size != memory.Read_U32(request.in_vectors[1].address) * sizeof(u32))
|
||||
@@ -46,7 +46,7 @@ IPCReply ESDevice::GetStoredContents(const ES::TMDReader& tmd, const IOCtlVReque
|
||||
return IPCReply(ES_EINVAL);
|
||||
}
|
||||
|
||||
const auto contents = GetStoredContentsFromTMD(tmd);
|
||||
const auto contents = m_core.GetStoredContentsFromTMD(tmd);
|
||||
const u32 max_content_count = memory.Read_U32(request.in_vectors[1].address);
|
||||
for (u32 i = 0; i < std::min(static_cast<u32>(contents.size()), max_content_count); ++i)
|
||||
memory.Write_U32(contents[i].id, request.io_vectors[0].address + i * sizeof(u32));
|
||||
@@ -59,10 +59,10 @@ IPCReply ESDevice::GetStoredContentsCount(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != sizeof(u64))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
const ES::TMDReader tmd = FindInstalledTMD(title_id);
|
||||
const ES::TMDReader tmd = m_core.FindInstalledTMD(title_id);
|
||||
if (!tmd.IsValid())
|
||||
return IPCReply(FS_ENOENT);
|
||||
return GetStoredContentsCount(tmd, request);
|
||||
@@ -73,10 +73,10 @@ IPCReply ESDevice::GetStoredContents(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(2, 1) || request.in_vectors[0].size != sizeof(u64))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
const ES::TMDReader tmd = FindInstalledTMD(title_id);
|
||||
const ES::TMDReader tmd = m_core.FindInstalledTMD(title_id);
|
||||
if (!tmd.IsValid())
|
||||
return IPCReply(FS_ENOENT);
|
||||
return GetStoredContents(tmd, request);
|
||||
@@ -88,7 +88,7 @@ IPCReply ESDevice::GetTMDStoredContentsCount(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
std::vector<u8> tmd_bytes(request.in_vectors[0].size);
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());
|
||||
return GetStoredContentsCount(ES::TMDReader{std::move(tmd_bytes)}, request);
|
||||
@@ -100,7 +100,7 @@ IPCReply ESDevice::GetTMDStoredContents(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
std::vector<u8> tmd_bytes(request.in_vectors[0].size);
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.CopyFromEmu(tmd_bytes.data(), request.in_vectors[0].address, tmd_bytes.size());
|
||||
|
||||
@@ -109,11 +109,12 @@ IPCReply ESDevice::GetTMDStoredContents(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
std::vector<u8> cert_store;
|
||||
ReturnCode ret = ReadCertStore(&cert_store);
|
||||
ReturnCode ret = m_core.ReadCertStore(&cert_store);
|
||||
if (ret != IPC_SUCCESS)
|
||||
return IPCReply(ret);
|
||||
|
||||
ret = VerifyContainer(VerifyContainerType::TMD, VerifyMode::UpdateCertStore, tmd, cert_store);
|
||||
ret = m_core.VerifyContainer(ESCore::VerifyContainerType::TMD,
|
||||
ESCore::VerifyMode::UpdateCertStore, tmd, cert_store);
|
||||
if (ret != IPC_SUCCESS)
|
||||
return IPCReply(ret);
|
||||
|
||||
@@ -125,7 +126,7 @@ IPCReply ESDevice::GetTitleCount(const std::vector<u64>& titles, const IOCtlVReq
|
||||
if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != 4)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(static_cast<u32>(titles.size()), request.io_vectors[0].address);
|
||||
|
||||
@@ -137,7 +138,7 @@ IPCReply ESDevice::GetTitles(const std::vector<u64>& titles, const IOCtlVRequest
|
||||
if (!request.HasNumberOfValidVectors(1, 1))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const size_t max_count = memory.Read_U32(request.in_vectors[0].address);
|
||||
for (size_t i = 0; i < std::min(max_count, titles.size()); i++)
|
||||
@@ -150,14 +151,14 @@ IPCReply ESDevice::GetTitles(const std::vector<u64>& titles, const IOCtlVRequest
|
||||
|
||||
IPCReply ESDevice::GetTitleCount(const IOCtlVRequest& request)
|
||||
{
|
||||
const std::vector<u64> titles = GetInstalledTitles();
|
||||
const std::vector<u64> titles = m_core.GetInstalledTitles();
|
||||
INFO_LOG_FMT(IOS_ES, "GetTitleCount: {} titles", titles.size());
|
||||
return GetTitleCount(titles, request);
|
||||
}
|
||||
|
||||
IPCReply ESDevice::GetTitles(const IOCtlVRequest& request)
|
||||
{
|
||||
return GetTitles(GetInstalledTitles(), request);
|
||||
return GetTitles(m_core.GetInstalledTitles(), request);
|
||||
}
|
||||
|
||||
IPCReply ESDevice::GetStoredTMDSize(const IOCtlVRequest& request)
|
||||
@@ -165,10 +166,10 @@ IPCReply ESDevice::GetStoredTMDSize(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 1))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
const ES::TMDReader tmd = FindInstalledTMD(title_id);
|
||||
const ES::TMDReader tmd = m_core.FindInstalledTMD(title_id);
|
||||
if (!tmd.IsValid())
|
||||
return IPCReply(FS_ENOENT);
|
||||
|
||||
@@ -185,10 +186,10 @@ IPCReply ESDevice::GetStoredTMD(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(2, 1))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
const ES::TMDReader tmd = FindInstalledTMD(title_id);
|
||||
const ES::TMDReader tmd = m_core.FindInstalledTMD(title_id);
|
||||
if (!tmd.IsValid())
|
||||
return IPCReply(FS_ENOENT);
|
||||
|
||||
@@ -207,14 +208,14 @@ IPCReply ESDevice::GetStoredTMD(const IOCtlVRequest& request)
|
||||
|
||||
IPCReply ESDevice::GetOwnedTitleCount(const IOCtlVRequest& request)
|
||||
{
|
||||
const std::vector<u64> titles = GetTitlesWithTickets();
|
||||
const std::vector<u64> titles = m_core.GetTitlesWithTickets();
|
||||
INFO_LOG_FMT(IOS_ES, "GetOwnedTitleCount: {} titles", titles.size());
|
||||
return GetTitleCount(titles, request);
|
||||
}
|
||||
|
||||
IPCReply ESDevice::GetOwnedTitles(const IOCtlVRequest& request)
|
||||
{
|
||||
return GetTitles(GetTitlesWithTickets(), request);
|
||||
return GetTitles(m_core.GetTitlesWithTickets(), request);
|
||||
}
|
||||
|
||||
IPCReply ESDevice::GetBoot2Version(const IOCtlVRequest& request)
|
||||
@@ -225,7 +226,7 @@ IPCReply ESDevice::GetBoot2Version(const IOCtlVRequest& request)
|
||||
INFO_LOG_FMT(IOS_ES, "IOCTL_ES_GETBOOT2VERSION");
|
||||
|
||||
// as of 26/02/2012, this was latest bootmii version
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(4, request.io_vectors[0].address);
|
||||
return IPCReply(IPC_SUCCESS);
|
||||
@@ -236,8 +237,8 @@ IPCReply ESDevice::GetSharedContentsCount(const IOCtlVRequest& request) const
|
||||
if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != sizeof(u32))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
const u32 count = GetSharedContentsCount();
|
||||
auto& system = Core::System::GetInstance();
|
||||
const u32 count = m_core.GetSharedContentsCount();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(count, request.io_vectors[0].address);
|
||||
|
||||
@@ -250,13 +251,13 @@ IPCReply ESDevice::GetSharedContents(const IOCtlVRequest& request) const
|
||||
if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != sizeof(u32))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const u32 max_count = memory.Read_U32(request.in_vectors[0].address);
|
||||
if (request.io_vectors[0].size != 20 * max_count)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
const std::vector<std::array<u8, 20>> hashes = GetSharedContents();
|
||||
const std::vector<std::array<u8, 20>> hashes = m_core.GetSharedContents();
|
||||
const u32 count = std::min(static_cast<u32>(hashes.size()), max_count);
|
||||
memory.CopyToEmu(request.io_vectors[0].address, hashes.data(), 20 * count);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ static ReturnCode WriteTicket(FS::FileSystem* fs, const ES::TicketReader& ticket
|
||||
return file->Write(raw_ticket.data(), raw_ticket.size()) ? IPC_SUCCESS : ES_EIO;
|
||||
}
|
||||
|
||||
void ESDevice::TitleImportExportContext::DoState(PointerWrap& p)
|
||||
void ESCore::TitleImportExportContext::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(valid);
|
||||
p.Do(key_handle);
|
||||
@@ -50,9 +50,9 @@ void ESDevice::TitleImportExportContext::DoState(PointerWrap& p)
|
||||
p.Do(content.buffer);
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ImportTicket(const std::vector<u8>& ticket_bytes,
|
||||
const std::vector<u8>& cert_chain, TicketImportType type,
|
||||
VerifySignature verify_signature)
|
||||
ReturnCode ESCore::ImportTicket(const std::vector<u8>& ticket_bytes,
|
||||
const std::vector<u8>& cert_chain, TicketImportType type,
|
||||
VerifySignature verify_signature)
|
||||
{
|
||||
ES::TicketReader ticket{ticket_bytes};
|
||||
if (!ticket.IsValid())
|
||||
@@ -98,14 +98,14 @@ IPCReply ESDevice::ImportTicket(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(3, 0))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
std::vector<u8> bytes(request.in_vectors[0].size);
|
||||
memory.CopyFromEmu(bytes.data(), request.in_vectors[0].address, request.in_vectors[0].size);
|
||||
std::vector<u8> cert_chain(request.in_vectors[1].size);
|
||||
memory.CopyFromEmu(cert_chain.data(), request.in_vectors[1].address, request.in_vectors[1].size);
|
||||
return IPCReply(ImportTicket(bytes, cert_chain));
|
||||
return IPCReply(m_core.ImportTicket(bytes, cert_chain));
|
||||
}
|
||||
|
||||
constexpr std::array<u8, 16> NULL_KEY{};
|
||||
@@ -132,15 +132,15 @@ static ReturnCode InitBackupKey(u64 tid, u32 title_flags, IOSC& iosc, IOSC::Hand
|
||||
return ret == IPC_SUCCESS ? iosc.ImportSecretKey(*key, NULL_KEY.data(), PID_ES) : ret;
|
||||
}
|
||||
|
||||
static void ResetTitleImportContext(ESDevice::Context* context, IOSC& iosc)
|
||||
static void ResetTitleImportContext(ESCore::Context* context, IOSC& iosc)
|
||||
{
|
||||
if (context->title_import_export.key_handle)
|
||||
iosc.DeleteObject(context->title_import_export.key_handle, PID_ES);
|
||||
context->title_import_export = {};
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ImportTmd(Context& context, const std::vector<u8>& tmd_bytes,
|
||||
u64 caller_title_id, u32 caller_title_flags)
|
||||
ReturnCode ESCore::ImportTmd(Context& context, const std::vector<u8>& tmd_bytes,
|
||||
u64 caller_title_id, u32 caller_title_flags)
|
||||
{
|
||||
INFO_LOG_FMT(IOS_ES, "ImportTmd");
|
||||
|
||||
@@ -191,13 +191,13 @@ IPCReply ESDevice::ImportTmd(Context& context, const IOCtlVRequest& request)
|
||||
if (!ES::IsValidTMDSize(request.in_vectors[0].size))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
std::vector<u8> tmd(request.in_vectors[0].size);
|
||||
memory.CopyFromEmu(tmd.data(), request.in_vectors[0].address, request.in_vectors[0].size);
|
||||
return IPCReply(ImportTmd(context, tmd, m_title_context.tmd.GetTitleId(),
|
||||
m_title_context.tmd.GetTitleFlags()));
|
||||
return IPCReply(m_core.ImportTmd(context, tmd, m_core.m_title_context.tmd.GetTitleId(),
|
||||
m_core.m_title_context.tmd.GetTitleFlags()));
|
||||
}
|
||||
|
||||
static ReturnCode InitTitleImportKey(const std::vector<u8>& ticket_bytes, IOSC& iosc,
|
||||
@@ -217,9 +217,9 @@ static ReturnCode InitTitleImportKey(const std::vector<u8>& ticket_bytes, IOSC&
|
||||
&ticket_bytes[offsetof(ES::Ticket, title_key)], PID_ES);
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ImportTitleInit(Context& context, const std::vector<u8>& tmd_bytes,
|
||||
const std::vector<u8>& cert_chain,
|
||||
VerifySignature verify_signature)
|
||||
ReturnCode ESCore::ImportTitleInit(Context& context, const std::vector<u8>& tmd_bytes,
|
||||
const std::vector<u8>& cert_chain,
|
||||
VerifySignature verify_signature)
|
||||
{
|
||||
INFO_LOG_FMT(IOS_ES, "ImportTitleInit");
|
||||
ResetTitleImportContext(&context, m_ios.GetIOSC());
|
||||
@@ -280,17 +280,17 @@ IPCReply ESDevice::ImportTitleInit(Context& context, const IOCtlVRequest& reques
|
||||
if (!ES::IsValidTMDSize(request.in_vectors[0].size))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
std::vector<u8> tmd(request.in_vectors[0].size);
|
||||
memory.CopyFromEmu(tmd.data(), request.in_vectors[0].address, request.in_vectors[0].size);
|
||||
std::vector<u8> certs(request.in_vectors[1].size);
|
||||
memory.CopyFromEmu(certs.data(), request.in_vectors[1].address, request.in_vectors[1].size);
|
||||
return IPCReply(ImportTitleInit(context, tmd, certs));
|
||||
return IPCReply(m_core.ImportTitleInit(context, tmd, certs));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ImportContentBegin(Context& context, u64 title_id, u32 content_id)
|
||||
ReturnCode ESCore::ImportContentBegin(Context& context, u64 title_id, u32 content_id)
|
||||
{
|
||||
if (context.title_import_export.content.valid)
|
||||
{
|
||||
@@ -338,16 +338,16 @@ IPCReply ESDevice::ImportContentBegin(Context& context, const IOCtlVRequest& req
|
||||
if (!request.HasNumberOfValidVectors(2, 0))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
u32 content_id = memory.Read_U32(request.in_vectors[1].address);
|
||||
return IPCReply(ImportContentBegin(context, title_id, content_id));
|
||||
return IPCReply(m_core.ImportContentBegin(context, title_id, content_id));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ImportContentData(Context& context, u32 content_fd, const u8* data,
|
||||
u32 data_size)
|
||||
ReturnCode ESCore::ImportContentData(Context& context, u32 content_fd, const u8* data,
|
||||
u32 data_size)
|
||||
{
|
||||
INFO_LOG_FMT(IOS_ES, "ImportContentData: content fd {:08x}, size {}", content_fd, data_size);
|
||||
context.title_import_export.content.buffer.insert(
|
||||
@@ -360,12 +360,13 @@ IPCReply ESDevice::ImportContentData(Context& context, const IOCtlVRequest& requ
|
||||
if (!request.HasNumberOfValidVectors(2, 0))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
u32 content_fd = memory.Read_U32(request.in_vectors[0].address);
|
||||
u8* data_start = memory.GetPointer(request.in_vectors[1].address);
|
||||
return IPCReply(ImportContentData(context, content_fd, data_start, request.in_vectors[1].size));
|
||||
return IPCReply(
|
||||
m_core.ImportContentData(context, content_fd, data_start, request.in_vectors[1].size));
|
||||
}
|
||||
|
||||
static bool CheckIfContentHashMatches(const std::vector<u8>& content, const ES::Content& info)
|
||||
@@ -378,7 +379,7 @@ static std::string GetImportContentPath(u64 title_id, u32 content_id)
|
||||
return fmt::format("{}/content/{:08x}.app", Common::GetImportTitlePath(title_id), content_id);
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ImportContentEnd(Context& context, u32 content_fd)
|
||||
ReturnCode ESCore::ImportContentEnd(Context& context, u32 content_fd)
|
||||
{
|
||||
INFO_LOG_FMT(IOS_ES, "ImportContentEnd: content fd {:08x}", content_fd);
|
||||
|
||||
@@ -446,11 +447,11 @@ IPCReply ESDevice::ImportContentEnd(Context& context, const IOCtlVRequest& reque
|
||||
if (!request.HasNumberOfValidVectors(1, 0))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
u32 content_fd = memory.Read_U32(request.in_vectors[0].address);
|
||||
return IPCReply(ImportContentEnd(context, content_fd));
|
||||
return IPCReply(m_core.ImportContentEnd(context, content_fd));
|
||||
}
|
||||
|
||||
static bool HasAllRequiredContents(Kernel& ios, const ES::TMDReader& tmd)
|
||||
@@ -472,7 +473,7 @@ static bool HasAllRequiredContents(Kernel& ios, const ES::TMDReader& tmd)
|
||||
});
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ImportTitleDone(Context& context)
|
||||
ReturnCode ESCore::ImportTitleDone(Context& context)
|
||||
{
|
||||
if (!context.title_import_export.valid || context.title_import_export.content.valid)
|
||||
{
|
||||
@@ -512,10 +513,10 @@ IPCReply ESDevice::ImportTitleDone(Context& context, const IOCtlVRequest& reques
|
||||
if (!request.HasNumberOfValidVectors(0, 0))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
return IPCReply(ImportTitleDone(context));
|
||||
return IPCReply(m_core.ImportTitleDone(context));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ImportTitleCancel(Context& context)
|
||||
ReturnCode ESCore::ImportTitleCancel(Context& context)
|
||||
{
|
||||
// The TMD buffer can exist without a valid title import context.
|
||||
if (context.title_import_export.tmd.GetBytes().empty() ||
|
||||
@@ -538,7 +539,7 @@ IPCReply ESDevice::ImportTitleCancel(Context& context, const IOCtlVRequest& requ
|
||||
if (!request.HasNumberOfValidVectors(0, 0))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
return IPCReply(ImportTitleCancel(context));
|
||||
return IPCReply(m_core.ImportTitleCancel(context));
|
||||
}
|
||||
|
||||
static bool CanDeleteTitle(u64 title_id)
|
||||
@@ -547,7 +548,7 @@ static bool CanDeleteTitle(u64 title_id)
|
||||
return static_cast<u32>(title_id >> 32) != 0x00000001 || static_cast<u32>(title_id) > 0x101;
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::DeleteTitle(u64 title_id)
|
||||
ReturnCode ESCore::DeleteTitle(u64 title_id)
|
||||
{
|
||||
if (!CanDeleteTitle(title_id))
|
||||
return ES_EINVAL;
|
||||
@@ -561,14 +562,14 @@ IPCReply ESDevice::DeleteTitle(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != 8)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
return IPCReply(DeleteTitle(title_id));
|
||||
return IPCReply(m_core.DeleteTitle(title_id));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::DeleteTicket(const u8* ticket_view)
|
||||
ReturnCode ESCore::DeleteTicket(const u8* ticket_view)
|
||||
{
|
||||
const auto fs = m_ios.GetFS();
|
||||
const u64 title_id = Common::swap64(ticket_view + offsetof(ES::TicketView, title_id));
|
||||
@@ -622,12 +623,12 @@ IPCReply ESDevice::DeleteTicket(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
return IPCReply(DeleteTicket(memory.GetPointer(request.in_vectors[0].address)));
|
||||
return IPCReply(m_core.DeleteTicket(memory.GetPointer(request.in_vectors[0].address)));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::DeleteTitleContent(u64 title_id) const
|
||||
ReturnCode ESCore::DeleteTitleContent(u64 title_id) const
|
||||
{
|
||||
if (!CanDeleteTitle(title_id))
|
||||
return ES_EINVAL;
|
||||
@@ -651,12 +652,12 @@ IPCReply ESDevice::DeleteTitleContent(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u64))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
return IPCReply(DeleteTitleContent(memory.Read_U64(request.in_vectors[0].address)));
|
||||
return IPCReply(m_core.DeleteTitleContent(memory.Read_U64(request.in_vectors[0].address)));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::DeleteContent(u64 title_id, u32 content_id) const
|
||||
ReturnCode ESCore::DeleteContent(u64 title_id, u32 content_id) const
|
||||
{
|
||||
if (!CanDeleteTitle(title_id))
|
||||
return ES_EINVAL;
|
||||
@@ -682,14 +683,14 @@ IPCReply ESDevice::DeleteContent(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
return IPCReply(DeleteContent(memory.Read_U64(request.in_vectors[0].address),
|
||||
memory.Read_U32(request.in_vectors[1].address)));
|
||||
return IPCReply(m_core.DeleteContent(memory.Read_U64(request.in_vectors[0].address),
|
||||
memory.Read_U32(request.in_vectors[1].address)));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ExportTitleInit(Context& context, u64 title_id, u8* tmd_bytes, u32 tmd_size,
|
||||
u64 caller_title_id, u32 caller_title_flags)
|
||||
ReturnCode ESCore::ExportTitleInit(Context& context, u64 title_id, u8* tmd_bytes, u32 tmd_size,
|
||||
u64 caller_title_id, u32 caller_title_flags)
|
||||
{
|
||||
// No concurrent title import/export is allowed.
|
||||
if (context.title_import_export.valid)
|
||||
@@ -722,19 +723,19 @@ IPCReply ESDevice::ExportTitleInit(Context& context, const IOCtlVRequest& reques
|
||||
if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != 8)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
u8* tmd_bytes = memory.GetPointer(request.io_vectors[0].address);
|
||||
const u32 tmd_size = request.io_vectors[0].size;
|
||||
|
||||
return IPCReply(ExportTitleInit(context, title_id, tmd_bytes, tmd_size,
|
||||
m_title_context.tmd.GetTitleId(),
|
||||
m_title_context.tmd.GetTitleFlags()));
|
||||
return IPCReply(m_core.ExportTitleInit(context, title_id, tmd_bytes, tmd_size,
|
||||
m_core.m_title_context.tmd.GetTitleId(),
|
||||
m_core.m_title_context.tmd.GetTitleFlags()));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ExportContentBegin(Context& context, u64 title_id, u32 content_id)
|
||||
ReturnCode ESCore::ExportContentBegin(Context& context, u64 title_id, u32 content_id)
|
||||
{
|
||||
context.title_import_export.content = {};
|
||||
if (!context.title_import_export.valid ||
|
||||
@@ -771,16 +772,16 @@ IPCReply ESDevice::ExportContentBegin(Context& context, const IOCtlVRequest& req
|
||||
request.in_vectors[1].size != 4)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
const u32 content_id = memory.Read_U32(request.in_vectors[1].address);
|
||||
|
||||
return IPCReply(ExportContentBegin(context, title_id, content_id));
|
||||
return IPCReply(m_core.ExportContentBegin(context, title_id, content_id));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ExportContentData(Context& context, u32 content_fd, u8* data, u32 data_size)
|
||||
ReturnCode ESCore::ExportContentData(Context& context, u32 content_fd, u8* data, u32 data_size)
|
||||
{
|
||||
if (!context.title_import_export.valid || !context.title_import_export.content.valid || !data ||
|
||||
data_size == 0)
|
||||
@@ -822,17 +823,17 @@ IPCReply ESDevice::ExportContentData(Context& context, const IOCtlVRequest& requ
|
||||
return IPCReply(ES_EINVAL);
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u32 content_fd = memory.Read_U32(request.in_vectors[0].address);
|
||||
u8* data = memory.GetPointer(request.io_vectors[0].address);
|
||||
const u32 bytes_to_read = request.io_vectors[0].size;
|
||||
|
||||
return IPCReply(ExportContentData(context, content_fd, data, bytes_to_read));
|
||||
return IPCReply(m_core.ExportContentData(context, content_fd, data, bytes_to_read));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ExportContentEnd(Context& context, u32 content_fd)
|
||||
ReturnCode ESCore::ExportContentEnd(Context& context, u32 content_fd)
|
||||
{
|
||||
if (!context.title_import_export.valid || !context.title_import_export.content.valid)
|
||||
return ES_EINVAL;
|
||||
@@ -844,14 +845,14 @@ IPCReply ESDevice::ExportContentEnd(Context& context, const IOCtlVRequest& reque
|
||||
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != 4)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u32 content_fd = memory.Read_U32(request.in_vectors[0].address);
|
||||
return IPCReply(ExportContentEnd(context, content_fd));
|
||||
return IPCReply(m_core.ExportContentEnd(context, content_fd));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::ExportTitleDone(Context& context)
|
||||
ReturnCode ESCore::ExportTitleDone(Context& context)
|
||||
{
|
||||
ResetTitleImportContext(&context, m_ios.GetIOSC());
|
||||
return IPC_SUCCESS;
|
||||
@@ -859,10 +860,10 @@ ReturnCode ESDevice::ExportTitleDone(Context& context)
|
||||
|
||||
IPCReply ESDevice::ExportTitleDone(Context& context, const IOCtlVRequest& request)
|
||||
{
|
||||
return IPCReply(ExportTitleDone(context));
|
||||
return IPCReply(m_core.ExportTitleDone(context));
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::DeleteSharedContent(const std::array<u8, 20>& sha1) const
|
||||
ReturnCode ESCore::DeleteSharedContent(const std::array<u8, 20>& sha1) const
|
||||
{
|
||||
ES::SharedContentMap map{m_ios.GetFSDevice()};
|
||||
const auto content_path = map.GetFilenameFromSHA1(sha1);
|
||||
@@ -905,10 +906,10 @@ IPCReply ESDevice::DeleteSharedContent(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sha1.size())
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
memory.CopyFromEmu(sha1.data(), request.in_vectors[0].address, request.in_vectors[0].size);
|
||||
return IPCReply(DeleteSharedContent(sha1));
|
||||
return IPCReply(m_core.DeleteSharedContent(sha1));
|
||||
}
|
||||
} // namespace IOS::HLE
|
||||
|
||||
@@ -41,12 +41,12 @@ IPCReply ESDevice::GetTicketViewCount(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 1))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u64 TitleID = memory.Read_U64(request.in_vectors[0].address);
|
||||
|
||||
const ES::TicketReader ticket = FindSignedTicket(TitleID);
|
||||
const ES::TicketReader ticket = m_core.FindSignedTicket(TitleID);
|
||||
u32 view_count = ticket.IsValid() ? static_cast<u32>(ticket.GetNumberOfTickets()) : 0;
|
||||
|
||||
if (!IsEmulated(TitleID))
|
||||
@@ -54,7 +54,7 @@ IPCReply ESDevice::GetTicketViewCount(const IOCtlVRequest& request)
|
||||
view_count = 0;
|
||||
ERROR_LOG_FMT(IOS_ES, "GetViewCount: Dolphin doesn't emulate IOS title {:016x}", TitleID);
|
||||
}
|
||||
else if (ShouldReturnFakeViewsForIOSes(TitleID, m_title_context))
|
||||
else if (ShouldReturnFakeViewsForIOSes(TitleID, m_core.m_title_context))
|
||||
{
|
||||
view_count = 1;
|
||||
WARN_LOG_FMT(IOS_ES, "GetViewCount: Faking IOS title {:016x} being present", TitleID);
|
||||
@@ -72,13 +72,13 @@ IPCReply ESDevice::GetTicketViews(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(2, 1))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u64 TitleID = memory.Read_U64(request.in_vectors[0].address);
|
||||
const u32 maxViews = memory.Read_U32(request.in_vectors[1].address);
|
||||
|
||||
const ES::TicketReader ticket = FindSignedTicket(TitleID);
|
||||
const ES::TicketReader ticket = m_core.FindSignedTicket(TitleID);
|
||||
|
||||
if (!IsEmulated(TitleID))
|
||||
{
|
||||
@@ -94,7 +94,7 @@ IPCReply ESDevice::GetTicketViews(const IOCtlVRequest& request)
|
||||
ticket_view.data(), ticket_view.size());
|
||||
}
|
||||
}
|
||||
else if (ShouldReturnFakeViewsForIOSes(TitleID, m_title_context))
|
||||
else if (ShouldReturnFakeViewsForIOSes(TitleID, m_core.m_title_context))
|
||||
{
|
||||
memory.Memset(request.io_vectors[0].address, 0, sizeof(ES::TicketView));
|
||||
WARN_LOG_FMT(IOS_ES, "GetViews: Faking IOS title {:016x} being present", TitleID);
|
||||
@@ -105,8 +105,8 @@ IPCReply ESDevice::GetTicketViews(const IOCtlVRequest& request)
|
||||
return IPCReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
ReturnCode ESDevice::GetTicketFromView(const u8* ticket_view, u8* ticket, u32* ticket_size,
|
||||
std::optional<u8> desired_version) const
|
||||
ReturnCode ESCore::GetTicketFromView(const u8* ticket_view, u8* ticket, u32* ticket_size,
|
||||
std::optional<u8> desired_version) const
|
||||
{
|
||||
const u64 title_id = Common::swap64(&ticket_view[offsetof(ES::TicketView, title_id)]);
|
||||
const u64 ticket_id = Common::swap64(&ticket_view[offsetof(ES::TicketView, ticket_id)]);
|
||||
@@ -160,10 +160,11 @@ IPCReply ESDevice::GetV0TicketFromView(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
return IPCReply(GetTicketFromView(memory.GetPointer(request.in_vectors[0].address),
|
||||
memory.GetPointer(request.io_vectors[0].address), nullptr, 0));
|
||||
return IPCReply(m_core.GetTicketFromView(memory.GetPointer(request.in_vectors[0].address),
|
||||
memory.GetPointer(request.io_vectors[0].address),
|
||||
nullptr, 0));
|
||||
}
|
||||
|
||||
IPCReply ESDevice::GetTicketSizeFromView(const IOCtlVRequest& request)
|
||||
@@ -176,10 +177,10 @@ IPCReply ESDevice::GetTicketSizeFromView(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
const ReturnCode ret = GetTicketFromView(memory.GetPointer(request.in_vectors[0].address),
|
||||
nullptr, &ticket_size, std::nullopt);
|
||||
const ReturnCode ret = m_core.GetTicketFromView(memory.GetPointer(request.in_vectors[0].address),
|
||||
nullptr, &ticket_size, std::nullopt);
|
||||
memory.Write_U32(ticket_size, request.io_vectors[0].address);
|
||||
return IPCReply(ret);
|
||||
}
|
||||
@@ -193,16 +194,16 @@ IPCReply ESDevice::GetTicketFromView(const IOCtlVRequest& request)
|
||||
return IPCReply(ES_EINVAL);
|
||||
}
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
u32 ticket_size = memory.Read_U32(request.in_vectors[1].address);
|
||||
if (ticket_size != request.io_vectors[0].size)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
return IPCReply(GetTicketFromView(memory.GetPointer(request.in_vectors[0].address),
|
||||
memory.GetPointer(request.io_vectors[0].address), &ticket_size,
|
||||
std::nullopt));
|
||||
return IPCReply(m_core.GetTicketFromView(memory.GetPointer(request.in_vectors[0].address),
|
||||
memory.GetPointer(request.io_vectors[0].address),
|
||||
&ticket_size, std::nullopt));
|
||||
}
|
||||
|
||||
IPCReply ESDevice::GetTMDViewSize(const IOCtlVRequest& request)
|
||||
@@ -210,11 +211,11 @@ IPCReply ESDevice::GetTMDViewSize(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 1))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u64 TitleID = memory.Read_U64(request.in_vectors[0].address);
|
||||
const ES::TMDReader tmd = FindInstalledTMD(TitleID);
|
||||
const ES::TMDReader tmd = m_core.FindInstalledTMD(TitleID);
|
||||
|
||||
if (!tmd.IsValid())
|
||||
return IPCReply(FS_ENOENT);
|
||||
@@ -228,7 +229,7 @@ IPCReply ESDevice::GetTMDViewSize(const IOCtlVRequest& request)
|
||||
|
||||
IPCReply ESDevice::GetTMDViews(const IOCtlVRequest& request)
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
if (!request.HasNumberOfValidVectors(2, 1) ||
|
||||
@@ -240,7 +241,7 @@ IPCReply ESDevice::GetTMDViews(const IOCtlVRequest& request)
|
||||
}
|
||||
|
||||
const u64 title_id = memory.Read_U64(request.in_vectors[0].address);
|
||||
const ES::TMDReader tmd = FindInstalledTMD(title_id);
|
||||
const ES::TMDReader tmd = m_core.FindInstalledTMD(title_id);
|
||||
|
||||
if (!tmd.IsValid())
|
||||
return IPCReply(FS_ENOENT);
|
||||
@@ -267,7 +268,7 @@ IPCReply ESDevice::DIGetTMDViewSize(const IOCtlVRequest& request)
|
||||
if (request.io_vectors[0].size != sizeof(u32))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const bool has_tmd = request.in_vectors[0].size != 0;
|
||||
@@ -289,10 +290,10 @@ IPCReply ESDevice::DIGetTMDViewSize(const IOCtlVRequest& request)
|
||||
else
|
||||
{
|
||||
// If no TMD was passed in and no title is active, IOS returns -1017.
|
||||
if (!m_title_context.active)
|
||||
if (!m_core.m_title_context.active)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
tmd_view_size = m_title_context.tmd.GetRawView().size();
|
||||
tmd_view_size = m_core.m_title_context.tmd.GetRawView().size();
|
||||
}
|
||||
|
||||
memory.Write_U32(static_cast<u32>(tmd_view_size), request.io_vectors[0].address);
|
||||
@@ -308,7 +309,7 @@ IPCReply ESDevice::DIGetTMDView(const IOCtlVRequest& request)
|
||||
if (request.in_vectors[0].size >= 4 * 1024 * 1024)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
// Check whether the TMD view size is consistent.
|
||||
@@ -335,10 +336,10 @@ IPCReply ESDevice::DIGetTMDView(const IOCtlVRequest& request)
|
||||
else
|
||||
{
|
||||
// If no TMD was passed in and no title is active, IOS returns -1017.
|
||||
if (!m_title_context.active)
|
||||
if (!m_core.m_title_context.active)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
tmd_view = m_title_context.tmd.GetRawView();
|
||||
tmd_view = m_core.m_title_context.tmd.GetRawView();
|
||||
}
|
||||
|
||||
if (tmd_view.size() > request.io_vectors[0].size)
|
||||
@@ -362,7 +363,7 @@ IPCReply ESDevice::DIGetTicketView(const IOCtlVRequest& request)
|
||||
if (!has_ticket_vector && request.in_vectors[0].size != 0)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
std::vector<u8> view;
|
||||
@@ -371,10 +372,10 @@ IPCReply ESDevice::DIGetTicketView(const IOCtlVRequest& request)
|
||||
// Of course, this returns -1017 if no title is active and no ticket is passed.
|
||||
if (!has_ticket_vector)
|
||||
{
|
||||
if (!m_title_context.active)
|
||||
if (!m_core.m_title_context.active)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
view = m_title_context.ticket.GetRawTicketView(0);
|
||||
view = m_core.m_title_context.ticket.GetRawTicketView(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -394,12 +395,12 @@ IPCReply ESDevice::DIGetTMDSize(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != sizeof(u32))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
if (!m_title_context.active)
|
||||
if (!m_core.m_title_context.active)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(static_cast<u32>(m_title_context.tmd.GetBytes().size()),
|
||||
memory.Write_U32(static_cast<u32>(m_core.m_title_context.tmd.GetBytes().size()),
|
||||
request.io_vectors[0].address);
|
||||
return IPCReply(IPC_SUCCESS);
|
||||
}
|
||||
@@ -409,17 +410,17 @@ IPCReply ESDevice::DIGetTMD(const IOCtlVRequest& request)
|
||||
if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != sizeof(u32))
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
|
||||
const u32 tmd_size = memory.Read_U32(request.in_vectors[0].address);
|
||||
if (tmd_size != request.io_vectors[0].size)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
if (!m_title_context.active)
|
||||
if (!m_core.m_title_context.active)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
const std::vector<u8>& tmd_bytes = m_title_context.tmd.GetBytes();
|
||||
const std::vector<u8>& tmd_bytes = m_core.m_title_context.tmd.GetBytes();
|
||||
|
||||
if (static_cast<u32>(tmd_bytes.size()) > tmd_size)
|
||||
return IPCReply(ES_EINVAL);
|
||||
|
||||
@@ -300,7 +300,11 @@ Kernel::Kernel(IOSC::ConsoleType console_type) : m_iosc(console_type)
|
||||
if (m_is_responsible_for_nand_root)
|
||||
Core::InitializeWiiRoot(false);
|
||||
|
||||
AddCoreDevices();
|
||||
m_fs = FS::MakeFileSystem(IOS::HLE::FS::Location::Session, Core::GetActiveNandRedirects());
|
||||
ASSERT(m_fs);
|
||||
|
||||
AddDevice(std::make_unique<FSDevice>(*this, "/dev/fs"));
|
||||
m_es_core = std::make_unique<ESCore>(*this);
|
||||
}
|
||||
|
||||
Kernel::~Kernel()
|
||||
@@ -333,7 +337,13 @@ EmulationKernel::EmulationKernel(Core::System& system, u64 title_id)
|
||||
return;
|
||||
}
|
||||
|
||||
AddCoreDevices();
|
||||
m_fs = FS::MakeFileSystem(IOS::HLE::FS::Location::Session, Core::GetActiveNandRedirects());
|
||||
ASSERT(m_fs);
|
||||
|
||||
AddDevice(std::make_unique<FSDevice>(*this, "/dev/fs"));
|
||||
m_es_core = std::make_unique<ESCore>(*this);
|
||||
AddDevice(std::make_unique<ESDevice>(*this, *m_es_core, "/dev/es"));
|
||||
|
||||
AddStaticDevices();
|
||||
}
|
||||
|
||||
@@ -360,7 +370,12 @@ std::shared_ptr<FSDevice> Kernel::GetFSDevice()
|
||||
return std::static_pointer_cast<FSDevice>(m_device_map.at("/dev/fs"));
|
||||
}
|
||||
|
||||
std::shared_ptr<ESDevice> Kernel::GetES()
|
||||
ESCore& Kernel::GetESCore()
|
||||
{
|
||||
return *m_es_core;
|
||||
}
|
||||
|
||||
std::shared_ptr<ESDevice> EmulationKernel::GetESDevice()
|
||||
{
|
||||
return std::static_pointer_cast<ESDevice>(m_device_map.at("/dev/es"));
|
||||
}
|
||||
@@ -537,16 +552,6 @@ void Kernel::AddDevice(std::unique_ptr<Device> device)
|
||||
m_device_map.insert_or_assign(device->GetDeviceName(), std::move(device));
|
||||
}
|
||||
|
||||
void Kernel::AddCoreDevices()
|
||||
{
|
||||
m_fs = FS::MakeFileSystem(IOS::HLE::FS::Location::Session, Core::GetActiveNandRedirects());
|
||||
ASSERT(m_fs);
|
||||
|
||||
std::lock_guard lock(m_device_map_mutex);
|
||||
AddDevice(std::make_unique<FSDevice>(*this, "/dev/fs"));
|
||||
AddDevice(std::make_unique<ESDevice>(*this, "/dev/es"));
|
||||
}
|
||||
|
||||
void EmulationKernel::AddStaticDevices()
|
||||
{
|
||||
std::lock_guard lock(m_device_map_mutex);
|
||||
|
||||
@@ -33,6 +33,7 @@ class FileSystem;
|
||||
}
|
||||
|
||||
class Device;
|
||||
class ESCore;
|
||||
class ESDevice;
|
||||
class FSDevice;
|
||||
class WiiSockMan;
|
||||
@@ -123,7 +124,7 @@ public:
|
||||
// They are also the only available resource managers even before loading any module.
|
||||
std::shared_ptr<FS::FileSystem> GetFS();
|
||||
std::shared_ptr<FSDevice> GetFSDevice();
|
||||
std::shared_ptr<ESDevice> GetES();
|
||||
ESCore& GetESCore();
|
||||
|
||||
void SetUidForPPC(u32 uid);
|
||||
u32 GetUidForPPC() const;
|
||||
@@ -142,9 +143,10 @@ protected:
|
||||
explicit Kernel(u64 title_id);
|
||||
|
||||
void AddDevice(std::unique_ptr<Device> device);
|
||||
void AddCoreDevices();
|
||||
std::shared_ptr<Device> GetDeviceByName(std::string_view device_name);
|
||||
|
||||
std::unique_ptr<ESCore> m_es_core;
|
||||
|
||||
bool m_is_responsible_for_nand_root = false;
|
||||
u64 m_title_id = 0;
|
||||
static constexpr u8 IPC_MAX_FDS = 0x18;
|
||||
@@ -178,6 +180,8 @@ public:
|
||||
// This only works for devices which are part of the device map.
|
||||
std::shared_ptr<Device> GetDeviceByName(std::string_view device_name);
|
||||
|
||||
std::shared_ptr<ESDevice> GetESDevice();
|
||||
|
||||
void DoState(PointerWrap& p);
|
||||
void UpdateDevices();
|
||||
void UpdateWantDeterminism(bool new_want_determinism);
|
||||
|
||||
@@ -165,7 +165,8 @@ std::optional<IPCReply> WFSIDevice::IOCtl(const IOCtlRequest& request)
|
||||
memory.CopyFromEmu(tmd_bytes.data(), tmd_addr, tmd_size);
|
||||
m_tmd.SetBytes(std::move(tmd_bytes));
|
||||
|
||||
const ES::TicketReader ticket = m_ios.GetES()->FindSignedTicket(m_tmd.GetTitleId());
|
||||
const ES::TicketReader ticket =
|
||||
GetEmulationKernel().GetESCore().FindSignedTicket(m_tmd.GetTitleId());
|
||||
if (!ticket.IsValid())
|
||||
{
|
||||
return_error_code = -11028;
|
||||
@@ -385,14 +386,14 @@ std::optional<IPCReply> WFSIDevice::IOCtl(const IOCtlRequest& request)
|
||||
{
|
||||
INFO_LOG_FMT(IOS_WFS, "IOCTL_WFSI_INIT");
|
||||
u64 tid;
|
||||
if (GetEmulationKernel().GetES()->GetTitleId(&tid) < 0)
|
||||
if (GetEmulationKernel().GetESCore().GetTitleId(&tid) < 0)
|
||||
{
|
||||
ERROR_LOG_FMT(IOS_WFS, "IOCTL_WFSI_INIT: Could not get title id.");
|
||||
return_error_code = IPC_EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
const ES::TMDReader tmd = GetEmulationKernel().GetES()->FindInstalledTMD(tid);
|
||||
const ES::TMDReader tmd = GetEmulationKernel().GetESCore().FindInstalledTMD(tid);
|
||||
SetCurrentTitleIdAndGroupId(tmd.GetTitleId(), tmd.GetGroupId());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1720,7 +1720,7 @@ std::optional<SaveSyncInfo> NetPlayServer::CollectSaveSyncInfo()
|
||||
if (m_settings.savedata_sync_all_wii)
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
for (const u64 title : ios.GetES()->GetInstalledTitles())
|
||||
for (const u64 title : ios.GetESCore().GetInstalledTitles())
|
||||
{
|
||||
auto save = WiiSave::MakeNandStorage(sync_info.configured_fs.get(), title);
|
||||
if (save && save->ReadHeader().has_value() && save->ReadBkHeader().has_value() &&
|
||||
|
||||
@@ -416,7 +416,7 @@ void CleanUpWiiFileSystemContents(const BootSessionData& boot_session_data)
|
||||
// cleanup process.
|
||||
const bool copy_all = !netplay_settings || netplay_settings->savedata_sync_all_wii;
|
||||
for (const u64 title_id :
|
||||
(copy_all ? ios->GetES()->GetInstalledTitles() : boot_session_data.GetWiiSyncTitles()))
|
||||
(copy_all ? ios->GetESCore().GetInstalledTitles() : boot_session_data.GetWiiSyncTitles()))
|
||||
{
|
||||
INFO_LOG_FMT(CORE, "Wii FS Cleanup: Copying {0:016x}.", title_id);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user