From 618eb9f7439c99ff54996db2b7c91bcfaea14e88 Mon Sep 17 00:00:00 2001 From: Starsam80 Date: Sat, 6 May 2017 21:26:46 -0600 Subject: [PATCH 1/2] NANDImporter: Use a indeterminate progress meter --- Source/Core/DiscIO/NANDImporter.cpp | 33 +++++++++------------------- Source/Core/DiscIO/NANDImporter.h | 9 ++------ Source/Core/DolphinWX/FrameTools.cpp | 6 +---- 3 files changed, 13 insertions(+), 35 deletions(-) diff --git a/Source/Core/DiscIO/NANDImporter.cpp b/Source/Core/DiscIO/NANDImporter.cpp index 7b523dbca9..512d3f6264 100644 --- a/Source/Core/DiscIO/NANDImporter.cpp +++ b/Source/Core/DiscIO/NANDImporter.cpp @@ -23,7 +23,7 @@ NANDImporter::NANDImporter() = default; NANDImporter::~NANDImporter() = default; void NANDImporter::ImportNANDBin(const std::string& path_to_bin, - std::function update_callback) + std::function update_callback) { m_update_callback = std::move(update_callback); @@ -32,7 +32,6 @@ void NANDImporter::ImportNANDBin(const std::string& path_to_bin, const std::string nand_root = File::GetUserPath(D_WIIROOT_IDX); FindSuperblock(); - CountEntries(0); ProcessEntry(0, nand_root); ExportKeys(nand_root); ExtractCertificates(nand_root); @@ -62,6 +61,11 @@ bool NANDImporter::ReadNANDBin(const std::string& path_to_bin) for (size_t i = 0; i < NAND_TOTAL_BLOCKS; i++) { + // Instead of updating on every cycle, we only update every 1000 cycles for a balance between + // not updating fast enough vs updating too fast + if (i % 1000 == 0) + m_update_callback(); + file.ReadBytes(&m_nand[i * NAND_BLOCK_SIZE], NAND_BLOCK_SIZE); file.Seek(NAND_ECC_BLOCK_SIZE, SEEK_CUR); // We don't care about the ECC blocks } @@ -113,7 +117,6 @@ void NANDImporter::ProcessEntry(u16 entry_number, const std::string& parent_path NANDFSTEntry entry; memcpy(&entry, &m_nand[m_nand_fst_offset + sizeof(NANDFSTEntry) * Common::swap16(entry_number)], sizeof(NANDFSTEntry)); - UpdateStatus(); if (entry.sib != 0xffff) ProcessEntry(entry.sib, parent_path); @@ -126,6 +129,8 @@ void NANDImporter::ProcessEntry(u16 entry_number, const std::string& parent_path void NANDImporter::ProcessDirectory(const NANDFSTEntry& entry, const std::string& parent_path) { + m_update_callback(); + const std::string path = GetPath(entry, parent_path); File::CreateDir(path); @@ -138,6 +143,8 @@ void NANDImporter::ProcessFile(const NANDFSTEntry& entry, const std::string& par constexpr size_t NAND_AES_KEY_OFFSET = 0x158; constexpr size_t NAND_FAT_BLOCK_SIZE = 0x4000; + m_update_callback(); + const std::string path = GetPath(entry, parent_path); File::IOFile file(path, "wb"); std::array key{}; @@ -201,24 +208,4 @@ void NANDImporter::ExportKeys(const std::string& nand_root) if (!file.WriteBytes(m_nand_keys.data(), NAND_KEYS_SIZE)) PanicAlertT("Unable to write to file %s", file_path.c_str()); } - -void NANDImporter::CountEntries(u16 entry_number) -{ - NANDFSTEntry entry; - memcpy(&entry, &m_nand[m_nand_fst_offset + sizeof(NANDFSTEntry) * Common::swap16(entry_number)], - sizeof(NANDFSTEntry)); - - m_total_entries++; - - if (entry.sib != 0xffff) - CountEntries(entry.sib); - - if ((entry.mode & 3) == 2 && entry.sub != 0xffff) - CountEntries(entry.sub); -} - -void NANDImporter::UpdateStatus() -{ - m_update_callback(m_current_entry++, m_total_entries); -} } diff --git a/Source/Core/DiscIO/NANDImporter.h b/Source/Core/DiscIO/NANDImporter.h index d79f733284..f46d8ff855 100644 --- a/Source/Core/DiscIO/NANDImporter.h +++ b/Source/Core/DiscIO/NANDImporter.h @@ -18,8 +18,7 @@ public: NANDImporter(); ~NANDImporter(); - void ImportNANDBin(const std::string& path_to_bin, - std::function update_callback); + void ImportNANDBin(const std::string& path_to_bin, std::function update_callback); void ExtractCertificates(const std::string& nand_root); private: @@ -46,15 +45,11 @@ private: void ProcessFile(const NANDFSTEntry& entry, const std::string& parent_path); void ProcessDirectory(const NANDFSTEntry& entry, const std::string& parent_path); void ExportKeys(const std::string& nand_root); - void CountEntries(u16 entry_number); - void UpdateStatus(); std::vector m_nand; std::vector m_nand_keys; size_t m_nand_fat_offset = 0; size_t m_nand_fst_offset = 0; - std::function m_update_callback; - size_t m_total_entries = 0; - size_t m_current_entry = 0; + std::function m_update_callback; }; } diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index c294efefbd..c7682c9fac 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -1279,11 +1279,7 @@ void CFrame::OnImportBootMiiBackup(wxCommandEvent& WXUNUSED(event)) wxProgressDialog dialog(_("Importing NAND backup"), _("Working..."), 100, this, wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_SMOOTH); - DiscIO::NANDImporter().ImportNANDBin(file_name, - [&dialog](size_t current_entry, size_t total_entries) { - dialog.SetRange(total_entries); - dialog.Update(current_entry); - }); + DiscIO::NANDImporter().ImportNANDBin(file_name, [&dialog] { dialog.Pulse(); }); UpdateLoadWiiMenuItem(); } From 3229cde292a7d38e52e45208cc1c2fdf76c288b4 Mon Sep 17 00:00:00 2001 From: Starsam80 Date: Sun, 14 May 2017 18:47:02 -0600 Subject: [PATCH 2/2] NANDImporter: Add logging --- Source/Core/DiscIO/NANDImporter.cpp | 22 ++++++++++++++++++++++ Source/Core/DiscIO/NANDImporter.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/Source/Core/DiscIO/NANDImporter.cpp b/Source/Core/DiscIO/NANDImporter.cpp index 512d3f6264..81de768435 100644 --- a/Source/Core/DiscIO/NANDImporter.cpp +++ b/Source/Core/DiscIO/NANDImporter.cpp @@ -10,7 +10,9 @@ #include "Common/Crypto/AES.h" #include "Common/FileUtil.h" +#include "Common/Logging/Log.h" #include "Common/MsgHandler.h" +#include "Common/StringUtil.h" #include "Common/Swap.h" #include "DiscIO/NANDContentLoader.h" @@ -31,6 +33,10 @@ void NANDImporter::ImportNANDBin(const std::string& path_to_bin, return; const std::string nand_root = File::GetUserPath(D_WIIROOT_IDX); + m_nand_root_length = nand_root.length(); + if (nand_root.back() == '/') + m_nand_root_length++; + FindSuperblock(); ProcessEntry(0, nand_root); ExportKeys(nand_root); @@ -87,6 +93,7 @@ void NANDImporter::FindSuperblock() if (!memcmp(m_nand.data() + pos, "SFFS", 4)) { u32 version = Common::swap32(&m_nand[pos + 4]); + INFO_LOG(DISCIO, "Found superblock at 0x%x with version 0x%x", pos, version); if (superblock == 0 || version > newest_version) { superblock = pos; @@ -97,6 +104,8 @@ void NANDImporter::FindSuperblock() m_nand_fat_offset = superblock + 0xC; m_nand_fst_offset = m_nand_fat_offset + 0x10000; + INFO_LOG(DISCIO, "Using superblock version 0x%x at position 0x%x. FAT/FST offset: 0x%x/0x%x", + newest_version, superblock, m_nand_fat_offset, m_nand_fst_offset); } std::string NANDImporter::GetPath(const NANDFSTEntry& entry, const std::string& parent_path) @@ -112,6 +121,13 @@ std::string NANDImporter::GetPath(const NANDFSTEntry& entry, const std::string& return parent_path + '/' + name; } +std::string NANDImporter::FormatDebugString(const NANDFSTEntry& entry) +{ + return StringFromFormat("%12.12s 0x%02x 0x%02x 0x%04x 0x%04x 0x%08x 0x%04x 0x%04x 0x%04x 0x%08x", + entry.name, entry.mode, entry.attr, entry.sub, entry.sib, entry.size, + entry.x1, entry.uid, entry.gid, entry.x3); +} + void NANDImporter::ProcessEntry(u16 entry_number, const std::string& parent_path) { NANDFSTEntry entry; @@ -125,17 +141,22 @@ void NANDImporter::ProcessEntry(u16 entry_number, const std::string& parent_path ProcessFile(entry, parent_path); else if ((entry.mode & 3) == 2) ProcessDirectory(entry, parent_path); + else + ERROR_LOG(DISCIO, "Unknown mode: %s", FormatDebugString(entry).c_str()); } void NANDImporter::ProcessDirectory(const NANDFSTEntry& entry, const std::string& parent_path) { m_update_callback(); + INFO_LOG(DISCIO, "Path: %s", FormatDebugString(entry).c_str()); const std::string path = GetPath(entry, parent_path); File::CreateDir(path); if (entry.sub != 0xffff) ProcessEntry(entry.sub, path); + + INFO_LOG(DISCIO, "Path: %s", parent_path.c_str() + m_nand_root_length); } void NANDImporter::ProcessFile(const NANDFSTEntry& entry, const std::string& parent_path) @@ -144,6 +165,7 @@ void NANDImporter::ProcessFile(const NANDFSTEntry& entry, const std::string& par constexpr size_t NAND_FAT_BLOCK_SIZE = 0x4000; m_update_callback(); + INFO_LOG(DISCIO, "File: %s", FormatDebugString(entry).c_str()); const std::string path = GetPath(entry, parent_path); File::IOFile file(path, "wb"); diff --git a/Source/Core/DiscIO/NANDImporter.h b/Source/Core/DiscIO/NANDImporter.h index f46d8ff855..f079c2e82d 100644 --- a/Source/Core/DiscIO/NANDImporter.h +++ b/Source/Core/DiscIO/NANDImporter.h @@ -41,6 +41,7 @@ private: bool ReadNANDBin(const std::string& path_to_bin); void FindSuperblock(); std::string GetPath(const NANDFSTEntry& entry, const std::string& parent_path); + std::string FormatDebugString(const NANDFSTEntry& entry); void ProcessEntry(u16 entry_number, const std::string& parent_path); void ProcessFile(const NANDFSTEntry& entry, const std::string& parent_path); void ProcessDirectory(const NANDFSTEntry& entry, const std::string& parent_path); @@ -51,5 +52,6 @@ private: size_t m_nand_fat_offset = 0; size_t m_nand_fst_offset = 0; std::function m_update_callback; + size_t m_nand_root_length = 0; }; }