#include #include #include #include #include namespace HLE { namespace OS { class Thread; } namespace IPC { struct StaticBuffer; } namespace PXI { struct PXIBuffer; } // Produce error codes on invalid API usage instead of throwing exceptions. // Used for the test suite, but disabled by default since we expect games to // behave nicely more often than not. // TODO: Expose this through a Setting instead inline constexpr bool test_mode = true; struct Utf8PathType : std::string { std::filesystem::path to_std_path() const { return std::filesystem::path { static_cast(*this) }; } }; struct BinaryPathType : std::vector { }; /** * Helper class for unified path handling. * * Non-binary paths are automatically converted to Utf-8, with trailing \0 characters removed. */ class CommonPath { static constexpr uint32_t max_length = 256; // Unverified. TODO: What's the actual maximum? std::variant data; static CommonPath FromUtf16(std::u16string_view utf16_data); static CommonPath FromUtf16(std::basic_string_view utf16_data); CommonPath(decltype(data) raw) : data(raw) { } template CommonPath(uint32_t type, uint32_t num_bytes, ReadByte&& read); public: CommonPath(OS::Thread& thread, uint32_t type, uint32_t num_bytes, const IPC::StaticBuffer&); CommonPath(OS::Thread& thread, uint32_t type, uint32_t num_bytes, const PXI::PXIBuffer&); template auto Visit(Utf8Handler&& utf8_handler, BinaryHandler&& bin_handler) const { return std::visit( [&](const auto& arg) { if constexpr (std::is_invocable_v) { return std::forward(utf8_handler)(arg); } else { return std::forward(bin_handler)(arg); } }, data); } }; /** * Absolute path verified to be within some sandbox path. * * As long as the "path" member isn't modified, it's save to recursively delete * data from this path without harming the host filesystem */ struct ValidatedHostPath { std::filesystem::path path; operator const std::filesystem::path&() const { return path; } private: ValidatedHostPath(std::filesystem::path path) : path(std::move(path)) {} friend class PathValidator; }; class PathValidator { protected: struct ErrFileNotFound {}; struct ErrDirectoryNotFound {}; struct ErrFileAlreadyExists {}; struct ErrDirectoryAlreadyExists {}; ValidatedHostPath ValidateAndGetSandboxedTreePath(const Utf8PathType&) const; virtual std::filesystem::path GetSandboxHostRoot() const = 0; }; std::filesystem::path GetRootDataDirectory(Settings::Settings& settings); } // namespace HLE