mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Service/CFG: convert to ServiceFramework
This commit is contained in:
		
							parent
							
								
									5dd8ac99e3
								
							
						
					
					
						commit
						b179b86f14
					
				
					 16 changed files with 554 additions and 550 deletions
				
			
		|  | @ -42,22 +42,16 @@ void ConfigureSystem::setConfiguration() { | ||||||
|     enabled = !Core::System::GetInstance().IsPoweredOn(); |     enabled = !Core::System::GetInstance().IsPoweredOn(); | ||||||
| 
 | 
 | ||||||
|     if (!enabled) { |     if (!enabled) { | ||||||
|  |         cfg = Service::CFG::GetCurrentModule(); | ||||||
|         ReadSystemSettings(); |         ReadSystemSettings(); | ||||||
|         ui->group_system_settings->setEnabled(false); |         ui->group_system_settings->setEnabled(false); | ||||||
|     } else { |     } else { | ||||||
|         // This tab is enabled only when game is not running (i.e. all service are not initialized).
 |         // This tab is enabled only when game is not running (i.e. all service are not initialized).
 | ||||||
|         // Temporarily register archive types and load the config savegame file to memory.
 |         // Temporarily register archive types and load the config savegame file to memory.
 | ||||||
|         Service::FS::RegisterArchiveTypes(); |         Service::FS::RegisterArchiveTypes(); | ||||||
|         ResultCode result = Service::CFG::LoadConfigNANDSaveFile(); |         cfg = std::make_shared<Service::CFG::Module>(); | ||||||
|         Service::FS::UnregisterArchiveTypes(); |         Service::FS::UnregisterArchiveTypes(); | ||||||
| 
 | 
 | ||||||
|         if (result.IsError()) { |  | ||||||
|             ui->label_disable_info->setText(tr("Failed to load system settings data.")); |  | ||||||
|             ui->group_system_settings->setEnabled(false); |  | ||||||
|             enabled = false; |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         ReadSystemSettings(); |         ReadSystemSettings(); | ||||||
|         ui->label_disable_info->hide(); |         ui->label_disable_info->hide(); | ||||||
|     } |     } | ||||||
|  | @ -65,14 +59,14 @@ void ConfigureSystem::setConfiguration() { | ||||||
| 
 | 
 | ||||||
| void ConfigureSystem::ReadSystemSettings() { | void ConfigureSystem::ReadSystemSettings() { | ||||||
|     // set username
 |     // set username
 | ||||||
|     username = Service::CFG::GetUsername(); |     username = cfg->GetUsername(); | ||||||
|     // TODO(wwylele): Use this when we move to Qt 5.5
 |     // TODO(wwylele): Use this when we move to Qt 5.5
 | ||||||
|     // ui->edit_username->setText(QString::fromStdU16String(username));
 |     // ui->edit_username->setText(QString::fromStdU16String(username));
 | ||||||
|     ui->edit_username->setText( |     ui->edit_username->setText( | ||||||
|         QString::fromUtf16(reinterpret_cast<const ushort*>(username.data()))); |         QString::fromUtf16(reinterpret_cast<const ushort*>(username.data()))); | ||||||
| 
 | 
 | ||||||
|     // set birthday
 |     // set birthday
 | ||||||
|     std::tie(birthmonth, birthday) = Service::CFG::GetBirthday(); |     std::tie(birthmonth, birthday) = cfg->GetBirthday(); | ||||||
|     ui->combo_birthmonth->setCurrentIndex(birthmonth - 1); |     ui->combo_birthmonth->setCurrentIndex(birthmonth - 1); | ||||||
|     updateBirthdayComboBox( |     updateBirthdayComboBox( | ||||||
|         birthmonth - |         birthmonth - | ||||||
|  | @ -80,15 +74,15 @@ void ConfigureSystem::ReadSystemSettings() { | ||||||
|     ui->combo_birthday->setCurrentIndex(birthday - 1); |     ui->combo_birthday->setCurrentIndex(birthday - 1); | ||||||
| 
 | 
 | ||||||
|     // set system language
 |     // set system language
 | ||||||
|     language_index = Service::CFG::GetSystemLanguage(); |     language_index = cfg->GetSystemLanguage(); | ||||||
|     ui->combo_language->setCurrentIndex(language_index); |     ui->combo_language->setCurrentIndex(language_index); | ||||||
| 
 | 
 | ||||||
|     // set sound output mode
 |     // set sound output mode
 | ||||||
|     sound_index = Service::CFG::GetSoundOutputMode(); |     sound_index = cfg->GetSoundOutputMode(); | ||||||
|     ui->combo_sound->setCurrentIndex(sound_index); |     ui->combo_sound->setCurrentIndex(sound_index); | ||||||
| 
 | 
 | ||||||
|     // set the console id
 |     // set the console id
 | ||||||
|     u64 console_id = Service::CFG::GetConsoleUniqueId(); |     u64 console_id = cfg->GetConsoleUniqueId(); | ||||||
|     ui->label_console_id->setText( |     ui->label_console_id->setText( | ||||||
|         tr("Console ID: 0x%1").arg(QString::number(console_id, 16).toUpper())); |         tr("Console ID: 0x%1").arg(QString::number(console_id, 16).toUpper())); | ||||||
| } | } | ||||||
|  | @ -105,7 +99,7 @@ void ConfigureSystem::applyConfiguration() { | ||||||
|     std::u16string new_username( |     std::u16string new_username( | ||||||
|         reinterpret_cast<const char16_t*>(ui->edit_username->text().utf16())); |         reinterpret_cast<const char16_t*>(ui->edit_username->text().utf16())); | ||||||
|     if (new_username != username) { |     if (new_username != username) { | ||||||
|         Service::CFG::SetUsername(new_username); |         cfg->SetUsername(new_username); | ||||||
|         modified = true; |         modified = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -113,27 +107,27 @@ void ConfigureSystem::applyConfiguration() { | ||||||
|     int new_birthmonth = ui->combo_birthmonth->currentIndex() + 1; |     int new_birthmonth = ui->combo_birthmonth->currentIndex() + 1; | ||||||
|     int new_birthday = ui->combo_birthday->currentIndex() + 1; |     int new_birthday = ui->combo_birthday->currentIndex() + 1; | ||||||
|     if (birthmonth != new_birthmonth || birthday != new_birthday) { |     if (birthmonth != new_birthmonth || birthday != new_birthday) { | ||||||
|         Service::CFG::SetBirthday(new_birthmonth, new_birthday); |         cfg->SetBirthday(new_birthmonth, new_birthday); | ||||||
|         modified = true; |         modified = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // apply language
 |     // apply language
 | ||||||
|     int new_language = ui->combo_language->currentIndex(); |     int new_language = ui->combo_language->currentIndex(); | ||||||
|     if (language_index != new_language) { |     if (language_index != new_language) { | ||||||
|         Service::CFG::SetSystemLanguage(static_cast<Service::CFG::SystemLanguage>(new_language)); |         cfg->SetSystemLanguage(static_cast<Service::CFG::SystemLanguage>(new_language)); | ||||||
|         modified = true; |         modified = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // apply sound
 |     // apply sound
 | ||||||
|     int new_sound = ui->combo_sound->currentIndex(); |     int new_sound = ui->combo_sound->currentIndex(); | ||||||
|     if (sound_index != new_sound) { |     if (sound_index != new_sound) { | ||||||
|         Service::CFG::SetSoundOutputMode(static_cast<Service::CFG::SoundOutputMode>(new_sound)); |         cfg->SetSoundOutputMode(static_cast<Service::CFG::SoundOutputMode>(new_sound)); | ||||||
|         modified = true; |         modified = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // update the config savegame if any item is modified.
 |     // update the config savegame if any item is modified.
 | ||||||
|     if (modified) |     if (modified) | ||||||
|         Service::CFG::UpdateConfigNANDSavegame(); |         cfg->UpdateConfigNANDSavegame(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) { | void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) { | ||||||
|  | @ -173,9 +167,9 @@ void ConfigureSystem::refreshConsoleID() { | ||||||
|         return; |         return; | ||||||
|     u32 random_number; |     u32 random_number; | ||||||
|     u64 console_id; |     u64 console_id; | ||||||
|     Service::CFG::GenerateConsoleUniqueId(random_number, console_id); |     cfg->GenerateConsoleUniqueId(random_number, console_id); | ||||||
|     Service::CFG::SetConsoleUniqueId(random_number, console_id); |     cfg->SetConsoleUniqueId(random_number, console_id); | ||||||
|     Service::CFG::UpdateConfigNANDSavegame(); |     cfg->UpdateConfigNANDSavegame(); | ||||||
|     ui->label_console_id->setText("Console ID: 0x" + QString::number(console_id, 16).toUpper()); |     ui->label_console_id->setText("Console ID: 0x" + QString::number(console_id, 16).toUpper()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,6 +11,12 @@ namespace Ui { | ||||||
| class ConfigureSystem; | class ConfigureSystem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | namespace Service { | ||||||
|  | namespace CFG { | ||||||
|  | class Module; | ||||||
|  | } // namespace CFG
 | ||||||
|  | } // namespace Service
 | ||||||
|  | 
 | ||||||
| class ConfigureSystem : public QWidget { | class ConfigureSystem : public QWidget { | ||||||
|     Q_OBJECT |     Q_OBJECT | ||||||
| 
 | 
 | ||||||
|  | @ -32,6 +38,7 @@ private: | ||||||
|     std::unique_ptr<Ui::ConfigureSystem> ui; |     std::unique_ptr<Ui::ConfigureSystem> ui; | ||||||
|     bool enabled; |     bool enabled; | ||||||
| 
 | 
 | ||||||
|  |     std::shared_ptr<Service::CFG::Module> cfg; | ||||||
|     std::u16string username; |     std::u16string username; | ||||||
|     int birthmonth, birthday; |     int birthmonth, birthday; | ||||||
|     int language_index; |     int language_index; | ||||||
|  |  | ||||||
|  | @ -79,7 +79,7 @@ static u64 GetTitleIdForApplet(AppletId id) { | ||||||
| 
 | 
 | ||||||
|     ASSERT_MSG(itr != applet_titleids.end(), "Unknown applet id 0x%03X", static_cast<u32>(id)); |     ASSERT_MSG(itr != applet_titleids.end(), "Unknown applet id 0x%03X", static_cast<u32>(id)); | ||||||
| 
 | 
 | ||||||
|     return itr->title_ids[CFG::GetRegionValue()]; |     return itr->title_ids[CFG::GetCurrentModule()->GetRegionValue()]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| AppletManager::AppletSlotData* AppletManager::GetAppletSlotData(AppletId id) { | AppletManager::AppletSlotData* AppletManager::GetAppletSlotData(AppletId id) { | ||||||
|  |  | ||||||
|  | @ -103,7 +103,7 @@ static u32 DecompressLZ11(const u8* in, u8* out) { | ||||||
| 
 | 
 | ||||||
| bool Module::LoadSharedFont() { | bool Module::LoadSharedFont() { | ||||||
|     u8 font_region_code; |     u8 font_region_code; | ||||||
|     switch (CFG::GetRegionValue()) { |     switch (CFG::GetCurrentModule()->GetRegionValue()) { | ||||||
|     case 4: // CHN
 |     case 4: // CHN
 | ||||||
|         font_region_code = 2; |         font_region_code = 2; | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|  | @ -3,7 +3,6 @@ | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <array> |  | ||||||
| #include <cryptopp/osrng.h> | #include <cryptopp/osrng.h> | ||||||
| #include <cryptopp/sha.h> | #include <cryptopp/sha.h> | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
|  | @ -13,7 +12,6 @@ | ||||||
| #include "core/file_sys/archive_systemsavedata.h" | #include "core/file_sys/archive_systemsavedata.h" | ||||||
| #include "core/file_sys/errors.h" | #include "core/file_sys/errors.h" | ||||||
| #include "core/file_sys/file_backend.h" | #include "core/file_sys/file_backend.h" | ||||||
| #include "core/hle/ipc.h" |  | ||||||
| #include "core/hle/ipc_helpers.h" | #include "core/hle/ipc_helpers.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
| #include "core/hle/service/cfg/cfg.h" | #include "core/hle/service/cfg/cfg.h" | ||||||
|  | @ -21,9 +19,6 @@ | ||||||
| #include "core/hle/service/cfg/cfg_nor.h" | #include "core/hle/service/cfg/cfg_nor.h" | ||||||
| #include "core/hle/service/cfg/cfg_s.h" | #include "core/hle/service/cfg/cfg_s.h" | ||||||
| #include "core/hle/service/cfg/cfg_u.h" | #include "core/hle/service/cfg/cfg_u.h" | ||||||
| #include "core/hle/service/fs/archive.h" |  | ||||||
| #include "core/hle/service/service.h" |  | ||||||
| #include "core/memory.h" |  | ||||||
| #include "core/settings.h" | #include "core/settings.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
|  | @ -113,35 +108,44 @@ static const std::array<float, 8> STEREO_CAMERA_SETTINGS = { | ||||||
| static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, | static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, | ||||||
|               "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes"); |               "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes"); | ||||||
| 
 | 
 | ||||||
| static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; |  | ||||||
| static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; |  | ||||||
| 
 |  | ||||||
| static Service::FS::ArchiveHandle cfg_system_save_data_archive; |  | ||||||
| static const std::vector<u8> cfg_system_savedata_id = { | static const std::vector<u8> cfg_system_savedata_id = { | ||||||
|     0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00, |     0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static u32 preferred_region_code = 0; | static std::weak_ptr<Module> current_cfg; | ||||||
| 
 | 
 | ||||||
| void GetCountryCodeString(Service::Interface* self) { | std::shared_ptr<Module> GetCurrentModule() { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     auto cfg = current_cfg.lock(); | ||||||
|     u32 country_code_id = cmd_buff[1]; |     ASSERT_MSG(cfg, "No CFG module running!"); | ||||||
|  |     return cfg; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | Module::Interface::Interface(std::shared_ptr<Module> cfg, const char* name, u32 max_session) | ||||||
|  |     : ServiceFramework(name, max_session), cfg(std::move(cfg)) {} | ||||||
|  | 
 | ||||||
|  | Module::Interface::~Interface() = default; | ||||||
|  | 
 | ||||||
|  | void Module::Interface::GetCountryCodeString(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp(ctx, 0x09, 1, 0); | ||||||
|  |     u16 country_code_id = rp.Pop<u16>(); | ||||||
|  | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
|     if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) { |     if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) { | ||||||
|         LOG_ERROR(Service_CFG, "requested country code id=%d is invalid", country_code_id); |         LOG_ERROR(Service_CFG, "requested country code id=%d is invalid", country_code_id); | ||||||
|         cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, |         rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Config, | ||||||
|                                  ErrorSummary::WrongArgument, ErrorLevel::Permanent) |                            ErrorSummary::WrongArgument, ErrorLevel::Permanent)); | ||||||
|                           .raw; |         rb.Skip(1, false); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     cmd_buff[1] = 0; |     rb.Push(RESULT_SUCCESS); | ||||||
|     cmd_buff[2] = country_codes[country_code_id]; |     // the real CFG service copies only three bytes (including the null-terminator) here
 | ||||||
|  |     rb.Push<u32>(country_codes[country_code_id]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GetCountryCodeID(Service::Interface* self) { | void Module::Interface::GetCountryCodeID(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x0A, 1, 0); | ||||||
|     u16 country_code = static_cast<u16>(cmd_buff[1]); |     u16 country_code = rp.Pop<u16>(); | ||||||
|     u16 country_code_id = 0; |     u16 country_code_id = 0; | ||||||
| 
 | 
 | ||||||
|     // The following algorithm will fail if the first country code isn't 0.
 |     // The following algorithm will fail if the first country code isn't 0.
 | ||||||
|  | @ -154,42 +158,43 @@ void GetCountryCodeID(Service::Interface* self) { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
|     if (0 == country_code_id) { |     if (0 == country_code_id) { | ||||||
|         LOG_ERROR(Service_CFG, "requested country code name=%c%c is invalid", country_code & 0xff, |         LOG_ERROR(Service_CFG, "requested country code name=%c%c is invalid", country_code & 0xff, | ||||||
|                   country_code >> 8); |                   country_code >> 8); | ||||||
|         cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, |         rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Config, | ||||||
|                                  ErrorSummary::WrongArgument, ErrorLevel::Permanent) |                            ErrorSummary::WrongArgument, ErrorLevel::Permanent)); | ||||||
|                           .raw; |         rb.Push<u16>(0x00FF); | ||||||
|         cmd_buff[2] = 0xFFFF; |  | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     cmd_buff[1] = 0; |     rb.Push(RESULT_SUCCESS); | ||||||
|     cmd_buff[2] = country_code_id; |     rb.Push<u16>(country_code_id); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u32 GetRegionValue() { | u32 Module::GetRegionValue() { | ||||||
|     if (Settings::values.region_value == Settings::REGION_VALUE_AUTO_SELECT) |     if (Settings::values.region_value == Settings::REGION_VALUE_AUTO_SELECT) | ||||||
|         return preferred_region_code; |         return preferred_region_code; | ||||||
| 
 | 
 | ||||||
|     return Settings::values.region_value; |     return Settings::values.region_value; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SecureInfoGetRegion(Service::Interface* self) { | void Module::Interface::SecureInfoGetRegion(Kernel::HLERequestContext& ctx, u16 id) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, id, 0, 0); | ||||||
| 
 | 
 | ||||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
|     cmd_buff[2] = GetRegionValue(); |     rb.Push(RESULT_SUCCESS); | ||||||
|  |     rb.Push<u8>(cfg->GetRegionValue()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GenHashConsoleUnique(Service::Interface* self) { | void Module::Interface::GenHashConsoleUnique(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x03, 1, 0); |     IPC::RequestParser rp(ctx, 0x03, 1, 0); | ||||||
|     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 = GetConfigInfoBlock(ConsoleUniqueID2BlockID, 8, 2, buffer.data()); |     const ResultCode result = cfg->GetConfigInfoBlock(ConsoleUniqueID2BlockID, 8, 2, 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)); | ||||||
|  | @ -208,105 +213,94 @@ void GenHashConsoleUnique(Service::Interface* self) { | ||||||
|     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 GetRegionCanadaUSA(Service::Interface* self) { | void Module::Interface::GetRegionCanadaUSA(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x04, 0, 0); | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
| 
 | 
 | ||||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; |     rb.Push(RESULT_SUCCESS); | ||||||
| 
 | 
 | ||||||
|     u8 canada_or_usa = 1; |     u8 canada_or_usa = 1; | ||||||
|     if (canada_or_usa == GetRegionValue()) { |     if (canada_or_usa == cfg->GetRegionValue()) { | ||||||
|         cmd_buff[2] = 1; |         rb.Push(true); | ||||||
|     } else { |     } else { | ||||||
|         cmd_buff[2] = 0; |         rb.Push(false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GetSystemModel(Service::Interface* self) { | void Module::Interface::GetSystemModel(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x05, 0, 0); | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
|     u32 data; |     u32 data; | ||||||
| 
 | 
 | ||||||
|     // TODO(Subv): Find out the correct error codes
 |     // TODO(Subv): Find out the correct error codes
 | ||||||
|     cmd_buff[1] = |     rb.Push(cfg->GetConfigInfoBlock(ConsoleModelBlockID, 4, 0x8, reinterpret_cast<u8*>(&data))); | ||||||
|         Service::CFG::GetConfigInfoBlock(ConsoleModelBlockID, 4, 0x8, reinterpret_cast<u8*>(&data)) |     rb.Push<u8>(data & 0xFF); | ||||||
|             .raw; |  | ||||||
|     cmd_buff[2] = data & 0xFF; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GetModelNintendo2DS(Service::Interface* self) { | void Module::Interface::GetModelNintendo2DS(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x06, 0, 0); | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||||
|     u32 data; |     u32 data; | ||||||
| 
 | 
 | ||||||
|     // TODO(Subv): Find out the correct error codes
 |     // TODO(Subv): Find out the correct error codes
 | ||||||
|     cmd_buff[1] = |     rb.Push(cfg->GetConfigInfoBlock(ConsoleModelBlockID, 4, 0x8, reinterpret_cast<u8*>(&data))); | ||||||
|         Service::CFG::GetConfigInfoBlock(ConsoleModelBlockID, 4, 0x8, reinterpret_cast<u8*>(&data)) |  | ||||||
|             .raw; |  | ||||||
| 
 |  | ||||||
|     u8 model = data & 0xFF; |     u8 model = data & 0xFF; | ||||||
|     if (model == Service::CFG::NINTENDO_2DS) |     rb.Push(model != Service::CFG::NINTENDO_2DS); | ||||||
|         cmd_buff[2] = 0; |  | ||||||
|     else |  | ||||||
|         cmd_buff[2] = 1; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GetConfigInfoBlk2(Service::Interface* self) { | void Module::Interface::GetConfigInfoBlk2(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x01, 2, 2); | ||||||
|     u32 size = cmd_buff[1]; |     u32 size = rp.Pop<u32>(); | ||||||
|     u32 block_id = cmd_buff[2]; |     u32 block_id = rp.Pop<u32>(); | ||||||
|     VAddr data_pointer = cmd_buff[4]; |     auto& buffer = rp.PopMappedBuffer(); | ||||||
| 
 | 
 | ||||||
|     if (!Memory::IsValidVirtualAddress(data_pointer)) { |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|         cmd_buff[1] = -1; // TODO(Subv): Find the right error code
 |     std::vector<u8> data(size); | ||||||
|         return; |     rb.Push(cfg->GetConfigInfoBlock(block_id, size, 0x2, data.data())); | ||||||
|     } |     buffer.Write(data.data(), 0, data.size()); | ||||||
|  |     rb.PushMappedBuffer(buffer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Module::Interface::GetConfigInfoBlk8(Kernel::HLERequestContext& ctx, u16 id) { | ||||||
|  |     IPC::RequestParser rp(ctx, id, 2, 2); | ||||||
|  |     u32 size = rp.Pop<u32>(); | ||||||
|  |     u32 block_id = rp.Pop<u32>(); | ||||||
|  |     auto& buffer = rp.PopMappedBuffer(); | ||||||
|  | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |     std::vector<u8> data(size); | ||||||
|  |     rb.Push(cfg->GetConfigInfoBlock(block_id, size, 0x8, data.data())); | ||||||
|  |     buffer.Write(data.data(), 0, data.size()); | ||||||
|  |     rb.PushMappedBuffer(buffer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Module::Interface::SetConfigInfoBlk4(Kernel::HLERequestContext& ctx, u16 id) { | ||||||
|  |     IPC::RequestParser rp(ctx, id, 2, 2); | ||||||
|  |     u32 block_id = rp.Pop<u32>(); | ||||||
|  |     u32 size = rp.Pop<u32>(); | ||||||
|  |     auto& buffer = rp.PopMappedBuffer(); | ||||||
| 
 | 
 | ||||||
|     std::vector<u8> data(size); |     std::vector<u8> data(size); | ||||||
|     cmd_buff[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x2, data.data()).raw; |     buffer.Read(data.data(), 0, data.size()); | ||||||
|     Memory::WriteBlock(data_pointer, data.data(), data.size()); | 
 | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||||
|  |     rb.Push(cfg->SetConfigInfoBlock(block_id, size, 0x4, data.data())); | ||||||
|  |     rb.PushMappedBuffer(buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GetConfigInfoBlk8(Service::Interface* self) { | void Module::Interface::UpdateConfigNANDSavegame(Kernel::HLERequestContext& ctx, u16 id) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, id, 0, 0); | ||||||
|     u32 size = cmd_buff[1]; |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|     u32 block_id = cmd_buff[2]; |     rb.Push(cfg->UpdateConfigNANDSavegame()); | ||||||
|     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); |  | ||||||
|     cmd_buff[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x8, data.data()).raw; |  | ||||||
|     Memory::WriteBlock(data_pointer, data.data(), data.size()); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SetConfigInfoBlk4(Service::Interface* self) { | void Module::Interface::FormatConfig(Kernel::HLERequestContext& ctx) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |     IPC::RequestParser rp(ctx, 0x0806, 0, 0); | ||||||
|     u32 block_id = cmd_buff[1]; |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|     u32 size = cmd_buff[2]; |     rb.Push(cfg->FormatConfig()); | ||||||
|     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) { | ResultVal<void*> Module::GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 flag) { | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |  | ||||||
|     cmd_buff[1] = Service::CFG::UpdateConfigNANDSavegame().raw; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void FormatConfig(Service::Interface* self) { |  | ||||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); |  | ||||||
|     cmd_buff[1] = Service::CFG::FormatConfig().raw; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static ResultVal<void*> GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 flag) { |  | ||||||
|     // Read the header
 |     // Read the header
 | ||||||
|     SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); |     SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | ||||||
| 
 | 
 | ||||||
|  | @ -346,7 +340,7 @@ static ResultVal<void*> GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 fl | ||||||
|     return MakeResult<void*>(pointer); |     return MakeResult<void*>(pointer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output) { | ResultCode Module::GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output) { | ||||||
|     void* pointer; |     void* pointer; | ||||||
|     CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); |     CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); | ||||||
|     memcpy(output, pointer, size); |     memcpy(output, pointer, size); | ||||||
|  | @ -354,14 +348,14 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output) { | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input) { | ResultCode Module::SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input) { | ||||||
|     void* pointer; |     void* pointer; | ||||||
|     CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); |     CASCADE_RESULT(pointer, GetConfigInfoBlockPointer(block_id, size, flag)); | ||||||
|     memcpy(pointer, input, size); |     memcpy(pointer, input, size); | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* data) { | ResultCode Module::CreateConfigInfoBlk(u32 block_id, u16 size, u16 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
 | ||||||
|  | @ -393,12 +387,12 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* da | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode DeleteConfigNANDSaveFile() { | ResultCode Module::DeleteConfigNANDSaveFile() { | ||||||
|     FileSys::Path path("/config"); |     FileSys::Path path("/config"); | ||||||
|     return Service::FS::DeleteFileFromArchive(cfg_system_save_data_archive, path); |     return Service::FS::DeleteFileFromArchive(cfg_system_save_data_archive, path); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode UpdateConfigNANDSavegame() { | ResultCode Module::UpdateConfigNANDSavegame() { | ||||||
|     FileSys::Mode mode = {}; |     FileSys::Mode mode = {}; | ||||||
|     mode.write_flag.Assign(1); |     mode.write_flag.Assign(1); | ||||||
|     mode.create_flag.Assign(1); |     mode.create_flag.Assign(1); | ||||||
|  | @ -414,7 +408,7 @@ ResultCode UpdateConfigNANDSavegame() { | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode FormatConfig() { | ResultCode Module::FormatConfig() { | ||||||
|     ResultCode res = DeleteConfigNANDSaveFile(); |     ResultCode res = DeleteConfigNANDSaveFile(); | ||||||
|     // The delete command fails if the file doesn't exist, so we have to check that too
 |     // The delete command fails if the file doesn't exist, so we have to check that too
 | ||||||
|     if (!res.IsSuccess() && res != FileSys::ERROR_FILE_NOT_FOUND) { |     if (!res.IsSuccess() && res != FileSys::ERROR_FILE_NOT_FOUND) { | ||||||
|  | @ -533,7 +527,7 @@ ResultCode FormatConfig() { | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode LoadConfigNANDSaveFile() { | ResultCode Module::LoadConfigNANDSaveFile() { | ||||||
|     // Open the SystemSaveData archive 0x00010017
 |     // Open the SystemSaveData archive 0x00010017
 | ||||||
|     FileSys::Path archive_path(cfg_system_savedata_id); |     FileSys::Path archive_path(cfg_system_savedata_id); | ||||||
|     auto archive_result = |     auto archive_result = | ||||||
|  | @ -570,18 +564,11 @@ ResultCode LoadConfigNANDSaveFile() { | ||||||
|     return FormatConfig(); |     return FormatConfig(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Init() { | Module::Module() { | ||||||
|     AddService(new CFG_I); |  | ||||||
|     AddService(new CFG_NOR); |  | ||||||
|     AddService(new CFG_S); |  | ||||||
|     AddService(new CFG_U); |  | ||||||
| 
 |  | ||||||
|     LoadConfigNANDSaveFile(); |     LoadConfigNANDSaveFile(); | ||||||
| 
 |  | ||||||
|     preferred_region_code = 0; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Shutdown() {} | Module::~Module() = default; | ||||||
| 
 | 
 | ||||||
| /// Checks if the language is available in the chosen region, and returns a proper one
 | /// Checks if the language is available in the chosen region, and returns a proper one
 | ||||||
| static SystemLanguage AdjustLanguageInfoBlock(u32 region, SystemLanguage language) { | static SystemLanguage AdjustLanguageInfoBlock(u32 region, SystemLanguage language) { | ||||||
|  | @ -610,7 +597,7 @@ static SystemLanguage AdjustLanguageInfoBlock(u32 region, SystemLanguage languag | ||||||
|     return language; |     return language; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SetPreferredRegionCode(u32 region_code) { | void Module::SetPreferredRegionCode(u32 region_code) { | ||||||
|     preferred_region_code = region_code; |     preferred_region_code = region_code; | ||||||
|     LOG_INFO(Service_CFG, "Preferred region code set to %u", preferred_region_code); |     LOG_INFO(Service_CFG, "Preferred region code set to %u", preferred_region_code); | ||||||
| 
 | 
 | ||||||
|  | @ -626,14 +613,14 @@ void SetPreferredRegionCode(u32 region_code) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SetUsername(const std::u16string& name) { | 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); |     SetConfigInfoBlock(UsernameBlockID, sizeof(block), 4, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::u16string GetUsername() { | std::u16string Module::GetUsername() { | ||||||
|     UsernameBlock block; |     UsernameBlock block; | ||||||
|     GetConfigInfoBlock(UsernameBlockID, sizeof(block), 8, &block); |     GetConfigInfoBlock(UsernameBlockID, sizeof(block), 8, &block); | ||||||
| 
 | 
 | ||||||
|  | @ -646,40 +633,40 @@ std::u16string GetUsername() { | ||||||
|     return username; |     return username; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void 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); |     SetConfigInfoBlock(BirthdayBlockID, sizeof(block), 4, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::tuple<u8, u8> GetBirthday() { | std::tuple<u8, u8> Module::GetBirthday() { | ||||||
|     BirthdayBlock block; |     BirthdayBlock block; | ||||||
|     GetConfigInfoBlock(BirthdayBlockID, sizeof(block), 8, &block); |     GetConfigInfoBlock(BirthdayBlockID, sizeof(block), 8, &block); | ||||||
|     return std::make_tuple(block.month, block.day); |     return std::make_tuple(block.month, block.day); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SetSystemLanguage(SystemLanguage language) { | void Module::SetSystemLanguage(SystemLanguage language) { | ||||||
|     u8 block = language; |     u8 block = language; | ||||||
|     SetConfigInfoBlock(LanguageBlockID, sizeof(block), 4, &block); |     SetConfigInfoBlock(LanguageBlockID, sizeof(block), 4, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SystemLanguage GetSystemLanguage() { | SystemLanguage Module::GetSystemLanguage() { | ||||||
|     u8 block; |     u8 block; | ||||||
|     GetConfigInfoBlock(LanguageBlockID, sizeof(block), 8, &block); |     GetConfigInfoBlock(LanguageBlockID, sizeof(block), 8, &block); | ||||||
|     return static_cast<SystemLanguage>(block); |     return static_cast<SystemLanguage>(block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void SetSoundOutputMode(SoundOutputMode mode) { | void Module::SetSoundOutputMode(SoundOutputMode mode) { | ||||||
|     u8 block = mode; |     u8 block = mode; | ||||||
|     SetConfigInfoBlock(SoundOutputModeBlockID, sizeof(block), 4, &block); |     SetConfigInfoBlock(SoundOutputModeBlockID, sizeof(block), 4, &block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SoundOutputMode GetSoundOutputMode() { | SoundOutputMode Module::GetSoundOutputMode() { | ||||||
|     u8 block; |     u8 block; | ||||||
|     GetConfigInfoBlock(SoundOutputModeBlockID, sizeof(block), 8, &block); |     GetConfigInfoBlock(SoundOutputModeBlockID, sizeof(block), 8, &block); | ||||||
|     return static_cast<SoundOutputMode>(block); |     return static_cast<SoundOutputMode>(block); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GenerateConsoleUniqueId(u32& random_number, u64& console_id) { | void Module::GenerateConsoleUniqueId(u32& random_number, u64& console_id) { | ||||||
|     CryptoPP::AutoSeededRandomPool rng; |     CryptoPP::AutoSeededRandomPool rng; | ||||||
|     random_number = rng.GenerateWord32(0, 0xFFFF); |     random_number = rng.GenerateWord32(0, 0xFFFF); | ||||||
|     u64_le local_friend_code_seed; |     u64_le local_friend_code_seed; | ||||||
|  | @ -688,7 +675,7 @@ void GenerateConsoleUniqueId(u32& random_number, u64& console_id) { | ||||||
|     console_id = (local_friend_code_seed & 0x3FFFFFFFF) | (static_cast<u64>(random_number) << 48); |     console_id = (local_friend_code_seed & 0x3FFFFFFFF) | (static_cast<u64>(random_number) << 48); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode 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 = | ||||||
|         SetConfigInfoBlock(ConsoleUniqueID1BlockID, sizeof(console_id_le), 0xE, &console_id_le); |         SetConfigInfoBlock(ConsoleUniqueID1BlockID, sizeof(console_id_le), 0xE, &console_id_le); | ||||||
|  | @ -708,11 +695,20 @@ ResultCode SetConsoleUniqueId(u32 random_number, u64 console_id) { | ||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u64 GetConsoleUniqueId() { | u64 Module::GetConsoleUniqueId() { | ||||||
|     u64_le console_id_le; |     u64_le console_id_le; | ||||||
|     GetConfigInfoBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le); |     GetConfigInfoBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le); | ||||||
|     return console_id_le; |     return console_id_le; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void InstallInterfaces(SM::ServiceManager& service_manager) { | ||||||
|  |     auto cfg = std::make_shared<Module>(); | ||||||
|  |     std::make_shared<CFG_I>(cfg)->InstallAsService(service_manager); | ||||||
|  |     std::make_shared<CFG_S>(cfg)->InstallAsService(service_manager); | ||||||
|  |     std::make_shared<CFG_U>(cfg)->InstallAsService(service_manager); | ||||||
|  |     std::make_shared<CFG_NOR>()->InstallAsService(service_manager); | ||||||
|  |     current_cfg = cfg; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
| } // namespace Service
 | } // namespace Service
 | ||||||
|  |  | ||||||
|  | @ -5,15 +5,12 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <array> | #include <array> | ||||||
|  | #include <memory> | ||||||
| #include <string> | #include <string> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| 
 | #include "core/hle/service/fs/archive.h" | ||||||
| union ResultCode; |  | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| 
 |  | ||||||
| class Interface; |  | ||||||
| 
 |  | ||||||
| namespace CFG { | namespace CFG { | ||||||
| 
 | 
 | ||||||
| enum SystemModel { | enum SystemModel { | ||||||
|  | @ -82,7 +79,17 @@ static const std::array<u16, 187> country_codes = {{ | ||||||
|     C("SM"), C("VA"), C("BM"),                                              // 184-186
 |     C("SM"), C("VA"), C("BM"),                                              // 184-186
 | ||||||
| }}; | }}; | ||||||
| 
 | 
 | ||||||
| /**
 | class Module final { | ||||||
|  | public: | ||||||
|  |     Module(); | ||||||
|  |     ~Module(); | ||||||
|  | 
 | ||||||
|  |     class Interface : public ServiceFramework<Interface> { | ||||||
|  |     public: | ||||||
|  |         Interface(std::shared_ptr<Module> cfg, const char* name, u32 max_session); | ||||||
|  |         ~Interface(); | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|          * CFG::GetCountryCodeString service function |          * CFG::GetCountryCodeString service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : Country Code ID |          *      1 : Country Code ID | ||||||
|  | @ -90,9 +97,9 @@ static const std::array<u16, 187> country_codes = {{ | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *      2 : Country's 2-char string |          *      2 : Country's 2-char string | ||||||
|          */ |          */ | ||||||
| void GetCountryCodeString(Service::Interface* self); |         void GetCountryCodeString(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::GetCountryCodeID service function |          * CFG::GetCountryCodeID service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : Country Code 2-char string |          *      1 : Country Code 2-char string | ||||||
|  | @ -100,11 +107,11 @@ void GetCountryCodeString(Service::Interface* self); | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *      2 : Country Code ID |          *      2 : Country Code ID | ||||||
|          */ |          */ | ||||||
| void GetCountryCodeID(Service::Interface* self); |         void GetCountryCodeID(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| u32 GetRegionValue(); |         u32 GetRegionValue(); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::SecureInfoGetRegion service function |          * CFG::SecureInfoGetRegion service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : None |          *      1 : None | ||||||
|  | @ -113,9 +120,9 @@ u32 GetRegionValue(); | ||||||
|          *      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(Service::Interface* self); |         void SecureInfoGetRegion(Kernel::HLERequestContext& ctx, u16 id); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::GenHashConsoleUnique service function |          * CFG::GenHashConsoleUnique service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : 20 bit application ID salt |          *      1 : 20 bit application ID salt | ||||||
|  | @ -125,9 +132,9 @@ void SecureInfoGetRegion(Service::Interface* self); | ||||||
|          *      2 : Hash/"ID" lower word |          *      2 : Hash/"ID" lower word | ||||||
|          *      3 : Hash/"ID" upper word |          *      3 : Hash/"ID" upper word | ||||||
|          */ |          */ | ||||||
| void GenHashConsoleUnique(Service::Interface* self); |         void GenHashConsoleUnique(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::GetRegionCanadaUSA service function |          * CFG::GetRegionCanadaUSA service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      1 : None |          *      1 : None | ||||||
|  | @ -136,9 +143,9 @@ void GenHashConsoleUnique(Service::Interface* self); | ||||||
|          *      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(Service::Interface* self); |         void GetRegionCanadaUSA(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::GetSystemModel service function |          * CFG::GetSystemModel service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x00050000 |          *      0 : 0x00050000 | ||||||
|  | @ -146,9 +153,9 @@ void GetRegionCanadaUSA(Service::Interface* self); | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *      2 : Model of the console |          *      2 : Model of the console | ||||||
|          */ |          */ | ||||||
| void GetSystemModel(Service::Interface* self); |         void GetSystemModel(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::GetModelNintendo2DS service function |          * CFG::GetModelNintendo2DS service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x00060000 |          *      0 : 0x00060000 | ||||||
|  | @ -156,9 +163,9 @@ void GetSystemModel(Service::Interface* self); | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          *      2 : 0 if the system is a Nintendo 2DS, 1 otherwise |          *      2 : 0 if the system is a Nintendo 2DS, 1 otherwise | ||||||
|          */ |          */ | ||||||
| void GetModelNintendo2DS(Service::Interface* self); |         void GetModelNintendo2DS(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::GetConfigInfoBlk2 service function |          * CFG::GetConfigInfoBlk2 service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x00010082 |          *      0 : 0x00010082 | ||||||
|  | @ -169,9 +176,9 @@ void GetModelNintendo2DS(Service::Interface* self); | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
| void GetConfigInfoBlk2(Service::Interface* self); |         void GetConfigInfoBlk2(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::GetConfigInfoBlk8 service function |          * CFG::GetConfigInfoBlk8 service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x04010082 / 0x08010082 |          *      0 : 0x04010082 / 0x08010082 | ||||||
|  | @ -182,9 +189,9 @@ void GetConfigInfoBlk2(Service::Interface* self); | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
| void GetConfigInfoBlk8(Service::Interface* self); |         void GetConfigInfoBlk8(Kernel::HLERequestContext& ctx, u16 id); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::SetConfigInfoBlk4 service function |          * CFG::SetConfigInfoBlk4 service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x04020082 / 0x08020082 |          *      0 : 0x04020082 / 0x08020082 | ||||||
|  | @ -198,27 +205,40 @@ void GetConfigInfoBlk8(Service::Interface* self); | ||||||
|          *      The parameters order is different from GetConfigInfoBlk2/8's, |          *      The parameters order is different from GetConfigInfoBlk2/8's, | ||||||
|          *      where Block ID and Size are switched. |          *      where Block ID and Size are switched. | ||||||
|          */ |          */ | ||||||
| void SetConfigInfoBlk4(Service::Interface* self); |         void SetConfigInfoBlk4(Kernel::HLERequestContext& ctx, u16 id); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::UpdateConfigNANDSavegame service function |          * CFG::UpdateConfigNANDSavegame service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x04030000 / 0x08030000 |          *      0 : 0x04030000 / 0x08030000 | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
| void UpdateConfigNANDSavegame(Service::Interface* self); |         void UpdateConfigNANDSavegame(Kernel::HLERequestContext& ctx, u16 id); | ||||||
| 
 | 
 | ||||||
| /**
 |         /**
 | ||||||
|          * CFG::FormatConfig service function |          * CFG::FormatConfig service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
|          *      0 : 0x08060000 |          *      0 : 0x08060000 | ||||||
|          *  Outputs: |          *  Outputs: | ||||||
|          *      1 : Result of function, 0 on success, otherwise error code |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|          */ |          */ | ||||||
| void FormatConfig(Service::Interface* self); |         void FormatConfig(Kernel::HLERequestContext& ctx); | ||||||
| 
 | 
 | ||||||
| /**
 |         /// A helper function for dispatching service functions that have multiple IDs
 | ||||||
|  |         template <void (Interface::*function)(Kernel::HLERequestContext& ctx, u16 id), u16 id> | ||||||
|  |         void D(Kernel::HLERequestContext& ctx) { | ||||||
|  |             (this->*function)(ctx, id); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     private: | ||||||
|  |         std::shared_ptr<Module> cfg; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     ResultVal<void*> GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 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 | ||||||
|      * and writes the output to output. The input size must match exactly the size of the requested |      * and writes the output to output. The input size must match exactly the size of the requested | ||||||
|      * block. |      * block. | ||||||
|  | @ -229,11 +249,12 @@ void FormatConfig(Service::Interface* self); | ||||||
|      * @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 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 |      * 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. |      * 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 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 | ||||||
|  | @ -241,9 +262,9 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output); | ||||||
|      * @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 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 |      * Creates a block with the specified id and writes the input data to the cfg savegame buffer in | ||||||
|      * memory. The config savegame file in the filesystem is not updated. |      * memory. The config savegame file in the filesystem is not updated. | ||||||
|      * |      * | ||||||
|  | @ -253,118 +274,126 @@ ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* inpu | ||||||
|      * @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 CreateConfigInfoBlk(u32 block_id, u16 size, u16 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 | ||||||
|      * @returns ResultCode indicating the result of the operation, 0 on success |      * @returns ResultCode indicating the result of the operation, 0 on success | ||||||
|      */ |      */ | ||||||
| ResultCode DeleteConfigNANDSaveFile(); |     ResultCode DeleteConfigNANDSaveFile(); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|  * Writes the config savegame memory buffer to the config savegame file in the filesystem |  | ||||||
|  * @returns ResultCode indicating the result of the operation, 0 on success |  | ||||||
|  */ |  | ||||||
| ResultCode UpdateConfigNANDSavegame(); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|      * Re-creates the config savegame file in memory and the filesystem with the default blocks |      * Re-creates the config savegame file in memory and the filesystem with the default blocks | ||||||
|      * @returns ResultCode indicating the result of the operation, 0 on success |      * @returns ResultCode indicating the result of the operation, 0 on success | ||||||
|      */ |      */ | ||||||
| ResultCode FormatConfig(); |     ResultCode FormatConfig(); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Open the config savegame file and load it to the memory buffer |      * Open the config savegame file and load it to the memory buffer | ||||||
|      * @returns ResultCode indicating the result of the operation, 0 on success |      * @returns ResultCode indicating the result of the operation, 0 on success | ||||||
|      */ |      */ | ||||||
| ResultCode LoadConfigNANDSaveFile(); |     ResultCode LoadConfigNANDSaveFile(); | ||||||
| 
 | 
 | ||||||
| /// Initialize the config service
 | public: | ||||||
| void Init(); |     u32 GetRegionValue(); | ||||||
| 
 | 
 | ||||||
| /// Shutdown the config service
 |     /**
 | ||||||
| void Shutdown(); |      * Set the region code preferred by the game so that CFG will adjust to it when the region | ||||||
| 
 |      * setting | ||||||
| /**
 |  | ||||||
|  * Set the region code preferred by the game so that CFG will adjust to it when the region setting |  | ||||||
|      * is auto. |      * is auto. | ||||||
|      * @param region_code the preferred region code to set |      * @param region_code the preferred region code to set | ||||||
|      */ |      */ | ||||||
| void SetPreferredRegionCode(u32 region_code); |     void SetPreferredRegionCode(u32 region_code); | ||||||
| 
 | 
 | ||||||
| // Utilities for frontend to set config data.
 |     // Utilities for frontend to set config data.
 | ||||||
| // Note: before calling these functions, LoadConfigNANDSaveFile should be called,
 |     // Note: UpdateConfigNANDSavegame should be called after making changes to config data.
 | ||||||
| // and UpdateConfigNANDSavegame should be called after making changes to config data.
 |  | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Sets the username in config savegame. |      * Sets the username in config savegame. | ||||||
|      * @param name the username to set. The maximum size is 10 in char16_t. |      * @param name the username to set. The maximum size is 10 in char16_t. | ||||||
|      */ |      */ | ||||||
| void SetUsername(const std::u16string& name); |     void SetUsername(const std::u16string& name); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Gets the username from config savegame. |      * Gets the username from config savegame. | ||||||
|      * @returns the username |      * @returns the username | ||||||
|      */ |      */ | ||||||
| std::u16string GetUsername(); |     std::u16string GetUsername(); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Sets the profile birthday in config savegame. |      * Sets the profile birthday in config savegame. | ||||||
|      * @param month the month of birthday. |      * @param month the month of birthday. | ||||||
|      * @param day the day of the birthday. |      * @param day the day of the birthday. | ||||||
|      */ |      */ | ||||||
| void SetBirthday(u8 month, u8 day); |     void SetBirthday(u8 month, u8 day); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Gets the profile birthday from the config savegame. |      * Gets the profile birthday from the config savegame. | ||||||
|      * @returns a tuple of (month, day) of birthday |      * @returns a tuple of (month, day) of birthday | ||||||
|      */ |      */ | ||||||
| std::tuple<u8, u8> GetBirthday(); |     std::tuple<u8, u8> GetBirthday(); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Sets the system language in config savegame. |      * Sets the system language in config savegame. | ||||||
|      * @param language the system language to set. |      * @param language the system language to set. | ||||||
|      */ |      */ | ||||||
| void SetSystemLanguage(SystemLanguage language); |     void SetSystemLanguage(SystemLanguage language); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Gets the system language from config savegame. |      * Gets the system language from config savegame. | ||||||
|      * @returns the system language |      * @returns the system language | ||||||
|      */ |      */ | ||||||
| SystemLanguage GetSystemLanguage(); |     SystemLanguage GetSystemLanguage(); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Sets the sound output mode in config savegame. |      * Sets the sound output mode in config savegame. | ||||||
|      * @param mode the sound output mode to set |      * @param mode the sound output mode to set | ||||||
|      */ |      */ | ||||||
| void SetSoundOutputMode(SoundOutputMode mode); |     void SetSoundOutputMode(SoundOutputMode mode); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Gets the sound output mode from config savegame. |      * Gets the sound output mode from config savegame. | ||||||
|      * @returns the sound output mode |      * @returns the sound output mode | ||||||
|      */ |      */ | ||||||
| SoundOutputMode GetSoundOutputMode(); |     SoundOutputMode GetSoundOutputMode(); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Generates a new random console unique id. |      * Generates a new random console unique id. | ||||||
|  * @param random_number a random generated 16bit number stored at 0x90002, used for generating the |      * @param random_number a random generated 16bit number stored at 0x90002, used for generating | ||||||
|  |      * the | ||||||
|      * console_id |      * console_id | ||||||
|      * @param console_id the randomly created console id |      * @param console_id the randomly created console id | ||||||
|      */ |      */ | ||||||
| void GenerateConsoleUniqueId(u32& random_number, u64& console_id); |     void GenerateConsoleUniqueId(u32& random_number, u64& console_id); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Sets the random_number and the  console unique id in the config savegame. |      * Sets the random_number and the  console unique id in the config savegame. | ||||||
|      * @param random_number the random_number to set |      * @param random_number the random_number to set | ||||||
|      * @param console_id the console id to set |      * @param console_id the console id to set | ||||||
|      */ |      */ | ||||||
| ResultCode SetConsoleUniqueId(u32 random_number, u64 console_id); |     ResultCode SetConsoleUniqueId(u32 random_number, u64 console_id); | ||||||
| 
 | 
 | ||||||
| /**
 |     /**
 | ||||||
|      * Gets the console unique id from config savegame. |      * Gets the console unique id from config savegame. | ||||||
|      * @returns the console unique id |      * @returns the console unique id | ||||||
|      */ |      */ | ||||||
| u64 GetConsoleUniqueId(); |     u64 GetConsoleUniqueId(); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Writes the config savegame memory buffer to the config savegame file in the filesystem | ||||||
|  |      * @returns ResultCode indicating the result of the operation, 0 on success | ||||||
|  |      */ | ||||||
|  |     ResultCode UpdateConfigNANDSavegame(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     static constexpr u32 CONFIG_SAVEFILE_SIZE = 0x8000; | ||||||
|  |     std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; | ||||||
|  |     Service::FS::ArchiveHandle cfg_system_save_data_archive; | ||||||
|  |     u32 preferred_region_code = 0; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void InstallInterfaces(SM::ServiceManager& service_manager); | ||||||
|  | std::shared_ptr<Module> GetCurrentModule(); | ||||||
| 
 | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
| } // namespace Service
 | } // namespace Service
 | ||||||
|  |  | ||||||
|  | @ -2,41 +2,43 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/cfg/cfg.h" |  | ||||||
| #include "core/hle/service/cfg/cfg_i.h" | #include "core/hle/service/cfg/cfg_i.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace CFG { | namespace CFG { | ||||||
| 
 | 
 | ||||||
| const Interface::FunctionInfo FunctionTable[] = { | CFG_I::CFG_I(std::shared_ptr<Module> cfg) : Module::Interface(std::move(cfg), "cfg:i", 23) { | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|         // cfg common
 |         // cfg common
 | ||||||
|     {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, |         {0x00010082, &CFG_I::GetConfigInfoBlk2, "GetConfigInfoBlk2"}, | ||||||
|     {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x00020000, &CFG_I::D<&CFG_I::SecureInfoGetRegion, 0x0002>, "SecureInfoGetRegion"}, | ||||||
|     {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, |         {0x00030040, &CFG_I::GenHashConsoleUnique, "GenHashConsoleUnique"}, | ||||||
|     {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, |         {0x00040000, &CFG_I::GetRegionCanadaUSA, "GetRegionCanadaUSA"}, | ||||||
|     {0x00050000, GetSystemModel, "GetSystemModel"}, |         {0x00050000, &CFG_I::GetSystemModel, "GetSystemModel"}, | ||||||
|     {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, |         {0x00060000, &CFG_I::GetModelNintendo2DS, "GetModelNintendo2DS"}, | ||||||
|         {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, |         {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, | ||||||
|         {0x00080080, nullptr, "GoThroughTable"}, |         {0x00080080, nullptr, "GoThroughTable"}, | ||||||
|     {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, |         {0x00090040, &CFG_I::GetCountryCodeString, "GetCountryCodeString"}, | ||||||
|     {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, |         {0x000A0040, &CFG_I::GetCountryCodeID, "GetCountryCodeID"}, | ||||||
|         {0x000B0000, nullptr, "IsFangateSupported"}, |         {0x000B0000, nullptr, "IsFangateSupported"}, | ||||||
|         // cfg:i
 |         // cfg:i
 | ||||||
|     {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, |         {0x04010082, &CFG_I::D<&CFG_I::GetConfigInfoBlk8, 0x0401>, "GetConfigInfoBlk8"}, | ||||||
|     {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, |         {0x04020082, &CFG_I::D<&CFG_I::SetConfigInfoBlk4, 0x0402>, "SetConfigInfoBlk4"}, | ||||||
|     {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, |         {0x04030000, &CFG_I::D<&CFG_I::UpdateConfigNANDSavegame, 0x0403>, | ||||||
|  |          "UpdateConfigNANDSavegame"}, | ||||||
|         {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, |         {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, | ||||||
|         {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, |         {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, | ||||||
|     {0x04060000, SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x04060000, &CFG_I::D<&CFG_I::SecureInfoGetRegion, 0x0406>, "SecureInfoGetRegion"}, | ||||||
|         {0x04070000, nullptr, "SecureInfoGetByte101"}, |         {0x04070000, nullptr, "SecureInfoGetByte101"}, | ||||||
|         {0x04080042, nullptr, "SecureInfoGetSerialNo"}, |         {0x04080042, nullptr, "SecureInfoGetSerialNo"}, | ||||||
|         {0x04090000, nullptr, "UpdateConfigBlk00040003"}, |         {0x04090000, nullptr, "UpdateConfigBlk00040003"}, | ||||||
|     {0x08010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, |         {0x08010082, &CFG_I::D<&CFG_I::GetConfigInfoBlk8, 0x0801>, "GetConfigInfoBlk8"}, | ||||||
|     {0x08020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, |         {0x08020082, &CFG_I::D<&CFG_I::SetConfigInfoBlk4, 0x0802>, "SetConfigInfoBlk4"}, | ||||||
|     {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, |         {0x08030000, &CFG_I::D<&CFG_I::UpdateConfigNANDSavegame, 0x0803>, | ||||||
|  |          "UpdateConfigNANDSavegame"}, | ||||||
|         {0x080400C2, nullptr, "CreateConfigInfoBlk"}, |         {0x080400C2, nullptr, "CreateConfigInfoBlk"}, | ||||||
|         {0x08050000, nullptr, "DeleteConfigNANDSavefile"}, |         {0x08050000, nullptr, "DeleteConfigNANDSavefile"}, | ||||||
|     {0x08060000, FormatConfig, "FormatConfig"}, |         {0x08060000, &CFG_I::FormatConfig, "FormatConfig"}, | ||||||
|         {0x08080000, nullptr, "UpdateConfigBlk1"}, |         {0x08080000, nullptr, "UpdateConfigBlk1"}, | ||||||
|         {0x08090000, nullptr, "UpdateConfigBlk2"}, |         {0x08090000, nullptr, "UpdateConfigBlk2"}, | ||||||
|         {0x080A0000, nullptr, "UpdateConfigBlk3"}, |         {0x080A0000, nullptr, "UpdateConfigBlk3"}, | ||||||
|  | @ -51,13 +53,11 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||||
|         {0x08130000, nullptr, "VerifySigSecureInfo"}, |         {0x08130000, nullptr, "VerifySigSecureInfo"}, | ||||||
|         {0x08140042, nullptr, "SecureInfoGetData"}, |         {0x08140042, nullptr, "SecureInfoGetData"}, | ||||||
|         {0x08150042, nullptr, "SecureInfoGetSignature"}, |         {0x08150042, nullptr, "SecureInfoGetSignature"}, | ||||||
|     {0x08160000, SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x08160000, &CFG_I::D<&CFG_I::SecureInfoGetRegion, 0x0816>, "SecureInfoGetRegion"}, | ||||||
|         {0x08170000, nullptr, "SecureInfoGetByte101"}, |         {0x08170000, nullptr, "SecureInfoGetByte101"}, | ||||||
|         {0x08180042, nullptr, "SecureInfoGetSerialNo"}, |         {0x08180042, nullptr, "SecureInfoGetSerialNo"}, | ||||||
| }; |     }; | ||||||
| 
 |     RegisterHandlers(functions); | ||||||
| CFG_I::CFG_I() { |  | ||||||
|     Register(FunctionTable); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
|  |  | ||||||
|  | @ -4,18 +4,14 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/cfg/cfg.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace CFG { | namespace CFG { | ||||||
| 
 | 
 | ||||||
| class CFG_I final : public Interface { | class CFG_I final : public Module::Interface { | ||||||
| public: | public: | ||||||
|     CFG_I(); |     explicit CFG_I(std::shared_ptr<Module> cfg); | ||||||
| 
 |  | ||||||
|     std::string GetPortName() const override { |  | ||||||
|         return "cfg:i"; |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
|  |  | ||||||
|  | @ -2,21 +2,19 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/cfg/cfg.h" |  | ||||||
| #include "core/hle/service/cfg/cfg_nor.h" | #include "core/hle/service/cfg/cfg_nor.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace CFG { | namespace CFG { | ||||||
| 
 | 
 | ||||||
| const Interface::FunctionInfo FunctionTable[] = { | CFG_NOR::CFG_NOR() : ServiceFramework("cfg:nor", 23) { | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|         {0x00010040, nullptr, "Initialize"}, |         {0x00010040, nullptr, "Initialize"}, | ||||||
|         {0x00020000, nullptr, "Shutdown"}, |         {0x00020000, nullptr, "Shutdown"}, | ||||||
|         {0x00050082, nullptr, "ReadData"}, |         {0x00050082, nullptr, "ReadData"}, | ||||||
|         {0x00060082, nullptr, "WriteData"}, |         {0x00060082, nullptr, "WriteData"}, | ||||||
| }; |     }; | ||||||
| 
 |     RegisterHandlers(functions); | ||||||
| CFG_NOR::CFG_NOR() { |  | ||||||
|     Register(FunctionTable); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
|  |  | ||||||
|  | @ -9,13 +9,9 @@ | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace CFG { | namespace CFG { | ||||||
| 
 | 
 | ||||||
| class CFG_NOR final : public Interface { | class CFG_NOR final : public ServiceFramework<CFG_NOR> { | ||||||
| public: | public: | ||||||
|     CFG_NOR(); |     CFG_NOR(); | ||||||
| 
 |  | ||||||
|     std::string GetPortName() const override { |  | ||||||
|         return "cfg:nor"; |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
|  |  | ||||||
|  | @ -2,39 +2,38 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/cfg/cfg.h" |  | ||||||
| #include "core/hle/service/cfg/cfg_s.h" | #include "core/hle/service/cfg/cfg_s.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace CFG { | namespace CFG { | ||||||
| 
 | 
 | ||||||
| const Interface::FunctionInfo FunctionTable[] = { | CFG_S::CFG_S(std::shared_ptr<Module> cfg) : Module::Interface(std::move(cfg), "cfg:s", 23) { | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|         // cfg common
 |         // cfg common
 | ||||||
|     {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, |         {0x00010082, &CFG_S::GetConfigInfoBlk2, "GetConfigInfoBlk2"}, | ||||||
|     {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x00020000, &CFG_S::D<&CFG_S::SecureInfoGetRegion, 0x0002>, "SecureInfoGetRegion"}, | ||||||
|     {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, |         {0x00030040, &CFG_S::GenHashConsoleUnique, "GenHashConsoleUnique"}, | ||||||
|     {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, |         {0x00040000, &CFG_S::GetRegionCanadaUSA, "GetRegionCanadaUSA"}, | ||||||
|     {0x00050000, GetSystemModel, "GetSystemModel"}, |         {0x00050000, &CFG_S::GetSystemModel, "GetSystemModel"}, | ||||||
|     {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, |         {0x00060000, &CFG_S::GetModelNintendo2DS, "GetModelNintendo2DS"}, | ||||||
|         {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, |         {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, | ||||||
|         {0x00080080, nullptr, "GoThroughTable"}, |         {0x00080080, nullptr, "GoThroughTable"}, | ||||||
|     {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, |         {0x00090040, &CFG_S::GetCountryCodeString, "GetCountryCodeString"}, | ||||||
|     {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, |         {0x000A0040, &CFG_S::GetCountryCodeID, "GetCountryCodeID"}, | ||||||
|         {0x000B0000, nullptr, "IsFangateSupported"}, |         {0x000B0000, nullptr, "IsFangateSupported"}, | ||||||
|         // cfg:s
 |         // cfg:s
 | ||||||
|     {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, |         {0x04010082, &CFG_S::D<&CFG_S::GetConfigInfoBlk8, 0x0401>, "GetConfigInfoBlk8"}, | ||||||
|     {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, |         {0x04020082, &CFG_S::D<&CFG_S::SetConfigInfoBlk4, 0x0402>, "SetConfigInfoBlk4"}, | ||||||
|     {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, |         {0x04030000, &CFG_S::D<&CFG_S::UpdateConfigNANDSavegame, 0x0403>, | ||||||
|  |          "UpdateConfigNANDSavegame"}, | ||||||
|         {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, |         {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, | ||||||
|         {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, |         {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, | ||||||
|     {0x04060000, nullptr, "SecureInfoGetRegion"}, |         {0x04060000, &CFG_S::D<&CFG_S::SecureInfoGetRegion, 0x0406>, "SecureInfoGetRegion"}, | ||||||
|         {0x04070000, nullptr, "SecureInfoGetByte101"}, |         {0x04070000, nullptr, "SecureInfoGetByte101"}, | ||||||
|         {0x04080042, nullptr, "SecureInfoGetSerialNo"}, |         {0x04080042, nullptr, "SecureInfoGetSerialNo"}, | ||||||
|         {0x04090000, nullptr, "UpdateConfigBlk00040003"}, |         {0x04090000, nullptr, "UpdateConfigBlk00040003"}, | ||||||
| }; |     }; | ||||||
| 
 |     RegisterHandlers(functions); | ||||||
| CFG_S::CFG_S() { |  | ||||||
|     Register(FunctionTable); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
|  |  | ||||||
|  | @ -4,18 +4,14 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/cfg/cfg.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace CFG { | namespace CFG { | ||||||
| 
 | 
 | ||||||
| class CFG_S final : public Interface { | class CFG_S final : public Module::Interface { | ||||||
| public: | public: | ||||||
|     CFG_S(); |     explicit CFG_S(std::shared_ptr<Module> cfg); | ||||||
| 
 |  | ||||||
|     std::string GetPortName() const override { |  | ||||||
|         return "cfg:s"; |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
|  |  | ||||||
|  | @ -2,29 +2,27 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/cfg/cfg.h" |  | ||||||
| #include "core/hle/service/cfg/cfg_u.h" | #include "core/hle/service/cfg/cfg_u.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace CFG { | namespace CFG { | ||||||
| 
 | 
 | ||||||
| const Interface::FunctionInfo FunctionTable[] = { | CFG_U::CFG_U(std::shared_ptr<Module> cfg) : Module::Interface(std::move(cfg), "cfg:u", 23) { | ||||||
|  |     static const FunctionInfo functions[] = { | ||||||
|         // cfg common
 |         // cfg common
 | ||||||
|     {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, |         {0x00010082, &CFG_U::GetConfigInfoBlk2, "GetConfigInfoBlk2"}, | ||||||
|     {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, |         {0x00020000, &CFG_U::D<&CFG_U::SecureInfoGetRegion, 0x0002>, "SecureInfoGetRegion"}, | ||||||
|     {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, |         {0x00030040, &CFG_U::GenHashConsoleUnique, "GenHashConsoleUnique"}, | ||||||
|     {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, |         {0x00040000, &CFG_U::GetRegionCanadaUSA, "GetRegionCanadaUSA"}, | ||||||
|     {0x00050000, GetSystemModel, "GetSystemModel"}, |         {0x00050000, &CFG_U::GetSystemModel, "GetSystemModel"}, | ||||||
|     {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, |         {0x00060000, &CFG_U::GetModelNintendo2DS, "GetModelNintendo2DS"}, | ||||||
|         {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, |         {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, | ||||||
|         {0x00080080, nullptr, "GoThroughTable"}, |         {0x00080080, nullptr, "GoThroughTable"}, | ||||||
|     {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, |         {0x00090040, &CFG_U::GetCountryCodeString, "GetCountryCodeString"}, | ||||||
|     {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, |         {0x000A0040, &CFG_U::GetCountryCodeID, "GetCountryCodeID"}, | ||||||
|         {0x000B0000, nullptr, "IsFangateSupported"}, |         {0x000B0000, nullptr, "IsFangateSupported"}, | ||||||
| }; |     }; | ||||||
| 
 |     RegisterHandlers(functions); | ||||||
| CFG_U::CFG_U() { |  | ||||||
|     Register(FunctionTable); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
|  |  | ||||||
|  | @ -4,18 +4,14 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/cfg/cfg.h" | ||||||
| 
 | 
 | ||||||
| namespace Service { | namespace Service { | ||||||
| namespace CFG { | namespace CFG { | ||||||
| 
 | 
 | ||||||
| class CFG_U final : public Interface { | class CFG_U final : public Module::Interface { | ||||||
| public: | public: | ||||||
|     CFG_U(); |     explicit CFG_U(std::shared_ptr<Module> cfg); | ||||||
| 
 |  | ||||||
|     std::string GetPortName() const override { |  | ||||||
|         return "cfg:u"; |  | ||||||
|     } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace CFG
 | } // namespace CFG
 | ||||||
|  |  | ||||||
|  | @ -242,7 +242,7 @@ void Init() { | ||||||
|     BOSS::Init(); |     BOSS::Init(); | ||||||
|     CAM::InstallInterfaces(*SM::g_service_manager); |     CAM::InstallInterfaces(*SM::g_service_manager); | ||||||
|     CECD::Init(); |     CECD::Init(); | ||||||
|     CFG::Init(); |     CFG::InstallInterfaces(*SM::g_service_manager); | ||||||
|     DLP::Init(); |     DLP::Init(); | ||||||
|     FRD::InstallInterfaces(*SM::g_service_manager); |     FRD::InstallInterfaces(*SM::g_service_manager); | ||||||
|     GSP::InstallInterfaces(*SM::g_service_manager); |     GSP::InstallInterfaces(*SM::g_service_manager); | ||||||
|  | @ -273,7 +273,6 @@ void Init() { | ||||||
| void Shutdown() { | void Shutdown() { | ||||||
|     NDM::Shutdown(); |     NDM::Shutdown(); | ||||||
|     DLP::Shutdown(); |     DLP::Shutdown(); | ||||||
|     CFG::Shutdown(); |  | ||||||
|     CECD::Shutdown(); |     CECD::Shutdown(); | ||||||
|     BOSS::Shutdown(); |     BOSS::Shutdown(); | ||||||
|     FS::ArchiveShutdown(); |     FS::ArchiveShutdown(); | ||||||
|  |  | ||||||
|  | @ -135,7 +135,7 @@ void AppLoader_NCCH::ParseRegionLockoutInfo() { | ||||||
|         constexpr u32 REGION_COUNT = 7; |         constexpr u32 REGION_COUNT = 7; | ||||||
|         for (u32 region = 0; region < REGION_COUNT; ++region) { |         for (u32 region = 0; region < REGION_COUNT; ++region) { | ||||||
|             if (region_lockout & 1) { |             if (region_lockout & 1) { | ||||||
|                 Service::CFG::SetPreferredRegionCode(region); |                 Service::CFG::GetCurrentModule()->SetPreferredRegionCode(region); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             region_lockout >>= 1; |             region_lockout >>= 1; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue