diff options
author | Liam <byteslice@airmail.cc> | 2023-08-11 03:34:43 +0200 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2023-08-15 23:47:25 +0200 |
commit | 86f6b6b7b2d930e8203114332b04a5c49a780b06 (patch) | |
tree | bf7ff58b0a36051d3c3489a40999d80357c570d0 /src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp | |
parent | Merge pull request #11287 from liamwhite/replaced-bytes (diff) | |
download | yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.tar yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.tar.gz yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.tar.bz2 yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.tar.lz yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.tar.xz yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.tar.zst yuzu-86f6b6b7b2d930e8203114332b04a5c49a780b06.zip |
Diffstat (limited to 'src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp')
-rw-r--r-- | src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp b/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp new file mode 100644 index 000000000..b2e031d5f --- /dev/null +++ b/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp @@ -0,0 +1,132 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h" +#include "core/file_sys/vfs_offset.h" + +namespace FileSys { + +HierarchicalIntegrityVerificationStorage::HierarchicalIntegrityVerificationStorage() + : m_data_size(-1) { + for (size_t i = 0; i < MaxLayers - 1; i++) { + m_verify_storages[i] = std::make_shared<IntegrityVerificationStorage>(); + } +} + +Result HierarchicalIntegrityVerificationStorage::Initialize( + const HierarchicalIntegrityVerificationInformation& info, + HierarchicalStorageInformation storage, int max_data_cache_entries, int max_hash_cache_entries, + s8 buffer_level) { + using AlignedStorage = AlignmentMatchingStoragePooledBuffer<1>; + + // Validate preconditions. + ASSERT(IntegrityMinLayerCount <= info.max_layers && info.max_layers <= IntegrityMaxLayerCount); + + // Set member variables. + m_max_layers = info.max_layers; + + // Initialize the top level verification storage. + m_verify_storages[0]->Initialize(storage[HierarchicalStorageInformation::MasterStorage], + storage[HierarchicalStorageInformation::Layer1Storage], + static_cast<s64>(1) << info.info[0].block_order, HashSize, + false); + + // Ensure we don't leak state if further initialization goes wrong. + ON_RESULT_FAILURE { + m_verify_storages[0]->Finalize(); + m_data_size = -1; + }; + + // Initialize the top level buffer storage. + m_buffer_storages[0] = std::make_shared<AlignedStorage>( + m_verify_storages[0], static_cast<s64>(1) << info.info[0].block_order); + R_UNLESS(m_buffer_storages[0] != nullptr, ResultAllocationMemoryFailedAllocateShared); + + // Prepare to initialize the level storages. + s32 level = 0; + + // Ensure we don't leak state if further initialization goes wrong. + ON_RESULT_FAILURE_2 { + m_verify_storages[level + 1]->Finalize(); + for (; level > 0; --level) { + m_buffer_storages[level].reset(); + m_verify_storages[level]->Finalize(); + } + }; + + // Initialize the level storages. + for (; level < m_max_layers - 3; ++level) { + // Initialize the verification storage. + auto buffer_storage = + std::make_shared<OffsetVfsFile>(m_buffer_storages[level], info.info[level].size, 0); + m_verify_storages[level + 1]->Initialize( + std::move(buffer_storage), storage[level + 2], + static_cast<s64>(1) << info.info[level + 1].block_order, + static_cast<s64>(1) << info.info[level].block_order, false); + + // Initialize the buffer storage. + m_buffer_storages[level + 1] = std::make_shared<AlignedStorage>( + m_verify_storages[level + 1], static_cast<s64>(1) << info.info[level + 1].block_order); + R_UNLESS(m_buffer_storages[level + 1] != nullptr, + ResultAllocationMemoryFailedAllocateShared); + } + + // Initialize the final level storage. + { + // Initialize the verification storage. + auto buffer_storage = + std::make_shared<OffsetVfsFile>(m_buffer_storages[level], info.info[level].size, 0); + m_verify_storages[level + 1]->Initialize( + std::move(buffer_storage), storage[level + 2], + static_cast<s64>(1) << info.info[level + 1].block_order, + static_cast<s64>(1) << info.info[level].block_order, true); + + // Initialize the buffer storage. + m_buffer_storages[level + 1] = std::make_shared<AlignedStorage>( + m_verify_storages[level + 1], static_cast<s64>(1) << info.info[level + 1].block_order); + R_UNLESS(m_buffer_storages[level + 1] != nullptr, + ResultAllocationMemoryFailedAllocateShared); + } + + // Set the data size. + m_data_size = info.info[level + 1].size; + + // We succeeded. + R_SUCCEED(); +} + +void HierarchicalIntegrityVerificationStorage::Finalize() { + if (m_data_size >= 0) { + m_data_size = 0; + + for (s32 level = m_max_layers - 2; level >= 0; --level) { + m_buffer_storages[level].reset(); + m_verify_storages[level]->Finalize(); + } + + m_data_size = -1; + } +} + +size_t HierarchicalIntegrityVerificationStorage::Read(u8* buffer, size_t size, + size_t offset) const { + // Validate preconditions. + ASSERT(m_data_size >= 0); + + // Succeed if zero-size. + if (size == 0) { + return size; + } + + // Validate arguments. + ASSERT(buffer != nullptr); + + // Read the data. + return m_buffer_storages[m_max_layers - 2]->Read(buffer, size, offset); +} + +size_t HierarchicalIntegrityVerificationStorage::GetSize() const { + return m_data_size; +} + +} // namespace FileSys |