Merge pull request #4278 from wwylele/cfg-ptm-direct-fs
cfg, ptm: access FS via backend directly
This commit is contained in:
commit
fceec34945
|
@ -7,7 +7,6 @@
|
||||||
#include "citra_qt/ui_settings.h"
|
#include "citra_qt/ui_settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
|
||||||
#include "core/hle/service/ptm/ptm.h"
|
#include "core/hle/service/ptm/ptm.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "ui_configure_system.h"
|
#include "ui_configure_system.h"
|
||||||
|
@ -252,11 +251,8 @@ void ConfigureSystem::setConfiguration() {
|
||||||
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.
|
|
||||||
Service::FS::RegisterArchiveTypes();
|
|
||||||
cfg = std::make_shared<Service::CFG::Module>();
|
cfg = std::make_shared<Service::CFG::Module>();
|
||||||
ReadSystemSettings();
|
ReadSystemSettings();
|
||||||
Service::FS::UnregisterArchiveTypes();
|
|
||||||
|
|
||||||
ui->label_disable_info->hide();
|
ui->label_disable_info->hide();
|
||||||
}
|
}
|
||||||
|
@ -348,10 +344,7 @@ void ConfigureSystem::applyConfiguration() {
|
||||||
// apply play coin
|
// apply play coin
|
||||||
u16 new_play_coin = static_cast<u16>(ui->spinBox_play_coins->value());
|
u16 new_play_coin = static_cast<u16>(ui->spinBox_play_coins->value());
|
||||||
if (play_coin != new_play_coin) {
|
if (play_coin != new_play_coin) {
|
||||||
// archive types must be registered to set play coins
|
|
||||||
Service::FS::RegisterArchiveTypes();
|
|
||||||
Service::PTM::Module::SetPlayCoins(new_play_coin);
|
Service::PTM::Module::SetPlayCoins(new_play_coin);
|
||||||
Service::FS::UnregisterArchiveTypes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the config savegame if any item is modified.
|
// update the config savegame if any item is modified.
|
||||||
|
|
|
@ -194,15 +194,6 @@ ArchiveFactory_ExtSaveData::ArchiveFactory_ExtSaveData(const std::string& mount_
|
||||||
LOG_DEBUG(Service_FS, "Directory {} set as base for ExtSaveData.", mount_point);
|
LOG_DEBUG(Service_FS, "Directory {} set as base for ExtSaveData.", mount_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArchiveFactory_ExtSaveData::Initialize() {
|
|
||||||
if (!FileUtil::CreateFullPath(mount_point)) {
|
|
||||||
LOG_ERROR(Service_FS, "Unable to create ExtSaveData base path.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Path ArchiveFactory_ExtSaveData::GetCorrectedPath(const Path& path) {
|
Path ArchiveFactory_ExtSaveData::GetCorrectedPath(const Path& path) {
|
||||||
if (!shared)
|
if (!shared)
|
||||||
return path;
|
return path;
|
||||||
|
|
|
@ -20,12 +20,6 @@ class ArchiveFactory_ExtSaveData final : public ArchiveFactory {
|
||||||
public:
|
public:
|
||||||
ArchiveFactory_ExtSaveData(const std::string& mount_point, bool shared);
|
ArchiveFactory_ExtSaveData(const std::string& mount_point, bool shared);
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the archive.
|
|
||||||
* @return true if it initialized successfully
|
|
||||||
*/
|
|
||||||
bool Initialize();
|
|
||||||
|
|
||||||
std::string GetName() const override {
|
std::string GetName() const override {
|
||||||
return "ExtSaveData";
|
return "ExtSaveData";
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <cryptopp/osrng.h>
|
#include <cryptopp/osrng.h>
|
||||||
#include <cryptopp/sha.h>
|
#include <cryptopp/sha.h>
|
||||||
|
#include "common/common_paths.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
@ -389,7 +390,7 @@ ResultCode Module::CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const
|
||||||
|
|
||||||
ResultCode Module::DeleteConfigNANDSaveFile() {
|
ResultCode Module::DeleteConfigNANDSaveFile() {
|
||||||
FileSys::Path path("/config");
|
FileSys::Path path("/config");
|
||||||
return Service::FS::DeleteFileFromArchive(cfg_system_save_data_archive, path);
|
return cfg_system_save_data_archive->DeleteFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode Module::UpdateConfigNANDSavegame() {
|
ResultCode Module::UpdateConfigNANDSavegame() {
|
||||||
|
@ -399,11 +400,11 @@ ResultCode Module::UpdateConfigNANDSavegame() {
|
||||||
|
|
||||||
FileSys::Path path("/config");
|
FileSys::Path path("/config");
|
||||||
|
|
||||||
auto config_result = Service::FS::OpenFileFromArchive(cfg_system_save_data_archive, path, mode);
|
auto config_result = cfg_system_save_data_archive->OpenFile(path, mode);
|
||||||
ASSERT_MSG(config_result.Succeeded(), "could not open file");
|
ASSERT_MSG(config_result.Succeeded(), "could not open file");
|
||||||
|
|
||||||
auto config = std::move(config_result).Unwrap();
|
auto config = std::move(config_result).Unwrap();
|
||||||
config->backend->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data());
|
config->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data());
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -528,36 +529,36 @@ ResultCode Module::FormatConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode Module::LoadConfigNANDSaveFile() {
|
ResultCode Module::LoadConfigNANDSaveFile() {
|
||||||
|
std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
|
||||||
|
FileSys::ArchiveFactory_SystemSaveData systemsavedata_factory(nand_directory);
|
||||||
|
|
||||||
// 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 = systemsavedata_factory.Open(archive_path);
|
||||||
Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
|
|
||||||
|
|
||||||
// If the archive didn't exist, create the files inside
|
// If the archive didn't exist, create the files inside
|
||||||
if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
|
if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
|
||||||
// Format the archive to create the directories
|
// Format the archive to create the directories
|
||||||
Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SystemSaveData,
|
systemsavedata_factory.Format(archive_path, FileSys::ArchiveFormatInfo());
|
||||||
FileSys::ArchiveFormatInfo(), archive_path);
|
|
||||||
|
|
||||||
// Open it again to get a valid archive now that the folder exists
|
// Open it again to get a valid archive now that the folder exists
|
||||||
archive_result =
|
cfg_system_save_data_archive = systemsavedata_factory.Open(archive_path).Unwrap();
|
||||||
Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!");
|
ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!");
|
||||||
|
|
||||||
cfg_system_save_data_archive = *archive_result;
|
cfg_system_save_data_archive = std::move(archive_result).Unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
FileSys::Path config_path("/config");
|
FileSys::Path config_path("/config");
|
||||||
FileSys::Mode open_mode = {};
|
FileSys::Mode open_mode = {};
|
||||||
open_mode.read_flag.Assign(1);
|
open_mode.read_flag.Assign(1);
|
||||||
|
|
||||||
auto config_result = Service::FS::OpenFileFromArchive(*archive_result, config_path, open_mode);
|
auto config_result = cfg_system_save_data_archive->OpenFile(config_path, open_mode);
|
||||||
|
|
||||||
// Read the file if it already exists
|
// Read the file if it already exists
|
||||||
if (config_result.Succeeded()) {
|
if (config_result.Succeeded()) {
|
||||||
auto config = std::move(config_result).Unwrap();
|
auto config = std::move(config_result).Unwrap();
|
||||||
config->backend->Read(0, CONFIG_SAVEFILE_SIZE, cfg_config_file_buffer.data());
|
config->Read(0, CONFIG_SAVEFILE_SIZE, cfg_config_file_buffer.data());
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,11 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
class ArchiveBackend;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service::CFG {
|
namespace Service::CFG {
|
||||||
|
|
||||||
|
@ -399,7 +403,7 @@ public:
|
||||||
private:
|
private:
|
||||||
static constexpr u32 CONFIG_SAVEFILE_SIZE = 0x8000;
|
static constexpr u32 CONFIG_SAVEFILE_SIZE = 0x8000;
|
||||||
std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer;
|
std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer;
|
||||||
Service::FS::ArchiveHandle cfg_system_save_data_archive;
|
std::unique_ptr<FileSys::ArchiveBackend> cfg_system_save_data_archive;
|
||||||
u32 preferred_region_code = 0;
|
u32 preferred_region_code = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -646,19 +646,11 @@ void RegisterArchiveTypes() {
|
||||||
|
|
||||||
auto extsavedata_factory =
|
auto extsavedata_factory =
|
||||||
std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(sdmc_directory, false);
|
std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(sdmc_directory, false);
|
||||||
if (extsavedata_factory->Initialize())
|
|
||||||
RegisterArchiveType(std::move(extsavedata_factory), ArchiveIdCode::ExtSaveData);
|
RegisterArchiveType(std::move(extsavedata_factory), ArchiveIdCode::ExtSaveData);
|
||||||
else
|
|
||||||
LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path {}",
|
|
||||||
extsavedata_factory->GetMountPoint());
|
|
||||||
|
|
||||||
auto sharedextsavedata_factory =
|
auto sharedextsavedata_factory =
|
||||||
std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(nand_directory, true);
|
std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(nand_directory, true);
|
||||||
if (sharedextsavedata_factory->Initialize())
|
|
||||||
RegisterArchiveType(std::move(sharedextsavedata_factory), ArchiveIdCode::SharedExtSaveData);
|
RegisterArchiveType(std::move(sharedextsavedata_factory), ArchiveIdCode::SharedExtSaveData);
|
||||||
else
|
|
||||||
LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path {}",
|
|
||||||
sharedextsavedata_factory->GetMountPoint());
|
|
||||||
|
|
||||||
// Create the NCCH archive, basically a small variation of the RomFS archive
|
// Create the NCCH archive, basically a small variation of the RomFS archive
|
||||||
auto savedatacheck_factory = std::make_unique<FileSys::ArchiveFactory_NCCH>();
|
auto savedatacheck_factory = std::make_unique<FileSys::ArchiveFactory_NCCH>();
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
#include "common/common_paths.h"
|
||||||
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "core/file_sys/archive_extsavedata.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/service/fs/archive.h"
|
|
||||||
#include "core/hle/service/ptm/ptm.h"
|
#include "core/hle/service/ptm/ptm.h"
|
||||||
#include "core/hle/service/ptm/ptm_gets.h"
|
#include "core/hle/service/ptm/ptm_gets.h"
|
||||||
#include "core/hle/service/ptm/ptm_play.h"
|
#include "core/hle/service/ptm/ptm_play.h"
|
||||||
|
@ -136,42 +138,44 @@ void Module::Interface::CheckNew3DS(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteGameCoinData(GameCoin gamecoin_data) {
|
static void WriteGameCoinData(GameCoin gamecoin_data) {
|
||||||
|
std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
|
||||||
|
FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
|
||||||
|
|
||||||
FileSys::Path archive_path(ptm_shared_extdata_id);
|
FileSys::Path archive_path(ptm_shared_extdata_id);
|
||||||
auto archive_result =
|
auto archive_result = extdata_archive_factory.Open(archive_path);
|
||||||
Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
|
std::unique_ptr<FileSys::ArchiveBackend> archive;
|
||||||
|
|
||||||
FileSys::Path gamecoin_path("/gamecoin.dat");
|
FileSys::Path gamecoin_path("/gamecoin.dat");
|
||||||
// If the archive didn't exist, create the files inside
|
// If the archive didn't exist, create the files inside
|
||||||
if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
|
if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
|
||||||
// Format the archive to create the directories
|
// Format the archive to create the directories
|
||||||
Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData,
|
extdata_archive_factory.Format(archive_path, FileSys::ArchiveFormatInfo());
|
||||||
FileSys::ArchiveFormatInfo(), archive_path);
|
|
||||||
// Open it again to get a valid archive now that the folder exists
|
// Open it again to get a valid archive now that the folder exists
|
||||||
archive_result =
|
archive = extdata_archive_factory.Open(archive_path).Unwrap();
|
||||||
Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
|
|
||||||
// Create the game coin file
|
// Create the game coin file
|
||||||
Service::FS::CreateFileInArchive(*archive_result, gamecoin_path, sizeof(GameCoin));
|
archive->CreateFile(gamecoin_path, sizeof(GameCoin));
|
||||||
} else {
|
} else {
|
||||||
ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!");
|
ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!");
|
||||||
|
archive = std::move(archive_result).Unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSys::Mode open_mode = {};
|
FileSys::Mode open_mode = {};
|
||||||
open_mode.write_flag.Assign(1);
|
open_mode.write_flag.Assign(1);
|
||||||
// Open the file and write the default gamecoin information
|
// Open the file and write the default gamecoin information
|
||||||
auto gamecoin_result =
|
auto gamecoin_result = archive->OpenFile(gamecoin_path, open_mode);
|
||||||
Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode);
|
|
||||||
if (gamecoin_result.Succeeded()) {
|
if (gamecoin_result.Succeeded()) {
|
||||||
auto gamecoin = std::move(gamecoin_result).Unwrap();
|
auto gamecoin = std::move(gamecoin_result).Unwrap();
|
||||||
gamecoin->backend->Write(0, sizeof(GameCoin), true,
|
gamecoin->Write(0, sizeof(GameCoin), true, reinterpret_cast<const u8*>(&gamecoin_data));
|
||||||
reinterpret_cast<const u8*>(&gamecoin_data));
|
gamecoin->Close();
|
||||||
gamecoin->backend->Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GameCoin ReadGameCoinData() {
|
static GameCoin ReadGameCoinData() {
|
||||||
|
std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
|
||||||
|
FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
|
||||||
|
|
||||||
FileSys::Path archive_path(ptm_shared_extdata_id);
|
FileSys::Path archive_path(ptm_shared_extdata_id);
|
||||||
auto archive_result =
|
auto archive_result = extdata_archive_factory.Open(archive_path);
|
||||||
Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
|
|
||||||
if (!archive_result.Succeeded()) {
|
if (!archive_result.Succeeded()) {
|
||||||
LOG_ERROR(Service_PTM, "Could not open the PTM SharedExtSaveData archive!");
|
LOG_ERROR(Service_PTM, "Could not open the PTM SharedExtSaveData archive!");
|
||||||
return default_game_coin;
|
return default_game_coin;
|
||||||
|
@ -181,8 +185,7 @@ static GameCoin ReadGameCoinData() {
|
||||||
FileSys::Mode open_mode = {};
|
FileSys::Mode open_mode = {};
|
||||||
open_mode.read_flag.Assign(1);
|
open_mode.read_flag.Assign(1);
|
||||||
|
|
||||||
auto gamecoin_result =
|
auto gamecoin_result = (*archive_result)->OpenFile(gamecoin_path, open_mode);
|
||||||
Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode);
|
|
||||||
if (!gamecoin_result.Succeeded()) {
|
if (!gamecoin_result.Succeeded()) {
|
||||||
LOG_ERROR(Service_PTM, "Could not open the game coin data file!");
|
LOG_ERROR(Service_PTM, "Could not open the game coin data file!");
|
||||||
return default_game_coin;
|
return default_game_coin;
|
||||||
|
@ -190,17 +193,18 @@ static GameCoin ReadGameCoinData() {
|
||||||
u16 result;
|
u16 result;
|
||||||
auto gamecoin = std::move(gamecoin_result).Unwrap();
|
auto gamecoin = std::move(gamecoin_result).Unwrap();
|
||||||
GameCoin gamecoin_data;
|
GameCoin gamecoin_data;
|
||||||
gamecoin->backend->Read(0, sizeof(GameCoin), reinterpret_cast<u8*>(&gamecoin_data));
|
gamecoin->Read(0, sizeof(GameCoin), reinterpret_cast<u8*>(&gamecoin_data));
|
||||||
gamecoin->backend->Close();
|
gamecoin->Close();
|
||||||
return gamecoin_data;
|
return gamecoin_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Module::Module() {
|
Module::Module() {
|
||||||
// Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't
|
// Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't
|
||||||
// exist
|
// exist
|
||||||
|
std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
|
||||||
|
FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
|
||||||
FileSys::Path archive_path(ptm_shared_extdata_id);
|
FileSys::Path archive_path(ptm_shared_extdata_id);
|
||||||
auto archive_result =
|
auto archive_result = extdata_archive_factory.Open(archive_path);
|
||||||
Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
|
|
||||||
// If the archive didn't exist, write the default game coin file
|
// If the archive didn't exist, write the default game coin file
|
||||||
if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
|
if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
|
||||||
WriteGameCoinData(default_game_coin);
|
WriteGameCoinData(default_game_coin);
|
||||||
|
|
Reference in New Issue