2019-12-07 07:19:48 +00:00
|
|
|
/*
|
2020-01-24 10:10:40 +00:00
|
|
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
2019-12-07 07:19:48 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms and conditions of the GNU General Public License,
|
|
|
|
* version 2, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2020-05-11 22:02:10 +00:00
|
|
|
#include <stratosphere.hpp>
|
2019-12-07 07:19:48 +00:00
|
|
|
#include "fsmitm_save_utils.hpp"
|
|
|
|
|
|
|
|
namespace ams::mitm::fs {
|
|
|
|
|
|
|
|
using namespace ams::fs;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
Result GetSaveDataSpaceIdString(const char **out_str, u8 space_id) {
|
2020-03-25 00:50:36 +00:00
|
|
|
switch (static_cast<SaveDataSpaceId>(space_id)) {
|
|
|
|
case SaveDataSpaceId::System:
|
|
|
|
case SaveDataSpaceId::ProperSystem:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "sys";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataSpaceId::User:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "user";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataSpaceId::SdSystem:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "sd_sys";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataSpaceId::Temporary:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "temp";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataSpaceId::SdUser:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "sd_user";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataSpaceId::SafeMode:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "safe";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return fs::ResultInvalidSaveDataSpaceId();
|
|
|
|
}
|
|
|
|
|
|
|
|
return ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-03-25 00:50:36 +00:00
|
|
|
Result GetSaveDataTypeString(const char **out_str, SaveDataType save_data_type) {
|
2019-12-07 07:19:48 +00:00
|
|
|
switch (save_data_type) {
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataType::System:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "system";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataType::Account:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "account";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataType::Bcat:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "bcat";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataType::Device:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "device";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataType::Temporary:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "temp";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataType::Cache:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "cache";
|
|
|
|
break;
|
2020-03-25 00:50:36 +00:00
|
|
|
case SaveDataType::SystemBcat:
|
2019-12-07 07:19:48 +00:00
|
|
|
*out_str = "system_bcat";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* TODO: Better result? */
|
|
|
|
return fs::ResultInvalidArgument();
|
|
|
|
}
|
|
|
|
|
|
|
|
return ResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-03-25 00:50:36 +00:00
|
|
|
constexpr inline bool IsEmptyAccountId(const UserId &uid) {
|
|
|
|
return uid == InvalidUserId;
|
2019-12-07 07:19:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-03-25 00:50:36 +00:00
|
|
|
Result SaveUtil::GetDirectorySaveDataPath(char *dst, size_t dst_size, ncm::ProgramId program_id, u8 space_id, const fs::SaveDataAttribute &attribute) {
|
2019-12-07 07:19:48 +00:00
|
|
|
/* Saves should be separate for emunand vs sysnand. */
|
|
|
|
const char *emummc_str = emummc::IsActive() ? "emummc" : "sysmmc";
|
|
|
|
|
|
|
|
/* Get space_id, save_data_type strings. */
|
|
|
|
const char *space_id_str, *save_type_str;
|
|
|
|
R_TRY(GetSaveDataSpaceIdString(&space_id_str, space_id));
|
2020-03-25 00:50:36 +00:00
|
|
|
R_TRY(GetSaveDataTypeString(&save_type_str, attribute.type));
|
2019-12-07 07:19:48 +00:00
|
|
|
|
|
|
|
/* Initialize the path. */
|
2020-03-25 00:50:36 +00:00
|
|
|
const bool is_system = attribute.system_save_data_id != InvalidSystemSaveDataId && IsEmptyAccountId(attribute.user_id);
|
2019-12-07 07:19:48 +00:00
|
|
|
size_t out_path_len;
|
|
|
|
if (is_system) {
|
2021-01-12 10:59:41 +00:00
|
|
|
out_path_len = static_cast<size_t>(util::SNPrintf(dst, dst_size, "/atmosphere/saves/%s/%s/%s/%016lx", emummc_str, space_id_str, save_type_str, attribute.system_save_data_id));
|
2019-12-07 07:19:48 +00:00
|
|
|
} else {
|
2021-01-12 10:59:41 +00:00
|
|
|
out_path_len = static_cast<size_t>(util::SNPrintf(dst, dst_size, "/atmosphere/saves/%s/%s/%s/%016lx/%016lx%016lx", emummc_str, space_id_str, save_type_str, static_cast<u64>(program_id), attribute.user_id.data[1], attribute.user_id.data[0]));
|
2019-12-07 07:19:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
R_UNLESS(out_path_len < dst_size, fs::ResultTooLongPath());
|
|
|
|
|
|
|
|
return ResultSuccess();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|