mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 15:39:02 -05:00 
			
		
		
		
	Service::CFG: add SetConfigInfoBlk4
This commit is contained in:
		| @@ -223,6 +223,22 @@ void GetConfigInfoBlk8(Service::Interface* self) { | ||||
|     Memory::WriteBlock(data_pointer, data.data(), data.size()); | ||||
| } | ||||
|  | ||||
| void SetConfigInfoBlk4(Service::Interface* self) { | ||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); | ||||
|     u32 block_id = cmd_buff[1]; | ||||
|     u32 size = cmd_buff[2]; | ||||
|     VAddr data_pointer = cmd_buff[4]; | ||||
|  | ||||
|     if (!Memory::IsValidVirtualAddress(data_pointer)) { | ||||
|         cmd_buff[1] = -1; // TODO(Subv): Find the right error code | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     std::vector<u8> data(size); | ||||
|     Memory::ReadBlock(data_pointer, data.data(), data.size()); | ||||
|     cmd_buff[1] = Service::CFG::SetConfigInfoBlock(block_id, size, 0x4, data.data()).raw; | ||||
| } | ||||
|  | ||||
| void UpdateConfigNANDSavegame(Service::Interface* self) { | ||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); | ||||
|     cmd_buff[1] = Service::CFG::UpdateConfigNANDSavegame().raw; | ||||
| @@ -233,13 +249,13 @@ void FormatConfig(Service::Interface* self) { | ||||
|     cmd_buff[1] = Service::CFG::FormatConfig().raw; | ||||
| } | ||||
|  | ||||
| ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { | ||||
| static ResultVal<void*> GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 flag) { | ||||
|     // Read the header | ||||
|     SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | ||||
|  | ||||
|     auto itr = std::find_if(std::begin(config->block_entries), std::end(config->block_entries), | ||||
|         [&](const SaveConfigBlockEntry& entry) { | ||||
|             return entry.block_id == block_id && (entry.flags & flag); | ||||
|             return entry.block_id == block_id; | ||||
|         }); | ||||
|  | ||||
|     if (itr == std::end(config->block_entries)) { | ||||
| @@ -247,17 +263,38 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { | ||||
|         return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||||
|     } | ||||
|  | ||||
|     if ((itr->flags & flag) == 0) { | ||||
|         LOG_ERROR(Service_CFG, "Invalid flag %u for config block 0x%X with size %u", flag, block_id, size); | ||||
|         return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||||
|     } | ||||
|  | ||||
|     if (itr->size != size) { | ||||
|         LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size, block_id, flag); | ||||
|         return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||||
|     } | ||||
|  | ||||
|     void* pointer; | ||||
|  | ||||
|     // The data is located in the block header itself if the size is less than 4 bytes | ||||
|     if (itr->size <= 4) | ||||
|         memcpy(output, &itr->offset_or_data, itr->size); | ||||
|         pointer = &itr->offset_or_data; | ||||
|     else | ||||
|         memcpy(output, &cfg_config_file_buffer[itr->offset_or_data], itr->size); | ||||
|         pointer = &cfg_config_file_buffer[itr->offset_or_data]; | ||||
|  | ||||
|     return MakeResult<void*>(pointer); | ||||
| } | ||||
|  | ||||
| ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output) { | ||||
|     void* pointer; | ||||
|     CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); | ||||
|     memcpy(output, pointer, size); | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input) { | ||||
|     void* pointer; | ||||
|     CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); | ||||
|     memcpy(pointer, input, size); | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -184,6 +184,22 @@ void GetConfigInfoBlk2(Service::Interface* self); | ||||
|  */ | ||||
| void GetConfigInfoBlk8(Service::Interface* self); | ||||
|  | ||||
| /** | ||||
|  * CFG::SetConfigInfoBlk4 service function | ||||
|  *  Inputs: | ||||
|  *      0 : 0x04020082 / 0x08020082 | ||||
|  *      1 : Block ID | ||||
|  *      2 : Size | ||||
|  *      3 : Descriptor for the output buffer | ||||
|  *      4 : Output buffer pointer | ||||
|  *  Outputs: | ||||
|  *      1 : Result of function, 0 on success, otherwise error code | ||||
|  *  Note: | ||||
|  *      The parameters order is different from GetConfigInfoBlk2/8's, | ||||
|  *      where Block ID and Size are switched. | ||||
|  */ | ||||
| void SetConfigInfoBlk4(Service::Interface* self); | ||||
|  | ||||
| /** | ||||
|  * CFG::UpdateConfigNANDSavegame service function | ||||
|  *  Inputs: | ||||
| @@ -212,7 +228,19 @@ void FormatConfig(Service::Interface* self); | ||||
|  * @param output A pointer where we will write the read data | ||||
|  * @returns ResultCode indicating the result of the operation, 0 on success | ||||
|  */ | ||||
| ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output); | ||||
| ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output); | ||||
|  | ||||
| /** | ||||
|  * Reads data from input and writes to a block with the specified id and flag | ||||
|  * in the Config savegame buffer. | ||||
|  * The input size must match exactly the size of the target block | ||||
|  * @param block_id The id of the block we want to write | ||||
|  * @param size The size of the block we want to write | ||||
|  * @param flag The target block must have this flag set | ||||
|  * @param input A pointer where we will read data and write to Config savegame buffer | ||||
|  * @returns ResultCode indicating the result of the operation, 0 on success | ||||
|  */ | ||||
| ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input); | ||||
|  | ||||
| /** | ||||
|  * Creates a block with the specified id and writes the input data to the cfg savegame buffer in memory. | ||||
|   | ||||
| @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||
|     {0x000A0040, GetCountryCodeID,                     "GetCountryCodeID"}, | ||||
|     // cfg:i | ||||
|     {0x04010082, GetConfigInfoBlk8,                    "GetConfigInfoBlk8"}, | ||||
|     {0x04020082, nullptr,                              "SetConfigInfoBlk4"}, | ||||
|     {0x04020082, SetConfigInfoBlk4,                    "SetConfigInfoBlk4"}, | ||||
|     {0x04030000, UpdateConfigNANDSavegame,             "UpdateConfigNANDSavegame"}, | ||||
|     {0x04040042, nullptr,                              "GetLocalFriendCodeSeedData"}, | ||||
|     {0x04050000, nullptr,                              "GetLocalFriendCodeSeed"}, | ||||
| @@ -31,7 +31,7 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||
|     {0x04080042, nullptr,                              "SecureInfoGetSerialNo"}, | ||||
|     {0x04090000, nullptr,                              "UpdateConfigBlk00040003"}, | ||||
|     {0x08010082, GetConfigInfoBlk8,                    "GetConfigInfoBlk8"}, | ||||
|     {0x08020082, nullptr,                              "SetConfigInfoBlk4"}, | ||||
|     {0x08020082, SetConfigInfoBlk4,                    "SetConfigInfoBlk4"}, | ||||
|     {0x08030000, UpdateConfigNANDSavegame,             "UpdateConfigNANDSavegame"}, | ||||
|     {0x080400C2, nullptr,                              "CreateConfigInfoBlk"}, | ||||
|     {0x08050000, nullptr,                              "DeleteConfigNANDSavefile"}, | ||||
|   | ||||
| @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||
|     {0x000A0040, GetCountryCodeID,                     "GetCountryCodeID"}, | ||||
|     // cfg:s | ||||
|     {0x04010082, GetConfigInfoBlk8,                    "GetConfigInfoBlk8"}, | ||||
|     {0x04020082, nullptr,                              "SetConfigInfoBlk4"}, | ||||
|     {0x04020082, SetConfigInfoBlk4,                    "SetConfigInfoBlk4"}, | ||||
|     {0x04030000, UpdateConfigNANDSavegame,             "UpdateConfigNANDSavegame"}, | ||||
|     {0x04040042, nullptr,                              "GetLocalFriendCodeSeedData"}, | ||||
|     {0x04050000, nullptr,                              "GetLocalFriendCodeSeed"}, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 wwylele
					wwylele