diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 8dd469620c..783f40dc79 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -438,7 +438,6 @@ - diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 8163603ae9..37e0d70794 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -1385,9 +1385,6 @@ IOS\ES - - IOS\ES - IOS\FS diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 6023325681..22e398a6f6 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -19,7 +19,6 @@ #include "Core/ConfigManager.h" #include "Core/HW/Memmap.h" #include "Core/IOS/ES/Formats.h" -#include "Core/IOS/ES/NandUtils.h" #include "DiscIO/NANDContentLoader.h" namespace IOS @@ -35,26 +34,6 @@ static TitleContext s_title_context; // Title to launch after IOS has been reset and reloaded (similar to /sys/launch.sys). static u64 s_title_to_launch; -static void FinishAllStaleImports() -{ - const std::vector titles = IOS::ES::GetTitleImports(); - for (const u64& title_id : titles) - { - const IOS::ES::TMDReader tmd = IOS::ES::FindImportTMD(title_id); - if (!tmd.IsValid()) - { - File::DeleteDirRecursively(Common::GetImportTitlePath(title_id) + "/content"); - continue; - } - - FinishImport(tmd); - } - - const std::string import_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/import"; - File::DeleteDirRecursively(import_dir); - File::CreateDir(import_dir); -} - ES::ES(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { FinishAllStaleImports(); @@ -193,7 +172,7 @@ IPCCommandResult ES::SetUID(u32 uid, const IOCtlVRequest& request) return GetDefaultReply(ret); } - const auto tmd = IOS::ES::FindInstalledTMD(title_id); + const auto tmd = FindInstalledTMD(title_id); if (!tmd.IsValid()) return GetDefaultReply(FS_ENOENT); diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index b56ac57b69..a7f205ba78 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -97,6 +97,20 @@ public: s32 ipc_fd = -1; }; + IOS::ES::TMDReader FindImportTMD(u64 title_id) const; + IOS::ES::TMDReader FindInstalledTMD(u64 title_id) const; + + // Get installed titles (in /title) without checking for TMDs at all. + std::vector GetInstalledTitles() const; + // Get titles which are being imported (in /import) without checking for TMDs at all. + std::vector GetTitleImports() const; + // Get titles for which there is a ticket (in /ticket). + std::vector GetTitlesWithTickets() const; + + std::vector GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd) const; + u32 GetSharedContentsCount() const; + std::vector> GetSharedContents() const; + // Title management ReturnCode ImportTicket(const std::vector& ticket_bytes); ReturnCode ImportTmd(Context& context, const std::vector& tmd_bytes); @@ -284,6 +298,16 @@ private: bool LaunchPPCTitle(u64 title_id, bool skip_reload); static TitleContext& GetTitleContext(); + // Start a title import. + bool InitImport(u64 title_id); + // Clean up the import content directory and move it back to /title. + bool FinishImport(const IOS::ES::TMDReader& tmd); + // Write a TMD for a title in /import atomically. + bool WriteImportTMD(const IOS::ES::TMDReader& tmd); + // Finish stale imports and clear the import directory. + void FinishStaleImport(u64 title_id); + void FinishAllStaleImports(); + static const DiscIO::NANDContentLoader& AccessContentDevice(u64 title_id); u32 OpenTitleContent(u32 CFD, u64 TitleID, u16 Index); diff --git a/Source/Core/Core/IOS/ES/NandUtils.cpp b/Source/Core/Core/IOS/ES/NandUtils.cpp index 70c03bbb05..d0fb59745d 100644 --- a/Source/Core/Core/IOS/ES/NandUtils.cpp +++ b/Source/Core/Core/IOS/ES/NandUtils.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include #include @@ -15,14 +16,16 @@ #include "Common/Logging/Log.h" #include "Common/NandPaths.h" #include "Common/StringUtil.h" +#include "Core/IOS/ES/ES.h" #include "Core/IOS/ES/Formats.h" -#include "Core/IOS/ES/NandUtils.h" namespace IOS { -namespace ES +namespace HLE { -static TMDReader FindTMD(u64 title_id, const std::string& tmd_path) +namespace Device +{ +static IOS::ES::TMDReader FindTMD(u64 title_id, const std::string& tmd_path) { File::IOFile file(tmd_path, "rb"); if (!file) @@ -32,15 +35,15 @@ static TMDReader FindTMD(u64 title_id, const std::string& tmd_path) if (!file.ReadBytes(tmd_bytes.data(), tmd_bytes.size())) return {}; - return TMDReader{std::move(tmd_bytes)}; + return IOS::ES::TMDReader{std::move(tmd_bytes)}; } -TMDReader FindImportTMD(u64 title_id) +IOS::ES::TMDReader ES::FindImportTMD(u64 title_id) const { return FindTMD(title_id, Common::GetImportTitlePath(title_id) + "/content/title.tmd"); } -TMDReader FindInstalledTMD(u64 title_id) +IOS::ES::TMDReader ES::FindInstalledTMD(u64 title_id) const { return FindTMD(title_id, Common::GetTMDFileName(title_id, Common::FROM_SESSION_ROOT)); } @@ -88,17 +91,17 @@ static std::vector GetTitlesInTitleOrImport(const std::string& titles_dir) return title_ids; } -std::vector GetInstalledTitles() +std::vector ES::GetInstalledTitles() const { return GetTitlesInTitleOrImport(Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/title"); } -std::vector GetTitleImports() +std::vector ES::GetTitleImports() const { return GetTitlesInTitleOrImport(Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/import"); } -std::vector GetTitlesWithTickets() +std::vector ES::GetTitlesWithTickets() const { const std::string tickets_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/ticket"; if (!File::IsDirectory(tickets_dir)) @@ -138,15 +141,15 @@ std::vector GetTitlesWithTickets() return title_ids; } -std::vector GetStoredContentsFromTMD(const TMDReader& tmd) +std::vector ES::GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd) const { if (!tmd.IsValid()) return {}; const IOS::ES::SharedContentMap shared{Common::FROM_SESSION_ROOT}; - const std::vector contents = tmd.GetContents(); + const std::vector contents = tmd.GetContents(); - std::vector stored_contents; + std::vector stored_contents; std::copy_if(contents.begin(), contents.end(), std::back_inserter(stored_contents), [&tmd, &shared](const auto& content) { @@ -163,7 +166,7 @@ std::vector GetStoredContentsFromTMD(const TMDReader& tmd) return stored_contents; } -u32 GetSharedContentsCount() +u32 ES::GetSharedContentsCount() const { const std::string shared1_path = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/shared1"; const auto entries = File::ScanDirectoryTree(shared1_path, false); @@ -174,13 +177,13 @@ u32 GetSharedContentsCount() })); } -std::vector> GetSharedContents() +std::vector> ES::GetSharedContents() const { const IOS::ES::SharedContentMap map{Common::FROM_SESSION_ROOT}; return map.GetHashes(); } -bool InitImport(u64 title_id) +bool ES::InitImport(u64 title_id) { const std::string content_dir = Common::GetTitleContentPath(title_id, Common::FROM_SESSION_ROOT); const std::string data_dir = Common::GetTitleDataPath(title_id, Common::FROM_SESSION_ROOT); @@ -193,7 +196,7 @@ bool InitImport(u64 title_id) } } - UIDSys uid_sys{Common::FROM_CONFIGURED_ROOT}; + IOS::ES::UIDSys uid_sys{Common::FROM_CONFIGURED_ROOT}; uid_sys.GetOrInsertUIDForTitle(title_id); // IOS moves the title content directory to /import if the TMD exists during an import. @@ -211,7 +214,7 @@ bool InitImport(u64 title_id) return true; } -bool FinishImport(const IOS::ES::TMDReader& tmd) +bool ES::FinishImport(const IOS::ES::TMDReader& tmd) { const u64 title_id = tmd.GetTitleId(); const std::string import_content_dir = Common::GetImportTitlePath(title_id) + "/content"; @@ -244,7 +247,7 @@ bool FinishImport(const IOS::ES::TMDReader& tmd) return true; } -bool WriteImportTMD(const IOS::ES::TMDReader& tmd) +bool ES::WriteImportTMD(const IOS::ES::TMDReader& tmd) { const std::string tmd_path = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/tmp/title.tmd"; File::CreateFullPath(tmd_path); @@ -258,5 +261,26 @@ bool WriteImportTMD(const IOS::ES::TMDReader& tmd) const std::string dest = Common::GetImportTitlePath(tmd.GetTitleId()) + "/content/title.tmd"; return File::Rename(tmd_path, dest); } -} // namespace ES + +void ES::FinishStaleImport(u64 title_id) +{ + const auto import_tmd = FindImportTMD(title_id); + if (!import_tmd.IsValid()) + File::DeleteDirRecursively(Common::GetImportTitlePath(title_id) + "/content"); + else + FinishImport(import_tmd); +} + +void ES::FinishAllStaleImports() +{ + const std::vector titles = GetTitleImports(); + for (const u64& title_id : titles) + FinishStaleImport(title_id); + + const std::string import_dir = Common::RootUserPath(Common::FROM_SESSION_ROOT) + "/import"; + File::DeleteDirRecursively(import_dir); + File::CreateDir(import_dir); +} +} // namespace Device +} // namespace HLE } // namespace IOS diff --git a/Source/Core/Core/IOS/ES/NandUtils.h b/Source/Core/Core/IOS/ES/NandUtils.h deleted file mode 100644 index 3135ebc490..0000000000 --- a/Source/Core/Core/IOS/ES/NandUtils.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include - -#include "Common/CommonTypes.h" - -namespace IOS -{ -namespace ES -{ -struct Content; -class TMDReader; - -TMDReader FindImportTMD(u64 title_id); -TMDReader FindInstalledTMD(u64 title_id); - -// Get installed titles (in /title) without checking for TMDs at all. -std::vector GetInstalledTitles(); -// Get titles which are being imported (in /import) without checking for TMDs at all. -std::vector GetTitleImports(); -// Get titles for which there is a ticket (in /ticket). -std::vector GetTitlesWithTickets(); - -std::vector GetStoredContentsFromTMD(const TMDReader& tmd); - -u32 GetSharedContentsCount(); -std::vector> GetSharedContents(); - -// Start a title import. -bool InitImport(u64 title_id); -// Clean up the import content directory and move it back to /title. -bool FinishImport(const IOS::ES::TMDReader& tmd); -// Write a TMD for a title in /import atomically. -bool WriteImportTMD(const IOS::ES::TMDReader& tmd); -} // namespace ES -} // namespace IOS diff --git a/Source/Core/Core/IOS/ES/TitleInformation.cpp b/Source/Core/Core/IOS/ES/TitleInformation.cpp index 085174dbd5..51c2dabc18 100644 --- a/Source/Core/Core/IOS/ES/TitleInformation.cpp +++ b/Source/Core/Core/IOS/ES/TitleInformation.cpp @@ -15,7 +15,6 @@ #include "Common/StringUtil.h" #include "Core/HW/Memmap.h" #include "Core/IOS/ES/Formats.h" -#include "Core/IOS/ES/NandUtils.h" #include "DiscIO/NANDContentLoader.h" namespace IOS @@ -32,7 +31,7 @@ IPCCommandResult ES::GetStoredContentsCount(const IOS::ES::TMDReader& tmd, if (request.io_vectors[0].size != sizeof(u32) || !tmd.IsValid()) return GetDefaultReply(ES_EINVAL); - const u16 num_contents = static_cast(IOS::ES::GetStoredContentsFromTMD(tmd).size()); + const u16 num_contents = static_cast(GetStoredContentsFromTMD(tmd).size()); Memory::Write_U32(num_contents, request.io_vectors[0].address); INFO_LOG(IOS_ES, "GetStoredContentsCount (0x%x): %u content(s) for %016" PRIx64, request.request, @@ -53,7 +52,7 @@ IPCCommandResult ES::GetStoredContents(const IOS::ES::TMDReader& tmd, const IOCt return GetDefaultReply(ES_EINVAL); } - const auto contents = IOS::ES::GetStoredContentsFromTMD(tmd); + const auto contents = 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)); @@ -67,7 +66,7 @@ IPCCommandResult ES::GetStoredContentsCount(const IOCtlVRequest& request) return GetDefaultReply(ES_EINVAL); const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); - const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id); + const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id); if (!tmd.IsValid()) return GetDefaultReply(FS_ENOENT); return GetStoredContentsCount(tmd, request); @@ -79,7 +78,7 @@ IPCCommandResult ES::GetStoredContents(const IOCtlVRequest& request) return GetDefaultReply(ES_EINVAL); const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); - const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id); + const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id); if (!tmd.IsValid()) return GetDefaultReply(FS_ENOENT); return GetStoredContents(tmd, request); @@ -131,14 +130,14 @@ IPCCommandResult ES::GetTitles(const std::vector& titles, const IOCtlVReque IPCCommandResult ES::GetTitleCount(const IOCtlVRequest& request) { - const std::vector titles = IOS::ES::GetInstalledTitles(); + const std::vector titles = GetInstalledTitles(); INFO_LOG(IOS_ES, "GetTitleCount: %zu titles", titles.size()); return GetTitleCount(titles, request); } IPCCommandResult ES::GetTitles(const IOCtlVRequest& request) { - return GetTitles(IOS::ES::GetInstalledTitles(), request); + return GetTitles(GetInstalledTitles(), request); } IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request) @@ -147,7 +146,7 @@ IPCCommandResult ES::GetStoredTMDSize(const IOCtlVRequest& request) return GetDefaultReply(ES_EINVAL); const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); - const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id); + const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id); if (!tmd.IsValid()) return GetDefaultReply(FS_ENOENT); @@ -165,7 +164,7 @@ IPCCommandResult ES::GetStoredTMD(const IOCtlVRequest& request) return GetDefaultReply(ES_EINVAL); const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); - const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id); + const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id); if (!tmd.IsValid()) return GetDefaultReply(FS_ENOENT); @@ -184,14 +183,14 @@ IPCCommandResult ES::GetStoredTMD(const IOCtlVRequest& request) IPCCommandResult ES::GetOwnedTitleCount(const IOCtlVRequest& request) { - const std::vector titles = IOS::ES::GetTitlesWithTickets(); + const std::vector titles = GetTitlesWithTickets(); INFO_LOG(IOS_ES, "GetOwnedTitleCount: %zu titles", titles.size()); return GetTitleCount(titles, request); } IPCCommandResult ES::GetOwnedTitles(const IOCtlVRequest& request) { - return GetTitles(IOS::ES::GetTitlesWithTickets(), request); + return GetTitles(GetTitlesWithTickets(), request); } IPCCommandResult ES::GetBoot2Version(const IOCtlVRequest& request) @@ -211,7 +210,7 @@ IPCCommandResult ES::GetSharedContentsCount(const IOCtlVRequest& request) const if (!request.HasNumberOfValidVectors(0, 1) || request.io_vectors[0].size != sizeof(u32)) return GetDefaultReply(ES_EINVAL); - const u32 count = IOS::ES::GetSharedContentsCount(); + const u32 count = GetSharedContentsCount(); Memory::Write_U32(count, request.io_vectors[0].address); INFO_LOG(IOS_ES, "GetSharedContentsCount: %u contents", count); @@ -227,7 +226,7 @@ IPCCommandResult ES::GetSharedContents(const IOCtlVRequest& request) const if (request.io_vectors[0].size != 20 * max_count) return GetDefaultReply(ES_EINVAL); - const std::vector> hashes = IOS::ES::GetSharedContents(); + const std::vector> hashes = 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 73a32bc581..01d0627a89 100644 --- a/Source/Core/Core/IOS/ES/TitleManagement.cpp +++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp @@ -20,7 +20,6 @@ #include "Common/StringUtil.h" #include "Core/HW/Memmap.h" #include "Core/IOS/ES/Formats.h" -#include "Core/IOS/ES/NandUtils.h" #include "Core/ec_wii.h" #include "DiscIO/NANDContentLoader.h" @@ -96,7 +95,7 @@ ReturnCode ES::ImportTmd(Context& context, const std::vector& tmd_bytes) if (!context.title_import.tmd.IsValid()) return ES_EINVAL; - if (!IOS::ES::InitImport(context.title_import.tmd.GetTitleId())) + if (!InitImport(context.title_import.tmd.GetTitleId())) return ES_EIO; return IPC_SUCCESS; @@ -115,15 +114,6 @@ IPCCommandResult ES::ImportTmd(Context& context, const IOCtlVRequest& request) return GetDefaultReply(ImportTmd(context, tmd)); } -static void CleanUpStaleImport(const u64 title_id) -{ - const auto import_tmd = IOS::ES::FindImportTMD(title_id); - if (!import_tmd.IsValid()) - File::DeleteDirRecursively(Common::GetImportTitlePath(title_id) + "/content"); - else - IOS::ES::FinishImport(import_tmd); -} - ReturnCode ES::ImportTitleInit(Context& context, const std::vector& tmd_bytes) { INFO_LOG(IOS_ES, "ImportTitleInit"); @@ -135,9 +125,9 @@ ReturnCode ES::ImportTitleInit(Context& context, const std::vector& tmd_byte } // Finish a previous import (if it exists). - CleanUpStaleImport(context.title_import.tmd.GetTitleId()); + FinishStaleImport(context.title_import.tmd.GetTitleId()); - if (!IOS::ES::InitImport(context.title_import.tmd.GetTitleId())) + if (!InitImport(context.title_import.tmd.GetTitleId())) return ES_EIO; // TODO: check and use the other vectors. @@ -340,7 +330,7 @@ ReturnCode ES::ImportTitleCancel(Context& context) if (!context.title_import.tmd.IsValid()) return ES_EINVAL; - CleanUpStaleImport(context.title_import.tmd.GetTitleId()); + FinishStaleImport(context.title_import.tmd.GetTitleId()); INFO_LOG(IOS_ES, "ImportTitleCancel: title %016" PRIx64, context.title_import.tmd.GetTitleId()); context.title_import.tmd.SetBytes({}); @@ -467,7 +457,7 @@ ReturnCode ES::DeleteContent(u64 title_id, u32 content_id) const if (!CanDeleteTitle(title_id)) return ES_EINVAL; - const auto tmd = IOS::ES::FindInstalledTMD(title_id); + const auto tmd = FindInstalledTMD(title_id); if (!tmd.IsValid()) return FS_ENOENT; @@ -501,7 +491,7 @@ ReturnCode ES::ExportTitleInit(Context& context, u64 title_id, u8* tmd_bytes, u3 if (context.title_export.valid) return ES_EINVAL; - const auto tmd = IOS::ES::FindInstalledTMD(title_id); + const auto tmd = FindInstalledTMD(title_id); if (!tmd.IsValid()) return FS_ENOENT; @@ -686,12 +676,12 @@ ReturnCode ES::DeleteSharedContent(const std::array& sha1) const return ES_EINVAL; // Check whether the shared content is used by a system title. - const std::vector titles = IOS::ES::GetInstalledTitles(); - const bool is_used_by_system_title = std::any_of(titles.begin(), titles.end(), [&sha1](u64 id) { + const std::vector titles = GetInstalledTitles(); + const bool is_used_by_system_title = std::any_of(titles.begin(), titles.end(), [&](u64 id) { if (!IOS::ES::IsTitleType(id, IOS::ES::TitleType::System)) return false; - const auto tmd = IOS::ES::FindInstalledTMD(id); + const auto tmd = FindInstalledTMD(id); if (!tmd.IsValid()) return true; diff --git a/Source/Core/Core/IOS/ES/Views.cpp b/Source/Core/Core/IOS/ES/Views.cpp index 9d1369ca79..ead7a5b7e4 100644 --- a/Source/Core/Core/IOS/ES/Views.cpp +++ b/Source/Core/Core/IOS/ES/Views.cpp @@ -16,7 +16,6 @@ #include "Core/Core.h" #include "Core/HW/Memmap.h" #include "Core/IOS/ES/Formats.h" -#include "Core/IOS/ES/NandUtils.h" #include "DiscIO/NANDContentLoader.h" namespace IOS @@ -206,7 +205,7 @@ IPCCommandResult ES::GetTMDViewSize(const IOCtlVRequest& request) u64 TitleID = Memory::Read_U64(request.in_vectors[0].address); - const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(TitleID); + const IOS::ES::TMDReader tmd = FindInstalledTMD(TitleID); if (!tmd.IsValid()) return GetDefaultReply(FS_ENOENT); @@ -229,7 +228,7 @@ IPCCommandResult ES::GetTMDViews(const IOCtlVRequest& request) } const u64 title_id = Memory::Read_U64(request.in_vectors[0].address); - const IOS::ES::TMDReader tmd = IOS::ES::FindInstalledTMD(title_id); + const IOS::ES::TMDReader tmd = FindInstalledTMD(title_id); if (!tmd.IsValid()) return GetDefaultReply(FS_ENOENT);