committed by
crueter
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
12 changed files with 281 additions and 52 deletions
-
3src/core/CMakeLists.txt
-
5src/core/file_sys/fssystem/fssystem_bucket_tree.cpp
-
66src/core/file_sys/fssystem/fssystem_hierarchical_sha3_storage.cpp
-
44src/core/file_sys/fssystem/fssystem_hierarchical_sha3_storage.h
-
155src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp
-
7src/core/file_sys/fssystem/fssystem_nca_file_system_driver.h
-
9src/core/file_sys/fssystem/fssystem_nca_header.cpp
-
32src/core/file_sys/fssystem/fssystem_passthrough_storage.h
-
2src/core/hle/service/am/applet.cpp
-
1src/core/hle/service/am/applet.h
-
8src/core/hle/service/am/service/application_functions.cpp
-
1src/core/hle/service/am/service/application_functions.h
@ -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 |
|||
@ -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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue