mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	services/cfg: Clean up definitions and access flag handling. (#6711)
This commit is contained in:
		
							parent
							
								
									b5e1a27a7e
								
							
						
					
					
						commit
						a537f56766
					
				
					 5 changed files with 155 additions and 128 deletions
				
			
		|  | @ -263,7 +263,7 @@ u32 Module::GetRegionValue() { | ||||||
|     return Settings::values.region_value.GetValue(); |     return Settings::values.region_value.GetValue(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::Interface::SecureInfoGetRegion(Kernel::HLERequestContext& ctx) { | void Module::Interface::GetRegion(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx); |     IPC::RequestParser rp(ctx); | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
|  | @ -282,14 +282,15 @@ void Module::Interface::SecureInfoGetByte101(Kernel::HLERequestContext& ctx) { | ||||||
|     rb.Push<u8>(0); |     rb.Push<u8>(0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::Interface::GenHashConsoleUnique(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; | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(3, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(3, 0); | ||||||
| 
 | 
 | ||||||
|     std::array<u8, 12> buffer; |     std::array<u8, 12> buffer; | ||||||
|     const ResultCode result = cfg->GetConfigInfoBlock(ConsoleUniqueID2BlockID, 8, 2, buffer.data()); |     const ResultCode result = | ||||||
|  |         cfg->GetConfigBlock(ConsoleUniqueID2BlockID, 8, AccessFlag::SystemRead, buffer.data()); | ||||||
|     rb.Push(result); |     rb.Push(result); | ||||||
|     if (result.IsSuccess()) { |     if (result.IsSuccess()) { | ||||||
|         std::memcpy(&buffer[8], &app_id_salt, sizeof(u32)); |         std::memcpy(&buffer[8], &app_id_salt, sizeof(u32)); | ||||||
|  | @ -308,7 +309,7 @@ void Module::Interface::GenHashConsoleUnique(Kernel::HLERequestContext& ctx) { | ||||||
|     LOG_DEBUG(Service_CFG, "called app_id_salt=0x{:X}", app_id_salt); |     LOG_DEBUG(Service_CFG, "called app_id_salt=0x{:X}", app_id_salt); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::Interface::GetRegionCanadaUSA(Kernel::HLERequestContext& ctx) { | void Module::Interface::IsCoppacsSupported(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx); |     IPC::RequestParser rp(ctx); | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
| 
 | 
 | ||||||
|  | @ -328,7 +329,8 @@ void Module::Interface::GetSystemModel(Kernel::HLERequestContext& ctx) { | ||||||
|     u32 data{}; |     u32 data{}; | ||||||
| 
 | 
 | ||||||
|     // TODO(Subv): Find out the correct error codes
 |     // TODO(Subv): Find out the correct error codes
 | ||||||
|     rb.Push(cfg->GetConfigInfoBlock(ConsoleModelBlockID, 4, 0x8, reinterpret_cast<u8*>(&data))); |     rb.Push(cfg->GetConfigBlock(ConsoleModelBlockID, 4, AccessFlag::SystemRead, | ||||||
|  |                                 reinterpret_cast<u8*>(&data))); | ||||||
|     ConsoleModelInfo model; |     ConsoleModelInfo model; | ||||||
|     std::memcpy(&model, &data, 4); |     std::memcpy(&model, &data, 4); | ||||||
|     if ((model.model == NINTENDO_3DS || model.model == NINTENDO_3DS_XL || |     if ((model.model == NINTENDO_3DS || model.model == NINTENDO_3DS_XL || | ||||||
|  | @ -350,12 +352,13 @@ void Module::Interface::GetModelNintendo2DS(Kernel::HLERequestContext& ctx) { | ||||||
|     u32 data{}; |     u32 data{}; | ||||||
| 
 | 
 | ||||||
|     // TODO(Subv): Find out the correct error codes
 |     // TODO(Subv): Find out the correct error codes
 | ||||||
|     rb.Push(cfg->GetConfigInfoBlock(ConsoleModelBlockID, 4, 0x8, reinterpret_cast<u8*>(&data))); |     rb.Push(cfg->GetConfigBlock(ConsoleModelBlockID, 4, AccessFlag::SystemRead, | ||||||
|  |                                 reinterpret_cast<u8*>(&data))); | ||||||
|     u8 model = data & 0xFF; |     u8 model = data & 0xFF; | ||||||
|     rb.Push(model != Service::CFG::NINTENDO_2DS); |     rb.Push(model != Service::CFG::NINTENDO_2DS); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::Interface::GetConfigInfoBlk2(Kernel::HLERequestContext& ctx) { | void Module::Interface::GetConfig(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx); |     IPC::RequestParser rp(ctx); | ||||||
|     u32 size = rp.Pop<u32>(); |     u32 size = rp.Pop<u32>(); | ||||||
|     u32 block_id = rp.Pop<u32>(); |     u32 block_id = rp.Pop<u32>(); | ||||||
|  | @ -363,12 +366,12 @@ void Module::Interface::GetConfigInfoBlk2(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|     std::vector<u8> data(size); |     std::vector<u8> data(size); | ||||||
|     rb.Push(cfg->GetConfigInfoBlock(block_id, size, 0x2, data.data())); |     rb.Push(cfg->GetConfigBlock(block_id, size, AccessFlag::UserRead, data.data())); | ||||||
|     buffer.Write(data.data(), 0, data.size()); |     buffer.Write(data.data(), 0, data.size()); | ||||||
|     rb.PushMappedBuffer(buffer); |     rb.PushMappedBuffer(buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::Interface::GetConfigInfoBlk8(Kernel::HLERequestContext& ctx) { | void Module::Interface::GetSystemConfig(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx); |     IPC::RequestParser rp(ctx); | ||||||
|     u32 size = rp.Pop<u32>(); |     u32 size = rp.Pop<u32>(); | ||||||
|     u32 block_id = rp.Pop<u32>(); |     u32 block_id = rp.Pop<u32>(); | ||||||
|  | @ -376,12 +379,12 @@ void Module::Interface::GetConfigInfoBlk8(Kernel::HLERequestContext& ctx) { | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|     std::vector<u8> data(size); |     std::vector<u8> data(size); | ||||||
|     rb.Push(cfg->GetConfigInfoBlock(block_id, size, 0x8, data.data())); |     rb.Push(cfg->GetConfigBlock(block_id, size, AccessFlag::SystemRead, data.data())); | ||||||
|     buffer.Write(data.data(), 0, data.size()); |     buffer.Write(data.data(), 0, data.size()); | ||||||
|     rb.PushMappedBuffer(buffer); |     rb.PushMappedBuffer(buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::Interface::SetConfigInfoBlk4(Kernel::HLERequestContext& ctx) { | void Module::Interface::SetSystemConfig(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx); |     IPC::RequestParser rp(ctx); | ||||||
|     u32 block_id = rp.Pop<u32>(); |     u32 block_id = rp.Pop<u32>(); | ||||||
|     u32 size = rp.Pop<u32>(); |     u32 size = rp.Pop<u32>(); | ||||||
|  | @ -391,7 +394,7 @@ void Module::Interface::SetConfigInfoBlk4(Kernel::HLERequestContext& ctx) { | ||||||
|     buffer.Read(data.data(), 0, data.size()); |     buffer.Read(data.data(), 0, data.size()); | ||||||
| 
 | 
 | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|     rb.Push(cfg->SetConfigInfoBlock(block_id, size, 0x4, data.data())); |     rb.Push(cfg->SetConfigBlock(block_id, size, AccessFlag::SystemWrite, data.data())); | ||||||
|     rb.PushMappedBuffer(buffer); |     rb.PushMappedBuffer(buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -407,31 +410,30 @@ void Module::Interface::FormatConfig(Kernel::HLERequestContext& ctx) { | ||||||
|     rb.Push(cfg->FormatConfig()); |     rb.Push(cfg->FormatConfig()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultVal<void*> Module::GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 flag) { | ResultVal<void*> Module::GetConfigBlockPointer(u32 block_id, u32 size, AccessFlag accesss_flag) { | ||||||
|     // Read the header
 |     // Read the header
 | ||||||
|     SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); |     auto config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | ||||||
| 
 |  | ||||||
|     auto itr = |     auto itr = | ||||||
|         std::find_if(std::begin(config->block_entries), std::end(config->block_entries), |         std::find_if(std::begin(config->block_entries), std::end(config->block_entries), | ||||||
|                      [&](const SaveConfigBlockEntry& entry) { return entry.block_id == block_id; }); |                      [&](const SaveConfigBlockEntry& entry) { return entry.block_id == block_id; }); | ||||||
| 
 | 
 | ||||||
|     if (itr == std::end(config->block_entries)) { |     if (itr == std::end(config->block_entries)) { | ||||||
|         LOG_ERROR(Service_CFG, "Config block 0x{:X} with flags {} and size {} was not found", |         LOG_ERROR(Service_CFG, "Config block 0x{:X} with flags {} and size {} was not found", | ||||||
|                   block_id, flag, size); |                   block_id, accesss_flag, size); | ||||||
|         return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, |         return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, | ||||||
|                           ErrorSummary::WrongArgument, ErrorLevel::Permanent); |                           ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if ((itr->flags & flag) == 0) { |     if (False(itr->access_flags & accesss_flag)) { | ||||||
|         LOG_ERROR(Service_CFG, "Invalid flag {} for config block 0x{:X} with size {}", flag, |         LOG_ERROR(Service_CFG, "Invalid access flag {:X} for config block 0x{:X} with size {}", | ||||||
|                   block_id, size); |                   accesss_flag, block_id, size); | ||||||
|         return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::Config, |         return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::Config, | ||||||
|                           ErrorSummary::WrongArgument, ErrorLevel::Permanent); |                           ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (itr->size != size) { |     if (itr->size != size) { | ||||||
|         LOG_ERROR(Service_CFG, "Invalid size {} for config block 0x{:X} with flags {}", size, |         LOG_ERROR(Service_CFG, "Invalid size {} for config block 0x{:X} with flags {}", size, | ||||||
|                   block_id, flag); |                   block_id, accesss_flag); | ||||||
|         return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, |         return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, | ||||||
|                           ErrorSummary::WrongArgument, ErrorLevel::Permanent); |                           ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||||||
|     } |     } | ||||||
|  | @ -447,28 +449,30 @@ ResultVal<void*> Module::GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 f | ||||||
|     return pointer; |     return pointer; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode Module::GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output) { | ResultCode Module::GetConfigBlock(u32 block_id, u32 size, AccessFlag accesss_flag, void* output) { | ||||||
|     void* pointer = nullptr; |     void* pointer = nullptr; | ||||||
|     CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); |     CASCADE_RESULT(pointer, GetConfigBlockPointer(block_id, size, accesss_flag)); | ||||||
|     std::memcpy(output, pointer, size); |     std::memcpy(output, pointer, size); | ||||||
| 
 | 
 | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode Module::SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input) { | ResultCode Module::SetConfigBlock(u32 block_id, u32 size, AccessFlag accesss_flag, | ||||||
|  |                                   const void* input) { | ||||||
|     void* pointer = nullptr; |     void* pointer = nullptr; | ||||||
|     CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); |     CASCADE_RESULT(pointer, GetConfigBlockPointer(block_id, size, accesss_flag)); | ||||||
|     std::memcpy(pointer, input, size); |     std::memcpy(pointer, input, size); | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode Module::CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* data) { | ResultCode Module::CreateConfigBlock(u32 block_id, u16 size, AccessFlag access_flags, | ||||||
|  |                                      const void* data) { | ||||||
|     SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); |     SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | ||||||
|     if (config->total_entries >= CONFIG_FILE_MAX_BLOCK_ENTRIES) |     if (config->total_entries >= CONFIG_FILE_MAX_BLOCK_ENTRIES) | ||||||
|         return ResultCode(-1); // TODO(Subv): Find the right error code
 |         return ResultCode(-1); // TODO(Subv): Find the right error code
 | ||||||
| 
 | 
 | ||||||
|     // Insert the block header with offset 0 for now
 |     // Insert the block header with offset 0 for now
 | ||||||
|     config->block_entries[config->total_entries] = {block_id, 0, size, flags}; |     config->block_entries[config->total_entries] = {block_id, 0, size, access_flags}; | ||||||
|     if (size > 4) { |     if (size > 4) { | ||||||
|         u32 offset = config->data_entries_offset; |         u32 offset = config->data_entries_offset; | ||||||
|         // Perform a search to locate the next offset for the new data
 |         // Perform a search to locate the next offset for the new data
 | ||||||
|  | @ -532,63 +536,68 @@ ResultCode Module::FormatConfig() { | ||||||
|     u8 zero_buffer[0xC0] = {}; |     u8 zero_buffer[0xC0] = {}; | ||||||
| 
 | 
 | ||||||
|     // 0x00030001 - User time offset (Read by CECD): displayed timestamp - RTC timestamp
 |     // 0x00030001 - User time offset (Read by CECD): displayed timestamp - RTC timestamp
 | ||||||
|     res = CreateConfigInfoBlk(UserTimeOffsetBlockID, 0x8, 0xE, zero_buffer); |     res = CreateConfigBlock(UserTimeOffsetBlockID, 0x8, AccessFlag::Global, zero_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x00050001 - Backlight controls
 |     // 0x00050001 - Backlight controls
 | ||||||
|     res = CreateConfigInfoBlk(BacklightControlsBlockID, sizeof(BACKLIGHT_CONTROLS), 0xC, |     res = CreateConfigBlock(BacklightControlsBlockID, sizeof(BACKLIGHT_CONTROLS), | ||||||
|                               &BACKLIGHT_CONTROLS); |                             AccessFlag::System, &BACKLIGHT_CONTROLS); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     res = CreateConfigInfoBlk(StereoCameraSettingsBlockID, sizeof(STEREO_CAMERA_SETTINGS), 0xE, |     res = CreateConfigBlock(StereoCameraSettingsBlockID, sizeof(STEREO_CAMERA_SETTINGS), | ||||||
|                               STEREO_CAMERA_SETTINGS.data()); |                             AccessFlag::Global, STEREO_CAMERA_SETTINGS.data()); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x00050009 - New 3DS backlight controls
 |     // 0x00050009 - New 3DS backlight controls
 | ||||||
|     res = CreateConfigInfoBlk(BacklightControlNew3dsBlockID, sizeof(NEW_3DS_BACKLIGHT_CONTROLS), |     res = CreateConfigBlock(BacklightControlNew3dsBlockID, sizeof(NEW_3DS_BACKLIGHT_CONTROLS), | ||||||
|                               0xC, &NEW_3DS_BACKLIGHT_CONTROLS); |                             AccessFlag::System, &NEW_3DS_BACKLIGHT_CONTROLS); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     res = CreateConfigInfoBlk(SoundOutputModeBlockID, sizeof(SOUND_OUTPUT_MODE), 0xE, |     res = CreateConfigBlock(SoundOutputModeBlockID, sizeof(SOUND_OUTPUT_MODE), AccessFlag::Global, | ||||||
|                               &SOUND_OUTPUT_MODE); |                             &SOUND_OUTPUT_MODE); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     const auto [random_number, console_id] = GenerateConsoleUniqueId(); |     const auto [random_number, console_id] = GenerateConsoleUniqueId(); | ||||||
| 
 | 
 | ||||||
|     u64_le console_id_le = console_id; |     u64_le console_id_le = console_id; | ||||||
|     res = CreateConfigInfoBlk(ConsoleUniqueID1BlockID, sizeof(console_id_le), 0xE, &console_id_le); |     res = CreateConfigBlock(ConsoleUniqueID1BlockID, sizeof(console_id_le), AccessFlag::Global, | ||||||
|  |                             &console_id_le); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     res = CreateConfigInfoBlk(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le); |     res = CreateConfigBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), AccessFlag::Global, | ||||||
|  |                             &console_id_le); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     u32_le random_number_le = random_number; |     u32_le random_number_le = random_number; | ||||||
|     res = CreateConfigInfoBlk(ConsoleUniqueID3BlockID, sizeof(random_number_le), 0xE, |     res = CreateConfigBlock(ConsoleUniqueID3BlockID, sizeof(random_number_le), AccessFlag::Global, | ||||||
|                               &random_number_le); |                             &random_number_le); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     res = CreateConfigInfoBlk(UsernameBlockID, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, |     res = CreateConfigBlock(UsernameBlockID, sizeof(CONSOLE_USERNAME_BLOCK), AccessFlag::Global, | ||||||
|                               &CONSOLE_USERNAME_BLOCK); |                             &CONSOLE_USERNAME_BLOCK); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     res = CreateConfigInfoBlk(BirthdayBlockID, sizeof(PROFILE_BIRTHDAY), 0xE, &PROFILE_BIRTHDAY); |     res = CreateConfigBlock(BirthdayBlockID, sizeof(PROFILE_BIRTHDAY), AccessFlag::Global, | ||||||
|  |                             &PROFILE_BIRTHDAY); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     res = CreateConfigInfoBlk(LanguageBlockID, sizeof(CONSOLE_LANGUAGE), 0xE, &CONSOLE_LANGUAGE); |     res = CreateConfigBlock(LanguageBlockID, sizeof(CONSOLE_LANGUAGE), AccessFlag::Global, | ||||||
|  |                             &CONSOLE_LANGUAGE); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     res = CreateConfigInfoBlk(CountryInfoBlockID, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO); |     res = CreateConfigBlock(CountryInfoBlockID, sizeof(COUNTRY_INFO), AccessFlag::Global, | ||||||
|  |                             &COUNTRY_INFO); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|  | @ -598,53 +607,54 @@ ResultCode Module::FormatConfig() { | ||||||
|         std::copy(region_name.cbegin(), region_name.cend(), country_name_buffer[i]); |         std::copy(region_name.cbegin(), region_name.cend(), country_name_buffer[i]); | ||||||
|     } |     } | ||||||
|     // 0x000B0001 - Localized names for the profile Country
 |     // 0x000B0001 - Localized names for the profile Country
 | ||||||
|     res = CreateConfigInfoBlk(CountryNameBlockID, sizeof(country_name_buffer), 0xE, |     res = CreateConfigBlock(CountryNameBlockID, sizeof(country_name_buffer), AccessFlag::Global, | ||||||
|                               country_name_buffer); |                             country_name_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x000B0002 - Localized names for the profile State/Province
 |     // 0x000B0002 - Localized names for the profile State/Province
 | ||||||
|     res = CreateConfigInfoBlk(StateNameBlockID, sizeof(country_name_buffer), 0xE, |     res = CreateConfigBlock(StateNameBlockID, sizeof(country_name_buffer), AccessFlag::Global, | ||||||
|                               country_name_buffer); |                             country_name_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x000B0003 - Coordinates. A pair of s16 represents latitude and longitude, respectively. One
 |     // 0x000B0003 - Coordinates. A pair of s16 represents latitude and longitude, respectively. One
 | ||||||
|     // need to multiply both value by 180/32768 to get coordinates in degrees
 |     // need to multiply both value by 180/32768 to get coordinates in degrees
 | ||||||
|     res = CreateConfigInfoBlk(LatitudeLongitudeBlockID, 0x4, 0xE, zero_buffer); |     res = CreateConfigBlock(LatitudeLongitudeBlockID, 0x4, AccessFlag::Global, zero_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x000C0000 - Restricted photo exchange data, and other info (includes a mirror of Parental
 |     // 0x000C0000 - Restricted photo exchange data, and other info (includes a mirror of Parental
 | ||||||
|     // Restrictions PIN/Secret Answer)
 |     // Restrictions PIN/Secret Answer)
 | ||||||
|     res = CreateConfigInfoBlk(RestrictedPhotoExchangeBlockID, 0xC0, 0xE, zero_buffer); |     res = CreateConfigBlock(RestrictedPhotoExchangeBlockID, 0xC0, AccessFlag::Global, zero_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x000C0001 - COPPACS restriction data
 |     // 0x000C0001 - COPPACS restriction data
 | ||||||
|     res = CreateConfigInfoBlk(CoppacsRestrictionBlockID, 0x14, 0xE, zero_buffer); |     res = CreateConfigBlock(CoppacsRestrictionBlockID, 0x14, AccessFlag::Global, zero_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x000D0000 - Accepted EULA version
 |     // 0x000D0000 - Accepted EULA version
 | ||||||
|     u32_le data = MAX_EULA_VERSION.minor + (MAX_EULA_VERSION.major << 8); |     u32_le data = MAX_EULA_VERSION.minor + (MAX_EULA_VERSION.major << 8); | ||||||
|     res = CreateConfigInfoBlk(EULAVersionBlockID, sizeof(data), 0xE, &data); |     res = CreateConfigBlock(EULAVersionBlockID, sizeof(data), AccessFlag::Global, &data); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     u8 unknown_data = 0; |     u8 unknown_data = 0; | ||||||
|     res = CreateConfigInfoBlk(Unknown_0x000E0000, sizeof(unknown_data), 0x2, &unknown_data); |     res = CreateConfigBlock(Unknown_0x000E0000, sizeof(unknown_data), AccessFlag::Global, | ||||||
|  |                             &unknown_data); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     res = CreateConfigInfoBlk(ConsoleModelBlockID, sizeof(CONSOLE_MODEL_OLD), 0xC, |     res = CreateConfigBlock(ConsoleModelBlockID, sizeof(CONSOLE_MODEL_OLD), AccessFlag::System, | ||||||
|                               &CONSOLE_MODEL_OLD); |                             &CONSOLE_MODEL_OLD); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x000F0006 - In NIM, taken as a (hopefully null terminated) string used for the
 |     // 0x000F0006 - In NIM, taken as a (hopefully null terminated) string used for the
 | ||||||
|     // "X-Device-Token" http header field for NPNS url.
 |     // "X-Device-Token" http header field for NPNS url.
 | ||||||
|     res = CreateConfigInfoBlk(XDeviceTokenBlockID, 0x28, 0xC, zero_buffer); |     res = CreateConfigBlock(XDeviceTokenBlockID, 0x28, AccessFlag::System, zero_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|  | @ -652,22 +662,23 @@ ResultCode Module::FormatConfig() { | ||||||
|     // system is booted for the first time or after doing a System Format: 0 = setup required,
 |     // system is booted for the first time or after doing a System Format: 0 = setup required,
 | ||||||
|     // non-zero = no setup required
 |     // non-zero = no setup required
 | ||||||
|     u32 system_setup_flag = 1; |     u32 system_setup_flag = 1; | ||||||
|     res = CreateConfigInfoBlk(SystemSetupRequiredBlockID, 0x4, 0xC, &system_setup_flag); |     res = | ||||||
|  |         CreateConfigBlock(SystemSetupRequiredBlockID, 0x4, AccessFlag::System, &system_setup_flag); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x00130000 - DebugMode (0x100 for debug mode)
 |     // 0x00130000 - DebugMode (0x100 for debug mode)
 | ||||||
|     res = CreateConfigInfoBlk(DebugModeBlockID, 0x4, 0xE, zero_buffer); |     res = CreateConfigBlock(DebugModeBlockID, 0x4, AccessFlag::Global, zero_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x00160000 - Unknown, first byte is used by config service-cmd 0x00070040.
 |     // 0x00160000 - Unknown, first byte is used by config service-cmd 0x00070040.
 | ||||||
|     res = CreateConfigInfoBlk(0x00160000, 0x4, 0xE, zero_buffer); |     res = CreateConfigBlock(0x00160000, 0x4, AccessFlag::Global, zero_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     // 0x00170000 - Miiverse (OLV) access key
 |     // 0x00170000 - Miiverse (OLV) access key
 | ||||||
|     res = CreateConfigInfoBlk(MiiverseAccessKeyBlockID, 0x4, 0xE, zero_buffer); |     res = CreateConfigBlock(MiiverseAccessKeyBlockID, 0x4, AccessFlag::Global, zero_buffer); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|  | @ -786,12 +797,12 @@ void Module::SetUsername(const std::u16string& name) { | ||||||
|     ASSERT(name.size() <= 10); |     ASSERT(name.size() <= 10); | ||||||
|     UsernameBlock block{}; |     UsernameBlock block{}; | ||||||
|     name.copy(block.username, name.size()); |     name.copy(block.username, name.size()); | ||||||
|     SetConfigInfoBlock(UsernameBlockID, sizeof(block), 4, &block); |     SetConfigBlock(UsernameBlockID, sizeof(block), AccessFlag::SystemWrite, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::u16string Module::GetUsername() { | std::u16string Module::GetUsername() { | ||||||
|     UsernameBlock block; |     UsernameBlock block; | ||||||
|     GetConfigInfoBlock(UsernameBlockID, sizeof(block), 8, &block); |     GetConfigBlock(UsernameBlockID, sizeof(block), AccessFlag::SystemRead, &block); | ||||||
| 
 | 
 | ||||||
|     // the username string in the block isn't null-terminated,
 |     // the username string in the block isn't null-terminated,
 | ||||||
|     // so we need to find the end manually.
 |     // so we need to find the end manually.
 | ||||||
|  | @ -804,56 +815,56 @@ std::u16string Module::GetUsername() { | ||||||
| 
 | 
 | ||||||
| void Module::SetBirthday(u8 month, u8 day) { | void Module::SetBirthday(u8 month, u8 day) { | ||||||
|     BirthdayBlock block = {month, day}; |     BirthdayBlock block = {month, day}; | ||||||
|     SetConfigInfoBlock(BirthdayBlockID, sizeof(block), 4, &block); |     SetConfigBlock(BirthdayBlockID, sizeof(block), AccessFlag::SystemWrite, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::tuple<u8, u8> Module::GetBirthday() { | std::tuple<u8, u8> Module::GetBirthday() { | ||||||
|     BirthdayBlock block; |     BirthdayBlock block; | ||||||
|     GetConfigInfoBlock(BirthdayBlockID, sizeof(block), 8, &block); |     GetConfigBlock(BirthdayBlockID, sizeof(block), AccessFlag::SystemRead, &block); | ||||||
|     return std::make_tuple(block.month, block.day); |     return std::make_tuple(block.month, block.day); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::SetSystemLanguage(SystemLanguage language) { | void Module::SetSystemLanguage(SystemLanguage language) { | ||||||
|     u8 block = language; |     u8 block = language; | ||||||
|     SetConfigInfoBlock(LanguageBlockID, sizeof(block), 4, &block); |     SetConfigBlock(LanguageBlockID, sizeof(block), AccessFlag::SystemWrite, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SystemLanguage Module::GetSystemLanguage() { | SystemLanguage Module::GetSystemLanguage() { | ||||||
|     u8 block{}; |     u8 block{}; | ||||||
|     GetConfigInfoBlock(LanguageBlockID, sizeof(block), 8, &block); |     GetConfigBlock(LanguageBlockID, sizeof(block), AccessFlag::SystemRead, &block); | ||||||
|     return static_cast<SystemLanguage>(block); |     return static_cast<SystemLanguage>(block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::SetSoundOutputMode(SoundOutputMode mode) { | void Module::SetSoundOutputMode(SoundOutputMode mode) { | ||||||
|     u8 block = mode; |     u8 block = mode; | ||||||
|     SetConfigInfoBlock(SoundOutputModeBlockID, sizeof(block), 4, &block); |     SetConfigBlock(SoundOutputModeBlockID, sizeof(block), AccessFlag::SystemWrite, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SoundOutputMode Module::GetSoundOutputMode() { | SoundOutputMode Module::GetSoundOutputMode() { | ||||||
|     u8 block{}; |     u8 block{}; | ||||||
|     GetConfigInfoBlock(SoundOutputModeBlockID, sizeof(block), 8, &block); |     GetConfigBlock(SoundOutputModeBlockID, sizeof(block), AccessFlag::SystemRead, &block); | ||||||
|     return static_cast<SoundOutputMode>(block); |     return static_cast<SoundOutputMode>(block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::SetCountryCode(u8 country_code) { | void Module::SetCountryCode(u8 country_code) { | ||||||
|     ConsoleCountryInfo block = {{0, 0}, default_subregion[country_code], country_code}; |     ConsoleCountryInfo block = {{0, 0}, default_subregion[country_code], country_code}; | ||||||
|     SetConfigInfoBlock(CountryInfoBlockID, sizeof(block), 4, &block); |     SetConfigBlock(CountryInfoBlockID, sizeof(block), AccessFlag::SystemWrite, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u8 Module::GetCountryCode() { | u8 Module::GetCountryCode() { | ||||||
|     ConsoleCountryInfo block{}; |     ConsoleCountryInfo block{}; | ||||||
|     GetConfigInfoBlock(CountryInfoBlockID, sizeof(block), 8, &block); |     GetConfigBlock(CountryInfoBlockID, sizeof(block), AccessFlag::SystemRead, &block); | ||||||
|     return block.country_code; |     return block.country_code; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::SetCountryInfo(u8 country_code, u8 state_code) { | void Module::SetCountryInfo(u8 country_code, u8 state_code) { | ||||||
|     ConsoleCountryInfo block = {{0, 0}, state_code, country_code}; |     ConsoleCountryInfo block = {{0, 0}, state_code, country_code}; | ||||||
|     SetConfigInfoBlock(CountryInfoBlockID, sizeof(block), 4, &block); |     SetConfigBlock(CountryInfoBlockID, sizeof(block), AccessFlag::SystemWrite, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u8 Module::GetStateCode() { | u8 Module::GetStateCode() { | ||||||
|     ConsoleCountryInfo block{}; |     ConsoleCountryInfo block{}; | ||||||
|     GetConfigInfoBlock(CountryInfoBlockID, sizeof(block), 8, &block); |     GetConfigBlock(CountryInfoBlockID, sizeof(block), AccessFlag::SystemRead, &block); | ||||||
|     return block.state_code; |     return block.state_code; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -873,18 +884,19 @@ std::pair<u32, u64> Module::GenerateConsoleUniqueId() const { | ||||||
| 
 | 
 | ||||||
| ResultCode Module::SetConsoleUniqueId(u32 random_number, u64 console_id) { | ResultCode Module::SetConsoleUniqueId(u32 random_number, u64 console_id) { | ||||||
|     u64_le console_id_le = console_id; |     u64_le console_id_le = console_id; | ||||||
|     ResultCode res = |     ResultCode res = SetConfigBlock(ConsoleUniqueID1BlockID, sizeof(console_id_le), | ||||||
|         SetConfigInfoBlock(ConsoleUniqueID1BlockID, sizeof(console_id_le), 0xE, &console_id_le); |                                     AccessFlag::Global, &console_id_le); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     res = SetConfigInfoBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le); |     res = SetConfigBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), AccessFlag::Global, | ||||||
|  |                          &console_id_le); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|     u32_le random_number_le = random_number; |     u32_le random_number_le = random_number; | ||||||
|     res = SetConfigInfoBlock(ConsoleUniqueID3BlockID, sizeof(random_number_le), 0xE, |     res = SetConfigBlock(ConsoleUniqueID3BlockID, sizeof(random_number_le), AccessFlag::Global, | ||||||
|                              &random_number_le); |                          &random_number_le); | ||||||
|     if (!res.IsSuccess()) |     if (!res.IsSuccess()) | ||||||
|         return res; |         return res; | ||||||
| 
 | 
 | ||||||
|  | @ -893,13 +905,14 @@ ResultCode Module::SetConsoleUniqueId(u32 random_number, u64 console_id) { | ||||||
| 
 | 
 | ||||||
| u64 Module::GetConsoleUniqueId() { | u64 Module::GetConsoleUniqueId() { | ||||||
|     u64_le console_id_le{}; |     u64_le console_id_le{}; | ||||||
|     GetConfigInfoBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le); |     GetConfigBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), AccessFlag::Global, | ||||||
|  |                    &console_id_le); | ||||||
|     return console_id_le; |     return console_id_le; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| EULAVersion Module::GetEULAVersion() { | EULAVersion Module::GetEULAVersion() { | ||||||
|     u32_le data{}; |     u32_le data{}; | ||||||
|     GetConfigInfoBlock(EULAVersionBlockID, sizeof(data), 0xE, &data); |     GetConfigBlock(EULAVersionBlockID, sizeof(data), AccessFlag::Global, &data); | ||||||
|     EULAVersion version; |     EULAVersion version; | ||||||
|     version.minor = data & 0xFF; |     version.minor = data & 0xFF; | ||||||
|     version.major = (data >> 8) & 0xFF; |     version.major = (data >> 8) & 0xFF; | ||||||
|  | @ -908,17 +921,17 @@ EULAVersion Module::GetEULAVersion() { | ||||||
| 
 | 
 | ||||||
| void Module::SetEULAVersion(const EULAVersion& version) { | void Module::SetEULAVersion(const EULAVersion& version) { | ||||||
|     u32_le data = version.minor + (version.major << 8); |     u32_le data = version.minor + (version.major << 8); | ||||||
|     SetConfigInfoBlock(EULAVersionBlockID, sizeof(data), 0xE, &data); |     SetConfigBlock(EULAVersionBlockID, sizeof(data), AccessFlag::Global, &data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Module::SetSystemSetupNeeded(bool setup_needed) { | void Module::SetSystemSetupNeeded(bool setup_needed) { | ||||||
|     u32 block = setup_needed ? 0 : 1; |     u32 block = setup_needed ? 0 : 1; | ||||||
|     SetConfigInfoBlock(SystemSetupRequiredBlockID, sizeof(block), 0xC, &block); |     SetConfigBlock(SystemSetupRequiredBlockID, sizeof(block), AccessFlag::System, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Module::IsSystemSetupNeeded() { | bool Module::IsSystemSetupNeeded() { | ||||||
|     u32 block{}; |     u32 block{}; | ||||||
|     GetConfigInfoBlock(SystemSetupRequiredBlockID, sizeof(block), 0xC, &block); |     GetConfigBlock(SystemSetupRequiredBlockID, sizeof(block), AccessFlag::System, &block); | ||||||
|     return (block & 0xFFFF) == 0; |     return (block & 0xFFFF) == 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -53,13 +53,25 @@ struct EULAVersion { | ||||||
|     u8 major; |     u8 major; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /// Access control flags for config blocks
 | ||||||
|  | enum class AccessFlag : u16 { | ||||||
|  |     UserRead = 1 << 1,    ///< Readable by user applications (cfg:u)
 | ||||||
|  |     SystemWrite = 1 << 2, ///< Writable by system applications and services (cfg:s / cfg:i)
 | ||||||
|  |     SystemRead = 1 << 3,  ///< Readable by system applications and services (cfg:s / cfg:i)
 | ||||||
|  | 
 | ||||||
|  |     // Commonly used combinations for convenience
 | ||||||
|  |     System = SystemRead | SystemWrite, | ||||||
|  |     Global = UserRead | SystemRead | SystemWrite, | ||||||
|  | }; | ||||||
|  | DECLARE_ENUM_FLAG_OPERATORS(AccessFlag); | ||||||
|  | 
 | ||||||
| /// Block header in the config savedata file
 | /// Block header in the config savedata file
 | ||||||
| struct SaveConfigBlockEntry { | struct SaveConfigBlockEntry { | ||||||
|     u32 block_id;       ///< The id of the current block
 |     u32 block_id;       ///< The id of the current block
 | ||||||
|     u32 offset_or_data; ///< This is the absolute offset to the block data if the size is greater
 |     u32 offset_or_data; ///< This is the absolute offset to the block data if the size is greater
 | ||||||
|                         /// than 4 bytes, otherwise it contains the data itself
 |                         /// than 4 bytes, otherwise it contains the data itself
 | ||||||
|     u16 size;           ///< The size of the block
 |     u16 size;           ///< The size of the block
 | ||||||
|     u16 flags;          ///< The flags of the block, possibly used for access control
 |     AccessFlag access_flags; ///< The access control flags of the block
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static constexpr u16 C(const char code[2]) { | static constexpr u16 C(const char code[2]) { | ||||||
|  | @ -155,7 +167,7 @@ public: | ||||||
|         void GetCountryCodeID(Kernel::HLERequestContext& ctx); |         void GetCountryCodeID(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * CFG::SecureInfoGetRegion service function |          * CFG::GetRegion service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : None |          *      1 : None | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|  | @ -163,7 +175,7 @@ public: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *      2 : Region value loaded from SecureInfo offset 0x100 |          *      2 : Region value loaded from SecureInfo offset 0x100 | ||||||
|          */ |          */ | ||||||
|         void SecureInfoGetRegion(Kernel::HLERequestContext& ctx); |         void GetRegion(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * CFG::SecureInfoGetByte101 service function |          * CFG::SecureInfoGetByte101 service function | ||||||
|  | @ -177,7 +189,7 @@ public: | ||||||
|         void SecureInfoGetByte101(Kernel::HLERequestContext& ctx); |         void SecureInfoGetByte101(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * CFG::GenHashConsoleUnique service function |          * CFG::GetTransferableId service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : 20 bit application ID salt |          *      1 : 20 bit application ID salt | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|  | @ -186,10 +198,10 @@ public: | ||||||
|          *      2 : Hash/"ID" lower word |          *      2 : Hash/"ID" lower word | ||||||
|          *      3 : Hash/"ID" upper word |          *      3 : Hash/"ID" upper word | ||||||
|          */ |          */ | ||||||
|         void GenHashConsoleUnique(Kernel::HLERequestContext& ctx); |         void GetTransferableId(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * CFG::GetRegionCanadaUSA service function |          * CFG::IsCoppacsSupported service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : None |          *      1 : None | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|  | @ -197,7 +209,7 @@ public: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *      2 : 1 if the system is a Canada or USA model, 0 otherwise |          *      2 : 1 if the system is a Canada or USA model, 0 otherwise | ||||||
|          */ |          */ | ||||||
|         void GetRegionCanadaUSA(Kernel::HLERequestContext& ctx); |         void IsCoppacsSupported(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * CFG::GetSystemModel service function |          * CFG::GetSystemModel service function | ||||||
|  | @ -220,7 +232,7 @@ public: | ||||||
|         void GetModelNintendo2DS(Kernel::HLERequestContext& ctx); |         void GetModelNintendo2DS(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * CFG::GetConfigInfoBlk2 service function |          * CFG::GetConfig service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x00010082 |          *      0 : 0x00010082 | ||||||
|          *      1 : Size |          *      1 : Size | ||||||
|  | @ -230,10 +242,10 @@ public: | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
|         void GetConfigInfoBlk2(Kernel::HLERequestContext& ctx); |         void GetConfig(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * CFG::GetConfigInfoBlk8 service function |          * CFG::GetSystemConfig service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x04010082 / 0x08010082 |          *      0 : 0x04010082 / 0x08010082 | ||||||
|          *      1 : Size |          *      1 : Size | ||||||
|  | @ -243,10 +255,10 @@ public: | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
|         void GetConfigInfoBlk8(Kernel::HLERequestContext& ctx); |         void GetSystemConfig(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * CFG::SetConfigInfoBlk4 service function |          * CFG::SetSystemConfig service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x04020082 / 0x08020082 |          *      0 : 0x04020082 / 0x08020082 | ||||||
|          *      1 : Block ID |          *      1 : Block ID | ||||||
|  | @ -256,10 +268,10 @@ public: | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *  Note: |          *  Note: | ||||||
|          *      The parameters order is different from GetConfigInfoBlk2/8's, |          *      The parameters order is different from GetConfig/GetSystemConfig's, | ||||||
|          *      where Block ID and Size are switched. |          *      where Block ID and Size are switched. | ||||||
|          */ |          */ | ||||||
|         void SetConfigInfoBlk4(Kernel::HLERequestContext& ctx); |         void SetSystemConfig(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|          * CFG::UpdateConfigNANDSavegame service function |          * CFG::UpdateConfigNANDSavegame service function | ||||||
|  | @ -284,7 +296,7 @@ public: | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     ResultVal<void*> GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 flag); |     ResultVal<void*> GetConfigBlockPointer(u32 block_id, u32 size, AccessFlag accesss_flag); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Reads a block with the specified id and flag from the Config savegame buffer |      * Reads a block with the specified id and flag from the Config savegame buffer | ||||||
|  | @ -293,11 +305,11 @@ private: | ||||||
|      * |      * | ||||||
|      * @param block_id The id of the block we want to read |      * @param block_id The id of the block we want to read | ||||||
|      * @param size The size of the block we want to read |      * @param size The size of the block we want to read | ||||||
|      * @param flag The requested block must have this flag set |      * @param accesss_flag The requested block must have this access flag set | ||||||
|      * @param output A pointer where we will write the read data |      * @param output A pointer where we will write the read data | ||||||
|      * @returns ResultCode indicating the result of the operation, 0 on success |      * @returns ResultCode indicating the result of the operation, 0 on success | ||||||
|      */ |      */ | ||||||
|     ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output); |     ResultCode GetConfigBlock(u32 block_id, u32 size, AccessFlag accesss_flag, void* output); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Reads data from input and writes to a block with the specified id and flag |      * Reads data from input and writes to a block with the specified id and flag | ||||||
|  | @ -306,11 +318,11 @@ private: | ||||||
|      * |      * | ||||||
|      * @param block_id The id of the block we want to write |      * @param block_id The id of the block we want to write | ||||||
|      * @param size The size 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 accesss_flag The target block must have this access flag set | ||||||
|      * @param input A pointer where we will read data and write to Config savegame buffer |      * @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 |      * @returns ResultCode indicating the result of the operation, 0 on success | ||||||
|      */ |      */ | ||||||
|     ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input); |     ResultCode SetConfigBlock(u32 block_id, u32 size, AccessFlag accesss_flag, const void* input); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Creates a block with the specified id and writes the input data to the cfg savegame buffer in |      * Creates a block with the specified id and writes the input data to the cfg savegame buffer in | ||||||
|  | @ -318,11 +330,12 @@ private: | ||||||
|      * |      * | ||||||
|      * @param block_id The id of the block we want to create |      * @param block_id The id of the block we want to create | ||||||
|      * @param size The size of the block we want to create |      * @param size The size of the block we want to create | ||||||
|      * @param flags The flags of the new block |      * @param accesss_flags The access flags of the new block | ||||||
|      * @param data A pointer containing the data we will write to the new block |      * @param data A pointer containing the data we will write to the new block | ||||||
|      * @returns ResultCode indicating the result of the operation, 0 on success |      * @returns ResultCode indicating the result of the operation, 0 on success | ||||||
|      */ |      */ | ||||||
|     ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* data); |     ResultCode CreateConfigBlock(u32 block_id, u16 size, AccessFlag accesss_flags, | ||||||
|  |                                  const void* data); | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Deletes the config savegame file from the filesystem, the buffer in memory is not affected |      * Deletes the config savegame file from the filesystem, the buffer in memory is not affected | ||||||
|  |  | ||||||
|  | @ -13,29 +13,30 @@ CFG_I::CFG_I(std::shared_ptr<Module> cfg) : Module::Interface(std::move(cfg), "c | ||||||
|     static const FunctionInfo functions[] = { |     static const FunctionInfo functions[] = { | ||||||
|         // cfg common
 |         // cfg common
 | ||||||
|         // clang-format off
 |         // clang-format off
 | ||||||
|         {0x0001, &CFG_I::GetConfigInfoBlk2, "GetConfigInfoBlk2"}, |         {0x0001, &CFG_I::GetConfig, "GetConfig"}, | ||||||
|         {0x0002, &CFG_I::SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x0002, &CFG_I::GetRegion, "GetRegion"}, | ||||||
|         {0x0003, &CFG_I::GenHashConsoleUnique, "GenHashConsoleUnique"}, |         {0x0003, &CFG_I::GetTransferableId, "GetTransferableId"}, | ||||||
|         {0x0004, &CFG_I::GetRegionCanadaUSA, "GetRegionCanadaUSA"}, |         {0x0004, &CFG_I::IsCoppacsSupported, "IsCoppacsSupported"}, | ||||||
|         {0x0005, &CFG_I::GetSystemModel, "GetSystemModel"}, |         {0x0005, &CFG_I::GetSystemModel, "GetSystemModel"}, | ||||||
|         {0x0006, &CFG_I::GetModelNintendo2DS, "GetModelNintendo2DS"}, |         {0x0006, &CFG_I::GetModelNintendo2DS, "GetModelNintendo2DS"}, | ||||||
|         {0x0007, nullptr, "WriteToFirstByteCfgSavegame"}, |         {0x0007, nullptr, "WriteToFirstByteCfgSavegame"}, | ||||||
|         {0x0008, nullptr, "GoThroughTable"}, |         {0x0008, nullptr, "TranslateCountryInfo"}, | ||||||
|         {0x0009, &CFG_I::GetCountryCodeString, "GetCountryCodeString"}, |         {0x0009, &CFG_I::GetCountryCodeString, "GetCountryCodeString"}, | ||||||
|         {0x000A, &CFG_I::GetCountryCodeID, "GetCountryCodeID"}, |         {0x000A, &CFG_I::GetCountryCodeID, "GetCountryCodeID"}, | ||||||
|         {0x000B, nullptr, "IsFangateSupported"}, |         {0x000B, nullptr, "IsFangateSupported"}, | ||||||
|         // cfg:i
 |         // cfg:s
 | ||||||
|         {0x0401, &CFG_I::GetConfigInfoBlk8, "GetConfigInfoBlk8"}, |         {0x0401, &CFG_I::GetSystemConfig, "GetSystemConfig"}, | ||||||
|         {0x0402, &CFG_I::SetConfigInfoBlk4, "SetConfigInfoBlk4"}, |         {0x0402, &CFG_I::SetSystemConfig, "SetSystemConfig"}, | ||||||
|         {0x0403, &CFG_I::UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, |         {0x0403, &CFG_I::UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, | ||||||
|         {0x0404, nullptr, "GetLocalFriendCodeSeedData"}, |         {0x0404, nullptr, "GetLocalFriendCodeSeedData"}, | ||||||
|         {0x0405, nullptr, "GetLocalFriendCodeSeed"}, |         {0x0405, nullptr, "GetLocalFriendCodeSeed"}, | ||||||
|         {0x0406, &CFG_I::SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x0406, &CFG_I::GetRegion, "GetRegion"}, | ||||||
|         {0x0407, &CFG_I::SecureInfoGetByte101, "SecureInfoGetByte101"}, |         {0x0407, &CFG_I::SecureInfoGetByte101, "SecureInfoGetByte101"}, | ||||||
|         {0x0408, nullptr, "SecureInfoGetSerialNo"}, |         {0x0408, nullptr, "SecureInfoGetSerialNo"}, | ||||||
|         {0x0409, nullptr, "UpdateConfigBlk00040003"}, |         {0x0409, nullptr, "UpdateConfigBlk00040003"}, | ||||||
|         {0x0801, &CFG_I::GetConfigInfoBlk8, "GetConfigInfoBlk8"}, |         // cfg:i
 | ||||||
|         {0x0802, &CFG_I::SetConfigInfoBlk4, "SetConfigInfoBlk4"}, |         {0x0801, &CFG_I::GetSystemConfig, "GetSystemConfig"}, | ||||||
|  |         {0x0802, &CFG_I::SetSystemConfig, "SetSystemConfig"}, | ||||||
|         {0x0803, &CFG_I::UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, |         {0x0803, &CFG_I::UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, | ||||||
|         {0x0804, nullptr, "CreateConfigInfoBlk"}, |         {0x0804, nullptr, "CreateConfigInfoBlk"}, | ||||||
|         {0x0805, nullptr, "DeleteConfigNANDSavefile"}, |         {0x0805, nullptr, "DeleteConfigNANDSavefile"}, | ||||||
|  | @ -54,7 +55,7 @@ CFG_I::CFG_I(std::shared_ptr<Module> cfg) : Module::Interface(std::move(cfg), "c | ||||||
|         {0x0813, nullptr, "VerifySigSecureInfo"}, |         {0x0813, nullptr, "VerifySigSecureInfo"}, | ||||||
|         {0x0814, nullptr, "SecureInfoGetData"}, |         {0x0814, nullptr, "SecureInfoGetData"}, | ||||||
|         {0x0815, nullptr, "SecureInfoGetSignature"}, |         {0x0815, nullptr, "SecureInfoGetSignature"}, | ||||||
|         {0x0816, &CFG_I::SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x0816, &CFG_I::GetRegion, "GetRegion"}, | ||||||
|         {0x0817, &CFG_I::SecureInfoGetByte101, "SecureInfoGetByte101"}, |         {0x0817, &CFG_I::SecureInfoGetByte101, "SecureInfoGetByte101"}, | ||||||
|         {0x0818, nullptr, "SecureInfoGetSerialNo"}, |         {0x0818, nullptr, "SecureInfoGetSerialNo"}, | ||||||
|         // clang-format on
 |         // clang-format on
 | ||||||
|  |  | ||||||
|  | @ -13,24 +13,24 @@ CFG_S::CFG_S(std::shared_ptr<Module> cfg) : Module::Interface(std::move(cfg), "c | ||||||
|     static const FunctionInfo functions[] = { |     static const FunctionInfo functions[] = { | ||||||
|         // cfg common
 |         // cfg common
 | ||||||
|         // clang-format off
 |         // clang-format off
 | ||||||
|         {0x0001, &CFG_S::GetConfigInfoBlk2, "GetConfigInfoBlk2"}, |         {0x0001, &CFG_S::GetConfig, "GetConfig"}, | ||||||
|         {0x0002, &CFG_S::SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x0002, &CFG_S::GetRegion, "GetRegion"}, | ||||||
|         {0x0003, &CFG_S::GenHashConsoleUnique, "GenHashConsoleUnique"}, |         {0x0003, &CFG_S::GetTransferableId, "GetTransferableId"}, | ||||||
|         {0x0004, &CFG_S::GetRegionCanadaUSA, "GetRegionCanadaUSA"}, |         {0x0004, &CFG_S::IsCoppacsSupported, "IsCoppacsSupported"}, | ||||||
|         {0x0005, &CFG_S::GetSystemModel, "GetSystemModel"}, |         {0x0005, &CFG_S::GetSystemModel, "GetSystemModel"}, | ||||||
|         {0x0006, &CFG_S::GetModelNintendo2DS, "GetModelNintendo2DS"}, |         {0x0006, &CFG_S::GetModelNintendo2DS, "GetModelNintendo2DS"}, | ||||||
|         {0x0007, nullptr, "WriteToFirstByteCfgSavegame"}, |         {0x0007, nullptr, "WriteToFirstByteCfgSavegame"}, | ||||||
|         {0x0008, nullptr, "GoThroughTable"}, |         {0x0008, nullptr, "TranslateCountryInfo"}, | ||||||
|         {0x0009, &CFG_S::GetCountryCodeString, "GetCountryCodeString"}, |         {0x0009, &CFG_S::GetCountryCodeString, "GetCountryCodeString"}, | ||||||
|         {0x000A, &CFG_S::GetCountryCodeID, "GetCountryCodeID"}, |         {0x000A, &CFG_S::GetCountryCodeID, "GetCountryCodeID"}, | ||||||
|         {0x000B, nullptr, "IsFangateSupported"}, |         {0x000B, nullptr, "IsFangateSupported"}, | ||||||
|         // cfg:s
 |         // cfg:s
 | ||||||
|         {0x0401, &CFG_S::GetConfigInfoBlk8, "GetConfigInfoBlk8"}, |         {0x0401, &CFG_S::GetSystemConfig, "GetSystemConfig"}, | ||||||
|         {0x0402, &CFG_S::SetConfigInfoBlk4, "SetConfigInfoBlk4"}, |         {0x0402, &CFG_S::SetSystemConfig, "SetSystemConfig"}, | ||||||
|         {0x0403, &CFG_S::UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, |         {0x0403, &CFG_S::UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, | ||||||
|         {0x0404, nullptr, "GetLocalFriendCodeSeedData"}, |         {0x0404, nullptr, "GetLocalFriendCodeSeedData"}, | ||||||
|         {0x0405, nullptr, "GetLocalFriendCodeSeed"}, |         {0x0405, nullptr, "GetLocalFriendCodeSeed"}, | ||||||
|         {0x0406, &CFG_S::SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x0406, &CFG_S::GetRegion, "GetRegion"}, | ||||||
|         {0x0407, &CFG_S::SecureInfoGetByte101, "SecureInfoGetByte101"}, |         {0x0407, &CFG_S::SecureInfoGetByte101, "SecureInfoGetByte101"}, | ||||||
|         {0x0408, nullptr, "SecureInfoGetSerialNo"}, |         {0x0408, nullptr, "SecureInfoGetSerialNo"}, | ||||||
|         {0x0409, nullptr, "UpdateConfigBlk00040003"}, |         {0x0409, nullptr, "UpdateConfigBlk00040003"}, | ||||||
|  |  | ||||||
|  | @ -13,14 +13,14 @@ CFG_U::CFG_U(std::shared_ptr<Module> cfg) : Module::Interface(std::move(cfg), "c | ||||||
|     static const FunctionInfo functions[] = { |     static const FunctionInfo functions[] = { | ||||||
|         // cfg common
 |         // cfg common
 | ||||||
|         // clang-format off
 |         // clang-format off
 | ||||||
|         {0x0001, &CFG_U::GetConfigInfoBlk2, "GetConfigInfoBlk2"}, |         {0x0001, &CFG_U::GetConfig, "GetConfig"}, | ||||||
|         {0x0002, &CFG_U::SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x0002, &CFG_U::GetRegion, "GetRegion"}, | ||||||
|         {0x0003, &CFG_U::GenHashConsoleUnique, "GenHashConsoleUnique"}, |         {0x0003, &CFG_U::GetTransferableId, "GetTransferableId"}, | ||||||
|         {0x0004, &CFG_U::GetRegionCanadaUSA, "GetRegionCanadaUSA"}, |         {0x0004, &CFG_U::IsCoppacsSupported, "IsCoppacsSupported"}, | ||||||
|         {0x0005, &CFG_U::GetSystemModel, "GetSystemModel"}, |         {0x0005, &CFG_U::GetSystemModel, "GetSystemModel"}, | ||||||
|         {0x0006, &CFG_U::GetModelNintendo2DS, "GetModelNintendo2DS"}, |         {0x0006, &CFG_U::GetModelNintendo2DS, "GetModelNintendo2DS"}, | ||||||
|         {0x0007, nullptr, "WriteToFirstByteCfgSavegame"}, |         {0x0007, nullptr, "WriteToFirstByteCfgSavegame"}, | ||||||
|         {0x0008, nullptr, "GoThroughTable"}, |         {0x0008, nullptr, "TranslateCountryInfo"}, | ||||||
|         {0x0009, &CFG_U::GetCountryCodeString, "GetCountryCodeString"}, |         {0x0009, &CFG_U::GetCountryCodeString, "GetCountryCodeString"}, | ||||||
|         {0x000A, &CFG_U::GetCountryCodeID, "GetCountryCodeID"}, |         {0x000A, &CFG_U::GetCountryCodeID, "GetCountryCodeID"}, | ||||||
|         {0x000B, nullptr, "IsFangateSupported"}, |         {0x000B, nullptr, "IsFangateSupported"}, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue