mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
Merge branch 'master' into emunand_dev
This commit is contained in:
commit
837b30d075
19 changed files with 97 additions and 215 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue