mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 13:20:03 +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
					
				
					 4 changed files with 102 additions and 1 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue