diff --git a/source/ApplicationState.cpp b/source/ApplicationState.cpp index 6c09623..c1bf789 100644 --- a/source/ApplicationState.cpp +++ b/source/ApplicationState.cpp @@ -129,6 +129,8 @@ void ApplicationState::render() { } } else if (this->state == STATE_INSTALL_STARTED) { WiiUScreen::drawLine("Installing..."); + } else if (this->state == STATE_INSTALL_BACKUP) { + WiiUScreen::drawLine("... backing up files"); } else if (this->state == STATE_INSTALL_FST) { WiiUScreen::drawLine("... patching title.fst"); } else if (this->state == STATE_INSTALL_COS) { @@ -233,7 +235,15 @@ void ApplicationState::update(Input *input) { return; } } else if (this->state == STATE_INSTALL_STARTED) { - this->state = STATE_INSTALL_FST; + this->state = STATE_INSTALL_BACKUP; + } else if (this->state == STATE_INSTALL_BACKUP) { + auto result = InstallerService::backupAppFiles(this->appInfo->path); + if (result != InstallerService::SUCCESS) { + setError(ERROR_INSTALLER_ERROR); + this->installerError = result; + } else { + this->state = STATE_INSTALL_FST; + } } else if (this->state == STATE_INSTALL_FST) { auto result = InstallerService::patchFST(this->appInfo->path, this->appInfo->fstHash); if (result != InstallerService::SUCCESS) { diff --git a/source/ApplicationState.h b/source/ApplicationState.h index 2e6aa08..4342f33 100644 --- a/source/ApplicationState.h +++ b/source/ApplicationState.h @@ -26,6 +26,7 @@ public: STATE_INSTALL_NO_COLDBOOT_ALLOWED, STATE_INSTALL_CONFIRM_DIALOG, STATE_INSTALL_STARTED, + STATE_INSTALL_BACKUP, STATE_INSTALL_FST, STATE_INSTALL_COS, STATE_INSTALL_RPX, diff --git a/source/InstallerService.cpp b/source/InstallerService.cpp index c373c0e..0fedc61 100644 --- a/source/InstallerService.cpp +++ b/source/InstallerService.cpp @@ -317,6 +317,41 @@ std::string InstallerService::ErrorMessage(InstallerService::eResults error) { } +InstallerService::eResults InstallerService::backupAppFiles(const std::string &path) { + std::string backupList[][2] = { + {"/code/title.fst", "/content/title.fst.bak"}, + {"/code/cos.xml", "/content/cos.xml.bak" }, + {"/code/safe.rpx", "/content/safe.rpx.bak" }, + }; + + for (auto &backupOp : backupList) { + std::string backupSrc = path + backupOp[0]; + std::string backupDst = path + backupOp[1]; + + if (FSUtils::CheckFile(backupDst.c_str())) { + DEBUG_FUNCTION_LINE("Already backed up: %s", backupSrc.c_str()); + continue; + } + + if (!FSUtils::copyFile(backupSrc, backupDst)) { + DEBUG_FUNCTION_LINE("Failed to copy files"); + return FAILED_TO_COPY_FILES; + } + + std::string srcHash = Utils::hashFile(backupSrc); + std::string dstHash = Utils::hashFile(backupDst); + + if (srcHash != dstHash) { + ::remove(backupDst.c_str()); + DEBUG_FUNCTION_LINE("Hashes do not match. %s %s", srcHash.c_str(), dstHash.c_str()); + return FAILED_TO_CHECK_HASH_COPIED_FILES; + } + } + + DEBUG_FUNCTION_LINE("Successfully backed up app files"); + return SUCCESS; +} + InstallerService::eResults InstallerService::patchFST(const std::string &path, const char *fstHash) { std::string fstFilePath = path + "/code/title.fst"; std::string fstBackupFilePath = path + "/code/backup.fst"; diff --git a/source/InstallerService.h b/source/InstallerService.h index 8548fc7..4dec188 100644 --- a/source/InstallerService.h +++ b/source/InstallerService.h @@ -43,6 +43,8 @@ public: return false; } + static eResults backupAppFiles(const std::string &path); + static eResults patchCOS(const std::string &path, char *hash); static eResults checkCOS(const std::string &path, char *hash); @@ -79,4 +81,4 @@ private: static bool patchCOSXMLData(pugi::xml_document *doc); static eResults checkFileHash(const std::string &filePath, const std::string &hash); -}; \ No newline at end of file +};