diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 15c79c3d3b..6ef614a325 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -34,7 +34,6 @@ add_library(common SettingsHandler.cpp StringUtil.cpp SymbolDB.cpp - SysConf.cpp Thread.cpp Timer.cpp TraversalClient.cpp diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj index 5b64898b7b..05a86d667c 100644 --- a/Source/Core/Common/Common.vcxproj +++ b/Source/Core/Common/Common.vcxproj @@ -147,7 +147,6 @@ - @@ -203,7 +202,6 @@ - diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters index 58b75ff30f..8dd8bd6aeb 100644 --- a/Source/Core/Common/Common.vcxproj.filters +++ b/Source/Core/Common/Common.vcxproj.filters @@ -67,7 +67,6 @@ - @@ -289,7 +288,6 @@ - diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 58a5254cb8..26ab98f803 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(core NetPlayServer.cpp PatchEngine.cpp State.cpp + SysConf.cpp TitleDatabase.cpp WiiRoot.cpp WiiUtils.cpp diff --git a/Source/Core/Core/Config/SYSCONFSettings.h b/Source/Core/Core/Config/SYSCONFSettings.h index f4ade3ddf8..2d1dd78e12 100644 --- a/Source/Core/Core/Config/SYSCONFSettings.h +++ b/Source/Core/Core/Config/SYSCONFSettings.h @@ -8,7 +8,7 @@ #include #include "Common/Config/Config.h" -#include "Common/SysConf.h" +#include "Core/SysConf.h" namespace Config { diff --git a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp index 4dcfb613ae..8d6e00fe20 100644 --- a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp @@ -17,12 +17,13 @@ #include "Common/FileUtil.h" #include "Common/IniFile.h" #include "Common/Logging/Log.h" -#include "Common/SysConf.h" #include "Core/Config/SYSCONFSettings.h" #include "Core/ConfigLoaders/IsSettingSaveable.h" #include "Core/Core.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Bluetooth/BTBase.h" +#include "Core/SysConf.h" namespace ConfigLoaders { @@ -31,7 +32,8 @@ void SaveToSYSCONF(Config::LayerType layer) if (Core::IsRunning()) return; - SysConf sysconf{Common::FromWhichRoot::FROM_CONFIGURED_ROOT}; + IOS::HLE::Kernel ios; + SysConf sysconf{ios.GetFS()}; for (const Config::SYSCONFSetting& setting : Config::SYSCONF_SETTINGS) { @@ -154,7 +156,8 @@ private: if (Core::IsRunning()) return; - SysConf sysconf{Common::FromWhichRoot::FROM_CONFIGURED_ROOT}; + IOS::HLE::Kernel ios; + SysConf sysconf{ios.GetFS()}; for (const Config::SYSCONFSetting& setting : Config::SYSCONF_SETTINGS) { std::visit( diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 641aaeaaab..3a1aeee2ea 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -292,6 +292,7 @@ + @@ -530,6 +531,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 5456cd4be5..25a151d371 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -179,6 +179,7 @@ + @@ -912,6 +913,7 @@ + diff --git a/Source/Core/Core/IOS/FS/FileSystem.cpp b/Source/Core/Core/IOS/FS/FileSystem.cpp index 552d68ec8b..f2beb7d0c8 100644 --- a/Source/Core/Core/IOS/FS/FileSystem.cpp +++ b/Source/Core/Core/IOS/FS/FileSystem.cpp @@ -28,7 +28,7 @@ FileHandle::FileHandle(FileHandle&& other) : m_fs{other.m_fs}, m_fd{other.m_fd} FileHandle& FileHandle::operator=(FileHandle&& other) { - if (*this != other) + if (std::tie(m_fs, m_fd) != std::tie(other.m_fs, other.m_fd)) *this = std::move(other); return *this; } @@ -46,6 +46,16 @@ Fd FileHandle::Release() return fd; } +Result FileHandle::Seek(u32 offset, SeekMode mode) const +{ + return m_fs->SeekFile(*m_fd, offset, mode); +} + +Result FileHandle::GetStatus() const +{ + return m_fs->GetFileStatus(*m_fd); +} + void FileSystem::Init() { if (Delete(0, 0, "/tmp") == ResultCode::Success) diff --git a/Source/Core/Core/IOS/FS/FileSystem.h b/Source/Core/Core/IOS/FS/FileSystem.h index 87890cdbad..eb14dc6673 100644 --- a/Source/Core/Core/IOS/FS/FileSystem.h +++ b/Source/Core/Core/IOS/FS/FileSystem.h @@ -108,10 +108,18 @@ public: FileHandle& operator=(const FileHandle&) = delete; FileHandle& operator=(FileHandle&&); - operator Fd() const { return m_fd.value(); } /// Release the FD so that it is not automatically closed. Fd Release(); + template + Result Read(T* ptr, size_t count) const; + + template + Result Write(const T* ptr, size_t count) const; + + Result Seek(u32 offset, SeekMode mode) const; + Result GetStatus() const; + private: FileSystem* m_fs; std::optional m_fd; @@ -140,26 +148,6 @@ public: /// Get status for a file descriptor. virtual Result GetFileStatus(Fd fd) = 0; - template - Result ReadFile(Fd fd, T* ptr, u32 count) - { - const Result bytes = ReadBytesFromFile(fd, reinterpret_cast(ptr), sizeof(T) * count); - if (!bytes) - return bytes.Error(); - if (*bytes != sizeof(T) * count) - return ResultCode::ShortRead; - return count; - } - - template - Result WriteFile(Fd fd, const T* ptr, u32 count) - { - const auto result = WriteBytesToFile(fd, reinterpret_cast(ptr), sizeof(T) * count); - if (!result) - return result.Error(); - return count; - } - /// 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, @@ -195,6 +183,28 @@ protected: void Init(); }; +template +Result FileHandle::Read(T* ptr, size_t count) const +{ + const Result bytes = m_fs->ReadBytesFromFile(*m_fd, reinterpret_cast(ptr), + static_cast(sizeof(T) * count)); + if (!bytes) + return bytes.Error(); + if (*bytes != sizeof(T) * count) + return ResultCode::ShortRead; + return count; +} + +template +Result FileHandle::Write(const T* ptr, size_t count) const +{ + const auto result = m_fs->WriteBytesToFile(*m_fd, reinterpret_cast(ptr), + static_cast(sizeof(T) * count)); + if (!result) + return result.Error(); + return count; +} + enum class Location { Configured, diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTBase.cpp b/Source/Core/Core/IOS/USB/Bluetooth/BTBase.cpp index c4770253d6..b1fadd8a1f 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTBase.cpp +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTBase.cpp @@ -13,7 +13,7 @@ #include "Common/File.h" #include "Common/FileUtil.h" #include "Common/Logging/Log.h" -#include "Common/SysConf.h" +#include "Core/SysConf.h" namespace IOS { diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp index 11b0da139e..454eddc37b 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp @@ -15,7 +15,6 @@ #include "Common/MsgHandler.h" #include "Common/NandPaths.h" #include "Common/StringUtil.h" -#include "Common/SysConf.h" #include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/Debugger/Debugger_SymbolMap.h" @@ -25,6 +24,7 @@ #include "Core/Host.h" #include "Core/IOS/Device.h" #include "Core/IOS/IOS.h" +#include "Core/SysConf.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" namespace IOS @@ -42,8 +42,7 @@ namespace Device BluetoothEmu::BluetoothEmu(Kernel& ios, const std::string& device_name) : BluetoothBase(ios, device_name) { - SysConf sysconf{Core::WantsDeterminism() ? Common::FromWhichRoot::FROM_SESSION_ROOT : - Common::FromWhichRoot::FROM_CONFIGURED_ROOT}; + SysConf sysconf{ios.GetFS()}; if (!Core::WantsDeterminism()) BackUpBTInfoSection(&sysconf); diff --git a/Source/Core/Common/SysConf.cpp b/Source/Core/Core/SysConf.cpp similarity index 85% rename from Source/Core/Common/SysConf.cpp rename to Source/Core/Core/SysConf.cpp index 22e902d042..6efb18a729 100644 --- a/Source/Core/Common/SysConf.cpp +++ b/Source/Core/Core/SysConf.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include "Common/SysConf.h" +#include "Core/SysConf.h" #include #include @@ -14,6 +14,7 @@ #include "Common/FileUtil.h" #include "Common/Logging/Log.h" #include "Common/Swap.h" +#include "Core/IOS/FS/FileSystem.h" constexpr size_t SYSCONF_SIZE = 0x4000; @@ -35,9 +36,8 @@ static size_t GetNonArrayEntrySize(SysConf::Entry::Type type) return 0; } } -SysConf::SysConf(const Common::FromWhichRoot root_type) +SysConf::SysConf(std::shared_ptr fs) : m_fs{fs} { - m_file_name = Common::RootUserPath(root_type) + DIR_SEP WII_SYSCONF_DIR DIR_SEP WII_SYSCONF; Load(); } @@ -55,39 +55,40 @@ void SysConf::Load() { Clear(); - if (File::GetSize(m_file_name) != SYSCONF_SIZE || !LoadFromFile(m_file_name)) + const auto file = m_fs->OpenFile(IOS::HLE::FS::Uid{0}, IOS::HLE::FS::Gid{0}, + "/shared2/sys/SYSCONF", IOS::HLE::FS::Mode::Read); + if (!file || file->GetStatus()->size != SYSCONF_SIZE || !LoadFromFile(*file)) { WARN_LOG(CORE, "No valid SYSCONF detected. Creating a new one."); InsertDefaultEntries(); } } -bool SysConf::LoadFromFile(const std::string& file_name) +bool SysConf::LoadFromFile(const IOS::HLE::FS::FileHandle& file) { - File::IOFile file(file_name, "rb"); - file.Seek(4, SEEK_SET); + file.Seek(4, IOS::HLE::FS::SeekMode::Set); u16 number_of_entries; - file.ReadBytes(&number_of_entries, sizeof(number_of_entries)); + file.Read(&number_of_entries, 1); number_of_entries = Common::swap16(number_of_entries); std::vector offsets(number_of_entries); for (u16& offset : offsets) { - file.ReadBytes(&offset, sizeof(offset)); + file.Read(&offset, 1); offset = Common::swap16(offset); } for (const u16 offset : offsets) { - file.Seek(offset, SEEK_SET); + file.Seek(offset, IOS::HLE::FS::SeekMode::Set); // Metadata u8 description = 0; - file.ReadBytes(&description, sizeof(description)); + file.Read(&description, 1); const Entry::Type type = static_cast((description & 0xe0) >> 5); const u8 name_length = (description & 0x1f) + 1; std::string name(name_length, '\0'); - file.ReadBytes(&name[0], name.size()); + file.Read(&name[0], name.size()); // Data std::vector data; @@ -96,7 +97,7 @@ bool SysConf::LoadFromFile(const std::string& file_name) case Entry::Type::BigArray: { u16 data_length = 0; - file.ReadBytes(&data_length, sizeof(data_length)); + file.Read(&data_length, 1); // The stored u16 is length - 1, not length. data.resize(Common::swap16(data_length) + 1); break; @@ -104,7 +105,7 @@ bool SysConf::LoadFromFile(const std::string& file_name) case Entry::Type::SmallArray: { u8 data_length = 0; - file.ReadBytes(&data_length, sizeof(data_length)); + file.Read(&data_length, 1); data.resize(data_length + 1); break; } @@ -121,7 +122,7 @@ bool SysConf::LoadFromFile(const std::string& file_name) return false; } - file.ReadBytes(data.data(), data.size()); + file.Read(data.data(), data.size()); AddEntry({type, name, std::move(data)}); } return true; @@ -194,14 +195,19 @@ bool SysConf::Save() const std::copy(footer.cbegin(), footer.cend(), buffer.end() - footer.size()); // Write the new data. - const std::string temp_file = m_file_name + ".tmp"; - File::CreateFullPath(temp_file); + const std::string temp_file = "/tmp/SYSCONF"; + constexpr u32 SYSMENU_UID = 0x1000; + constexpr u16 SYSMENU_GID = 1; + constexpr auto rw_mode = IOS::HLE::FS::Mode::ReadWrite; { - File::IOFile file(temp_file, "wb"); - if (!file.WriteBytes(buffer.data(), buffer.size())) + m_fs->CreateFile(SYSMENU_UID, SYSMENU_GID, temp_file, 0, rw_mode, rw_mode, rw_mode); + auto file = m_fs->OpenFile(SYSMENU_UID, SYSMENU_GID, temp_file, IOS::HLE::FS::Mode::Write); + if (!file || !file->Write(buffer.data(), buffer.size())) return false; } - return File::RenameSync(temp_file, m_file_name); + m_fs->CreateDirectory(SYSMENU_UID, SYSMENU_GID, "/shared2/sys", 0, rw_mode, rw_mode, rw_mode); + const auto result = m_fs->Rename(SYSMENU_UID, SYSMENU_GID, temp_file, "/shared2/sys/SYSCONF"); + return result == IOS::HLE::FS::ResultCode::Success; } SysConf::Entry::Entry(Type type_, const std::string& name_) : type(type_), name(name_) diff --git a/Source/Core/Common/SysConf.h b/Source/Core/Core/SysConf.h similarity index 89% rename from Source/Core/Common/SysConf.h rename to Source/Core/Core/SysConf.h index 92ff1c6718..241254e749 100644 --- a/Source/Core/Common/SysConf.h +++ b/Source/Core/Core/SysConf.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include @@ -14,10 +15,16 @@ #include "Common/CommonTypes.h" #include "Common/NandPaths.h" +namespace IOS::HLE::FS +{ +class FileHandle; +class FileSystem; +} + class SysConf final { public: - explicit SysConf(Common::FromWhichRoot root_type); + explicit SysConf(std::shared_ptr fs); ~SysConf(); void Clear(); @@ -85,8 +92,8 @@ public: private: void InsertDefaultEntries(); - bool LoadFromFile(const std::string& file_name); + bool LoadFromFile(const IOS::HLE::FS::FileHandle& file); - std::string m_file_name; std::vector m_entries; + std::shared_ptr m_fs; }; diff --git a/Source/Core/Core/WiiRoot.cpp b/Source/Core/Core/WiiRoot.cpp index f6d696a435..a705801fc1 100644 --- a/Source/Core/Core/WiiRoot.cpp +++ b/Source/Core/Core/WiiRoot.cpp @@ -11,10 +11,11 @@ #include "Common/Logging/Log.h" #include "Common/NandPaths.h" #include "Common/StringUtil.h" -#include "Common/SysConf.h" #include "Core/ConfigManager.h" +#include "Core/IOS/IOS.h" #include "Core/Movie.h" #include "Core/NetPlayClient.h" +#include "Core/SysConf.h" namespace Core { @@ -64,7 +65,7 @@ void InitializeWiiRoot(bool use_temporary) WARN_LOG(IOS_FS, "Using temporary directory %s for minimal Wii FS", s_temp_wii_root.c_str()); File::SetUserPath(D_SESSION_WIIROOT_IDX, s_temp_wii_root); // Generate a SYSCONF with default settings for the temporary Wii NAND. - SysConf sysconf{Common::FromWhichRoot::FROM_SESSION_ROOT}; + SysConf sysconf{IOS::HLE::Kernel{}.GetFS()}; sysconf.Save(); InitializeDeterministicWiiSaves(); diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp index 2c509cd5ca..931c400d4b 100644 --- a/Source/Core/Core/WiiUtils.cpp +++ b/Source/Core/Core/WiiUtils.cpp @@ -29,13 +29,13 @@ #include "Common/NandPaths.h" #include "Common/StringUtil.h" #include "Common/Swap.h" -#include "Common/SysConf.h" #include "Core/CommonTitles.h" #include "Core/ConfigManager.h" #include "Core/IOS/Device.h" #include "Core/IOS/ES/ES.h" #include "Core/IOS/ES/Formats.h" #include "Core/IOS/IOS.h" +#include "Core/SysConf.h" #include "DiscIO/DiscExtractor.h" #include "DiscIO/Enums.h" #include "DiscIO/Filesystem.h" @@ -136,7 +136,7 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::WiiWAD& wad, InstallType in } // Delete a previous temporary title, if it exists. - SysConf sysconf{Common::FROM_SESSION_ROOT}; + SysConf sysconf{ios.GetFS()}; SysConf::Entry* tid_entry = sysconf.GetOrAddEntry("IPL.TID", SysConf::Entry::Type::LongLong); if (const u64 previous_temporary_title_id = Common::swap64(tid_entry->GetData(0))) ios.GetES()->DeleteTitleContent(previous_temporary_title_id); diff --git a/Source/Core/DolphinWX/GameListCtrl.cpp b/Source/Core/DolphinWX/GameListCtrl.cpp index 6c893bccf3..c0f7303e90 100644 --- a/Source/Core/DolphinWX/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/GameListCtrl.cpp @@ -39,7 +39,6 @@ #include "Common/CommonTypes.h" #include "Common/FileUtil.h" #include "Common/StringUtil.h" -#include "Common/SysConf.h" #include "Common/Thread.h" #include "Core/Boot/Boot.h" #include "Core/Config/NetplaySettings.h" @@ -48,6 +47,7 @@ #include "Core/HW/DVD/DVDInterface.h" #include "Core/HW/WiiSaveCrypted.h" #include "Core/Movie.h" +#include "Core/SysConf.h" #include "Core/TitleDatabase.h" #include "Core/WiiUtils.h" #include "DiscIO/Blob.h" diff --git a/Source/Core/DolphinWX/VideoConfigDiag.cpp b/Source/Core/DolphinWX/VideoConfigDiag.cpp index ab9c983bb1..e3ad121d0c 100644 --- a/Source/Core/DolphinWX/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/VideoConfigDiag.cpp @@ -24,10 +24,10 @@ #include "Common/Assert.h" #include "Common/FileUtil.h" -#include "Common/SysConf.h" #include "Core/Config/SYSCONFSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" +#include "Core/SysConf.h" #include "DolphinWX/DolphinSlider.h" #include "DolphinWX/Frame.h" #include "DolphinWX/Main.h"