diff options
| author | wwylele <wwylele@gmail.com> | 2016-06-01 10:37:57 +0300 | 
|---|---|---|
| committer | wwylele <wwylele@gmail.com> | 2016-07-03 08:23:58 +0300 | 
| commit | 324c8d21a4e5e7847c3c97d81757d0243ea9bb7f (patch) | |
| tree | 3dff7473330fa2075b43ec4a34f005b21420cc59 /src/core/hle | |
| parent | f00e8d4b2b397b090ff7a7044c9909d3e700749b (diff) | |
Service::CFG: add SetConfigInfoBlk4
Diffstat (limited to 'src/core/hle')
| -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) {      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;  } 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);  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:   *      0 : 0x04030000 / 0x08030000 @@ -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. 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[] = {      {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"}, 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[] = {      {0x000A0040, GetCountryCodeID,                     "GetCountryCodeID"},      // cfg:s      {0x04010082, GetConfigInfoBlk8,                    "GetConfigInfoBlk8"}, -    {0x04020082, nullptr,                              "SetConfigInfoBlk4"}, +    {0x04020082, SetConfigInfoBlk4,                    "SetConfigInfoBlk4"},      {0x04030000, UpdateConfigNANDSavegame,             "UpdateConfigNANDSavegame"},      {0x04040042, nullptr,                              "GetLocalFriendCodeSeedData"},      {0x04050000, nullptr,                              "GetLocalFriendCodeSeed"}, | 
