Implement working prodinfo blanking.
This commit is contained in:
@@ -112,7 +112,6 @@ class IROStorage : public IStorage {
|
||||
virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) = 0;
|
||||
};
|
||||
|
||||
|
||||
class ProxyStorage : public IStorage {
|
||||
private:
|
||||
FsStorage *base_storage;
|
||||
@@ -172,4 +171,4 @@ class ROProxyStorage : public IROStorage {
|
||||
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);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
113
stratosphere/ams_mitm/source/fs_mitm/fs_memory_storage.hpp
Normal file
113
stratosphere/ams_mitm/source/fs_mitm/fs_memory_storage.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
#include "fs_shim.h"
|
||||
|
||||
#include "../debug.hpp"
|
||||
#include "fs_istorage.hpp"
|
||||
|
||||
class MemoryStorage : public IStorage {
|
||||
private:
|
||||
u8 * const buffer;
|
||||
const u64 size;
|
||||
public:
|
||||
MemoryStorage(void *b, u64 sz) : buffer(static_cast<u8 *>(b)), size(sz) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
virtual ~MemoryStorage() {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
virtual Result Read(void *buffer, size_t size, u64 offset) override {
|
||||
if (size == 0) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
if (buffer == nullptr) {
|
||||
return ResultFsNullptrArgument;
|
||||
}
|
||||
if (!IStorage::IsRangeValid(offset, size, this->size)) {
|
||||
return ResultFsOutOfRange;
|
||||
}
|
||||
|
||||
std::memcpy(buffer, this->buffer + offset, size);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
virtual Result Write(void *buffer, size_t size, u64 offset) override {
|
||||
if (size == 0) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
if (buffer == nullptr) {
|
||||
return ResultFsNullptrArgument;
|
||||
}
|
||||
if (!IStorage::IsRangeValid(offset, size, this->size)) {
|
||||
return ResultFsOutOfRange;
|
||||
}
|
||||
|
||||
std::memcpy(this->buffer + offset, buffer, size);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
virtual Result GetSize(u64 *out_size) override {
|
||||
*out_size = this->size;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
virtual Result SetSize(u64 size) override {
|
||||
return ResultFsUnsupportedOperation;
|
||||
}
|
||||
|
||||
virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override {
|
||||
switch (operation_type) {
|
||||
case 2: /* TODO: OperationType_Invalidate */
|
||||
return ResultSuccess;
|
||||
case 3: /* TODO: OperationType_Query */
|
||||
if (out_range_info == nullptr) {
|
||||
return ResultFsNullptrArgument;
|
||||
}
|
||||
/* N checks for size == sizeof(*out_range_info) here, but that's because their wrapper api is bad. */
|
||||
std::memset(out_range_info, 0, sizeof(*out_range_info));
|
||||
return ResultSuccess;
|
||||
default:
|
||||
return ResultFsUnsupportedOperation;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ReadOnlyMemoryStorage : public MemoryStorage {
|
||||
public:
|
||||
ReadOnlyMemoryStorage(const void *b, u64 sz) : MemoryStorage(const_cast<void *>(b), sz) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
virtual ~ReadOnlyMemoryStorage() {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
virtual Result Write(void *buffer, size_t size, u64 offset) override {
|
||||
return ResultFsUnsupportedOperation;
|
||||
}
|
||||
};
|
||||
@@ -27,12 +27,14 @@
|
||||
#include "fsmitm_boot0storage.hpp"
|
||||
#include "fsmitm_romstorage.hpp"
|
||||
#include "fsmitm_layeredrom.hpp"
|
||||
#include "fsmitm_utils.hpp"
|
||||
|
||||
#include "fs_dir_utils.hpp"
|
||||
#include "fs_save_utils.hpp"
|
||||
#include "fs_subdirectory_filesystem.hpp"
|
||||
#include "fs_directory_savedata_filesystem.hpp"
|
||||
#include "fs_file_storage.hpp"
|
||||
#include "fs_memory_storage.hpp"
|
||||
|
||||
#include "../debug.hpp"
|
||||
|
||||
@@ -262,23 +264,13 @@ 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");
|
||||
const bool has_blank_cal0_flag = Utils::HasGlobalFlag("blank_prodinfo");
|
||||
const bool has_blank_cal0_flag = ShouldBlankProdInfo();
|
||||
if (bis_partition_id == BisStorageId_Boot0) {
|
||||
storage = std::make_shared<IStorageInterface>(new Boot0Storage(bis_storage, this->title_id));
|
||||
} else if (bis_partition_id == BisStorageId_Prodinfo) {
|
||||
/* PRODINFO should *never* be writable. */
|
||||
if (has_blank_cal0_flag) {
|
||||
FsFile file;
|
||||
|
||||
if (R_FAILED((rc = Utils::OpenBlankProdInfoFile(&file)))) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
storage = std::make_shared<IStorageInterface>(new FileStorage(new ProxyFile(&file)));
|
||||
if (out_storage.IsDomain()) {
|
||||
out_domain_id = file.s.object_id;
|
||||
}
|
||||
return rc;
|
||||
storage = std::make_shared<IStorageInterface>(new MitmProxyStorage(std::make_unique<ReadOnlyMemoryStorage>(Utils::GetBlankProdInfoBuffer(), ProdInfoSize), bis_storage.s));
|
||||
} else if (is_sysmodule || has_cal0_read_flag) {
|
||||
storage = std::make_shared<IStorageInterface>(new ROProxyStorage(bis_storage));
|
||||
} else {
|
||||
|
||||
59
stratosphere/ams_mitm/source/fs_mitm/fsmitm_utils.hpp
Normal file
59
stratosphere/ams_mitm/source/fs_mitm/fsmitm_utils.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
|
||||
#include "fs_istorage.hpp"
|
||||
|
||||
class MitmProxyStorage : public IStorage {
|
||||
private:
|
||||
Service srv_holder;
|
||||
std::unique_ptr<IStorage> fwd_storage;
|
||||
public:
|
||||
MitmProxyStorage(std::unique_ptr<IStorage> st, Service sr = {}) : srv_holder(sr), fwd_storage(std::move(st)) {
|
||||
/* ... */
|
||||
}
|
||||
virtual ~MitmProxyStorage() {
|
||||
if (serviceIsActive(&srv_holder)) {
|
||||
serviceClose(&srv_holder);
|
||||
}
|
||||
}
|
||||
public:
|
||||
virtual Result Read(void *buffer, size_t size, u64 offset) override {
|
||||
return this->fwd_storage->Read(buffer, size, offset);
|
||||
}
|
||||
|
||||
virtual Result Write(void *buffer, size_t size, u64 offset) override {
|
||||
return this->fwd_storage->Write(buffer, size, offset);
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
return this->fwd_storage->Flush();
|
||||
}
|
||||
|
||||
virtual Result GetSize(u64 *out_size) override {
|
||||
return this->fwd_storage->GetSize(out_size);
|
||||
}
|
||||
|
||||
virtual Result SetSize(u64 size) override {
|
||||
return this->fwd_storage->SetSize(size);
|
||||
}
|
||||
|
||||
virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override {
|
||||
return this->fwd_storage->OperateRange(operation_type, offset, size, out_range_info);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user