diff --git a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_partition_file_system_meta.hpp b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_partition_file_system_meta.hpp index ee8e89472..619dee581 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_partition_file_system_meta.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_partition_file_system_meta.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 Atmosphère-NX + * Copyright (c) 2018-2020 Adubbz, 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, @@ -32,10 +32,12 @@ namespace ams::fssystem { static_assert(std::is_pod::value); #pragma pack(pop) - static constexpr char VersionSignature[] = { 'P', 'F', 'S', '0' }; + static constexpr const char VersionSignature[] = { 'P', 'F', 'S', '0' }; static constexpr size_t EntryNameLengthMax = ::ams::fs::EntryNameLengthMax; static constexpr size_t FileDataAlignmentSize = 0x20; + + using ResultSignatureVerificationFailed = fs::ResultPartitionSignatureVerificationFailed; }; } @@ -50,7 +52,6 @@ namespace ams::fssystem { struct PartitionFileSystemHeader; using PartitionEntry = typename Format::PartitionEntry; - using ResultSignatureVerificationFailed = fs::ResultSha256PartitionSignatureVerificationFailed; protected: bool initialized; PartitionFileSystemHeader *header; @@ -60,9 +61,9 @@ namespace ams::fssystem { MemoryResource *allocator; char *buffer; public: - PartitionFileSystemMetaCore() { /* ... */ } + PartitionFileSystemMetaCore() : initialized(false), allocator(nullptr), buffer(nullptr) { /* ... */ } ~PartitionFileSystemMetaCore(); - + Result Initialize(fs::IStorage *storage, MemoryResource *allocator); Result Initialize(fs::IStorage *storage, void *header, size_t header_size); @@ -72,7 +73,8 @@ namespace ams::fssystem { const char *GetEntryName(s32 index) const; size_t GetHeaderSize() const; size_t GetMetaDataSize() const; - Result QueryMetaDataSize(size_t *out_size, fs::IStorage *storage) const; + public: + static Result QueryMetaDataSize(size_t *out_size, fs::IStorage *storage); protected: void DeallocateBuffer(); }; diff --git a/libraries/libstratosphere/source/fssystem/fssystem_partition_file_system_meta.cpp b/libraries/libstratosphere/source/fssystem/fssystem_partition_file_system_meta.cpp index 4e7aeb87a..0daa64e75 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_partition_file_system_meta.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_partition_file_system_meta.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 Atmosphère-NX + * Copyright (c) 2018-2020 Adubbz, 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, @@ -19,11 +19,13 @@ namespace ams::fssystem { template struct PartitionFileSystemMetaCore::PartitionFileSystemHeader { - u32 signature; + char signature[sizeof(Format::VersionSignature)]; s32 entry_count; u32 name_table_size; u32 reserved; }; + static_assert(std::is_pod::value); + static_assert(sizeof(PartitionFileSystemMeta::PartitionFileSystemHeader) == 0x10); template PartitionFileSystemMetaCore::~PartitionFileSystemMetaCore() { @@ -32,14 +34,17 @@ namespace ams::fssystem { template Result PartitionFileSystemMetaCore::Initialize(fs::IStorage *storage, MemoryResource *allocator) { + /* Validate preconditions. */ + AMS_ASSERT(allocator != nullptr); + /* Determine the meta data size. */ R_TRY(this->QueryMetaDataSize(std::addressof(this->meta_data_size), storage)); /* Deallocate any old meta buffer and allocate a new one. */ this->DeallocateBuffer(); this->allocator = allocator; - this->buffer = reinterpret_cast(this->allocator->Allocate(this->meta_data_size)); - R_UNLESS(this->buffer != nullptr, fs::ResultAllocationFailureInPartitionFileSystemMetaCore()); + this->buffer = static_cast(this->allocator->Allocate(this->meta_data_size)); + R_UNLESS(this->buffer != nullptr, fs::ResultAllocationFailureInPartitionFileSystemMetaA()); /* Perform regular initialization. */ return this->Initialize(storage, this->buffer, this->meta_data_size); @@ -55,12 +60,12 @@ namespace ams::fssystem { /* Set and validate the header. */ this->header = reinterpret_cast(meta); - R_UNLESS(crypto::IsSameBytes(this->header, Format::VersionSignature, sizeof(Format::VersionSignature)), ResultSignatureVerificationFailed()); + R_UNLESS(crypto::IsSameBytes(this->header->signature, Format::VersionSignature, sizeof(Format::VersionSignature)), typename Format::ResultSignatureVerificationFailed()); /* Setup entries and name table. */ const size_t entries_size = this->header->entry_count * sizeof(typename Format::PartitionEntry); - this->entries = reinterpret_cast(reinterpret_cast(meta) + sizeof(PartitionFileSystemHeader)); - this->name_table = reinterpret_cast(meta) + sizeof(PartitionFileSystemHeader) + entries_size; + this->entries = reinterpret_cast(static_cast(meta) + sizeof(PartitionFileSystemHeader)); + this->name_table = static_cast(meta) + sizeof(PartitionFileSystemHeader) + entries_size; /* Validate size for header + entries + name table. */ R_UNLESS(meta_size >= sizeof(PartitionFileSystemHeader) + entries_size + this->header->name_table_size, fs::ResultInvalidSize()); @@ -84,7 +89,7 @@ namespace ams::fssystem { template const typename Format::PartitionEntry *PartitionFileSystemMetaCore::GetEntry(s32 index) const { - if (this->initialized && index >= 0 && index < this->header->entry_count) { + if (this->initialized && 0 <= index && index < static_cast(this->header->entry_count)) { return std::addressof(this->entries[index]); } return nullptr; @@ -100,32 +105,33 @@ namespace ams::fssystem { template s32 PartitionFileSystemMetaCore::GetEntryIndex(const char *name) const { - if (this->initialized) { - for (s32 i = 0; i < this->header->entry_count; i++) { - const auto &entry = this->entries[i]; - - /* Name offset is invalid. */ - if (entry.name_offset >= this->header->name_table_size) { - return 0; - } - - /* Compare to input name. */ - const s32 max_count = this->header->name_table_size - entry.name_offset; - if (std::strncmp(std::addressof(this->name_table[entry.name_offset]), name, max_count) == 0) { - return i; - } - } - - /* Not found. */ - return -1; + /* Fail if not initialized. */ + if (!this->initialized) { + return 0; } - return 0; + for (s32 i = 0; i < static_cast(this->header->entry_count); i++) { + const auto &entry = this->entries[i]; + + /* Name offset is invalid. */ + if (entry.name_offset >= this->header->name_table_size) { + return 0; + } + + /* Compare to input name. */ + const s32 max_name_len = this->header->name_table_size - entry.name_offset; + if (std::strncmp(std::addressof(this->name_table[entry.name_offset]), name, max_name_len) == 0) { + return i; + } + } + + /* Not found. */ + return -1; } template const char *PartitionFileSystemMetaCore::GetEntryName(s32 index) const { - if (this->initialized && index < this->header->entry_count) { + if (this->initialized && index < static_cast(this->header->entry_count)) { return std::addressof(this->name_table[this->GetEntry(index)->name_offset]); } return nullptr; @@ -142,13 +148,11 @@ namespace ams::fssystem { } template - Result PartitionFileSystemMetaCore::QueryMetaDataSize(size_t *out_size, fs::IStorage *storage) const { - AMS_ABORT_UNLESS(allocator != nullptr); - + Result PartitionFileSystemMetaCore::QueryMetaDataSize(size_t *out_size, fs::IStorage *storage) { /* Read and validate the header. */ PartitionFileSystemHeader header; R_TRY(storage->Read(0, std::addressof(header), sizeof(PartitionFileSystemHeader))); - R_UNLESS(crypto::IsSameBytes(std::addressof(header), Format::VersionSignature, sizeof(Format::VersionSignature)), ResultSignatureVerificationFailed()); + R_UNLESS(crypto::IsSameBytes(std::addressof(header), Format::VersionSignature, sizeof(Format::VersionSignature)), typename Format::ResultSignatureVerificationFailed()); /* Output size. */ *out_size = sizeof(PartitionFileSystemHeader) + header.entry_count * sizeof(typename Format::PartitionEntry) + header.name_table_size; diff --git a/libraries/libvapours/include/vapours/results/fs_results.hpp b/libraries/libvapours/include/vapours/results/fs_results.hpp index 76f77445d..eb8bde043 100644 --- a/libraries/libvapours/include/vapours/results/fs_results.hpp +++ b/libraries/libvapours/include/vapours/results/fs_results.hpp @@ -75,7 +75,8 @@ namespace ams::fs { R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemB, 3248); R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemC, 3249); R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321); - R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaCore, 3350); + R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaA, 3350); + R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaB, 3351); R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemD, 3352); R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355); R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterA, 3365);