summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZach Hilman <zachhilman@gmail.com>2018-08-25 17:50:04 +0200
committerZach Hilman <zachhilman@gmail.com>2018-09-04 20:28:41 +0200
commitf7eaea424d07e971d0279257d20d408b64ef05b6 (patch)
tree4ddf73c89c0b2a88cecb7b508c9ef5d680b506c7
parentloader: Add AppLoader for NSP files (diff)
downloadyuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.tar
yuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.tar.gz
yuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.tar.bz2
yuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.tar.lz
yuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.tar.xz
yuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.tar.zst
yuzu-f7eaea424d07e971d0279257d20d408b64ef05b6.zip
-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(
return out;
}
-static std::shared_ptr<NCA> GetNCAFromXCIForID(std::shared_ptr<XCI> xci, const NcaID& id) {
- const auto filename = fmt::format("{}.nca", Common::HexArrayToString(id, false));
- const auto iter =
- std::find_if(xci->GetNCAs().begin(), xci->GetNCAs().end(),
- [&filename](std::shared_ptr<NCA> nca) { return nca->GetName() == filename; });
- return iter == xci->GetNCAs().end() ? nullptr : *iter;
+static std::shared_ptr<NCA> GetNCAFromNSPForID(std::shared_ptr<NSP> nsp, const NcaID& id) {
+ const auto file = nsp->GetFile(fmt::format("{}.nca", Common::HexArrayToString(id, false)));
+ if (file == nullptr)
+ return nullptr;
+ return std::make_shared<NCA>(file);
}
InstallResult RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci, bool overwrite_if_exists,
const VfsCopyFunction& copy) {
- const auto& ncas = xci->GetNCAs();
+ return InstallEntry(xci->GetSecurePartitionNSP(), overwrite_if_exists, copy);
+}
+
+InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NSP> nsp, bool overwrite_if_exists,
+ const VfsCopyFunction& copy) {
+ const auto& ncas = nsp->GetNCAsCollapsed();
const auto& meta_iter = std::find_if(ncas.begin(), ncas.end(), [](std::shared_ptr<NCA> nca) {
return nca->GetType() == NCAContentType::Meta;
});
@@ -392,7 +396,7 @@ InstallResult RegisteredCache::InstallEntry(std::shared_ptr<XCI> xci, bool overw
const auto cnmt_file = section0->GetFiles()[0];
const CNMT cnmt(cnmt_file);
for (const auto& record : cnmt.GetContentRecords()) {
- const auto nca = GetNCAFromXCIForID(xci, record.nca_id);
+ const auto nca = GetNCAFromNSPForID(nsp, record.nca_id);
if (nca == nullptr)
return InstallResult::ErrorCopyFailed;
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:
boost::optional<ContentRecordType> record_type = boost::none,
boost::optional<u64> title_id = boost::none) const;
- // Raw copies all the ncas from the xci to the csache. Does some quick checks to make sure there
- // is a meta NCA and all of them are accessible.
+ // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure
+ // there is a meta NCA and all of them are accessible.
InstallResult InstallEntry(std::shared_ptr<XCI> xci, bool overwrite_if_exists = false,
const VfsCopyFunction& copy = &VfsRawCopy);
+ InstallResult InstallEntry(std::shared_ptr<NSP> nsp, bool overwrite_if_exists = false,
+ const VfsCopyFunction& copy = &VfsRawCopy);
// Due to the fact that we must use Meta-type NCAs to determine the existance of files, this
// 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() {
QMessageBox::Yes;
};
- if (filename.endsWith("xci", Qt::CaseInsensitive)) {
- const auto xci = std::make_shared<FileSys::XCI>(
- vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
- if (xci->GetStatus() != Loader::ResultStatus::Success) {
+ if (filename.endsWith("xci", Qt::CaseInsensitive) ||
+ filename.endsWith("nsp", Qt::CaseInsensitive)) {
+
+ std::shared_ptr<FileSys::NSP> nsp;
+ if (filename.endsWith("nsp", Qt::CaseInsensitive)) {
+ nsp = std::make_shared<FileSys::NSP>(
+ vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
+ if (!nsp->IsExtractedType())
+ failed();
+ } else {
+ const auto xci = std::make_shared<FileSys::XCI>(
+ vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
+ nsp = xci->GetSecurePartitionNSP();
+ }
+
+ if (nsp->GetStatus() != Loader::ResultStatus::Success) {
failed();
return;
}
const auto res =
- Service::FileSystem::GetUserNANDContents()->InstallEntry(xci, false, qt_raw_copy);
+ Service::FileSystem::GetUserNANDContents()->InstallEntry(nsp, false, qt_raw_copy);
if (res == FileSys::InstallResult::Success) {
success();
} else {
if (res == FileSys::InstallResult::ErrorAlreadyExists) {
if (overwrite()) {
const auto res2 = Service::FileSystem::GetUserNANDContents()->InstallEntry(
- xci, true, qt_raw_copy);
+ nsp, true, qt_raw_copy);
if (res2 == FileSys::InstallResult::Success) {
success();
} else {