diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index 4e2d0fa8d9..10af9fbd02 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -105,10 +105,10 @@ public: std::vector> GetSharedContents() const; // Title contents - s32 OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid); - ReturnCode CloseContent(u32 cfd, u32 uid); - s32 ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid); - s32 SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid); + s32 OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid, Ticks ticks = {}); + s32 CloseContent(u32 cfd, u32 uid, Ticks ticks = {}); + s32 ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid, Ticks ticks = {}); + s32 SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid, Ticks ticks = {}); // Title management enum class TicketImportType @@ -371,7 +371,7 @@ private: struct OpenedContent { bool m_opened = false; - FS::Fd m_fd; + u64 m_fd; u64 m_title_id = 0; ES::Content m_content; u32 m_uid = 0; diff --git a/Source/Core/Core/IOS/ES/TitleContents.cpp b/Source/Core/Core/IOS/ES/TitleContents.cpp index 547df70eaf..9a68475743 100644 --- a/Source/Core/Core/IOS/ES/TitleContents.cpp +++ b/Source/Core/Core/IOS/ES/TitleContents.cpp @@ -4,18 +4,17 @@ #include "Core/IOS/ES/ES.h" -#include #include #include "Common/Logging/Log.h" -#include "Common/MsgHandler.h" #include "Core/HW/Memmap.h" #include "Core/IOS/ES/Formats.h" +#include "Core/IOS/FS/FileSystemProxy.h" #include "Core/IOS/Uids.h" namespace IOS::HLE { -s32 ESDevice::OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid) +s32 ESDevice::OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid, Ticks ticks) { const u64 title_id = tmd.GetTitleId(); @@ -29,13 +28,13 @@ s32 ESDevice::OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid) if (entry.m_opened) continue; - auto file = m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, GetContentPath(title_id, content), - FS::Mode::Read); - if (!file) - return FS::ConvertResult(file.Error()); + const std::string path = GetContentPath(title_id, content, ticks); + s64 fd = m_ios.GetFSDevice()->Open(PID_KERNEL, PID_KERNEL, path, FS::Mode::Read, {}, ticks); + if (fd < 0) + return fd; entry.m_opened = true; - entry.m_fd = file->Release(); + entry.m_fd = fd; entry.m_content = content; entry.m_title_id = title_id; entry.m_uid = uid; @@ -50,43 +49,48 @@ s32 ESDevice::OpenContent(const ES::TMDReader& tmd, u16 content_index, u32 uid) IPCReply ESDevice::OpenContent(u32 uid, const IOCtlVRequest& request) { - if (!request.HasNumberOfValidVectors(3, 0) || request.in_vectors[0].size != sizeof(u64) || - request.in_vectors[1].size != sizeof(ES::TicketView) || - request.in_vectors[2].size != sizeof(u32)) - { - return IPCReply(ES_EINVAL); - } + return MakeIPCReply(IPC_OVERHEAD_TICKS, [&](Ticks ticks) -> s32 { + if (!request.HasNumberOfValidVectors(3, 0) || request.in_vectors[0].size != sizeof(u64) || + request.in_vectors[1].size != sizeof(ES::TicketView) || + request.in_vectors[2].size != sizeof(u32)) + { + return ES_EINVAL; + } - 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 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); - if (!tmd.IsValid()) - return IPCReply(FS_ENOENT); + const auto tmd = FindInstalledTMD(title_id, ticks); + if (!tmd.IsValid()) + return FS_ENOENT; - return IPCReply(OpenContent(tmd, content_index, uid)); + return OpenContent(tmd, content_index, uid, ticks); + }); } IPCReply ESDevice::OpenActiveTitleContent(u32 caller_uid, const IOCtlVRequest& request) { - if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u32)) - return IPCReply(ES_EINVAL); + return MakeIPCReply(IPC_OVERHEAD_TICKS, [&](Ticks ticks) -> s32 { + if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u32)) + return ES_EINVAL; - const u32 content_index = Memory::Read_U32(request.in_vectors[0].address); + const u32 content_index = Memory::Read_U32(request.in_vectors[0].address); - if (!m_title_context.active) - return IPCReply(ES_EINVAL); + if (!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()); - if (caller_uid != 0 && caller_uid != uid) - return IPCReply(ES_EACCES); + ES::UIDSys uid_map{m_ios.GetFSDevice()}; + const u32 uid = uid_map.GetOrInsertUIDForTitle(m_title_context.tmd.GetTitleId()); + ticks.Add(uid_map.GetTicks()); + if (caller_uid != 0 && caller_uid != uid) + return ES_EACCES; - return IPCReply(OpenContent(m_title_context.tmd, content_index, caller_uid)); + return OpenContent(m_title_context.tmd, content_index, caller_uid, ticks); + }); } -s32 ESDevice::ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid) +s32 ESDevice::ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid, Ticks ticks) { if (cfd >= m_content_table.size()) return ES_EINVAL; @@ -97,25 +101,26 @@ s32 ESDevice::ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid) if (!entry.m_opened) return IPC_EINVAL; - const auto result = m_ios.GetFS()->ReadBytesFromFile(entry.m_fd, buffer, size); - return result.Succeeded() ? *result : FS::ConvertResult(result.Error()); + return m_ios.GetFSDevice()->Read(entry.m_fd, buffer, size, {}, ticks); } IPCReply ESDevice::ReadContent(u32 uid, const IOCtlVRequest& request) { - if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != sizeof(u32)) - return IPCReply(ES_EINVAL); + return MakeIPCReply(IPC_OVERHEAD_TICKS, [&](Ticks ticks) -> s32 { + if (!request.HasNumberOfValidVectors(1, 1) || request.in_vectors[0].size != sizeof(u32)) + return ES_EINVAL; - const u32 cfd = Memory::Read_U32(request.in_vectors[0].address); - const u32 size = request.io_vectors[0].size; - const u32 addr = request.io_vectors[0].address; + const u32 cfd = Memory::Read_U32(request.in_vectors[0].address); + const u32 size = request.io_vectors[0].size; + const u32 addr = request.io_vectors[0].address; - INFO_LOG_FMT(IOS_ES, "ReadContent(uid={:#x}, cfd={}, size={}, addr={:08x})", uid, cfd, size, - addr); - return IPCReply(ReadContent(cfd, Memory::GetPointer(addr), size, uid)); + 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); + }); } -ReturnCode ESDevice::CloseContent(u32 cfd, u32 uid) +s32 ESDevice::CloseContent(u32 cfd, u32 uid, Ticks ticks) { if (cfd >= m_content_table.size()) return ES_EINVAL; @@ -126,7 +131,7 @@ ReturnCode ESDevice::CloseContent(u32 cfd, u32 uid) if (!entry.m_opened) return IPC_EINVAL; - m_ios.GetFS()->Close(entry.m_fd); + m_ios.GetFSDevice()->Close(entry.m_fd, ticks); entry = {}; INFO_LOG_FMT(IOS_ES, "CloseContent: CFD {}", cfd); return IPC_SUCCESS; @@ -134,14 +139,16 @@ ReturnCode ESDevice::CloseContent(u32 cfd, u32 uid) IPCReply ESDevice::CloseContent(u32 uid, const IOCtlVRequest& request) { - if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u32)) - return IPCReply(ES_EINVAL); + return MakeIPCReply(IPC_OVERHEAD_TICKS, [&](Ticks ticks) -> s32 { + if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != sizeof(u32)) + return ES_EINVAL; - const u32 cfd = Memory::Read_U32(request.in_vectors[0].address); - return IPCReply(CloseContent(cfd, uid)); + const u32 cfd = Memory::Read_U32(request.in_vectors[0].address); + return CloseContent(cfd, uid, ticks); + }); } -s32 ESDevice::SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid) +s32 ESDevice::SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid, Ticks ticks) { if (cfd >= m_content_table.size()) return ES_EINVAL; @@ -152,19 +159,20 @@ s32 ESDevice::SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid) if (!entry.m_opened) return IPC_EINVAL; - const auto result = m_ios.GetFS()->SeekFile(entry.m_fd, offset, static_cast(mode)); - return result.Succeeded() ? *result : FS::ConvertResult(result.Error()); + return m_ios.GetFSDevice()->Seek(entry.m_fd, offset, static_cast(mode), ticks); } IPCReply ESDevice::SeekContent(u32 uid, const IOCtlVRequest& request) { - if (!request.HasNumberOfValidVectors(3, 0)) - return IPCReply(ES_EINVAL); + return MakeIPCReply(IPC_OVERHEAD_TICKS, [&](Ticks ticks) -> s32 { + if (!request.HasNumberOfValidVectors(3, 0)) + return ES_EINVAL; - const u32 cfd = Memory::Read_U32(request.in_vectors[0].address); - const u32 offset = Memory::Read_U32(request.in_vectors[1].address); - const SeekMode mode = static_cast(Memory::Read_U32(request.in_vectors[2].address)); + 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 IPCReply(SeekContent(cfd, offset, mode, uid)); + return SeekContent(cfd, offset, mode, uid, ticks); + }); } } // namespace IOS::HLE diff --git a/Source/Core/Core/IOS/ES/TitleManagement.cpp b/Source/Core/Core/IOS/ES/TitleManagement.cpp index df9c6ec9c2..cf63efd8f6 100644 --- a/Source/Core/Core/IOS/ES/TitleManagement.cpp +++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp @@ -793,7 +793,7 @@ ReturnCode ESDevice::ExportContentEnd(Context& context, u32 content_fd) { if (!context.title_import_export.valid || !context.title_import_export.content.valid) return ES_EINVAL; - return CloseContent(content_fd, 0); + return static_cast(CloseContent(content_fd, 0)); } IPCReply ESDevice::ExportContentEnd(Context& context, const IOCtlVRequest& request)