diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/file_sys/archive_ncch.cpp | 36 | ||||
| -rw-r--r-- | src/core/hle/service/fs/fs_user.cpp | 54 |
2 files changed, 37 insertions, 53 deletions
diff --git a/src/core/file_sys/archive_ncch.cpp b/src/core/file_sys/archive_ncch.cpp index bf4e0916b..84950f871 100644 --- a/src/core/file_sys/archive_ncch.cpp +++ b/src/core/file_sys/archive_ncch.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "common/file_util.h" | 9 | #include "common/file_util.h" |
| 10 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 11 | #include "common/string_util.h" | 11 | #include "common/string_util.h" |
| 12 | #include "core/core.h" | ||
| 12 | #include "core/file_sys/archive_ncch.h" | 13 | #include "core/file_sys/archive_ncch.h" |
| 13 | #include "core/file_sys/ivfc_archive.h" | 14 | #include "core/file_sys/ivfc_archive.h" |
| 14 | #include "core/hle/service/fs/archive.h" | 15 | #include "core/hle/service/fs/archive.h" |
| @@ -33,10 +34,43 @@ ArchiveFactory_NCCH::ArchiveFactory_NCCH(const std::string& nand_directory) | |||
| 33 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_NCCH::Open(const Path& path) { | 34 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_NCCH::Open(const Path& path) { |
| 34 | auto vec = path.AsBinary(); | 35 | auto vec = path.AsBinary(); |
| 35 | const u32* data = reinterpret_cast<u32*>(vec.data()); | 36 | const u32* data = reinterpret_cast<u32*>(vec.data()); |
| 36 | std::string file_path = GetNCCHPath(mount_point, data[1], data[0]); | 37 | u32 high = data[1]; |
| 38 | u32 low = data[0]; | ||
| 39 | std::string file_path = GetNCCHPath(mount_point, high, low); | ||
| 37 | auto file = std::make_shared<FileUtil::IOFile>(file_path, "rb"); | 40 | auto file = std::make_shared<FileUtil::IOFile>(file_path, "rb"); |
| 38 | 41 | ||
| 39 | if (!file->IsOpen()) { | 42 | if (!file->IsOpen()) { |
| 43 | // High Title ID of the archive: The category (https://3dbrew.org/wiki/Title_list). | ||
| 44 | const u32 shared_data_archive = 0x0004009B; | ||
| 45 | const u32 system_data_archive = 0x000400DB; | ||
| 46 | |||
| 47 | // Low Title IDs. | ||
| 48 | const u32 mii_data = 0x00010202; | ||
| 49 | const u32 region_manifest = 0x00010402; | ||
| 50 | const u32 ng_word_list = 0x00010302; | ||
| 51 | |||
| 52 | LOG_DEBUG(Service_FS, "Full Path: %s. Category: 0x%X. Path: 0x%X.", path.DebugStr().c_str(), | ||
| 53 | high, low); | ||
| 54 | |||
| 55 | if (high == shared_data_archive) { | ||
| 56 | if (low == mii_data) { | ||
| 57 | LOG_ERROR(Service_FS, "Failed to get a handle for shared data archive: Mii data. "); | ||
| 58 | Core::System::GetInstance().SetStatus(Core::System::ResultStatus::ErrorSystemFiles, | ||
| 59 | "Mii data"); | ||
| 60 | } else if (low == region_manifest) { | ||
| 61 | LOG_ERROR(Service_FS, | ||
| 62 | "Failed to get a handle for shared data archive: region manifes"); | ||
| 63 | Core::System::GetInstance().SetStatus(Core::System::ResultStatus::ErrorSystemFiles, | ||
| 64 | "Region manifest"); | ||
| 65 | } | ||
| 66 | } else if (high == system_data_archive) { | ||
| 67 | if (low == ng_word_list) { | ||
| 68 | LOG_ERROR(Service_FS, | ||
| 69 | "Failed to get a handle for system data archive: NG bad word list."); | ||
| 70 | Core::System::GetInstance().SetStatus(Core::System::ResultStatus::ErrorSystemFiles, | ||
| 71 | "NG bad word list"); | ||
| 72 | } | ||
| 73 | } | ||
| 40 | return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, | 74 | return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, |
| 41 | ErrorLevel::Status); | 75 | ErrorLevel::Status); |
| 42 | } | 76 | } |
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index c65d46238..c1825e9c8 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp | |||
| @@ -130,61 +130,11 @@ static void OpenFileDirectly(Service::Interface* self) { | |||
| 130 | 130 | ||
| 131 | ResultVal<ArchiveHandle> archive_handle = OpenArchive(archive_id, archive_path); | 131 | ResultVal<ArchiveHandle> archive_handle = OpenArchive(archive_id, archive_path); |
| 132 | if (archive_handle.Failed()) { | 132 | if (archive_handle.Failed()) { |
| 133 | cmd_buff[1] = archive_handle.Code().raw; | ||
| 134 | cmd_buff[3] = 0; | ||
| 135 | |||
| 136 | if (static_cast<FS::ArchiveIdCode>(archive_id) == ArchiveIdCode::NCCH) { | ||
| 137 | // High Title ID of the archive: The category (https://3dbrew.org/wiki/Title_list). | ||
| 138 | // (Note: The values there are big endian, these must be little endian.) | ||
| 139 | const std::vector<u8> shared_data_archive = {0x9B, 0x00, 0x04, 0x00}; | ||
| 140 | const std::vector<u8> system_data_archive = {0xDB, 0x00, 0x04, 0x00}; | ||
| 141 | |||
| 142 | // Low Title IDs. | ||
| 143 | const std::vector<u8> mii_data = {0x02, 0x02, 0x01, 0x00}; | ||
| 144 | const std::vector<u8> region_manifest = {0x02, 0x04, 0x01, 0x00}; | ||
| 145 | const std::vector<u8> ng_word_list = {0x02, 0x03, 0x01, 0x00}; | ||
| 146 | |||
| 147 | // Make a copy of the binary path because reusing AsBinary() for creating category | ||
| 148 | // results in bad_alloc being thrown. | ||
| 149 | std::vector<u8> binary_archive_path = archive_path.AsBinary(); | ||
| 150 | std::vector<u8> category(binary_archive_path.begin() + 4, | ||
| 151 | binary_archive_path.begin() + 8); | ||
| 152 | std::vector<u8> path(binary_archive_path.begin(), binary_archive_path.begin() + 4); | ||
| 153 | |||
| 154 | if (category == shared_data_archive) { | ||
| 155 | if (path == mii_data) { | ||
| 156 | LOG_ERROR(Service_FS, | ||
| 157 | "Failed to get a handle for shared data archive: Mii data. " | ||
| 158 | "Archive ID=0x%08X Archive Path=%s", | ||
| 159 | static_cast<u32>(archive_id), archive_path.DebugStr().c_str()); | ||
| 160 | Core::System::GetInstance().SetStatus( | ||
| 161 | Core::System::ResultStatus::ErrorSystemFiles, "Mii data"); | ||
| 162 | return; | ||
| 163 | } else if (path == region_manifest) { | ||
| 164 | LOG_ERROR(Service_FS, | ||
| 165 | "Failed to get a handle for shared data archive: region manifest. " | ||
| 166 | "Archive ID=0x%08X Archive Path=%s", | ||
| 167 | static_cast<u32>(archive_id), archive_path.DebugStr().c_str()); | ||
| 168 | Core::System::GetInstance().SetStatus( | ||
| 169 | Core::System::ResultStatus::ErrorSystemFiles, "Region manifest"); | ||
| 170 | return; | ||
| 171 | } | ||
| 172 | } else if (category == system_data_archive) { | ||
| 173 | if (path == ng_word_list) { | ||
| 174 | LOG_ERROR(Service_FS, | ||
| 175 | "Failed to get a handle for system data archive: NG bad word list. " | ||
| 176 | "Archive ID=0x%08X Archive Path=%s", | ||
| 177 | static_cast<u32>(archive_id), archive_path.DebugStr().c_str()); | ||
| 178 | Core::System::GetInstance().SetStatus( | ||
| 179 | Core::System::ResultStatus::ErrorSystemFiles, "NG bad word list"); | ||
| 180 | return; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | LOG_ERROR(Service_FS, | 133 | LOG_ERROR(Service_FS, |
| 186 | "Failed to get a handle for archive archive_id=0x%08X archive_path=%s", | 134 | "Failed to get a handle for archive archive_id=0x%08X archive_path=%s", |
| 187 | static_cast<u32>(archive_id), archive_path.DebugStr().c_str()); | 135 | static_cast<u32>(archive_id), archive_path.DebugStr().c_str()); |
| 136 | cmd_buff[1] = archive_handle.Code().raw; | ||
| 137 | cmd_buff[3] = 0; | ||
| 188 | return; | 138 | return; |
| 189 | } | 139 | } |
| 190 | SCOPE_EXIT({ CloseArchive(*archive_handle); }); | 140 | SCOPE_EXIT({ CloseArchive(*archive_handle); }); |