Fix system files setup for region changed consoles
Some checks are pending
citra-build / macos-universal (push) Blocked by required conditions
citra-build / source (push) Waiting to run
citra-build / linux (appimage) (push) Waiting to run
citra-build / linux (fresh) (push) Waiting to run
citra-build / macos (arm64) (push) Waiting to run
citra-build / macos (x86_64) (push) Waiting to run
citra-build / windows (msvc) (push) Waiting to run
citra-build / windows (msys2) (push) Waiting to run
citra-build / android (push) Waiting to run
citra-build / ios (push) Waiting to run
citra-format / clang-format (push) Waiting to run
citra-transifex / transifex (push) Waiting to run

This commit is contained in:
PabloMK7 2025-04-13 19:31:40 +02:00 committed by OpenSauce
parent 8acc5e22a0
commit 52ccaabca8
5 changed files with 92 additions and 40 deletions

View file

@ -662,29 +662,27 @@ void ConfigureSystem::RefreshSecureDataStatus() {
auto status_to_str = [](HW::UniqueData::SecureDataLoadStatus status) {
switch (status) {
case HW::UniqueData::SecureDataLoadStatus::Loaded:
return "Loaded";
return tr("Status: Loaded");
case HW::UniqueData::SecureDataLoadStatus::InvalidSignature:
return "Loaded (Invalid Signature)";
return tr("Status: Loaded (Invalid Signature)");
case HW::UniqueData::SecureDataLoadStatus::RegionChanged:
return tr("Status: Loaded (Region Changed)");
case HW::UniqueData::SecureDataLoadStatus::NotFound:
return "Not Found";
return tr("Status: Not Found");
case HW::UniqueData::SecureDataLoadStatus::Invalid:
return "Invalid";
return tr("Status: Invalid");
case HW::UniqueData::SecureDataLoadStatus::IOError:
return "IO Error";
return tr("Status: IO Error");
default:
return "";
return QString();
}
};
ui->label_secure_info_status->setText(
tr((std::string("Status: ") + status_to_str(HW::UniqueData::LoadSecureInfoA())).c_str()));
ui->label_secure_info_status->setText(status_to_str(HW::UniqueData::LoadSecureInfoA()));
ui->label_friend_code_seed_status->setText(
tr((std::string("Status: ") + status_to_str(HW::UniqueData::LoadLocalFriendCodeSeedB()))
.c_str()));
ui->label_otp_status->setText(
tr((std::string("Status: ") + status_to_str(HW::UniqueData::LoadOTP())).c_str()));
ui->label_movable_status->setText(
tr((std::string("Status: ") + status_to_str(HW::UniqueData::LoadMovable())).c_str()));
status_to_str(HW::UniqueData::LoadLocalFriendCodeSeedB()));
ui->label_otp_status->setText(status_to_str(HW::UniqueData::LoadOTP()));
ui->label_movable_status->setText(status_to_str(HW::UniqueData::LoadMovable()));
if (HW::UniqueData::IsFullConsoleLinked()) {
ui->linked_console->setVisible(true);

View file

@ -18,6 +18,7 @@ namespace HW::UniqueData {
static SecureInfoA secure_info_a;
static bool secure_info_a_signature_valid = false;
static bool secure_info_a_region_changed = false;
static LocalFriendCodeSeedB local_friend_code_seed_b;
static bool local_friend_code_seed_b_signature_valid = false;
static FileSys::OTP otp;
@ -41,8 +42,10 @@ bool MovableSed::VerifySignature() const {
SecureDataLoadStatus LoadSecureInfoA() {
if (secure_info_a.IsValid()) {
return secure_info_a_signature_valid ? SecureDataLoadStatus::Loaded
: SecureDataLoadStatus::InvalidSignature;
return secure_info_a_signature_valid
? SecureDataLoadStatus::Loaded
: (secure_info_a_region_changed ? SecureDataLoadStatus::RegionChanged
: SecureDataLoadStatus::InvalidSignature);
}
std::string file_path = GetSecureInfoAPath();
if (!FileUtil::Exists(file_path)) {
@ -61,13 +64,31 @@ SecureDataLoadStatus LoadSecureInfoA() {
}
HW::AES::InitKeys();
secure_info_a_region_changed = false;
secure_info_a_signature_valid = secure_info_a.VerifySignature();
if (!secure_info_a_signature_valid) {
// Check if the file has been region changed
SecureInfoA copy = secure_info_a;
for (u8 orig_reg = 0; orig_reg < Region::COUNT; orig_reg++) {
if (orig_reg == secure_info_a.body.region) {
continue;
}
copy.body.region = orig_reg;
if (copy.VerifySignature()) {
secure_info_a_region_changed = true;
LOG_WARNING(HW, "SecureInfo_A is region changed and its signature invalid");
break;
}
}
if (!secure_info_a_region_changed) {
LOG_WARNING(HW, "SecureInfo_A signature check failed");
}
}
return secure_info_a_signature_valid ? SecureDataLoadStatus::Loaded
: SecureDataLoadStatus::InvalidSignature;
return secure_info_a_signature_valid
? SecureDataLoadStatus::Loaded
: (secure_info_a_region_changed ? SecureDataLoadStatus::RegionChanged
: SecureDataLoadStatus::InvalidSignature);
}
SecureDataLoadStatus LoadLocalFriendCodeSeedB() {

View file

@ -17,6 +17,19 @@ class OTP;
namespace HW::UniqueData {
struct Region {
enum : u8 {
JPN,
USA,
EUR,
AUS,
CHN,
KOR,
TWN,
};
static constexpr u8 COUNT = TWN + 1;
};
struct SecureInfoA {
std::array<u8, 0x100> signature;
struct {
@ -122,6 +135,7 @@ static_assert(sizeof(MovableSedFull) == 0x140);
enum class SecureDataLoadStatus {
Loaded = 0,
InvalidSignature = 1,
RegionChanged = 2,
NotFound = -1,
Invalid = -2,

View file

@ -93,7 +93,7 @@ public:
}
private:
static constexpr u32 SETUP_TOOL_VERSION = 1;
static constexpr u32 SETUP_TOOL_VERSION = 2;
/**
* Loads .code section into memory for booting
* @param process The newly created process

View file

@ -5,6 +5,7 @@
#include <vector>
#include "core/hle/service/am/am.h"
#include "core/hle/service/fs/archive.h"
#include "core/hw/unique_data.h"
#include "core/system_titles.h"
namespace Core {
@ -193,22 +194,22 @@ static const std::array<SystemTitleCategory, NUM_SYSTEM_TITLE_CATEGORIES>
.name = "NNID Web Browser Data",
.sets = SystemTitleSet::Old3ds | SystemTitleSet::New3ds |
SystemTitleSet::Minimal,
.title_id_lows = {0x00018002, 0x00018002, 0x00018002, 0x00018002,
0x00018002, 0x00018002, 0x00018002},
.title_id_lows = {0x00018002, 0x00018002, 0x00018002, 0x00018002, 0,
0, 0},
},
{
.name = "Miiverse Offline Mode Web Browser Data",
.sets = SystemTitleSet::Old3ds | SystemTitleSet::New3ds |
SystemTitleSet::Minimal,
.title_id_lows = {0x00018102, 0x00018102, 0x00018102, 0x00018102,
0x00018102, 0x00018102, 0x00018102},
.title_id_lows = {0x00018102, 0x00018102, 0x00018102, 0x00018102, 0,
0, 0},
},
{
.name = "NNID/Miiverse OSS CROs",
.sets = SystemTitleSet::Old3ds | SystemTitleSet::New3ds |
SystemTitleSet::Minimal,
.title_id_lows = {0x00018202, 0x00018202, 0x00018202, 0x00018202,
0x00018202, 0x00018202, 0x00018202},
.title_id_lows = {0x00018202, 0x00018202, 0x00018202, 0x00018202, 0,
0, 0},
},
{
.name = "NFC Peripheral Firmware",
@ -258,8 +259,8 @@ static const std::array<SystemTitleCategory, NUM_SYSTEM_TITLE_CATEGORIES>
{
.name = "Error Display (Safe Mode, O3DS)",
.sets = SystemTitleSet::Old3ds,
.title_id_lows = {0x00008A03, 0x00008A03, 0x00008A03, 0x00008A03,
0x00008A03, 0x00008A03, 0x00008A03},
.title_id_lows = {0x00008A03, 0x00008A03, 0x00008A03, 0x00008A03, 0,
0, 0},
},
{
.name = "Error Display (Safe Mode, N3DS)",
@ -483,8 +484,8 @@ static const std::array<SystemTitleCategory, NUM_SYSTEM_TITLE_CATEGORIES>
.name = "EULA",
.sets = SystemTitleSet::Old3ds | SystemTitleSet::New3ds |
SystemTitleSet::Minimal,
.title_id_lows = {0x00013202, 0x00013302, 0x00013102, 0x00013102,
0x00013502, 0, 0},
.title_id_lows = {0x00013202, 0x00013302, 0x00013102, 0x00013102, 0,
0, 0},
},
{
.name = "JPN/EUR/USA System Font",
@ -904,8 +905,8 @@ static const std::array<SystemTitleCategory, NUM_SYSTEM_TITLE_CATEGORIES>
{
.name = "NIM Module (Safe Mode, O3DS)",
.sets = SystemTitleSet::Old3ds,
.title_id_lows = {0x00002C03, 0x00002C03, 0x00002C03, 0x00002C03,
0x00002C03, 0x00002C03, 0x00002C03},
.title_id_lows = {0x00002C03, 0x00002C03, 0x00002C03, 0x00002C03, 0,
0, 0},
},
{
.name = "NIM Module (Safe Mode, N3DS)",
@ -1067,8 +1068,8 @@ static const std::array<SystemTitleCategory, NUM_SYSTEM_TITLE_CATEGORIES>
{
.name = "NS Module (Safe Mode, O3DS)",
.sets = SystemTitleSet::Old3ds,
.title_id_lows = {0x00008003, 0x00008003, 0x00008003, 0x00008003,
0x00008003, 0x00008003, 0x00008003},
.title_id_lows = {0x00008003, 0x00008003, 0x00008003, 0x00008003, 0,
0, 0},
},
{
.name = "NS Module (Safe Mode, N3DS)",
@ -1120,8 +1121,8 @@ static const std::array<SystemTitleCategory, NUM_SYSTEM_TITLE_CATEGORIES>
{
.name = "AGB_FIRM (O3DS)",
.sets = SystemTitleSet::Old3ds,
.title_id_lows = {0x00000202, 0x00000202, 0x00000202, 0x00000202,
0x00000202, 0x00000202, 0x00000202},
.title_id_lows = {0x00000202, 0x00000202, 0x00000202, 0x00000202, 0,
0x00000202, 0},
},
{
.name = "AGB_FIRM (N3DS)",
@ -1215,6 +1216,10 @@ std::pair<bool, bool> AreSystemTitlesInstalled() {
std::array<u32, NUM_SYSTEM_TITLE_REGIONS> n_installed_titles{};
std::array<u32, NUM_SYSTEM_TITLE_REGIONS> n_total_titles{};
static const char* region_names[NUM_SYSTEM_TITLE_REGIONS] = {
"JPN", "USA", "EUR", "AUS", "CHN", "KOR", "TWN",
};
for (auto categ = system_titles.begin(); categ != system_titles.end(); categ++) {
for (auto title = categ->titles.begin(); title != categ->titles.end(); title++) {
@ -1241,6 +1246,14 @@ std::pair<bool, bool> AreSystemTitlesInstalled() {
if (title->sets & SystemTitleSet::New3ds) {
n_installed_titles[i]++;
}
} else {
std::string set = (title->sets & SystemTitleSet::Old3ds) ? "O3DS" : "";
if (title->sets & SystemTitleSet::New3ds) {
set += set.empty() ? "N3DS" : "/N3DS";
}
LOG_DEBUG(Service_AM, "{}, {}, {}, {} not found", categ->name, title->name,
region_names[i], set);
}
}
}
@ -1252,15 +1265,21 @@ std::pair<bool, bool> AreSystemTitlesInstalled() {
for (size_t i = 0; i < o_installed_titles.size(); i++) {
if (o_installed_titles[i] == o_total_titles[i]) {
o_all = true;
// CHN/TWN don't have n3ds variants
if (i == HW::UniqueData::Region::CHN || i == HW::UniqueData::Region::TWN) {
n_all = true;
}
break;
}
}
if (!n_all) {
for (size_t i = 0; i < n_installed_titles.size(); i++) {
if (n_installed_titles[i] == n_total_titles[i]) {
n_all = true;
break;
}
}
}
return std::make_pair(o_all, n_all);
}