Merge branch 'master' into emunand_dev

This commit is contained in:
Michael Scire 2019-06-03 12:22:01 -07:00
commit 837b30d075
19 changed files with 97 additions and 215 deletions

View file

@ -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;

View file

@ -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);
}
};

View file

@ -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<void *>(reinterpret_cast<uintptr_t>(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;
}

View file

@ -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;
};

View file

@ -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<FsRangeInfo> 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<FsOperationId>(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);
}
};

View file

@ -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<FsRangeInfo> 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<FsOperationId>(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<IStorage> 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<IStorage> 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);
};
};

View file

@ -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;
}

View file

@ -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

View file

@ -23,7 +23,7 @@
IStorage::~IStorage() = default;
LayeredRomFS::LayeredRomFS(std::shared_ptr<RomInterfaceStorage> s_r, std::shared_ptr<RomFileStorage> f_r, u64 tid) : storage_romfs(s_r), file_romfs(f_r), title_id(tid) {
LayeredRomFS::LayeredRomFS(std::shared_ptr<IROStorage> s_r, std::shared_ptr<IROStorage> 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<std::vector<RomFSSourceInfo>>(new std::vector<RomFSSourceInfo>(), [](std::vector<RomFSSourceInfo> *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;

View file

@ -18,7 +18,7 @@
#include <switch.h>
#include <stratosphere.hpp>
#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<RomInterfaceStorage> storage_romfs;
std::shared_ptr<RomFileStorage> file_romfs;
std::shared_ptr<IROStorage> storage_romfs;
std::shared_ptr<IROStorage> file_romfs;
/* Information about the merged RomFS. */
u64 title_id;
std::shared_ptr<std::vector<RomFSSourceInfo>> p_source_infos;
public:
LayeredRomFS(std::shared_ptr<RomInterfaceStorage> s_r, std::shared_ptr<RomFileStorage> f_r, u64 tid);
LayeredRomFS(std::shared_ptr<IROStorage> s_r, std::shared_ptr<IROStorage> 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;
};

View file

@ -19,9 +19,8 @@
#include <switch.h>
#include <map>
#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;

View file

@ -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);
};

View file

@ -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_redirection_filesystem.hpp"
#include "fs_directory_savedata_filesystem.hpp"
@ -279,10 +279,11 @@ Result FsMitmService::OpenSaveDataFileSystem(Out<std::shared_ptr<IFileSystemInte
}
/* Gate access to the BIS partitions. */
Result FsMitmService::OpenBisStorage(Out<std::shared_ptr<IStorageInterface>> out_storage, u32 bis_partition_id) {
Result FsMitmService::OpenBisStorage(Out<std::shared_ptr<IStorageInterface>> out_storage, u32 _bis_partition_id) {
std::shared_ptr<IStorageInterface> storage = nullptr;
u32 out_domain_id = 0;
Result rc = ResultSuccess;
const FsBisStorageId bis_partition_id = static_cast<FsBisStorageId>(_bis_partition_id);
ON_SCOPE_EXIT {
if (R_SUCCEEDED(rc)) {
@ -300,12 +301,12 @@ Result FsMitmService::OpenBisStorage(Out<std::shared_ptr<IStorageInterface>> 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<IStorageInterface>(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<IStorageInterface>(new ROProxyStorage(bis_storage));
storage = std::make_shared<IStorageInterface>(new ReadOnlyStorageAdapter(new ProxyStorage(bis_storage)));
} else {
/* Do not allow non-sysmodules to read *or* write CAL0. */
fsStorageClose(&bis_storage);
@ -317,14 +318,15 @@ Result FsMitmService::OpenBisStorage(Out<std::shared_ptr<IStorageInterface>> out
/* Sysmodules should still be allowed to read and write. */
storage = std::make_shared<IStorageInterface>(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<IStorageInterface>(new ProxyStorage(bis_storage));
} else {
/* Non-sysmodules should be allowed to read. */
storage = std::make_shared<IStorageInterface>(new ROProxyStorage(bis_storage));
storage = std::make_shared<IStorageInterface>(new ReadOnlyStorageAdapter(new ProxyStorage(bis_storage)));
}
}
if (out_storage.IsDomain()) {
@ -386,9 +388,9 @@ Result FsMitmService::OpenDataStorageByCurrentProcess(Out<std::shared_ptr<IStora
if (Utils::HasSdRomfsContent(this->title_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<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), this->title_id));
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<ReadOnlyStorageAdapter>(new ProxyStorage(data_storage)), std::make_shared<ReadOnlyStorageAdapter>(new FileStorage(new ProxyFile(data_file))), this->title_id));
} else {
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, this->title_id));
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<ReadOnlyStorageAdapter>(new ProxyStorage(data_storage)), nullptr, this->title_id));
}
if (out_storage.IsDomain()) {
out_domain_id = data_storage.s.object_id;
@ -453,9 +455,9 @@ Result FsMitmService::OpenDataStorageByDataId(Out<std::shared_ptr<IStorageInterf
if (Utils::HasSdRomfsContent(data_id)) {
/* TODO: Is there a sensible path that ends in ".romfs" we can use?" */
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(data_id, "romfs.bin", FS_OPEN_READ, &data_file))) {
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), std::make_shared<RomFileStorage>(data_file), data_id));
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<ReadOnlyStorageAdapter>(new ProxyStorage(data_storage)), std::make_shared<ReadOnlyStorageAdapter>(new FileStorage(new ProxyFile(data_file))), data_id));
} else {
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<RomInterfaceStorage>(data_storage), nullptr, data_id));
storage = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<ReadOnlyStorageAdapter>(new ProxyStorage(data_storage)), nullptr, data_id));
}
if (out_storage.IsDomain()) {
out_domain_id = data_storage.s.object_id;

View file

@ -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)) {

View file

@ -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);

View file

@ -18,25 +18,6 @@
#include <switch.h>
#include <stratosphere.hpp>
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;

View file

@ -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<u32>('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;
}

View file

@ -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<Boot0Meta> {
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<Boot0Meta> {
class Boot1Accessor : public PartitionAccessor<Boot1Meta> {
public:
static constexpr u32 PartitionId = 10;
static constexpr FsBisStorageId PartitionId = FsBisStorageId_Boot1;
public:
Boot1Accessor() : PartitionAccessor<Boot1Meta>(PartitionId) { }
};

@ -1 +1 @@
Subproject commit 44f52b445e9154a18fc0e99b9efc6be78b859495
Subproject commit 05c58ef00263552d4925ed29ac0828cacdfc2ed1