diff --git a/Source/Android/jni/WiiUtils.cpp b/Source/Android/jni/WiiUtils.cpp index b6f494e405..77ef3e3f7f 100644 --- a/Source/Android/jni/WiiUtils.cpp +++ b/Source/Android/jni/WiiUtils.cpp @@ -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()) { diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index b6f3a22322..86501bd910 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -690,8 +690,8 @@ void UpdateStateFlags(std::function 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, diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index c79c4a4520..921e454948 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -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; } diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp index ebb9a9b31b..848fcedbf8 100644 --- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp @@ -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(); diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index cf33a27b2b..d052cd70fe 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -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."); diff --git a/Source/Core/Core/HW/WiiSave.cpp b/Source/Core/Core/HW/WiiSave.cpp index 76c5df6f33..e706f19afe 100644 --- a/Source/Core/Core/HW/WiiSave.cpp +++ b/Source/Core/Core/HW/WiiSave.cpp @@ -553,7 +553,7 @@ CopyResult Import(const std::string& data_bin_path, std::function 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; diff --git a/Source/Core/Core/IOS/DI/DI.cpp b/Source/Core/Core/IOS/DI/DI.cpp index dd695d0586..f3b9744da8 100644 --- a/Source/Core/Core/IOS/DI/DI.cpp +++ b/Source/Core/Core/IOS/DI/DI.cpp @@ -736,7 +736,8 @@ std::optional DIDevice::IOCtlV(const IOCtlVRequest& request) const std::vector& 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; diff --git a/Source/Core/Core/IOS/Device.cpp b/Source/Core/Core/IOS/Device.cpp index 920b53bccc..ded8e04224 100644 --- a/Source/Core/Core/IOS/Device.cpp +++ b/Source/Core/Core/IOS/Device.cpp @@ -28,7 +28,7 @@ OpenRequest::OpenRequest(Core::System& system, const u32 address_) : Request(sys auto& memory = system.GetMemory(); path = memory.GetString(memory.Read_U32(address + 0xc)); flags = static_cast(memory.Read_U32(address + 0x10)); - const Kernel* ios = GetIOS(); + const EmulationKernel* ios = GetIOS(); if (ios) { uid = ios->GetUidForPPC(); diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 9cdc76b7ab..4c3bbb33c7 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -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 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); @@ -242,9 +252,9 @@ IPCReply ESDevice::GetTitleId(const IOCtlVRequest& request) return IPCReply(IPC_SUCCESS); } -static bool UpdateUIDAndGID(Kernel& kernel, const ES::TMDReader& tmd) +static bool UpdateUIDAndGID(EmulationKernel& kernel, const ES::TMDReader& tmd) { - ES::UIDSys uid_sys{kernel.GetFSDevice()}; + ES::UIDSys uid_sys{kernel.GetFSCore()}; const u64 title_id = tmd.GetTitleId(); const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id); if (uid == 0) @@ -257,10 +267,10 @@ static bool UpdateUIDAndGID(Kernel& kernel, const ES::TMDReader& tmd) return true; } -static ReturnCode CheckIsAllowedToSetUID(Kernel& kernel, const u32 caller_uid, +static ReturnCode CheckIsAllowedToSetUID(EmulationKernel& kernel, const u32 caller_uid, const ES::TMDReader& active_tmd) { - ES::UIDSys uid_map{kernel.GetFSDevice()}; + ES::UIDSys uid_map{kernel.GetFSCore()}; const u32 system_menu_uid = uid_map.GetOrInsertUIDForTitle(Titles::SYSTEM_MENU); if (!system_menu_uid) return ES_SHORT_READ; @@ -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().GetFSCore().DeleteFile(PID_KERNEL, PID_KERNEL, SPACE_FILE_PATH, ticks); std::vector 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().GetFSCore().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().GetFSCore().DeleteFile(PID_KERNEL, PID_KERNEL, LAUNCH_FILE_PATH, &ticks); WriteSystemFile(SPACE_FILE_PATH, std::vector(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 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 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 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 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* buffer) const +ReturnCode ESCore::ReadCertStore(std::vector* 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* 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 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& cert_chain, u32* issuer_handle_out) +ReturnCode ESCore::VerifyContainer(VerifyContainerType type, VerifyMode mode, + const ES::SignedBlobReader& signed_blob, + const std::vector& 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& cert_chain, - u32 certificate_iosc_handle) +ReturnCode ESCore::VerifyContainer(VerifyContainerType type, VerifyMode mode, + const ES::CertReader& cert, const std::vector& cert_chain, + u32 certificate_iosc_handle) { IOSC::Handle issuer_handle; ReturnCode ret = VerifyContainer(type, mode, cert, cert_chain, &issuer_handle); diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index 5867452e03..ba5f68607a 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -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 Open(const OpenRequest& request) override; - std::optional Close(u32 fd) override; - std::optional 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 GetTitlesWithTickets() const; + enum class CheckContentHashes : bool + { + Yes = true, + No = false, + }; + std::vector GetStoredContentsFromTMD(const ES::TMDReader& tmd, CheckContentHashes check_content_hashes = CheckContentHashes::No) const; @@ -186,6 +181,71 @@ public: const ES::CertReader& certificate, const std::vector& 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* 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; + 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 Open(const OpenRequest& request) override; + std::optional Close(u32 fd) override; + std::optional 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; // 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* 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& 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; - 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 diff --git a/Source/Core/Core/IOS/ES/Formats.cpp b/Source/Core/Core/IOS/ES/Formats.cpp index cccf5086b8..60749b70c9 100644 --- a/Source/Core/Core/IOS/ES/Formats.cpp +++ b/Source/Core/Core/IOS/ES/Formats.cpp @@ -554,17 +554,16 @@ struct SharedContentMap::Entry }; constexpr char CONTENT_MAP_PATH[] = "/shared1/content.map"; -SharedContentMap::SharedContentMap(std::shared_ptr fs) - : m_fs_device{fs}, m_fs{fs->GetFS()} +SharedContentMap::SharedContentMap(HLE::FSCore& fs_core) : m_fs_core{fs_core}, m_fs{fs_core.GetFS()} { static_assert(sizeof(Entry) == 28, "SharedContentMap::Entry has the wrong size"); Entry entry; const auto fd = - fs->Open(PID_KERNEL, PID_KERNEL, CONTENT_MAP_PATH, HLE::FS::Mode::Read, {}, &m_ticks); + fs_core.Open(PID_KERNEL, PID_KERNEL, CONTENT_MAP_PATH, HLE::FS::Mode::Read, {}, &m_ticks); if (fd.Get() < 0) return; - while (fs->Read(fd.Get(), &entry, 1, &m_ticks) == sizeof(entry)) + while (fs_core.Read(fd.Get(), &entry, 1, &m_ticks) == sizeof(entry)) { m_entries.push_back(entry); m_last_id++; @@ -637,7 +636,7 @@ bool SharedContentMap::WriteEntries() const HLE::FS::ResultCode::Success; } -static std::pair ReadUidSysEntry(HLE::FSDevice& fs, u64 fd, u64* ticks) +static std::pair ReadUidSysEntry(HLE::FSCore& fs, u64 fd, u64* ticks) { u64 title_id = 0; if (fs.Read(fd, &title_id, 1, ticks) != sizeof(title_id)) @@ -651,15 +650,15 @@ static std::pair ReadUidSysEntry(HLE::FSDevice& fs, u64 fd, u64* ticks } constexpr char UID_MAP_PATH[] = "/sys/uid.sys"; -UIDSys::UIDSys(std::shared_ptr fs) : m_fs_device{fs}, m_fs{fs->GetFS()} +UIDSys::UIDSys(HLE::FSCore& fs_core) : m_fs_core{fs_core}, m_fs{fs_core.GetFS()} { if (const auto fd = - fs->Open(PID_KERNEL, PID_KERNEL, UID_MAP_PATH, HLE::FS::Mode::Read, {}, &m_ticks); + fs_core.Open(PID_KERNEL, PID_KERNEL, UID_MAP_PATH, HLE::FS::Mode::Read, {}, &m_ticks); fd.Get() >= 0) { while (true) { - std::pair entry = ReadUidSysEntry(*fs, fd.Get(), &m_ticks); + std::pair entry = ReadUidSysEntry(fs_core, fd.Get(), &m_ticks); if (!entry.first && !entry.second) break; diff --git a/Source/Core/Core/IOS/ES/Formats.h b/Source/Core/Core/IOS/ES/Formats.h index 72f36beded..56704e9caa 100644 --- a/Source/Core/Core/IOS/ES/Formats.h +++ b/Source/Core/Core/IOS/ES/Formats.h @@ -280,7 +280,7 @@ public: class SharedContentMap final { public: - explicit SharedContentMap(std::shared_ptr fs); + explicit SharedContentMap(HLE::FSCore& fs_core); ~SharedContentMap(); std::optional GetFilenameFromSHA1(const std::array& sha1) const; @@ -296,7 +296,7 @@ private: struct Entry; u32 m_last_id = 0; std::vector m_entries; - std::shared_ptr m_fs_device; + HLE::FSCore& m_fs_core; std::shared_ptr m_fs; u64 m_ticks = 0; }; @@ -304,7 +304,7 @@ private: class UIDSys final { public: - explicit UIDSys(std::shared_ptr fs); + explicit UIDSys(HLE::FSCore& fs_core); u32 GetUIDFromTitle(u64 title_id) const; u32 GetOrInsertUIDForTitle(u64 title_id); @@ -313,7 +313,7 @@ public: u64 GetTicks() const { return m_ticks; } private: - std::shared_ptr m_fs_device; + HLE::FSCore& m_fs_core; std::shared_ptr m_fs; std::map m_entries; u64 m_ticks = 0; diff --git a/Source/Core/Core/IOS/ES/Identity.cpp b/Source/Core/Core/IOS/ES/Identity.cpp index 1642fe6815..2554bc6891 100644 --- a/Source/Core/Core/IOS/ES/Identity.cpp +++ b/Source/Core/Core/IOS/ES/Identity.cpp @@ -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& hash, const std::vector& ecc_signature, - const std::vector& certs_bytes) +ReturnCode ESCore::VerifySign(const std::vector& hash, const std::vector& ecc_signature, + const std::vector& certs_bytes) { const std::map 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 hash(request.in_vectors[0].size); @@ -217,6 +220,6 @@ IPCReply ESDevice::VerifySign(const IOCtlVRequest& request) std::vector 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 diff --git a/Source/Core/Core/IOS/ES/NandUtils.cpp b/Source/Core/Core/IOS/ES/NandUtils.cpp index e93d6148fd..89af3f140f 100644 --- a/Source/Core/Core/IOS/ES/NandUtils.cpp +++ b/Source/Core/Core/IOS/ES/NandUtils.cpp @@ -25,7 +25,7 @@ namespace IOS::HLE { -static ES::TMDReader FindTMD(FSDevice& fs, const std::string& tmd_path, Ticks ticks) +static ES::TMDReader FindTMD(FSCore& fs, const std::string& tmd_path, Ticks ticks) { const auto fd = fs.Open(PID_KERNEL, PID_KERNEL, tmd_path, FS::Mode::Read, {}, ticks); if (fd.Get() < 0) @@ -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", + return FindTMD(m_ios.GetFSCore(), 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); + return FindTMD(m_ios.GetFSCore(), Common::GetTMDFileName(title_id), ticks); } -ES::TicketReader ESDevice::FindSignedTicket(u64 title_id, std::optional desired_version) const +ES::TicketReader ESCore::FindSignedTicket(u64 title_id, std::optional desired_version) const { std::string path = desired_version == 1 ? Common::GetV1TicketFileName(title_id) : Common::GetTicketFileName(title_id); @@ -125,17 +125,17 @@ static std::vector GetTitlesInTitleOrImport(FS::FileSystem* fs, const std:: return title_ids; } -std::vector ESDevice::GetInstalledTitles() const +std::vector ESCore::GetInstalledTitles() const { return GetTitlesInTitleOrImport(m_ios.GetFS().get(), "/title"); } -std::vector ESDevice::GetTitleImports() const +std::vector ESCore::GetTitleImports() const { return GetTitlesInTitleOrImport(m_ios.GetFS().get(), "/import"); } -std::vector ESDevice::GetTitlesWithTickets() const +std::vector 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 ESDevice::GetTitlesWithTickets() const } std::vector -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( @@ -226,9 +226,9 @@ u32 ESDevice::GetSharedContentsCount() const })); } -std::vector> ESDevice::GetSharedContents() const +std::vector> ESCore::GetSharedContents() const { - const ES::SharedContentMap map{m_ios.GetFSDevice()}; + const ES::SharedContentMap map{m_ios.GetFSCore()}; 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(); @@ -278,7 +278,7 @@ bool ESDevice::CreateTitleDirectories(u64 title_id, u16 group_id) const return false; } - ES::UIDSys uid_sys{m_ios.GetFSDevice()}; + ES::UIDSys uid_sys{m_ios.GetFSCore()}; const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id); if (fs->SetMetadata(0, data_dir, uid, group_id, 0, data_dir_modes) != FS::ResultCode::Success) { @@ -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,19 +385,19 @@ void ESDevice::FinishStaleImport(u64 title_id) } } -void ESDevice::FinishAllStaleImports() +void ESCore::FinishAllStaleImports() { const std::vector 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()) { - ES::SharedContentMap content_map{m_ios.GetFSDevice()}; + ES::SharedContentMap content_map{m_ios.GetFSCore()}; ticks.Add(content_map.GetTicks()); return content_map.GetFilenameFromSHA1(content.sha1).value_or(""); } @@ -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& data, Ticks ticks) { - auto& fs = *m_ios.GetFSDevice(); + auto& fs = GetEmulationKernel().GetFSCore(); const std::string tmp_path = "/tmp/" + PathToFileName(path); auto result = fs.CreateFile(PID_KERNEL, PID_KERNEL, tmp_path, {}, diff --git a/Source/Core/Core/IOS/ES/TitleContents.cpp b/Source/Core/Core/IOS/ES/TitleContents.cpp index 0099803460..5d9d84f235 100644 --- a/Source/Core/Core/IOS/ES/TitleContents.cpp +++ b/Source/Core/Core/IOS/ES/TitleContents.cpp @@ -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(); @@ -29,7 +29,7 @@ s32 ESDevice::OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid, continue; const std::string path = GetContentPath(title_id, content, ticks); - auto fd = m_ios.GetFSDevice()->Open(PID_KERNEL, PID_KERNEL, path, FS::Mode::Read, {}, ticks); + auto fd = m_ios.GetFSCore().Open(PID_KERNEL, PID_KERNEL, path, FS::Mode::Read, {}, ticks); if (fd.Get() < 0) return fd.Get(); @@ -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().GetFSCore()}; + 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; @@ -105,7 +105,7 @@ s32 ESDevice::ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid, Ticks ticks) if (!entry.m_opened) return IPC_EINVAL; - return m_ios.GetFSDevice()->Read(entry.m_fd, buffer, size, {}, ticks); + return m_ios.GetFSCore().Read(entry.m_fd, buffer, size, {}, ticks); } IPCReply ESDevice::ReadContent(u32 uid, const IOCtlVRequest& request) @@ -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; @@ -137,7 +137,7 @@ s32 ESDevice::CloseContent(u32 cfd, u32 uid, Ticks ticks) if (!entry.m_opened) return IPC_EINVAL; - m_ios.GetFSDevice()->Close(entry.m_fd, ticks); + m_ios.GetFSCore().Close(entry.m_fd, ticks); entry = {}; INFO_LOG_FMT(IOS_ES, "CloseContent: CFD {}", cfd); return IPC_SUCCESS; @@ -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; @@ -167,7 +167,7 @@ s32 ESDevice::SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid, Ticks tic if (!entry.m_opened) return IPC_EINVAL; - return m_ios.GetFSDevice()->Seek(entry.m_fd, offset, static_cast(mode), ticks); + return m_ios.GetFSCore().Seek(entry.m_fd, offset, static_cast(mode), ticks); } IPCReply ESDevice::SeekContent(u32 uid, const IOCtlVRequest& request) @@ -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(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 diff --git a/Source/Core/Core/IOS/ES/TitleInformation.cpp b/Source/Core/Core/IOS/ES/TitleInformation.cpp index e8f2909ef0..368325295b 100644 --- a/Source/Core/Core/IOS/ES/TitleInformation.cpp +++ b/Source/Core/Core/IOS/ES/TitleInformation.cpp @@ -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(GetStoredContentsFromTMD(tmd).size()); - auto& system = Core::System::GetInstance(); + const u16 num_contents = static_cast(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(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 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 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 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& 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(titles.size()), request.io_vectors[0].address); @@ -137,7 +138,7 @@ IPCReply ESDevice::GetTitles(const std::vector& 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& titles, const IOCtlVRequest IPCReply ESDevice::GetTitleCount(const IOCtlVRequest& request) { - const std::vector titles = GetInstalledTitles(); + const std::vector 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 titles = GetTitlesWithTickets(); + const std::vector 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> hashes = GetSharedContents(); + const std::vector> hashes = m_core.GetSharedContents(); const u32 count = std::min(static_cast(hashes.size()), max_count); memory.CopyToEmu(request.io_vectors[0].address, hashes.data(), 20 * count); diff --git a/Source/Core/Core/IOS/ES/TitleManagement.cpp b/Source/Core/Core/IOS/ES/TitleManagement.cpp index 13884d5628..0a48ab9c47 100644 --- a/Source/Core/Core/IOS/ES/TitleManagement.cpp +++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp @@ -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& ticket_bytes, - const std::vector& cert_chain, TicketImportType type, - VerifySignature verify_signature) +ReturnCode ESCore::ImportTicket(const std::vector& ticket_bytes, + const std::vector& 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 bytes(request.in_vectors[0].size); memory.CopyFromEmu(bytes.data(), request.in_vectors[0].address, request.in_vectors[0].size); std::vector 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 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& tmd_bytes, - u64 caller_title_id, u32 caller_title_flags) +ReturnCode ESCore::ImportTmd(Context& context, const std::vector& 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 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& ticket_bytes, IOSC& iosc, @@ -217,9 +217,9 @@ static ReturnCode InitTitleImportKey(const std::vector& ticket_bytes, IOSC& &ticket_bytes[offsetof(ES::Ticket, title_key)], PID_ES); } -ReturnCode ESDevice::ImportTitleInit(Context& context, const std::vector& tmd_bytes, - const std::vector& cert_chain, - VerifySignature verify_signature) +ReturnCode ESCore::ImportTitleInit(Context& context, const std::vector& tmd_bytes, + const std::vector& 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 tmd(request.in_vectors[0].size); memory.CopyFromEmu(tmd.data(), request.in_vectors[0].address, request.in_vectors[0].size); std::vector 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& 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); @@ -407,7 +408,7 @@ ReturnCode ESDevice::ImportContentEnd(Context& context, u32 content_fd) std::string content_path; if (content_info.IsShared()) { - ES::SharedContentMap shared_content{m_ios.GetFSDevice()}; + ES::SharedContentMap shared_content{m_ios.GetFSCore()}; content_path = shared_content.AddSharedContent(content_info.sha1); } else @@ -446,18 +447,18 @@ 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) { const u64 title_id = tmd.GetTitleId(); const std::vector contents = tmd.GetContents(); - const ES::SharedContentMap shared_content_map{ios.GetFSDevice()}; + const ES::SharedContentMap shared_content_map{ios.GetFSCore()}; return std::all_of(contents.cbegin(), contents.cend(), [&](const ES::Content& content) { if (content.IsOptional()) return true; @@ -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(title_id >> 32) != 0x00000001 || static_cast(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,12 +860,12 @@ 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& sha1) const +ReturnCode ESCore::DeleteSharedContent(const std::array& sha1) const { - ES::SharedContentMap map{m_ios.GetFSDevice()}; + ES::SharedContentMap map{m_ios.GetFSCore()}; const auto content_path = map.GetFilenameFromSHA1(sha1); if (!content_path) return ES_EINVAL; @@ -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 diff --git a/Source/Core/Core/IOS/ES/Views.cpp b/Source/Core/Core/IOS/ES/Views.cpp index cedc3a6edf..92012ef641 100644 --- a/Source/Core/Core/IOS/ES/Views.cpp +++ b/Source/Core/Core/IOS/ES/Views.cpp @@ -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(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 desired_version) const +ReturnCode ESCore::GetTicketFromView(const u8* ticket_view, u8* ticket, u32* ticket_size, + std::optional 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(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 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(m_title_context.tmd.GetBytes().size()), + memory.Write_U32(static_cast(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& tmd_bytes = m_title_context.tmd.GetBytes(); + const std::vector& tmd_bytes = m_core.m_title_context.tmd.GetBytes(); if (static_cast(tmd_bytes.size()) > tmd_size) return IPCReply(ES_EINVAL); diff --git a/Source/Core/Core/IOS/FS/FileSystemProxy.cpp b/Source/Core/Core/IOS/FS/FileSystemProxy.cpp index 81820ef79b..0dd3284b51 100644 --- a/Source/Core/Core/IOS/FS/FileSystemProxy.cpp +++ b/Source/Core/Core/IOS/FS/FileSystemProxy.cpp @@ -83,7 +83,7 @@ constexpr SystemTimers::TimeBaseTick GetFreeClusterCheckTbTicks() constexpr size_t CLUSTER_DATA_SIZE = 0x4000; -FSDevice::FSDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name) +FSCore::FSCore(Kernel& ios) : m_ios(ios) { if (ios.GetFS()->Delete(PID_KERNEL, PID_KERNEL, "/tmp") == ResultCode::Success) { @@ -92,14 +92,23 @@ FSDevice::FSDevice(Kernel& ios, const std::string& device_name) : Device(ios, de } } +FSCore::~FSCore() = default; + +FSDevice::FSDevice(EmulationKernel& ios, FSCore& core, const std::string& device_name) + : EmulationDevice(ios, device_name), m_core(core) +{ +} + +FSDevice::~FSDevice() = default; + void FSDevice::DoState(PointerWrap& p) { Device::DoState(p); - p.Do(m_dirty_cache); - p.Do(m_cache_chain_index); - p.Do(m_cache_fd); - p.Do(m_next_fd); - p.Do(m_fd_map); + p.Do(m_core.m_dirty_cache); + p.Do(m_core.m_cache_chain_index); + p.Do(m_core.m_cache_fd); + p.Do(m_core.m_next_fd); + p.Do(m_core.m_fd_map); } template @@ -161,14 +170,15 @@ static IPCReply GetReplyForSuperblockOperation(int ios_version, ResultCode resul std::optional FSDevice::Open(const OpenRequest& request) { return MakeIPCReply([&](Ticks t) { - return Open(request.uid, request.gid, request.path, static_cast(request.flags & 3), - request.fd, t) + return m_core + .Open(request.uid, request.gid, request.path, static_cast(request.flags & 3), + request.fd, t) .Release(); }); } -FSDevice::ScopedFd FSDevice::Open(FS::Uid uid, FS::Gid gid, const std::string& path, FS::Mode mode, - std::optional ipc_fd, Ticks ticks) +FSCore::ScopedFd FSCore::Open(FS::Uid uid, FS::Gid gid, const std::string& path, FS::Mode mode, + std::optional ipc_fd, Ticks ticks) { ticks.Add(IPC_OVERHEAD_TICKS); @@ -200,10 +210,10 @@ FSDevice::ScopedFd FSDevice::Open(FS::Uid uid, FS::Gid gid, const std::string& p std::optional FSDevice::Close(u32 fd) { - return MakeIPCReply([&](Ticks t) { return Close(static_cast(fd), t); }); + return MakeIPCReply([&](Ticks t) { return m_core.Close(static_cast(fd), t); }); } -s32 FSDevice::Close(u64 fd, Ticks ticks) +s32 FSCore::Close(u64 fd, Ticks ticks) { ticks.Add(IPC_OVERHEAD_TICKS); @@ -232,7 +242,7 @@ s32 FSDevice::Close(u64 fd, Ticks ticks) return IPC_SUCCESS; } -u64 FSDevice::SimulatePopulateFileCache(u64 fd, u32 offset, u32 file_size) +u64 FSCore::SimulatePopulateFileCache(u64 fd, u32 offset, u32 file_size) { if (HasCacheForFile(fd, offset)) return 0; @@ -246,7 +256,7 @@ u64 FSDevice::SimulatePopulateFileCache(u64 fd, u32 offset, u32 file_size) return ticks; } -u64 FSDevice::SimulateFlushFileCache() +u64 FSCore::SimulateFlushFileCache() { if (!m_cache_fd.has_value() || !m_dirty_cache) return 0; @@ -256,8 +266,8 @@ u64 FSDevice::SimulateFlushFileCache() } // Simulate parts of the FS read/write logic to estimate ticks for file operations correctly. -u64 FSDevice::EstimateTicksForReadWrite(const Handle& handle, u64 fd, IPCCommandType command, - u32 size) +u64 FSCore::EstimateTicksForReadWrite(const Handle& handle, u64 fd, IPCCommandType command, + u32 size) { u64 ticks = 0; @@ -304,7 +314,7 @@ u64 FSDevice::EstimateTicksForReadWrite(const Handle& handle, u64 fd, IPCCommand return ticks; } -bool FSDevice::HasCacheForFile(u64 fd, u32 offset) const +bool FSCore::HasCacheForFile(u64 fd, u32 offset) const { const u16 chain_index = static_cast(offset / CLUSTER_DATA_SIZE); return m_cache_fd == fd && m_cache_chain_index == chain_index; @@ -313,13 +323,14 @@ bool FSDevice::HasCacheForFile(u64 fd, u32 offset) const std::optional FSDevice::Read(const ReadWriteRequest& request) { return MakeIPCReply([&](Ticks t) { - auto& system = Core::System::GetInstance(); + auto& system = GetSystem(); auto& memory = system.GetMemory(); - return Read(request.fd, memory.GetPointer(request.buffer), request.size, request.buffer, t); + return m_core.Read(request.fd, memory.GetPointer(request.buffer), request.size, request.buffer, + t); }); } -s32 FSDevice::Read(u64 fd, u8* data, u32 size, std::optional ipc_buffer_addr, Ticks ticks) +s32 FSCore::Read(u64 fd, u8* data, u32 size, std::optional ipc_buffer_addr, Ticks ticks) { ticks.Add(IPC_OVERHEAD_TICKS); @@ -343,14 +354,14 @@ s32 FSDevice::Read(u64 fd, u8* data, u32 size, std::optional ipc_buffer_add std::optional FSDevice::Write(const ReadWriteRequest& request) { return MakeIPCReply([&](Ticks t) { - auto& system = Core::System::GetInstance(); + auto& system = GetSystem(); auto& memory = system.GetMemory(); - return Write(request.fd, memory.GetPointer(request.buffer), request.size, request.buffer, t); + return m_core.Write(request.fd, memory.GetPointer(request.buffer), request.size, request.buffer, + t); }); } -s32 FSDevice::Write(u64 fd, const u8* data, u32 size, std::optional ipc_buffer_addr, - Ticks ticks) +s32 FSCore::Write(u64 fd, const u8* data, u32 size, std::optional ipc_buffer_addr, Ticks ticks) { ticks.Add(IPC_OVERHEAD_TICKS); @@ -374,11 +385,11 @@ s32 FSDevice::Write(u64 fd, const u8* data, u32 size, std::optional ipc_buf std::optional FSDevice::Seek(const SeekRequest& request) { return MakeIPCReply([&](Ticks t) { - return Seek(request.fd, request.offset, HLE::FS::SeekMode(request.mode), t); + return m_core.Seek(request.fd, request.offset, HLE::FS::SeekMode(request.mode), t); }); } -s32 FSDevice::Seek(u64 fd, u32 offset, FS::SeekMode mode, Ticks ticks) +s32 FSCore::Seek(u64 fd, u32 offset, FS::SeekMode mode, Ticks ticks) { ticks.Add(IPC_OVERHEAD_TICKS); @@ -422,14 +433,11 @@ struct ISFSFileStats #pragma pack(pop) template -static Result GetParams(const IOCtlRequest& request) +static Result GetParams(Memory::MemoryManager& memory, const IOCtlRequest& request) { if (request.buffer_in_size < sizeof(T)) return ResultCode::Invalid; - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - T params; memory.CopyFromEmu(¶ms, request.buffer_in, sizeof(params)); return params; @@ -437,8 +445,8 @@ static Result GetParams(const IOCtlRequest& request) std::optional FSDevice::IOCtl(const IOCtlRequest& request) { - const auto it = m_fd_map.find(request.fd); - if (it == m_fd_map.end()) + const auto it = m_core.m_fd_map.find(request.fd); + if (it == m_core.m_fd_map.end()) return IPCReply(ConvertResult(ResultCode::Invalid)); switch (request.request) @@ -472,8 +480,8 @@ std::optional FSDevice::IOCtl(const IOCtlRequest& request) std::optional FSDevice::IOCtlV(const IOCtlVRequest& request) { - const auto it = m_fd_map.find(request.fd); - if (it == m_fd_map.end()) + const auto it = m_core.m_fd_map.find(request.fd); + if (it == m_core.m_fd_map.end()) return IPCReply(ConvertResult(ResultCode::Invalid)); switch (request.request) @@ -506,7 +514,7 @@ IPCReply FSDevice::GetStats(const Handle& handle, const IOCtlRequest& request) if (!stats) return IPCReply(ConvertResult(stats.Error())); - auto& system = Core::System::GetInstance(); + auto& system = GetSystem(); auto& memory = system.GetMemory(); ISFSNandStats out; @@ -523,7 +531,7 @@ IPCReply FSDevice::GetStats(const Handle& handle, const IOCtlRequest& request) IPCReply FSDevice::CreateDirectory(const Handle& handle, const IOCtlRequest& request) { - const auto params = GetParams(request); + const auto params = GetParams(GetSystem().GetMemory(), request); if (!params) return GetFSReply(ConvertResult(params.Error())); @@ -541,7 +549,7 @@ IPCReply FSDevice::ReadDirectory(const Handle& handle, const IOCtlVRequest& requ return GetFSReply(ConvertResult(ResultCode::Invalid)); } - auto& system = Core::System::GetInstance(); + auto& system = GetSystem(); auto& memory = system.GetMemory(); u32 file_list_address, file_count_address, max_count; @@ -592,7 +600,7 @@ IPCReply FSDevice::ReadDirectory(const Handle& handle, const IOCtlVRequest& requ IPCReply FSDevice::SetAttribute(const Handle& handle, const IOCtlRequest& request) { - const auto params = GetParams(request); + const auto params = GetParams(GetSystem().GetMemory(), request); if (!params) return GetFSReply(ConvertResult(params.Error())); @@ -607,7 +615,7 @@ IPCReply FSDevice::GetAttribute(const Handle& handle, const IOCtlRequest& reques if (request.buffer_in_size < 64 || request.buffer_out_size < sizeof(ISFSParams)) return GetFSReply(ConvertResult(ResultCode::Invalid)); - auto& system = Core::System::GetInstance(); + auto& system = GetSystem(); auto& memory = system.GetMemory(); const std::string path = memory.GetString(request.buffer_in, 64); @@ -629,7 +637,7 @@ IPCReply FSDevice::GetAttribute(const Handle& handle, const IOCtlRequest& reques return GetFSReply(IPC_SUCCESS, ticks); } -FS::ResultCode FSDevice::DeleteFile(FS::Uid uid, FS::Gid gid, const std::string& path, Ticks ticks) +FS::ResultCode FSCore::DeleteFile(FS::Uid uid, FS::Gid gid, const std::string& path, Ticks ticks) { ticks.Add(IPC_OVERHEAD_TICKS); @@ -644,16 +652,17 @@ IPCReply FSDevice::DeleteFile(const Handle& handle, const IOCtlRequest& request) if (request.buffer_in_size < 64) return GetFSReply(ConvertResult(ResultCode::Invalid)); - auto& system = Core::System::GetInstance(); + auto& system = GetSystem(); auto& memory = system.GetMemory(); const std::string path = memory.GetString(request.buffer_in, 64); - return MakeIPCReply( - [&](Ticks ticks) { return ConvertResult(DeleteFile(handle.uid, handle.gid, path, ticks)); }); + return MakeIPCReply([&](Ticks ticks) { + return ConvertResult(m_core.DeleteFile(handle.uid, handle.gid, path, ticks)); + }); } -FS::ResultCode FSDevice::RenameFile(FS::Uid uid, FS::Gid gid, const std::string& old_path, - const std::string& new_path, Ticks ticks) +FS::ResultCode FSCore::RenameFile(FS::Uid uid, FS::Gid gid, const std::string& old_path, + const std::string& new_path, Ticks ticks) { ticks.Add(IPC_OVERHEAD_TICKS); @@ -668,18 +677,18 @@ IPCReply FSDevice::RenameFile(const Handle& handle, const IOCtlRequest& request) if (request.buffer_in_size < 64 * 2) return GetFSReply(ConvertResult(ResultCode::Invalid)); - auto& system = Core::System::GetInstance(); + auto& system = GetSystem(); auto& memory = system.GetMemory(); const std::string old_path = memory.GetString(request.buffer_in, 64); const std::string new_path = memory.GetString(request.buffer_in + 64, 64); return MakeIPCReply([&](Ticks ticks) { - return ConvertResult(RenameFile(handle.uid, handle.gid, old_path, new_path, ticks)); + return ConvertResult(m_core.RenameFile(handle.uid, handle.gid, old_path, new_path, ticks)); }); } -FS::ResultCode FSDevice::CreateFile(FS::Uid uid, FS::Gid gid, const std::string& path, - FS::FileAttribute attribute, FS::Modes modes, Ticks ticks) +FS::ResultCode FSCore::CreateFile(FS::Uid uid, FS::Gid gid, const std::string& path, + FS::FileAttribute attribute, FS::Modes modes, Ticks ticks) { ticks.Add(IPC_OVERHEAD_TICKS); @@ -691,18 +700,18 @@ FS::ResultCode FSDevice::CreateFile(FS::Uid uid, FS::Gid gid, const std::string& IPCReply FSDevice::CreateFile(const Handle& handle, const IOCtlRequest& request) { - const auto params = GetParams(request); + const auto params = GetParams(GetSystem().GetMemory(), request); if (!params) return GetFSReply(ConvertResult(params.Error())); return MakeIPCReply([&](Ticks ticks) { return ConvertResult( - CreateFile(handle.uid, handle.gid, params->path, params->attribute, params->modes)); + m_core.CreateFile(handle.uid, handle.gid, params->path, params->attribute, params->modes)); }); } IPCReply FSDevice::SetFileVersionControl(const Handle& handle, const IOCtlRequest& request) { - const auto params = GetParams(request); + const auto params = GetParams(GetSystem().GetMemory(), request); if (!params) return GetFSReply(ConvertResult(params.Error())); @@ -718,11 +727,11 @@ IPCReply FSDevice::GetFileStats(const Handle& handle, const IOCtlRequest& reques return GetFSReply(ConvertResult(ResultCode::Invalid)); return MakeIPCReply([&](Ticks ticks) { - const Result status = GetFileStatus(request.fd, ticks); + const Result status = m_core.GetFileStatus(request.fd, ticks); if (!status) return ConvertResult(status.Error()); - auto& system = Core::System::GetInstance(); + auto& system = GetSystem(); auto& memory = system.GetMemory(); ISFSFileStats out; @@ -733,7 +742,7 @@ IPCReply FSDevice::GetFileStats(const Handle& handle, const IOCtlRequest& reques }); } -FS::Result FSDevice::GetFileStatus(u64 fd, Ticks ticks) +FS::Result FSCore::GetFileStatus(u64 fd, Ticks ticks) { ticks.Add(IPC_OVERHEAD_TICKS); const auto& handle = m_fd_map[fd]; @@ -753,7 +762,7 @@ IPCReply FSDevice::GetUsage(const Handle& handle, const IOCtlVRequest& request) return GetFSReply(ConvertResult(ResultCode::Invalid)); } - auto& system = Core::System::GetInstance(); + auto& system = GetSystem(); auto& memory = system.GetMemory(); const std::string directory = memory.GetString(request.in_vectors[0].address, 64); diff --git a/Source/Core/Core/IOS/FS/FileSystemProxy.h b/Source/Core/Core/IOS/FS/FileSystemProxy.h index 49779ef6e5..8f3bb1e8b4 100644 --- a/Source/Core/Core/IOS/FS/FileSystemProxy.h +++ b/Source/Core/Core/IOS/FS/FileSystemProxy.h @@ -20,13 +20,22 @@ namespace IOS::HLE { constexpr FS::Fd INVALID_FD = 0xffffffff; -class FSDevice : public Device +class FSDevice; + +class FSCore final { public: + explicit FSCore(Kernel& ios); + FSCore(const FSCore& other) = delete; + FSCore(FSCore&& other) = delete; + FSCore& operator=(const FSCore& other) = delete; + FSCore& operator=(FSCore&& other) = delete; + ~FSCore(); + class ScopedFd { public: - ScopedFd(FSDevice* fs, s64 fd, Ticks tick_tracker = {}) + ScopedFd(FSCore* fs, s64 fd, Ticks tick_tracker = {}) : m_fs{fs}, m_fd{fd}, m_tick_tracker{tick_tracker} { } @@ -46,13 +55,11 @@ public: s64 Release() { return std::exchange(m_fd, -1); } private: - FSDevice* m_fs{}; + FSCore* m_fs{}; s64 m_fd = -1; Ticks m_tick_tracker{}; }; - FSDevice(Kernel& ios, const std::string& device_name); - // These are the equivalent of the IPC command handlers so IPC overhead is included // in timing calculations. ScopedFd Open(FS::Uid uid, FS::Gid gid, const std::string& path, FS::Mode mode, @@ -78,16 +85,6 @@ public: std::shared_ptr GetFS() const { return m_ios.GetFS(); } - void DoState(PointerWrap& p) override; - - std::optional Open(const OpenRequest& request) override; - std::optional Close(u32 fd) override; - std::optional Read(const ReadWriteRequest& request) override; - std::optional Write(const ReadWriteRequest& request) override; - std::optional Seek(const SeekRequest& request) override; - std::optional IOCtl(const IOCtlRequest& request) override; - std::optional IOCtlV(const IOCtlVRequest& request) override; - private: struct Handle { @@ -99,6 +96,40 @@ private: bool superblock_flush_needed = false; }; + u64 EstimateTicksForReadWrite(const Handle& handle, u64 fd, IPCCommandType command, u32 size); + u64 SimulatePopulateFileCache(u64 fd, u32 offset, u32 file_size); + u64 SimulateFlushFileCache(); + bool HasCacheForFile(u64 fd, u32 offset) const; + + Kernel& m_ios; + + bool m_dirty_cache = false; + u16 m_cache_chain_index = 0; + std::optional m_cache_fd; + // The first 0x18 IDs are reserved for the PPC. + u64 m_next_fd = 0x18; + std::map m_fd_map; + + friend class FSDevice; +}; + +class FSDevice final : public EmulationDevice +{ +public: + FSDevice(EmulationKernel& ios, FSCore& core, const std::string& device_name); + ~FSDevice(); + + void DoState(PointerWrap& p) override; + + std::optional Open(const OpenRequest& request) override; + std::optional Close(u32 fd) override; + std::optional Read(const ReadWriteRequest& request) override; + std::optional Write(const ReadWriteRequest& request) override; + std::optional Seek(const SeekRequest& request) override; + std::optional IOCtl(const IOCtlRequest& request) override; + std::optional IOCtlV(const IOCtlVRequest& request) override; + +private: enum { ISFS_IOCTL_FORMAT = 1, @@ -116,6 +147,8 @@ private: ISFS_IOCTL_SHUTDOWN = 13, }; + using Handle = FSCore::Handle; + IPCReply Format(const Handle& handle, const IOCtlRequest& request); IPCReply GetStats(const Handle& handle, const IOCtlRequest& request); IPCReply CreateDirectory(const Handle& handle, const IOCtlRequest& request); @@ -130,16 +163,6 @@ private: IPCReply GetUsage(const Handle& handle, const IOCtlVRequest& request); IPCReply Shutdown(const Handle& handle, const IOCtlRequest& request); - u64 EstimateTicksForReadWrite(const Handle& handle, u64 fd, IPCCommandType command, u32 size); - u64 SimulatePopulateFileCache(u64 fd, u32 offset, u32 file_size); - u64 SimulateFlushFileCache(); - bool HasCacheForFile(u64 fd, u32 offset) const; - - bool m_dirty_cache = false; - u16 m_cache_chain_index = 0; - std::optional m_cache_fd; - // The first 0x18 IDs are reserved for the PPC. - u64 m_next_fd = 0x18; - std::map m_fd_map; + FSCore& m_core; }; } // namespace IOS::HLE diff --git a/Source/Core/Core/IOS/IOS.cpp b/Source/Core/Core/IOS/IOS.cpp index fe4b20e93c..3ae6ddc828 100644 --- a/Source/Core/Core/IOS/IOS.cpp +++ b/Source/Core/Core/IOS/IOS.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -300,17 +299,15 @@ 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); + + m_fs_core = std::make_unique(*this); + m_es_core = std::make_unique(*this); } Kernel::~Kernel() { - { - std::lock_guard lock(m_device_map_mutex); - m_device_map.clear(); - m_socket_manager.reset(); - } - if (m_is_responsible_for_nand_root) Core::ShutdownWiiRoot(); } @@ -333,13 +330,23 @@ EmulationKernel::EmulationKernel(Core::System& system, u64 title_id) return; } - AddCoreDevices(); + m_fs = FS::MakeFileSystem(IOS::HLE::FS::Location::Session, Core::GetActiveNandRedirects()); + ASSERT(m_fs); + + m_fs_core = std::make_unique(*this); + AddDevice(std::make_unique(*this, *m_fs_core, "/dev/fs")); + m_es_core = std::make_unique(*this); + AddDevice(std::make_unique(*this, *m_es_core, "/dev/es")); + AddStaticDevices(); } EmulationKernel::~EmulationKernel() { Core::System::GetInstance().GetCoreTiming().RemoveAllEvents(s_event_enqueue); + + m_device_map.clear(); + m_socket_manager.reset(); } // The title ID is a u64 where the first 32 bits are used for the title type. @@ -355,12 +362,22 @@ std::shared_ptr Kernel::GetFS() return m_fs; } -std::shared_ptr Kernel::GetFSDevice() +FSCore& Kernel::GetFSCore() +{ + return *m_fs_core; +} + +std::shared_ptr EmulationKernel::GetFSDevice() { return std::static_pointer_cast(m_device_map.at("/dev/fs")); } -std::shared_ptr Kernel::GetES() +ESCore& Kernel::GetESCore() +{ + return *m_es_core; +} + +std::shared_ptr EmulationKernel::GetESDevice() { return std::static_pointer_cast(m_device_map.at("/dev/es")); } @@ -372,51 +389,51 @@ std::shared_ptr EmulationKernel::GetSocketManager() // Since we don't have actual processes, we keep track of only the PPC's UID/GID. // These functions roughly correspond to syscalls 0x2b, 0x2c, 0x2d, 0x2e (though only for the PPC). -void Kernel::SetUidForPPC(u32 uid) +void EmulationKernel::SetUidForPPC(u32 uid) { m_ppc_uid = uid; } -u32 Kernel::GetUidForPPC() const +u32 EmulationKernel::GetUidForPPC() const { return m_ppc_uid; } -void Kernel::SetGidForPPC(u16 gid) +void EmulationKernel::SetGidForPPC(u16 gid) { m_ppc_gid = gid; } -u16 Kernel::GetGidForPPC() const +u16 EmulationKernel::GetGidForPPC() const { return m_ppc_gid; } -static std::vector ReadBootContent(FSDevice* fs, const std::string& path, size_t max_size, +static std::vector ReadBootContent(FSCore& fs, const std::string& path, size_t max_size, Ticks ticks = {}) { - const auto fd = fs->Open(0, 0, path, FS::Mode::Read, {}, ticks); + const auto fd = fs.Open(0, 0, path, FS::Mode::Read, {}, ticks); if (fd.Get() < 0) return {}; - const size_t file_size = fs->GetFileStatus(fd.Get(), ticks)->size; + const size_t file_size = fs.GetFileStatus(fd.Get(), ticks)->size; if (max_size != 0 && file_size > max_size) return {}; std::vector buffer(file_size); - if (!fs->Read(fd.Get(), buffer.data(), buffer.size(), ticks)) + if (!fs.Read(fd.Get(), buffer.data(), buffer.size(), ticks)) return {}; return buffer; } // This corresponds to syscall 0x41, which loads a binary from the NAND and bootstraps the PPC. // Unlike 0x42, IOS will set up some constants in memory before booting the PPC. -bool Kernel::BootstrapPPC(Core::System& system, const std::string& boot_content_path) +bool EmulationKernel::BootstrapPPC(Core::System& system, const std::string& boot_content_path) { // Seeking and processing overhead is ignored as most time is spent reading from the NAND. u64 ticks = 0; - const DolReader dol{ReadBootContent(GetFSDevice().get(), boot_content_path, 0, &ticks)}; + const DolReader dol{ReadBootContent(GetFSCore(), boot_content_path, 0, &ticks)}; if (!dol.IsValid()) return false; @@ -485,8 +502,8 @@ static constexpr SystemTimers::TimeBaseTick GetIOSBootTicks(u32 version) // Passing a boot content path is optional because we do not require IOSes // to be installed at the moment. If one is passed, the boot binary must exist // on the NAND, or the call will fail like on a Wii. -bool Kernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_ppc, - const std::string& boot_content_path) +bool EmulationKernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_ppc, + const std::string& boot_content_path) { // IOS suspends regular PPC<->ARM IPC before loading a new IOS. // IPC is not resumed if the boot fails for any reason. @@ -497,7 +514,7 @@ bool Kernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_ // Load the ARM binary to memory (if possible). // Because we do not actually emulate the Starlet, only load the sections that are in MEM1. - ARMBinary binary{ReadBootContent(GetFSDevice().get(), boot_content_path, 0xB00000)}; + ARMBinary binary{ReadBootContent(GetFSCore(), boot_content_path, 0xB00000)}; if (!binary.IsValid()) return false; @@ -522,7 +539,7 @@ bool Kernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_ return true; } -void Kernel::InitIPC() +void EmulationKernel::InitIPC() { if (!Core::IsRunning()) return; @@ -531,26 +548,14 @@ void Kernel::InitIPC() GenerateAck(0); } -void Kernel::AddDevice(std::unique_ptr device) +void EmulationKernel::AddDevice(std::unique_ptr device) { ASSERT(device->GetDeviceType() == Device::DeviceType::Static); 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(*this, "/dev/fs")); - AddDevice(std::make_unique(*this, "/dev/es")); -} - void EmulationKernel::AddStaticDevices() { - std::lock_guard lock(m_device_map_mutex); - const Feature features = GetFeatures(GetVersion()); // Dolphin-specific device for letting homebrew access and alter emulator state. @@ -637,16 +642,10 @@ s32 EmulationKernel::GetFreeDeviceID() return -1; } -std::shared_ptr Kernel::GetDeviceByName(std::string_view device_name) -{ - std::lock_guard lock(m_device_map_mutex); - const auto iterator = m_device_map.find(device_name); - return iterator != m_device_map.end() ? iterator->second : nullptr; -} - std::shared_ptr EmulationKernel::GetDeviceByName(std::string_view device_name) { - return Kernel::GetDeviceByName(device_name); + const auto iterator = m_device_map.find(device_name); + return iterator != m_device_map.end() ? iterator->second : nullptr; } // Returns the FD for the newly opened device (on success) or an error code. diff --git a/Source/Core/Core/IOS/IOS.h b/Source/Core/Core/IOS/IOS.h index b985a33028..0339ad13bb 100644 --- a/Source/Core/Core/IOS/IOS.h +++ b/Source/Core/Core/IOS/IOS.h @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -33,7 +32,9 @@ class FileSystem; } class Device; +class ESCore; class ESDevice; +class FSCore; class FSDevice; class WiiSockMan; @@ -122,18 +123,9 @@ public: // These are *always* part of the IOS kernel and always available. // They are also the only available resource managers even before loading any module. std::shared_ptr GetFS(); - std::shared_ptr GetFSDevice(); - std::shared_ptr GetES(); + FSCore& GetFSCore(); + ESCore& GetESCore(); - void SetUidForPPC(u32 uid); - u32 GetUidForPPC() const; - void SetGidForPPC(u16 gid); - u16 GetGidForPPC() const; - - bool BootstrapPPC(Core::System& system, const std::string& boot_content_path); - bool BootIOS(Core::System& system, u64 ios_title_id, HangPPC hang_ppc = HangPPC::No, - const std::string& boot_content_path = {}); - void InitIPC(); u32 GetVersion() const; IOSC& GetIOSC(); @@ -141,26 +133,11 @@ public: protected: explicit Kernel(u64 title_id); - void AddDevice(std::unique_ptr device); - void AddCoreDevices(); - std::shared_ptr GetDeviceByName(std::string_view device_name); + std::unique_ptr m_fs_core; + std::unique_ptr m_es_core; bool m_is_responsible_for_nand_root = false; u64 m_title_id = 0; - static constexpr u8 IPC_MAX_FDS = 0x18; - std::map, std::less<>> m_device_map; - std::mutex m_device_map_mutex; - // TODO: make this fdmap per process. - std::array, IPC_MAX_FDS> m_fdmap; - - u32 m_ppc_uid = 0; - u16 m_ppc_gid = 0; - - using IPCMsgQueue = std::deque; - IPCMsgQueue m_request_queue; // ppc -> arm - IPCMsgQueue m_reply_queue; // arm -> ppc - u64 m_last_reply_time = 0; - bool m_ipc_paused = false; IOSC m_iosc; std::shared_ptr m_fs; @@ -178,6 +155,9 @@ public: // This only works for devices which are part of the device map. std::shared_ptr GetDeviceByName(std::string_view device_name); + std::shared_ptr GetFSDevice(); + std::shared_ptr GetESDevice(); + void DoState(PointerWrap& p); void UpdateDevices(); void UpdateWantDeterminism(bool new_want_determinism); @@ -191,17 +171,43 @@ public: void EnqueueIPCReply(const Request& request, s32 return_value, s64 cycles_in_future = 0, CoreTiming::FromThread from = CoreTiming::FromThread::CPU); + void SetUidForPPC(u32 uid); + u32 GetUidForPPC() const; + void SetGidForPPC(u16 gid); + u16 GetGidForPPC() const; + + bool BootstrapPPC(Core::System& system, const std::string& boot_content_path); + bool BootIOS(Core::System& system, u64 ios_title_id, HangPPC hang_ppc = HangPPC::No, + const std::string& boot_content_path = {}); + void InitIPC(); + Core::System& GetSystem() const { return m_system; } private: - Core::System& m_system; - void ExecuteIPCCommand(u32 address); std::optional HandleIPCCommand(const Request& request); + void AddDevice(std::unique_ptr device); + void AddStaticDevices(); s32 GetFreeDeviceID(); std::optional OpenDevice(OpenRequest& request); + + Core::System& m_system; + + static constexpr u8 IPC_MAX_FDS = 0x18; + std::map, std::less<>> m_device_map; + // TODO: make this fdmap per process. + std::array, IPC_MAX_FDS> m_fdmap; + + u32 m_ppc_uid = 0; + u16 m_ppc_gid = 0; + + using IPCMsgQueue = std::deque; + IPCMsgQueue m_request_queue; // ppc -> arm + IPCMsgQueue m_reply_queue; // arm -> ppc + u64 m_last_reply_time = 0; + bool m_ipc_paused = false; }; // Used for controlling and accessing an IOS instance that is tied to emulation. diff --git a/Source/Core/Core/IOS/WFS/WFSI.cpp b/Source/Core/Core/IOS/WFS/WFSI.cpp index 253b472142..81d5844743 100644 --- a/Source/Core/Core/IOS/WFS/WFSI.cpp +++ b/Source/Core/Core/IOS/WFS/WFSI.cpp @@ -165,7 +165,8 @@ std::optional 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 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; } diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index 6969c686f3..5452d9e80f 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -1720,7 +1720,7 @@ std::optional 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() && diff --git a/Source/Core/Core/WiiRoot.cpp b/Source/Core/Core/WiiRoot.cpp index d12958229c..ef56bcb397 100644 --- a/Source/Core/Core/WiiRoot.cpp +++ b/Source/Core/Core/WiiRoot.cpp @@ -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); diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp index 295e6f685c..5e36e13cfd 100644 --- a/Source/Core/Core/WiiUtils.cpp +++ b/Source/Core/Core/WiiUtils.cpp @@ -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 data = wad.GetContent(content.index); - if (es->ImportContentBegin(context, title_id, content.id) < 0 || - es->ImportContentData(context, 0, data.data(), static_cast(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(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& 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"( @@ -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(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(ret)); return UpdateResult::ImportFailed; } // Now download and install contents listed in the TMD. - const std::vector stored_contents = es->GetStoredContentsFromTMD(tmd.first); + const std::vector 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(ret)); @@ -612,8 +612,8 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_ return UpdateResult::DownloadFailed; } - if (es->ImportContentData(context, 0, data->data(), static_cast(data->size())) < 0 || - es->ImportContentEnd(context, 0) < 0) + if (es.ImportContentData(context, 0, data->data(), static_cast(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(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(); }); diff --git a/Source/Core/Core/WiiUtils.h b/Source/Core/Core/WiiUtils.h index 55a4c4e286..ae2d7c85e0 100644 --- a/Source/Core/Core/WiiUtils.h +++ b/Source/Core/Core/WiiUtils.h @@ -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 { diff --git a/Source/Core/DiscIO/VolumeVerifier.cpp b/Source/Core/DiscIO/VolumeVerifier.cpp index 855142143f..66e7d00dc4 100644 --- a/Source/Core/DiscIO/VolumeVerifier.cpp +++ b/Source/Core/DiscIO/VolumeVerifier.cpp @@ -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& 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& 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, diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index 2744095f66..663aadd341 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -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(