diff options
| -rw-r--r-- | src/core/file_sys/nca_metadata.cpp | 11 | ||||
| -rw-r--r-- | src/core/file_sys/registered_cache.cpp | 13 | ||||
| -rw-r--r-- | src/core/file_sys/vfs_real.cpp | 16 |
3 files changed, 22 insertions, 18 deletions
diff --git a/src/core/file_sys/nca_metadata.cpp b/src/core/file_sys/nca_metadata.cpp index 234d70199..449244444 100644 --- a/src/core/file_sys/nca_metadata.cpp +++ b/src/core/file_sys/nca_metadata.cpp | |||
| @@ -103,7 +103,10 @@ bool CNMT::UnionRecords(const CNMT& other) { | |||
| 103 | std::vector<u8> CNMT::Serialize() const { | 103 | std::vector<u8> CNMT::Serialize() const { |
| 104 | const bool has_opt_header = | 104 | const bool has_opt_header = |
| 105 | header.type >= TitleType::Application && header.type <= TitleType::AOC; | 105 | header.type >= TitleType::Application && header.type <= TitleType::AOC; |
| 106 | std::vector<u8> out(sizeof(CNMTHeader) + (has_opt_header ? sizeof(OptionalHeader) : 0)); | 106 | const auto dead_zone = header.table_offset + sizeof(CNMTHeader); |
| 107 | std::vector<u8> out( | ||
| 108 | std::max(sizeof(CNMTHeader) + (has_opt_header ? sizeof(OptionalHeader) : 0), dead_zone) + | ||
| 109 | content_records.size() * sizeof(ContentRecord) + meta_records.size() * sizeof(MetaRecord)); | ||
| 107 | memcpy(out.data(), &header, sizeof(CNMTHeader)); | 110 | memcpy(out.data(), &header, sizeof(CNMTHeader)); |
| 108 | 111 | ||
| 109 | // Optional Header | 112 | // Optional Header |
| @@ -113,17 +116,11 @@ std::vector<u8> CNMT::Serialize() const { | |||
| 113 | 116 | ||
| 114 | auto offset = header.table_offset; | 117 | auto offset = header.table_offset; |
| 115 | 118 | ||
| 116 | const auto dead_zone = offset + sizeof(CNMTHeader) - out.size(); | ||
| 117 | if (dead_zone > 0) | ||
| 118 | out.resize(offset + sizeof(CNMTHeader)); | ||
| 119 | |||
| 120 | out.resize(out.size() + content_records.size() * sizeof(ContentRecord)); | ||
| 121 | for (const auto& rec : content_records) { | 119 | for (const auto& rec : content_records) { |
| 122 | memcpy(out.data() + offset + sizeof(CNMTHeader), &rec, sizeof(ContentRecord)); | 120 | memcpy(out.data() + offset + sizeof(CNMTHeader), &rec, sizeof(ContentRecord)); |
| 123 | offset += sizeof(ContentRecord); | 121 | offset += sizeof(ContentRecord); |
| 124 | } | 122 | } |
| 125 | 123 | ||
| 126 | out.resize(out.size() + content_records.size() * sizeof(MetaRecord)); | ||
| 127 | for (const auto& rec : meta_records) { | 124 | for (const auto& rec : meta_records) { |
| 128 | memcpy(out.data() + offset + sizeof(CNMTHeader), &rec, sizeof(MetaRecord)); | 125 | memcpy(out.data() + offset + sizeof(CNMTHeader), &rec, sizeof(MetaRecord)); |
| 129 | offset += sizeof(MetaRecord); | 126 | offset += sizeof(MetaRecord); |
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index e916d5610..a5e935f64 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp | |||
| @@ -29,8 +29,8 @@ static bool FollowsTwoDigitDirFormat(std::string_view name) { | |||
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | static bool FollowsNcaIdFormat(std::string_view name) { | 31 | static bool FollowsNcaIdFormat(std::string_view name) { |
| 32 | static const std::regex nca_id_regex("[0-9A-F]{32}.nca", std::regex_constants::ECMAScript | | 32 | static const std::regex nca_id_regex("[0-9A-F]{32}\\.nca", std::regex_constants::ECMAScript | |
| 33 | std::regex_constants::icase); | 33 | std::regex_constants::icase); |
| 34 | return name.size() == 36 && std::regex_match(name.begin(), name.end(), nca_id_regex); | 34 | return name.size() == 36 && std::regex_match(name.begin(), name.end(), nca_id_regex); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| @@ -59,8 +59,10 @@ static std::string GetCNMTName(TitleType type, u64 title_id) { | |||
| 59 | 59 | ||
| 60 | auto index = static_cast<size_t>(type); | 60 | auto index = static_cast<size_t>(type); |
| 61 | // If the index is after the jump in TitleType, subtract it out. | 61 | // If the index is after the jump in TitleType, subtract it out. |
| 62 | if (index >= static_cast<size_t>(TitleType::Application)) | 62 | if (index >= static_cast<size_t>(TitleType::Application)) { |
| 63 | index -= 0x7B; | 63 | index -= static_cast<size_t>(TitleType::Application) - |
| 64 | static_cast<size_t>(TitleType::FirmwarePackageB); | ||
| 65 | } | ||
| 64 | return fmt::format("{}_{:016x}.cnmt", TITLE_TYPE_NAMES[index], title_id); | 66 | return fmt::format("{}_{:016x}.cnmt", TITLE_TYPE_NAMES[index], title_id); |
| 65 | } | 67 | } |
| 66 | 68 | ||
| @@ -96,7 +98,8 @@ VirtualFile RegisteredCache::OpenFileOrDirectoryConcat(const VirtualDir& dir, | |||
| 96 | file = files[0]; | 98 | file = files[0]; |
| 97 | } else { | 99 | } else { |
| 98 | std::vector<VirtualFile> concat; | 100 | std::vector<VirtualFile> concat; |
| 99 | for (u8 i = 0; i < 0x10; ++i) { | 101 | // Since the files are a two-digit hex number, max is FF. |
| 102 | for (size_t i = 0; i < 0x100; ++i) { | ||
| 100 | auto next = nca_dir->GetFile(fmt::format("{:02X}", i)); | 103 | auto next = nca_dir->GetFile(fmt::format("{:02X}", i)); |
| 101 | if (next != nullptr) { | 104 | if (next != nullptr) { |
| 102 | concat.push_back(std::move(next)); | 105 | concat.push_back(std::move(next)); |
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 02cdb039a..0afe515f0 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp | |||
| @@ -84,9 +84,11 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { | |||
| 84 | VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { | 84 | VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { |
| 85 | const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); | 85 | const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); |
| 86 | const auto path_fwd = FileUtil::SanitizePath(path, FileUtil::DirectorySeparator::ForwardSlash); | 86 | const auto path_fwd = FileUtil::SanitizePath(path, FileUtil::DirectorySeparator::ForwardSlash); |
| 87 | if (!FileUtil::Exists(path) && !FileUtil::CreateFullPath(path_fwd) && | 87 | if (!FileUtil::Exists(path)) { |
| 88 | !FileUtil::CreateEmptyFile(path)) | 88 | FileUtil::CreateFullPath(path_fwd); |
| 89 | return nullptr; | 89 | if (!FileUtil::CreateEmptyFile(path)) |
| 90 | return nullptr; | ||
| 91 | } | ||
| 90 | return OpenFile(path, perms); | 92 | return OpenFile(path, perms); |
| 91 | } | 93 | } |
| 92 | 94 | ||
| @@ -143,9 +145,11 @@ VirtualDir RealVfsFilesystem::OpenDirectory(std::string_view path_, Mode perms) | |||
| 143 | VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, Mode perms) { | 145 | VirtualDir RealVfsFilesystem::CreateDirectory(std::string_view path_, Mode perms) { |
| 144 | const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); | 146 | const auto path = FileUtil::SanitizePath(path_, FileUtil::DirectorySeparator::PlatformDefault); |
| 145 | const auto path_fwd = FileUtil::SanitizePath(path, FileUtil::DirectorySeparator::ForwardSlash); | 147 | const auto path_fwd = FileUtil::SanitizePath(path, FileUtil::DirectorySeparator::ForwardSlash); |
| 146 | if (!FileUtil::Exists(path) && !FileUtil::CreateFullPath(path_fwd) && | 148 | if (!FileUtil::Exists(path)) { |
| 147 | !FileUtil::CreateEmptyFile(path)) | 149 | FileUtil::CreateFullPath(path_fwd); |
| 148 | return nullptr; | 150 | if (!FileUtil::CreateDir(path)) |
| 151 | return nullptr; | ||
| 152 | } | ||
| 149 | // Cannot use make_shared as RealVfsDirectory constructor is private | 153 | // Cannot use make_shared as RealVfsDirectory constructor is private |
| 150 | return std::shared_ptr<RealVfsDirectory>(new RealVfsDirectory(*this, path, perms)); | 154 | return std::shared_ptr<RealVfsDirectory>(new RealVfsDirectory(*this, path, perms)); |
| 151 | } | 155 | } |