diff --git a/app/src/main/cpp/skyline/vfs/backing.h b/app/src/main/cpp/skyline/vfs/backing.h index 1a96fa67..d0f76b9a 100644 --- a/app/src/main/cpp/skyline/vfs/backing.h +++ b/app/src/main/cpp/skyline/vfs/backing.h @@ -11,12 +11,27 @@ namespace skyline::vfs { */ class Backing { public: + /** + * @brief This describes the modes that a backing is capable of + */ + union Mode { + struct { + bool read : 1; //!< The backing is readable + bool write : 1; //!< The backing is writable + bool append : 1; //!< The backing can be appended + }; + u32 raw; //!< The raw value of the mode + }; + static_assert(sizeof(Mode) == 0x4); + + Mode mode; //!< The mode of the backing size_t size; //!< The size of the backing in bytes /** + * @param mode The mode to use for the backing * @param size The initial size of the backing */ - Backing(size_t size = 0) : size(size) {} + Backing(Mode mode = {true, false, false}, size_t size = 0) : mode(mode), size(size) {} /* Delete the move constructor to prevent multiple instances of the same backing */ Backing(const Backing &) = delete; diff --git a/app/src/main/cpp/skyline/vfs/os_backing.cpp b/app/src/main/cpp/skyline/vfs/os_backing.cpp index 55a74e26..6bd9e1af 100644 --- a/app/src/main/cpp/skyline/vfs/os_backing.cpp +++ b/app/src/main/cpp/skyline/vfs/os_backing.cpp @@ -7,7 +7,7 @@ #include "os_backing.h" namespace skyline::vfs { - OsBacking::OsBacking(int fd) : fd(fd) { + OsBacking::OsBacking(int fd) : Backing(), fd(fd) { struct stat fileInfo; if (fstat(fd, &fileInfo)) @@ -17,6 +17,9 @@ namespace skyline::vfs { } size_t OsBacking::Read(u8 *output, size_t offset, size_t size) { + if (!mode.read) + throw exception("Attempting to read a backing that is not readable"); + auto ret = pread64(fd, output, size, offset); if (ret < 0) diff --git a/app/src/main/cpp/skyline/vfs/region_backing.h b/app/src/main/cpp/skyline/vfs/region_backing.h index 8e8c25c1..84fcfb14 100644 --- a/app/src/main/cpp/skyline/vfs/region_backing.h +++ b/app/src/main/cpp/skyline/vfs/region_backing.h @@ -20,9 +20,12 @@ namespace skyline::vfs { * @param offset The offset of the region start within the parent backing * @param size The size of the region in the parent backing */ - RegionBacking(const std::shared_ptr &backing, size_t offset, size_t size) : Backing(size), backing(backing), offset(offset) {}; + RegionBacking(const std::shared_ptr &backing, size_t offset, size_t size, Mode mode = {true, false, false}) : Backing(mode, size), backing(backing), offset(offset) {}; inline size_t Read(u8 *output, size_t offset, size_t size) { + if (!mode.read) + throw exception("Attempting to read a backing that is not readable"); + size = std::min(offset + size, this->size) - offset; return backing->Read(output, this->offset + offset, size);