summaryrefslogtreecommitdiff
path: root/src/core/loader/nro.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2018-07-23 14:14:11 -0700
committerGravatar GitHub2018-07-23 14:14:11 -0700
commit07e5319d552ed1ad9b9fbe47852c581d48c1e46c (patch)
treeb40b503cde453eb513228f67c826f11ff6ef5d1c /src/core/loader/nro.cpp
parentMerge pull request #778 from lioncash/log (diff)
parentNRO Assets and NACP file format (diff)
downloadyuzu-07e5319d552ed1ad9b9fbe47852c581d48c1e46c.tar.gz
yuzu-07e5319d552ed1ad9b9fbe47852c581d48c1e46c.tar.xz
yuzu-07e5319d552ed1ad9b9fbe47852c581d48c1e46c.zip
Merge pull request #695 from DarkLordZach/nro-asset
NRO Assets and NACP File Format
Diffstat (limited to 'src/core/loader/nro.cpp')
-rw-r--r--src/core/loader/nro.cpp79
1 files changed, 78 insertions, 1 deletions
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index c020399f2..44158655c 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -10,6 +10,8 @@
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11#include "common/swap.h" 11#include "common/swap.h"
12#include "core/core.h" 12#include "core/core.h"
13#include "core/file_sys/control_metadata.h"
14#include "core/file_sys/vfs_offset.h"
13#include "core/gdbstub/gdbstub.h" 15#include "core/gdbstub/gdbstub.h"
14#include "core/hle/kernel/process.h" 16#include "core/hle/kernel/process.h"
15#include "core/hle/kernel/resource_limit.h" 17#include "core/hle/kernel/resource_limit.h"
@@ -49,7 +51,55 @@ struct ModHeader {
49}; 51};
50static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size."); 52static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size.");
51 53
52AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} 54struct AssetSection {
55 u64_le offset;
56 u64_le size;
57};
58static_assert(sizeof(AssetSection) == 0x10, "AssetSection has incorrect size.");
59
60struct AssetHeader {
61 u32_le magic;
62 u32_le format_version;
63 AssetSection icon;
64 AssetSection nacp;
65 AssetSection romfs;
66};
67static_assert(sizeof(AssetHeader) == 0x38, "AssetHeader has incorrect size.");
68
69AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file) : AppLoader(file) {
70 NroHeader nro_header{};
71 if (file->ReadObject(&nro_header) != sizeof(NroHeader))
72 return;
73
74 if (file->GetSize() >= nro_header.file_size + sizeof(AssetHeader)) {
75 u64 offset = nro_header.file_size;
76 AssetHeader asset_header{};
77 if (file->ReadObject(&asset_header, offset) != sizeof(AssetHeader))
78 return;
79
80 if (asset_header.format_version != 0)
81 LOG_WARNING(Loader,
82 "NRO Asset Header has format {}, currently supported format is 0. If "
83 "strange glitches occur with metadata, check NRO assets.",
84 asset_header.format_version);
85 if (asset_header.magic != Common::MakeMagic('A', 'S', 'E', 'T'))
86 return;
87
88 if (asset_header.nacp.size > 0) {
89 nacp = std::make_unique<FileSys::NACP>(std::make_shared<FileSys::OffsetVfsFile>(
90 file, asset_header.nacp.size, offset + asset_header.nacp.offset, "Control.nacp"));
91 }
92
93 if (asset_header.romfs.size > 0) {
94 romfs = std::make_shared<FileSys::OffsetVfsFile>(
95 file, asset_header.romfs.size, offset + asset_header.romfs.offset, "game.romfs");
96 }
97
98 if (asset_header.icon.size > 0) {
99 icon_data = file->ReadBytes(asset_header.icon.size, offset + asset_header.icon.offset);
100 }
101 }
102}
53 103
54FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& file) { 104FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& file) {
55 // Read NSO header 105 // Read NSO header
@@ -136,4 +186,31 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
136 return ResultStatus::Success; 186 return ResultStatus::Success;
137} 187}
138 188
189ResultStatus AppLoader_NRO::ReadIcon(std::vector<u8>& buffer) {
190 if (icon_data.empty())
191 return ResultStatus::ErrorNotUsed;
192 buffer = icon_data;
193 return ResultStatus::Success;
194}
195
196ResultStatus AppLoader_NRO::ReadProgramId(u64& out_program_id) {
197 if (nacp == nullptr)
198 return ResultStatus::ErrorNotUsed;
199 out_program_id = nacp->GetTitleId();
200 return ResultStatus::Success;
201}
202
203ResultStatus AppLoader_NRO::ReadRomFS(FileSys::VirtualFile& dir) {
204 if (romfs == nullptr)
205 return ResultStatus::ErrorNotUsed;
206 dir = romfs;
207 return ResultStatus::Success;
208}
209
210ResultStatus AppLoader_NRO::ReadTitle(std::string& title) {
211 if (nacp == nullptr)
212 return ResultStatus::ErrorNotUsed;
213 title = nacp->GetApplicationName();
214 return ResultStatus::Success;
215}
139} // namespace Loader 216} // namespace Loader