mirror of
https://github.com/citra-emu/citra-canary.git
synced 2024-12-23 04:25:39 +00:00
Implement cfg UUID Clock Sequence (#7169)
* Implement cfg UUID Clock Sequence * Remove unneeded variable. * Apply suggestions * Apply suggestions
This commit is contained in:
parent
52254537b7
commit
f8ae41dfe3
|
@ -220,6 +220,24 @@ void Module::Interface::SecureInfoGetByte101(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push<u8>(0);
|
rb.Push<u8>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Module::Interface::SetUUIDClockSequence(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp(ctx);
|
||||||
|
|
||||||
|
cfg->mcu_data.clock_sequence = rp.Pop<u16>();
|
||||||
|
cfg->SaveMCUConfig();
|
||||||
|
|
||||||
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::Interface::GetUUIDClockSequence(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp(ctx);
|
||||||
|
|
||||||
|
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.Push<u16>(static_cast<u16>(cfg->mcu_data.clock_sequence));
|
||||||
|
}
|
||||||
|
|
||||||
void Module::Interface::GetTransferableId(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::GetTransferableId(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx);
|
IPC::RequestParser rp(ctx);
|
||||||
const u32 app_id_salt = rp.Pop<u32>() & 0x000FFFFF;
|
const u32 app_id_salt = rp.Pop<u32>() & 0x000FFFFF;
|
||||||
|
@ -557,8 +575,33 @@ ResultCode Module::LoadConfigNANDSaveFile() {
|
||||||
return FormatConfig();
|
return FormatConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Module::LoadMCUConfig() {
|
||||||
|
FileUtil::IOFile mcu_data_file(
|
||||||
|
fmt::format("{}/mcu.dat", FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir)), "r");
|
||||||
|
|
||||||
|
if (mcu_data_file.IsOpen() && mcu_data_file.GetSize() >= sizeof(MCUData) &&
|
||||||
|
mcu_data_file.ReadBytes(&mcu_data, sizeof(MCUData)) == sizeof(MCUData)) {
|
||||||
|
if (mcu_data.IsValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mcu_data_file.Close();
|
||||||
|
mcu_data = MCUData();
|
||||||
|
SaveMCUConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::SaveMCUConfig() {
|
||||||
|
FileUtil::IOFile mcu_data_file(
|
||||||
|
fmt::format("{}/mcu.dat", FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir)), "w");
|
||||||
|
|
||||||
|
if (mcu_data_file.IsOpen()) {
|
||||||
|
mcu_data_file.WriteBytes(&mcu_data, sizeof(MCUData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Module::Module() {
|
Module::Module() {
|
||||||
LoadConfigNANDSaveFile();
|
LoadConfigNANDSaveFile();
|
||||||
|
LoadMCUConfig();
|
||||||
// Check the config savegame EULA Version and update it to 0x7F7F if necessary
|
// Check the config savegame EULA Version and update it to 0x7F7F if necessary
|
||||||
// so users will never get a prompt to accept EULA
|
// so users will never get a prompt to accept EULA
|
||||||
auto version = GetEULAVersion();
|
auto version = GetEULAVersion();
|
||||||
|
|
|
@ -82,7 +82,7 @@ enum ConfigBlockID {
|
||||||
DebugModeBlockID = 0x00130000,
|
DebugModeBlockID = 0x00130000,
|
||||||
ClockSequenceBlockID = 0x00150000,
|
ClockSequenceBlockID = 0x00150000,
|
||||||
Unknown_0x00150001 = 0x00150001,
|
Unknown_0x00150001 = 0x00150001,
|
||||||
NpnsUrlID = 0x00150002, // Maybe? 3dbrew documentation is weirdly written.
|
ServerType = 0x00150002,
|
||||||
Unknown_0x00160000 = 0x00160000,
|
Unknown_0x00160000 = 0x00160000,
|
||||||
MiiverseAccessKeyBlockID = 0x00170000,
|
MiiverseAccessKeyBlockID = 0x00170000,
|
||||||
QtmInfraredLedRelatedBlockID = 0x00180000,
|
QtmInfraredLedRelatedBlockID = 0x00180000,
|
||||||
|
@ -230,6 +230,27 @@ public:
|
||||||
*/
|
*/
|
||||||
void SecureInfoGetByte101(Kernel::HLERequestContext& ctx);
|
void SecureInfoGetByte101(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CFG::SetUUIDClockSequence service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : UUID Clock Sequence
|
||||||
|
* Outputs:
|
||||||
|
* 0 : Result Header code
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
*/
|
||||||
|
void SetUUIDClockSequence(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CFG::GetUUIDClockSequence service function
|
||||||
|
* Inputs:
|
||||||
|
* 1 : None
|
||||||
|
* Outputs:
|
||||||
|
* 0 : Result Header code
|
||||||
|
* 1 : Result of function, 0 on success, otherwise error code
|
||||||
|
* 2 : UUID Clock Sequence
|
||||||
|
*/
|
||||||
|
void GetUUIDClockSequence(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CFG::GetTransferableId service function
|
* CFG::GetTransferableId service function
|
||||||
* Inputs:
|
* Inputs:
|
||||||
|
@ -338,6 +359,25 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Represents save data that would normally be stored in the MCU
|
||||||
|
// on real hardware. Try to keep this struct backwards compatible
|
||||||
|
// if a new version is needed to prevent data loss.
|
||||||
|
struct MCUData {
|
||||||
|
struct Header {
|
||||||
|
static constexpr u32 MAGIC_VALUE = 0x4455434D;
|
||||||
|
static constexpr u32 VERSION_VALUE = 1;
|
||||||
|
u32 magic = MAGIC_VALUE;
|
||||||
|
u32 version = VERSION_VALUE;
|
||||||
|
u64 reserved = 0;
|
||||||
|
};
|
||||||
|
Header header;
|
||||||
|
u32 clock_sequence = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsValid() const {
|
||||||
|
return header.magic == Header::MAGIC_VALUE && header.version == Header::VERSION_VALUE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ResultVal<void*> GetConfigBlockPointer(u32 block_id, u32 size, AccessFlag accesss_flag);
|
ResultVal<void*> GetConfigBlockPointer(u32 block_id, u32 size, AccessFlag accesss_flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -397,6 +437,11 @@ private:
|
||||||
*/
|
*/
|
||||||
ResultCode LoadConfigNANDSaveFile();
|
ResultCode LoadConfigNANDSaveFile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads MCU specific data
|
||||||
|
*/
|
||||||
|
void LoadMCUConfig();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
u32 GetRegionValue();
|
u32 GetRegionValue();
|
||||||
|
|
||||||
|
@ -538,11 +583,17 @@ public:
|
||||||
*/
|
*/
|
||||||
ResultCode UpdateConfigNANDSavegame();
|
ResultCode UpdateConfigNANDSavegame();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves MCU specific data
|
||||||
|
*/
|
||||||
|
void SaveMCUConfig();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr u32 CONFIG_SAVEFILE_SIZE = 0x8000;
|
static constexpr u32 CONFIG_SAVEFILE_SIZE = 0x8000;
|
||||||
std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer;
|
std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer;
|
||||||
std::unique_ptr<FileSys::ArchiveBackend> cfg_system_save_data_archive;
|
std::unique_ptr<FileSys::ArchiveBackend> cfg_system_save_data_archive;
|
||||||
u32 preferred_region_code = 0;
|
u32 preferred_region_code = 0;
|
||||||
|
MCUData mcu_data{};
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int);
|
void serialize(Archive& ar, const unsigned int);
|
||||||
|
|
|
@ -57,6 +57,8 @@ constexpr ConsoleModelInfo DEFAULT_CONSOLE_MODEL{NEW_NINTENDO_3DS_XL, {0, 0, 0}}
|
||||||
constexpr std::array<u8, 0x28> DEFAULT_X_DEVICE_TOKEN = {};
|
constexpr std::array<u8, 0x28> DEFAULT_X_DEVICE_TOKEN = {};
|
||||||
constexpr u32_le DEFAULT_SYSTEM_SETUP_REQUIRED_FLAG = 1;
|
constexpr u32_le DEFAULT_SYSTEM_SETUP_REQUIRED_FLAG = 1;
|
||||||
constexpr u32_le DEFAULT_DEBUG_MODE_FLAG = 0;
|
constexpr u32_le DEFAULT_DEBUG_MODE_FLAG = 0;
|
||||||
|
constexpr u32_le DEFAULT_CLOCK_SEQUENCE = 0;
|
||||||
|
constexpr const char DEFAULT_SERVER_TYPE[4] = {'L', '1', '\0', '\0'};
|
||||||
constexpr u32_le DEFAULT_0x00160000_DATA = 0;
|
constexpr u32_le DEFAULT_0x00160000_DATA = 0;
|
||||||
constexpr u32_le DEFAULT_MIIVERSE_ACCESS_KEY = 0;
|
constexpr u32_le DEFAULT_MIIVERSE_ACCESS_KEY = 0;
|
||||||
|
|
||||||
|
@ -108,6 +110,9 @@ static const std::unordered_map<ConfigBlockID, ConfigBlockDefaults> DEFAULT_CONF
|
||||||
sizeof(DEFAULT_SYSTEM_SETUP_REQUIRED_FLAG)}},
|
sizeof(DEFAULT_SYSTEM_SETUP_REQUIRED_FLAG)}},
|
||||||
{DebugModeBlockID,
|
{DebugModeBlockID,
|
||||||
{AccessFlag::Global, &DEFAULT_DEBUG_MODE_FLAG, sizeof(DEFAULT_DEBUG_MODE_FLAG)}},
|
{AccessFlag::Global, &DEFAULT_DEBUG_MODE_FLAG, sizeof(DEFAULT_DEBUG_MODE_FLAG)}},
|
||||||
|
{ClockSequenceBlockID,
|
||||||
|
{AccessFlag::System, &DEFAULT_CLOCK_SEQUENCE, sizeof(DEFAULT_CLOCK_SEQUENCE)}},
|
||||||
|
{ServerType, {AccessFlag::Global, DEFAULT_SERVER_TYPE, sizeof(DEFAULT_SERVER_TYPE)}},
|
||||||
{Unknown_0x00160000,
|
{Unknown_0x00160000,
|
||||||
{AccessFlag::Global, &DEFAULT_0x00160000_DATA, sizeof(DEFAULT_0x00160000_DATA)}},
|
{AccessFlag::Global, &DEFAULT_0x00160000_DATA, sizeof(DEFAULT_0x00160000_DATA)}},
|
||||||
{MiiverseAccessKeyBlockID,
|
{MiiverseAccessKeyBlockID,
|
||||||
|
|
|
@ -34,6 +34,8 @@ CFG_S::CFG_S(std::shared_ptr<Module> cfg) : Module::Interface(std::move(cfg), "c
|
||||||
{0x0407, &CFG_S::SecureInfoGetByte101, "SecureInfoGetByte101"},
|
{0x0407, &CFG_S::SecureInfoGetByte101, "SecureInfoGetByte101"},
|
||||||
{0x0408, nullptr, "SecureInfoGetSerialNo"},
|
{0x0408, nullptr, "SecureInfoGetSerialNo"},
|
||||||
{0x0409, nullptr, "UpdateConfigBlk00040003"},
|
{0x0409, nullptr, "UpdateConfigBlk00040003"},
|
||||||
|
{0x040D, &CFG_S::SetUUIDClockSequence, "SetUUIDClockSequence"},
|
||||||
|
{0x040E, &CFG_S::GetUUIDClockSequence, "GetUUIDClockSequence"},
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
Loading…
Reference in a new issue