summaryrefslogtreecommitdiff
path: root/src/yuzu
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu')
-rw-r--r--src/yuzu/main.cpp82
-rw-r--r--src/yuzu/main.h6
-rw-r--r--src/yuzu/main.ui6
3 files changed, 94 insertions, 0 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index e11833c5a..fc186dc2d 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -31,6 +31,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QMessageBox>
+#include <QtConcurrent/QtConcurrent>
#include <QtGui>
#include <QtWidgets>
#include <fmt/format.h>
@@ -171,6 +172,9 @@ GMainWindow::GMainWindow()
.arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));
show();
+ // Gen keys if necessary
+ OnReinitializeKeys(ReinitializeKeyBehavior::NoWarning);
+
// Necessary to load titles from nand in gamelist.
Service::FileSystem::CreateFactories(vfs);
game_list->LoadCompatibilityList();
@@ -443,6 +447,8 @@ void GMainWindow::ConnectMenuEvents() {
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
// Help
+ connect(ui.action_Rederive, &QAction::triggered, this,
+ std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning));
connect(ui.action_About, &QAction::triggered, this, &GMainWindow::OnAbout);
}
@@ -1375,6 +1381,82 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
}
}
+void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
+ if (behavior == ReinitializeKeyBehavior::Warning) {
+ const auto res = QMessageBox::information(
+ this, tr("Confirm Key Rederivation"),
+ tr("You are about to force rederive all of your keys. \nIf you do not know what this "
+ "means or what you are doing, \nthis is a potentially destructive action. \nPlease "
+ "make "
+ "sure this is what you want \nand optionally make backups.\n\nThis will delete your "
+ "autogenerated key files and re-run the key derivation module."),
+ QMessageBox::StandardButtons{QMessageBox::Ok, QMessageBox::Cancel});
+
+ if (res == QMessageBox::Cancel)
+ return;
+
+ FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::KeysDir) +
+ "prod.keys_autogenerated");
+ FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::KeysDir) +
+ "console.keys_autogenerated");
+ FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::KeysDir) +
+ "title.keys_autogenerated");
+ }
+
+ Core::Crypto::KeyManager keys{};
+ if (keys.BaseDeriveNecessary()) {
+ Core::Crypto::PartitionDataManager pdm{vfs->OpenDirectory(
+ FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), FileSys::Mode::Read)};
+
+ const auto function = [this, &keys, &pdm] {
+ keys.PopulateFromPartitionData(pdm);
+ Service::FileSystem::CreateFactories(vfs);
+ keys.DeriveETicket(pdm);
+ };
+
+ QString errors;
+
+ if (!pdm.HasFuses())
+ errors += tr("- Missing fuses - Cannot derive SBK\n");
+ if (!pdm.HasBoot0())
+ errors += tr("- Missing BOOT0 - Cannot derive master keys\n");
+ if (!pdm.HasPackage2())
+ errors += tr("- Missing BCPKG2-1-Normal-Main - Cannot derive general keys\n");
+ if (!pdm.HasProdInfo())
+ errors += tr("- Missing PRODINFO - Cannot derive title keys\n");
+
+ if (!errors.isEmpty()) {
+
+ QMessageBox::warning(
+ this, tr("Warning Missing Derivation Components"),
+ tr("The following are missing from your configuration that may hinder key "
+ "derivation. It will be attempted but may not complete.\n\n") +
+ errors);
+ }
+
+ QProgressDialog prog;
+ prog.setRange(0, 0);
+ prog.setLabelText(tr("Deriving keys...\nThis may take up to a minute depending \non your "
+ "system's performance."));
+ prog.setWindowTitle(tr("Deriving Keys"));
+
+ prog.show();
+
+ auto future = QtConcurrent::run(function);
+ while (!future.isFinished()) {
+ QCoreApplication::processEvents();
+ }
+
+ prog.close();
+ }
+
+ Service::FileSystem::CreateFactories(vfs);
+
+ if (behavior == ReinitializeKeyBehavior::Warning) {
+ game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
+ }
+}
+
bool GMainWindow::ConfirmClose() {
if (emu_thread == nullptr || !UISettings::values.confirm_before_closing)
return true;
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index fe0e9a50a..3663d6aed 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -41,6 +41,11 @@ enum class EmulatedDirectoryTarget {
SDMC,
};
+enum class ReinitializeKeyBehavior {
+ NoWarning,
+ Warning,
+};
+
namespace DiscordRPC {
class DiscordInterface;
}
@@ -167,6 +172,7 @@ private slots:
void HideFullscreen();
void ToggleWindowMode();
void OnCoreError(Core::System::ResultStatus, std::string);
+ void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
private:
void UpdateStatusBar();
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui
index cb1664b21..9851f507d 100644
--- a/src/yuzu/main.ui
+++ b/src/yuzu/main.ui
@@ -103,6 +103,7 @@
</property>
<addaction name="action_Report_Compatibility"/>
<addaction name="separator"/>
+ <addaction name="action_Rederive"/>
<addaction name="action_About"/>
</widget>
<addaction name="menu_File"/>
@@ -159,6 +160,11 @@
<string>&amp;Stop</string>
</property>
</action>
+ <action name="action_Rederive">
+ <property name="text">
+ <string>Reinitialize keys...</string>
+ </property>
+ </action>
<action name="action_About">
<property name="text">
<string>About yuzu</string>