Merge pull request #1436 from lioncash/view

submission_package: Cleanup and bug fixes
pull/8/head
bunnei 7 years ago committed by GitHub
commit 15b2e2ec13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -18,91 +18,57 @@
#include "core/loader/loader.h" #include "core/loader/loader.h"
namespace FileSys { namespace FileSys {
NSP::NSP(VirtualFile file_) namespace {
: file(std::move(file_)), status{Loader::ResultStatus::Success}, void SetTicketKeys(const std::vector<VirtualFile>& files) {
pfs(std::make_shared<PartitionFilesystem>(file)) { Core::Crypto::KeyManager keys;
if (pfs->GetStatus() != Loader::ResultStatus::Success) {
status = pfs->GetStatus();
return;
}
if (IsDirectoryExeFS(pfs)) {
extracted = true;
exefs = pfs;
const auto& files = pfs->GetFiles(); for (const auto& ticket_file : files) {
const auto romfs_iter = if (ticket_file == nullptr) {
std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { continue;
return file->GetName().find(".romfs") != std::string::npos;
});
if (romfs_iter != files.end())
romfs = *romfs_iter;
return;
} }
extracted = false; if (ticket_file->GetExtension() != "tik") {
const auto files = pfs->GetFiles(); continue;
}
Core::Crypto::KeyManager keys; if (ticket_file->GetSize() <
for (const auto& ticket_file : files) {
if (ticket_file->GetExtension() == "tik") {
if (ticket_file == nullptr ||
ticket_file->GetSize() <
Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET + sizeof(Core::Crypto::Key128)) { Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET + sizeof(Core::Crypto::Key128)) {
continue; continue;
} }
Core::Crypto::Key128 key{}; Core::Crypto::Key128 key{};
ticket_file->Read(key.data(), key.size(), Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET); ticket_file->Read(key.data(), key.size(), Core::Crypto::TICKET_FILE_TITLEKEY_OFFSET);
std::string_view name_only(ticket_file->GetName());
name_only.remove_suffix(4); // We get the name without the extension in order to create the rights ID.
std::string name_only(ticket_file->GetName());
name_only.erase(name_only.size() - 4);
const auto rights_id_raw = Common::HexStringToArray<16>(name_only); const auto rights_id_raw = Common::HexStringToArray<16>(name_only);
u128 rights_id; u128 rights_id;
std::memcpy(rights_id.data(), rights_id_raw.data(), sizeof(u128)); std::memcpy(rights_id.data(), rights_id_raw.data(), sizeof(u128));
keys.SetKey(Core::Crypto::S128KeyType::Titlekey, key, rights_id[1], rights_id[0]); keys.SetKey(Core::Crypto::S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
} }
} }
} // Anonymous namespace
for (const auto& outer_file : files) { NSP::NSP(VirtualFile file_)
if (outer_file->GetName().substr(outer_file->GetName().size() - 9) == ".cnmt.nca") { : file(std::move(file_)), status{Loader::ResultStatus::Success},
const auto nca = std::make_shared<NCA>(outer_file); pfs(std::make_shared<PartitionFilesystem>(file)) {
if (nca->GetStatus() != Loader::ResultStatus::Success) { if (pfs->GetStatus() != Loader::ResultStatus::Success) {
program_status[nca->GetTitleId()] = nca->GetStatus(); status = pfs->GetStatus();
continue; return;
} }
const auto section0 = nca->GetSubdirectories()[0]; const auto files = pfs->GetFiles();
for (const auto& inner_file : section0->GetFiles()) {
if (inner_file->GetExtension() != "cnmt")
continue;
const CNMT cnmt(inner_file);
auto& ncas_title = ncas[cnmt.GetTitleID()];
ncas_title[ContentRecordType::Meta] = nca;
for (const auto& rec : cnmt.GetContentRecords()) {
const auto id_string = Common::HexArrayToString(rec.nca_id, false);
const auto next_file = pfs->GetFile(fmt::format("{}.nca", id_string));
if (next_file == nullptr) {
LOG_WARNING(Service_FS,
"NCA with ID {}.nca is listed in content metadata, but cannot "
"be found in PFS. NSP appears to be corrupted.",
id_string);
continue;
}
auto next_nca = std::make_shared<NCA>(next_file); if (IsDirectoryExeFS(pfs)) {
if (next_nca->GetType() == NCAContentType::Program) extracted = true;
program_status[cnmt.GetTitleID()] = next_nca->GetStatus(); InitializeExeFSAndRomFS(files);
if (next_nca->GetStatus() == Loader::ResultStatus::Success) return;
ncas_title[rec.type] = std::move(next_nca);
} }
break; SetTicketKeys(files);
} ReadNCAs(files);
}
}
} }
NSP::~NSP() = default; NSP::~NSP() = default;
@ -242,4 +208,63 @@ VirtualDir NSP::GetParentDirectory() const {
bool NSP::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { bool NSP::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
return false; return false;
} }
void NSP::InitializeExeFSAndRomFS(const std::vector<VirtualFile>& files) {
exefs = pfs;
const auto romfs_iter = std::find_if(files.begin(), files.end(), [](const VirtualFile& file) {
return file->GetName().rfind(".romfs") != std::string::npos;
});
if (romfs_iter == files.end()) {
return;
}
romfs = *romfs_iter;
}
void NSP::ReadNCAs(const std::vector<VirtualFile>& files) {
for (const auto& outer_file : files) {
if (outer_file->GetName().substr(outer_file->GetName().size() - 9) != ".cnmt.nca") {
continue;
}
const auto nca = std::make_shared<NCA>(outer_file);
if (nca->GetStatus() != Loader::ResultStatus::Success) {
program_status[nca->GetTitleId()] = nca->GetStatus();
continue;
}
const auto section0 = nca->GetSubdirectories()[0];
for (const auto& inner_file : section0->GetFiles()) {
if (inner_file->GetExtension() != "cnmt")
continue;
const CNMT cnmt(inner_file);
auto& ncas_title = ncas[cnmt.GetTitleID()];
ncas_title[ContentRecordType::Meta] = nca;
for (const auto& rec : cnmt.GetContentRecords()) {
const auto id_string = Common::HexArrayToString(rec.nca_id, false);
const auto next_file = pfs->GetFile(fmt::format("{}.nca", id_string));
if (next_file == nullptr) {
LOG_WARNING(Service_FS,
"NCA with ID {}.nca is listed in content metadata, but cannot "
"be found in PFS. NSP appears to be corrupted.",
id_string);
continue;
}
auto next_nca = std::make_shared<NCA>(next_file);
if (next_nca->GetType() == NCAContentType::Program)
program_status[cnmt.GetTitleID()] = next_nca->GetStatus();
if (next_nca->GetStatus() == Loader::ResultStatus::Success)
ncas_title[rec.type] = std::move(next_nca);
}
break;
}
}
}
} // namespace FileSys } // namespace FileSys

@ -59,9 +59,12 @@ protected:
bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
private: private:
void InitializeExeFSAndRomFS(const std::vector<VirtualFile>& files);
void ReadNCAs(const std::vector<VirtualFile>& files);
VirtualFile file; VirtualFile file;
bool extracted; bool extracted = false;
Loader::ResultStatus status; Loader::ResultStatus status;
std::map<u64, Loader::ResultStatus> program_status; std::map<u64, Loader::ResultStatus> program_status;

Loading…
Cancel
Save