Permalink
Browse files

FS: Add a struct for modes

As suggested here: https://dolp.in/pr7059#pullrequestreview-125401778

More descriptive than having a std::tuple of FS::Mode, and lets us
give names to known triplets of modes (like in ES). Functions that
only forward mode arguments are slightly less verbose now too.
  • Loading branch information...
leoetlino committed Jun 3, 2018
1 parent d1a8661 commit 6b9aef7042468b5a63f7a2595b4118a53cf2eebd
@@ -478,8 +478,8 @@ void UpdateStateFlags(std::function<void(StateFlags*)> update_function)
const std::string file_path = Common::GetTitleDataPath(Titles::SYSTEM_MENU) + "/" WII_STATE;
const auto fs = IOS::HLE::GetIOS()->GetFS();
constexpr IOS::HLE::FS::Mode rw_mode = IOS::HLE::FS::Mode::ReadWrite;
const auto file = fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, file_path, rw_mode,
rw_mode, rw_mode);
const auto file = fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, file_path,
{rw_mode, rw_mode, rw_mode});
if (!file)
return;
@@ -269,7 +269,7 @@ bool CBoot::SetupWiiMemory()
constexpr IOS::HLE::FS::Mode rw_mode = IOS::HLE::FS::Mode::ReadWrite;
const auto settings_file = fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID,
settings_file_path, rw_mode, rw_mode, rw_mode);
settings_file_path, {rw_mode, rw_mode, rw_mode});
if (!settings_file || !settings_file->Write(gen.GetBytes().data(), gen.GetBytes().size()))
{
PanicAlertT("SetupWiiMemory: Can't create setting.txt file");
@@ -343,7 +343,7 @@ static void WriteEmptyPlayRecord()
const auto fs = IOS::HLE::GetIOS()->GetFS();
constexpr IOS::HLE::FS::Mode rw_mode = IOS::HLE::FS::Mode::ReadWrite;
const auto playrec_file = fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, file_path,
rw_mode, rw_mode, rw_mode);
{rw_mode, rw_mode, rw_mode});
if (!playrec_file)
return;
std::vector<u8> empty_record(0x80);
@@ -205,9 +205,8 @@ class NandStorage final : public Storage
return false;
const std::string banner_file_path = m_data_dir + "/banner.bin";
const std::tuple<FS::Mode, FS::Mode, FS::Mode> modes = GetFsMode(header.permissions);
const auto file = m_fs->CreateAndOpenFile(*m_uid, *m_gid, banner_file_path, std::get<0>(modes),
std::get<1>(modes), std::get<2>(modes));
const FS::Modes modes = GetFsMode(header.permissions);
const auto file = m_fs->CreateAndOpenFile(*m_uid, *m_gid, banner_file_path, modes);
return file && file->Write(header.banner, header.banner_size);
}
@@ -220,11 +219,10 @@ class NandStorage final : public Storage
for (const SaveFile& file : files)
{
const std::tuple<FS::Mode, FS::Mode, FS::Mode> modes = GetFsMode(file.mode);
const FS::Modes modes = GetFsMode(file.mode);
if (file.type == SaveFile::Type::File)
{
const auto raw_file = m_fs->CreateAndOpenFile(*m_uid, *m_gid, file.path, std::get<0>(modes),
std::get<1>(modes), std::get<2>(modes));
const auto raw_file = m_fs->CreateAndOpenFile(*m_uid, *m_gid, file.path, modes);
const std::optional<std::vector<u8>>& data = *file.data;
if (!data || !raw_file || !raw_file->Write(data->data(), data->size()))
return false;
@@ -235,9 +233,7 @@ class NandStorage final : public Storage
if (!meta || meta->is_file)
return false;
const FS::ResultCode result =
m_fs->CreateDirectory(*m_uid, *m_gid, file.path, 0, std::get<0>(modes),
std::get<1>(modes), std::get<2>(modes));
const FS::ResultCode result = m_fs->CreateDirectory(*m_uid, *m_gid, file.path, 0, modes);
if (result != FS::ResultCode::Success)
return false;
}
@@ -266,7 +262,7 @@ class NandStorage final : public Storage
return;
SaveFile save_file;
save_file.mode = GetBinMode(*metadata);
save_file.mode = GetBinMode(metadata->modes);
save_file.attributes = 0;
save_file.type = metadata->is_file ? SaveFile::Type::File : SaveFile::Type::Directory;
save_file.path = path;
@@ -298,20 +294,20 @@ class NandStorage final : public Storage
m_gid = metadata->gid;
}
static constexpr std::tuple<FS::Mode, FS::Mode, FS::Mode> GetFsMode(u8 bin_mode)
static constexpr FS::Modes GetFsMode(u8 bin_mode)
{
return {FS::Mode(bin_mode >> 4 & 3), FS::Mode(bin_mode >> 2 & 3), FS::Mode(bin_mode >> 0 & 3)};
}
static constexpr u8 GetBinMode(const FS::Metadata& meta)
static constexpr u8 GetBinMode(const FS::Modes& modes)
{
return u8(meta.owner_mode) << 4 | u8(meta.group_mode) << 2 | u8(meta.other_mode) << 0;
return u8(modes.owner) << 4 | u8(modes.group) << 2 | u8(modes.other) << 0;
}
u8 GetBinMode(const std::string& path) const
{
if (const FS::Result<FS::Metadata> meta = m_fs->GetMetadata(*m_uid, *m_gid, path))
return GetBinMode(*meta);
return GetBinMode(meta->modes);
return 0;
}
@@ -39,24 +39,22 @@ struct DirectoryToCreate
{
const char* path;
FS::FileAttribute attribute;
FS::Mode owner_mode;
FS::Mode group_mode;
FS::Mode other_mode;
FS::Modes modes;
FS::Uid uid = PID_KERNEL;
FS::Gid gid = PID_KERNEL;
};
constexpr FS::Modes public_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::ReadWrite};
constexpr std::array<DirectoryToCreate, 9> s_directories_to_create = {{
{"/sys", 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None},
{"/ticket", 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None},
{"/title", 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::Read},
{"/shared1", 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None},
{"/shared2", 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::ReadWrite},
{"/tmp", 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::ReadWrite},
{"/import", 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None},
{"/meta", 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::ReadWrite, SYSMENU_UID,
SYSMENU_GID},
{"/wfs", 0, FS::Mode::ReadWrite, FS::Mode::None, FS::Mode::None, PID_UNKNOWN, PID_UNKNOWN},
{"/sys", 0, {FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None}},
{"/ticket", 0, {FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None}},
{"/title", 0, {FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::Read}},
{"/shared1", 0, {FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None}},
{"/shared2", 0, public_modes},
{"/tmp", 0, public_modes},
{"/import", 0, {FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None}},
{"/meta", 0, public_modes, SYSMENU_UID, SYSMENU_GID},
{"/wfs", 0, {FS::Mode::ReadWrite, FS::Mode::None, FS::Mode::None}, PID_UNKNOWN, PID_UNKNOWN},
}};
ES::ES(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
@@ -66,14 +64,13 @@ ES::ES(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
// Note: ES sets its own UID and GID to 0/0 at boot, so all filesystem accesses in ES are done
// as UID 0 even though its PID is 1.
const auto result = m_ios.GetFS()->CreateDirectory(PID_KERNEL, PID_KERNEL, directory.path,
directory.attribute, directory.owner_mode,
directory.group_mode, directory.other_mode);
directory.attribute, directory.modes);
if (result != FS::ResultCode::Success && result != FS::ResultCode::AlreadyExists)
ERROR_LOG(IOS_ES, "Failed to create %s: error %d", directory.path, FS::ConvertResult(result));
// Now update the UID/GID and other attributes.
m_ios.GetFS()->SetMetadata(0, directory.path, directory.uid, directory.gid, directory.attribute,
directory.owner_mode, directory.group_mode, directory.other_mode);
directory.modes);
}
FinishAllStaleImports();
@@ -623,9 +620,9 @@ static s32 WriteTmdForDiVerify(FS::FileSystem* fs, const IOS::ES::TMDReader& tmd
{
const std::string temp_path = "/tmp/title.tmd";
fs->Delete(PID_KERNEL, PID_KERNEL, temp_path);
constexpr FS::Modes internal_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None};
{
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::None);
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, internal_modes);
if (!file)
return FS::ConvertResult(file.Error());
if (!file->Write(tmd.GetBytes().data(), tmd.GetBytes().size()))
@@ -634,13 +631,12 @@ static s32 WriteTmdForDiVerify(FS::FileSystem* fs, const IOS::ES::TMDReader& tmd
const std::string tmd_dir = Common::GetTitleContentPath(tmd.GetTitleId());
const std::string tmd_path = Common::GetTMDFileName(tmd.GetTitleId());
const auto result = fs->CreateFullPath(PID_KERNEL, PID_KERNEL, tmd_path, 0, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::Read);
constexpr FS::Modes parent_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::Read};
const auto result = fs->CreateFullPath(PID_KERNEL, PID_KERNEL, tmd_path, 0, parent_modes);
if (result != FS::ResultCode::Success)
return FS::ConvertResult(result);
fs->SetMetadata(PID_KERNEL, tmd_dir, PID_KERNEL, PID_KERNEL, 0, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::None);
fs->SetMetadata(PID_KERNEL, tmd_dir, PID_KERNEL, PID_KERNEL, 0, internal_modes);
return FS::ConvertResult(fs->Rename(PID_KERNEL, PID_KERNEL, temp_path, tmd_path));
}
@@ -678,10 +674,10 @@ s32 ES::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& tic
const std::string data_dir = Common::GetTitleDataPath(tmd.GetTitleId());
// Might already exist, so we only need to check whether the second operation succeeded.
fs->CreateDirectory(PID_KERNEL, PID_KERNEL, data_dir, 0, FS::Mode::ReadWrite, FS::Mode::None,
FS::Mode::None);
return FS::ConvertResult(fs->SetMetadata(0, data_dir, m_ios.GetUidForPPC(), m_ios.GetGidForPPC(),
0, FS::Mode::ReadWrite, FS::Mode::None, FS::Mode::None));
constexpr FS::Modes data_dir_modes{FS::Mode::ReadWrite, FS::Mode::None, FS::Mode::None};
fs->CreateDirectory(PID_KERNEL, PID_KERNEL, data_dir, 0, data_dir_modes);
return FS::ConvertResult(
fs->SetMetadata(0, data_dir, m_ios.GetUidForPPC(), m_ios.GetGidForPPC(), 0, data_dir_modes));
}
ReturnCode ES::CheckStreamKeyPermissions(const u32 uid, const u8* ticket_view,
@@ -877,8 +873,8 @@ ReturnCode ES::WriteNewCertToStore(const IOS::ES::CertReader& cert)
// Otherwise, write the new cert at the end of the store.
const auto store_file =
m_ios.GetFS()->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, CERT_STORE_PATH, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::Read);
m_ios.GetFS()->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, CERT_STORE_PATH,
{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::Read});
if (!store_file || !store_file->Seek(0, FS::SeekMode::End) ||
!store_file->Write(cert.GetBytes().data(), cert.GetBytes().size()))
{
@@ -591,9 +591,9 @@ bool SharedContentMap::WriteEntries() const
const std::string temp_path = "/tmp/content.map";
// Atomically write the new content map.
{
const auto file =
m_fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, HLE::FS::Mode::ReadWrite,
HLE::FS::Mode::ReadWrite, HLE::FS::Mode::None);
constexpr HLE::FS::Modes modes{HLE::FS::Mode::ReadWrite, HLE::FS::Mode::ReadWrite,
HLE::FS::Mode::None};
const auto file = m_fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, modes);
if (!file || !file->Write(m_entries.data(), m_entries.size()))
return false;
}
@@ -665,9 +665,9 @@ u32 UIDSys::GetOrInsertUIDForTitle(const u64 title_id)
const u64 swapped_title_id = Common::swap64(title_id);
const u32 swapped_uid = Common::swap32(uid);
const auto file =
m_fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, UID_MAP_PATH, HLE::FS::Mode::ReadWrite,
HLE::FS::Mode::ReadWrite, HLE::FS::Mode::None);
constexpr HLE::FS::Modes modes{HLE::FS::Mode::ReadWrite, HLE::FS::Mode::ReadWrite,
HLE::FS::Mode::None};
const auto file = m_fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, UID_MAP_PATH, modes);
if (!file || !file->Seek(0, HLE::FS::SeekMode::End) || !file->Write(&swapped_title_id, 1) ||
!file->Write(&swapped_uid, 1))
{
@@ -222,15 +222,19 @@ static bool DeleteDirectoriesIfEmpty(FS::FileSystem* fs, const std::string& path
return true;
}
constexpr FS::Modes title_dir_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::Read};
constexpr FS::Modes content_dir_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None};
constexpr FS::Modes data_dir_modes{FS::Mode::ReadWrite, FS::Mode::None, FS::Mode::None};
bool ES::CreateTitleDirectories(u64 title_id, u16 group_id) const
{
const auto fs = m_ios.GetFS();
const std::string content_dir = Common::GetTitleContentPath(title_id);
const auto result1 = fs->CreateFullPath(PID_KERNEL, PID_KERNEL, content_dir + '/', 0,
FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::Read);
const auto result2 = fs->SetMetadata(PID_KERNEL, content_dir, PID_KERNEL, PID_KERNEL, 0,
FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None);
const auto result1 =
fs->CreateFullPath(PID_KERNEL, PID_KERNEL, content_dir + '/', 0, title_dir_modes);
const auto result2 =
fs->SetMetadata(PID_KERNEL, content_dir, PID_KERNEL, PID_KERNEL, 0, content_dir_modes);
if (result1 != FS::ResultCode::Success || result2 != FS::ResultCode::Success)
{
ERROR_LOG(IOS_ES, "Failed to create or set metadata on content dir for %016" PRIx64, title_id);
@@ -239,19 +243,17 @@ bool ES::CreateTitleDirectories(u64 title_id, u16 group_id) const
const std::string data_dir = Common::GetTitleDataPath(title_id);
const auto data_dir_contents = fs->ReadDirectory(PID_KERNEL, PID_KERNEL, data_dir);
if (!data_dir_contents &&
(data_dir_contents.Error() != FS::ResultCode::NotFound ||
fs->CreateDirectory(PID_KERNEL, PID_KERNEL, data_dir, 0, FS::Mode::ReadWrite, FS::Mode::None,
FS::Mode::None) != FS::ResultCode::Success))
if (!data_dir_contents && (data_dir_contents.Error() != FS::ResultCode::NotFound ||
fs->CreateDirectory(PID_KERNEL, PID_KERNEL, data_dir, 0,
data_dir_modes) != FS::ResultCode::Success))
{
ERROR_LOG(IOS_ES, "Failed to create data dir for %016" PRIx64, title_id);
return false;
}
IOS::ES::UIDSys uid_sys{fs};
const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id);
if (fs->SetMetadata(0, data_dir, uid, group_id, 0, FS::Mode::ReadWrite, FS::Mode::None,
FS::Mode::None) != FS::ResultCode::Success)
if (fs->SetMetadata(0, data_dir, uid, group_id, 0, data_dir_modes) != FS::ResultCode::Success)
{
ERROR_LOG(IOS_ES, "Failed to set metadata on data dir for %016" PRIx64, title_id);
return false;
@@ -267,8 +269,8 @@ bool ES::InitImport(const IOS::ES::TMDReader& tmd)
const auto fs = m_ios.GetFS();
const std::string import_content_dir = Common::GetImportTitlePath(tmd.GetTitleId()) + "/content";
const auto result = fs->CreateFullPath(PID_KERNEL, PID_KERNEL, import_content_dir + '/', 0,
FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None);
const auto result =
fs->CreateFullPath(PID_KERNEL, PID_KERNEL, import_content_dir + '/', 0, content_dir_modes);
if (result != FS::ResultCode::Success)
{
ERROR_LOG(IOS_ES, "InitImport: Failed to create content dir for %016" PRIx64, tmd.GetTitleId());
@@ -330,8 +332,7 @@ bool ES::WriteImportTMD(const IOS::ES::TMDReader& tmd)
const auto fs = m_ios.GetFS();
const std::string tmd_path = "/tmp/title.tmd";
{
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, tmd_path, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::None);
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, tmd_path, content_dir_modes);
if (!file || !file->Write(tmd.GetBytes().data(), tmd.GetBytes().size()))
return false;
}
@@ -33,11 +33,9 @@ static ReturnCode WriteTicket(FS::FileSystem* fs, const IOS::ES::TicketReader& t
const u64 title_id = ticket.GetTitleId();
const std::string path = Common::GetTicketFileName(title_id);
fs->CreateFullPath(PID_KERNEL, PID_KERNEL, path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite,
FS::Mode::None);
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, path, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::None);
constexpr FS::Modes ticket_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None};
fs->CreateFullPath(PID_KERNEL, PID_KERNEL, path, 0, ticket_modes);
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, path, ticket_modes);
if (!file)
return FS::ConvertResult(file.Error());
@@ -400,8 +398,8 @@ ReturnCode ES::ImportContentEnd(Context& context, u32 content_fd)
"/tmp/" + content_path.substr(content_path.find_last_of('/') + 1, std::string::npos);
{
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::None);
constexpr FS::Modes content_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None};
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, content_modes);
if (!file || !file->Write(decrypted_data.data(), content_info.size))
{
ERROR_LOG(IOS_ES, "ImportContentEnd: Failed to write to %s", temp_path.c_str());
@@ -69,25 +69,25 @@ Result<FileStatus> FileHandle::GetStatus() const
void FileSystem::Init()
{
if (Delete(0, 0, "/tmp") == ResultCode::Success)
CreateDirectory(0, 0, "/tmp", 0, Mode::ReadWrite, Mode::ReadWrite, Mode::ReadWrite);
CreateDirectory(0, 0, "/tmp", 0, {Mode::ReadWrite, Mode::ReadWrite, Mode::ReadWrite});
}
Result<FileHandle> FileSystem::CreateAndOpenFile(Uid uid, Gid gid, const std::string& path,
Mode owner_mode, Mode group_mode, Mode other_mode)
Modes modes)
{
Result<FileHandle> file = OpenFile(uid, gid, path, Mode::ReadWrite);
if (file.Succeeded())
return file;
const ResultCode result = CreateFile(uid, gid, path, 0, owner_mode, group_mode, other_mode);
const ResultCode result = CreateFile(uid, gid, path, 0, modes);
if (result != ResultCode::Success)
return result;
return OpenFile(uid, gid, path, Mode::ReadWrite);
}
ResultCode FileSystem::CreateFullPath(Uid uid, Gid gid, const std::string& path,
FileAttribute attribute, Mode owner, Mode group, Mode other)
FileAttribute attribute, Modes modes)
{
std::string::size_type position = 1;
while (true)
@@ -103,7 +103,7 @@ ResultCode FileSystem::CreateFullPath(Uid uid, Gid gid, const std::string& path,
if (metadata && metadata->is_file)
return ResultCode::Invalid;
const ResultCode result = CreateDirectory(uid, gid, subpath, attribute, owner, group, other);
const ResultCode result = CreateDirectory(uid, gid, subpath, attribute, modes);
if (result != ResultCode::Success && result != ResultCode::AlreadyExists)
return result;
Oops, something went wrong.

0 comments on commit 6b9aef7

Please sign in to comment.