aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar Subv <subv2112@gmail.com>2015-02-24 18:02:40 -0500
committerGravatar Subv <subv2112@gmail.com>2015-02-25 19:37:10 -0500
commit9db5c9b6dc7b01a0a69179707823f27f42b9cdd9 (patch)
tree8f5c1e9de1e90b2db1f636224e5b7c4b62d69213 /src/core/hle
parent3700263f71d24b27fe1ff992985f45d7438069c1 (diff)
Archives: Properly implemented the SystemSaveData archive.
Ported to the new factory pattern we have for archives.
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/service/cfg/cfg.cpp64
-rw-r--r--src/core/hle/service/fs/archive.cpp4
2 files changed, 42 insertions, 26 deletions
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index 1a2104b4..b7cdccb8 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -4,8 +4,8 @@
#include <algorithm>
#include "common/make_unique.h"
-#include "core/file_sys/archive_systemsavedata.h"
#include "core/hle/service/cfg/cfg.h"
+#include "core/hle/service/fs/archive.h"
namespace Service {
namespace CFG {
@@ -36,7 +36,8 @@ const std::array<float, 8> STEREO_CAMERA_SETTINGS = {
static const u32 CONFIG_SAVEFILE_SIZE = 0x8000;
static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer;
-static std::unique_ptr<FileSys::Archive_SystemSaveData> cfg_system_save_data;
+static Service::FS::ArchiveHandle cfg_system_save_data_archive;
+static const std::vector<u8> cfg_system_savedata_id = { 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00 };
ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) {
// Read the header
@@ -97,19 +98,22 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const u8* data
ResultCode DeleteConfigNANDSaveFile() {
FileSys::Path path("config");
- if (cfg_system_save_data->DeleteFile(path))
- return RESULT_SUCCESS;
- return ResultCode(-1); // TODO(Subv): Find the right error code
+ return Service::FS::DeleteFileFromArchive(cfg_system_save_data_archive, path);
}
ResultCode UpdateConfigNANDSavegame() {
FileSys::Mode mode = {};
mode.write_flag = 1;
mode.create_flag = 1;
+
FileSys::Path path("config");
- auto file = cfg_system_save_data->OpenFile(path, mode);
- ASSERT_MSG(file != nullptr, "could not open file");
- file->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data());
+
+ auto config_result = Service::FS::OpenFileFromArchive(cfg_system_save_data_archive, path, mode);
+ ASSERT_MSG(config_result.Succeeded(), "could not open file");
+
+ auto config = config_result.MoveFrom();
+ config->backend->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data());
+
return RESULT_SUCCESS;
}
@@ -158,27 +162,33 @@ ResultCode FormatConfig() {
}
void CFGInit() {
- // TODO(Subv): In the future we should use the FS service to query this archive,
- // currently it is not possible because you can only have one open archive of the same type at any time
- std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX);
- cfg_system_save_data = Common::make_unique<FileSys::Archive_SystemSaveData>(
- nand_directory, CFG_SAVE_ID);
- if (!cfg_system_save_data->Initialize()) {
- LOG_CRITICAL(Service_CFG, "Could not initialize SystemSaveData archive for the CFG:U service");
- return;
+ // Open the SystemSaveData archive 0x00010017
+ FileSys::Path archive_path(cfg_system_savedata_id);
+ auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
+
+ // If the archive didn't exist, create the files inside
+ if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) {
+ // Format the archive to create the directories
+ Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
+
+ // Open it again to get a valid archive now that the folder exists
+ archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
}
- // TODO(Subv): All this code should be moved to cfg:i,
- // it's only here because we do not currently emulate the lower level code that uses that service
- // Try to open the file in read-only mode to check its existence
- FileSys::Mode mode = {};
- mode.read_flag = 1;
- FileSys::Path path("config");
- auto file = cfg_system_save_data->OpenFile(path, mode);
+ ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!");
+
+ cfg_system_save_data_archive = *archive_result;
+
+ FileSys::Path config_path("config");
+ FileSys::Mode open_mode = {};
+ open_mode.read_flag = 1;
- // Load the config if it already exists
- if (file != nullptr) {
- file->Read(0, CONFIG_SAVEFILE_SIZE, cfg_config_file_buffer.data());
+ auto config_result = Service::FS::OpenFileFromArchive(*archive_result, config_path, open_mode);
+
+ // Read the file if it already exists
+ if (config_result.Succeeded()) {
+ auto config = config_result.MoveFrom();
+ config->backend->Read(0, CONFIG_SAVEFILE_SIZE, cfg_config_file_buffer.data());
return;
}
@@ -186,10 +196,12 @@ void CFGInit() {
// TODO(Subv): Initialize this directly in the variable when MSVC supports char16_t string literals
CONSOLE_USERNAME_BLOCK.ng_word = 0;
CONSOLE_USERNAME_BLOCK.zero = 0;
+
// Copy string to buffer and pad with zeros at the end
auto size = Common::UTF8ToUTF16(CONSOLE_USERNAME).copy(CONSOLE_USERNAME_BLOCK.username, 0x14);
std::fill(std::begin(CONSOLE_USERNAME_BLOCK.username) + size,
std::end(CONSOLE_USERNAME_BLOCK.username), 0);
+
FormatConfig();
}
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index a69c4f25..c5020cb2 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -18,6 +18,7 @@
#include "core/file_sys/archive_savedata.h"
#include "core/file_sys/archive_savedatacheck.h"
#include "core/file_sys/archive_sdmc.h"
+#include "core/file_sys/archive_systemsavedata.h"
#include "core/file_sys/directory_backend.h"
#include "core/hle/service/fs/archive.h"
#include "core/hle/result.h"
@@ -449,6 +450,9 @@ void ArchiveInit() {
// Create the SaveDataCheck archive, basically a small variation of the RomFS archive
auto savedatacheck_factory = Common::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory);
RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck);
+
+ auto systemsavedata_factory = Common::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory);
+ RegisterArchiveType(std::move(systemsavedata_factory), ArchiveIdCode::SystemSaveData);
}
/// Shutdown archives