diff options
| -rw-r--r-- | src/core/file_sys/archive_selfncch.cpp | 43 | ||||
| -rw-r--r-- | src/core/file_sys/archive_selfncch.h | 9 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.h | 7 | ||||
| -rw-r--r-- | src/core/loader/3dsx.cpp | 3 | ||||
| -rw-r--r-- | src/core/loader/ncch.cpp | 3 |
6 files changed, 65 insertions, 18 deletions
diff --git a/src/core/file_sys/archive_selfncch.cpp b/src/core/file_sys/archive_selfncch.cpp index 7dc91a405..a16941c70 100644 --- a/src/core/file_sys/archive_selfncch.cpp +++ b/src/core/file_sys/archive_selfncch.cpp | |||
| @@ -3,12 +3,14 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <cinttypes> | ||
| 6 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 7 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 8 | #include "common/swap.h" | 9 | #include "common/swap.h" |
| 9 | #include "core/file_sys/archive_selfncch.h" | 10 | #include "core/file_sys/archive_selfncch.h" |
| 10 | #include "core/file_sys/errors.h" | 11 | #include "core/file_sys/errors.h" |
| 11 | #include "core/file_sys/ivfc_archive.h" | 12 | #include "core/file_sys/ivfc_archive.h" |
| 13 | #include "core/hle/kernel/process.h" | ||
| 12 | 14 | ||
| 13 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 15 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 14 | // FileSys namespace | 16 | // FileSys namespace |
| @@ -227,38 +229,57 @@ private: | |||
| 227 | NCCHData ncch_data; | 229 | NCCHData ncch_data; |
| 228 | }; | 230 | }; |
| 229 | 231 | ||
| 230 | ArchiveFactory_SelfNCCH::ArchiveFactory_SelfNCCH(Loader::AppLoader& app_loader) { | 232 | void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) { |
| 231 | std::shared_ptr<FileUtil::IOFile> romfs_file; | 233 | u64 program_id = 0; |
| 234 | if (app_loader.ReadProgramId(program_id) != Loader::ResultStatus::Success) { | ||
| 235 | LOG_WARNING( | ||
| 236 | Service_FS, | ||
| 237 | "Could not read program id when registering with SelfNCCH, this might be a 3dsx file"); | ||
| 238 | } | ||
| 239 | |||
| 240 | LOG_DEBUG(Service_FS, "Registering program %016" PRIX64 " with the SelfNCCH archive factory", | ||
| 241 | program_id); | ||
| 242 | |||
| 243 | if (ncch_data.find(program_id) != ncch_data.end()) { | ||
| 244 | LOG_WARNING(Service_FS, "Registering program %016" PRIX64 | ||
| 245 | " with SelfNCCH will override existing mapping", | ||
| 246 | program_id); | ||
| 247 | } | ||
| 248 | |||
| 249 | NCCHData& data = ncch_data[program_id]; | ||
| 250 | |||
| 251 | std::shared_ptr<FileUtil::IOFile> romfs_file_; | ||
| 232 | if (Loader::ResultStatus::Success == | 252 | if (Loader::ResultStatus::Success == |
| 233 | app_loader.ReadRomFS(romfs_file, ncch_data.romfs_offset, ncch_data.romfs_size)) { | 253 | app_loader.ReadRomFS(romfs_file_, data.romfs_offset, data.romfs_size)) { |
| 234 | 254 | ||
| 235 | ncch_data.romfs_file = std::move(romfs_file); | 255 | data.romfs_file = std::move(romfs_file_); |
| 236 | } | 256 | } |
| 237 | 257 | ||
| 238 | std::shared_ptr<FileUtil::IOFile> update_romfs_file; | 258 | std::shared_ptr<FileUtil::IOFile> update_romfs_file; |
| 239 | if (Loader::ResultStatus::Success == | 259 | if (Loader::ResultStatus::Success == |
| 240 | app_loader.ReadUpdateRomFS(update_romfs_file, ncch_data.update_romfs_offset, | 260 | app_loader.ReadUpdateRomFS(update_romfs_file, data.update_romfs_offset, |
| 241 | ncch_data.update_romfs_size)) { | 261 | data.update_romfs_size)) { |
| 242 | 262 | ||
| 243 | ncch_data.update_romfs_file = std::move(update_romfs_file); | 263 | data.update_romfs_file = std::move(update_romfs_file); |
| 244 | } | 264 | } |
| 245 | 265 | ||
| 246 | std::vector<u8> buffer; | 266 | std::vector<u8> buffer; |
| 247 | 267 | ||
| 248 | if (Loader::ResultStatus::Success == app_loader.ReadIcon(buffer)) | 268 | if (Loader::ResultStatus::Success == app_loader.ReadIcon(buffer)) |
| 249 | ncch_data.icon = std::make_shared<std::vector<u8>>(std::move(buffer)); | 269 | data.icon = std::make_shared<std::vector<u8>>(std::move(buffer)); |
| 250 | 270 | ||
| 251 | buffer.clear(); | 271 | buffer.clear(); |
| 252 | if (Loader::ResultStatus::Success == app_loader.ReadLogo(buffer)) | 272 | if (Loader::ResultStatus::Success == app_loader.ReadLogo(buffer)) |
| 253 | ncch_data.logo = std::make_shared<std::vector<u8>>(std::move(buffer)); | 273 | data.logo = std::make_shared<std::vector<u8>>(std::move(buffer)); |
| 254 | 274 | ||
| 255 | buffer.clear(); | 275 | buffer.clear(); |
| 256 | if (Loader::ResultStatus::Success == app_loader.ReadBanner(buffer)) | 276 | if (Loader::ResultStatus::Success == app_loader.ReadBanner(buffer)) |
| 257 | ncch_data.banner = std::make_shared<std::vector<u8>>(std::move(buffer)); | 277 | data.banner = std::make_shared<std::vector<u8>>(std::move(buffer)); |
| 258 | } | 278 | } |
| 259 | 279 | ||
| 260 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SelfNCCH::Open(const Path& path) { | 280 | ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SelfNCCH::Open(const Path& path) { |
| 261 | auto archive = std::make_unique<SelfNCCHArchive>(ncch_data); | 281 | auto archive = std::make_unique<SelfNCCHArchive>( |
| 282 | ncch_data[Kernel::g_current_process->codeset->program_id]); | ||
| 262 | return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); | 283 | return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); |
| 263 | } | 284 | } |
| 264 | 285 | ||
diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index f1c659948..0d6d6766e 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | #include <unordered_map> | ||
| 9 | #include <vector> | 10 | #include <vector> |
| 10 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 11 | #include "core/file_sys/archive_backend.h" | 12 | #include "core/file_sys/archive_backend.h" |
| @@ -33,7 +34,10 @@ struct NCCHData { | |||
| 33 | /// File system interface to the SelfNCCH archive | 34 | /// File system interface to the SelfNCCH archive |
| 34 | class ArchiveFactory_SelfNCCH final : public ArchiveFactory { | 35 | class ArchiveFactory_SelfNCCH final : public ArchiveFactory { |
| 35 | public: | 36 | public: |
| 36 | explicit ArchiveFactory_SelfNCCH(Loader::AppLoader& app_loader); | 37 | ArchiveFactory_SelfNCCH() = default; |
| 38 | |||
| 39 | /// Registers a loaded application so that we can open its SelfNCCH archive when requested. | ||
| 40 | void Register(Loader::AppLoader& app_loader); | ||
| 37 | 41 | ||
| 38 | std::string GetName() const override { | 42 | std::string GetName() const override { |
| 39 | return "SelfNCCH"; | 43 | return "SelfNCCH"; |
| @@ -43,7 +47,8 @@ public: | |||
| 43 | ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; | 47 | ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; |
| 44 | 48 | ||
| 45 | private: | 49 | private: |
| 46 | NCCHData ncch_data; | 50 | /// Mapping of ProgramId -> NCCHData |
| 51 | std::unordered_map<u64, NCCHData> ncch_data; | ||
| 47 | }; | 52 | }; |
| 48 | 53 | ||
| 49 | } // namespace FileSys | 54 | } // namespace FileSys |
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 033fbc9aa..4ccb3cd32 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include "core/file_sys/archive_savedata.h" | 20 | #include "core/file_sys/archive_savedata.h" |
| 21 | #include "core/file_sys/archive_sdmc.h" | 21 | #include "core/file_sys/archive_sdmc.h" |
| 22 | #include "core/file_sys/archive_sdmcwriteonly.h" | 22 | #include "core/file_sys/archive_sdmcwriteonly.h" |
| 23 | #include "core/file_sys/archive_selfncch.h" | ||
| 23 | #include "core/file_sys/archive_systemsavedata.h" | 24 | #include "core/file_sys/archive_systemsavedata.h" |
| 24 | #include "core/file_sys/directory_backend.h" | 25 | #include "core/file_sys/directory_backend.h" |
| 25 | #include "core/file_sys/errors.h" | 26 | #include "core/file_sys/errors.h" |
| @@ -48,7 +49,7 @@ struct hash<Service::FS::ArchiveIdCode> { | |||
| 48 | return std::hash<Type>()(static_cast<Type>(id_code)); | 49 | return std::hash<Type>()(static_cast<Type>(id_code)); |
| 49 | } | 50 | } |
| 50 | }; | 51 | }; |
| 51 | } | 52 | } // namespace std |
| 52 | 53 | ||
| 53 | static constexpr Kernel::Handle INVALID_HANDLE{}; | 54 | static constexpr Kernel::Handle INVALID_HANDLE{}; |
| 54 | 55 | ||
| @@ -564,6 +565,21 @@ void RegisterArchiveTypes() { | |||
| 564 | auto systemsavedata_factory = | 565 | auto systemsavedata_factory = |
| 565 | std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory); | 566 | std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory); |
| 566 | RegisterArchiveType(std::move(systemsavedata_factory), ArchiveIdCode::SystemSaveData); | 567 | RegisterArchiveType(std::move(systemsavedata_factory), ArchiveIdCode::SystemSaveData); |
| 568 | |||
| 569 | auto selfncch_factory = std::make_unique<FileSys::ArchiveFactory_SelfNCCH>(); | ||
| 570 | RegisterArchiveType(std::move(selfncch_factory), ArchiveIdCode::SelfNCCH); | ||
| 571 | } | ||
| 572 | |||
| 573 | void RegisterSelfNCCH(Loader::AppLoader& app_loader) { | ||
| 574 | auto itr = id_code_map.find(ArchiveIdCode::SelfNCCH); | ||
| 575 | if (itr == id_code_map.end()) { | ||
| 576 | LOG_ERROR(Service_FS, | ||
| 577 | "Could not register a new NCCH because the SelfNCCH archive hasn't been created"); | ||
| 578 | return; | ||
| 579 | } | ||
| 580 | |||
| 581 | auto* factory = static_cast<FileSys::ArchiveFactory_SelfNCCH*>(itr->second.get()); | ||
| 582 | factory->Register(app_loader); | ||
| 567 | } | 583 | } |
| 568 | 584 | ||
| 569 | void UnregisterArchiveTypes() { | 585 | void UnregisterArchiveTypes() { |
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 3a3371c88..e3c8fc2ef 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h | |||
| @@ -21,6 +21,10 @@ static constexpr char SYSTEM_ID[]{"00000000000000000000000000000000"}; | |||
| 21 | /// The scrambled SD card CID, also known as ID1 | 21 | /// The scrambled SD card CID, also known as ID1 |
| 22 | static constexpr char SDCARD_ID[]{"00000000000000000000000000000000"}; | 22 | static constexpr char SDCARD_ID[]{"00000000000000000000000000000000"}; |
| 23 | 23 | ||
| 24 | namespace Loader { | ||
| 25 | class AppLoader; | ||
| 26 | } | ||
| 27 | |||
| 24 | namespace Service { | 28 | namespace Service { |
| 25 | namespace FS { | 29 | namespace FS { |
| 26 | 30 | ||
| @@ -259,6 +263,9 @@ void ArchiveInit(); | |||
| 259 | /// Shutdown archives | 263 | /// Shutdown archives |
| 260 | void ArchiveShutdown(); | 264 | void ArchiveShutdown(); |
| 261 | 265 | ||
| 266 | /// Registers a new NCCH file with the SelfNCCH archive factory | ||
| 267 | void RegisterSelfNCCH(Loader::AppLoader& app_loader); | ||
| 268 | |||
| 262 | /// Register all archive types | 269 | /// Register all archive types |
| 263 | void RegisterArchiveTypes(); | 270 | void RegisterArchiveTypes(); |
| 264 | 271 | ||
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index a03515e6e..5ad5c5287 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -278,8 +278,7 @@ ResultStatus AppLoader_THREEDSX::Load() { | |||
| 278 | 278 | ||
| 279 | Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); | 279 | Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); |
| 280 | 280 | ||
| 281 | Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_SelfNCCH>(*this), | 281 | Service::FS::RegisterSelfNCCH(*this); |
| 282 | Service::FS::ArchiveIdCode::SelfNCCH); | ||
| 283 | 282 | ||
| 284 | is_loaded = true; | 283 | is_loaded = true; |
| 285 | return ResultStatus::Success; | 284 | return ResultStatus::Success; |
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index c46d7cfc6..5107135f9 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp | |||
| @@ -187,8 +187,7 @@ ResultStatus AppLoader_NCCH::Load() { | |||
| 187 | if (ResultStatus::Success != result) | 187 | if (ResultStatus::Success != result) |
| 188 | return result; | 188 | return result; |
| 189 | 189 | ||
| 190 | Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_SelfNCCH>(*this), | 190 | Service::FS::RegisterSelfNCCH(*this); |
| 191 | Service::FS::ArchiveIdCode::SelfNCCH); | ||
| 192 | 191 | ||
| 193 | ParseRegionLockoutInfo(); | 192 | ParseRegionLockoutInfo(); |
| 194 | 193 | ||