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:
parent
361a8b2c8e
commit
6a339cbdb3
|
@ -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);
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
namespace WiiUtils
|
||||
{
|
||||
static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad,
|
||||
IOS::HLE::ESDevice::VerifySignature verify_signature)
|
||||
IOS::HLE::ESCore::VerifySignature verify_signature)
|
||||
{
|
||||
if (!wad.GetTicket().IsValid() || !wad.GetTMD().IsValid())
|
||||
{
|
||||
|
@ -58,20 +58,20 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad,
|
|||
}
|
||||
|
||||
const auto tmd = wad.GetTMD();
|
||||
const auto es = ios.GetES();
|
||||
auto& es = ios.GetESCore();
|
||||
const auto fs = ios.GetFS();
|
||||
|
||||
IOS::HLE::ESDevice::Context context;
|
||||
IOS::HLE::ESCore::Context context;
|
||||
IOS::HLE::ReturnCode ret;
|
||||
|
||||
// Ensure the common key index is correct, as it's checked by IOS.
|
||||
IOS::ES::TicketReader ticket = wad.GetTicketWithFixedCommonKey();
|
||||
|
||||
while ((ret = es->ImportTicket(ticket.GetBytes(), wad.GetCertificateChain(),
|
||||
IOS::HLE::ESDevice::TicketImportType::Unpersonalised,
|
||||
verify_signature)) < 0 ||
|
||||
(ret = es->ImportTitleInit(context, tmd.GetBytes(), wad.GetCertificateChain(),
|
||||
verify_signature)) < 0)
|
||||
while ((ret = es.ImportTicket(ticket.GetBytes(), wad.GetCertificateChain(),
|
||||
IOS::HLE::ESCore::TicketImportType::Unpersonalised,
|
||||
verify_signature)) < 0 ||
|
||||
(ret = es.ImportTitleInit(context, tmd.GetBytes(), wad.GetCertificateChain(),
|
||||
verify_signature)) < 0)
|
||||
{
|
||||
if (ret != IOS::HLE::IOSC_FAIL_CHECKVALUE)
|
||||
{
|
||||
|
@ -87,9 +87,9 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad,
|
|||
{
|
||||
const std::vector<u8> data = wad.GetContent(content.index);
|
||||
|
||||
if (es->ImportContentBegin(context, title_id, content.id) < 0 ||
|
||||
es->ImportContentData(context, 0, data.data(), static_cast<u32>(data.size())) < 0 ||
|
||||
es->ImportContentEnd(context, 0) < 0)
|
||||
if (es.ImportContentBegin(context, title_id, content.id) < 0 ||
|
||||
es.ImportContentData(context, 0, data.data(), static_cast<u32>(data.size())) < 0 ||
|
||||
es.ImportContentEnd(context, 0) < 0)
|
||||
{
|
||||
PanicAlertFmtT("WAD installation failed: Could not import content {0:08x}.", content.id);
|
||||
return false;
|
||||
|
@ -98,8 +98,8 @@ static bool ImportWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad,
|
|||
return true;
|
||||
}();
|
||||
|
||||
if ((contents_imported && es->ImportTitleDone(context) < 0) ||
|
||||
(!contents_imported && es->ImportTitleCancel(context) < 0))
|
||||
if ((contents_imported && es.ImportTitleDone(context) < 0) ||
|
||||
(!contents_imported && es.ImportTitleCancel(context) < 0))
|
||||
{
|
||||
PanicAlertFmtT("WAD installation failed: Could not finalise title import.");
|
||||
return false;
|
||||
|
@ -151,8 +151,8 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, InstallType
|
|||
const u64 title_id = wad.GetTMD().GetTitleId();
|
||||
|
||||
// Skip the install if the WAD is already installed.
|
||||
const auto installed_contents = ios.GetES()->GetStoredContentsFromTMD(
|
||||
wad.GetTMD(), IOS::HLE::ESDevice::CheckContentHashes::Yes);
|
||||
const auto installed_contents = ios.GetESCore().GetStoredContentsFromTMD(
|
||||
wad.GetTMD(), IOS::HLE::ESCore::CheckContentHashes::Yes);
|
||||
if (wad.GetTMD().GetContents() == installed_contents)
|
||||
{
|
||||
// Clear the "temporary title ID" flag in case the user tries to permanently install a title
|
||||
|
@ -164,7 +164,7 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, InstallType
|
|||
|
||||
// If a different version is currently installed, warn the user to make sure
|
||||
// they don't overwrite the current version by mistake.
|
||||
const IOS::ES::TMDReader installed_tmd = ios.GetES()->FindInstalledTMD(title_id);
|
||||
const IOS::ES::TMDReader installed_tmd = ios.GetESCore().FindInstalledTMD(title_id);
|
||||
const bool has_another_version =
|
||||
installed_tmd.IsValid() && installed_tmd.GetTitleVersion() != wad.GetTMD().GetTitleVersion();
|
||||
if (has_another_version &&
|
||||
|
@ -178,10 +178,10 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, InstallType
|
|||
|
||||
// Delete a previous temporary title, if it exists.
|
||||
if (previous_temporary_title_id)
|
||||
ios.GetES()->DeleteTitleContent(previous_temporary_title_id);
|
||||
ios.GetESCore().DeleteTitleContent(previous_temporary_title_id);
|
||||
|
||||
// A lot of people use fakesigned WADs, so disable signature checking when installing a WAD.
|
||||
if (!ImportWAD(ios, wad, IOS::HLE::ESDevice::VerifySignature::No))
|
||||
if (!ImportWAD(ios, wad, IOS::HLE::ESCore::VerifySignature::No))
|
||||
return false;
|
||||
|
||||
// Keep track of the title ID so this title can be removed to make room for any future install.
|
||||
|
@ -207,7 +207,7 @@ bool InstallWAD(const std::string& wad_path)
|
|||
bool UninstallTitle(u64 title_id)
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
return ios.GetES()->DeleteTitleContent(title_id) == IOS::HLE::IPC_SUCCESS;
|
||||
return ios.GetESCore().DeleteTitleContent(title_id) == IOS::HLE::IPC_SUCCESS;
|
||||
}
|
||||
|
||||
bool IsTitleInstalled(u64 title_id)
|
||||
|
@ -266,7 +266,7 @@ IOS::ES::TMDReader FindBackupTMD(IOS::HLE::FS::FileSystem& fs, u64 title_id)
|
|||
}
|
||||
}
|
||||
|
||||
bool EnsureTMDIsImported(IOS::HLE::FS::FileSystem& fs, IOS::HLE::ESDevice& es, u64 title_id)
|
||||
bool EnsureTMDIsImported(IOS::HLE::FS::FileSystem& fs, IOS::HLE::ESCore& es, u64 title_id)
|
||||
{
|
||||
if (IsTMDImported(fs, title_id))
|
||||
return true;
|
||||
|
@ -275,7 +275,7 @@ bool EnsureTMDIsImported(IOS::HLE::FS::FileSystem& fs, IOS::HLE::ESDevice& es, u
|
|||
if (!tmd.IsValid())
|
||||
return false;
|
||||
|
||||
IOS::HLE::ESDevice::Context context;
|
||||
IOS::HLE::ESCore::Context context;
|
||||
context.uid = IOS::SYSMENU_UID;
|
||||
context.gid = IOS::SYSMENU_GID;
|
||||
const auto import_result =
|
||||
|
@ -308,7 +308,7 @@ protected:
|
|||
std::string SystemUpdater::GetDeviceRegion()
|
||||
{
|
||||
// Try to determine the region from an installed system menu.
|
||||
const auto tmd = m_ios.GetES()->FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
const auto tmd = m_ios.GetESCore().FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
if (tmd.IsValid())
|
||||
{
|
||||
const DiscIO::Region region = tmd.GetRegion();
|
||||
|
@ -325,7 +325,7 @@ std::string SystemUpdater::GetDeviceRegion()
|
|||
std::string SystemUpdater::GetDeviceId()
|
||||
{
|
||||
u32 ios_device_id;
|
||||
if (m_ios.GetES()->GetDeviceId(&ios_device_id) < 0)
|
||||
if (m_ios.GetESCore().GetDeviceId(&ios_device_id) < 0)
|
||||
return "";
|
||||
return std::to_string((u64(1) << 32) | ios_device_id);
|
||||
}
|
||||
|
@ -417,10 +417,10 @@ OnlineSystemUpdater::ParseTitlesResponse(const std::vector<u8>& response) const
|
|||
|
||||
bool OnlineSystemUpdater::ShouldInstallTitle(const TitleInfo& title)
|
||||
{
|
||||
const auto es = m_ios.GetES();
|
||||
const auto installed_tmd = es->FindInstalledTMD(title.id);
|
||||
const auto& es = m_ios.GetESCore();
|
||||
const auto installed_tmd = es.FindInstalledTMD(title.id);
|
||||
return !(installed_tmd.IsValid() && installed_tmd.GetTitleVersion() >= title.version &&
|
||||
es->GetStoredContentsFromTMD(installed_tmd).size() == installed_tmd.GetNumContents());
|
||||
es.GetStoredContentsFromTMD(installed_tmd).size() == installed_tmd.GetNumContents());
|
||||
}
|
||||
|
||||
constexpr const char* GET_SYSTEM_TITLES_REQUEST_PAYLOAD = R"(<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
@ -545,8 +545,8 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
|
|||
|
||||
// Import the ticket.
|
||||
IOS::HLE::ReturnCode ret = IOS::HLE::IPC_SUCCESS;
|
||||
const auto es = m_ios.GetES();
|
||||
if ((ret = es->ImportTicket(ticket.first, ticket.second)) < 0)
|
||||
auto& es = m_ios.GetESCore();
|
||||
if ((ret = es.ImportTicket(ticket.first, ticket.second)) < 0)
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "Failed to import ticket: error {}", static_cast<u32>(ret));
|
||||
return UpdateResult::ImportFailed;
|
||||
|
@ -564,7 +564,7 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
|
|||
const u64 ios_id = tmd.first.GetIOSId();
|
||||
if (ios_id != 0 && IOS::ES::IsTitleType(ios_id, IOS::ES::TitleType::System))
|
||||
{
|
||||
if (!es->FindInstalledTMD(ios_id).IsValid())
|
||||
if (!es.FindInstalledTMD(ios_id).IsValid())
|
||||
{
|
||||
WARN_LOG_FMT(CORE, "Importing required system title {:016x} first", ios_id);
|
||||
const UpdateResult res = InstallTitleFromNUS(prefix_url, {ios_id, 0}, updated_titles);
|
||||
|
@ -577,15 +577,15 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
|
|||
}
|
||||
|
||||
// Initialise the title import.
|
||||
IOS::HLE::ESDevice::Context context;
|
||||
if ((ret = es->ImportTitleInit(context, tmd.first.GetBytes(), tmd.second)) < 0)
|
||||
IOS::HLE::ESCore::Context context;
|
||||
if ((ret = es.ImportTitleInit(context, tmd.first.GetBytes(), tmd.second)) < 0)
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "Failed to initialise title import: error {}", static_cast<u32>(ret));
|
||||
return UpdateResult::ImportFailed;
|
||||
}
|
||||
|
||||
// Now download and install contents listed in the TMD.
|
||||
const std::vector<IOS::ES::Content> stored_contents = es->GetStoredContentsFromTMD(tmd.first);
|
||||
const std::vector<IOS::ES::Content> stored_contents = es.GetStoredContentsFromTMD(tmd.first);
|
||||
const UpdateResult import_result = [&]() {
|
||||
for (const IOS::ES::Content& content : tmd.first.GetContents())
|
||||
{
|
||||
|
@ -598,7 +598,7 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
|
|||
if (is_already_installed)
|
||||
continue;
|
||||
|
||||
if ((ret = es->ImportContentBegin(context, title.id, content.id)) < 0)
|
||||
if ((ret = es.ImportContentBegin(context, title.id, content.id)) < 0)
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "Failed to initialise import for content {:08x}: error {}", content.id,
|
||||
static_cast<u32>(ret));
|
||||
|
@ -612,8 +612,8 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
|
|||
return UpdateResult::DownloadFailed;
|
||||
}
|
||||
|
||||
if (es->ImportContentData(context, 0, data->data(), static_cast<u32>(data->size())) < 0 ||
|
||||
es->ImportContentEnd(context, 0) < 0)
|
||||
if (es.ImportContentData(context, 0, data->data(), static_cast<u32>(data->size())) < 0 ||
|
||||
es.ImportContentEnd(context, 0) < 0)
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "Failed to import content {:08x}", content.id);
|
||||
return UpdateResult::ImportFailed;
|
||||
|
@ -623,8 +623,8 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
|
|||
}();
|
||||
const bool all_contents_imported = import_result == UpdateResult::Succeeded;
|
||||
|
||||
if ((all_contents_imported && (ret = es->ImportTitleDone(context)) < 0) ||
|
||||
(!all_contents_imported && (ret = es->ImportTitleCancel(context)) < 0))
|
||||
if ((all_contents_imported && (ret = es.ImportTitleDone(context)) < 0) ||
|
||||
(!all_contents_imported && (ret = es.ImportTitleCancel(context)) < 0))
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "Failed to finalise title import: error {}", static_cast<u32>(ret));
|
||||
return UpdateResult::ImportFailed;
|
||||
|
@ -742,7 +742,8 @@ UpdateResult DiscSystemUpdater::DoDiscUpdate()
|
|||
|
||||
// Do not allow mismatched regions, because installing an update will automatically change
|
||||
// the Wii's region and may result in semi/full system menu bricks.
|
||||
const IOS::ES::TMDReader system_menu_tmd = m_ios.GetES()->FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
const IOS::ES::TMDReader system_menu_tmd =
|
||||
m_ios.GetESCore().FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
if (system_menu_tmd.IsValid() && m_volume->GetRegion() != system_menu_tmd.GetRegion())
|
||||
return UpdateResult::RegionMismatch;
|
||||
|
||||
|
@ -826,8 +827,8 @@ UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs,
|
|||
if (type != 2 && type != 3 && type != 6 && type != 7)
|
||||
return UpdateResult::AlreadyUpToDate;
|
||||
|
||||
const IOS::ES::TMDReader tmd = m_ios.GetES()->FindInstalledTMD(title.id);
|
||||
const IOS::ES::TicketReader ticket = m_ios.GetES()->FindSignedTicket(title.id);
|
||||
const IOS::ES::TMDReader tmd = m_ios.GetESCore().FindInstalledTMD(title.id);
|
||||
const IOS::ES::TicketReader ticket = m_ios.GetESCore().FindSignedTicket(title.id);
|
||||
|
||||
// Optional titles can be skipped if the ticket is present, even when the title isn't installed.
|
||||
if (attrs.test(16) && ticket.IsValid())
|
||||
|
@ -846,7 +847,7 @@ UpdateResult DiscSystemUpdater::ProcessEntry(u32 type, std::bitset<32> attrs,
|
|||
return UpdateResult::DiscReadFailed;
|
||||
}
|
||||
const DiscIO::VolumeWAD wad{std::move(blob)};
|
||||
const bool success = ImportWAD(m_ios, wad, IOS::HLE::ESDevice::VerifySignature::Yes);
|
||||
const bool success = ImportWAD(m_ios, wad, IOS::HLE::ESCore::VerifySignature::Yes);
|
||||
return success ? UpdateResult::Succeeded : UpdateResult::ImportFailed;
|
||||
}
|
||||
|
||||
|
@ -865,7 +866,7 @@ UpdateResult DoDiscUpdate(UpdateCallback update_callback, const std::string& ima
|
|||
static NANDCheckResult CheckNAND(IOS::HLE::Kernel& ios, bool repair)
|
||||
{
|
||||
NANDCheckResult result;
|
||||
const auto es = ios.GetES();
|
||||
const auto& es = ios.GetESCore();
|
||||
|
||||
// Check for NANDs that were used with old Dolphin versions.
|
||||
const std::string sys_replace_path =
|
||||
|
@ -892,7 +893,7 @@ static NANDCheckResult CheckNAND(IOS::HLE::Kernel& ios, bool repair)
|
|||
result.bad = true;
|
||||
}
|
||||
|
||||
for (const u64 title_id : es->GetInstalledTitles())
|
||||
for (const u64 title_id : es.GetInstalledTitles())
|
||||
{
|
||||
const std::string title_dir = Common::GetTitlePath(title_id, Common::FROM_CONFIGURED_ROOT);
|
||||
const std::string content_dir = title_dir + "/content";
|
||||
|
@ -912,7 +913,7 @@ static NANDCheckResult CheckNAND(IOS::HLE::Kernel& ios, bool repair)
|
|||
}
|
||||
|
||||
// Check for incomplete title installs (missing ticket, TMD or contents).
|
||||
const auto ticket = es->FindSignedTicket(title_id);
|
||||
const auto ticket = es.FindSignedTicket(title_id);
|
||||
if (!IOS::ES::IsDiscTitle(title_id) && !ticket.IsValid())
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "CheckNAND: Missing ticket for title {:016x}", title_id);
|
||||
|
@ -923,7 +924,7 @@ static NANDCheckResult CheckNAND(IOS::HLE::Kernel& ios, bool repair)
|
|||
result.bad = true;
|
||||
}
|
||||
|
||||
const auto tmd = es->FindInstalledTMD(title_id);
|
||||
const auto tmd = es.FindInstalledTMD(title_id);
|
||||
if (!tmd.IsValid())
|
||||
{
|
||||
if (File::ScanDirectoryTree(content_dir, false).children.empty())
|
||||
|
@ -943,7 +944,7 @@ static NANDCheckResult CheckNAND(IOS::HLE::Kernel& ios, bool repair)
|
|||
continue;
|
||||
}
|
||||
|
||||
const auto installed_contents = es->GetStoredContentsFromTMD(tmd);
|
||||
const auto installed_contents = es.GetStoredContentsFromTMD(tmd);
|
||||
const bool is_installed = std::any_of(installed_contents.begin(), installed_contents.end(),
|
||||
[](const auto& content) { return !content.IsShared(); });
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ class VolumeWAD;
|
|||
namespace IOS::HLE
|
||||
{
|
||||
class BluetoothEmuDevice;
|
||||
class ESDevice;
|
||||
class ESCore;
|
||||
class Kernel;
|
||||
} // namespace IOS::HLE
|
||||
|
||||
|
@ -59,7 +59,7 @@ IOS::ES::TMDReader FindBackupTMD(IOS::HLE::FS::FileSystem& fs, u64 title_id);
|
|||
// Checks if there's a title.tmd imported for the given title ID. If there is not, we attempt to
|
||||
// re-import it from the TMDs stored in /title/00000001/00000002/data/tmds.sys.
|
||||
// Returns true if, after this function call, we have an imported title.tmd, or false if not.
|
||||
bool EnsureTMDIsImported(IOS::HLE::FS::FileSystem& fs, IOS::HLE::ESDevice& es, u64 title_id);
|
||||
bool EnsureTMDIsImported(IOS::HLE::FS::FileSystem& fs, IOS::HLE::ESCore& es, u64 title_id);
|
||||
|
||||
enum class UpdateResult
|
||||
{
|
||||
|
|
|
@ -578,17 +578,17 @@ bool VolumeVerifier::CheckPartition(const Partition& partition)
|
|||
const auto console_type =
|
||||
IsDebugSigned() ? IOS::HLE::IOSC::ConsoleType::RVT : IOS::HLE::IOSC::ConsoleType::Retail;
|
||||
IOS::HLE::Kernel ios(console_type);
|
||||
const auto es = ios.GetES();
|
||||
auto& es = ios.GetESCore();
|
||||
const std::vector<u8>& cert_chain = m_volume.GetCertificateChain(partition);
|
||||
|
||||
if (IOS::HLE::IPC_SUCCESS !=
|
||||
es->VerifyContainer(IOS::HLE::ESDevice::VerifyContainerType::Ticket,
|
||||
IOS::HLE::ESDevice::VerifyMode::DoNotUpdateCertStore,
|
||||
m_volume.GetTicket(partition), cert_chain) ||
|
||||
es.VerifyContainer(IOS::HLE::ESCore::VerifyContainerType::Ticket,
|
||||
IOS::HLE::ESCore::VerifyMode::DoNotUpdateCertStore,
|
||||
m_volume.GetTicket(partition), cert_chain) ||
|
||||
IOS::HLE::IPC_SUCCESS !=
|
||||
es->VerifyContainer(IOS::HLE::ESDevice::VerifyContainerType::TMD,
|
||||
IOS::HLE::ESDevice::VerifyMode::DoNotUpdateCertStore,
|
||||
m_volume.GetTMD(partition), cert_chain))
|
||||
es.VerifyContainer(IOS::HLE::ESCore::VerifyContainerType::TMD,
|
||||
IOS::HLE::ESCore::VerifyMode::DoNotUpdateCertStore,
|
||||
m_volume.GetTMD(partition), cert_chain))
|
||||
{
|
||||
AddProblem(Severity::Low,
|
||||
Common::FmtFormatT("The {0} partition is not correctly signed.", name));
|
||||
|
@ -982,21 +982,21 @@ void VolumeVerifier::CheckMisc()
|
|||
if (m_volume.GetVolumeType() == Platform::WiiWAD)
|
||||
{
|
||||
IOS::HLE::Kernel ios(m_ticket.GetConsoleType());
|
||||
const auto es = ios.GetES();
|
||||
auto& es = ios.GetESCore();
|
||||
const std::vector<u8>& cert_chain = m_volume.GetCertificateChain(PARTITION_NONE);
|
||||
|
||||
if (IOS::HLE::IPC_SUCCESS !=
|
||||
es->VerifyContainer(IOS::HLE::ESDevice::VerifyContainerType::Ticket,
|
||||
IOS::HLE::ESDevice::VerifyMode::DoNotUpdateCertStore, m_ticket,
|
||||
cert_chain))
|
||||
es.VerifyContainer(IOS::HLE::ESCore::VerifyContainerType::Ticket,
|
||||
IOS::HLE::ESCore::VerifyMode::DoNotUpdateCertStore, m_ticket,
|
||||
cert_chain))
|
||||
{
|
||||
// i18n: "Ticket" here is a kind of digital authorization to use a certain title (e.g. a game)
|
||||
AddProblem(Severity::Low, Common::GetStringT("The ticket is not correctly signed."));
|
||||
}
|
||||
|
||||
if (IOS::HLE::IPC_SUCCESS !=
|
||||
es->VerifyContainer(IOS::HLE::ESDevice::VerifyContainerType::TMD,
|
||||
IOS::HLE::ESDevice::VerifyMode::DoNotUpdateCertStore, tmd, cert_chain))
|
||||
es.VerifyContainer(IOS::HLE::ESCore::VerifyContainerType::TMD,
|
||||
IOS::HLE::ESCore::VerifyMode::DoNotUpdateCertStore, tmd, cert_chain))
|
||||
{
|
||||
AddProblem(
|
||||
Severity::Medium,
|
||||
|
|
|
@ -1011,7 +1011,7 @@ void MenuBar::UpdateToolsMenu(bool emulation_started)
|
|||
if (!emulation_started)
|
||||
{
|
||||
IOS::HLE::Kernel ios;
|
||||
const auto tmd = ios.GetES()->FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
const auto tmd = ios.GetESCore().FindInstalledTMD(Titles::SYSTEM_MENU);
|
||||
|
||||
const QString sysmenu_version =
|
||||
tmd.IsValid() ? QString::fromStdString(
|
||||
|
|
Loading…
Reference in New Issue