diff --git a/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_reboot_manager.cpp b/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_reboot_manager.cpp index 98f37bcf1..a7701ccd8 100644 --- a/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_reboot_manager.cpp +++ b/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_reboot_manager.cpp @@ -39,7 +39,7 @@ void BpcRebootManager::Initialize() { /* Read payload file. */ size_t actual_size; - fsFileRead(&payload_file, 0, g_reboot_payload, IRAM_PAYLOAD_MAX_SIZE, &actual_size); + fsFileRead(&payload_file, 0, g_reboot_payload, IRAM_PAYLOAD_MAX_SIZE, FS_READOPTION_NONE, &actual_size); g_payload_loaded = true; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp index e7ec6596a..5ba3747ae 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp @@ -48,13 +48,13 @@ class DirectorySaveDataFile : public IFile { virtual Result FlushImpl() override { return this->base_file->Flush(); } - virtual Result WriteImpl(u64 offset, void *buffer, u64 size, bool flush) override { - return this->base_file->Write(offset, buffer, size, flush); + virtual Result WriteImpl(u64 offset, void *buffer, u64 size, u32 option) override { + return this->base_file->Write(offset, buffer, size, option); } virtual Result SetSizeImpl(u64 size) override { return this->base_file->SetSize(size); } - virtual Result OperateRangeImpl(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { + virtual Result OperateRangeImpl(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { return this->base_file->OperateRange(operation_type, offset, size, out_range_info); } }; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp index f4e154f7d..55fecc95b 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp @@ -45,7 +45,12 @@ Result FileStorage::Read(void *buffer, size_t size, u64 offset) { return ResultFsOutOfRange; } - return this->file->Read(&read_size, offset, buffer, size); + /* Nintendo doesn't do check output read size, but we will for safety. */ + R_TRY(this->file->Read(&read_size, offset, buffer, size)); + if (read_size != size && read_size) { + return this->Read(reinterpret_cast(reinterpret_cast(buffer) + read_size), size - read_size, offset + read_size); + } + return ResultSuccess; } Result FileStorage::Write(void *buffer, size_t size, u64 offset) { @@ -85,14 +90,14 @@ Result FileStorage::SetSize(u64 size) { return this->file->SetSize(size); } -Result FileStorage::OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) { +Result FileStorage::OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) { Result rc; switch (operation_type) { - case 2: /* TODO: OperationType_Invalidate */ - case 3: /* TODO: OperationType_Query */ + case FsOperationId_InvalidateCache: + case FsOperationId_QueryRange: if (size == 0) { - if (operation_type == 3) { + if (operation_type == FsOperationId_QueryRange) { if (out_range_info == nullptr) { return ResultFsNullptrArgument; } diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.hpp b/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.hpp index 6b21383e4..58f4da8f4 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.hpp @@ -50,5 +50,5 @@ class FileStorage : public IStorage { virtual Result Flush() override; virtual Result GetSize(u64 *out_size) override; virtual Result SetSize(u64 size) override; - virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override; + virtual Result OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override; }; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_ifile.hpp b/stratosphere/ams_mitm/source/fs_mitm/fs_ifile.hpp index 10f58477d..f07cb0d03 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_ifile.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_ifile.hpp @@ -70,8 +70,7 @@ class IFile { if (buffer == nullptr) { return ResultFsNullptrArgument; } - const bool flush = (flags & 1) != 0; - return WriteImpl(offset, buffer, size, flush); + return WriteImpl(offset, buffer, size, flags); } Result Write(uint64_t offset, void *buffer, uint64_t size, bool flush = false) { @@ -88,8 +87,8 @@ class IFile { return SetSizeImpl(size); } - Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) { - if (operation_type == 3) { + Result OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) { + if (operation_type == FsOperationId_QueryRange) { return OperateRangeImpl(operation_type, offset, size, out_range_info); } return ResultFsUnsupportedOperation; @@ -101,9 +100,9 @@ class IFile { virtual Result ReadImpl(u64 *out, u64 offset, void *buffer, u64 size) = 0; virtual Result GetSizeImpl(u64 *out) = 0; virtual Result FlushImpl() = 0; - virtual Result WriteImpl(u64 offset, void *buffer, u64 size, bool flush) = 0; + virtual Result WriteImpl(u64 offset, void *buffer, u64 size, u32 option) = 0; virtual Result SetSizeImpl(u64 size) = 0; - virtual Result OperateRangeImpl(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) = 0; + virtual Result OperateRangeImpl(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) = 0; }; class IFileInterface : public IServiceObject { @@ -135,7 +134,7 @@ class IFileInterface : public IServiceObject { return this->base_file->GetSize(size.GetPointer()); }; virtual Result OperateRange(Out range_info, u32 operation_type, u64 offset, u64 size) final { - return this->base_file->OperateRange(operation_type, offset, size, range_info.GetPointer()); + return this->base_file->OperateRange(static_cast(operation_type), offset, size, range_info.GetPointer()); }; public: DEFINE_SERVICE_DISPATCH_TABLE { @@ -174,7 +173,7 @@ class ProxyFile : public IFile { virtual Result ReadImpl(u64 *out, u64 offset, void *buffer, u64 size) override { size_t out_sz; - Result rc = fsFileRead(this->base_file.get(), offset, buffer, size, &out_sz); + Result rc = fsFileRead(this->base_file.get(), offset, buffer, size, FS_READOPTION_NONE, &out_sz); if (R_SUCCEEDED(rc)) { *out = out_sz; } @@ -187,18 +186,13 @@ class ProxyFile : public IFile { virtual Result FlushImpl() override { return fsFileFlush(this->base_file.get()); } - virtual Result WriteImpl(u64 offset, void *buffer, u64 size, bool flush) override { - Result rc = fsFileWrite(this->base_file.get(), offset, buffer, size); - if (R_SUCCEEDED(rc)) { - /* libnx doesn't allow passing the flush flag. */ - rc = fsFileFlush(this->base_file.get()); - } - return rc; + virtual Result WriteImpl(u64 offset, void *buffer, u64 size, u32 option) override { + return fsFileWrite(this->base_file.get(), offset, buffer, size, option); } virtual Result SetSizeImpl(u64 size) override { return fsFileSetSize(this->base_file.get(), size); } - virtual Result OperateRangeImpl(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { + virtual Result OperateRangeImpl(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { return fsFileOperateRange(this->base_file.get(), operation_type, offset, size, out_range_info); } }; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_istorage.hpp b/stratosphere/ams_mitm/source/fs_mitm/fs_istorage.hpp index 34ace2eb9..32705292b 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_istorage.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_istorage.hpp @@ -39,7 +39,7 @@ class IStorage { virtual Result Flush() = 0; virtual Result SetSize(u64 size) = 0; virtual Result GetSize(u64 *out_size) = 0; - virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) = 0; + virtual Result OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) = 0; static inline bool IsRangeValid(uint64_t offset, uint64_t size, uint64_t total_size) { return size <= total_size && offset <= total_size - size; @@ -76,7 +76,7 @@ class IStorageInterface : public IServiceObject { return this->base_storage->GetSize(size.GetPointer()); }; virtual Result OperateRange(Out range_info, u32 operation_type, u64 offset, u64 size) final { - return this->base_storage->OperateRange(operation_type, offset, size, range_info.GetPointer()); + return this->base_storage->OperateRange(static_cast(operation_type), offset, size, range_info.GetPointer()); }; public: DEFINE_SERVICE_DISPATCH_TABLE { @@ -109,7 +109,7 @@ class IROStorage : public IStorage { return ResultFsUnsupportedOperation; }; virtual Result GetSize(u64 *out_size) = 0; - virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) = 0; + virtual Result OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) = 0; }; @@ -143,33 +143,33 @@ class ProxyStorage : public IStorage { virtual Result SetSize(u64 size) override { return fsStorageSetSize(this->base_storage, size); }; - virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { + virtual Result OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { return fsStorageOperateRange(this->base_storage, operation_type, offset, size, out_range_info); }; }; -class ROProxyStorage : public IROStorage { +class ReadOnlyStorageAdapter : public IROStorage { private: - FsStorage *base_storage; + std::shared_ptr base_storage; + IStorage *storage; public: - ROProxyStorage(FsStorage *s) : base_storage(s) { + ReadOnlyStorageAdapter(IStorage *s) : base_storage(s) { + this->storage = this->base_storage.get(); + } + ReadOnlyStorageAdapter(std::shared_ptr s) : base_storage(s) { + this->storage = this->base_storage.get(); + } + virtual ~ReadOnlyStorageAdapter() { /* ... */ - }; - ROProxyStorage(FsStorage s) { - this->base_storage = new FsStorage(s); - }; - virtual ~ROProxyStorage() { - fsStorageClose(base_storage); - delete base_storage; - }; + } public: virtual Result Read(void *buffer, size_t size, u64 offset) override { - return fsStorageRead(this->base_storage, offset, buffer, size); + return this->base_storage->Read(buffer, size, offset); }; virtual Result GetSize(u64 *out_size) override { - return fsStorageGetSize(this->base_storage, out_size); + return this->base_storage->GetSize(out_size); }; - virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { - return fsStorageOperateRange(this->base_storage, operation_type, offset, size, out_range_info); + virtual Result OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { + return this->base_storage->OperateRange(operation_type, offset, size, out_range_info); }; -}; \ No newline at end of file +}; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_shim.c b/stratosphere/ams_mitm/source/fs_mitm/fs_shim.c index 524584b94..02470f76e 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_shim.c +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_shim.c @@ -19,7 +19,7 @@ #include "fs_shim.h" /* Missing fsp-srv commands. */ -Result fsOpenBisStorageFwd(Service* s, FsStorage* out, u32 PartitionId) { +Result fsOpenBisStorageFwd(Service* s, FsStorage* out, FsBisStorageId PartitionId) { IpcCommand c; ipcInitialize(&c); @@ -264,85 +264,3 @@ Result fsOpenSaveDataFileSystemFwd(Service *s, FsFileSystem* out, u8 inval, FsSa return rc; } - -/* Missing FS File commands. */ -Result fsFileOperateRange(FsFile* f, u32 op_id, u64 off, u64 len, FsRangeInfo *out) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u32 op_id; - u64 off; - u64 len; - } *raw; - - raw = serviceIpcPrepareHeader(&f->s, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 5; - raw->op_id = op_id; - raw->off = off; - raw->len = len; - - Result rc = serviceIpcDispatch(&f->s); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - FsRangeInfo range_info; - } *resp; - - serviceIpcParse(&f->s, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc) && out) *out = resp->range_info; - } - - return rc; -} - -/* Missing FS Storage commands. */ -Result fsStorageOperateRange(FsStorage* s, u32 op_id, u64 off, u64 len, FsRangeInfo *out) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u32 op_id; - u64 off; - u64 len; - } *raw; - - raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 5; - raw->op_id = op_id; - raw->off = off; - raw->len = len; - - Result rc = serviceIpcDispatch(&s->s); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - FsRangeInfo range_info; - } *resp; - - serviceIpcParse(&s->s, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - if (R_SUCCEEDED(rc) && out) *out = resp->range_info; - } - - return rc; -} \ No newline at end of file diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_shim.h b/stratosphere/ams_mitm/source/fs_mitm/fs_shim.h index fa163fe7e..96b0fc0fc 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_shim.h +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_shim.h @@ -11,25 +11,14 @@ extern "C" { #endif -/* TODO: Reverse this more. */ -typedef struct { - u32 flags[0x40/sizeof(u32)]; -} FsRangeInfo; - /* Missing fsp-srv commands. */ -Result fsOpenBisStorageFwd(Service* s, FsStorage* out, u32 PartitionId); +Result fsOpenBisStorageFwd(Service* s, FsStorage* out, FsBisStorageId PartitionId); Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out); Result fsOpenDataStorageByDataIdFwd(Service* s, FsStorageId storage_id, u64 data_id, FsStorage* out); Result fsOpenFileSystemWithPatchFwd(Service* s, FsFileSystem* out, u64 titleId, FsFileSystemType fsType); Result fsOpenFileSystemWithIdFwd(Service* s, FsFileSystem* out, u64 titleId, FsFileSystemType fsType, const char* contentPath); Result fsOpenSaveDataFileSystemFwd(Service* s, FsFileSystem* out, u8 inval, FsSave *save); -/* Missing FS File commands. */ -Result fsFileOperateRange(FsFile* f, u32 op_id, u64 off, u64 len, FsRangeInfo *out); - -/* Missing FS Storage commands. */ -Result fsStorageOperateRange(FsStorage* s, u32 op_id, u64 off, u64 len, FsRangeInfo *out); - #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.cpp index 95fd7e687..c57738971 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.cpp @@ -23,7 +23,7 @@ IStorage::~IStorage() = default; -LayeredRomFS::LayeredRomFS(std::shared_ptr s_r, std::shared_ptr f_r, u64 tid) : storage_romfs(s_r), file_romfs(f_r), title_id(tid) { +LayeredRomFS::LayeredRomFS(std::shared_ptr s_r, std::shared_ptr f_r, u64 tid) : storage_romfs(s_r), file_romfs(f_r), title_id(tid) { /* Start building the new virtual romfs. */ RomFSBuildContext build_ctx(this->title_id); this->p_source_infos = std::shared_ptr>(new std::vector(), [](std::vector *to_delete) { @@ -95,7 +95,7 @@ Result LayeredRomFS::Read(void *buffer, size_t size, u64 offset) { fatalSimple(rc); } size_t out_read; - if (R_FAILED((rc = fsFileRead(&file, (offset - cur_source->virtual_offset), (void *)((uintptr_t)buffer + read_so_far), cur_read_size, &out_read)))) { + if (R_FAILED((rc = fsFileRead(&file, (offset - cur_source->virtual_offset), (void *)((uintptr_t)buffer + read_so_far), cur_read_size, FS_READOPTION_NONE, &out_read)))) { fatalSimple(rc); } if (out_read != cur_read_size) { @@ -111,7 +111,7 @@ Result LayeredRomFS::Read(void *buffer, size_t size, u64 offset) { fatalSimple(rc); } size_t out_read; - if (R_FAILED((rc = fsFileRead(&file, (offset - cur_source->virtual_offset), (void *)((uintptr_t)buffer + read_so_far), cur_read_size, &out_read)))) { + if (R_FAILED((rc = fsFileRead(&file, (offset - cur_source->virtual_offset), (void *)((uintptr_t)buffer + read_so_far), cur_read_size, FS_READOPTION_NONE, &out_read)))) { fatalSimple(rc); } if (out_read != cur_read_size) { @@ -164,9 +164,9 @@ Result LayeredRomFS::GetSize(u64 *out_size) { *out_size = (*this->p_source_infos)[this->p_source_infos->size() - 1].virtual_offset + (*this->p_source_infos)[this->p_source_infos->size() - 1].size; return ResultSuccess; } -Result LayeredRomFS::OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) { +Result LayeredRomFS::OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) { /* TODO: How should I implement this for a virtual romfs? */ - if (operation_type == 3) { + if (operation_type == FsOperationId_QueryRange) { *out_range_info = {0}; } return ResultSuccess; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.hpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.hpp index cebf07a89..e06de07d4 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_layeredrom.hpp @@ -18,7 +18,7 @@ #include #include -#include "fsmitm_romstorage.hpp" +#include "fs_istorage.hpp" #include "fsmitm_romfsbuild.hpp" #include "../utils.hpp" @@ -27,17 +27,17 @@ class LayeredRomFS : public IROStorage { private: /* Data Sources. */ - std::shared_ptr storage_romfs; - std::shared_ptr file_romfs; + std::shared_ptr storage_romfs; + std::shared_ptr file_romfs; /* Information about the merged RomFS. */ u64 title_id; std::shared_ptr> p_source_infos; public: - LayeredRomFS(std::shared_ptr s_r, std::shared_ptr f_r, u64 tid); + LayeredRomFS(std::shared_ptr s_r, std::shared_ptr f_r, u64 tid); virtual ~LayeredRomFS() = default; virtual Result Read(void *buffer, size_t size, u64 offset) override; virtual Result GetSize(u64 *out_size) override; - virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override; + virtual Result OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override; }; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfsbuild.hpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfsbuild.hpp index 2079ebcfe..d59ebe583 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfsbuild.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfsbuild.hpp @@ -19,9 +19,8 @@ #include #include -#include "fsmitm_romstorage.hpp" - #include "../debug.hpp" +#include "fs_istorage.hpp" #define ROMFS_ENTRY_EMPTY 0xFFFFFFFF #define ROMFS_FILEPARTITION_OFS 0x200 @@ -65,7 +64,7 @@ struct RomFSSourceInfo { RomFSFileSourceInfo file_source_info; RomFSLooseSourceInfo loose_source_info; RomFSMemorySourceInfo memory_source_info; - RomFSMemorySourceInfo metadata_source_info; + RomFSMetaDataSourceInfo metadata_source_info; }; RomFSDataSource type; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romstorage.hpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romstorage.hpp index 779f4db4e..b3c531d64 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romstorage.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romstorage.hpp @@ -38,7 +38,7 @@ class RomFileStorage : public IROStorage { public: Result Read(void *buffer, size_t size, u64 offset) override { size_t out_sz = 0; - Result rc = fsFileRead(this->base_file, offset, buffer, size, &out_sz); + Result rc = fsFileRead(this->base_file, offset, buffer, size, FS_READOPTION_NONE, &out_sz); if (R_SUCCEEDED(rc) && out_sz != size && out_sz) { return this->Read((void *)((uintptr_t)buffer + out_sz), size - out_sz, offset + out_sz); } @@ -47,7 +47,7 @@ class RomFileStorage : public IROStorage { Result GetSize(u64 *out_size) override { return fsFileGetSize(this->base_file, out_size); }; - Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { + Result OperateRange(FsOperationId operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override { /* TODO: Merge into libnx? */ return fsFileOperateRange(this->base_file, operation_type, offset, size, out_range_info); }; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp index 3ce545193..c3a5a9113 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp @@ -25,11 +25,11 @@ #include "../utils.hpp" #include "fsmitm_boot0storage.hpp" -#include "fsmitm_romstorage.hpp" #include "fsmitm_layeredrom.hpp" #include "fs_dir_utils.hpp" #include "fs_save_utils.hpp" +#include "fs_file_storage.hpp" #include "fs_subdirectory_filesystem.hpp" #include "fs_directory_savedata_filesystem.hpp" @@ -241,10 +241,11 @@ Result FsMitmService::OpenSaveDataFileSystem(Out> out_storage, u32 bis_partition_id) { +Result FsMitmService::OpenBisStorage(Out> out_storage, u32 _bis_partition_id) { std::shared_ptr storage = nullptr; u32 out_domain_id = 0; Result rc = ResultSuccess; + const FsBisStorageId bis_partition_id = static_cast(_bis_partition_id); ON_SCOPE_EXIT { if (R_SUCCEEDED(rc)) { @@ -262,12 +263,12 @@ Result FsMitmService::OpenBisStorage(Out> out const bool is_sysmodule = TitleIdIsSystem(this->title_id); const bool has_bis_write_flag = Utils::HasFlag(this->title_id, "bis_write"); const bool has_cal0_read_flag = Utils::HasFlag(this->title_id, "cal_read"); - if (bis_partition_id == BisStorageId_Boot0) { + if (bis_partition_id == FsBisStorageId_Boot0) { storage = std::make_shared(new Boot0Storage(bis_storage, this->title_id)); - } else if (bis_partition_id == BisStorageId_Prodinfo) { + } else if (bis_partition_id == FsBisStorageId_CalibrationBinary) { /* PRODINFO should *never* be writable. */ if (is_sysmodule || has_cal0_read_flag) { - storage = std::make_shared(new ROProxyStorage(bis_storage)); + storage = std::make_shared(new ReadOnlyStorageAdapter(new ProxyStorage(bis_storage))); } else { /* Do not allow non-sysmodules to read *or* write CAL0. */ fsStorageClose(&bis_storage); @@ -279,14 +280,15 @@ Result FsMitmService::OpenBisStorage(Out> out /* Sysmodules should still be allowed to read and write. */ storage = std::make_shared(new ProxyStorage(bis_storage)); } else if (Utils::IsHblTid(this->title_id) && - ((BisStorageId_BcPkg2_1 <= bis_partition_id && bis_partition_id <= BisStorageId_BcPkg2_6) || bis_partition_id == BisStorageId_Boot1)) { + ((FsBisStorageId_BootConfigAndPackage2NormalMain <= bis_partition_id && bis_partition_id <= FsBisStorageId_BootConfigAndPackage2RepairSub) || + bis_partition_id == FsBisStorageId_Boot1)) { /* Allow HBL to write to boot1 (safe firm) + package2. */ /* This is needed to not break compatibility with ChoiDujourNX, which does not check for write access before beginning an update. */ /* TODO: get fixed so that this can be turned off without causing bricks :/ */ storage = std::make_shared(new ProxyStorage(bis_storage)); } else { /* Non-sysmodules should be allowed to read. */ - storage = std::make_shared(new ROProxyStorage(bis_storage)); + storage = std::make_shared(new ReadOnlyStorageAdapter(new ProxyStorage(bis_storage))); } } if (out_storage.IsDomain()) { @@ -348,9 +350,9 @@ Result FsMitmService::OpenDataStorageByCurrentProcess(Outtitle_id)) { /* TODO: Is there a sensible path that ends in ".romfs" we can use?" */ if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(this->title_id, "romfs.bin", FS_OPEN_READ, &data_file))) { - storage = std::make_shared(new LayeredRomFS(std::make_shared(data_storage), std::make_shared(data_file), this->title_id)); + storage = std::make_shared(new LayeredRomFS(std::make_shared(new ProxyStorage(data_storage)), std::make_shared(new FileStorage(new ProxyFile(data_file))), this->title_id)); } else { - storage = std::make_shared(new LayeredRomFS(std::make_shared(data_storage), nullptr, this->title_id)); + storage = std::make_shared(new LayeredRomFS(std::make_shared(new ProxyStorage(data_storage)), nullptr, this->title_id)); } if (out_storage.IsDomain()) { out_domain_id = data_storage.s.object_id; @@ -415,9 +417,9 @@ Result FsMitmService::OpenDataStorageByDataId(Out(new LayeredRomFS(std::make_shared(data_storage), std::make_shared(data_file), data_id)); + storage = std::make_shared(new LayeredRomFS(std::make_shared(new ProxyStorage(data_storage)), std::make_shared(new FileStorage(new ProxyFile(data_file))), data_id)); } else { - storage = std::make_shared(new LayeredRomFS(std::make_shared(data_storage), nullptr, data_id)); + storage = std::make_shared(new LayeredRomFS(std::make_shared(new ProxyStorage(data_storage)), nullptr, data_id)); } if (out_storage.IsDomain()) { out_domain_id = data_storage.s.object_id; diff --git a/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp b/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp index 2fc433e4e..ef483d696 100644 --- a/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp @@ -263,7 +263,7 @@ void SettingsItemManager::LoadConfiguration() { /* Read from file. */ if (R_SUCCEEDED(rc)) { size_t actual_size; - rc = fsFileRead(&config_file, 0, config_buf, 0xFFFF, &actual_size); + rc = fsFileRead(&config_file, 0, config_buf, 0xFFFF, FS_READOPTION_NONE, &actual_size); } if (R_SUCCEEDED(rc)) { diff --git a/stratosphere/ams_mitm/source/utils.cpp b/stratosphere/ams_mitm/source/utils.cpp index 1304c31a7..d208d7829 100644 --- a/stratosphere/ams_mitm/source/utils.cpp +++ b/stratosphere/ams_mitm/source/utils.cpp @@ -99,7 +99,7 @@ void Utils::InitializeThreadFunc(void *args) { fsFsCreateDirectory(&g_sd_filesystem, "/atmosphere/automatic_backups"); { FsStorage cal0_storage; - if (R_FAILED(fsOpenBisStorage(&cal0_storage, BisStorageId_Prodinfo)) || R_FAILED(fsStorageRead(&cal0_storage, 0, g_cal0_storage_backup, ProdinfoSize))) { + if (R_FAILED(fsOpenBisStorage(&cal0_storage, FsBisStorageId_CalibrationBinary)) || R_FAILED(fsStorageRead(&cal0_storage, 0, g_cal0_storage_backup, ProdinfoSize))) { std::abort(); } fsStorageClose(&cal0_storage); @@ -119,7 +119,7 @@ void Utils::InitializeThreadFunc(void *args) { if (R_SUCCEEDED(fsFsOpenFile(&g_sd_filesystem, prodinfo_backup_path, FS_OPEN_READ | FS_OPEN_WRITE, &g_cal0_file))) { bool has_auto_backup = false; size_t read = 0; - if (R_SUCCEEDED(fsFileRead(&g_cal0_file, 0, g_cal0_backup, sizeof(g_cal0_backup), &read)) && read == sizeof(g_cal0_backup)) { + if (R_SUCCEEDED(fsFileRead(&g_cal0_file, 0, g_cal0_backup, sizeof(g_cal0_backup), FS_READOPTION_NONE, &read)) && read == sizeof(g_cal0_backup)) { bool is_cal0_valid = true; is_cal0_valid &= memcmp(g_cal0_backup, "CAL0", 4) == 0; is_cal0_valid &= memcmp(g_cal0_backup + 0x250, serial_number, 0x18) == 0; @@ -135,8 +135,7 @@ void Utils::InitializeThreadFunc(void *args) { if (!has_auto_backup) { fsFileSetSize(&g_cal0_file, ProdinfoSize); - fsFileWrite(&g_cal0_file, 0, g_cal0_storage_backup, ProdinfoSize); - fsFileFlush(&g_cal0_file); + fsFileWrite(&g_cal0_file, 0, g_cal0_storage_backup, ProdinfoSize, FS_WRITEOPTION_FLUSH); } /* NOTE: g_cal0_file is intentionally not closed here. This prevents any other process from opening it. */ @@ -378,7 +377,7 @@ Result Utils::SaveSdFileForAtmosphere(u64 title_id, const char *fn, void *data, } /* Try to write the data. */ - rc = fsFileWrite(&f, 0, data, size); + rc = fsFileWrite(&f, 0, data, size, FS_WRITEOPTION_FLUSH); return rc; } @@ -614,7 +613,7 @@ OverrideKey Utils::GetTitleOverrideKey(u64 tid) { ON_SCOPE_EXIT { free(config_buf); }; /* Read title ini contents. */ - fsFileRead(&cfg_file, 0, config_buf, config_file_size, &config_file_size); + fsFileRead(&cfg_file, 0, config_buf, config_file_size, FS_READOPTION_NONE, &config_file_size); /* Parse title ini. */ ini_parse_string(config_buf, FsMitmTitleSpecificIniHandler, &cfg); @@ -672,7 +671,7 @@ OverrideLocale Utils::GetTitleOverrideLocale(u64 tid) { ON_SCOPE_EXIT { free(config_buf); }; /* Read title ini contents. */ - fsFileRead(&cfg_file, 0, config_buf, config_file_size, &config_file_size); + fsFileRead(&cfg_file, 0, config_buf, config_file_size, FS_READOPTION_NONE, &config_file_size); /* Parse title ini. */ ini_parse_string(config_buf, FsMitmTitleSpecificLocaleIniHandler, &locale); @@ -698,7 +697,7 @@ void Utils::RefreshConfiguration() { /* Read in string. */ std::fill(g_config_ini_data, g_config_ini_data + 0x800, 0); size_t r_s; - fsFileRead(&config_file, 0, g_config_ini_data, size, &r_s); + fsFileRead(&config_file, 0, g_config_ini_data, size, FS_READOPTION_NONE, &r_s); fsFileClose(&config_file); ini_parse_string(g_config_ini_data, FsMitmIniHandler, NULL); diff --git a/stratosphere/ams_mitm/source/utils.hpp b/stratosphere/ams_mitm/source/utils.hpp index a3e9ce4ab..02c300dc4 100644 --- a/stratosphere/ams_mitm/source/utils.hpp +++ b/stratosphere/ams_mitm/source/utils.hpp @@ -18,25 +18,6 @@ #include #include -enum BisStorageId : u32 { - BisStorageId_Boot0 = 0, - BisStorageId_Boot1 = 10, - BisStorageId_RawNand = 20, - BisStorageId_BcPkg2_1 = 21, - BisStorageId_BcPkg2_2 = 22, - BisStorageId_BcPkg2_3 = 23, - BisStorageId_BcPkg2_4 = 24, - BisStorageId_BcPkg2_5 = 25, - BisStorageId_BcPkg2_6 = 26, - BisStorageId_Prodinfo = 27, - BisStorageId_ProdinfoF = 28, - BisStorageId_Safe = 29, - BisStorageId_User = 30, - BisStorageId_System = 31, - BisStorageId_SystemProperEncryption = 32, - BisStorageId_SystemProperPartition = 33, -}; - struct OverrideKey { u64 key_combination; bool override_by_default; diff --git a/stratosphere/boot/source/boot_calibration.cpp b/stratosphere/boot/source/boot_calibration.cpp index 67bfadab4..9971b255b 100644 --- a/stratosphere/boot/source/boot_calibration.cpp +++ b/stratosphere/boot/source/boot_calibration.cpp @@ -21,8 +21,6 @@ static constexpr size_t BatteryLotSize = 0x20; static constexpr size_t BatteryVersionOffset = 0x4310; static constexpr size_t BatteryVersionSize = 0x10; -static constexpr u32 BisStorageId_Prodinfo = 27; - static constexpr u32 DefaultBatteryVendor = static_cast('A'); static constexpr u32 DefaultBatteryVersion = 0; @@ -57,7 +55,7 @@ static Result ValidateCalibrationCrc16(const void *data, size_t size) { static Result GetBatteryVendorImpl(u32 *vendor) { FsStorage s; - Result rc = fsOpenBisStorage(&s, BisStorageId_Prodinfo); + Result rc = fsOpenBisStorage(&s, FsBisStorageId_CalibrationBinary); if (R_FAILED(rc)) { return rc; } @@ -78,7 +76,7 @@ static Result GetBatteryVendorImpl(u32 *vendor) { static Result GetBatteryVersionImpl(u32 *version) { FsStorage s; - Result rc = fsOpenBisStorage(&s, BisStorageId_Prodinfo); + Result rc = fsOpenBisStorage(&s, FsBisStorageId_CalibrationBinary); if (R_FAILED(rc)) { return rc; } diff --git a/stratosphere/boot/source/updater/updater_bis_management.hpp b/stratosphere/boot/source/updater/updater_bis_management.hpp index b4260c8c0..299109eab 100644 --- a/stratosphere/boot/source/updater/updater_bis_management.hpp +++ b/stratosphere/boot/source/updater/updater_bis_management.hpp @@ -25,10 +25,10 @@ class BisAccessor { static constexpr size_t SectorAlignment = 0x200; private: FsStorage storage = {}; - u32 partition_id; + FsBisStorageId partition_id; bool active; public: - BisAccessor(u32 id) : partition_id(id), active(false) { } + BisAccessor(FsBisStorageId id) : partition_id(id), active(false) { } ~BisAccessor() { if (this->active) { fsStorageClose(&storage); @@ -126,7 +126,7 @@ class PartitionAccessor : public BisAccessor { using EnumType = typename Meta::EnumType; using OffsetSizeType = typename Meta::OffsetSizeType; public: - PartitionAccessor(u32 id) : BisAccessor(id) { } + PartitionAccessor(FsBisStorageId id) : BisAccessor(id) { } private: constexpr const OffsetSizeType *FindEntry(EnumType which) { for (size_t i = 0; i < Meta::NumEntries; i++) { @@ -177,9 +177,6 @@ class PartitionAccessor : public BisAccessor { } }; -static constexpr u32 BisStorageId_Boot0 = 0; -static constexpr u32 BisStorageId_Boot1 = 10; - enum class Package2Type { NormalMain, NormalSub, @@ -189,20 +186,20 @@ enum class Package2Type { RepairSub, }; -static constexpr u32 GetPackage2StorageId(Package2Type which) { +static constexpr FsBisStorageId GetPackage2StorageId(Package2Type which) { switch (which) { case Package2Type::NormalMain: - return 21; + return FsBisStorageId_BootConfigAndPackage2NormalMain; case Package2Type::NormalSub: - return 22; + return FsBisStorageId_BootConfigAndPackage2NormalSub; case Package2Type::SafeMain: - return 23; + return FsBisStorageId_BootConfigAndPackage2SafeMain; case Package2Type::SafeSub: - return 24; + return FsBisStorageId_BootConfigAndPackage2SafeSub; case Package2Type::RepairMain: - return 25; + return FsBisStorageId_BootConfigAndPackage2RepairMain; case Package2Type::RepairSub: - return 26; + return FsBisStorageId_BootConfigAndPackage2RepairSub; default: std::abort(); } @@ -210,7 +207,7 @@ static constexpr u32 GetPackage2StorageId(Package2Type which) { class Boot0Accessor : public PartitionAccessor { public: - static constexpr u32 PartitionId = 0; + static constexpr FsBisStorageId PartitionId = FsBisStorageId_Boot0; static constexpr size_t BctPubkOffset = 0x210; static constexpr size_t BctPubkSize = 0x100; static constexpr size_t BctEksOffset = 0x450; @@ -230,7 +227,7 @@ class Boot0Accessor : public PartitionAccessor { class Boot1Accessor : public PartitionAccessor { public: - static constexpr u32 PartitionId = 10; + static constexpr FsBisStorageId PartitionId = FsBisStorageId_Boot1; public: Boot1Accessor() : PartitionAccessor(PartitionId) { } }; diff --git a/stratosphere/libstratosphere b/stratosphere/libstratosphere index 8f2328975..05c58ef00 160000 --- a/stratosphere/libstratosphere +++ b/stratosphere/libstratosphere @@ -1 +1 @@ -Subproject commit 8f2328975a66519275ada907cbc0000377ce5ede +Subproject commit 05c58ef00263552d4925ed29ac0828cacdfc2ed1