ES: Use new filesystem interface for content handling

This commit is contained in:
Léo Lam 2018-05-06 18:31:06 +02:00
parent 3dafc66c36
commit 359a5dcb54
6 changed files with 20 additions and 58 deletions

View File

@ -343,12 +343,8 @@ void ES::DoState(PointerWrap& p)
p.Do(entry.m_opened); p.Do(entry.m_opened);
p.Do(entry.m_title_id); p.Do(entry.m_title_id);
p.Do(entry.m_content); p.Do(entry.m_content);
p.Do(entry.m_position); p.Do(entry.m_fd);
p.Do(entry.m_uid); 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); m_title_context.DoState(p);

View File

@ -10,9 +10,9 @@
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/File.h"
#include "Core/IOS/Device.h" #include "Core/IOS/Device.h"
#include "Core/IOS/ES/Formats.h" #include "Core/IOS/ES/Formats.h"
#include "Core/IOS/FS/FileSystem.h"
#include "Core/IOS/IOS.h" #include "Core/IOS/IOS.h"
#include "Core/IOS/IOSC.h" #include "Core/IOS/IOSC.h"
@ -339,14 +339,12 @@ private:
const IOS::ES::SharedContentMap& map) const; const IOS::ES::SharedContentMap& map) const;
std::string GetContentPath(u64 title_id, const IOS::ES::Content& content) const; std::string GetContentPath(u64 title_id, const IOS::ES::Content& content) const;
// TODO: reuse the FS code.
struct OpenedContent struct OpenedContent
{ {
bool m_opened = false; bool m_opened = false;
File::IOFile m_file; FS::Fd m_fd;
u64 m_title_id = 0; u64 m_title_id = 0;
IOS::ES::Content m_content; IOS::ES::Content m_content;
u32 m_position = 0;
u32 m_uid = 0; u32 m_uid = 0;
}; };

View File

@ -177,7 +177,7 @@ std::vector<IOS::ES::Content> ES::GetStoredContentsFromTMD(const IOS::ES::TMDRea
std::copy_if(contents.begin(), contents.end(), std::back_inserter(stored_contents), std::copy_if(contents.begin(), contents.end(), std::back_inserter(stored_contents),
[this, &tmd, &map](const IOS::ES::Content& content) { [this, &tmd, &map](const IOS::ES::Content& content) {
const std::string path = GetContentPath(tmd.GetTitleId(), content, map); 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; 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 const IOS::ES::SharedContentMap& content_map) const
{ {
if (content.IsShared()) if (content.IsShared())
{ return content_map.GetFilenameFromSHA1(content.sha1).value_or("");
const std::string path = content_map.GetFilenameFromSHA1(content.sha1).value_or(""); return Common::GetTitleContentPath(title_id) + StringFromFormat("/%08x.app", content.id);
return path.empty() ? "" : Common::RootUserPath(Common::FROM_SESSION_ROOT) + path;
}
return Common::GetTitleContentPath(title_id, Common::FROM_SESSION_ROOT) +
StringFromFormat("/%08x.app", content.id);
} }
std::string ES::GetContentPath(const u64 title_id, const IOS::ES::Content& content) const std::string ES::GetContentPath(const u64 title_id, const IOS::ES::Content& content) const

View File

@ -33,11 +33,13 @@ s32 ES::OpenContent(const IOS::ES::TMDReader& tmd, u16 content_index, u32 uid)
if (entry.m_opened) if (entry.m_opened)
continue; continue;
if (!entry.m_file.Open(GetContentPath(title_id, content), "rb")) auto file = m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, GetContentPath(title_id, content),
return FS_ENOENT; FS::Mode::Read);
if (!file)
return FS::ConvertResult(file.Error());
entry.m_opened = true; entry.m_opened = true;
entry.m_position = 0; entry.m_fd = file->Release();
entry.m_content = content; entry.m_content = content;
entry.m_title_id = title_id; entry.m_title_id = title_id;
entry.m_uid = uid; entry.m_uid = uid;
@ -97,21 +99,8 @@ s32 ES::ReadContent(u32 cfd, u8* buffer, u32 size, u32 uid)
if (!entry.m_opened) if (!entry.m_opened)
return IPC_EINVAL; return IPC_EINVAL;
// XXX: make this reuse the FS code... ES just does a simple "IOS_Read" call here const auto result = m_ios.GetFS()->ReadBytesFromFile(entry.m_fd, buffer, size);
// instead of all this duplicated filesystem logic. return result.Succeeded() ? *result : FS::ConvertResult(result.Error());
if (entry.m_position + size > entry.m_file.GetSize())
size = static_cast<u32>(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;
} }
IPCCommandResult ES::ReadContent(u32 uid, const IOCtlVRequest& request) IPCCommandResult ES::ReadContent(u32 uid, const IOCtlVRequest& request)
@ -137,6 +126,7 @@ ReturnCode ES::CloseContent(u32 cfd, u32 uid)
if (!entry.m_opened) if (!entry.m_opened)
return IPC_EINVAL; return IPC_EINVAL;
m_ios.GetFS()->Close(entry.m_fd);
entry = {}; entry = {};
INFO_LOG(IOS_ES, "CloseContent: CFD %u", cfd); INFO_LOG(IOS_ES, "CloseContent: CFD %u", cfd);
return IPC_SUCCESS; return IPC_SUCCESS;
@ -162,26 +152,8 @@ s32 ES::SeekContent(u32 cfd, u32 offset, SeekMode mode, u32 uid)
if (!entry.m_opened) if (!entry.m_opened)
return IPC_EINVAL; return IPC_EINVAL;
// XXX: This should be a simple IOS_Seek. const auto result = m_ios.GetFS()->SeekFile(entry.m_fd, offset, static_cast<FS::SeekMode>(mode));
switch (mode) return result.Succeeded() ? *result : FS::ConvertResult(result.Error());
{
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<u32>(entry.m_content.size) + offset;
break;
default:
return FS_EINVAL;
}
return entry.m_position;
} }
IPCCommandResult ES::SeekContent(u32 uid, const IOCtlVRequest& request) IPCCommandResult ES::SeekContent(u32 uid, const IOCtlVRequest& request)

View File

@ -310,10 +310,11 @@ Result<Metadata> HostFileSystem::GetMetadata(Uid, Gid, const std::string& path)
// Hack: if the path that is being accessed is within an installed title directory, get the // Hack: if the path that is being accessed is within an installed title directory, get the
// UID/GID from the installed title TMD. // UID/GID from the installed title TMD.
Kernel* ios = GetIOS();
u64 title_id; 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()) if (tmd.IsValid())
metadata.gid = tmd.GetGroupId(); metadata.gid = tmd.GetGroupId();
} }

View File

@ -74,7 +74,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread; static std::thread g_save_thread;
// Don't forget to increase this after doing changes on the savestate system // 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. // Maps savestate versions to Dolphin versions.
// Versions after 42 don't need to be added to this list, // Versions after 42 don't need to be added to this list,