Implement working prodinfo blanking.

This commit is contained in:
Michael Scire
2019-05-23 03:10:32 -07:00
parent 3bba035b84
commit 967f14fc7e
13 changed files with 239 additions and 82 deletions

View File

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

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

View File

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

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