From a621fdf857460d0cb4cb493fd5dc4f3b69d37295 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Thu, 16 Jun 2022 03:59:14 +0200 Subject: [PATCH] Core: In deterministic mode, build SD cards with a consistent filename order and dummy timestamps. --- Source/Core/Common/FatFsUtil.cpp | 22 ++++++++++++++++++++-- Source/Core/Common/FatFsUtil.h | 2 +- Source/Core/Core/Core.cpp | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Source/Core/Common/FatFsUtil.cpp b/Source/Core/Common/FatFsUtil.cpp index ffd42e68ab..7e0c2e2a21 100644 --- a/Source/Core/Common/FatFsUtil.cpp +++ b/Source/Core/Common/FatFsUtil.cpp @@ -30,6 +30,7 @@ enum : u32 static std::mutex s_fatfs_mutex; static File::IOFile s_image; +static bool s_deterministic; extern "C" DSTATUS disk_status(BYTE pdrv) { @@ -96,6 +97,9 @@ extern "C" DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff) extern "C" DWORD get_fattime(void) { + if (s_deterministic) + return 0; + const std::time_t time = std::time(nullptr); std::tm tm; #ifdef _WIN32 @@ -286,13 +290,26 @@ static bool Pack(const File::FSTEntry& entry, bool is_root, std::vector& tmp return true; } -bool SyncSDFolderToSDImage() +static void SortFST(File::FSTEntry* root) { + std::sort(root->children.begin(), root->children.end(), + [](const File::FSTEntry& lhs, const File::FSTEntry& rhs) { + return lhs.virtualName < rhs.virtualName; + }); + for (auto& child : root->children) + SortFST(&child); +} + +bool SyncSDFolderToSDImage(bool deterministic) +{ + deterministic = true; const std::string root_path = File::GetUserPath(D_WIISDCARDSYNCFOLDER_IDX); if (!File::IsDirectory(root_path)) return false; - const File::FSTEntry root = File::ScanDirectoryTree(root_path, true); + File::FSTEntry root = File::ScanDirectoryTree(root_path, true); + if (deterministic) + SortFST(&root); if (!CheckIfFATCompatible(root)) return false; @@ -302,6 +319,7 @@ bool SyncSDFolderToSDImage() size = AlignUp(size, MAX_CLUSTER_SIZE); std::lock_guard lk(s_fatfs_mutex); + s_deterministic = deterministic; const std::string image_path = File::GetUserPath(F_WIISDCARDIMAGE_IDX); const std::string temp_image_path = File::GetTempFilenameForAtomicWrite(image_path); diff --git a/Source/Core/Common/FatFsUtil.h b/Source/Core/Common/FatFsUtil.h index bb981e2267..91f28330fb 100644 --- a/Source/Core/Common/FatFsUtil.h +++ b/Source/Core/Common/FatFsUtil.h @@ -7,6 +7,6 @@ namespace Common { -bool SyncSDFolderToSDImage(); +bool SyncSDFolderToSDImage(bool deterministic); bool SyncSDImageToSDFolder(); } // namespace Common diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 79ac6a2ae6..f2a9ec334d 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -499,7 +499,7 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi bool sync_sd_folder = core_parameter.bWii && Config::Get(Config::MAIN_WII_SD_CARD) && Config::Get(Config::MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC); if (sync_sd_folder) - sync_sd_folder = Common::SyncSDFolderToSDImage(); + sync_sd_folder = Common::SyncSDFolderToSDImage(Core::WantsDeterminism()); Common::ScopeGuard sd_folder_sync_guard{[sync_sd_folder] { if (sync_sd_folder && Config::Get(Config::MAIN_ALLOW_SD_WRITES))