summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/loader/3dsx.cpp40
-rw-r--r--src/core/loader/3dsx.h14
-rw-r--r--src/core/loader/loader.cpp10
3 files changed, 61 insertions, 3 deletions
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp
index 530837d08..111b6a409 100644
--- a/src/core/loader/3dsx.cpp
+++ b/src/core/loader/3dsx.cpp
@@ -62,6 +62,10 @@ struct THREEDSX_Header
62 // Sizes of the code, rodata and data segments + 62 // Sizes of the code, rodata and data segments +
63 // size of the BSS section (uninitialized latter half of the data segment) 63 // size of the BSS section (uninitialized latter half of the data segment)
64 u32 code_seg_size, rodata_seg_size, data_seg_size, bss_size; 64 u32 code_seg_size, rodata_seg_size, data_seg_size, bss_size;
65 // offset and size of smdh
66 u32 smdh_offset, smdh_size;
67 // offset to filesystem
68 u32 fs_offset;
65}; 69};
66 70
67// Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts. 71// Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts.
@@ -267,4 +271,40 @@ ResultStatus AppLoader_THREEDSX::Load() {
267 return ResultStatus::Success; 271 return ResultStatus::Success;
268} 272}
269 273
274ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) {
275 if (!file.IsOpen())
276 return ResultStatus::Error;
277
278 // Reset read pointer in case this file has been read before.
279 file.Seek(0, SEEK_SET);
280
281 THREEDSX_Header hdr;
282 if (file.ReadBytes(&hdr, sizeof(THREEDSX_Header)) != sizeof(THREEDSX_Header))
283 return ResultStatus::Error;
284
285 if (hdr.header_size != sizeof(THREEDSX_Header))
286 return ResultStatus::Error;
287
288 // Check if the 3DSX has a RomFS...
289 if (hdr.fs_offset != 0) {
290 u32 romfs_offset = hdr.fs_offset;
291 u32 romfs_size = file.GetSize() - hdr.fs_offset;
292
293 LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset);
294 LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size);
295
296 // We reopen the file, to allow its position to be independent from file's
297 romfs_file = std::make_shared<FileUtil::IOFile>(filepath, "rb");
298 if (!romfs_file->IsOpen())
299 return ResultStatus::Error;
300
301 offset = romfs_offset;
302 size = romfs_size;
303
304 return ResultStatus::Success;
305 }
306 LOG_DEBUG(Loader, "3DSX has no RomFS");
307 return ResultStatus::ErrorNotUsed;
308}
309
270} // namespace Loader 310} // namespace Loader
diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h
index a0aa0c533..365ddb7a5 100644
--- a/src/core/loader/3dsx.h
+++ b/src/core/loader/3dsx.h
@@ -17,8 +17,8 @@ namespace Loader {
17/// Loads an 3DSX file 17/// Loads an 3DSX file
18class AppLoader_THREEDSX final : public AppLoader { 18class AppLoader_THREEDSX final : public AppLoader {
19public: 19public:
20 AppLoader_THREEDSX(FileUtil::IOFile&& file, std::string filename) 20 AppLoader_THREEDSX(FileUtil::IOFile&& file, std::string filename, const std::string& filepath)
21 : AppLoader(std::move(file)), filename(std::move(filename)) {} 21 : AppLoader(std::move(file)), filename(std::move(filename)), filepath(filepath) {}
22 22
23 /** 23 /**
24 * Returns the type of the file 24 * Returns the type of the file
@@ -33,8 +33,18 @@ public:
33 */ 33 */
34 ResultStatus Load() override; 34 ResultStatus Load() override;
35 35
36 /**
37 * Get the RomFS of the application
38 * @param romfs_file Reference to buffer to store data
39 * @param offset Offset in the file to the RomFS
40 * @param size Size of the RomFS in bytes
41 * @return ResultStatus result of function
42 */
43 ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override;
44
36private: 45private:
37 std::string filename; 46 std::string filename;
47 std::string filepath;
38}; 48};
39 49
40} // namespace Loader 50} // namespace Loader
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 74eb6e871..c4b4f5a5d 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -116,7 +116,15 @@ ResultStatus LoadFile(const std::string& filename) {
116 116
117 //3DSX file format... 117 //3DSX file format...
118 case FileType::THREEDSX: 118 case FileType::THREEDSX:
119 return AppLoader_THREEDSX(std::move(file), filename_filename).Load(); 119 {
120 AppLoader_THREEDSX app_loader(std::move(file), filename_filename, filename);
121 // Load application and RomFS
122 if (ResultStatus::Success == app_loader.Load()) {
123 Service::FS::RegisterArchiveType(Common::make_unique<FileSys::ArchiveFactory_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS);
124 return ResultStatus::Success;
125 }
126 break;
127 }
120 128
121 // Standard ELF file format... 129 // Standard ELF file format...
122 case FileType::ELF: 130 case FileType::ELF: