mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-06-02 05:58:43 +02:00
66 lines
2.4 KiB
C++
66 lines
2.4 KiB
C++
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
|
|
|
#include <kernel/types/KProcess.h>
|
|
#include "nca.h"
|
|
#include "nsp.h"
|
|
|
|
namespace skyline::loader {
|
|
NspLoader::NspLoader(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<crypto::KeyStore> &keyStore) : nsp(std::make_shared<vfs::PartitionFileSystem>(backing)) {
|
|
auto root{nsp->OpenDirectory("", {false, true})};
|
|
|
|
for (const auto &entry : root->Read()) {
|
|
if (entry.name.substr(entry.name.find_last_of(".") + 1) != "nca")
|
|
continue;
|
|
|
|
try {
|
|
auto nca{vfs::NCA(nsp->OpenFile(entry.name), keyStore)};
|
|
|
|
if (nca.contentType == vfs::NcaContentType::Program && nca.romFs != nullptr && nca.exeFs != nullptr)
|
|
programNca = std::move(nca);
|
|
else if (nca.contentType == vfs::NcaContentType::Control && nca.romFs != nullptr)
|
|
controlNca = std::move(nca);
|
|
} catch (const loader_exception &e) {
|
|
throw loader_exception(e.error);
|
|
} catch (const std::exception &e) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (!programNca || !controlNca)
|
|
throw exception("Incomplete NSP file");
|
|
|
|
romFs = programNca->romFs;
|
|
controlRomFs = std::make_shared<vfs::RomFileSystem>(controlNca->romFs);
|
|
nacp.emplace(controlRomFs->OpenFile("control.nacp"));
|
|
}
|
|
|
|
void *NspLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
|
process->npdm = vfs::NPDM(programNca->exeFs->OpenFile("main.npdm"));
|
|
return NcaLoader::LoadExeFs(programNca->exeFs, process, state);
|
|
}
|
|
|
|
std::vector<u8> NspLoader::GetIcon() {
|
|
if (romFs == nullptr)
|
|
return std::vector<u8>();
|
|
|
|
auto root{controlRomFs->OpenDirectory("", {false, true})};
|
|
std::shared_ptr<vfs::Backing> icon;
|
|
|
|
// Use the first icon file available
|
|
for (const auto &entry : root->Read()) {
|
|
if (entry.name.rfind("icon") == 0) {
|
|
icon = controlRomFs->OpenFile(entry.name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (icon == nullptr)
|
|
return std::vector<u8>();
|
|
|
|
std::vector<u8> buffer(icon->size);
|
|
icon->Read(buffer);
|
|
return buffer;
|
|
}
|
|
}
|