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.
This commit is contained in:
Léo Lam 2018-06-03 20:32:32 +02:00
parent d1a8661709
commit 6b9aef7042
17 changed files with 124 additions and 165 deletions

View File

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

View File

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

View File

@ -205,9 +205,8 @@ public:
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 @@ public:
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 @@ public:
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 @@ private:
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 @@ private:
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;
}

View File

@ -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()))
{

View File

@ -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))
{

View File

@ -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,10 +243,9 @@ 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;
@ -250,8 +253,7 @@ bool ES::CreateTitleDirectories(u64 title_id, u16 group_id) const
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;
}

View File

@ -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());

View File

@ -69,17 +69,17 @@ 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;
@ -87,7 +87,7 @@ Result<FileHandle> FileSystem::CreateAndOpenFile(Uid uid, Gid gid, const std::st
}
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;

View File

@ -67,12 +67,17 @@ enum class SeekMode : u32
using FileAttribute = u8;
struct Modes
{
Mode owner, group, other;
};
struct Metadata
{
Uid uid;
Gid gid;
FileAttribute attribute;
Mode owner_mode, group_mode, other_mode;
Modes modes;
bool is_file;
u32 size;
u16 fst_index;
@ -142,8 +147,7 @@ public:
/// Get a file descriptor for accessing a file. The FD will be automatically closed after use.
virtual Result<FileHandle> OpenFile(Uid uid, Gid gid, const std::string& path, Mode mode) = 0;
/// Create a file if it doesn't exist and open it in read/write mode.
Result<FileHandle> CreateAndOpenFile(Uid uid, Gid gid, const std::string& path, Mode owner_mode,
Mode group_mode, Mode other_mode);
Result<FileHandle> CreateAndOpenFile(Uid uid, Gid gid, const std::string& path, Modes modes);
/// Close a file descriptor.
virtual ResultCode Close(Fd fd) = 0;
/// Read `size` bytes from the file descriptor. Returns the number of bytes read.
@ -157,17 +161,15 @@ public:
/// Create a file with the specified path and metadata.
virtual ResultCode CreateFile(Uid caller_uid, Gid caller_gid, const std::string& path,
FileAttribute attribute, Mode owner_mode, Mode group_mode,
Mode other_mode) = 0;
FileAttribute attribute, Modes modes) = 0;
/// Create a directory with the specified path and metadata.
virtual ResultCode CreateDirectory(Uid caller_uid, Gid caller_gid, const std::string& path,
FileAttribute attribute, Mode owner_mode, Mode group_mode,
Mode other_mode) = 0;
FileAttribute attribute, Modes modes) = 0;
/// Create any parent directories for a path with the specified metadata.
/// Example: "/a/b" to create directory /a; "/a/b/" to create directories /a and /a/b
ResultCode CreateFullPath(Uid caller_uid, Gid caller_gid, const std::string& path,
FileAttribute attribute, Mode ownerm, Mode group, Mode other);
FileAttribute attribute, Modes modes);
/// Delete a file or directory with the specified path.
virtual ResultCode Delete(Uid caller_uid, Gid caller_gid, const std::string& path) = 0;
@ -183,8 +185,7 @@ public:
virtual Result<Metadata> GetMetadata(Uid caller_uid, Gid caller_gid, const std::string& path) = 0;
/// Set metadata for a file.
virtual ResultCode SetMetadata(Uid caller_uid, const std::string& path, Uid uid, Gid gid,
FileAttribute attribute, Mode owner_mode, Mode group_mode,
Mode other_mode) = 0;
FileAttribute attribute, Modes modes) = 0;
/// Get usage information about the NAND (block size, cluster and inode counts).
virtual Result<NandStats> GetNandStats() = 0;

View File

@ -282,9 +282,7 @@ struct ISFSParams
Common::BigEndianValue<Uid> uid;
Common::BigEndianValue<Gid> gid;
char path[64];
Mode owner_mode;
Mode group_mode;
Mode other_mode;
Modes modes;
FileAttribute attribute;
};
@ -406,9 +404,8 @@ IPCCommandResult FS::CreateDirectory(const Handle& handle, const IOCtlRequest& r
if (!params)
return GetFSReply(ConvertResult(params.Error()));
const ResultCode result =
m_ios.GetFS()->CreateDirectory(handle.uid, handle.gid, params->path, params->attribute,
params->owner_mode, params->group_mode, params->other_mode);
const ResultCode result = m_ios.GetFS()->CreateDirectory(handle.uid, handle.gid, params->path,
params->attribute, params->modes);
LogResult(StringFromFormat("CreateDirectory(%s)", params->path), result);
return GetReplyForSuperblockOperation(result);
}
@ -474,8 +471,7 @@ IPCCommandResult FS::SetAttribute(const Handle& handle, const IOCtlRequest& requ
return GetFSReply(ConvertResult(params.Error()));
const ResultCode result = m_ios.GetFS()->SetMetadata(
handle.uid, params->path, params->uid, params->gid, params->attribute, params->owner_mode,
params->group_mode, params->other_mode);
handle.uid, params->path, params->uid, params->gid, params->attribute, params->modes);
LogResult(StringFromFormat("SetMetadata(%s)", params->path), result);
return GetReplyForSuperblockOperation(result);
}
@ -499,9 +495,7 @@ IPCCommandResult FS::GetAttribute(const Handle& handle, const IOCtlRequest& requ
out.uid = metadata->uid;
out.gid = metadata->gid;
out.attribute = metadata->attribute;
out.owner_mode = metadata->owner_mode;
out.group_mode = metadata->group_mode;
out.other_mode = metadata->other_mode;
out.modes = metadata->modes;
Memory::CopyToEmu(request.buffer_out, &out, sizeof(out));
return GetFSReply(IPC_SUCCESS, ticks);
}
@ -535,9 +529,8 @@ IPCCommandResult FS::CreateFile(const Handle& handle, const IOCtlRequest& reques
if (!params)
return GetFSReply(ConvertResult(params.Error()));
const ResultCode result =
m_ios.GetFS()->CreateFile(handle.uid, handle.gid, params->path, params->attribute,
params->owner_mode, params->group_mode, params->other_mode);
const ResultCode result = m_ios.GetFS()->CreateFile(handle.uid, handle.gid, params->path,
params->attribute, params->modes);
LogResult(StringFromFormat("CreateFile(%s)", params->path), result);
return GetReplyForSuperblockOperation(result);
}

View File

@ -167,8 +167,7 @@ ResultCode HostFileSystem::Format(Uid uid)
return ResultCode::Success;
}
ResultCode HostFileSystem::CreateFile(Uid, Gid, const std::string& path, FileAttribute attribute,
Mode owner_mode, Mode group_mode, Mode other_mode)
ResultCode HostFileSystem::CreateFile(Uid, Gid, const std::string& path, FileAttribute, Modes)
{
std::string file_name(BuildFilename(path));
// check if the file already exist
@ -186,9 +185,7 @@ ResultCode HostFileSystem::CreateFile(Uid, Gid, const std::string& path, FileAtt
return ResultCode::Success;
}
ResultCode HostFileSystem::CreateDirectory(Uid, Gid, const std::string& path,
FileAttribute attribute, Mode owner_mode,
Mode group_mode, Mode other_mode)
ResultCode HostFileSystem::CreateDirectory(Uid, Gid, const std::string& path, FileAttribute, Modes)
{
if (!IsValidWiiPath(path))
return ResultCode::Invalid;
@ -310,9 +307,7 @@ Result<Metadata> HostFileSystem::GetMetadata(Uid, Gid, const std::string& path)
return ResultCode::Invalid;
std::string file_name = BuildFilename(path);
metadata.owner_mode = Mode::ReadWrite;
metadata.group_mode = Mode::ReadWrite;
metadata.other_mode = Mode::ReadWrite;
metadata.modes = {Mode::ReadWrite, Mode::ReadWrite, Mode::ReadWrite};
metadata.attribute = 0x00; // no attributes
// Hack: if the path that is being accessed is within an installed title directory, get the
@ -335,8 +330,7 @@ Result<Metadata> HostFileSystem::GetMetadata(Uid, Gid, const std::string& path)
}
ResultCode HostFileSystem::SetMetadata(Uid caller_uid, const std::string& path, Uid uid, Gid gid,
FileAttribute attribute, Mode owner_mode, Mode group_mode,
Mode other_mode)
FileAttribute, Modes)
{
if (!IsValidWiiPath(path))
return ResultCode::Invalid;

View File

@ -38,12 +38,10 @@ public:
Result<FileStatus> GetFileStatus(Fd fd) override;
ResultCode CreateFile(Uid caller_uid, Gid caller_gid, const std::string& path,
FileAttribute attribute, Mode owner_mode, Mode group_mode,
Mode other_mode) override;
FileAttribute attribute, Modes modes) override;
ResultCode CreateDirectory(Uid caller_uid, Gid caller_gid, const std::string& path,
FileAttribute attribute, Mode owner_mode, Mode group_mode,
Mode other_mode) override;
FileAttribute attribute, Modes modes) override;
ResultCode Delete(Uid caller_uid, Gid caller_gid, const std::string& path) override;
ResultCode Rename(Uid caller_uid, Gid caller_gid, const std::string& old_path,
@ -54,8 +52,7 @@ public:
Result<Metadata> GetMetadata(Uid caller_uid, Gid caller_gid, const std::string& path) override;
ResultCode SetMetadata(Uid caller_uid, const std::string& path, Uid uid, Gid gid,
FileAttribute attribute, Mode owner_mode, Mode group_mode,
Mode other_mode) override;
FileAttribute attribute, Modes modes) override;
Result<NandStats> GetNandStats() override;
Result<DirectoryStats> GetDirectoryStats(const std::string& path) override;

View File

@ -44,9 +44,9 @@ void NWC24Config::ReadConfig()
void NWC24Config::WriteConfig() const
{
constexpr FS::Mode rw_mode = FS::Mode::ReadWrite;
m_fs->CreateFullPath(PID_KD, PID_KD, CONFIG_PATH, 0, rw_mode, rw_mode, rw_mode);
const auto file = m_fs->CreateAndOpenFile(PID_KD, PID_KD, CONFIG_PATH, rw_mode, rw_mode, rw_mode);
constexpr FS::Modes public_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::ReadWrite};
m_fs->CreateFullPath(PID_KD, PID_KD, CONFIG_PATH, 0, public_modes);
const auto file = m_fs->CreateAndOpenFile(PID_KD, PID_KD, CONFIG_PATH, public_modes);
if (!file || !file->Write(&m_data, 1))
ERROR_LOG(IOS_WC24, "Failed to open or write WC24 config file");
}

View File

@ -36,10 +36,9 @@ void WiiNetConfig::ReadConfig(FS::FileSystem* fs)
void WiiNetConfig::WriteConfig(FS::FileSystem* fs) const
{
fs->CreateFullPath(PID_NCD, PID_NCD, CONFIG_PATH, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite,
FS::Mode::ReadWrite);
const auto file = fs->CreateAndOpenFile(PID_NCD, PID_NCD, CONFIG_PATH, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::ReadWrite);
constexpr FS::Modes public_modes{FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::ReadWrite};
fs->CreateFullPath(PID_NCD, PID_NCD, CONFIG_PATH, 0, public_modes);
const auto file = fs->CreateAndOpenFile(PID_NCD, PID_NCD, CONFIG_PATH, public_modes);
if (!file || !file->Write(&m_data, 1))
ERROR_LOG(IOS_NET, "Failed to write config");
}

View File

@ -199,13 +199,13 @@ bool SysConf::Save() const
const std::string temp_file = "/tmp/SYSCONF";
constexpr auto rw_mode = IOS::HLE::FS::Mode::ReadWrite;
{
auto file = m_fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, temp_file, rw_mode,
rw_mode, rw_mode);
auto file = m_fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, temp_file,
{rw_mode, rw_mode, rw_mode});
if (!file || !file->Write(buffer.data(), buffer.size()))
return false;
}
m_fs->CreateDirectory(IOS::SYSMENU_UID, IOS::SYSMENU_GID, "/shared2/sys", 0, rw_mode, rw_mode,
rw_mode);
m_fs->CreateDirectory(IOS::SYSMENU_UID, IOS::SYSMENU_GID, "/shared2/sys", 0,
{rw_mode, rw_mode, rw_mode});
const auto result =
m_fs->Rename(IOS::SYSMENU_UID, IOS::SYSMENU_GID, temp_file, "/shared2/sys/SYSCONF");
return result == IOS::HLE::FS::ResultCode::Success;

View File

@ -96,12 +96,11 @@ static bool CopySysmenuFilesToFS(IOS::HLE::FS::FileSystem* fs, const std::string
const std::string host_path = host_source_path + '/' + entry.virtualName;
const std::string nand_path = nand_target_path + '/' + entry.virtualName;
constexpr IOS::HLE::FS::Mode rw_mode = IOS::HLE::FS::Mode::ReadWrite;
constexpr IOS::HLE::FS::Modes public_modes{rw_mode, rw_mode, rw_mode};
if (entry.isDirectory)
{
fs->CreateDirectory(IOS::SYSMENU_UID, IOS::SYSMENU_GID, nand_path, 0, rw_mode, rw_mode,
rw_mode);
fs->CreateDirectory(IOS::SYSMENU_UID, IOS::SYSMENU_GID, nand_path, 0, public_modes);
if (!CopySysmenuFilesToFS(fs, host_path, nand_path))
return false;
}
@ -116,8 +115,8 @@ static bool CopySysmenuFilesToFS(IOS::HLE::FS::FileSystem* fs, const std::string
if (!host_file.ReadBytes(file_data.data(), file_data.size()))
return false;
const auto nand_file = fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, nand_path,
rw_mode, rw_mode, rw_mode);
const auto nand_file =
fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, nand_path, public_modes);
if (!nand_file || !nand_file->Write(file_data.data(), file_data.size()))
return false;
}

View File

@ -16,6 +16,8 @@
using namespace IOS::HLE::FS;
constexpr Modes modes{Mode::ReadWrite, Mode::None, Mode::None};
class FileSystemTest : public testing::Test
{
protected:
@ -50,8 +52,7 @@ TEST_F(FileSystemTest, CreateFile)
{
const std::string PATH = "/tmp/f";
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, PATH, 0, Mode::Read, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, PATH, 0, modes), ResultCode::Success);
const Result<Metadata> stats = m_fs->GetMetadata(Uid{0}, Gid{0}, PATH);
ASSERT_TRUE(stats.Succeeded());
@ -60,8 +61,7 @@ TEST_F(FileSystemTest, CreateFile)
// TODO: After we start saving metadata correctly, check the UID, GID, permissions
// as well (issue 10234).
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, PATH, 0, Mode::Read, Mode::None, Mode::None),
ResultCode::AlreadyExists);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, PATH, 0, modes), ResultCode::AlreadyExists);
const Result<std::vector<std::string>> tmp_files = m_fs->ReadDirectory(Uid{0}, Gid{0}, "/tmp");
ASSERT_TRUE(tmp_files.Succeeded());
@ -72,8 +72,7 @@ TEST_F(FileSystemTest, CreateDirectory)
{
const std::string PATH = "/tmp/d";
ASSERT_EQ(m_fs->CreateDirectory(Uid{0}, Gid{0}, PATH, 0, Mode::Read, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateDirectory(Uid{0}, Gid{0}, PATH, 0, modes), ResultCode::Success);
const Result<Metadata> stats = m_fs->GetMetadata(Uid{0}, Gid{0}, PATH);
ASSERT_TRUE(stats.Succeeded());
@ -112,15 +111,9 @@ TEST_F(FileSystemTest, RenameWithExistingTargetDirectory)
// Test directory -> existing, non-empty directory.
// IOS's FS sysmodule is not POSIX compliant and will remove the existing directory
// if it exists, even when there are files in it.
ASSERT_EQ(
m_fs->CreateDirectory(Uid{0}, Gid{0}, "/tmp/d", 0, Mode::ReadWrite, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(
m_fs->CreateDirectory(Uid{0}, Gid{0}, "/tmp/d2", 0, Mode::ReadWrite, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(
m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/d2/file", 0, Mode::ReadWrite, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateDirectory(Uid{0}, Gid{0}, "/tmp/d", 0, modes), ResultCode::Success);
ASSERT_EQ(m_fs->CreateDirectory(Uid{0}, Gid{0}, "/tmp/d2", 0, modes), ResultCode::Success);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/d2/file", 0, modes), ResultCode::Success);
EXPECT_EQ(m_fs->Rename(Uid{0}, Gid{0}, "/tmp/d", "/tmp/d2"), ResultCode::Success);
EXPECT_EQ(m_fs->ReadDirectory(Uid{0}, Gid{0}, "/tmp/d").Error(), ResultCode::NotFound);
@ -132,8 +125,7 @@ TEST_F(FileSystemTest, RenameWithExistingTargetDirectory)
TEST_F(FileSystemTest, RenameWithExistingTargetFile)
{
// Create the test source file and write some data (so that we can check its size later on).
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f1", 0, Mode::ReadWrite, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f1", 0, modes), ResultCode::Success);
const std::vector<u8> TEST_DATA{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
std::vector<u8> read_buffer(TEST_DATA.size());
{
@ -143,8 +135,7 @@ TEST_F(FileSystemTest, RenameWithExistingTargetFile)
}
// Create the test target file and leave it empty.
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f2", 0, Mode::ReadWrite, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f2", 0, modes), ResultCode::Success);
// Rename f1 to f2 and check that f1 replaced f2.
EXPECT_EQ(m_fs->Rename(Uid{0}, Gid{0}, "/tmp/f1", "/tmp/f2"), ResultCode::Success);
@ -169,8 +160,7 @@ TEST_F(FileSystemTest, GetDirectoryStats)
check_stats(0u, 1u);
EXPECT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/file", 0, Mode::Read, Mode::None, Mode::None),
ResultCode::Success);
EXPECT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/file", 0, modes), ResultCode::Success);
// Still no clusters (because the file is empty), but 2 inodes now.
check_stats(0u, 2u);
@ -204,8 +194,7 @@ TEST_F(FileSystemTest, Seek)
{
const std::vector<u8> TEST_DATA(10);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, Mode::ReadWrite, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, modes), ResultCode::Success);
const Result<FileHandle> file = m_fs->OpenFile(Uid{0}, Gid{0}, "/tmp/f", Mode::ReadWrite);
ASSERT_TRUE(file.Succeeded());
@ -244,8 +233,7 @@ TEST_F(FileSystemTest, WriteAndSimpleReadback)
const std::vector<u8> TEST_DATA{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
std::vector<u8> read_buffer(TEST_DATA.size());
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, Mode::ReadWrite, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, modes), ResultCode::Success);
const Result<FileHandle> file = m_fs->OpenFile(Uid{0}, Gid{0}, "/tmp/f", Mode::ReadWrite);
ASSERT_TRUE(file.Succeeded());
@ -264,8 +252,7 @@ TEST_F(FileSystemTest, WriteAndRead)
const std::vector<u8> TEST_DATA{{0xf, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
std::vector<u8> buffer(TEST_DATA.size());
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, Mode::ReadWrite, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, modes), ResultCode::Success);
Result<FileHandle> tmp_handle = m_fs->OpenFile(Uid{0}, Gid{0}, "/tmp/f", Mode::ReadWrite);
ASSERT_TRUE(tmp_handle.Succeeded());
@ -298,8 +285,7 @@ TEST_F(FileSystemTest, WriteAndRead)
TEST_F(FileSystemTest, MultipleHandles)
{
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, Mode::ReadWrite, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, modes), ResultCode::Success);
{
const Result<FileHandle> file = m_fs->OpenFile(Uid{0}, Gid{0}, "/tmp/f", Mode::ReadWrite);
@ -333,8 +319,7 @@ TEST_F(FileSystemTest, MultipleHandles)
// If it is not a file, ResultCode::Invalid must be returned.
TEST_F(FileSystemTest, ReadDirectoryOnFile)
{
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, Mode::Read, Mode::None, Mode::None),
ResultCode::Success);
ASSERT_EQ(m_fs->CreateFile(Uid{0}, Gid{0}, "/tmp/f", 0, modes), ResultCode::Success);
const Result<std::vector<std::string>> result = m_fs->ReadDirectory(Uid{0}, Gid{0}, "/tmp/f");
ASSERT_FALSE(result.Succeeded());