ES: Use new filesystem interface for content handling
This commit is contained in:
parent
3dafc66c36
commit
359a5dcb54
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue