summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-08-25 11:50:04 -0400
committerGravatar Zach Hilman2018-09-04 14:28:41 -0400
commitf7eaea424d07e971d0279257d20d408b64ef05b6 (patch)
tree4ddf73c89c0b2a88cecb7b508c9ef5d680b506c7 /src
parentloader: Add AppLoader for NSP files (diff)
downloadyuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.tar.gz
yuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.tar.xz
yuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.zip
registration: Add support for installing NSP files
Diffstat (limited to 'src')
-rw-r--r--src/core/file_sys/registered_cache.cpp20
-rw-r--r--src/core/file_sys/registered_cache.h6
-rw-r--r--src/yuzu/main.cpp24
3 files changed, 34 insertions, 16 deletions
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index d9decc104..94268d127 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -358,17 +358,21 @@ std::vector<RegisteredCacheEntry> RegisteredCache::ListEntriesFilter(
358 return out; 358 return out;
359} 359}
360 360
361static std::shared_ptr<NCA> GetNCAFromXCIForID(std::shared_ptr<XCI> xci, const NcaID& id) { 361static std::shared_ptr<NCA> GetNCAFromNSPForID(std::shared_ptr<NSP> nsp, const NcaID& id) {
362 const auto filename = fmt::format("{}.nca", Common::HexArrayToString(id, false)); 362 const auto file = nsp->GetFile(fmt::format("{}.nca", Common::HexArrayToString(id, false)));
363 const auto iter = 363 if (file == nullptr)
364 std::find_if(xci->GetNCAs().begin(), xci->GetNCAs().end(), 364 return nullptr;
365 [&filename](std::shared_ptr<NCA> nca) { return nca->GetName() == filename; }); 365 return std::make_shared<NCA>(file);
366 return iter == xci->GetNCAs().end() ? nullptr : *iter;
367} 366}
368 367
369InstallResult RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci, bool overwrite_if_exists, 368InstallResult RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci, bool overwrite_if_exists,
370 const VfsCopyFunction& copy) { 369 const VfsCopyFunction& copy) {
371 const auto& ncas = xci->GetNCAs(); 370 return InstallEntry(xci->GetSecurePartitionNSP(), overwrite_if_exists, copy);
371}
372
373InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NSP> nsp, bool overwrite_if_exists,
374 const VfsCopyFunction& copy) {
375 const auto& ncas = nsp->GetNCAsCollapsed();
372 const auto& meta_iter = std::find_if(ncas.begin(), ncas.end(), [](std::shared_ptr<NCA> nca) { 376 const auto& meta_iter = std::find_if(ncas.begin(), ncas.end(), [](std::shared_ptr<NCA> nca) {
373 return nca->GetType() == NCAContentType::Meta; 377 return nca->GetType() == NCAContentType::Meta;
374 }); 378 });
@@ -392,7 +396,7 @@ InstallResult RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci, bool overw
392 const auto cnmt_file = section0->GetFiles()[0]; 396 const auto cnmt_file = section0->GetFiles()[0];
393 const CNMT cnmt(cnmt_file); 397 const CNMT cnmt(cnmt_file);
394 for (const auto& record : cnmt.GetContentRecords()) { 398 for (const auto& record : cnmt.GetContentRecords()) {
395 const auto nca = GetNCAFromXCIForID(xci, record.nca_id); 399 const auto nca = GetNCAFromNSPForID(nsp, record.nca_id);
396 if (nca == nullptr) 400 if (nca == nullptr)
397 return InstallResult::ErrorCopyFailed; 401 return InstallResult::ErrorCopyFailed;
398 const auto res2 = RawInstallNCA(nca, copy, overwrite_if_exists, record.nca_id); 402 const auto res2 = RawInstallNCA(nca, copy, overwrite_if_exists, record.nca_id);
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index fe2cdc3d9..50e26f8fb 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -89,10 +89,12 @@ public:
89 boost::optional<ContentRecordType> record_type = boost::none, 89 boost::optional<ContentRecordType> record_type = boost::none,
90 boost::optional<u64> title_id = boost::none) const; 90 boost::optional<u64> title_id = boost::none) const;
91 91
92 // Raw copies all the ncas from the xci to the csache. Does some quick checks to make sure there 92 // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure
93 // is a meta NCA and all of them are accessible. 93 // there is a meta NCA and all of them are accessible.
94 InstallResult InstallEntry(std::shared_ptr<XCI> xci, bool overwrite_if_exists = false, 94 InstallResult InstallEntry(std::shared_ptr<XCI> xci, bool overwrite_if_exists = false,
95 const VfsCopyFunction& copy = &VfsRawCopy); 95 const VfsCopyFunction& copy = &VfsRawCopy);
96 InstallResult InstallEntry(std::shared_ptr<NSP> nsp, bool overwrite_if_exists = false,
97 const VfsCopyFunction& copy = &VfsRawCopy);
96 98
97 // Due to the fact that we must use Meta-type NCAs to determine the existance of files, this 99 // Due to the fact that we must use Meta-type NCAs to determine the existance of files, this
98 // poses quite a challenge. Instead of creating a new meta NCA for this file, yuzu will create a 100 // poses quite a challenge. Instead of creating a new meta NCA for this file, yuzu will create a
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 262e33487..c4eda4bab 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -806,22 +806,34 @@ void GMainWindow::OnMenuInstallToNAND() {
806 QMessageBox::Yes; 806 QMessageBox::Yes;
807 }; 807 };
808 808
809 if (filename.endsWith("xci", Qt::CaseInsensitive)) { 809 if (filename.endsWith("xci", Qt::CaseInsensitive) ||
810 const auto xci = std::make_shared<FileSys::XCI>( 810 filename.endsWith("nsp", Qt::CaseInsensitive)) {
811 vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); 811
812 if (xci->GetStatus() != Loader::ResultStatus::Success) { 812 std::shared_ptr<FileSys::NSP> nsp;
813 if (filename.endsWith("nsp", Qt::CaseInsensitive)) {
814 nsp = std::make_shared<FileSys::NSP>(
815 vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
816 if (!nsp->IsExtractedType())
817 failed();
818 } else {
819 const auto xci = std::make_shared<FileSys::XCI>(
820 vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
821 nsp = xci->GetSecurePartitionNSP();
822 }
823
824 if (nsp->GetStatus() != Loader::ResultStatus::Success) {
813 failed(); 825 failed();
814 return; 826 return;
815 } 827 }
816 const auto res = 828 const auto res =
817 Service::FileSystem::GetUserNANDContents()->InstallEntry(xci, false, qt_raw_copy); 829 Service::FileSystem::GetUserNANDContents()->InstallEntry(nsp, false, qt_raw_copy);
818 if (res == FileSys::InstallResult::Success) { 830 if (res == FileSys::InstallResult::Success) {
819 success(); 831 success();
820 } else { 832 } else {
821 if (res == FileSys::InstallResult::ErrorAlreadyExists) { 833 if (res == FileSys::InstallResult::ErrorAlreadyExists) {
822 if (overwrite()) { 834 if (overwrite()) {
823 const auto res2 = Service::FileSystem::GetUserNANDContents()->InstallEntry( 835 const auto res2 = Service::FileSystem::GetUserNANDContents()->InstallEntry(
824 xci, true, qt_raw_copy); 836 nsp, true, qt_raw_copy);
825 if (res2 == FileSys::InstallResult::Success) { 837 if (res2 == FileSys::InstallResult::Success) {
826 success(); 838 success();
827 } else { 839 } else {