core: Add dump RomFS support
This is added to LayeredFS, then the NCCH container and then the loader interface.
This commit is contained in:
@ -52,7 +52,7 @@ struct FileMetadata {
|
||||
static_assert(sizeof(FileMetadata) == 0x20, "Size of FileMetadata is not correct");
|
||||
|
||||
LayeredFS::LayeredFS(std::shared_ptr<RomFSReader> romfs_, std::string patch_path_,
|
||||
std::string patch_ext_path_)
|
||||
std::string patch_ext_path_, bool load_relocations)
|
||||
: romfs(std::move(romfs_)), patch_path(std::move(patch_path_)),
|
||||
patch_ext_path(std::move(patch_ext_path_)) {
|
||||
|
||||
@ -64,8 +64,10 @@ LayeredFS::LayeredFS(std::shared_ptr<RomFSReader> romfs_, std::string patch_path
|
||||
root.parent = &root;
|
||||
LoadDirectory(root, 0);
|
||||
|
||||
LoadRelocations();
|
||||
LoadExtRelocations();
|
||||
if (load_relocations) {
|
||||
LoadRelocations();
|
||||
LoadExtRelocations();
|
||||
}
|
||||
|
||||
RebuildMetadata();
|
||||
}
|
||||
@ -541,4 +543,60 @@ std::size_t LayeredFS::ReadFile(std::size_t offset, std::size_t length, u8* buff
|
||||
return read_size;
|
||||
}
|
||||
|
||||
bool LayeredFS::ExtractDirectory(Directory& current, const std::string& target_path) {
|
||||
if (!FileUtil::CreateFullPath(target_path + current.path)) {
|
||||
LOG_ERROR(Service_FS, "Could not create path {}", target_path + current.path);
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr std::size_t BufferSize = 0x10000;
|
||||
std::array<u8, BufferSize> buffer;
|
||||
for (const auto& file : current.files) {
|
||||
// Extract file
|
||||
const auto path = target_path + file->path;
|
||||
LOG_INFO(Service_FS, "Extracting {} to {}", file->path, path);
|
||||
|
||||
FileUtil::IOFile target_file(path, "wb");
|
||||
if (!target_file) {
|
||||
LOG_ERROR(Service_FS, "Could not open file {}", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::size_t written = 0;
|
||||
while (written < file->relocation.size) {
|
||||
const auto to_read =
|
||||
std::min<std::size_t>(buffer.size(), file->relocation.size - written);
|
||||
if (romfs->ReadFile(file->relocation.original_offset + written, to_read,
|
||||
buffer.data()) != to_read) {
|
||||
LOG_ERROR(Service_FS, "Could not read from RomFS");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target_file.WriteBytes(buffer.data(), to_read) != to_read) {
|
||||
LOG_ERROR(Service_FS, "Could not write to file {}", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
written += to_read;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& directory : current.directories) {
|
||||
if (!ExtractDirectory(*directory, target_path)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LayeredFS::DumpRomFS(const std::string& target_path) {
|
||||
std::string path = target_path;
|
||||
if (path.back() == '/' || path.back() == '\\') {
|
||||
path.erase(path.size() - 1, 1);
|
||||
}
|
||||
|
||||
return ExtractDirectory(root, path);
|
||||
}
|
||||
|
||||
} // namespace FileSys
|
||||
|
Reference in New Issue
Block a user