Attempt to add RomFS dumping

This commit is contained in:
wheremyfoodat 2023-10-07 21:23:05 +03:00
parent f9dc9ac94d
commit abe4675477
10 changed files with 180 additions and 8 deletions

View file

@ -26,6 +26,7 @@ bool NCCH::loadFromHeader(Crypto::AESEngine &aesEngine, IOFile& file, const FSIn
codeFile.clear();
saveData.clear();
partitionInfo = info;
size = u64(*(u32*)&header[0x104]) * mediaUnit; // TODO: Maybe don't type pun because big endian will break
exheaderSize = *(u32*)&header[0x180];

View file

@ -581,4 +581,63 @@ void Emulator::updateDiscord() {
}
#else
void Emulator::updateDiscord() {}
#endif
#endif
static void printNode(const RomFS::RomFSNode& node, int indentation) {
for (int i = 0; i < indentation; i++) {
printf(" ");
}
printf("%s/\n", std::string(node.name.begin(), node.name.end()).c_str());
for (auto& file : node.files) {
for (int i = 0; i <= indentation; i++) {
printf(" ");
}
printf("%s\n", std::string(file->name.begin(), file->name.end()).c_str());
}
indentation++;
for (auto& directory : node.directories) {
printNode(*directory, indentation);
}
indentation--;
}
RomFS::DumpingResult Emulator::dumpRomFS(const std::filesystem::path& path) {
using namespace RomFS;
if (romType != ROMType::NCSD && romType != ROMType::CXI && romType != ROMType::HB_3DSX) {
return DumpingResult::InvalidFormat;
}
// Contents of RomFS as raw bytes
std::vector<u8> romFS;
u64 size;
if (romType == ROMType::HB_3DSX) {
auto hb3dsx = memory.get3DSX();
if (!hb3dsx->hasRomFs()) {
return DumpingResult::NoRomFS;
}
size = hb3dsx->romFSSize;
romFS.resize(size);
hb3dsx->readRomFSBytes(&romFS[0], 0, size);
} else {
auto cxi = memory.getCXI();
if (!cxi->hasRomFS()) {
return DumpingResult::NoRomFS;
}
const u64 offset = cxi->romFS.offset;
size = cxi->romFS.size;
romFS.resize(size);
cxi->readFromFile(memory.CXIFile, cxi->partitionInfo, &romFS[0], offset - cxi->fileOffset, size);
}
std::unique_ptr<RomFSNode> node = parseRomFSTree((uintptr_t)&romFS[0], size);
printNode(*node, 0);
return DumpingResult::Success;
}

View file

@ -0,0 +1,37 @@
#include "memory_mapped_file.hpp"
MemoryMappedFile::MemoryMappedFile() : opened(false), filePath(""), pointer(nullptr) {}
MemoryMappedFile::MemoryMappedFile(const std::filesystem::path& path) { open(path); }
MemoryMappedFile::~MemoryMappedFile() { close(); }
// TODO: This should probably also return the error one way or another eventually
bool MemoryMappedFile::open(const std::filesystem::path& path) {
std::error_code error;
map = mio::make_mmap_sink(path.string(), 0, mio::map_entire_file, error);
if (error) {
opened = false;
return false;
}
filePath = path;
pointer = (u8*)map.data();
opened = true;
return true;
}
void MemoryMappedFile::close() {
if (opened) {
opened = false;
pointer = nullptr; // Set the pointer to nullptr to avoid errors related to lingering pointers
map.unmap();
}
}
std::error_code MemoryMappedFile::flush() {
std::error_code ret;
map.sync(ret);
return ret;
}

View file

@ -16,13 +16,19 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
menuBar = new QMenuBar(this);
setMenuBar(menuBar);
// Create menu bar menus
auto fileMenu = menuBar->addMenu(tr("File"));
auto emulationMenu = menuBar->addMenu(tr("Emulation"));
auto toolsMenu = menuBar->addMenu(tr("Tools"));
auto helpMenu = menuBar->addMenu(tr("Help"));
auto aboutMenu = menuBar->addMenu(tr("About"));
// Create and bind actions for them
auto pandaAction = fileMenu->addAction(tr("panda..."));
connect(pandaAction, &QAction::triggered, this, &MainWindow::selectROM);
auto emulationMenu = menuBar->addMenu(tr("Emulation"));
auto helpMenu = menuBar->addMenu(tr("Help"));
auto aboutMenu = menuBar->addMenu(tr("About"));
auto dumpRomFSAction = toolsMenu->addAction(tr("Dump RomFS"));
connect(dumpRomFSAction, &QAction::triggered, this, &MainWindow::dumpRomFS);
// Set up theme selection
setTheme(Theme::Dark);
@ -71,6 +77,7 @@ void MainWindow::emuThreadMainLoop() {
}
needToLoadROM.store(false, std::memory_order::seq_cst);
emu->dumpRomFS("");
}
emu->runFrame();
@ -98,8 +105,8 @@ void MainWindow::selectROM() {
return;
}
auto path =
QFileDialog::getOpenFileName(this, tr("Select 3DS ROM to load"), "", tr("Nintendo 3DS ROMs (*.3ds *.cci *.cxi *.app *.3dsx *.elf *.axf)"));
auto path = QFileDialog::getOpenFileName(
this, tr("Select 3DS ROM to load"), {}, tr("Nintendo 3DS ROMs (*.3ds *.cci *.cxi *.app *.3dsx *.elf *.axf)"), {});
if (!path.isEmpty()) {
romToLoad = path.toStdU16String();
@ -175,4 +182,18 @@ void MainWindow::setTheme(Theme theme) {
break;
}
}
}
void MainWindow::dumpRomFS() {
// TODO: LOCK FILE MUTEX HERE
auto folder = QFileDialog::getExistingDirectory(
this, tr("Select folder to dump RomFS files to"), "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
);
if (folder.isEmpty()) {
return;
}
std::filesystem::path path(folder.toStdU16String());
//RomFS::DumpingResult res = emu->dumpRomFS(path);
}