From 5f567b38fe2a8ac067d051fd3669bb2c43f50f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 12 May 2018 16:52:33 +0200 Subject: [PATCH 1/4] WiiRoot: Move content manipulation to separate functions {Initialize,Shutdown}WiiRoot should only be responsible for setting the SESSION_WII_ROOT or managing the temporary NAND directory. Move all the content manipulation out of these functions to ensure separation of concerns and call them after/before WiiRoot init/shutdown to make sure they operate on the correct root. --- Source/Core/Core/HW/HW.cpp | 2 ++ Source/Core/Core/WiiRoot.cpp | 65 ++++++++++++++++++++++-------------- Source/Core/Core/WiiRoot.h | 4 +++ 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/Source/Core/Core/HW/HW.cpp b/Source/Core/Core/HW/HW.cpp index 5cf808ee3f..a60102bf7e 100644 --- a/Source/Core/Core/HW/HW.cpp +++ b/Source/Core/Core/HW/HW.cpp @@ -54,11 +54,13 @@ void Init() Core::InitializeWiiRoot(Core::WantsDeterminism()); IOS::Init(); IOS::HLE::Init(); // Depends on Memory + Core::InitializeWiiFileSystemContents(); } } void Shutdown() { + Core::CleanUpWiiFileSystemContents(); // IOS should always be shut down regardless of bWii because it can be running in GC mode (MIOS). IOS::HLE::Shutdown(); // Depends on Memory IOS::Shutdown(); diff --git a/Source/Core/Core/WiiRoot.cpp b/Source/Core/Core/WiiRoot.cpp index 8058ab2685..526b2e923b 100644 --- a/Source/Core/Core/WiiRoot.cpp +++ b/Source/Core/Core/WiiRoot.cpp @@ -61,14 +61,8 @@ void InitializeWiiRoot(bool use_temporary) ERROR_LOG(IOS_FS, "Could not create temporary directory"); return; } - File::CopyDir(File::GetSysDirectory() + WII_USER_DIR, s_temp_wii_root); WARN_LOG(IOS_FS, "Using temporary directory %s for minimal Wii FS", s_temp_wii_root.c_str()); File::SetUserPath(D_SESSION_WIIROOT_IDX, s_temp_wii_root); - // Generate a SYSCONF with default settings for the temporary Wii NAND. - SysConf sysconf{IOS::HLE::Kernel{}.GetFS()}; - sysconf.Save(); - - InitializeDeterministicWiiSaves(); } else { @@ -80,27 +74,48 @@ void ShutdownWiiRoot() { if (!s_temp_wii_root.empty()) { - const u64 title_id = SConfig::GetInstance().GetTitleID(); - std::string save_path = Common::GetTitleDataPath(title_id, Common::FROM_SESSION_ROOT); - std::string user_save_path = Common::GetTitleDataPath(title_id, Common::FROM_CONFIGURED_ROOT); - std::string user_backup_path = File::GetUserPath(D_BACKUP_IDX) + - StringFromFormat("%08x/%08x/", static_cast(title_id >> 32), - static_cast(title_id)); - if (File::Exists(save_path + "/banner.bin") && SConfig::GetInstance().bEnableMemcardSdWriting) - { - // Backup the existing save just in case it's still needed. - if (File::Exists(user_save_path + "/banner.bin")) - { - if (File::Exists(user_backup_path)) - File::DeleteDirRecursively(user_backup_path); - File::CopyDir(user_save_path, user_backup_path); - File::DeleteDirRecursively(user_save_path); - } - File::CopyDir(save_path, user_save_path); - File::DeleteDirRecursively(save_path); - } File::DeleteDirRecursively(s_temp_wii_root); s_temp_wii_root.clear(); } } + +void InitializeWiiFileSystemContents() +{ + if (s_temp_wii_root.empty()) + return; + + File::CopyDir(File::GetSysDirectory() + WII_USER_DIR, s_temp_wii_root); + + // Generate a SYSCONF with default settings for the temporary Wii NAND. + SysConf sysconf{IOS::HLE::GetIOS()->GetFS()}; + sysconf.Save(); + + InitializeDeterministicWiiSaves(); } + +void CleanUpWiiFileSystemContents() +{ + if (s_temp_wii_root.empty()) + return; + + const u64 title_id = SConfig::GetInstance().GetTitleID(); + std::string save_path = Common::GetTitleDataPath(title_id, Common::FROM_SESSION_ROOT); + std::string user_save_path = Common::GetTitleDataPath(title_id, Common::FROM_CONFIGURED_ROOT); + std::string user_backup_path = + File::GetUserPath(D_BACKUP_IDX) + + StringFromFormat("%08x/%08x/", static_cast(title_id >> 32), static_cast(title_id)); + if (File::Exists(save_path + "/banner.bin") && SConfig::GetInstance().bEnableMemcardSdWriting) + { + // Backup the existing save just in case it's still needed. + if (File::Exists(user_save_path + "/banner.bin")) + { + if (File::Exists(user_backup_path)) + File::DeleteDirRecursively(user_backup_path); + File::CopyDir(user_save_path, user_backup_path); + File::DeleteDirRecursively(user_save_path); + } + File::CopyDir(save_path, user_save_path); + File::DeleteDirRecursively(save_path); + } +} +} // namespace Core diff --git a/Source/Core/Core/WiiRoot.h b/Source/Core/Core/WiiRoot.h index 7174fd9943..8aab1dc25e 100644 --- a/Source/Core/Core/WiiRoot.h +++ b/Source/Core/Core/WiiRoot.h @@ -8,4 +8,8 @@ namespace Core { void InitializeWiiRoot(bool use_temporary); void ShutdownWiiRoot(); + +// Initialize or clean up the filesystem contents. +void InitializeWiiFileSystemContents(); +void CleanUpWiiFileSystemContents(); } From 94dc746351f8549b8aac75736f59fd577e690f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 12 May 2018 17:08:24 +0200 Subject: [PATCH 2/4] Copy Wii NAND data to user NAND in WiiRoot Dolphin doesn't use any of the WC24 files, so this can be done when actually starting emulation in WiiRoot. The benefit of moving the copy is that we don't need to handle temporary NANDs in a special way. --- Source/Core/Core/WiiRoot.cpp | 4 ++-- Source/Core/UICommon/UICommon.cpp | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/WiiRoot.cpp b/Source/Core/Core/WiiRoot.cpp index 526b2e923b..5aa435c806 100644 --- a/Source/Core/Core/WiiRoot.cpp +++ b/Source/Core/Core/WiiRoot.cpp @@ -81,11 +81,11 @@ void ShutdownWiiRoot() void InitializeWiiFileSystemContents() { + File::CopyDir(File::GetSysDirectory() + WII_USER_DIR, File::GetUserPath(D_SESSION_WIIROOT_IDX)); + if (s_temp_wii_root.empty()) return; - File::CopyDir(File::GetSysDirectory() + WII_USER_DIR, s_temp_wii_root); - // Generate a SYSCONF with default settings for the temporary Wii NAND. SysConf sysconf{IOS::HLE::GetIOS()->GetFS()}; sysconf.Save(); diff --git a/Source/Core/UICommon/UICommon.cpp b/Source/Core/UICommon/UICommon.cpp index 7ac4c226fb..b4d3a8acfc 100644 --- a/Source/Core/UICommon/UICommon.cpp +++ b/Source/Core/UICommon/UICommon.cpp @@ -130,9 +130,6 @@ void SetLocale(std::string locale_name) void CreateDirectories() { - // Copy initial Wii NAND data from Sys to User. - File::CopyDir(File::GetSysDirectory() + WII_USER_DIR, File::GetUserPath(D_WIIROOT_IDX)); - File::CreateFullPath(File::GetUserPath(D_USER_IDX)); File::CreateFullPath(File::GetUserPath(D_CACHE_IDX)); File::CreateFullPath(File::GetUserPath(D_CONFIG_IDX)); From 037040c7a0ca2b6724d52f47a222eb8145d62dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 12 May 2018 18:51:45 +0200 Subject: [PATCH 3/4] Data: Remove /shared2/{ec,succession} These are created by the ECDK library (used in the Wii Shop Channel for example) on first use. There's no need to provide dummy files. --- Data/Sys/Wii/shared2/ec/shopsetu.log | Bin 32 -> 0 bytes Data/Sys/Wii/shared2/succession/shop.log | Bin 32 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Data/Sys/Wii/shared2/ec/shopsetu.log delete mode 100644 Data/Sys/Wii/shared2/succession/shop.log diff --git a/Data/Sys/Wii/shared2/ec/shopsetu.log b/Data/Sys/Wii/shared2/ec/shopsetu.log deleted file mode 100644 index 4e4e4935707a596987ec1cc32e3d0d587dbe4f04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 KcmZQzzz+ZbAOHaX diff --git a/Data/Sys/Wii/shared2/succession/shop.log b/Data/Sys/Wii/shared2/succession/shop.log deleted file mode 100644 index 4e4e4935707a596987ec1cc32e3d0d587dbe4f04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 KcmZQzzz+ZbAOHaX From 48fa835bd3474dea800b767bc2d2666a6e3d0197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 12 May 2018 18:44:47 +0200 Subject: [PATCH 4/4] WiiRoot: Copy initial NAND files with proper metadata --- Source/Core/Core/WiiRoot.cpp | 57 ++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/WiiRoot.cpp b/Source/Core/Core/WiiRoot.cpp index 5aa435c806..2f74f11580 100644 --- a/Source/Core/Core/WiiRoot.cpp +++ b/Source/Core/Core/WiiRoot.cpp @@ -5,14 +5,19 @@ #include "Core/WiiRoot.h" #include +#include #include "Common/CommonPaths.h" +#include "Common/CommonTypes.h" +#include "Common/File.h" #include "Common/FileUtil.h" #include "Common/Logging/Log.h" #include "Common/NandPaths.h" #include "Common/StringUtil.h" #include "Core/ConfigManager.h" +#include "Core/IOS/FS/FileSystem.h" #include "Core/IOS/IOS.h" +#include "Core/IOS/Uids.h" #include "Core/Movie.h" #include "Core/NetPlayClient.h" #include "Core/SysConf.h" @@ -79,15 +84,63 @@ void ShutdownWiiRoot() } } +/// Copy a directory from host_source_path (on the host FS) to nand_target_path on the NAND. +/// +/// Both paths should not have trailing slashes. To specify the NAND root, use "". +static bool CopySysmenuFilesToFS(IOS::HLE::FS::FileSystem* fs, const std::string& host_source_path, + const std::string& nand_target_path) +{ + const auto entries = File::ScanDirectoryTree(host_source_path, false); + for (const File::FSTEntry& entry : entries.children) + { + const std::string host_path = host_source_path + '/' + entry.virtualName; + const std::string nand_path = nand_target_path + '/' + entry.virtualName; + constexpr IOS::HLE::FS::Mode rw_mode = IOS::HLE::FS::Mode::ReadWrite; + + if (entry.isDirectory) + { + fs->CreateDirectory(IOS::SYSMENU_UID, IOS::SYSMENU_GID, nand_path, 0, rw_mode, rw_mode, + rw_mode); + + if (!CopySysmenuFilesToFS(fs, host_path, nand_path)) + return false; + } + else + { + // Do not overwrite any existing files. + if (fs->GetMetadata(IOS::SYSMENU_UID, IOS::SYSMENU_UID, nand_path).Succeeded()) + continue; + + File::IOFile host_file{host_path, "rb"}; + std::vector file_data(host_file.GetSize()); + if (!host_file.ReadBytes(file_data.data(), file_data.size())) + return false; + + const auto nand_file = fs->CreateAndOpenFile(IOS::SYSMENU_UID, IOS::SYSMENU_GID, nand_path, + rw_mode, rw_mode, rw_mode); + if (!nand_file || !nand_file->Write(file_data.data(), file_data.size())) + return false; + } + } + return true; +} + void InitializeWiiFileSystemContents() { - File::CopyDir(File::GetSysDirectory() + WII_USER_DIR, File::GetUserPath(D_SESSION_WIIROOT_IDX)); + const auto fs = IOS::HLE::GetIOS()->GetFS(); + + // Some games (such as Mario Kart Wii) assume that NWC24 files will always be present + // even upon the first launch as they are normally created by the system menu. + // Because we do not require the system menu to be run, WiiConnect24 files must be copied + // to the NAND manually. + if (!CopySysmenuFilesToFS(fs.get(), File::GetSysDirectory() + WII_USER_DIR, "")) + WARN_LOG(CORE, "Failed to copy initial System Menu files to the NAND"); if (s_temp_wii_root.empty()) return; // Generate a SYSCONF with default settings for the temporary Wii NAND. - SysConf sysconf{IOS::HLE::GetIOS()->GetFS()}; + SysConf sysconf{fs}; sysconf.Save(); InitializeDeterministicWiiSaves();