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_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);

View File

@ -10,9 +10,9 @@
#include <vector>
#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;
};

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),
[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

View File

@ -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<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;
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<u32>(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<FS::SeekMode>(mode));
return result.Succeeded() ? *result : FS::ConvertResult(result.Error());
}
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
// 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();
}

View File

@ -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,