From 0737ff771dbbc25d91e606639e29a91016908800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo?= Date: Fri, 10 Jan 2025 08:57:34 -0300 Subject: [PATCH] Use different path for patched executable. (#70) * Use different path for patched executable. * Use error code variant on std::filesystem::create_directories. --- UnleashedRecomp/install/installer.cpp | 54 +++++++++++++-------------- UnleashedRecomp/install/installer.h | 2 +- UnleashedRecomp/main.cpp | 6 +-- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/UnleashedRecomp/install/installer.cpp b/UnleashedRecomp/install/installer.cpp index fd561ed..b271b97 100644 --- a/UnleashedRecomp/install/installer.cpp +++ b/UnleashedRecomp/install/installer.cpp @@ -17,6 +17,7 @@ static const std::string GameDirectory = "game"; static const std::string DLCDirectory = "dlc"; +static const std::string PatchedDirectory = "patched"; static const std::string ApotosShamarDirectory = DLCDirectory + "/Apotos & Shamar Adventure Pack"; static const std::string ChunnanDirectory = DLCDirectory + "/Chun-nan Adventure Pack"; static const std::string EmpireCityAdabatDirectory = DLCDirectory + "/Empire City & Adabat Adventure Pack"; @@ -104,7 +105,8 @@ static bool copyFile(const FilePair &pair, const uint64_t *fileHashes, VirtualFi std::filesystem::path parentPath = targetPath.parent_path(); if (!std::filesystem::exists(parentPath)) { - std::filesystem::create_directories(parentPath); + std::error_code ec; + std::filesystem::create_directories(parentPath, ec); } while (!parentPath.empty()) { @@ -196,9 +198,10 @@ static DLC detectDLC(const std::filesystem::path &sourcePath, VirtualFileSystem } } -bool Installer::checkGameInstall(const std::filesystem::path &baseDirectory) +bool Installer::checkGameInstall(const std::filesystem::path &baseDirectory, std::filesystem::path &modulePath) { - return std::filesystem::exists(baseDirectory / GameDirectory / GameExecutableFile); + modulePath = baseDirectory / PatchedDirectory / GameExecutableFile; + return std::filesystem::exists(modulePath); } bool Installer::checkDLCInstall(const std::filesystem::path &baseDirectory, DLC dlc) @@ -255,7 +258,8 @@ bool Installer::computeTotalSize(std::span filePairs, const uint bool Installer::copyFiles(std::span filePairs, const uint64_t *fileHashes, VirtualFileSystem &sourceVfs, const std::filesystem::path &targetDirectory, const std::string &validationFile, bool skipHashChecks, Journal &journal, const std::function &progressCallback) { - if (!std::filesystem::exists(targetDirectory) && !std::filesystem::create_directories(targetDirectory)) + std::error_code ec; + if (!std::filesystem::exists(targetDirectory) && !std::filesystem::create_directories(targetDirectory, ec)) { journal.lastResult = Journal::Result::DirectoryCreationFailed; journal.lastErrorMessage = "Unable to create directory at " + fromPath(targetDirectory); @@ -452,12 +456,28 @@ bool Installer::install(const Sources &sources, const std::filesystem::path &tar return false; } + // Create the directory where the patched executable will be stored. + std::error_code ec; + std::filesystem::path patchedDirectory = targetDirectory / PatchedDirectory; + if (!std::filesystem::exists(patchedDirectory) && !std::filesystem::create_directories(patchedDirectory, ec)) + { + journal.lastResult = Journal::Result::DirectoryCreationFailed; + journal.lastErrorMessage = "Unable to create directory at " + fromPath(patchedDirectory); + return false; + } + + journal.createdDirectories.insert(patchedDirectory); + // Patch the executable with the update's file. std::filesystem::path baseXexPath = targetDirectory / GameDirectory / GameExecutableFile; std::filesystem::path patchPath = targetDirectory / UpdateDirectory / UpdateExecutablePatchFile; - std::filesystem::path patchedXexPath = targetDirectory / GameDirectory / (GameExecutableFile + TempExtension); + std::filesystem::path patchedXexPath = patchedDirectory / GameExecutableFile; XexPatcher::Result patcherResult = XexPatcher::apply(baseXexPath, patchPath, patchedXexPath); - if (patcherResult != XexPatcher::Result::Success) + if (patcherResult == XexPatcher::Result::Success) + { + journal.createdFiles.push_back(patchedXexPath); + } + else { journal.lastResult = Journal::Result::PatchProcessFailed; journal.lastPatcherResult = patcherResult; @@ -469,28 +489,6 @@ bool Installer::install(const Sources &sources, const std::filesystem::path &tar journal.progressCounter += PatcherContribution; progressCallback(); - // Replace the executable by renaming and deleting in a safe way. - std::error_code ec; - std::filesystem::path oldXexPath = targetDirectory / GameDirectory / (GameExecutableFile + OldExtension); - std::filesystem::rename(baseXexPath, oldXexPath, ec); - if (ec) - { - journal.lastResult = Journal::Result::PatchReplacementFailed; - journal.lastErrorMessage = "Failed to rename executable."; - return false; - } - - std::filesystem::rename(patchedXexPath, baseXexPath, ec); - if (ec) - { - std::filesystem::rename(oldXexPath, baseXexPath, ec); - journal.lastResult = Journal::Result::PatchReplacementFailed; - journal.lastErrorMessage = "Failed to rename executable."; - return false; - } - - std::filesystem::remove(oldXexPath); - return true; } diff --git a/UnleashedRecomp/install/installer.h b/UnleashedRecomp/install/installer.h index 39cbf98..c61beda 100644 --- a/UnleashedRecomp/install/installer.h +++ b/UnleashedRecomp/install/installer.h @@ -71,7 +71,7 @@ struct Installer uint64_t totalSize = 0; }; - static bool checkGameInstall(const std::filesystem::path &baseDirectory); + static bool checkGameInstall(const std::filesystem::path &baseDirectory, std::filesystem::path &modulePath); static bool checkDLCInstall(const std::filesystem::path &baseDirectory, DLC dlc); static bool checkAllDLC(const std::filesystem::path &baseDirectory); static bool computeTotalSize(std::span filePairs, const uint64_t *fileHashes, VirtualFileSystem &sourceVfs, Journal &journal, uint64_t &totalSize); diff --git a/UnleashedRecomp/main.cpp b/UnleashedRecomp/main.cpp index 6a6c3bc..262a4b8 100644 --- a/UnleashedRecomp/main.cpp +++ b/UnleashedRecomp/main.cpp @@ -19,8 +19,6 @@ #include #include -#define GAME_XEX_PATH "game:\\default.xex" - const size_t XMAIOBegin = 0x7FEA0000; const size_t XMAIOEnd = XMAIOBegin + 0x0000FFFF; @@ -171,7 +169,8 @@ int main(int argc, char *argv[]) HostStartup(); - bool isGameInstalled = Installer::checkGameInstall(GAME_INSTALL_DIRECTORY); + std::filesystem::path modulePath; + bool isGameInstalled = Installer::checkGameInstall(GAME_INSTALL_DIRECTORY, modulePath); bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled; if (runInstallerWizard) { @@ -189,7 +188,6 @@ int main(int argc, char *argv[]) KiSystemStartup(); - auto modulePath = FileSystem::ResolvePath(GAME_XEX_PATH, false); uint32_t entry = LdrLoadModule(modulePath); if (!runInstallerWizard)