diff options
| author | 2016-06-01 10:37:57 +0300 | |
|---|---|---|
| committer | 2016-07-03 08:23:58 +0300 | |
| commit | 324c8d21a4e5e7847c3c97d81757d0243ea9bb7f (patch) | |
| tree | 3dff7473330fa2075b43ec4a34f005b21420cc59 /src | |
| parent | Service::CFG: add missing language (diff) | |
| download | yuzu-324c8d21a4e5e7847c3c97d81757d0243ea9bb7f.tar.gz yuzu-324c8d21a4e5e7847c3c97d81757d0243ea9bb7f.tar.xz yuzu-324c8d21a4e5e7847c3c97d81757d0243ea9bb7f.zip | |
Service::CFG: add SetConfigInfoBlk4
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/cfg/cfg.cpp | 45 | ||||
| -rw-r--r-- | src/core/hle/service/cfg/cfg.h | 30 | ||||
| -rw-r--r-- | src/core/hle/service/cfg/cfg_i.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/cfg/cfg_s.cpp | 2 |
4 files changed, 73 insertions, 8 deletions
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 8e0848bf1..907a82301 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp | |||
| @@ -223,6 +223,22 @@ void GetConfigInfoBlk8(Service::Interface* self) { | |||
| 223 | Memory::WriteBlock(data_pointer, data.data(), data.size()); | 223 | Memory::WriteBlock(data_pointer, data.data(), data.size()); |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | void SetConfigInfoBlk4(Service::Interface* self) { | ||
| 227 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 228 | u32 block_id = cmd_buff[1]; | ||
| 229 | u32 size = cmd_buff[2]; | ||
| 230 | VAddr data_pointer = cmd_buff[4]; | ||
| 231 | |||
| 232 | if (!Memory::IsValidVirtualAddress(data_pointer)) { | ||
| 233 | cmd_buff[1] = -1; // TODO(Subv): Find the right error code | ||
| 234 | return; | ||
| 235 | } | ||
| 236 | |||
| 237 | std::vector<u8> data(size); | ||
| 238 | Memory::ReadBlock(data_pointer, data.data(), data.size()); | ||
| 239 | cmd_buff[1] = Service::CFG::SetConfigInfoBlock(block_id, size, 0x4, data.data()).raw; | ||
| 240 | } | ||
| 241 | |||
| 226 | void UpdateConfigNANDSavegame(Service::Interface* self) { | 242 | void UpdateConfigNANDSavegame(Service::Interface* self) { |
| 227 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 243 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 228 | cmd_buff[1] = Service::CFG::UpdateConfigNANDSavegame().raw; | 244 | cmd_buff[1] = Service::CFG::UpdateConfigNANDSavegame().raw; |
| @@ -233,13 +249,13 @@ void FormatConfig(Service::Interface* self) { | |||
| 233 | cmd_buff[1] = Service::CFG::FormatConfig().raw; | 249 | cmd_buff[1] = Service::CFG::FormatConfig().raw; |
| 234 | } | 250 | } |
| 235 | 251 | ||
| 236 | ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { | 252 | static ResultVal<void*> GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 flag) { |
| 237 | // Read the header | 253 | // Read the header |
| 238 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | 254 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); |
| 239 | 255 | ||
| 240 | auto itr = std::find_if(std::begin(config->block_entries), std::end(config->block_entries), | 256 | auto itr = std::find_if(std::begin(config->block_entries), std::end(config->block_entries), |
| 241 | [&](const SaveConfigBlockEntry& entry) { | 257 | [&](const SaveConfigBlockEntry& entry) { |
| 242 | return entry.block_id == block_id && (entry.flags & flag); | 258 | return entry.block_id == block_id; |
| 243 | }); | 259 | }); |
| 244 | 260 | ||
| 245 | if (itr == std::end(config->block_entries)) { | 261 | if (itr == std::end(config->block_entries)) { |
| @@ -247,17 +263,38 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { | |||
| 247 | return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); | 263 | return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); |
| 248 | } | 264 | } |
| 249 | 265 | ||
| 266 | if ((itr->flags & flag) == 0) { | ||
| 267 | LOG_ERROR(Service_CFG, "Invalid flag %u for config block 0x%X with size %u", flag, block_id, size); | ||
| 268 | return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||
| 269 | } | ||
| 270 | |||
| 250 | if (itr->size != size) { | 271 | if (itr->size != size) { |
| 251 | LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size, block_id, flag); | 272 | LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size, block_id, flag); |
| 252 | return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); | 273 | return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); |
| 253 | } | 274 | } |
| 254 | 275 | ||
| 276 | void* pointer; | ||
| 277 | |||
| 255 | // The data is located in the block header itself if the size is less than 4 bytes | 278 | // The data is located in the block header itself if the size is less than 4 bytes |
| 256 | if (itr->size <= 4) | 279 | if (itr->size <= 4) |
| 257 | memcpy(output, &itr->offset_or_data, itr->size); | 280 | pointer = &itr->offset_or_data; |
| 258 | else | 281 | else |
| 259 | memcpy(output, &cfg_config_file_buffer[itr->offset_or_data], itr->size); | 282 | pointer = &cfg_config_file_buffer[itr->offset_or_data]; |
| 283 | |||
| 284 | return MakeResult<void*>(pointer); | ||
| 285 | } | ||
| 286 | |||
| 287 | ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output) { | ||
| 288 | void* pointer; | ||
| 289 | CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); | ||
| 290 | memcpy(output, pointer, size); | ||
| 291 | return RESULT_SUCCESS; | ||
| 292 | } | ||
| 260 | 293 | ||
| 294 | ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input) { | ||
| 295 | void* pointer; | ||
| 296 | CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); | ||
| 297 | memcpy(pointer, input, size); | ||
| 261 | return RESULT_SUCCESS; | 298 | return RESULT_SUCCESS; |
| 262 | } | 299 | } |
| 263 | 300 | ||
diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h index bf544bd8d..4822433cf 100644 --- a/src/core/hle/service/cfg/cfg.h +++ b/src/core/hle/service/cfg/cfg.h | |||
| @@ -185,6 +185,22 @@ void GetConfigInfoBlk2(Service::Interface* self); | |||
| 185 | void GetConfigInfoBlk8(Service::Interface* self); | 185 | void GetConfigInfoBlk8(Service::Interface* self); |
| 186 | 186 | ||
| 187 | /** | 187 | /** |
| 188 | * CFG::SetConfigInfoBlk4 service function | ||
| 189 | * Inputs: | ||
| 190 | * 0 : 0x04020082 / 0x08020082 | ||
| 191 | * 1 : Block ID | ||
| 192 | * 2 : Size | ||
| 193 | * 3 : Descriptor for the output buffer | ||
| 194 | * 4 : Output buffer pointer | ||
| 195 | * Outputs: | ||
| 196 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 197 | * Note: | ||
| 198 | * The parameters order is different from GetConfigInfoBlk2/8's, | ||
| 199 | * where Block ID and Size are switched. | ||
| 200 | */ | ||
| 201 | void SetConfigInfoBlk4(Service::Interface* self); | ||
| 202 | |||
| 203 | /** | ||
| 188 | * CFG::UpdateConfigNANDSavegame service function | 204 | * CFG::UpdateConfigNANDSavegame service function |
| 189 | * Inputs: | 205 | * Inputs: |
| 190 | * 0 : 0x04030000 / 0x08030000 | 206 | * 0 : 0x04030000 / 0x08030000 |
| @@ -212,7 +228,19 @@ void FormatConfig(Service::Interface* self); | |||
| 212 | * @param output A pointer where we will write the read data | 228 | * @param output A pointer where we will write the read data |
| 213 | * @returns ResultCode indicating the result of the operation, 0 on success | 229 | * @returns ResultCode indicating the result of the operation, 0 on success |
| 214 | */ | 230 | */ |
| 215 | ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output); | 231 | ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output); |
| 232 | |||
| 233 | /** | ||
| 234 | * Reads data from input and writes to a block with the specified id and flag | ||
| 235 | * in the Config savegame buffer. | ||
| 236 | * The input size must match exactly the size of the target block | ||
| 237 | * @param block_id The id of the block we want to write | ||
| 238 | * @param size The size of the block we want to write | ||
| 239 | * @param flag The target block must have this flag set | ||
| 240 | * @param input A pointer where we will read data and write to Config savegame buffer | ||
| 241 | * @returns ResultCode indicating the result of the operation, 0 on success | ||
| 242 | */ | ||
| 243 | ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input); | ||
| 216 | 244 | ||
| 217 | /** | 245 | /** |
| 218 | * Creates a block with the specified id and writes the input data to the cfg savegame buffer in memory. | 246 | * Creates a block with the specified id and writes the input data to the cfg savegame buffer in memory. |
diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index b18060f6d..8b0db785f 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp | |||
| @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 22 | {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, | 22 | {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, |
| 23 | // cfg:i | 23 | // cfg:i |
| 24 | {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, | 24 | {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, |
| 25 | {0x04020082, nullptr, "SetConfigInfoBlk4"}, | 25 | {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, |
| 26 | {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, | 26 | {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, |
| 27 | {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, | 27 | {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, |
| 28 | {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, | 28 | {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, |
| @@ -31,7 +31,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 31 | {0x04080042, nullptr, "SecureInfoGetSerialNo"}, | 31 | {0x04080042, nullptr, "SecureInfoGetSerialNo"}, |
| 32 | {0x04090000, nullptr, "UpdateConfigBlk00040003"}, | 32 | {0x04090000, nullptr, "UpdateConfigBlk00040003"}, |
| 33 | {0x08010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, | 33 | {0x08010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, |
| 34 | {0x08020082, nullptr, "SetConfigInfoBlk4"}, | 34 | {0x08020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, |
| 35 | {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, | 35 | {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, |
| 36 | {0x080400C2, nullptr, "CreateConfigInfoBlk"}, | 36 | {0x080400C2, nullptr, "CreateConfigInfoBlk"}, |
| 37 | {0x08050000, nullptr, "DeleteConfigNANDSavefile"}, | 37 | {0x08050000, nullptr, "DeleteConfigNANDSavefile"}, |
diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index e001f7687..12b458783 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp | |||
| @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 22 | {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, | 22 | {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, |
| 23 | // cfg:s | 23 | // cfg:s |
| 24 | {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, | 24 | {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, |
| 25 | {0x04020082, nullptr, "SetConfigInfoBlk4"}, | 25 | {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, |
| 26 | {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, | 26 | {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, |
| 27 | {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, | 27 | {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, |
| 28 | {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, | 28 | {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, |