From 065867e2c24e9856c360fc2d6b9a86c92aedc43e Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Tue, 25 May 2021 19:32:56 -0400 Subject: common: fs: Rework the Common Filesystem interface to make use of std::filesystem (#6270) * common: fs: fs_types: Create filesystem types Contains various filesystem types used by the Common::FS library * common: fs: fs_util: Add std::string to std::u8string conversion utility * common: fs: path_util: Add utlity functions for paths Contains various utility functions for getting or manipulating filesystem paths used by the Common::FS library * common: fs: file: Rewrite the IOFile implementation * common: fs: Reimplement Common::FS library using std::filesystem * common: fs: fs_paths: Add fs_paths to replace common_paths * common: fs: path_util: Add the rest of the path functions * common: Remove the previous Common::FS implementation * general: Remove unused fs includes * string_util: Remove unused function and include * nvidia_flags: Migrate to the new Common::FS library * settings: Migrate to the new Common::FS library * logging: backend: Migrate to the new Common::FS library * core: Migrate to the new Common::FS library * perf_stats: Migrate to the new Common::FS library * reporter: Migrate to the new Common::FS library * telemetry_session: Migrate to the new Common::FS library * key_manager: Migrate to the new Common::FS library * bis_factory: Migrate to the new Common::FS library * registered_cache: Migrate to the new Common::FS library * xts_archive: Migrate to the new Common::FS library * service: acc: Migrate to the new Common::FS library * applets/profile: Migrate to the new Common::FS library * applets/web: Migrate to the new Common::FS library * service: filesystem: Migrate to the new Common::FS library * loader: Migrate to the new Common::FS library * gl_shader_disk_cache: Migrate to the new Common::FS library * nsight_aftermath_tracker: Migrate to the new Common::FS library * vulkan_library: Migrate to the new Common::FS library * configure_debug: Migrate to the new Common::FS library * game_list_worker: Migrate to the new Common::FS library * config: Migrate to the new Common::FS library * configure_filesystem: Migrate to the new Common::FS library * configure_per_game_addons: Migrate to the new Common::FS library * configure_profile_manager: Migrate to the new Common::FS library * configure_ui: Migrate to the new Common::FS library * input_profiles: Migrate to the new Common::FS library * yuzu_cmd: config: Migrate to the new Common::FS library * yuzu_cmd: Migrate to the new Common::FS library * vfs_real: Migrate to the new Common::FS library * vfs: Migrate to the new Common::FS library * vfs_libzip: Migrate to the new Common::FS library * service: bcat: Migrate to the new Common::FS library * yuzu: main: Migrate to the new Common::FS library * vfs_real: Delete the contents of an existing file in CreateFile Current usages of CreateFile expect to delete the contents of an existing file, retain this behavior for now. * input_profiles: Don't iterate the input profile dir if it does not exist Silences an error produced in the log if the directory does not exist. * game_list_worker: Skip parsing file if the returned VfsFile is nullptr Prevents crashes in GetLoader when the virtual file is nullptr * common: fs: Validate paths for path length * service: filesystem: Open the mod load directory as read only --- src/core/core.cpp | 4 +- src/core/crypto/key_manager.cpp | 139 ++++++++------ src/core/crypto/key_manager.h | 6 +- src/core/file_sys/bis_factory.cpp | 4 +- src/core/file_sys/mode.h | 8 +- src/core/file_sys/partition_filesystem.cpp | 1 - src/core/file_sys/patch_manager.cpp | 1 - src/core/file_sys/registered_cache.cpp | 2 +- src/core/file_sys/vfs.cpp | 8 +- src/core/file_sys/vfs_libzip.cpp | 1 + src/core/file_sys/vfs_real.cpp | 245 ++++++++++++------------ src/core/file_sys/vfs_real.h | 4 +- src/core/file_sys/xts_archive.cpp | 2 +- src/core/hle/service/acc/acc.cpp | 28 +-- src/core/hle/service/acc/profile_manager.cpp | 33 ++-- src/core/hle/service/am/applets/web_browser.cpp | 47 ++--- src/core/hle/service/am/applets/web_browser.h | 5 +- src/core/hle/service/bcat/backend/boxcat.cpp | 68 ++++--- src/core/hle/service/fatal/fatal.cpp | 1 - src/core/hle/service/filesystem/filesystem.cpp | 21 +- src/core/hle/service/mii/manager.cpp | 1 - src/core/hle/service/ns/pl_u.cpp | 2 - src/core/loader/deconstructed_rom_directory.cpp | 1 - src/core/loader/elf.cpp | 1 - src/core/loader/loader.cpp | 2 +- src/core/loader/nca.cpp | 1 - src/core/loader/nro.cpp | 1 - src/core/loader/nso.cpp | 1 - src/core/perf_stats.cpp | 19 +- src/core/reporter.cpp | 23 ++- src/core/telemetry_session.cpp | 47 +++-- 31 files changed, 387 insertions(+), 340 deletions(-) (limited to 'src/core') diff --git a/src/core/core.cpp b/src/core/core.cpp index 826a00ad6..c5004b7b4 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -6,7 +6,7 @@ #include #include -#include "common/file_util.h" +#include "common/fs/fs.h" #include "common/logging/log.h" #include "common/microprofile.h" #include "common/settings.h" @@ -121,7 +121,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, dir->GetName()); } - if (Common::FS::IsDirectory(path)) { + if (Common::FS::IsDir(path)) { return vfs->OpenFile(path + "/main", FileSys::Mode::Read); } diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index a4b739c63..fb451a423 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -18,8 +18,9 @@ #include #include #include "common/common_funcs.h" -#include "common/common_paths.h" -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/hex_util.h" #include "common/logging/log.h" #include "common/settings.h" @@ -325,46 +326,55 @@ Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source) } std::optional DeriveSDSeed() { - const Common::FS::IOFile save_43(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) + - "/system/save/8000000000000043", - "rb+"); + const auto system_save_43_path = + Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000043"; + const Common::FS::IOFile save_43{system_save_43_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; + if (!save_43.IsOpen()) { return std::nullopt; } - const Common::FS::IOFile sd_private(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir) + - "/Nintendo/Contents/private", - "rb+"); + const auto sd_private_path = + Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "Nintendo/Contents/private"; + + const Common::FS::IOFile sd_private{sd_private_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; + if (!sd_private.IsOpen()) { return std::nullopt; } std::array private_seed{}; - if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != private_seed.size()) { + if (sd_private.Read(private_seed) != private_seed.size()) { return std::nullopt; } std::array buffer{}; - std::size_t offset = 0; - for (; offset + 0x10 < save_43.GetSize(); ++offset) { - if (!save_43.Seek(offset, SEEK_SET)) { + s64 offset = 0; + for (; offset + 0x10 < static_cast(save_43.GetSize()); ++offset) { + if (!save_43.Seek(offset)) { + return std::nullopt; + } + + if (save_43.Read(buffer) != buffer.size()) { return std::nullopt; } - save_43.ReadBytes(buffer.data(), buffer.size()); if (buffer == private_seed) { break; } } - if (!save_43.Seek(offset + 0x10, SEEK_SET)) { + if (!save_43.Seek(offset + 0x10)) { return std::nullopt; } Key128 seed{}; - if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) { + if (save_43.Read(seed) != seed.size()) { return std::nullopt; } + return seed; } @@ -435,7 +445,7 @@ std::vector GetTicketblob(const Common::FS::IOFile& ticket_save) { } std::vector buffer(ticket_save.GetSize()); - if (ticket_save.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { + if (ticket_save.Read(buffer) != buffer.size()) { return {}; } @@ -566,27 +576,26 @@ std::optional> ParseTicket(const Ticket& ticket, KeyManager::KeyManager() { // Initialize keys - const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath(); - const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); - if (!Common::FS::Exists(yuzu_keys_dir)) { - Common::FS::CreateDir(yuzu_keys_dir); + if (!Common::FS::CreateDir(yuzu_keys_dir)) { + LOG_ERROR(Core, "Failed to create the keys directory."); } if (Settings::values.use_dev_keys) { dev_mode = true; - AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "dev.keys_autogenerated", false); + LoadFromFile(yuzu_keys_dir / "dev.keys", false); + LoadFromFile(yuzu_keys_dir / "dev.keys_autogenerated", false); } else { dev_mode = false; - AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "prod.keys", false); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "prod.keys_autogenerated", false); + LoadFromFile(yuzu_keys_dir / "prod.keys", false); + LoadFromFile(yuzu_keys_dir / "prod.keys_autogenerated", false); } - AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "title.keys_autogenerated", true); - AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "console.keys", false); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "console.keys_autogenerated", false); + LoadFromFile(yuzu_keys_dir / "title.keys", true); + LoadFromFile(yuzu_keys_dir / "title.keys_autogenerated", true); + LoadFromFile(yuzu_keys_dir / "console.keys", false); + LoadFromFile(yuzu_keys_dir / "console.keys_autogenerated", false); } static bool ValidCryptoRevisionString(std::string_view base, size_t begin, size_t length) { @@ -597,9 +606,14 @@ static bool ValidCryptoRevisionString(std::string_view base, size_t begin, size_ [](u8 c) { return std::isxdigit(c); }); } -void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { +void KeyManager::LoadFromFile(const std::filesystem::path& file_path, bool is_title_keys) { + if (!Common::FS::Exists(file_path)) { + return; + } + std::ifstream file; - Common::FS::OpenFStream(file, filename, std::ios_base::in); + Common::FS::OpenFileStream(file, file_path, std::ios_base::in); + if (!file.is_open()) { return; } @@ -694,15 +708,6 @@ void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { } } -void KeyManager::AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, - const std::string& filename, bool title) { - if (Common::FS::Exists(dir1 + DIR_SEP + filename)) { - LoadFromFile(dir1 + DIR_SEP + filename, title); - } else if (Common::FS::Exists(dir2 + DIR_SEP + filename)) { - LoadFromFile(dir2 + DIR_SEP + filename, title); - } -} - bool KeyManager::BaseDeriveNecessary() const { const auto check_key_existence = [this](auto key_type, u64 index1 = 0, u64 index2 = 0) { return !HasKey(key_type, index1, index2); @@ -766,30 +771,35 @@ Key256 KeyManager::GetBISKey(u8 partition_id) const { template void KeyManager::WriteKeyToFile(KeyCategory category, std::string_view keyname, const std::array& key) { - const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + std::string filename = "title.keys_autogenerated"; + if (category == KeyCategory::Standard) { filename = dev_mode ? "dev.keys_autogenerated" : "prod.keys_autogenerated"; } else if (category == KeyCategory::Console) { filename = "console.keys_autogenerated"; } - const auto path = yuzu_keys_dir + DIR_SEP + filename; + const auto path = yuzu_keys_dir / filename; const auto add_info_text = !Common::FS::Exists(path); - Common::FS::CreateFullPath(path); - Common::FS::IOFile file{path, "a"}; + + Common::FS::IOFile file{path, Common::FS::FileAccessMode::Append, + Common::FS::FileType::TextFile}; + if (!file.IsOpen()) { return; } + if (add_info_text) { - file.WriteString( + void(file.WriteString( "# This file is autogenerated by Yuzu\n" "# It serves to store keys that were automatically generated from the normal keys\n" - "# If you are experiencing issues involving keys, it may help to delete this file\n"); + "# If you are experiencing issues involving keys, it may help to delete this file\n")); } - file.WriteString(fmt::format("\n{} = {}", keyname, Common::HexToString(key))); - AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, filename, category == KeyCategory::Title); + void(file.WriteString(fmt::format("\n{} = {}", keyname, Common::HexToString(key)))); + LoadFromFile(path, category == KeyCategory::Title); } void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { @@ -861,20 +871,17 @@ void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) { } bool KeyManager::KeyFileExists(bool title) { - const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath(); - const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); + const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir); + if (title) { - return Common::FS::Exists(hactool_keys_dir + DIR_SEP + "title.keys") || - Common::FS::Exists(yuzu_keys_dir + DIR_SEP + "title.keys"); + return Common::FS::Exists(yuzu_keys_dir / "title.keys"); } if (Settings::values.use_dev_keys) { - return Common::FS::Exists(hactool_keys_dir + DIR_SEP + "dev.keys") || - Common::FS::Exists(yuzu_keys_dir + DIR_SEP + "dev.keys"); + return Common::FS::Exists(yuzu_keys_dir / "dev.keys"); } - return Common::FS::Exists(hactool_keys_dir + DIR_SEP + "prod.keys") || - Common::FS::Exists(yuzu_keys_dir + DIR_SEP + "prod.keys"); + return Common::FS::Exists(yuzu_keys_dir / "prod.keys"); } void KeyManager::DeriveSDSeedLazy() { @@ -1115,15 +1122,21 @@ void KeyManager::PopulateTickets() { return; } - const Common::FS::IOFile save1(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) + - "/system/save/80000000000000e1", - "rb+"); - const Common::FS::IOFile save2(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) + - "/system/save/80000000000000e2", - "rb+"); + const auto system_save_e1_path = + Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e1"; + + const Common::FS::IOFile save_e1{system_save_e1_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; + + const auto system_save_e2_path = + Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e2"; + + const Common::FS::IOFile save_e2{system_save_e2_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; + + const auto blob2 = GetTicketblob(save_e2); + auto res = GetTicketblob(save_e1); - const auto blob2 = GetTicketblob(save2); - auto res = GetTicketblob(save1); const auto idx = res.size(); res.insert(res.end(), blob2.begin(), blob2.end()); diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 0a7220286..e771625e1 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include #include @@ -283,9 +284,8 @@ private: std::array eticket_extended_kek{}; bool dev_mode; - void LoadFromFile(const std::string& filename, bool is_title_keys); - void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, - const std::string& filename, bool title); + void LoadFromFile(const std::filesystem::path& file_path, bool is_title_keys); + template void WriteKeyToFile(KeyCategory category, std::string_view keyname, const std::array& key); diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index 7c6304ff0..f3891acf1 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include -#include "common/file_util.h" +#include "common/fs/path_util.h" #include "core/file_sys/bis_factory.h" #include "core/file_sys/mode.h" #include "core/file_sys/registered_cache.h" @@ -85,7 +85,7 @@ VirtualFile BISFactory::OpenPartitionStorage(BisPartitionId id, VirtualFilesystem file_system) const { auto& keys = Core::Crypto::KeyManager::Instance(); Core::Crypto::PartitionDataManager pdm{file_system->OpenDirectory( - Common::FS::GetUserPath(Common::FS::UserPath::SysDataDir), Mode::Read)}; + Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir), Mode::Read)}; keys.PopulateFromPartitionData(pdm); switch (id) { diff --git a/src/core/file_sys/mode.h b/src/core/file_sys/mode.h index 2b4f21073..6c49a64e2 100644 --- a/src/core/file_sys/mode.h +++ b/src/core/file_sys/mode.h @@ -10,11 +10,13 @@ namespace FileSys { enum class Mode : u32 { - Read = 1, - Write = 2, + Read = 1 << 0, + Write = 1 << 1, ReadWrite = Read | Write, - Append = 4, + Append = 1 << 2, + ReadAppend = Read | Append, WriteAppend = Write | Append, + All = ReadWrite | Append, }; DECLARE_ENUM_FLAG_OPERATORS(Mode) diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index 48a2ed4d4..c5967049e 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp @@ -8,7 +8,6 @@ #include #include -#include "common/file_util.h" #include "common/logging/log.h" #include "core/file_sys/partition_filesystem.h" #include "core/file_sys/vfs_offset.h" diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index cc9b4b637..53b8b7ca0 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -7,7 +7,6 @@ #include #include -#include "common/file_util.h" #include "common/hex_util.h" #include "common/logging/log.h" #include "common/settings.h" diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index b0cb65952..066c6789a 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -7,7 +7,7 @@ #include #include #include "common/assert.h" -#include "common/file_util.h" +#include "common/fs/path_util.h" #include "common/hex_util.h" #include "common/logging/log.h" #include "core/crypto/key_manager.h" diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp index f497e9396..215e1cb1a 100644 --- a/src/core/file_sys/vfs.cpp +++ b/src/core/file_sys/vfs.cpp @@ -5,8 +5,7 @@ #include #include #include -#include "common/common_paths.h" -#include "common/file_util.h" +#include "common/fs/path_util.h" #include "common/logging/backend.h" #include "core/file_sys/mode.h" #include "core/file_sys/vfs.h" @@ -122,15 +121,14 @@ VirtualDir VfsFilesystem::CopyDirectory(std::string_view old_path_, std::string_ return nullptr; for (const auto& file : old_dir->GetFiles()) { - const auto x = - CopyFile(old_path + DIR_SEP + file->GetName(), new_path + DIR_SEP + file->GetName()); + const auto x = CopyFile(old_path + '/' + file->GetName(), new_path + '/' + file->GetName()); if (x == nullptr) return nullptr; } for (const auto& dir : old_dir->GetSubdirectories()) { const auto x = - CopyDirectory(old_path + DIR_SEP + dir->GetName(), new_path + DIR_SEP + dir->GetName()); + CopyDirectory(old_path + '/' + dir->GetName(), new_path + '/' + dir->GetName()); if (x == nullptr) return nullptr; } diff --git a/src/core/file_sys/vfs_libzip.cpp b/src/core/file_sys/vfs_libzip.cpp index 618eb658a..cd162c0c3 100644 --- a/src/core/file_sys/vfs_libzip.cpp +++ b/src/core/file_sys/vfs_libzip.cpp @@ -13,6 +13,7 @@ #pragma GCC diagnostic pop #endif +#include "common/fs/path_util.h" #include "common/logging/backend.h" #include "core/file_sys/vfs.h" #include "core/file_sys/vfs_libzip.h" diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 3d89dd644..d0b8fd046 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp @@ -7,8 +7,9 @@ #include #include #include "common/assert.h" -#include "common/common_paths.h" -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/logging/log.h" #include "core/file_sys/vfs_real.h" @@ -16,33 +17,31 @@ namespace FileSys { namespace FS = Common::FS; -static std::string ModeFlagsToString(Mode mode) { - std::string mode_str; - - // Calculate the correct open mode for the file. - if (True(mode & Mode::Read) && True(mode & Mode::Write)) { - if (True(mode & Mode::Append)) { - mode_str = "a+"; - } else { - mode_str = "r+"; - } - } else { - if (True(mode & Mode::Read)) { - mode_str = "r"; - } else if (True(mode & Mode::Append)) { - mode_str = "a"; - } else if (True(mode & Mode::Write)) { - mode_str = "w"; - } else { - UNREACHABLE_MSG("Invalid file open mode: {:02X}", static_cast(mode)); - } +namespace { + +constexpr FS::FileAccessMode ModeFlagsToFileAccessMode(Mode mode) { + switch (mode) { + case Mode::Read: + return FS::FileAccessMode::Read; + case Mode::Write: + return FS::FileAccessMode::Write; + case Mode::ReadWrite: + return FS::FileAccessMode::ReadWrite; + case Mode::Append: + return FS::FileAccessMode::Append; + case Mode::ReadAppend: + return FS::FileAccessMode::ReadAppend; + case Mode::WriteAppend: + return FS::FileAccessMode::Append; + case Mode::All: + return FS::FileAccessMode::ReadAppend; + default: + return {}; } - - mode_str += "b"; - - return mode_str; } +} // Anonymous namespace + RealVfsFilesystem::RealVfsFilesystem() : VfsFilesystem(nullptr) {} RealVfsFilesystem::~RealVfsFilesystem() = default; @@ -63,7 +62,7 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const { if (!FS::Exists(path)) { return VfsEntryType::None; } - if (FS::IsDirectory(path)) { + if (FS::IsDir(path)) { return VfsEntryType::Directory; } @@ -81,12 +80,13 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { } } - if (!FS::Exists(path) && True(perms & Mode::WriteAppend)) { - FS::CreateEmptyFile(path); + auto backing = FS::FileOpen(path, ModeFlagsToFileAccessMode(perms), FS::FileType::BinaryFile); + + if (!backing) { + return nullptr; } - auto backing = std::make_shared(path, ModeFlagsToString(perms).c_str()); - cache.insert_or_assign(path, backing); + cache.insert_or_assign(path, std::move(backing)); // Cannot use make_shared as RealVfsFile constructor is private return std::shared_ptr(new RealVfsFile(*this, backing, path, perms)); @@ -94,25 +94,29 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); - const auto path_fwd = FS::SanitizePath(path, FS::DirectorySeparator::ForwardSlash); - if (!FS::Exists(path)) { - FS::CreateFullPath(path_fwd); - if (!FS::CreateEmptyFile(path)) { + // Current usages of CreateFile expect to delete the contents of an existing file. + if (FS::IsFile(path)) { + FS::IOFile temp{path, FS::FileAccessMode::Write, FS::FileType::BinaryFile}; + + if (!temp.IsOpen()) { return nullptr; } + + temp.Close(); + + return OpenFile(path, perms); + } + + if (!FS::NewFile(path)) { + return nullptr; } + return OpenFile(path, perms); } VirtualFile RealVfsFilesystem::CopyFile(std::string_view old_path_, std::string_view new_path_) { - const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); - const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); - - if (!FS::Exists(old_path) || FS::Exists(new_path) || FS::IsDirectory(old_path) || - !FS::Copy(old_path, new_path)) { - return nullptr; - } - return OpenFile(new_path, Mode::ReadWrite); + // Unused + return nullptr; } VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { @@ -127,13 +131,13 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_ file->Close(); } - if (!FS::Exists(old_path) || FS::Exists(new_path) || FS::IsDirectory(old_path) || - !FS::Rename(old_path, new_path)) { + if (!FS::RenameFile(old_path, new_path)) { return nullptr; } cache.erase(old_path); - if (file->Open(new_path, "r+b")) { + file->Open(new_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile); + if (file->IsOpen()) { cache.insert_or_assign(new_path, std::move(file)); } else { LOG_ERROR(Service_FS, "Failed to open path {} in order to re-cache it", new_path); @@ -157,7 +161,7 @@ bool RealVfsFilesystem::DeleteFile(std::string_view path_) { cache.erase(path); } - return FS::Delete(path); + return FS::RemoveFile(path); } VirtualDir RealVfsFilesystem::OpenDirectory(std::string_view path_, Mode perms) { @@ -168,12 +172,8 @@ VirtualDir RealVfsFilesystem::OpenDirectory(std::string_view path_, Mode perms) VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, Mode perms) { const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); - const auto path_fwd = FS::SanitizePath(path, FS::DirectorySeparator::ForwardSlash); - if (!FS::Exists(path)) { - FS::CreateFullPath(path_fwd); - if (!FS::CreateDir(path)) { - return nullptr; - } + if (!FS::CreateDirs(path)) { + return nullptr; } // Cannot use make_shared as RealVfsDirectory constructor is private return std::shared_ptr(new RealVfsDirectory(*this, path, perms)); @@ -181,13 +181,8 @@ VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, Mode perms VirtualDir RealVfsFilesystem::CopyDirectory(std::string_view old_path_, std::string_view new_path_) { - const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); - const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); - if (!FS::Exists(old_path) || FS::Exists(new_path) || !FS::IsDirectory(old_path)) { - return nullptr; - } - FS::CopyDir(old_path, new_path); - return OpenDirectory(new_path, Mode::ReadWrite); + // Unused + return nullptr; } VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, @@ -195,8 +190,7 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); - if (!FS::Exists(old_path) || FS::Exists(new_path) || FS::IsDirectory(old_path) || - !FS::Rename(old_path, new_path)) { + if (!FS::RenameDir(old_path, new_path)) { return nullptr; } @@ -208,7 +202,7 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, const auto file_old_path = FS::SanitizePath(kv.first, FS::DirectorySeparator::PlatformDefault); - auto file_new_path = FS::SanitizePath(new_path + DIR_SEP + kv.first.substr(old_path.size()), + auto file_new_path = FS::SanitizePath(new_path + '/' + kv.first.substr(old_path.size()), FS::DirectorySeparator::PlatformDefault); const auto& cached = cache[file_old_path]; @@ -218,7 +212,8 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_, auto file = cached.lock(); cache.erase(file_old_path); - if (file->Open(file_new_path, "r+b")) { + file->Open(file_new_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile); + if (file->IsOpen()) { cache.insert_or_assign(std::move(file_new_path), std::move(file)); } else { LOG_ERROR(Service_FS, "Failed to open path {} in order to re-cache it", file_new_path); @@ -245,15 +240,13 @@ bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) { cache.erase(kv.first); } - return FS::DeleteDirRecursively(path); + return FS::RemoveDirRecursively(path); } RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::shared_ptr backing_, const std::string& path_, Mode perms_) : base(base_), backing(std::move(backing_)), path(path_), parent_path(FS::GetParentPath(path_)), - path_components(FS::SplitPathComponents(path_)), - parent_components(FS::SliceVector(path_components, 0, path_components.size() - 1)), - perms(perms_) {} + path_components(FS::SplitPathComponents(path_)), perms(perms_) {} RealVfsFile::~RealVfsFile() = default; @@ -266,7 +259,7 @@ std::size_t RealVfsFile::GetSize() const { } bool RealVfsFile::Resize(std::size_t new_size) { - return backing->Resize(new_size); + return backing->SetSize(new_size); } VirtualDir RealVfsFile::GetContainingDirectory() const { @@ -274,33 +267,33 @@ VirtualDir RealVfsFile::GetContainingDirectory() const { } bool RealVfsFile::IsWritable() const { - return True(perms & Mode::WriteAppend); + return True(perms & Mode::Write); } bool RealVfsFile::IsReadable() const { - return True(perms & Mode::ReadWrite); + return True(perms & Mode::Read); } std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const { - if (!backing->Seek(static_cast(offset), SEEK_SET)) { + if (!backing->Seek(static_cast(offset))) { return 0; } - return backing->ReadBytes(data, length); + return backing->ReadSpan(std::span{data, length}); } std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) { - if (!backing->Seek(static_cast(offset), SEEK_SET)) { + if (!backing->Seek(static_cast(offset))) { return 0; } - return backing->WriteBytes(data, length); + return backing->WriteSpan(std::span{data, length}); } bool RealVfsFile::Rename(std::string_view name) { - return base.MoveFile(path, parent_path + DIR_SEP + std::string(name)) != nullptr; + return base.MoveFile(path, parent_path + '/' + std::string(name)) != nullptr; } -bool RealVfsFile::Close() { - return backing->Close(); +void RealVfsFile::Close() { + backing->Close(); } // TODO(DarkLordZach): MSVC would not let me combine the following two functions using 'if @@ -313,15 +306,16 @@ std::vector RealVfsDirectory::IterateEntries( } std::vector out; - FS::ForeachDirectoryEntry( - nullptr, path, - [&out, this](u64* entries_out, const std::string& directory, const std::string& filename) { - const std::string full_path = directory + DIR_SEP + filename; - if (!FS::IsDirectory(full_path)) { - out.emplace_back(base.OpenFile(full_path, perms)); - } - return true; - }); + + const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) { + const auto full_path_string = FS::PathToUTF8String(full_path); + + out.emplace_back(base.OpenFile(full_path_string, perms)); + + return true; + }; + + FS::IterateDirEntries(path, callback, FS::DirEntryFilter::File); return out; } @@ -333,42 +327,41 @@ std::vector RealVfsDirectory::IterateEntries out; - FS::ForeachDirectoryEntry( - nullptr, path, - [&out, this](u64* entries_out, const std::string& directory, const std::string& filename) { - const std::string full_path = directory + DIR_SEP + filename; - if (FS::IsDirectory(full_path)) { - out.emplace_back(base.OpenDirectory(full_path, perms)); - } - return true; - }); + + const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) { + const auto full_path_string = FS::PathToUTF8String(full_path); + + out.emplace_back(base.OpenDirectory(full_path_string, perms)); + + return true; + }; + + FS::IterateDirEntries(path, callback, FS::DirEntryFilter::Directory); return out; } RealVfsDirectory::RealVfsDirectory(RealVfsFilesystem& base_, const std::string& path_, Mode perms_) : base(base_), path(FS::RemoveTrailingSlash(path_)), parent_path(FS::GetParentPath(path)), - path_components(FS::SplitPathComponents(path)), - parent_components(FS::SliceVector(path_components, 0, path_components.size() - 1)), - perms(perms_) { - if (!FS::Exists(path) && True(perms & Mode::WriteAppend)) { - FS::CreateDir(path); + path_components(FS::SplitPathComponents(path)), perms(perms_) { + if (!FS::Exists(path) && True(perms & Mode::Write)) { + void(FS::CreateDirs(path)); } } RealVfsDirectory::~RealVfsDirectory() = default; VirtualFile RealVfsDirectory::GetFileRelative(std::string_view relative_path) const { - const auto full_path = FS::SanitizePath(path + DIR_SEP + std::string(relative_path)); - if (!FS::Exists(full_path) || FS::IsDirectory(full_path)) { + const auto full_path = FS::SanitizePath(path + '/' + std::string(relative_path)); + if (!FS::Exists(full_path) || FS::IsDir(full_path)) { return nullptr; } return base.OpenFile(full_path, perms); } VirtualDir RealVfsDirectory::GetDirectoryRelative(std::string_view relative_path) const { - const auto full_path = FS::SanitizePath(path + DIR_SEP + std::string(relative_path)); - if (!FS::Exists(full_path) || !FS::IsDirectory(full_path)) { + const auto full_path = FS::SanitizePath(path + '/' + std::string(relative_path)); + if (!FS::Exists(full_path) || !FS::IsDir(full_path)) { return nullptr; } return base.OpenDirectory(full_path, perms); @@ -383,17 +376,20 @@ VirtualDir RealVfsDirectory::GetSubdirectory(std::string_view name) const { } VirtualFile RealVfsDirectory::CreateFileRelative(std::string_view relative_path) { - const auto full_path = FS::SanitizePath(path + DIR_SEP + std::string(relative_path)); + const auto full_path = FS::SanitizePath(path + '/' + std::string(relative_path)); + if (!FS::CreateParentDirs(full_path)) { + return nullptr; + } return base.CreateFile(full_path, perms); } VirtualDir RealVfsDirectory::CreateDirectoryRelative(std::string_view relative_path) { - const auto full_path = FS::SanitizePath(path + DIR_SEP + std::string(relative_path)); + const auto full_path = FS::SanitizePath(path + '/' + std::string(relative_path)); return base.CreateDirectory(full_path, perms); } bool RealVfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) { - const auto full_path = FS::SanitizePath(this->path + DIR_SEP + std::string(name)); + const auto full_path = FS::SanitizePath(this->path + '/' + std::string(name)); return base.DeleteDirectory(full_path); } @@ -406,11 +402,11 @@ std::vector RealVfsDirectory::GetSubdirectories() const { } bool RealVfsDirectory::IsWritable() const { - return True(perms & Mode::WriteAppend); + return True(perms & Mode::Write); } bool RealVfsDirectory::IsReadable() const { - return True(perms & Mode::ReadWrite); + return True(perms & Mode::Read); } std::string RealVfsDirectory::GetName() const { @@ -426,27 +422,27 @@ VirtualDir RealVfsDirectory::GetParentDirectory() const { } VirtualDir RealVfsDirectory::CreateSubdirectory(std::string_view name) { - const std::string subdir_path = (path + DIR_SEP).append(name); + const std::string subdir_path = (path + '/').append(name); return base.CreateDirectory(subdir_path, perms); } VirtualFile RealVfsDirectory::CreateFile(std::string_view name) { - const std::string file_path = (path + DIR_SEP).append(name); + const std::string file_path = (path + '/').append(name); return base.CreateFile(file_path, perms); } bool RealVfsDirectory::DeleteSubdirectory(std::string_view name) { - const std::string subdir_path = (path + DIR_SEP).append(name); + const std::string subdir_path = (path + '/').append(name); return base.DeleteDirectory(subdir_path); } bool RealVfsDirectory::DeleteFile(std::string_view name) { - const std::string file_path = (path + DIR_SEP).append(name); + const std::string file_path = (path + '/').append(name); return base.DeleteFile(file_path); } bool RealVfsDirectory::Rename(std::string_view name) { - const std::string new_name = (parent_path + DIR_SEP).append(name); + const std::string new_name = (parent_path + '/').append(name); return base.MoveFile(path, new_name) != nullptr; } @@ -462,14 +458,17 @@ std::map> RealVfsDirectory::GetEntries() } std::map> out; - FS::ForeachDirectoryEntry( - nullptr, path, - [&out](u64* entries_out, const std::string& directory, const std::string& filename) { - const std::string full_path = directory + DIR_SEP + filename; - out.emplace(filename, - FS::IsDirectory(full_path) ? VfsEntryType::Directory : VfsEntryType::File); - return true; - }); + + const FS::DirEntryCallable callback = [&out](const std::filesystem::path& full_path) { + const auto filename = FS::PathToUTF8String(full_path.filename()); + + out.insert_or_assign(filename, + FS::IsDir(full_path) ? VfsEntryType::Directory : VfsEntryType::File); + + return true; + }; + + FS::IterateDirEntries(path, callback); return out; } diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h index 0666f2679..e4d1bba79 100644 --- a/src/core/file_sys/vfs_real.h +++ b/src/core/file_sys/vfs_real.h @@ -61,14 +61,13 @@ private: RealVfsFile(RealVfsFilesystem& base, std::shared_ptr backing, const std::string& path, Mode perms = Mode::Read); - bool Close(); + void Close(); RealVfsFilesystem& base; std::shared_ptr backing; std::string path; std::string parent_path; std::vector path_components; - std::vector parent_components; Mode perms; }; @@ -110,7 +109,6 @@ private: std::string path; std::string parent_path; std::vector path_components; - std::vector parent_components; Mode perms; }; diff --git a/src/core/file_sys/xts_archive.cpp b/src/core/file_sys/xts_archive.cpp index 814fd5680..d6fe1af47 100644 --- a/src/core/file_sys/xts_archive.cpp +++ b/src/core/file_sys/xts_archive.cpp @@ -11,7 +11,7 @@ #include #include -#include "common/file_util.h" +#include "common/fs/path_util.h" #include "common/hex_util.h" #include "common/string_util.h" #include "core/crypto/aes_util.h" diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 49c09a570..39cd1efc1 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -4,9 +4,9 @@ #include #include -#include "common/common_paths.h" #include "common/common_types.h" -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/path_util.h" #include "common/logging/log.h" #include "common/string_util.h" #include "common/swap.h" @@ -41,9 +41,9 @@ constexpr ResultCode ERR_FAILED_SAVE_DATA{ErrorModule::Account, 100}; // Thumbnails are hard coded to be at least this size constexpr std::size_t THUMBNAIL_SIZE = 0x24000; -static std::string GetImagePath(Common::UUID uuid) { - return Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) + - "/system/save/8000000000000010/su/avators/" + uuid.FormatSwitch() + ".jpg"; +static std::filesystem::path GetImagePath(Common::UUID uuid) { + return Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / + fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormatSwitch()); } static constexpr u32 SanitizeJPEGSize(std::size_t size) { @@ -328,7 +328,8 @@ protected: IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - const Common::FS::IOFile image(GetImagePath(user_id), "rb"); + const Common::FS::IOFile image(GetImagePath(user_id), Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile); if (!image.IsOpen()) { LOG_WARNING(Service_ACC, "Failed to load user provided image! Falling back to built-in backup..."); @@ -339,7 +340,10 @@ protected: const u32 size = SanitizeJPEGSize(image.GetSize()); std::vector buffer(size); - image.ReadBytes(buffer.data(), buffer.size()); + + if (image.Read(buffer) != buffer.size()) { + LOG_ERROR(Service_ACC, "Failed to read all the bytes in the user provided image."); + } ctx.WriteBuffer(buffer); rb.Push(size); @@ -350,7 +354,8 @@ protected: IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - const Common::FS::IOFile image(GetImagePath(user_id), "rb"); + const Common::FS::IOFile image(GetImagePath(user_id), Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile); if (!image.IsOpen()) { LOG_WARNING(Service_ACC, @@ -415,10 +420,11 @@ protected: ProfileData data; std::memcpy(&data, user_data.data(), sizeof(ProfileData)); - Common::FS::IOFile image(GetImagePath(user_id), "wb"); + Common::FS::IOFile image(GetImagePath(user_id), Common::FS::FileAccessMode::Write, + Common::FS::FileType::BinaryFile); - if (!image.IsOpen() || !image.Resize(image_data.size()) || - image.WriteBytes(image_data.data(), image_data.size()) != image_data.size() || + if (!image.IsOpen() || !image.SetSize(image_data.size()) || + image.Write(image_data) != image_data.size() || !profile_manager.SetProfileBaseAndData(user_id, base, data)) { LOG_ERROR(Service_ACC, "Failed to update profile data, base, and image!"); IPC::ResponseBuilder rb{ctx, 2}; diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index de83d82a4..77510489c 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -7,7 +7,9 @@ #include -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/settings.h" #include "core/hle/service/acc/profile_manager.h" @@ -36,7 +38,7 @@ constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, u32(-1)); constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, u32(-2)); constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); -constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "/system/save/8000000000000010/su/avators/"; +constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "system/save/8000000000000010/su/avators"; ProfileManager::ProfileManager() { ParseUserSaveFile(); @@ -325,8 +327,9 @@ bool ProfileManager::SetProfileBaseAndData(Common::UUID uuid, const ProfileBase& } void ProfileManager::ParseUserSaveFile() { - const FS::IOFile save( - FS::GetUserPath(FS::UserPath::NANDDir) + ACC_SAVE_AVATORS_BASE_PATH + "profiles.dat", "rb"); + const auto save_path(FS::GetYuzuPath(FS::YuzuPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH / + "profiles.dat"); + const FS::IOFile save(save_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile); if (!save.IsOpen()) { LOG_WARNING(Service_ACC, "Failed to load profile data from save data... Generating new " @@ -335,7 +338,7 @@ void ProfileManager::ParseUserSaveFile() { } ProfileDataRaw data; - if (save.ReadBytes(&data, sizeof(ProfileDataRaw)) != sizeof(ProfileDataRaw)) { + if (!save.ReadObject(data)) { LOG_WARNING(Service_ACC, "profiles.dat is smaller than expected... Generating new user " "'yuzu' with random UUID."); return; @@ -372,31 +375,27 @@ void ProfileManager::WriteUserSaveFile() { }; } - const auto raw_path = FS::GetUserPath(FS::UserPath::NANDDir) + "/system/save/8000000000000010"; - if (FS::Exists(raw_path) && !FS::IsDirectory(raw_path)) { - FS::Delete(raw_path); + const auto raw_path(FS::GetYuzuPath(FS::YuzuPath::NANDDir) / "system/save/8000000000000010"); + if (FS::IsFile(raw_path) && !FS::RemoveFile(raw_path)) { + return; } - const auto path = - FS::GetUserPath(FS::UserPath::NANDDir) + ACC_SAVE_AVATORS_BASE_PATH + "profiles.dat"; + const auto save_path(FS::GetYuzuPath(FS::YuzuPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH / + "profiles.dat"); - if (!FS::CreateFullPath(path)) { + if (!FS::CreateParentDirs(save_path)) { LOG_WARNING(Service_ACC, "Failed to create full path of profiles.dat. Create the directory " "nand/system/save/8000000000000010/su/avators to mitigate this " "issue."); return; } - FS::IOFile save(path, "wb"); + FS::IOFile save(save_path, FS::FileAccessMode::Write, FS::FileType::BinaryFile); - if (!save.IsOpen()) { + if (!save.IsOpen() || !save.SetSize(sizeof(ProfileDataRaw)) || !save.WriteObject(raw)) { LOG_WARNING(Service_ACC, "Failed to write save data to file... No changes to user data " "made in current session will be saved."); - return; } - - save.Resize(sizeof(ProfileDataRaw)); - save.WriteBytes(&raw, sizeof(ProfileDataRaw)); } }; // namespace Service::Account diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index e5f4a4485..3b28e829b 100644 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp @@ -3,8 +3,9 @@ // Refer to the license.txt file included. #include "common/assert.h" -#include "common/common_paths.h" -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/logging/log.h" #include "common/string_util.h" #include "core/core.h" @@ -135,14 +136,10 @@ void ExtractSharedFonts(Core::System& system) { "FontNintendoExtended2.ttf", }; - for (std::size_t i = 0; i < NS::SHARED_FONTS.size(); ++i) { - const auto fonts_dir = Common::FS::SanitizePath( - fmt::format("{}/fonts", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)), - Common::FS::DirectorySeparator::PlatformDefault); + const auto fonts_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "fonts"; - const auto font_file_path = - Common::FS::SanitizePath(fmt::format("{}/{}", fonts_dir, DECRYPTED_SHARED_FONTS[i]), - Common::FS::DirectorySeparator::PlatformDefault); + for (std::size_t i = 0; i < NS::SHARED_FONTS.size(); ++i) { + const auto font_file_path = fonts_dir / DECRYPTED_SHARED_FONTS[i]; if (Common::FS::Exists(font_file_path)) { continue; @@ -197,8 +194,8 @@ void ExtractSharedFonts(Core::System& system) { FileSys::VirtualFile decrypted_font = std::make_shared( std::move(decrypted_data), DECRYPTED_SHARED_FONTS[i]); - const auto temp_dir = - system.GetFilesystem()->CreateDirectory(fonts_dir, FileSys::Mode::ReadWrite); + const auto temp_dir = system.GetFilesystem()->CreateDirectory( + Common::FS::PathToUTF8String(fonts_dir), FileSys::Mode::ReadWrite); const auto out_file = temp_dir->CreateFile(DECRYPTED_SHARED_FONTS[i]); @@ -312,13 +309,14 @@ void WebBrowser::Execute() { } void WebBrowser::ExtractOfflineRomFS() { - LOG_DEBUG(Service_AM, "Extracting RomFS to {}", offline_cache_dir); + LOG_DEBUG(Service_AM, "Extracting RomFS to {}", + Common::FS::PathToUTF8String(offline_cache_dir)); const auto extracted_romfs_dir = FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard); - const auto temp_dir = - system.GetFilesystem()->CreateDirectory(offline_cache_dir, FileSys::Mode::ReadWrite); + const auto temp_dir = system.GetFilesystem()->CreateDirectory( + Common::FS::PathToUTF8String(offline_cache_dir), FileSys::Mode::ReadWrite); FileSys::VfsRawCopyD(extracted_romfs_dir, temp_dir); } @@ -397,15 +395,12 @@ void WebBrowser::InitializeOffline() { "system_data", }; - offline_cache_dir = Common::FS::SanitizePath( - fmt::format("{}/offline_web_applet_{}/{:016X}", - Common::FS::GetUserPath(Common::FS::UserPath::CacheDir), - RESOURCE_TYPES[static_cast(document_kind) - 1], title_id), - Common::FS::DirectorySeparator::PlatformDefault); + offline_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / + fmt::format("offline_web_applet_{}/{:016X}", + RESOURCE_TYPES[static_cast(document_kind) - 1], title_id); - offline_document = Common::FS::SanitizePath( - fmt::format("{}/{}/{}", offline_cache_dir, additional_paths, document_path), - Common::FS::DirectorySeparator::PlatformDefault); + offline_document = Common::FS::ConcatPathSafe( + offline_cache_dir, fmt::format("{}/{}", additional_paths, document_path)); } void WebBrowser::InitializeShare() {} @@ -429,8 +424,7 @@ void WebBrowser::ExecuteLogin() { } void WebBrowser::ExecuteOffline() { - const auto main_url = Common::FS::SanitizePath(GetMainURL(offline_document), - Common::FS::DirectorySeparator::PlatformDefault); + const auto main_url = GetMainURL(Common::FS::PathToUTF8String(offline_document)); if (!Common::FS::Exists(main_url)) { offline_romfs = GetOfflineRomFS(system, title_id, nca_type); @@ -444,10 +438,11 @@ void WebBrowser::ExecuteOffline() { } } - LOG_INFO(Service_AM, "Opening offline document at {}", offline_document); + LOG_INFO(Service_AM, "Opening offline document at {}", + Common::FS::PathToUTF8String(offline_document)); frontend.OpenLocalWebPage( - offline_document, [this] { ExtractOfflineRomFS(); }, + Common::FS::PathToUTF8String(offline_document), [this] { ExtractOfflineRomFS(); }, [this](WebExitReason exit_reason, std::string last_url) { WebBrowserExit(exit_reason, last_url); }); diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h index 1e1812f36..cdeaf2c40 100644 --- a/src/core/hle/service/am/applets/web_browser.h +++ b/src/core/hle/service/am/applets/web_browser.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include "common/common_funcs.h" @@ -75,8 +76,8 @@ private: u64 title_id{}; FileSys::ContentRecordType nca_type{}; - std::string offline_cache_dir; - std::string offline_document; + std::filesystem::path offline_cache_dir; + std::filesystem::path offline_document; FileSys::VirtualFile offline_romfs; std::string external_url; diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp index d6d2f52e5..3cc397604 100644 --- a/src/core/hle/service/bcat/backend/boxcat.cpp +++ b/src/core/hle/service/bcat/backend/boxcat.cpp @@ -15,6 +15,9 @@ #pragma GCC diagnostic pop #endif +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/hex_util.h" #include "common/logging/backend.h" #include "common/logging/log.h" @@ -96,14 +99,14 @@ constexpr u32 PORT = 443; constexpr u32 TIMEOUT_SECONDS = 30; [[maybe_unused]] constexpr u64 VFS_COPY_BLOCK_SIZE = 1ULL << 24; // 4MB -std::string GetBINFilePath(u64 title_id) { - return fmt::format("{}bcat/{:016X}/launchparam.bin", - Common::FS::GetUserPath(Common::FS::UserPath::CacheDir), title_id); +std::filesystem::path GetBINFilePath(u64 title_id) { + return Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "bcat" / + fmt::format("{:016X}/launchparam.bin", title_id); } -std::string GetZIPFilePath(u64 title_id) { - return fmt::format("{}bcat/{:016X}/data.zip", - Common::FS::GetUserPath(Common::FS::UserPath::CacheDir), title_id); +std::filesystem::path GetZIPFilePath(u64 title_id) { + return Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "bcat" / + fmt::format("{:016X}/data.zip", title_id); } // If the error is something the user should know about (build ID mismatch, bad client version), @@ -187,7 +190,7 @@ bool VfsRawCopyDProgress(FileSys::VirtualDir src, FileSys::VirtualDir dest, class Boxcat::Client { public: - Client(std::string path_, u64 title_id_, u64 build_id_) + Client(std::filesystem::path path_, u64 title_id_, u64 build_id_) : path(std::move(path_)), title_id(title_id_), build_id(build_id_) {} DownloadResult DownloadDataZip() { @@ -217,10 +220,11 @@ private: }; if (Common::FS::Exists(path)) { - Common::FS::IOFile file{path, "rb"}; + Common::FS::IOFile file{path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; if (file.IsOpen()) { std::vector bytes(file.GetSize()); - file.ReadBytes(bytes.data(), bytes.size()); + void(file.Read(bytes)); const auto digest = DigestFile(bytes); headers.insert({std::string("If-None-Match"), Common::HexToString(digest, false)}); } @@ -247,14 +251,23 @@ private: return DownloadResult::InvalidContentType; } - Common::FS::CreateFullPath(path); - Common::FS::IOFile file{path, "wb"}; - if (!file.IsOpen()) + if (!Common::FS::CreateDirs(path)) { return DownloadResult::GeneralFSError; - if (!file.Resize(response->body.size())) + } + + Common::FS::IOFile file{path, Common::FS::FileAccessMode::Append, + Common::FS::FileType::BinaryFile}; + if (!file.IsOpen()) { + return DownloadResult::GeneralFSError; + } + + if (!file.SetSize(response->body.size())) { return DownloadResult::GeneralFSError; - if (file.WriteBytes(response->body.data(), response->body.size()) != response->body.size()) + } + + if (file.Write(response->body) != response->body.size()) { return DownloadResult::GeneralFSError; + } return DownloadResult::Success; } @@ -267,7 +280,7 @@ private: } std::unique_ptr client; - std::string path; + std::filesystem::path path; u64 title_id; u64 build_id; }; @@ -291,7 +304,7 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe return; } - const auto zip_path{GetZIPFilePath(title.title_id)}; + const auto zip_path = GetZIPFilePath(title.title_id); Boxcat::Client client{zip_path, title.title_id, title.build_id}; progress.StartConnecting(); @@ -301,7 +314,7 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res); if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) { - Common::FS::Delete(zip_path); + void(Common::FS::RemoveFile(zip_path)); } HandleDownloadDisplayResult(applet_manager, res); @@ -311,11 +324,13 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe progress.StartProcessingDataList(); - Common::FS::IOFile zip{zip_path, "rb"}; + Common::FS::IOFile zip{zip_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; const auto size = zip.GetSize(); std::vector bytes(size); - if (!zip.IsOpen() || size == 0 || zip.ReadBytes(bytes.data(), bytes.size()) != bytes.size()) { - LOG_ERROR(Service_BCAT, "Boxcat failed to read ZIP file at path '{}'!", zip_path); + if (!zip.IsOpen() || size == 0 || zip.Read(bytes) != bytes.size()) { + LOG_ERROR(Service_BCAT, "Boxcat failed to read ZIP file at path '{}'!", + Common::FS::PathToUTF8String(zip_path)); progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE); return; } @@ -419,19 +434,19 @@ void Boxcat::SetPassphrase(u64 title_id, const Passphrase& passphrase) { } std::optional> Boxcat::GetLaunchParameter(TitleIDVersion title) { - const auto path{GetBINFilePath(title.title_id)}; + const auto bin_file_path = GetBINFilePath(title.title_id); if (Settings::values.bcat_boxcat_local) { LOG_INFO(Service_BCAT, "Boxcat using local data by override, skipping download."); } else { - Client launch_client{path, title.title_id, title.build_id}; + Client launch_client{bin_file_path, title.title_id, title.build_id}; const auto res = launch_client.DownloadLaunchParam(); if (res != DownloadResult::Success) { LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res); if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) { - Common::FS::Delete(path); + void(Common::FS::RemoveFile(bin_file_path)); } HandleDownloadDisplayResult(applet_manager, res); @@ -439,12 +454,13 @@ std::optional> Boxcat::GetLaunchParameter(TitleIDVersion title) } } - Common::FS::IOFile bin{path, "rb"}; + Common::FS::IOFile bin{bin_file_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; const auto size = bin.GetSize(); std::vector bytes(size); - if (!bin.IsOpen() || size == 0 || bin.ReadBytes(bytes.data(), bytes.size()) != bytes.size()) { + if (!bin.IsOpen() || size == 0 || bin.Read(bytes) != bytes.size()) { LOG_ERROR(Service_BCAT, "Boxcat failed to read launch parameter binary at path '{}'!", - path); + Common::FS::PathToUTF8String(bin_file_path)); return std::nullopt; } diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 432abde76..b7666e95a 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp @@ -6,7 +6,6 @@ #include #include #include -#include "common/file_util.h" #include "common/logging/log.h" #include "common/scm_rev.h" #include "common/swap.h" diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 67baaee9b..78664439d 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -5,7 +5,7 @@ #include #include "common/assert.h" -#include "common/file_util.h" +#include "common/fs/path_util.h" #include "common/settings.h" #include "core/core.h" #include "core/file_sys/bis_factory.h" @@ -728,14 +728,17 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove sdmc_factory = nullptr; } - auto nand_directory = vfs.OpenDirectory(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir), - FileSys::Mode::ReadWrite); - auto sd_directory = vfs.OpenDirectory(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir), - FileSys::Mode::ReadWrite); - auto load_directory = vfs.OpenDirectory(Common::FS::GetUserPath(Common::FS::UserPath::LoadDir), - FileSys::Mode::ReadWrite); - auto dump_directory = vfs.OpenDirectory(Common::FS::GetUserPath(Common::FS::UserPath::DumpDir), - FileSys::Mode::ReadWrite); + using YuzuPath = Common::FS::YuzuPath; + const auto rw_mode = FileSys::Mode::ReadWrite; + + auto nand_directory = + vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode); + auto sd_directory = + vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::SDMCDir), rw_mode); + auto load_directory = + vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::LoadDir), FileSys::Mode::Read); + auto dump_directory = + vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::DumpDir), rw_mode); if (bis_factory == nullptr) { bis_factory = diff --git a/src/core/hle/service/mii/manager.cpp b/src/core/hle/service/mii/manager.cpp index 70350a2a3..114aff31c 100644 --- a/src/core/hle/service/mii/manager.cpp +++ b/src/core/hle/service/mii/manager.cpp @@ -6,7 +6,6 @@ #include #include "common/assert.h" -#include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index e14acce58..90ba5c752 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -7,9 +7,7 @@ #include #include "common/assert.h" -#include "common/common_paths.h" #include "common/common_types.h" -#include "common/file_util.h" #include "common/logging/log.h" #include "common/swap.h" #include "core/core.h" diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 022885c1b..a19bb220a 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -5,7 +5,6 @@ #include #include #include "common/common_funcs.h" -#include "common/file_util.h" #include "common/logging/log.h" #include "core/core.h" #include "core/file_sys/content_archive.h" diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index c062a4259..3d9276f15 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -7,7 +7,6 @@ #include #include "common/common_funcs.h" #include "common/common_types.h" -#include "common/file_util.h" #include "common/logging/log.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index d4808fb5b..228dc6389 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -7,7 +7,7 @@ #include #include #include "common/concepts.h" -#include "common/file_util.h" +#include "common/fs/path_util.h" #include "common/logging/log.h" #include "common/string_util.h" #include "core/core.h" diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 418cbf61b..aa51b0daa 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -4,7 +4,6 @@ #include -#include "common/file_util.h" #include "common/logging/log.h" #include "core/core.h" #include "core/file_sys/content_archive.h" diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index ef54fa574..618555202 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -7,7 +7,6 @@ #include "common/common_funcs.h" #include "common/common_types.h" -#include "common/file_util.h" #include "common/logging/log.h" #include "common/settings.h" #include "common/swap.h" diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index df59412cf..0f5cfda68 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -7,7 +7,6 @@ #include #include "common/common_funcs.h" -#include "common/file_util.h" #include "common/hex_util.h" #include "common/logging/log.h" #include "common/lz4_compression.h" diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index c42c437b7..6635a1339 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -11,7 +11,9 @@ #include #include #include -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/math_util.h" #include "common/settings.h" #include "core/perf_stats.h" @@ -38,12 +40,17 @@ PerfStats::~PerfStats() { std::ostringstream stream; std::copy(perf_history.begin() + IgnoreFrames, perf_history.begin() + current_index, std::ostream_iterator(stream, "\n")); - const std::string& path = Common::FS::GetUserPath(Common::FS::UserPath::LogDir); + + const auto path = Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir); // %F Date format expanded is "%Y-%m-%d" - const std::string filename = - fmt::format("{}/{:%F-%H-%M}_{:016X}.csv", path, *std::localtime(&t), title_id); - Common::FS::IOFile file(filename, "w"); - file.WriteString(stream.str()); + const auto filename = fmt::format("{:%F-%H-%M}_{:016X}.csv", *std::localtime(&t), title_id); + const auto filepath = path / filename; + + if (Common::FS::CreateParentDir(filepath)) { + Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Write, + Common::FS::FileType::TextFile); + void(file.WriteString(stream.str())); + } } void PerfStats::BeginSystemFrame() { diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index d1e807dd4..a9596fe4d 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -11,7 +11,9 @@ #include #include -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/hex_util.h" #include "common/scm_rev.h" #include "common/settings.h" @@ -26,10 +28,9 @@ namespace { -std::string GetPath(std::string_view type, u64 title_id, std::string_view timestamp) { - return fmt::format("{}{}/{:016X}_{}.json", - Common::FS::GetUserPath(Common::FS::UserPath::LogDir), type, title_id, - timestamp); +std::filesystem::path GetPath(std::string_view type, u64 title_id, std::string_view timestamp) { + return Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir) / type / + fmt::format("{:016X}_{}.json", title_id, timestamp); } std::string GetTimestamp() { @@ -39,14 +40,16 @@ std::string GetTimestamp() { using namespace nlohmann; -void SaveToFile(json json, const std::string& filename) { - if (!Common::FS::CreateFullPath(filename)) { - LOG_ERROR(Core, "Failed to create path for '{}' to save report!", filename); +void SaveToFile(json json, const std::filesystem::path& filename) { + if (!Common::FS::CreateParentDirs(filename)) { + LOG_ERROR(Core, "Failed to create path for '{}' to save report!", + Common::FS::PathToUTF8String(filename)); return; } - std::ofstream file( - Common::FS::SanitizePath(filename, Common::FS::DirectorySeparator::PlatformDefault)); + std::ofstream file; + Common::FS::OpenFileStream(file, filename, std::ios_base::out | std::ios_base::trunc); + file << std::setw(4) << json << std::endl; } diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 6dcff5400..ad1a9ffb4 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -9,7 +9,9 @@ #include "common/assert.h" #include "common/common_types.h" -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/logging/log.h" #include "common/settings.h" @@ -72,31 +74,41 @@ static const char* TranslateGPUAccuracyLevel(Settings::GPUAccuracy backend) { u64 GetTelemetryId() { u64 telemetry_id{}; - const std::string filename{Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir) + - "telemetry_id"}; + const auto filename = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir) / "telemetry_id"; bool generate_new_id = !Common::FS::Exists(filename); + if (!generate_new_id) { - Common::FS::IOFile file(filename, "rb"); + Common::FS::IOFile file{filename, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; + if (!file.IsOpen()) { - LOG_ERROR(Core, "failed to open telemetry_id: {}", filename); + LOG_ERROR(Core, "failed to open telemetry_id: {}", + Common::FS::PathToUTF8String(filename)); return {}; } - file.ReadBytes(&telemetry_id, sizeof(u64)); - if (telemetry_id == 0) { + + if (!file.ReadObject(telemetry_id) || telemetry_id == 0) { LOG_ERROR(Frontend, "telemetry_id is 0. Generating a new one.", telemetry_id); generate_new_id = true; } } if (generate_new_id) { - Common::FS::IOFile file(filename, "wb"); + Common::FS::IOFile file{filename, Common::FS::FileAccessMode::Write, + Common::FS::FileType::BinaryFile}; + if (!file.IsOpen()) { - LOG_ERROR(Core, "failed to open telemetry_id: {}", filename); + LOG_ERROR(Core, "failed to open telemetry_id: {}", + Common::FS::PathToUTF8String(filename)); return {}; } + telemetry_id = GenerateTelemetryId(); - file.WriteBytes(&telemetry_id, sizeof(u64)); + + if (!file.WriteObject(telemetry_id)) { + LOG_ERROR(Core, "Failed to write telemetry_id to file."); + } } return telemetry_id; @@ -104,15 +116,20 @@ u64 GetTelemetryId() { u64 RegenerateTelemetryId() { const u64 new_telemetry_id{GenerateTelemetryId()}; - const std::string filename{Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir) + - "telemetry_id"}; + const auto filename = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir) / "telemetry_id"; + + Common::FS::IOFile file{filename, Common::FS::FileAccessMode::Write, + Common::FS::FileType::BinaryFile}; - Common::FS::IOFile file(filename, "wb"); if (!file.IsOpen()) { - LOG_ERROR(Core, "failed to open telemetry_id: {}", filename); + LOG_ERROR(Core, "failed to open telemetry_id: {}", Common::FS::PathToUTF8String(filename)); return {}; } - file.WriteBytes(&new_telemetry_id, sizeof(u64)); + + if (!file.WriteObject(new_telemetry_id)) { + LOG_ERROR(Core, "Failed to write telemetry_id to file."); + } + return new_telemetry_id; } -- cgit v1.2.3