From 755506d4047af89aaa4cb90720ef721582431784 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Tue, 7 Jul 2020 06:57:20 -0400
Subject: [PATCH] vfs_real: Fix MoveFile

The file wasn't closed prior to being renamed / moved, throwing an error that states "The process cannot access the file because it is being used by another process." Fix this by closing the file prior to a rename / move operation.

Fixes saving in Luigi's Mansion 3 and KATANA KAMI: A Way of the Samurai Story.
---
 src/core/file_sys/vfs_real.cpp | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index e21300a7c7..96ce5957c4 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -112,19 +112,26 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_
     const auto new_path =
         FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault);
 
-    if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) ||
-        FileUtil::IsDirectory(old_path) || !FileUtil::Rename(old_path, new_path))
-        return nullptr;
-
     if (cache.find(old_path) != cache.end()) {
-        auto cached = cache[old_path];
-        if (!cached.expired()) {
-            auto file = cached.lock();
-            file->Open(new_path, "r+b");
-            cache.erase(old_path);
-            cache[new_path] = file;
+        auto file = cache[old_path].lock();
+
+        if (!cache[old_path].expired()) {
+            file->Close();
         }
+
+        if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) ||
+            FileUtil::IsDirectory(old_path) || !FileUtil::Rename(old_path, new_path)) {
+            return nullptr;
+        }
+
+        cache.erase(old_path);
+        file->Open(new_path, "r+b");
+        cache[new_path] = file;
+    } else {
+        UNREACHABLE();
+        return nullptr;
     }
+
     return OpenFile(new_path, Mode::ReadWrite);
 }