diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 4619516c76..a68e975df9 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -623,10 +623,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); - fs->CreateFile(PID_KERNEL, PID_KERNEL, temp_path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, - FS::Mode::None); { - const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::Write); + const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::ReadWrite, + FS::Mode::ReadWrite, FS::Mode::None); if (!file) return FS::ConvertResult(file.Error()); if (!file->Write(tmd.GetBytes().data(), tmd.GetBytes().size())) @@ -880,7 +879,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()->OpenFile(PID_KERNEL, PID_KERNEL, CERT_STORE_PATH, FS::Mode::ReadWrite); + 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())) { diff --git a/Source/Core/Core/IOS/ES/Formats.cpp b/Source/Core/Core/IOS/ES/Formats.cpp index 6a50d95047..260847e629 100644 --- a/Source/Core/Core/IOS/ES/Formats.cpp +++ b/Source/Core/Core/IOS/ES/Formats.cpp @@ -558,13 +558,11 @@ bool SharedContentMap::WriteEntries() const { // Temporary files are only 12 characters long and must match the final file name const std::string temp_path = "/tmp/content.map"; - m_fs->CreateFile(HLE::PID_KERNEL, HLE::PID_KERNEL, temp_path, 0, HLE::FS::Mode::ReadWrite, - HLE::FS::Mode::ReadWrite, HLE::FS::Mode::None); - // Atomically write the new content map. { - const auto file = - m_fs->OpenFile(HLE::PID_KERNEL, HLE::PID_KERNEL, temp_path, HLE::FS::Mode::Write); + const auto file = m_fs->CreateAndOpenFile(HLE::PID_KERNEL, HLE::PID_KERNEL, temp_path, + HLE::FS::Mode::ReadWrite, HLE::FS::Mode::ReadWrite, + HLE::FS::Mode::None); if (!file || !file->Write(m_entries.data(), m_entries.size())) return false; } @@ -637,8 +635,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->OpenFile(HLE::PID_KERNEL, HLE::PID_KERNEL, UID_MAP_PATH, HLE::FS::Mode::ReadWrite); + const auto file = m_fs->CreateAndOpenFile(HLE::PID_KERNEL, HLE::PID_KERNEL, UID_MAP_PATH, + HLE::FS::Mode::ReadWrite, HLE::FS::Mode::ReadWrite, + HLE::FS::Mode::None); if (!file || !file->Seek(0, HLE::FS::SeekMode::End) || !file->Write(&swapped_title_id, 1) || !file->Write(&swapped_uid, 1)) { diff --git a/Source/Core/Core/IOS/ES/NandUtils.cpp b/Source/Core/Core/IOS/ES/NandUtils.cpp index 738ddeaafd..c954961ff9 100644 --- a/Source/Core/Core/IOS/ES/NandUtils.cpp +++ b/Source/Core/Core/IOS/ES/NandUtils.cpp @@ -312,9 +312,8 @@ bool ES::WriteImportTMD(const IOS::ES::TMDReader& tmd) const auto fs = m_ios.GetFS(); const std::string tmd_path = "/tmp/title.tmd"; { - fs->CreateFile(PID_KERNEL, PID_KERNEL, tmd_path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, - FS::Mode::None); - const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, tmd_path, FS::Mode::Write); + const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, tmd_path, FS::Mode::ReadWrite, + FS::Mode::ReadWrite, FS::Mode::None); if (!file || !file->Write(tmd.GetBytes().data(), tmd.GetBytes().size())) return false; } diff --git a/Source/Core/Core/IOS/ES/TitleManagement.cpp b/Source/Core/Core/IOS/ES/TitleManagement.cpp index 30d15d23e0..7bc0ed65aa 100644 --- a/Source/Core/Core/IOS/ES/TitleManagement.cpp +++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp @@ -34,10 +34,9 @@ static ReturnCode WriteTicket(FS::FileSystem* fs, const IOS::ES::TicketReader& t 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); - fs->CreateFile(PID_KERNEL, PID_KERNEL, path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, - FS::Mode::None); - const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, path, FS::Mode::Write); + const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, path, FS::Mode::ReadWrite, + FS::Mode::ReadWrite, FS::Mode::None); if (!file) return FS::ConvertResult(file.Error()); @@ -387,10 +386,9 @@ ReturnCode ES::ImportContentEnd(Context& context, u32 content_fd) const std::string temp_path = "/tmp/" + content_path.substr(content_path.find_last_of('/') + 1, std::string::npos); - fs->CreateFile(PID_KERNEL, PID_KERNEL, temp_path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, - FS::Mode::None); { - const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::Write); + const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::ReadWrite, + FS::Mode::ReadWrite, FS::Mode::None); if (!file || !file->Write(decrypted_data.data(), content_info.size)) { ERROR_LOG(IOS_ES, "ImportContentEnd: Failed to write to %s", temp_path.c_str()); diff --git a/Source/Core/Core/IOS/FS/FileSystem.cpp b/Source/Core/Core/IOS/FS/FileSystem.cpp index e62c6bcc6b..06916c6fed 100644 --- a/Source/Core/Core/IOS/FS/FileSystem.cpp +++ b/Source/Core/Core/IOS/FS/FileSystem.cpp @@ -72,6 +72,20 @@ void FileSystem::Init() CreateDirectory(0, 0, "/tmp", 0, Mode::ReadWrite, Mode::ReadWrite, Mode::ReadWrite); } +Result FileSystem::CreateAndOpenFile(Uid uid, Gid gid, const std::string& path, + Mode owner_mode, Mode group_mode, Mode other_mode) +{ + Result 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); + 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) { diff --git a/Source/Core/Core/IOS/FS/FileSystem.h b/Source/Core/Core/IOS/FS/FileSystem.h index a53cd36ac9..b3701c0f1e 100644 --- a/Source/Core/Core/IOS/FS/FileSystem.h +++ b/Source/Core/Core/IOS/FS/FileSystem.h @@ -141,6 +141,9 @@ public: /// Get a file descriptor for accessing a file. The FD will be automatically closed after use. virtual Result 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 CreateAndOpenFile(Uid uid, Gid gid, const std::string& path, Mode owner_mode, + Mode group_mode, Mode other_mode); /// Close a file descriptor. virtual ResultCode Close(Fd fd) = 0; /// Read `size` bytes from the file descriptor. Returns the number of bytes read. diff --git a/Source/Core/Core/IOS/Network/NCD/WiiNetConfig.cpp b/Source/Core/Core/IOS/Network/NCD/WiiNetConfig.cpp index 80e06289ad..fa58158e28 100644 --- a/Source/Core/Core/IOS/Network/NCD/WiiNetConfig.cpp +++ b/Source/Core/Core/IOS/Network/NCD/WiiNetConfig.cpp @@ -37,9 +37,8 @@ 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); - fs->CreateFile(PID_NCD, PID_NCD, CONFIG_PATH, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite, - FS::Mode::ReadWrite); - const auto file = fs->OpenFile(PID_NCD, PID_NCD, CONFIG_PATH, FS::Mode::Write); + const auto file = fs->CreateAndOpenFile(PID_NCD, PID_NCD, CONFIG_PATH, FS::Mode::ReadWrite, + FS::Mode::ReadWrite, FS::Mode::ReadWrite); if (!file || !file->Write(&m_data, 1)) ERROR_LOG(IOS_NET, "Failed to write config"); }