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