disable verification
This commit is contained in:
parent
bbcd8aded6
commit
f772730571
|
|
@ -88,6 +88,8 @@ add_library(core STATIC
|
|||
file_sys/fssystem/fssystem_crypto_configuration.h
|
||||
file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp
|
||||
file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h
|
||||
file_sys/fssystem/fssystem_hierarchical_sha3_storage.cpp
|
||||
file_sys/fssystem/fssystem_hierarchical_sha3_storage.h
|
||||
file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp
|
||||
file_sys/fssystem/fssystem_hierarchical_sha256_storage.h
|
||||
file_sys/fssystem/fssystem_indirect_storage.cpp
|
||||
|
|
@ -102,6 +104,7 @@ add_library(core STATIC
|
|||
file_sys/fssystem/fssystem_nca_header.cpp
|
||||
file_sys/fssystem/fssystem_nca_header.h
|
||||
file_sys/fssystem/fssystem_nca_reader.cpp
|
||||
file_sys/fssystem/fssystem_passthrough_storage.h
|
||||
file_sys/fssystem/fssystem_pooled_buffer.cpp
|
||||
file_sys/fssystem/fssystem_pooled_buffer.h
|
||||
file_sys/fssystem/fssystem_sparse_storage.cpp
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -233,7 +236,7 @@ Result BucketTree::Initialize(VirtualFile node_storage, VirtualFile entry_storag
|
|||
void BucketTree::Initialize(size_t node_size, s64 end_offset) {
|
||||
ASSERT(NodeSizeMin <= node_size && node_size <= NodeSizeMax);
|
||||
ASSERT(Common::IsPowerOfTwo(node_size));
|
||||
ASSERT(end_offset > 0);
|
||||
//TODO: ASSERT(end_offset > 0);
|
||||
ASSERT(!this->IsInitialized());
|
||||
|
||||
m_node_size = node_size;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "core/file_sys/fssystem/fssystem_hierarchical_sha3_storage.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
namespace {
|
||||
s32 Log2(s32 value) {
|
||||
ASSERT(value > 0);
|
||||
ASSERT(Common::IsPowerOfTwo(value));
|
||||
s32 log = 0;
|
||||
while ((value >>= 1) > 0) {
|
||||
++log;
|
||||
}
|
||||
return log;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Result HierarchicalSha3Storage::Initialize(VirtualFile* base_storages, s32 layer_count, size_t htbs,
|
||||
void* hash_buf, size_t hash_buf_size) {
|
||||
ASSERT(layer_count == LayerCount);
|
||||
ASSERT(Common::IsPowerOfTwo(htbs));
|
||||
ASSERT(hash_buf != nullptr);
|
||||
|
||||
m_hash_target_block_size = static_cast<s32>(htbs);
|
||||
m_log_size_ratio = Log2(m_hash_target_block_size / HashSize);
|
||||
|
||||
m_base_storage_size = base_storages[2]->GetSize();
|
||||
{
|
||||
auto size_guard = SCOPE_GUARD {
|
||||
m_base_storage_size = 0;
|
||||
};
|
||||
R_UNLESS(m_base_storage_size <= static_cast<s64>(HashSize)
|
||||
<< m_log_size_ratio << m_log_size_ratio,
|
||||
ResultHierarchicalSha256BaseStorageTooLarge);
|
||||
size_guard.Cancel();
|
||||
}
|
||||
|
||||
m_base_storage = base_storages[2];
|
||||
m_hash_buffer = static_cast<char*>(hash_buf);
|
||||
m_hash_buffer_size = hash_buf_size;
|
||||
|
||||
std::array<u8, HashSize> master_hash{};
|
||||
base_storages[0]->ReadObject(std::addressof(master_hash));
|
||||
|
||||
s64 hash_storage_size = base_storages[1]->GetSize();
|
||||
ASSERT(Common::IsAligned(hash_storage_size, HashSize));
|
||||
ASSERT(hash_storage_size <= m_hash_target_block_size);
|
||||
ASSERT(hash_storage_size <= static_cast<s64>(m_hash_buffer_size));
|
||||
|
||||
base_storages[1]->Read(reinterpret_cast<u8*>(m_hash_buffer),
|
||||
static_cast<size_t>(hash_storage_size), 0);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
size_t HierarchicalSha3Storage::Read(u8* buffer, size_t size, size_t offset) const {
|
||||
if (size == 0)
|
||||
return size;
|
||||
ASSERT(buffer != nullptr);
|
||||
return m_base_storage->Read(buffer, size, offset);
|
||||
}
|
||||
|
||||
} // namespace FileSys
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "core/file_sys/errors.h"
|
||||
#include "core/file_sys/fssystem/fs_i_storage.h"
|
||||
#include "core/file_sys/vfs/vfs.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
class HierarchicalSha3Storage : public IReadOnlyStorage {
|
||||
YUZU_NON_COPYABLE(HierarchicalSha3Storage);
|
||||
YUZU_NON_MOVEABLE(HierarchicalSha3Storage);
|
||||
|
||||
public:
|
||||
static constexpr s32 LayerCount = 3;
|
||||
static constexpr size_t HashSize = 256 / 8; // SHA3-256
|
||||
|
||||
public:
|
||||
HierarchicalSha3Storage() : m_mutex() {}
|
||||
|
||||
Result Initialize(VirtualFile* base_storages, s32 layer_count, size_t htbs, void* hash_buf,
|
||||
size_t hash_buf_size);
|
||||
|
||||
virtual size_t GetSize() const override {
|
||||
return m_base_storage->GetSize();
|
||||
}
|
||||
|
||||
virtual size_t Read(u8* buffer, size_t length, size_t offset) const override;
|
||||
|
||||
private:
|
||||
VirtualFile m_base_storage;
|
||||
s64 m_base_storage_size{};
|
||||
char* m_hash_buffer{};
|
||||
size_t m_hash_buffer_size{};
|
||||
s32 m_hash_target_block_size{};
|
||||
s32 m_log_size_ratio{};
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
} // namespace FileSys
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -10,10 +13,12 @@
|
|||
#include "core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_indirect_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_integrity_romfs_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_passthrough_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_memory_resource_buffer_hold_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_nca_file_system_driver.h"
|
||||
#include "core/file_sys/fssystem/fssystem_sparse_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_switch_storage.h"
|
||||
#include "core/file_sys/fssystem/fssystem_hierarchical_sha3_storage.h"
|
||||
#include "core/file_sys/vfs/vfs_offset.h"
|
||||
#include "core/file_sys/vfs/vfs_vector.h"
|
||||
|
||||
|
|
@ -299,18 +304,24 @@ Result NcaFileSystemDriver::CreateStorageByRawStorage(VirtualFile* out,
|
|||
// Process hash/integrity layer.
|
||||
switch (header_reader->GetHashType()) {
|
||||
case NcaFsHeader::HashType::HierarchicalSha256Hash:
|
||||
R_TRY(this->CreateSha256Storage(std::addressof(storage), std::move(storage),
|
||||
header_reader->GetHashData().hierarchical_sha256_data));
|
||||
R_TRY(CreateSha256Storage(&storage, std::move(storage),
|
||||
header_reader->GetHashData().hierarchical_sha256_data));
|
||||
break;
|
||||
case NcaFsHeader::HashType::HierarchicalIntegrityHash:
|
||||
R_TRY(this->CreateIntegrityVerificationStorage(
|
||||
std::addressof(storage), std::move(storage),
|
||||
header_reader->GetHashData().integrity_meta_info));
|
||||
R_TRY(CreateIntegrityVerificationStorage(&storage, std::move(storage),
|
||||
header_reader->GetHashData().integrity_meta_info));
|
||||
break;
|
||||
case NcaFsHeader::HashType::HierarchicalSha3256Hash:
|
||||
R_TRY(CreateSha3Storage(&storage, std::move(storage),
|
||||
header_reader->GetHashData().hierarchical_sha256_data));
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR(Loader, "Unhandled Fs HashType enum={}",
|
||||
static_cast<int>(header_reader->GetHashType()));
|
||||
R_THROW(ResultInvalidNcaFsHeaderHashType);
|
||||
}
|
||||
|
||||
|
||||
// Process compression layer.
|
||||
if (header_reader->ExistsCompressionLayer()) {
|
||||
R_TRY(this->CreateCompressedStorage(
|
||||
|
|
@ -679,6 +690,7 @@ Result NcaFileSystemDriver::CreateSparseStorageMetaStorageWithVerification(
|
|||
|
||||
// Create the verification storage.
|
||||
VirtualFile integrity_storage;
|
||||
|
||||
Result rc = this->CreateIntegrityVerificationStorageForMeta(
|
||||
std::addressof(integrity_storage), out_layer_info_storage, std::move(decrypted_storage),
|
||||
meta_offset, meta_data_hash_data_info);
|
||||
|
|
@ -734,8 +746,26 @@ Result NcaFileSystemDriver::CreateSparseStorageWithVerification(
|
|||
NcaHeader::CtrBlockSize)));
|
||||
|
||||
// Check the meta data hash type.
|
||||
R_UNLESS(meta_data_hash_type == NcaFsHeader::MetaDataHashType::HierarchicalIntegrity,
|
||||
ResultRomNcaInvalidSparseMetaDataHashType);
|
||||
if (meta_data_hash_type != NcaFsHeader::MetaDataHashType::HierarchicalIntegrity) {
|
||||
LOG_ERROR(Loader, "Sparse meta hash type {} not supported for verification; mounting sparse data WITHOUT verification (temporary).", static_cast<int>(meta_data_hash_type));
|
||||
|
||||
R_TRY(this->CreateBodySubStorage(std::addressof(body_substorage),
|
||||
sparse_info.physical_offset,
|
||||
sparse_info.GetPhysicalSize()));
|
||||
|
||||
// Create sparse core directly (no meta verification)
|
||||
std::shared_ptr<SparseStorage> sparse_storage_fallback;
|
||||
R_TRY(this->CreateSparseStorageCore(std::addressof(sparse_storage_fallback),
|
||||
body_substorage, sparse_info.GetPhysicalSize(),
|
||||
/*meta_storage*/ body_substorage, // dummy; not used
|
||||
sparse_info, false));
|
||||
|
||||
if (out_sparse_storage)
|
||||
*out_sparse_storage = sparse_storage_fallback;
|
||||
*out_fs_data_offset = fs_offset;
|
||||
*out = std::move(sparse_storage_fallback);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
// Create the meta storage.
|
||||
VirtualFile meta_storage;
|
||||
|
|
@ -1093,6 +1123,56 @@ Result NcaFileSystemDriver::CreatePatchMetaStorage(
|
|||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result NcaFileSystemDriver::CreateSha3Storage(
|
||||
VirtualFile* out, VirtualFile base_storage,
|
||||
const NcaFsHeader::HashData::HierarchicalSha256Data& hash_data) {
|
||||
ASSERT(out != nullptr);
|
||||
ASSERT(base_storage != nullptr);
|
||||
|
||||
using VerificationStorage = HierarchicalSha3Storage;
|
||||
|
||||
R_UNLESS(Common::IsPowerOfTwo(hash_data.hash_block_size),
|
||||
ResultInvalidHierarchicalSha256BlockSize);
|
||||
R_UNLESS(hash_data.hash_layer_count == VerificationStorage::LayerCount - 1,
|
||||
ResultInvalidHierarchicalSha256LayerCount);
|
||||
|
||||
const auto& hash_region = hash_data.hash_layer_region[0];
|
||||
const auto& data_region = hash_data.hash_layer_region[1];
|
||||
|
||||
constexpr s32 CacheBlockCount = 2;
|
||||
const auto hash_buffer_size = static_cast<size_t>(hash_region.size);
|
||||
const auto cache_buffer_size = CacheBlockCount * hash_data.hash_block_size;
|
||||
const auto total_buffer_size = hash_buffer_size + cache_buffer_size;
|
||||
|
||||
auto buffer_hold_storage = std::make_shared<MemoryResourceBufferHoldStorage>(
|
||||
std::move(base_storage), total_buffer_size);
|
||||
R_UNLESS(buffer_hold_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
|
||||
R_UNLESS(buffer_hold_storage->IsValid(), ResultAllocationMemoryFailedInNcaFileSystemDriverI);
|
||||
|
||||
s64 base_size = buffer_hold_storage->GetSize();
|
||||
R_UNLESS(hash_region.offset + hash_region.size <= base_size, ResultNcaBaseStorageOutOfRangeC);
|
||||
R_UNLESS(data_region.offset + data_region.size <= base_size, ResultNcaBaseStorageOutOfRangeC);
|
||||
|
||||
auto master_hash_storage =
|
||||
std::make_shared<ArrayVfsFile<sizeof(Hash)>>(hash_data.fs_data_master_hash.value);
|
||||
|
||||
auto verification_storage = std::make_shared<VerificationStorage>();
|
||||
R_UNLESS(verification_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
|
||||
|
||||
std::array<VirtualFile, VerificationStorage::LayerCount> layer_storages{
|
||||
std::make_shared<OffsetVfsFile>(master_hash_storage, sizeof(Hash), 0),
|
||||
std::make_shared<OffsetVfsFile>(buffer_hold_storage, hash_region.size, hash_region.offset),
|
||||
std::make_shared<OffsetVfsFile>(buffer_hold_storage, data_region.size, data_region.offset),
|
||||
};
|
||||
|
||||
R_TRY(verification_storage->Initialize(layer_storages.data(), VerificationStorage::LayerCount,
|
||||
hash_data.hash_block_size,
|
||||
buffer_hold_storage->GetBuffer(), hash_buffer_size));
|
||||
|
||||
*out = std::move(verification_storage);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result NcaFileSystemDriver::CreateSha256Storage(
|
||||
VirtualFile* out, VirtualFile base_storage,
|
||||
const NcaFsHeader::HashData::HierarchicalSha256Data& hash_data) {
|
||||
|
|
@ -1160,6 +1240,7 @@ Result NcaFileSystemDriver::CreateSha256Storage(
|
|||
Result NcaFileSystemDriver::CreateIntegrityVerificationStorage(
|
||||
VirtualFile* out, VirtualFile base_storage,
|
||||
const NcaFsHeader::HashData::IntegrityMetaInfo& meta_info) {
|
||||
|
||||
R_RETURN(this->CreateIntegrityVerificationStorageImpl(
|
||||
out, base_storage, meta_info, 0, IntegrityDataCacheCount, IntegrityHashCacheCount,
|
||||
HierarchicalIntegrityVerificationStorage::GetDefaultDataCacheBufferLevel(
|
||||
|
|
@ -1208,63 +1289,41 @@ Result NcaFileSystemDriver::CreateIntegrityVerificationStorageForMeta(
|
|||
Result NcaFileSystemDriver::CreateIntegrityVerificationStorageImpl(
|
||||
VirtualFile* out, VirtualFile base_storage,
|
||||
const NcaFsHeader::HashData::IntegrityMetaInfo& meta_info, s64 layer_info_offset,
|
||||
int max_data_cache_entries, int max_hash_cache_entries, s8 buffer_level) {
|
||||
// Validate preconditions.
|
||||
int /*max_data_cache_entries*/, int /*max_hash_cache_entries*/, s8 /*buffer_level*/) {
|
||||
// Preconditions
|
||||
ASSERT(out != nullptr);
|
||||
ASSERT(base_storage != nullptr);
|
||||
ASSERT(layer_info_offset >= 0);
|
||||
|
||||
// Define storage types.
|
||||
using VerificationStorage = HierarchicalIntegrityVerificationStorage;
|
||||
using StorageInfo = VerificationStorage::HierarchicalStorageInformation;
|
||||
// Read IVFC layout
|
||||
HierarchicalIntegrityVerificationInformation lhi{};
|
||||
std::memcpy(std::addressof(lhi), std::addressof(meta_info.level_hash_info), sizeof(lhi));
|
||||
|
||||
// Validate the meta info.
|
||||
HierarchicalIntegrityVerificationInformation level_hash_info;
|
||||
std::memcpy(std::addressof(level_hash_info), std::addressof(meta_info.level_hash_info),
|
||||
sizeof(level_hash_info));
|
||||
|
||||
R_UNLESS(IntegrityMinLayerCount <= level_hash_info.max_layers,
|
||||
R_UNLESS(IntegrityMinLayerCount <= lhi.max_layers,
|
||||
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
|
||||
R_UNLESS(level_hash_info.max_layers <= IntegrityMaxLayerCount,
|
||||
R_UNLESS(lhi.max_layers <= IntegrityMaxLayerCount,
|
||||
ResultInvalidNcaHierarchicalIntegrityVerificationLayerCount);
|
||||
|
||||
// Get the base storage size.
|
||||
s64 base_storage_size = base_storage->GetSize();
|
||||
const auto& data_li = lhi.info[lhi.max_layers - 2];
|
||||
|
||||
// Create storage info.
|
||||
StorageInfo storage_info;
|
||||
for (s32 i = 0; i < static_cast<s32>(level_hash_info.max_layers - 2); ++i) {
|
||||
const auto& layer_info = level_hash_info.info[i];
|
||||
R_UNLESS(layer_info_offset + layer_info.offset + layer_info.size <= base_storage_size,
|
||||
ResultNcaBaseStorageOutOfRangeD);
|
||||
const s64 base_size = base_storage->GetSize();
|
||||
|
||||
storage_info[i + 1] = std::make_shared<OffsetVfsFile>(
|
||||
base_storage, layer_info.size, layer_info_offset + layer_info.offset);
|
||||
}
|
||||
|
||||
// Set the last layer info.
|
||||
const auto& layer_info = level_hash_info.info[level_hash_info.max_layers - 2];
|
||||
const s64 last_layer_info_offset = layer_info_offset > 0 ? 0LL : layer_info.offset.Get();
|
||||
R_UNLESS(last_layer_info_offset + layer_info.size <= base_storage_size,
|
||||
ResultNcaBaseStorageOutOfRangeD);
|
||||
// Compute the data layer window
|
||||
const s64 data_off = (layer_info_offset > 0) ? 0LL : data_li.offset.Get();
|
||||
R_UNLESS(data_off + data_li.size <= base_size, ResultNcaBaseStorageOutOfRangeD);
|
||||
if (layer_info_offset > 0) {
|
||||
R_UNLESS(last_layer_info_offset + layer_info.size <= layer_info_offset,
|
||||
R_UNLESS(data_off + data_li.size <= layer_info_offset,
|
||||
ResultRomNcaInvalidIntegrityLayerInfoOffset);
|
||||
}
|
||||
storage_info.SetDataStorage(std::make_shared<OffsetVfsFile>(
|
||||
std::move(base_storage), layer_info.size, last_layer_info_offset));
|
||||
|
||||
// Make the integrity romfs storage.
|
||||
auto integrity_storage = std::make_shared<IntegrityRomFsStorage>();
|
||||
R_UNLESS(integrity_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
|
||||
// TODO: Passthrough (temporary compatibility: integrity disabled)
|
||||
auto data_view = std::make_shared<OffsetVfsFile>(base_storage, data_li.size, data_off);
|
||||
R_UNLESS(data_view != nullptr, ResultAllocationMemoryFailedAllocateShared);
|
||||
|
||||
// Initialize the integrity storage.
|
||||
R_TRY(integrity_storage->Initialize(level_hash_info, meta_info.master_hash, storage_info,
|
||||
max_data_cache_entries, max_hash_cache_entries,
|
||||
buffer_level));
|
||||
auto passthrough = std::make_shared<PassthroughStorage>(std::move(data_view));
|
||||
R_UNLESS(passthrough != nullptr, ResultAllocationMemoryFailedAllocateShared);
|
||||
|
||||
// Set the output.
|
||||
*out = std::move(integrity_storage);
|
||||
*out = std::move(passthrough);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -329,6 +332,10 @@ private:
|
|||
const NcaPatchInfo& patch_info,
|
||||
const NcaMetaDataHashDataInfo& meta_data_hash_data_info);
|
||||
|
||||
|
||||
Result CreateSha3Storage(VirtualFile* out, VirtualFile base_storage,
|
||||
const NcaFsHeader::HashData::HierarchicalSha256Data& hash_data);
|
||||
|
||||
Result CreateSha256Storage(VirtualFile* out, VirtualFile base_storage,
|
||||
const NcaFsHeader::HashData::HierarchicalSha256Data& sha256_data);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
@ -10,11 +13,13 @@ u8 NcaHeader::GetProperKeyGeneration() const {
|
|||
}
|
||||
|
||||
bool NcaPatchInfo::HasIndirectTable() const {
|
||||
return this->indirect_size != 0;
|
||||
static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'};
|
||||
return std::memcmp(indirect_header.data(), BKTR, sizeof(BKTR)) == 0;
|
||||
}
|
||||
|
||||
bool NcaPatchInfo::HasAesCtrExTable() const {
|
||||
return this->aes_ctr_ex_size != 0;
|
||||
static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'};
|
||||
return std::memcmp(aes_ctr_ex_header.data(), BKTR, sizeof(BKTR)) == 0;
|
||||
}
|
||||
|
||||
} // namespace FileSys
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
#include "core/file_sys/fssystem/fs_i_storage.h"
|
||||
#include "core/file_sys/vfs/vfs.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
//TODO: No integrity verification.
|
||||
class PassthroughStorage final : public IReadOnlyStorage {
|
||||
YUZU_NON_COPYABLE(PassthroughStorage);
|
||||
YUZU_NON_MOVEABLE(PassthroughStorage);
|
||||
|
||||
public:
|
||||
explicit PassthroughStorage(VirtualFile base) : base_(std::move(base)) {}
|
||||
~PassthroughStorage() override = default;
|
||||
|
||||
size_t Read(u8* buffer, size_t size, size_t offset) const override {
|
||||
if (!base_ || size == 0)
|
||||
return 0;
|
||||
return base_->Read(buffer, size, offset);
|
||||
}
|
||||
size_t GetSize() const override {
|
||||
return base_ ? base_->GetSize() : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
VirtualFile base_{};
|
||||
};
|
||||
|
||||
} // namespace FileSys
|
||||
|
|
@ -12,7 +12,7 @@ Applet::Applet(Core::System& system, std::unique_ptr<Process> process_, bool is_
|
|||
process(std::move(process_)), hid_registration(system, *process),
|
||||
gpu_error_detected_event(context), friend_invitation_storage_channel_event(context),
|
||||
notification_storage_channel_event(context), health_warning_disappeared_system_event(context),
|
||||
acquired_sleep_lock_event(context), pop_from_general_channel_event(context),
|
||||
unknown_event(context), acquired_sleep_lock_event(context), pop_from_general_channel_event(context),
|
||||
library_applet_launchable_event(context), accumulated_suspended_tick_changed_event(context),
|
||||
sleep_lock_event(context), state_changed_event(context) {
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ struct Applet {
|
|||
Event friend_invitation_storage_channel_event;
|
||||
Event notification_storage_channel_event;
|
||||
Event health_warning_disappeared_system_event;
|
||||
Event unknown_event;
|
||||
Event acquired_sleep_lock_event;
|
||||
Event pop_from_general_channel_event;
|
||||
Event library_applet_launchable_event;
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_
|
|||
{181, nullptr, "UpgradeLaunchRequiredVersion"},
|
||||
{190, nullptr, "SendServerMaintenanceOverlayNotification"},
|
||||
{200, nullptr, "GetLastApplicationExitReason"},
|
||||
{210, D<&IApplicationFunctions::GetUnknownEvent210>, "Unknown210"},
|
||||
{500, nullptr, "StartContinuousRecordingFlushForDebug"},
|
||||
{1000, nullptr, "CreateMovieMaker"},
|
||||
{1001, D<&IApplicationFunctions::PrepareForJit>, "PrepareForJit"},
|
||||
|
|
@ -487,6 +488,13 @@ Result IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(
|
|||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationFunctions::GetUnknownEvent210(
|
||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
*out_event = m_applet->unknown_event.GetHandle();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IApplicationFunctions::PrepareForJit() {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ private:
|
|||
Result TryPopFromFriendInvitationStorageChannel(Out<SharedPointer<IStorage>> out_storage);
|
||||
Result GetNotificationStorageChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
Result GetHealthWarningDisappearedSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
Result GetUnknownEvent210(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||
Result PrepareForJit();
|
||||
|
||||
const std::shared_ptr<Applet> m_applet;
|
||||
|
|
|
|||
Loading…
Reference in New Issue