summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/core.cpp13
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/file_sys/card_image.cpp18
-rw-r--r--src/core/file_sys/card_image.h3
-rw-r--r--src/core/file_sys/submission_package.cpp71
-rw-r--r--src/core/file_sys/submission_package.h11
-rw-r--r--src/core/loader/loader.cpp13
-rw-r--r--src/core/loader/loader.h13
-rw-r--r--src/core/loader/nsp.cpp34
-rw-r--r--src/core/loader/nsp.h4
-rw-r--r--src/core/loader/xci.cpp14
-rw-r--r--src/core/loader/xci.h3
12 files changed, 116 insertions, 83 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 406320ed6..15226cf41 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -216,9 +216,9 @@ struct System::Impl {
}
ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath,
- std::size_t program_index) {
+ u64 program_id, std::size_t program_index) {
app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
- program_index);
+ program_id, program_index);
if (!app_loader) {
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
@@ -269,11 +269,10 @@ struct System::Impl {
}
}
- u64 title_id{0};
- if (app_loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
+ if (app_loader->ReadProgramId(program_id) != Loader::ResultStatus::Success) {
LOG_ERROR(Core, "Failed to find title id for ROM (Error {})", load_result);
}
- perf_stats = std::make_unique<PerfStats>(title_id);
+ perf_stats = std::make_unique<PerfStats>(program_id);
// Reset counters and set time origin to current frame
GetAndResetPerfStats();
perf_stats->BeginSystemFrame();
@@ -459,8 +458,8 @@ void System::Shutdown() {
}
System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
- std::size_t program_index) {
- return impl->Load(*this, emu_window, filepath, program_index);
+ u64 program_id, std::size_t program_index) {
+ return impl->Load(*this, emu_window, filepath, program_id, program_index);
}
bool System::IsPoweredOn() const {
diff --git a/src/core/core.h b/src/core/core.h
index 8b93ba998..b93c32e60 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -175,7 +175,7 @@ public:
* @returns ResultStatus code, indicating if the operation succeeded.
*/
[[nodiscard]] ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
- std::size_t program_index = 0);
+ u64 program_id = 0, std::size_t program_index = 0);
/**
* Indicates if the emulated system is powered on (all subsystems initialized and able to run an
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp
index db2f6a955..755d3303e 100644
--- a/src/core/file_sys/card_image.cpp
+++ b/src/core/file_sys/card_image.cpp
@@ -29,7 +29,7 @@ constexpr std::array partition_names{
"logo",
};
-XCI::XCI(VirtualFile file_, std::size_t program_index)
+XCI::XCI(VirtualFile file_, u64 program_id, size_t program_index)
: file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA},
partitions(partition_names.size()),
partitions_raw(partition_names.size()), keys{Core::Crypto::KeyManager::Instance()} {
@@ -63,12 +63,12 @@ XCI::XCI(VirtualFile file_, std::size_t program_index)
secure_partition = std::make_shared<NSP>(
main_hfs.GetFile(partition_names[static_cast<std::size_t>(XCIPartition::Secure)]),
- program_index);
+ program_id, program_index);
ncas = secure_partition->GetNCAsCollapsed();
program =
secure_partition->GetNCA(secure_partition->GetProgramTitleID(), ContentRecordType::Program);
- program_nca_status = secure_partition->GetProgramStatus(secure_partition->GetProgramTitleID());
+ program_nca_status = secure_partition->GetProgramStatus();
if (program_nca_status == Loader::ResultStatus::ErrorNSPMissingProgramNCA) {
program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA;
}
@@ -174,6 +174,10 @@ u64 XCI::GetProgramTitleID() const {
return secure_partition->GetProgramTitleID();
}
+std::vector<u64> XCI::GetProgramTitleIDs() const {
+ return secure_partition->GetProgramTitleIDs();
+}
+
u32 XCI::GetSystemUpdateVersion() {
const auto update = GetPartition(XCIPartition::Update);
if (update == nullptr) {
@@ -229,9 +233,11 @@ const std::vector<std::shared_ptr<NCA>>& XCI::GetNCAs() const {
}
std::shared_ptr<NCA> XCI::GetNCAByType(NCAContentType type) const {
- const auto iter =
- std::find_if(ncas.begin(), ncas.end(),
- [type](const std::shared_ptr<NCA>& nca) { return nca->GetType() == type; });
+ const auto program_id = secure_partition->GetProgramTitleID();
+ const auto iter = std::find_if(
+ ncas.begin(), ncas.end(), [this, type, program_id](const std::shared_ptr<NCA>& nca) {
+ return nca->GetType() == type && nca->GetTitleId() == program_id;
+ });
return iter == ncas.end() ? nullptr : *iter;
}
diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h
index 4960e90fe..0fd9fa87c 100644
--- a/src/core/file_sys/card_image.h
+++ b/src/core/file_sys/card_image.h
@@ -78,7 +78,7 @@ enum class XCIPartition : u8 { Update, Normal, Secure, Logo };
class XCI : public ReadOnlyVfsDirectory {
public:
- explicit XCI(VirtualFile file, std::size_t program_index = 0);
+ explicit XCI(VirtualFile file, u64 program_id = 0, size_t program_index = 0);
~XCI() override;
Loader::ResultStatus GetStatus() const;
@@ -104,6 +104,7 @@ public:
VirtualFile GetLogoPartitionRaw() const;
u64 GetProgramTitleID() const;
+ std::vector<u64> GetProgramTitleIDs() const;
u32 GetSystemUpdateVersion();
u64 GetSystemUpdateTitleID() const;
diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp
index d51d469e3..f192dffa5 100644
--- a/src/core/file_sys/submission_package.cpp
+++ b/src/core/file_sys/submission_package.cpp
@@ -20,8 +20,9 @@
namespace FileSys {
-NSP::NSP(VirtualFile file_, std::size_t program_index_)
- : file(std::move(file_)), program_index(program_index_), status{Loader::ResultStatus::Success},
+NSP::NSP(VirtualFile file_, u64 title_id_, std::size_t program_index_)
+ : file(std::move(file_)), expected_program_id(title_id_),
+ program_index(program_index_), status{Loader::ResultStatus::Success},
pfs(std::make_shared<PartitionFilesystem>(file)), keys{Core::Crypto::KeyManager::Instance()} {
if (pfs->GetStatus() != Loader::ResultStatus::Success) {
status = pfs->GetStatus();
@@ -46,60 +47,59 @@ Loader::ResultStatus NSP::GetStatus() const {
return status;
}
-Loader::ResultStatus NSP::GetProgramStatus(u64 title_id) const {
+Loader::ResultStatus NSP::GetProgramStatus() const {
if (IsExtractedType() && GetExeFS() != nullptr && FileSys::IsDirectoryExeFS(GetExeFS())) {
return Loader::ResultStatus::Success;
}
- const auto iter = program_status.find(title_id);
+ const auto iter = program_status.find(GetProgramTitleID());
if (iter == program_status.end())
return Loader::ResultStatus::ErrorNSPMissingProgramNCA;
return iter->second;
}
-u64 NSP::GetFirstTitleID() const {
- if (IsExtractedType()) {
- return GetProgramTitleID();
- }
-
- if (program_status.empty())
- return 0;
- return program_status.begin()->first;
-}
-
u64 NSP::GetProgramTitleID() const {
if (IsExtractedType()) {
- if (GetExeFS() == nullptr || !IsDirectoryExeFS(GetExeFS())) {
- return 0;
- }
+ return GetExtractedTitleID() + program_index;
+ }
- ProgramMetadata meta;
- if (meta.Load(GetExeFS()->GetFile("main.npdm")) == Loader::ResultStatus::Success) {
- return meta.GetTitleID();
- } else {
- return 0;
+ auto program_id = expected_program_id;
+ if (program_id == 0) {
+ if (!program_status.empty()) {
+ program_id = program_status.begin()->first;
}
}
- const auto out = GetFirstTitleID();
- if ((out & 0x800) == 0)
- return out;
+ program_id = program_id + program_index;
+ if (program_status.find(program_id) != program_status.end()) {
+ return program_id;
+ }
- const auto ids = GetTitleIDs();
+ const auto ids = GetProgramTitleIDs();
const auto iter =
std::find_if(ids.begin(), ids.end(), [](u64 tid) { return (tid & 0x800) == 0; });
- return iter == ids.end() ? out : *iter;
+ return iter == ids.end() ? 0 : *iter;
+}
+
+u64 NSP::GetExtractedTitleID() const {
+ if (GetExeFS() == nullptr || !IsDirectoryExeFS(GetExeFS())) {
+ return 0;
+ }
+
+ ProgramMetadata meta;
+ if (meta.Load(GetExeFS()->GetFile("main.npdm")) == Loader::ResultStatus::Success) {
+ return meta.GetTitleID();
+ } else {
+ return 0;
+ }
}
-std::vector<u64> NSP::GetTitleIDs() const {
+std::vector<u64> NSP::GetProgramTitleIDs() const {
if (IsExtractedType()) {
- return {GetProgramTitleID()};
+ return {GetExtractedTitleID()};
}
- std::vector<u64> out;
- out.reserve(ncas.size());
- for (const auto& kv : ncas)
- out.push_back(kv.first);
+ std::vector<u64> out{program_ids.cbegin(), program_ids.cend()};
return out;
}
@@ -146,7 +146,7 @@ std::shared_ptr<NCA> NSP::GetNCA(u64 title_id, ContentRecordType type, TitleType
if (extracted)
LOG_WARNING(Service_FS, "called on an NSP that is of type extracted.");
- const auto title_id_iter = ncas.find(title_id + program_index);
+ const auto title_id_iter = ncas.find(title_id);
if (title_id_iter == ncas.end())
return nullptr;
@@ -160,7 +160,7 @@ std::shared_ptr<NCA> NSP::GetNCA(u64 title_id, ContentRecordType type, TitleType
VirtualFile NSP::GetNCAFile(u64 title_id, ContentRecordType type, TitleType title_type) const {
if (extracted)
LOG_WARNING(Service_FS, "called on an NSP that is of type extracted.");
- const auto nca = GetNCA(title_id, type);
+ const auto nca = GetNCA(title_id, type, title_type);
if (nca != nullptr)
return nca->GetBaseFile();
return nullptr;
@@ -286,6 +286,7 @@ void NSP::ReadNCAs(const std::vector<VirtualFile>& files) {
if (next_nca->GetType() == NCAContentType::Program) {
program_status[next_nca->GetTitleId()] = next_nca->GetStatus();
+ program_ids.insert(next_nca->GetTitleId() & 0xFFFFFFFFFFFFF000);
}
if (next_nca->GetStatus() != Loader::ResultStatus::Success &&
diff --git a/src/core/file_sys/submission_package.h b/src/core/file_sys/submission_package.h
index ecb3b6f15..030f36c09 100644
--- a/src/core/file_sys/submission_package.h
+++ b/src/core/file_sys/submission_package.h
@@ -6,6 +6,7 @@
#include <map>
#include <memory>
+#include <set>
#include <vector>
#include "common/common_types.h"
#include "core/file_sys/vfs.h"
@@ -27,15 +28,15 @@ enum class ContentRecordType : u8;
class NSP : public ReadOnlyVfsDirectory {
public:
- explicit NSP(VirtualFile file_, std::size_t program_index_ = 0);
+ explicit NSP(VirtualFile file_, u64 title_id = 0, std::size_t program_index_ = 0);
~NSP() override;
Loader::ResultStatus GetStatus() const;
- Loader::ResultStatus GetProgramStatus(u64 title_id) const;
+ Loader::ResultStatus GetProgramStatus() const;
// Should only be used when one title id can be assured.
- u64 GetFirstTitleID() const;
u64 GetProgramTitleID() const;
- std::vector<u64> GetTitleIDs() const;
+ u64 GetExtractedTitleID() const;
+ std::vector<u64> GetProgramTitleIDs() const;
bool IsExtractedType() const;
@@ -69,6 +70,7 @@ private:
VirtualFile file;
+ const u64 expected_program_id;
const std::size_t program_index;
bool extracted = false;
@@ -78,6 +80,7 @@ private:
std::shared_ptr<PartitionFilesystem> pfs;
// Map title id -> {map type -> NCA}
std::map<u64, std::map<std::pair<TitleType, ContentRecordType>, std::shared_ptr<NCA>>> ncas;
+ std::set<u64> program_ids;
std::vector<VirtualFile> ticket_files;
Core::Crypto::KeyManager& keys;
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 228dc6389..199e69e89 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -206,7 +206,8 @@ AppLoader::~AppLoader() = default;
* @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type
*/
static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::VirtualFile file,
- FileType type, std::size_t program_index) {
+ FileType type, u64 program_id,
+ std::size_t program_index) {
switch (type) {
// Standard ELF file format.
case FileType::ELF:
@@ -227,7 +228,8 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V
// NX XCI (nX Card Image) file format.
case FileType::XCI:
return std::make_unique<AppLoader_XCI>(std::move(file), system.GetFileSystemController(),
- system.GetContentProvider(), program_index);
+ system.GetContentProvider(), program_id,
+ program_index);
// NX NAX (NintendoAesXts) file format.
case FileType::NAX:
@@ -236,7 +238,8 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V
// NX NSP (Nintendo Submission Package) file format
case FileType::NSP:
return std::make_unique<AppLoader_NSP>(std::move(file), system.GetFileSystemController(),
- system.GetContentProvider(), program_index);
+ system.GetContentProvider(), program_id,
+ program_index);
// NX KIP (Kernel Internal Process) file format
case FileType::KIP:
@@ -252,7 +255,7 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V
}
std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file,
- std::size_t program_index) {
+ u64 program_id, std::size_t program_index) {
FileType type = IdentifyFile(file);
const FileType filename_type = GuessFromFilename(file->GetName());
@@ -266,7 +269,7 @@ std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile
LOG_DEBUG(Loader, "Loading file {} as {}...", file->GetName(), GetFileTypeString(type));
- return GetFileLoader(system, std::move(file), type, program_index);
+ return GetFileLoader(system, std::move(file), type, program_id, program_index);
}
} // namespace Loader
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index edc8bb257..7b1bac3f7 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -227,6 +227,17 @@ public:
}
/**
+ * Get the program ids of the application
+ *
+ * @param[out] out_program_ids Reference to store program ids into
+ *
+ * @return ResultStatus result of function
+ */
+ virtual ResultStatus ReadProgramIds(std::vector<u64>& out_program_ids) {
+ return ResultStatus::ErrorNotImplemented;
+ }
+
+ /**
* Get the RomFS of the application
* Since the RomFS can be huge, we return a file reference instead of copying to a buffer
*
@@ -324,6 +335,6 @@ protected:
* @return the best loader for this file.
*/
std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file,
- std::size_t program_index = 0);
+ u64 program_id = 0, std::size_t program_index = 0);
} // namespace Loader
diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp
index d815a7cd3..8b167ad3c 100644
--- a/src/core/loader/nsp.cpp
+++ b/src/core/loader/nsp.cpp
@@ -23,10 +23,9 @@ namespace Loader {
AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file_,
const Service::FileSystem::FileSystemController& fsc,
- const FileSys::ContentProvider& content_provider,
+ const FileSys::ContentProvider& content_provider, u64 program_id,
std::size_t program_index)
- : AppLoader(file_), nsp(std::make_unique<FileSys::NSP>(file_, program_index)),
- title_id(nsp->GetProgramTitleID()) {
+ : AppLoader(file_), nsp(std::make_unique<FileSys::NSP>(file_, program_id, program_index)) {
if (nsp->GetStatus() != ResultStatus::Success) {
return;
@@ -46,12 +45,8 @@ AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file_,
return pm.ParseControlNCA(*control_nca);
}();
- if (title_id == 0) {
- return;
- }
-
secondary_loader = std::make_unique<AppLoader_NCA>(
- nsp->GetNCAFile(title_id, FileSys::ContentRecordType::Program));
+ nsp->GetNCAFile(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Program));
}
}
@@ -68,10 +63,11 @@ FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& nsp_file) {
}
// Non-Extracted Type case
+ const auto program_id = nsp.GetProgramTitleID();
if (!nsp.IsExtractedType() &&
- nsp.GetNCA(nsp.GetFirstTitleID(), FileSys::ContentRecordType::Program) != nullptr &&
- AppLoader_NCA::IdentifyType(nsp.GetNCAFile(
- nsp.GetFirstTitleID(), FileSys::ContentRecordType::Program)) == FileType::NCA) {
+ nsp.GetNCA(program_id, FileSys::ContentRecordType::Program) != nullptr &&
+ AppLoader_NCA::IdentifyType(
+ nsp.GetNCAFile(program_id, FileSys::ContentRecordType::Program)) == FileType::NCA) {
return FileType::NSP;
}
}
@@ -84,6 +80,8 @@ AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::KProcess& process, Core::S
return {ResultStatus::ErrorAlreadyLoaded, {}};
}
+ const auto title_id = nsp->GetProgramTitleID();
+
if (!nsp->IsExtractedType() && title_id == 0) {
return {ResultStatus::ErrorNSPMissingProgramNCA, {}};
}
@@ -93,7 +91,7 @@ AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::KProcess& process, Core::S
return {nsp_status, {}};
}
- const auto nsp_program_status = nsp->GetProgramStatus(title_id);
+ const auto nsp_program_status = nsp->GetProgramStatus();
if (nsp_program_status != ResultStatus::Success) {
return {nsp_program_status, {}};
}
@@ -134,8 +132,8 @@ ResultStatus AppLoader_NSP::ReadUpdateRaw(FileSys::VirtualFile& out_file) {
return ResultStatus::ErrorNoPackedUpdate;
}
- const auto read =
- nsp->GetNCAFile(FileSys::GetUpdateTitleID(title_id), FileSys::ContentRecordType::Program);
+ const auto read = nsp->GetNCAFile(FileSys::GetUpdateTitleID(nsp->GetProgramTitleID()),
+ FileSys::ContentRecordType::Program);
if (read == nullptr) {
return ResultStatus::ErrorNoPackedUpdate;
@@ -151,11 +149,15 @@ ResultStatus AppLoader_NSP::ReadUpdateRaw(FileSys::VirtualFile& out_file) {
}
ResultStatus AppLoader_NSP::ReadProgramId(u64& out_program_id) {
- if (title_id == 0) {
+ out_program_id = nsp->GetProgramTitleID();
+ if (out_program_id == 0) {
return ResultStatus::ErrorNotInitialized;
}
+ return ResultStatus::Success;
+}
- out_program_id = title_id;
+ResultStatus AppLoader_NSP::ReadProgramIds(std::vector<u64>& out_program_ids) {
+ out_program_ids = nsp->GetProgramTitleIDs();
return ResultStatus::Success;
}
diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h
index 644c0ff58..50406a92e 100644
--- a/src/core/loader/nsp.h
+++ b/src/core/loader/nsp.h
@@ -28,7 +28,7 @@ class AppLoader_NSP final : public AppLoader {
public:
explicit AppLoader_NSP(FileSys::VirtualFile file_,
const Service::FileSystem::FileSystemController& fsc,
- const FileSys::ContentProvider& content_provider,
+ const FileSys::ContentProvider& content_provider, u64 program_id,
std::size_t program_index);
~AppLoader_NSP() override;
@@ -51,6 +51,7 @@ public:
u64 ReadRomFSIVFCOffset() const override;
ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override;
ResultStatus ReadProgramId(u64& out_program_id) override;
+ ResultStatus ReadProgramIds(std::vector<u64>& out_program_ids) override;
ResultStatus ReadIcon(std::vector<u8>& buffer) override;
ResultStatus ReadTitle(std::string& title) override;
ResultStatus ReadControlData(FileSys::NACP& nacp) override;
@@ -67,7 +68,6 @@ private:
FileSys::VirtualFile icon_file;
std::unique_ptr<FileSys::NACP> nacp_file;
- u64 title_id;
};
} // namespace Loader
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp
index 635d6ae15..269603eef 100644
--- a/src/core/loader/xci.cpp
+++ b/src/core/loader/xci.cpp
@@ -22,9 +22,9 @@ namespace Loader {
AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file_,
const Service::FileSystem::FileSystemController& fsc,
- const FileSys::ContentProvider& content_provider,
+ const FileSys::ContentProvider& content_provider, u64 program_id,
std::size_t program_index)
- : AppLoader(file_), xci(std::make_unique<FileSys::XCI>(file_, program_index)),
+ : AppLoader(file_), xci(std::make_unique<FileSys::XCI>(file_, program_id, program_index)),
nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) {
if (xci->GetStatus() != ResultStatus::Success) {
return;
@@ -121,6 +121,11 @@ ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) {
return nca_loader->ReadProgramId(out_program_id);
}
+ResultStatus AppLoader_XCI::ReadProgramIds(std::vector<u64>& out_program_ids) {
+ out_program_ids = xci->GetProgramTitleIDs();
+ return ResultStatus::Success;
+}
+
ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) {
if (icon_file == nullptr) {
return ResultStatus::ErrorNoControl;
@@ -149,8 +154,9 @@ ResultStatus AppLoader_XCI::ReadControlData(FileSys::NACP& control) {
}
ResultStatus AppLoader_XCI::ReadManualRomFS(FileSys::VirtualFile& out_file) {
- const auto nca = xci->GetSecurePartitionNSP()->GetNCA(xci->GetProgramTitleID(),
- FileSys::ContentRecordType::HtmlDocument);
+ const auto nca =
+ xci->GetSecurePartitionNSP()->GetNCA(xci->GetSecurePartitionNSP()->GetProgramTitleID(),
+ FileSys::ContentRecordType::HtmlDocument);
if (xci->GetStatus() != ResultStatus::Success || nca == nullptr) {
return ResultStatus::ErrorXCIMissingPartition;
}
diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h
index 708155c30..30caaf90e 100644
--- a/src/core/loader/xci.h
+++ b/src/core/loader/xci.h
@@ -28,7 +28,7 @@ class AppLoader_XCI final : public AppLoader {
public:
explicit AppLoader_XCI(FileSys::VirtualFile file_,
const Service::FileSystem::FileSystemController& fsc,
- const FileSys::ContentProvider& content_provider,
+ const FileSys::ContentProvider& content_provider, u64 program_id,
std::size_t program_index);
~AppLoader_XCI() override;
@@ -51,6 +51,7 @@ public:
u64 ReadRomFSIVFCOffset() const override;
ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override;
ResultStatus ReadProgramId(u64& out_program_id) override;
+ ResultStatus ReadProgramIds(std::vector<u64>& out_program_ids) override;
ResultStatus ReadIcon(std::vector<u8>& buffer) override;
ResultStatus ReadTitle(std::string& title) override;
ResultStatus ReadControlData(FileSys::NACP& control) override;