diff --git a/Data/Sys/Wii/shared2/ec/shopsetu.log b/Data/Sys/Wii/shared2/ec/shopsetu.log deleted file mode 100644 index 4e4e493570..0000000000 Binary files a/Data/Sys/Wii/shared2/ec/shopsetu.log and /dev/null differ diff --git a/Data/Sys/Wii/shared2/succession/shop.log b/Data/Sys/Wii/shared2/succession/shop.log deleted file mode 100644 index 4e4e493570..0000000000 Binary files a/Data/Sys/Wii/shared2/succession/shop.log and /dev/null differ 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..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" @@ -61,14 +66,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 +79,96 @@ 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(); } } + +/// 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() +{ + 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{fs}; + 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(); } 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));