Merge pull request #6144 from leoetlino/nand-import-fix
NANDImporter: Add support for dumps that don't include keys
This commit is contained in:
commit
201ce4b600
|
@ -27,11 +27,12 @@ NANDImporter::NANDImporter() = default;
|
||||||
NANDImporter::~NANDImporter() = default;
|
NANDImporter::~NANDImporter() = default;
|
||||||
|
|
||||||
void NANDImporter::ImportNANDBin(const std::string& path_to_bin,
|
void NANDImporter::ImportNANDBin(const std::string& path_to_bin,
|
||||||
std::function<void()> update_callback)
|
std::function<void()> update_callback,
|
||||||
|
std::function<std::string()> get_otp_dump_path)
|
||||||
{
|
{
|
||||||
m_update_callback = std::move(update_callback);
|
m_update_callback = std::move(update_callback);
|
||||||
|
|
||||||
if (!ReadNANDBin(path_to_bin))
|
if (!ReadNANDBin(path_to_bin, get_otp_dump_path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::string nand_root = File::GetUserPath(D_WIIROOT_IDX);
|
const std::string nand_root = File::GetUserPath(D_WIIROOT_IDX);
|
||||||
|
@ -45,20 +46,20 @@ void NANDImporter::ImportNANDBin(const std::string& path_to_bin,
|
||||||
ExtractCertificates(nand_root);
|
ExtractCertificates(nand_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NANDImporter::ReadNANDBin(const std::string& path_to_bin)
|
bool NANDImporter::ReadNANDBin(const std::string& path_to_bin,
|
||||||
|
std::function<std::string()> get_otp_dump_path)
|
||||||
{
|
{
|
||||||
constexpr size_t NAND_TOTAL_BLOCKS = 0x40000;
|
constexpr size_t NAND_TOTAL_BLOCKS = 0x40000;
|
||||||
constexpr size_t NAND_BLOCK_SIZE = 0x800;
|
constexpr size_t NAND_BLOCK_SIZE = 0x800;
|
||||||
constexpr size_t NAND_ECC_BLOCK_SIZE = 0x40;
|
constexpr size_t NAND_ECC_BLOCK_SIZE = 0x40;
|
||||||
constexpr size_t NAND_BIN_SIZE =
|
constexpr size_t NAND_BIN_SIZE =
|
||||||
(NAND_BLOCK_SIZE + NAND_ECC_BLOCK_SIZE) * NAND_TOTAL_BLOCKS + NAND_KEYS_SIZE; // 0x21000400
|
(NAND_BLOCK_SIZE + NAND_ECC_BLOCK_SIZE) * NAND_TOTAL_BLOCKS; // 0x21000000
|
||||||
|
|
||||||
File::IOFile file(path_to_bin, "rb");
|
File::IOFile file(path_to_bin, "rb");
|
||||||
if (file.GetSize() != NAND_BIN_SIZE)
|
const u64 image_size = file.GetSize();
|
||||||
|
if (image_size != NAND_BIN_SIZE + NAND_KEYS_SIZE && image_size != NAND_BIN_SIZE)
|
||||||
{
|
{
|
||||||
PanicAlertT("This file does not look like a BootMii NAND backup. (0x%" PRIx64
|
PanicAlertT("This file does not look like a BootMii NAND backup.");
|
||||||
" does not equal 0x%zx)",
|
|
||||||
file.GetSize(), NAND_BIN_SIZE);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +77,20 @@ bool NANDImporter::ReadNANDBin(const std::string& path_to_bin)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nand_keys.resize(NAND_KEYS_SIZE);
|
m_nand_keys.resize(NAND_KEYS_SIZE);
|
||||||
file.ReadBytes(m_nand_keys.data(), NAND_KEYS_SIZE);
|
|
||||||
return true;
|
// Read the OTP/SEEPROM dump.
|
||||||
|
// If it is not included in the NAND image, get a path to the dump and read key data from it.
|
||||||
|
if (image_size == NAND_BIN_SIZE)
|
||||||
|
{
|
||||||
|
const std::string otp_dump_path = get_otp_dump_path();
|
||||||
|
if (otp_dump_path.empty())
|
||||||
|
return false;
|
||||||
|
File::IOFile keys_file{otp_dump_path, "rb"};
|
||||||
|
return keys_file.ReadBytes(m_nand_keys.data(), NAND_KEYS_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, just read the key data from the NAND image.
|
||||||
|
return file.ReadBytes(m_nand_keys.data(), NAND_KEYS_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NANDImporter::FindSuperblock()
|
void NANDImporter::FindSuperblock()
|
||||||
|
|
|
@ -18,7 +18,11 @@ public:
|
||||||
NANDImporter();
|
NANDImporter();
|
||||||
~NANDImporter();
|
~NANDImporter();
|
||||||
|
|
||||||
void ImportNANDBin(const std::string& path_to_bin, std::function<void()> update_callback);
|
// Extract a NAND image to the configured NAND root.
|
||||||
|
// If the associated OTP/SEEPROM dump (keys.bin) is not included in the image,
|
||||||
|
// get_otp_dump_path will be called to get a path to it.
|
||||||
|
void ImportNANDBin(const std::string& path_to_bin, std::function<void()> update_callback,
|
||||||
|
std::function<std::string()> get_otp_dump_path);
|
||||||
bool ExtractCertificates(const std::string& nand_root);
|
bool ExtractCertificates(const std::string& nand_root);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -38,7 +42,7 @@ private:
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
bool ReadNANDBin(const std::string& path_to_bin);
|
bool ReadNANDBin(const std::string& path_to_bin, std::function<std::string()> get_otp_dump_path);
|
||||||
void FindSuperblock();
|
void FindSuperblock();
|
||||||
std::string GetPath(const NANDFSTEntry& entry, const std::string& parent_path);
|
std::string GetPath(const NANDFSTEntry& entry, const std::string& parent_path);
|
||||||
std::string FormatDebugString(const NANDFSTEntry& entry);
|
std::string FormatDebugString(const NANDFSTEntry& entry);
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "DolphinQt2/NetPlay/NetPlayDialog.h"
|
#include "DolphinQt2/NetPlay/NetPlayDialog.h"
|
||||||
#include "DolphinQt2/NetPlay/NetPlaySetupDialog.h"
|
#include "DolphinQt2/NetPlay/NetPlaySetupDialog.h"
|
||||||
#include "DolphinQt2/QtUtils/QueueOnObject.h"
|
#include "DolphinQt2/QtUtils/QueueOnObject.h"
|
||||||
|
#include "DolphinQt2/QtUtils/RunOnObject.h"
|
||||||
#include "DolphinQt2/QtUtils/WindowActivationEventFilter.h"
|
#include "DolphinQt2/QtUtils/WindowActivationEventFilter.h"
|
||||||
#include "DolphinQt2/Resources.h"
|
#include "DolphinQt2/Resources.h"
|
||||||
#include "DolphinQt2/Settings.h"
|
#include "DolphinQt2/Settings.h"
|
||||||
|
@ -879,12 +880,23 @@ void MainWindow::OnImportNANDBackup()
|
||||||
auto beginning = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
auto beginning = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||||
|
|
||||||
auto result = std::async(std::launch::async, [&] {
|
auto result = std::async(std::launch::async, [&] {
|
||||||
DiscIO::NANDImporter().ImportNANDBin(file.toStdString(), [&dialog, beginning] {
|
DiscIO::NANDImporter().ImportNANDBin(
|
||||||
|
file.toStdString(),
|
||||||
|
[&dialog, beginning] {
|
||||||
QueueOnObject(dialog, [&dialog, beginning] {
|
QueueOnObject(dialog, [&dialog, beginning] {
|
||||||
dialog->setLabelText(
|
dialog->setLabelText(
|
||||||
tr("Importing NAND backup\n Time elapsed: %1s")
|
tr("Importing NAND backup\n Time elapsed: %1s")
|
||||||
.arg((QDateTime::currentDateTime().toMSecsSinceEpoch() - beginning) / 1000));
|
.arg((QDateTime::currentDateTime().toMSecsSinceEpoch() - beginning) / 1000));
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
[this] {
|
||||||
|
return RunOnObject(this, [this] {
|
||||||
|
return QFileDialog::getOpenFileName(this, tr("Select the OTP/SEEPROM dump"),
|
||||||
|
QDir::currentPath(),
|
||||||
|
tr("BootMii OTP/SEEPROM dump (*.bin);;"
|
||||||
|
"All Files (*)"))
|
||||||
|
.toStdString();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
QueueOnObject(dialog, &QProgressDialog::close);
|
QueueOnObject(dialog, &QProgressDialog::close);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1301,7 +1301,14 @@ void CFrame::OnImportBootMiiBackup(wxCommandEvent& WXUNUSED(event))
|
||||||
|
|
||||||
wxProgressDialog dialog(_("Importing NAND backup"), _("Working..."), 100, this,
|
wxProgressDialog dialog(_("Importing NAND backup"), _("Working..."), 100, this,
|
||||||
wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_SMOOTH);
|
wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_SMOOTH);
|
||||||
DiscIO::NANDImporter().ImportNANDBin(file_name, [&dialog] { dialog.Pulse(); });
|
DiscIO::NANDImporter().ImportNANDBin(
|
||||||
|
file_name, [&dialog] { dialog.Pulse(); },
|
||||||
|
[this] {
|
||||||
|
return WxStrToStr(wxFileSelector(
|
||||||
|
_("Select the OTP/SEEPROM dump"), wxEmptyString, wxEmptyString, wxEmptyString,
|
||||||
|
_("BootMii OTP/SEEPROM dump (*.bin)") + "|*.bin|" + wxGetTranslation(wxALL_FILES),
|
||||||
|
wxFD_OPEN | wxFD_PREVIEW | wxFD_FILE_MUST_EXIST, this));
|
||||||
|
});
|
||||||
wxPostEvent(GetMenuBar(), wxCommandEvent{DOLPHIN_EVT_UPDATE_LOAD_WII_MENU_ITEM});
|
wxPostEvent(GetMenuBar(), wxCommandEvent{DOLPHIN_EVT_UPDATE_LOAD_WII_MENU_ITEM});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue