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;
|
||||
|
||||
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);
|
||||
|
||||
if (!ReadNANDBin(path_to_bin))
|
||||
if (!ReadNANDBin(path_to_bin, get_otp_dump_path))
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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_BLOCK_SIZE = 0x800;
|
||||
constexpr size_t NAND_ECC_BLOCK_SIZE = 0x40;
|
||||
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");
|
||||
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
|
||||
" does not equal 0x%zx)",
|
||||
file.GetSize(), NAND_BIN_SIZE);
|
||||
PanicAlertT("This file does not look like a BootMii NAND backup.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -76,8 +77,20 @@ bool NANDImporter::ReadNANDBin(const std::string& path_to_bin)
|
|||
}
|
||||
|
||||
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()
|
||||
|
|
|
@ -18,7 +18,11 @@ public:
|
|||
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);
|
||||
|
||||
private:
|
||||
|
@ -38,7 +42,7 @@ private:
|
|||
};
|
||||
#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();
|
||||
std::string GetPath(const NANDFSTEntry& entry, const std::string& parent_path);
|
||||
std::string FormatDebugString(const NANDFSTEntry& entry);
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "DolphinQt2/NetPlay/NetPlayDialog.h"
|
||||
#include "DolphinQt2/NetPlay/NetPlaySetupDialog.h"
|
||||
#include "DolphinQt2/QtUtils/QueueOnObject.h"
|
||||
#include "DolphinQt2/QtUtils/RunOnObject.h"
|
||||
#include "DolphinQt2/QtUtils/WindowActivationEventFilter.h"
|
||||
#include "DolphinQt2/Resources.h"
|
||||
#include "DolphinQt2/Settings.h"
|
||||
|
@ -879,13 +880,24 @@ void MainWindow::OnImportNANDBackup()
|
|||
auto beginning = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||
|
||||
auto result = std::async(std::launch::async, [&] {
|
||||
DiscIO::NANDImporter().ImportNANDBin(file.toStdString(), [&dialog, beginning] {
|
||||
QueueOnObject(dialog, [&dialog, beginning] {
|
||||
dialog->setLabelText(
|
||||
tr("Importing NAND backup\n Time elapsed: %1s")
|
||||
.arg((QDateTime::currentDateTime().toMSecsSinceEpoch() - beginning) / 1000));
|
||||
});
|
||||
});
|
||||
DiscIO::NANDImporter().ImportNANDBin(
|
||||
file.toStdString(),
|
||||
[&dialog, beginning] {
|
||||
QueueOnObject(dialog, [&dialog, beginning] {
|
||||
dialog->setLabelText(
|
||||
tr("Importing NAND backup\n Time elapsed: %1s")
|
||||
.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);
|
||||
});
|
||||
|
||||
|
|
|
@ -1301,7 +1301,14 @@ 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] { 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});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue