From d954e85826b7fe011f7857f199738ef9b41fcb29 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 6 Aug 2022 08:48:51 -0700 Subject: [PATCH] fs/emummc: fix DirectoryRedirectionFileSystem not stripping prefix --- ...ystem_directory_redirection_filesystem.hpp | 2 +- .../source/amsmitm_initialization.cpp | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_directory_redirection_filesystem.hpp b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_directory_redirection_filesystem.hpp index 5252348c9..24c48d0c8 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_directory_redirection_filesystem.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_directory_redirection_filesystem.hpp @@ -42,7 +42,7 @@ namespace ams::fssystem { Result ResolveFullPath(fs::Path *out, const fs::Path &path) { if (path.IsMatchHead(m_before_dir.GetString(), m_before_dir.GetLength())) { R_TRY(out->Initialize(m_after_dir)); - R_TRY(out->AppendChild(path)); + R_TRY(out->AppendChild(path.GetString() + m_before_dir.GetLength())); } else { R_TRY(out->Initialize(path)); } diff --git a/stratosphere/ams_mitm/source/amsmitm_initialization.cpp b/stratosphere/ams_mitm/source/amsmitm_initialization.cpp index f0d08fb72..e9979ce52 100644 --- a/stratosphere/ams_mitm/source/amsmitm_initialization.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_initialization.cpp @@ -169,6 +169,43 @@ namespace ams::mitm { util::SNPrintf(emummc_path, sizeof(emummc_path), "%s/eMMC", emummc_file_path); mitm::fs::OpenSdFile(std::addressof(g_emummc_file), emummc_path, ams::fs::OpenMode_Read); } + + /* NOTE: due to an Atmosphere bug, NS accesses to the Nintendo dir accessed /Nintendo/Nintendo */ + /* instead of /Nintendo. This logic is potentially temporary, and fixes the case where this would have happened. */ + { + auto HasDir = [](const char *p) -> bool { bool res{}; R_ABORT_UNLESS(ams::fs::HasDirectory(std::addressof(res), p)); return res; }; + auto HasFile = [](const char *p) -> bool { bool res{}; R_ABORT_UNLESS(ams::fs::HasFile(std::addressof(res), p)); return res; }; + + char emummc_path[ams::fs::EntryNameLengthMax + 1]; + char emummc_bug_path[ams::fs::EntryNameLengthMax + 1]; + util::SNPrintf(emummc_path, sizeof(emummc_path), "%s:/%s", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); + util::SNPrintf(emummc_bug_path, sizeof(emummc_bug_path), "%s:/%s/Nintendo", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); + + if (HasDir(emummc_bug_path)) { + /* Ensure Contents directory exists for normal emummc. */ + /* NOTE: Allowed to fail on already-exists. */ + util::SNPrintf(emummc_path, sizeof(emummc_path), "%s:/%s/Contents", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); + ams::fs::CreateDirectory(emummc_path); + + /* Fix Contents/private */ + util::SNPrintf(emummc_path, sizeof(emummc_path), "%s:/%s/Contents/private", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); + util::SNPrintf(emummc_bug_path, sizeof(emummc_bug_path), "%s:/%s/Nintendo/Contents/private", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); + if (HasFile(emummc_bug_path) && !HasFile(emummc_path)) { + R_ABORT_UNLESS(ams::fs::RenameFile(emummc_bug_path, emummc_path)); + } + + /* Fix Contents/private1 */ + util::SNPrintf(emummc_path, sizeof(emummc_path), "%s:/%s/Contents/private1", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); + util::SNPrintf(emummc_bug_path, sizeof(emummc_bug_path), "%s:/%s/Nintendo/Contents/private1", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); + if (HasFile(emummc_bug_path) && !HasFile(emummc_path)) { + R_ABORT_UNLESS(ams::fs::RenameFile(emummc_bug_path, emummc_path)); + } + + /* Delete bug directory. */ + util::SNPrintf(emummc_bug_path, sizeof(emummc_bug_path), "%s:/%s/Nintendo", ams::fs::impl::SdCardFileSystemMountName, emummc::GetNintendoDirPath()); + R_ABORT_UNLESS(ams::fs::DeleteDirectoryRecursively(emummc_bug_path)); + } + } } /* Connect to set:sys. */