ams: support building unit test programs on windows/linux/macos

This commit is contained in:
Michael Scire
2022-03-06 12:08:20 -08:00
committed by SciresM
parent 9a38be201a
commit 64a97576d0
756 changed files with 33359 additions and 9372 deletions

View File

@@ -114,7 +114,7 @@ namespace ams::mitm {
Sha256Hash calc_hash;
ON_SCOPE_EXIT { ::ams::crypto::ClearMemory(std::addressof(calc_hash), sizeof(calc_hash)); };
::ams::crypto::GenerateSha256Hash(std::addressof(calc_hash), sizeof(calc_hash), data, data_size);
::ams::crypto::GenerateSha256(std::addressof(calc_hash), sizeof(calc_hash), data, data_size);
return ::ams::crypto::IsSameBytes(std::addressof(calc_hash), std::addressof(hash), sizeof(Sha256Hash));
}
@@ -182,7 +182,7 @@ namespace ams::mitm {
} else {
static_assert(Block::IsShaBlock);
std::memset(std::addressof(block), 0, Block::Size);
::ams::crypto::GenerateSha256Hash(std::addressof(block.sha256_hash), sizeof(block.sha256_hash), std::addressof(block), Block::Size - sizeof(block.sha256_hash));
::ams::crypto::GenerateSha256(std::addressof(block.sha256_hash), sizeof(block.sha256_hash), std::addressof(block), Block::Size - sizeof(block.sha256_hash));
}
}
@@ -224,7 +224,7 @@ namespace ams::mitm {
Blank(info.GetBlock<ExtendedSslKeyBlock>());
/* Set header hash. */
crypto::GenerateSha256Hash(std::addressof(info.header.body_hash), sizeof(info.header.body_hash), std::addressof(info.body), sizeof(info.body));
crypto::GenerateSha256(std::addressof(info.header.body_hash), sizeof(info.header.body_hash), std::addressof(info.body), sizeof(info.body));
}
bool IsValidHeader(const CalibrationInfo &cal) {
@@ -375,7 +375,7 @@ namespace ams::mitm {
AMS_ABORT_UNLESS(IsValidForSecureBackup(src->info));
/* Set the Sha256 hash. */
crypto::GenerateSha256Hash(std::addressof(src->hash), sizeof(src->hash), std::addressof(src->info), sizeof(src->info));
crypto::GenerateSha256(std::addressof(src->hash), sizeof(src->hash), std::addressof(src->info), sizeof(src->info));
/* Validate the hash. */
AMS_ABORT_UNLESS(IsValidSha256Hash(src->hash, std::addressof(src->info), sizeof(src->info)));
@@ -407,7 +407,7 @@ namespace ams::mitm {
util::SNPrintf(dst, dst_size, "automatic_backups/%s_PRODINFO.bin", sn);
} else {
Sha256Hash hash;
crypto::GenerateSha256Hash(std::addressof(hash), sizeof(hash), std::addressof(info), sizeof(info));
crypto::GenerateSha256(std::addressof(hash), sizeof(hash), std::addressof(info), sizeof(info));
ON_SCOPE_EXIT { crypto::ClearMemory(std::addressof(hash), sizeof(hash)); };
if (IsValid(info)) {
@@ -484,7 +484,7 @@ namespace ams::mitm {
data_buffer[2] = os::GetSystemTick().GetInt64Value();
}
return crypto::GenerateSha256Hash(dst, sizeof(*dst), data_buffer, sizeof(data_buffer));
return crypto::GenerateSha256(dst, sizeof(*dst), data_buffer, sizeof(data_buffer));
}
void FillWithGarbage(void *dst, size_t dst_size) {
@@ -579,7 +579,7 @@ namespace ams::mitm {
} else {
Sha256Hash hash;
ON_SCOPE_EXIT { crypto::ClearMemory(std::addressof(hash), sizeof(hash)); };
crypto::GenerateSha256Hash(std::addressof(hash), sizeof(hash), std::addressof(g_calibration_info), sizeof(g_calibration_info));
crypto::GenerateSha256(std::addressof(hash), sizeof(hash), std::addressof(g_calibration_info), sizeof(g_calibration_info));
util::SNPrintf(out_name, out_name_size, "%02X%02X%02X%02X", hash.data[0], hash.data[1], hash.data[2], hash.data[3]);
}

View File

@@ -30,7 +30,7 @@ namespace ams::mitm::fs {
namespace {
constexpr const char AtmosphereHblWebContentDir[] = "/atmosphere/hbl_html/";
constexpr const ams::fs::Path AtmosphereHblWebContentDirPath = fs::MakeConstantPath("/atmosphere/hbl_html/");
constexpr const char ProgramWebContentDir[] = "/manual_html/";
constinit os::SdkMutex g_boot0_detect_lock;
@@ -77,7 +77,7 @@ namespace ams::mitm::fs {
/* Hbl html directory must exist. */
{
FsDir d;
R_UNLESS(R_SUCCEEDED(mitm::fs::OpenSdDirectory(std::addressof(d), AtmosphereHblWebContentDir, fs::OpenDirectoryMode_Directory)), sm::mitm::ResultShouldForwardToSession());
R_UNLESS(R_SUCCEEDED(mitm::fs::OpenSdDirectory(std::addressof(d), AtmosphereHblWebContentDirPath.GetString(), fs::OpenDirectoryMode_Directory)), sm::mitm::ResultShouldForwardToSession());
fsDirClose(std::addressof(d));
}
@@ -87,7 +87,10 @@ namespace ams::mitm::fs {
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(sd_fs.s))};
std::unique_ptr<fs::fsa::IFileSystem> sd_ifs = std::make_unique<fs::RemoteFileSystem>(sd_fs);
out.SetValue(MakeSharedFileSystem(std::make_shared<fs::ReadOnlyFileSystem>(std::make_unique<fssystem::SubDirectoryFileSystem>(std::move(sd_ifs), AtmosphereHblWebContentDir)), false), target_object_id);
auto subdir_fs = std::make_unique<fssystem::SubDirectoryFileSystem>(std::move(sd_ifs));
R_TRY(subdir_fs->Initialize(AtmosphereHblWebContentDirPath));
out.SetValue(MakeSharedFileSystem(std::make_shared<fs::ReadOnlyFileSystem>(std::move(subdir_fs)), false), target_object_id);
return ResultSuccess();
}
@@ -106,12 +109,17 @@ namespace ams::mitm::fs {
std::unique_ptr<fs::fsa::IFileSystem> sd_ifs = std::make_unique<fs::RemoteFileSystem>(sd_fs);
/* Format the subdirectory path. */
char program_web_content_path[fs::EntryNameLengthMax + 1];
FormatAtmosphereSdPath(program_web_content_path, sizeof(program_web_content_path), program_id, ProgramWebContentDir);
char program_web_content_raw_path[0x100];
FormatAtmosphereSdPath(program_web_content_raw_path, sizeof(program_web_content_raw_path), program_id, ProgramWebContentDir);
ams::fs::Path program_web_content_path;
R_TRY(program_web_content_path.SetShallowBuffer(program_web_content_raw_path));
/* Make a new filesystem. */
{
std::unique_ptr<fs::fsa::IFileSystem> subdir_fs = std::make_unique<fssystem::SubDirectoryFileSystem>(std::move(sd_ifs), program_web_content_path);
auto subdir_fs = std::make_unique<fssystem::SubDirectoryFileSystem>(std::move(sd_ifs));
R_TRY(subdir_fs->Initialize(program_web_content_path));
std::shared_ptr<fs::fsa::IFileSystem> new_fs = nullptr;
/* Try to open the existing fs. */
@@ -165,7 +173,7 @@ namespace ams::mitm::fs {
Result FsMitmService::OpenSdCardFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out) {
/* We only care about redirecting this for NS/emummc. */
R_UNLESS(m_client_info.program_id == ncm::SystemProgramId::Ns, sm::mitm::ResultShouldForwardToSession());
R_UNLESS(emummc::IsActive(), sm::mitm::ResultShouldForwardToSession());
R_UNLESS(emummc::IsActive(), sm::mitm::ResultShouldForwardToSession());
/* Create a new SD card filesystem. */
FsFileSystem sd_fs;
@@ -173,7 +181,9 @@ namespace ams::mitm::fs {
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(sd_fs.s))};
/* Return output filesystem. */
std::shared_ptr<fs::fsa::IFileSystem> redir_fs = std::make_shared<fssystem::DirectoryRedirectionFileSystem>(std::make_shared<RemoteFileSystem>(sd_fs), "/Nintendo", emummc::GetNintendoDirPath());
auto redir_fs = std::make_shared<fssystem::DirectoryRedirectionFileSystem>(std::make_unique<RemoteFileSystem>(sd_fs));
R_TRY(redir_fs->InitializeWithFixedPath("/Nintendo", emummc::GetNintendoDirPath()));
out.SetValue(MakeSharedFileSystem(std::move(redir_fs), false), target_object_id);
return ResultSuccess();
}
@@ -209,8 +219,12 @@ namespace ams::mitm::fs {
/* Verify that we can open the save directory, and that it exists. */
const ncm::ProgramId application_id = attribute.program_id == ncm::InvalidProgramId ? m_client_info.program_id : attribute.program_id;
char save_dir_path[fs::EntryNameLengthMax + 1];
R_TRY(mitm::fs::SaveUtil::GetDirectorySaveDataPath(save_dir_path, sizeof(save_dir_path), application_id, space_id, attribute));
char save_dir_raw_path[0x100];
R_TRY(mitm::fs::SaveUtil::GetDirectorySaveDataPath(save_dir_raw_path, sizeof(save_dir_raw_path), application_id, space_id, attribute));
ams::fs::Path save_dir_path;
R_TRY(save_dir_path.SetShallowBuffer(save_dir_raw_path));
/* Check if this is the first time we're making the save. */
bool is_new_save = false;
@@ -223,19 +237,25 @@ namespace ams::mitm::fs {
}
/* Ensure the directory exists. */
R_TRY(fssystem::EnsureDirectoryRecursively(sd_ifs.get(), save_dir_path));
R_TRY(fssystem::EnsureDirectory(sd_ifs.get(), save_dir_path));
/* Create directory savedata filesystem. */
std::unique_ptr<fs::fsa::IFileSystem> subdir_fs = std::make_unique<fssystem::SubDirectoryFileSystem>(sd_ifs, save_dir_path);
auto subdir_fs = std::make_unique<fssystem::SubDirectoryFileSystem>(sd_ifs);
R_TRY(subdir_fs->Initialize(save_dir_path));
std::shared_ptr<fssystem::DirectorySaveDataFileSystem> dirsave_ifs = std::make_shared<fssystem::DirectorySaveDataFileSystem>(std::move(subdir_fs));
/* Ensure correct directory savedata filesystem state. */
R_TRY(dirsave_ifs->Initialize());
R_TRY(dirsave_ifs->Initialize(true, true, true));
/* If it's the first time we're making the save, copy existing savedata over. */
if (is_new_save) {
/* TODO: Check error? */
dirsave_ifs->CopySaveFromFileSystem(save_ifs.get());
fs::DirectoryEntry work_entry;
constexpr const fs::Path root_path = fs::MakeConstantPath("/");
u8 savedata_copy_buffer[2_KB];
fssystem::CopyDirectoryRecursively(dirsave_ifs.get(), save_ifs.get(), root_path, root_path, std::addressof(work_entry), savedata_copy_buffer, sizeof(savedata_copy_buffer));
}
/* Set output. */
@@ -265,19 +285,20 @@ namespace ams::mitm::fs {
/* Set output storage. */
if (bis_partition_id == FsBisPartitionId_BootPartition1Root) {
if (IsBoot0CustomPublicKey(bis_storage)) {
out.SetValue(MakeSharedStorage(new CustomPublicKeyBoot0Storage(bis_storage, m_client_info, spl::GetSocType())), target_object_id);
out.SetValue(MakeSharedStorage(std::make_shared<CustomPublicKeyBoot0Storage>(bis_storage, m_client_info, spl::GetSocType())), target_object_id);
} else {
out.SetValue(MakeSharedStorage(new Boot0Storage(bis_storage, m_client_info)), target_object_id);
out.SetValue(MakeSharedStorage(std::make_shared<Boot0Storage>(bis_storage, m_client_info)), target_object_id);
}
} else if (bis_partition_id == FsBisPartitionId_CalibrationBinary) {
out.SetValue(MakeSharedStorage(new CalibrationBinaryStorage(bis_storage, m_client_info)), target_object_id);
out.SetValue(MakeSharedStorage(std::make_shared<CalibrationBinaryStorage>(bis_storage, m_client_info)), target_object_id);
} else {
if (can_write_bis || can_write_bis_for_choi_support) {
/* We can write, so create a writable storage. */
out.SetValue(MakeSharedStorage(new RemoteStorage(bis_storage)), target_object_id);
out.SetValue(MakeSharedStorage(std::make_shared<RemoteStorage>(bis_storage)), target_object_id);
} else {
/* We can only read, so create a readable storage. */
out.SetValue(MakeSharedStorage(new ReadOnlyStorageAdapter(new RemoteStorage(bis_storage))), target_object_id);
std::unique_ptr<ams::fs::IStorage> unique_bis = std::make_unique<RemoteStorage>(bis_storage);
out.SetValue(MakeSharedStorage(std::make_shared<ReadOnlyStorageAdapter>(std::move(unique_bis))), target_object_id);
}
}

View File

@@ -27,52 +27,52 @@ namespace ams::mitm::fs {
virtual ~ReadOnlyLayeredFileSystem() { /* ... */ }
private:
virtual Result DoCreateFile(const char *path, s64 size, int flags) override final {
virtual Result DoCreateFile(const ams::fs::Path &path, s64 size, int flags) override final {
AMS_UNUSED(path, size, flags);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoDeleteFile(const char *path) override final {
virtual Result DoDeleteFile(const ams::fs::Path &path) override final {
AMS_UNUSED(path);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoCreateDirectory(const char *path) override final {
virtual Result DoCreateDirectory(const ams::fs::Path &path) override final {
AMS_UNUSED(path);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoDeleteDirectory(const char *path) override final {
virtual Result DoDeleteDirectory(const ams::fs::Path &path) override final {
AMS_UNUSED(path);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoDeleteDirectoryRecursively(const char *path) override final {
virtual Result DoDeleteDirectoryRecursively(const ams::fs::Path &path) override final {
AMS_UNUSED(path);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoRenameFile(const char *old_path, const char *new_path) override final {
virtual Result DoRenameFile(const ams::fs::Path &old_path, const ams::fs::Path &new_path) override final {
AMS_UNUSED(old_path, new_path);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoRenameDirectory(const char *old_path, const char *new_path) override final {
virtual Result DoRenameDirectory(const ams::fs::Path &old_path, const ams::fs::Path &new_path) override final {
AMS_UNUSED(old_path, new_path);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoGetEntryType(ams::fs::DirectoryEntryType *out, const char *path) override final {
virtual Result DoGetEntryType(ams::fs::DirectoryEntryType *out, const ams::fs::Path &path) override final {
R_SUCCEED_IF(R_SUCCEEDED(m_fs_1.GetEntryType(out, path)));
return m_fs_2.GetEntryType(out, path);
}
virtual Result DoOpenFile(std::unique_ptr<ams::fs::fsa::IFile> *out_file, const char *path, ams::fs::OpenMode mode) override final {
virtual Result DoOpenFile(std::unique_ptr<ams::fs::fsa::IFile> *out_file, const ams::fs::Path &path, ams::fs::OpenMode mode) override final {
R_SUCCEED_IF(R_SUCCEEDED(m_fs_1.OpenFile(out_file, path, mode)));
return m_fs_2.OpenFile(out_file, path, mode);
}
virtual Result DoOpenDirectory(std::unique_ptr<ams::fs::fsa::IDirectory> *out_dir, const char *path, ams::fs::OpenDirectoryMode mode) override final {
virtual Result DoOpenDirectory(std::unique_ptr<ams::fs::fsa::IDirectory> *out_dir, const ams::fs::Path &path, ams::fs::OpenDirectoryMode mode) override final {
R_SUCCEED_IF(R_SUCCEEDED(m_fs_1.OpenDirectory(out_dir, path, mode)));
return m_fs_2.OpenDirectory(out_dir, path, mode);
}
@@ -81,22 +81,22 @@ namespace ams::mitm::fs {
return ResultSuccess();
}
virtual Result DoGetFreeSpaceSize(s64 *out, const char *path) {
virtual Result DoGetFreeSpaceSize(s64 *out, const ams::fs::Path &path) {
AMS_UNUSED(out, path);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoGetTotalSpaceSize(s64 *out, const char *path) {
virtual Result DoGetTotalSpaceSize(s64 *out, const ams::fs::Path &path) {
AMS_UNUSED(out, path);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoCleanDirectoryRecursively(const char *path) {
virtual Result DoCleanDirectoryRecursively(const ams::fs::Path &path) {
AMS_UNUSED(path);
return ams::fs::ResultUnsupportedOperation();
}
virtual Result DoGetFileTimeStampRaw(ams::fs::FileTimeStampRaw *out, const char *path) {
virtual Result DoGetFileTimeStampRaw(ams::fs::FileTimeStampRaw *out, const ams::fs::Path &path) {
R_SUCCEED_IF(R_SUCCEEDED(m_fs_1.GetFileTimeStampRaw(out, path)));
return m_fs_2.GetFileTimeStampRaw(out, path);
}

View File

@@ -269,7 +269,7 @@ namespace ams::mitm::fs::romfs {
size_t m_file_hash_table_size;
size_t m_file_partition_size;
ams::fs::DirectoryEntry m_dir_entry;
::FsDirectoryEntry m_dir_entry;
DataSourceType m_cur_source_type;
private:
void VisitDirectory(FsFileSystem *fs, BuildDirectoryContext *parent);

View File

@@ -25,22 +25,25 @@ namespace ams::mitm::sysupdater {
constexpr inline const size_t NcaExtensionSize = 4;
constexpr inline const size_t NspExtensionSize = 4;
constexpr const ams::fs::PathFlags SdCardContentMetaPathNormalizePathFlags = [] {
fs::PathFlags flags{};
flags.AllowMountName();
return flags;
}();
static_assert(NcaExtensionSize == NspExtensionSize);
constexpr inline const size_t NcaNspExtensionSize = NcaExtensionSize;
constexpr inline std::underlying_type<fssrv::PathNormalizer::Option>::type SdCardContentMetaPathNormalizeOption = fssrv::PathNormalizer::Option_PreserveTailSeparator |
fssrv::PathNormalizer::Option_HasMountName;
Result CheckNcaOrNsp(const char **path) {
/* Ensure that the path is currently at the mount name delimeter. */
R_UNLESS(std::strncmp(*path, ams::fs::impl::MountNameDelimiter, strnlen(ams::fs::impl::MountNameDelimiter, ams::fs::EntryNameLengthMax)) == 0, fs::ResultPathNotFound());
R_UNLESS(util::Strncmp(*path, ams::fs::impl::MountNameDelimiter, util::Strnlen(ams::fs::impl::MountNameDelimiter, ams::fs::EntryNameLengthMax)) == 0, fs::ResultPathNotFound());
/* Advance past the :. */
static_assert(ams::fs::impl::MountNameDelimiter[0] == ':');
*path += 1;
/* Ensure path is long enough for the extension. */
const auto path_len = strnlen(*path, ams::fs::EntryNameLengthMax);
const size_t path_len = util::Strnlen(*path, ams::fs::EntryNameLengthMax);
R_UNLESS(path_len > NcaNspExtensionSize, fs::ResultPathNotFound());
/* Get the extension. */
@@ -56,7 +59,7 @@ namespace ams::mitm::sysupdater {
Result ParseMountName(const char **path, std::shared_ptr<ams::fs::fsa::IFileSystem> *out) {
/* The equivalent function here supports all the common mount names; we'll only support the SD card, system content storage. */
if (const auto mount_len = strnlen(ams::fs::impl::SdCardFileSystemMountName, ams::fs::MountNameLengthMax); std::strncmp(*path, ams::fs::impl::SdCardFileSystemMountName, mount_len) == 0) {
if (const auto mount_len = util::Strnlen(ams::fs::impl::SdCardFileSystemMountName, ams::fs::MountNameLengthMax); util::Strncmp(*path, ams::fs::impl::SdCardFileSystemMountName, mount_len) == 0) {
/* Advance the path. */
*path += mount_len;
@@ -70,7 +73,7 @@ namespace ams::mitm::sysupdater {
/* Set the output fs. */
*out = std::move(fsa);
} else if (const auto mount_len = strnlen(ams::fs::impl::ContentStorageSystemMountName, ams::fs::MountNameLengthMax); std::strncmp(*path, ams::fs::impl::ContentStorageSystemMountName, mount_len) == 0) {
} else if (const auto mount_len = util::Strnlen(ams::fs::impl::ContentStorageSystemMountName, ams::fs::MountNameLengthMax); util::Strncmp(*path, ams::fs::impl::ContentStorageSystemMountName, mount_len) == 0) {
/* Advance the path. */
*path += mount_len;
@@ -89,7 +92,7 @@ namespace ams::mitm::sysupdater {
}
/* Ensure that there's something that could be a mount name delimiter. */
R_UNLESS(strnlen(*path, fs::EntryNameLengthMax) != 0, fs::ResultPathNotFound());
R_UNLESS(util::Strnlen(*path, fs::EntryNameLengthMax) != 0, fs::ResultPathNotFound());
return ResultSuccess();
}
@@ -115,10 +118,8 @@ namespace ams::mitm::sysupdater {
work_path += NspExtensionSize;
/* Get the nsp path. */
char nsp_path[fs::EntryNameLengthMax + 1];
R_UNLESS(static_cast<size_t>(work_path - *path) <= sizeof(nsp_path), fs::ResultTooLongPath());
std::memcpy(nsp_path, *path, work_path - *path);
nsp_path[work_path - *path] = '\x00';
ams::fs::Path nsp_path;
R_TRY(nsp_path.InitializeWithNormalization(*path, work_path - *path));
/* Open the file storage. */
std::shared_ptr<ams::fs::FileStorageBasedFileSystem> file_storage = fssystem::AllocateShared<ams::fs::FileStorageBasedFileSystem>();
@@ -138,7 +139,12 @@ namespace ams::mitm::sysupdater {
/* Open the file storage. */
std::shared_ptr<ams::fs::FileStorageBasedFileSystem> file_storage = fssystem::AllocateShared<ams::fs::FileStorageBasedFileSystem>();
R_UNLESS(file_storage != nullptr, fs::ResultAllocationFailureInFileSystemProxyCoreImplE());
R_TRY(file_storage->Initialize(std::move(base_fs), *path, ams::fs::OpenMode_Read));
/* Get the nca path. */
ams::fs::Path nca_path;
R_TRY(nca_path.InitializeWithNormalization(*path));
R_TRY(file_storage->Initialize(std::move(base_fs), nca_path, ams::fs::OpenMode_Read));
/* Create the nca reader. */
std::shared_ptr<fssystem::NcaReader> nca_reader;
@@ -196,7 +202,7 @@ namespace ams::mitm::sysupdater {
/* Open meta storage. */
std::shared_ptr<ams::fs::IStorage> storage;
std::shared_ptr<fssystem::IAsynchronousAccessSplitter> splitter;
fssystem::NcaFsHeader::FsType fs_type;
fssystem::NcaFsHeader::FsType fs_type = static_cast<fssystem::NcaFsHeader::FsType>(~0);
R_TRY(OpenMetaStorage(std::addressof(storage), std::addressof(splitter), std::move(nca_reader), std::addressof(fs_type)));
/* Open the appropriate interface. */
@@ -230,12 +236,12 @@ namespace ams::mitm::sysupdater {
R_UNLESS(path != nullptr, fs::ResultInvalidPath());
/* Normalize the path. */
fssrv::PathNormalizer normalized_path(path, SdCardContentMetaPathNormalizeOption);
R_TRY(normalized_path.GetResult());
char normalized_path[fs::EntryNameLengthMax + 1];
R_TRY(ams::fs::PathFormatter::Normalize(normalized_path, sizeof(normalized_path), path, std::strlen(path) + 1, SdCardContentMetaPathNormalizePathFlags));
/* Open the filesystem. */
std::shared_ptr<ams::fs::fsa::IFileSystem> fs;
R_TRY(OpenContentMetaFileSystem(std::addressof(fs), normalized_path.GetPath()));
R_TRY(OpenContentMetaFileSystem(std::addressof(fs), normalized_path));
/* Create a holder for the fs. */
std::unique_ptr unique_fs = std::make_unique<ams::fs::SharedFileSystemHolder>(std::move(fs));

View File

@@ -506,7 +506,7 @@ namespace ams::mitm::sysupdater {
R_TRY(FormatUserPackagePath(std::addressof(package_root), path));
/* Ensure that we can create an update context. */
R_TRY(fs::EnsureDirectoryRecursively("@Sdcard:/atmosphere/update/"));
R_TRY(fs::EnsureDirectory("@Sdcard:/atmosphere/update/"));
const char *context_path = "@Sdcard:/atmosphere/update/cup.ctx";
/* Create and initialize the update task. */