From 359a5dcb54877e95c2ce23dc56493de312aefd25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 6 May 2018 18:31:06 +0200 Subject: [PATCH] ES: Use new filesystem interface for content handling --- Source/Core/Core/IOS/ES/ES.cpp | 6 +-- Source/Core/Core/IOS/ES/ES.h | 6 +-- Source/Core/Core/IOS/ES/NandUtils.cpp | 11 ++--- Source/Core/Core/IOS/ES/TitleContents.cpp | 48 +++++----------------- Source/Core/Core/IOS/FS/HostBackend/FS.cpp | 5 ++- Source/Core/Core/State.cpp | 2 +- 6 files changed, 20 insertions(+), 58 deletions(-) diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index cf0e18c494..5c931e0679 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -343,12 +343,8 @@ void ES::DoState(PointerWrap& p) p.Do(entry.m_opened); p.Do(entry.m_title_id); p.Do(entry.m_content); - p.Do(entry.m_position); + p.Do(entry.m_fd); p.Do(entry.m_uid); - if (entry.m_opened) - entry.m_opened = entry.m_file.Open(GetContentPath(entry.m_title_id, entry.m_content), "rb"); - else - entry.m_file.Close(); } m_title_context.DoState(p); diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index e345511ee9..852f42a0fe 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -10,9 +10,9 @@ #include #include "Common/CommonTypes.h" -#include "Common/File.h" #include "Core/IOS/Device.h" #include "Core/IOS/ES/Formats.h" +#include "Core/IOS/FS/FileSystem.h" #include "Core/IOS/IOS.h" #include "Core/IOS/IOSC.h" @@ -339,14 +339,12 @@ private: const IOS::ES::SharedContentMap& map) const; std::string GetContentPath(u64 title_id, const IOS::ES::Content& content) const; - // TODO: reuse the FS code. struct OpenedContent { bool m_opened = false; - File::IOFile m_file; + FS::Fd m_fd; u64 m_title_id = 0; IOS::ES::Content m_content; - u32 m_position = 0; u32 m_uid = 0; }; diff --git a/Source/Core/Core/IOS/ES/NandUtils.cpp b/Source/Core/Core/IOS/ES/NandUtils.cpp index cf378ca902..dd6bd2cac1 100644 --- a/Source/Core/Core/IOS/ES/NandUtils.cpp +++ b/Source/Core/Core/IOS/ES/NandUtils.cpp @@ -177,7 +177,7 @@ std::vector ES::GetStoredContentsFromTMD(const IOS::ES::TMDRea std::copy_if(contents.begin(), contents.end(), std::back_inserter(stored_contents), [this, &tmd, &map](const IOS::ES::Content& content) { const std::string path = GetContentPath(tmd.GetTitleId(), content, map); - return !path.empty() && File::Exists(path); + return !path.empty() && m_ios.GetFS()->GetMetadata(0, 0, path).Succeeded(); }); return stored_contents; @@ -307,13 +307,8 @@ std::string ES::GetContentPath(const u64 title_id, const IOS::ES::Content& conte const IOS::ES::SharedContentMap& content_map) const { if (content.IsShared()) - { - const std::string path = content_map.GetFilenameFromSHA1(content.sha1).value_or(""); - return path.empty() ? "" : Common::RootUserPath(Common::FROM_SESSION_ROOT) + path; - } - - return Common::GetTitleContentPath(title_id, Common::FROM_SESSION_ROOT) + - StringFromFormat("/%08x.app", content.id); + return content_map.GetFilenameFromSHA1(content.sha1).value_or(""); + return Common::GetTitleContentPath(title_id) + StringFromFormat("/%08x.app", content.id); } std::string ES::GetContentPath(const u64 title_id, const IOS::ES::Content& content) const diff --git a/Source/Core/Core/IOS/ES/TitleContents.cpp b/Source/Core/Core/IOS/ES/TitleContents.cpp index 8ea71f3bf4..0570ccb167 100644 --- a/Source/Core/Core/IOS/ES/TitleContents.cpp +++ b/Source/Core/Core/IOS/ES/TitleContents.cpp @@ -33,11 +33,13 @@ s32 ES::OpenContent(const IOS::ES::TMDReader& tmd, u16 content_index, u32 uid) if (entry.m_opened) continue; - if (!entry.m_file.Open(GetContentPath(title_id, content), "rb")) - return FS_ENOENT; + auto file = m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, GetContentPath(title_id, content), + FS::Mode::Read); + if (!file) + return FS::ConvertResult(file.Error()); entry.m_opened = true; - entry.m_position = 0; + entry.m_fd = file->Release(); entry.m_content = content; entry.m_title_id = title_id; entry.m_uid = uid; @@ -97,21 +99,8 @@ s32 ES::ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid) if (!entry.m_opened) return IPC_EINVAL; - // XXX: make this reuse the FS code... ES just does a simple "IOS_Read" call here - // instead of all this duplicated filesystem logic. - - if (entry.m_position + size > entry.m_file.GetSize()) - size = static_cast(entry.m_file.GetSize()) - entry.m_position; - - entry.m_file.Seek(entry.m_position, SEEK_SET); - if (!entry.m_file.ReadBytes(buffer, size)) - { - ERROR_LOG(IOS_ES, "ES: failed to read %u bytes from %u!", size, entry.m_position); - return ES_SHORT_READ; - } - - entry.m_position += size; - return size; + const auto result = m_ios.GetFS()->ReadBytesFromFile(entry.m_fd, buffer, size); + return result.Succeeded() ? *result : FS::ConvertResult(result.Error()); } IPCCommandResult ES::ReadContent(u32 uid, const IOCtlVRequest& request) @@ -137,6 +126,7 @@ ReturnCode ES::CloseContent(u32 cfd, u32 uid) if (!entry.m_opened) return IPC_EINVAL; + m_ios.GetFS()->Close(entry.m_fd); entry = {}; INFO_LOG(IOS_ES, "CloseContent: CFD %u", cfd); return IPC_SUCCESS; @@ -162,26 +152,8 @@ s32 ES::SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid) if (!entry.m_opened) return IPC_EINVAL; - // XXX: This should be a simple IOS_Seek. - switch (mode) - { - case SeekMode::IOS_SEEK_SET: - entry.m_position = offset; - break; - - case SeekMode::IOS_SEEK_CUR: - entry.m_position += offset; - break; - - case SeekMode::IOS_SEEK_END: - entry.m_position = static_cast(entry.m_content.size) + offset; - break; - - default: - return FS_EINVAL; - } - - return entry.m_position; + const auto result = m_ios.GetFS()->SeekFile(entry.m_fd, offset, static_cast(mode)); + return result.Succeeded() ? *result : FS::ConvertResult(result.Error()); } IPCCommandResult ES::SeekContent(u32 uid, const IOCtlVRequest& request) diff --git a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp index 1e512a623a..112eee0e66 100644 --- a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp +++ b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp @@ -310,10 +310,11 @@ Result HostFileSystem::GetMetadata(Uid, Gid, const std::string& path) // Hack: if the path that is being accessed is within an installed title directory, get the // UID/GID from the installed title TMD. + Kernel* ios = GetIOS(); u64 title_id; - if (IsTitlePath(file_name, Common::FROM_SESSION_ROOT, &title_id)) + if (ios && IsTitlePath(file_name, Common::FROM_SESSION_ROOT, &title_id)) { - IOS::ES::TMDReader tmd = GetIOS()->GetES()->FindInstalledTMD(title_id); + IOS::ES::TMDReader tmd = ios->GetES()->FindInstalledTMD(title_id); if (tmd.IsValid()) metadata.gid = tmd.GetGroupId(); } diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 925039f5da..6f1a8817fc 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -74,7 +74,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 96; // Last changed in PR 6565 +static const u32 STATE_VERSION = 97; // Last changed in PR 6772 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list,