From 7c987b5b9d83155f619d88e062c03aed86d4f7e6 Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 6 May 2024 13:25:44 +0200 Subject: [PATCH] Add option to (un)block updates from within the boot selector and update block warning --- source/MenuUtils.cpp | 44 +++++++++++++++++++++++++++++++++++------- source/MenuUtils.h | 3 ++- source/logger.h | 2 ++ source/main.cpp | 11 +++++++++++ source/main.h | 2 ++ source/utils.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++ source/utils.h | 6 +++++- 7 files changed, 105 insertions(+), 9 deletions(-) diff --git a/source/MenuUtils.cpp b/source/MenuUtils.cpp index 6a850df..93382f3 100644 --- a/source/MenuUtils.cpp +++ b/source/MenuUtils.cpp @@ -4,15 +4,18 @@ #include "InputUtils.h" #include "PairUtils.h" #include "logger.h" +#include "main.h" #include "utils.h" #include "version.h" #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -55,7 +58,7 @@ void writeAutobootOption(std::string &configPath, int32_t autobootOption) { } } -void drawMenuScreen(const std::map &menu, uint32_t selectedIndex, uint32_t autobootIndex) { +void drawMenuScreen(const std::map &menu, uint32_t selectedIndex, uint32_t autobootIndex, bool updatesBlocked) { DrawUtils::beginDraw(); DrawUtils::clear(COLOR_BACKGROUND); @@ -93,6 +96,14 @@ void drawMenuScreen(const std::map &menu, uint32_t select const char *autobootHints = "\ue002/\ue046 Clear Autoboot / \ue003/\ue045 Select Autoboot"; DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(autobootHints) / 2, SCREEN_HEIGHT - 8, autobootHints, true); + if (updatesBlocked) { + DrawUtils::setFontSize(10); + DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 24 - 8 - 4 - 10, "Updates blocked! Hold \ue045 + \ue046 to restore Update folder", true); + } else { + DrawUtils::setFontSize(10); + DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 24 - 8 - 4 - 10, "Updates not blocked! Hold \ue045 + \ue046 to delete Update folder", true); + } + DrawUtils::endDraw(); } @@ -133,16 +144,18 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, c } } - { PairMenu pairMenu; + int32_t holdUpdateBlockedForFrames = 0; while (true) { if (pairMenu.ProcessPairScreen()) { continue; } + InputUtils::InputData input = InputUtils::getControllerInput(); + if (input.trigger & VPAD_BUTTON_UP) { selectedIndex--; @@ -164,10 +177,20 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, c autobootIndex = -1; } else if (input.trigger & (VPAD_BUTTON_Y | VPAD_BUTTON_PLUS)) { autobootIndex = selectedIndex; + } else if ((input.hold & (VPAD_BUTTON_PLUS | VPAD_BUTTON_MINUS)) == (VPAD_BUTTON_PLUS | VPAD_BUTTON_MINUS)) { + if (holdUpdateBlockedForFrames++ > 50) { + if (gUpdatesBlocked) { + gUpdatesBlocked = !RestoreMLCUpdateDirectory(); + } else { + gUpdatesBlocked = DeleteMLCUpdateDirectory(); + } + holdUpdateBlockedForFrames = 0; + } + } else { + holdUpdateBlockedForFrames = 0; } - - drawMenuScreen(menu, selectedIndex, autobootIndex); + drawMenuScreen(menu, selectedIndex, autobootIndex, gUpdatesBlocked); } } @@ -335,7 +358,7 @@ void drawUpdateWarningScreen() { DrawUtils::beginDraw(); DrawUtils::clear(COLOR_BACKGROUND_WARN); - DrawUtils::setFontColor(COLOR_TEXT); + DrawUtils::setFontColor(COLOR_WARNING); // draw top bar DrawUtils::setFontSize(48); @@ -349,8 +372,12 @@ void drawUpdateWarningScreen() { DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 - 48, message, true); message = "Your system might not be blocking updates properly!"; DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 - 24, message, true); + + message = "Press \ue002 to block the updates! This can be reverted in the Boot Selector."; + DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 + 24, message, true); + message = "See https://wiiu.hacks.guide/#/block-updates for more information."; - DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 + 0, message, true); + DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 + 64 + 24, message, true); DrawUtils::setFontSize(16); @@ -360,7 +387,7 @@ void drawUpdateWarningScreen() { // draw bottom bar DrawUtils::drawRectFilled(8, SCREEN_HEIGHT - 24 - 8 - 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_WHITE); DrawUtils::setFontSize(18); - const char *exitHints = "\ue000 Continue / \ue001 Don't show this again"; + const char *exitHints = "\ue000 Continue without blocking / \ue001 Don't show this again"; DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHints) / 2, SCREEN_HEIGHT - 8, exitHints, true); DrawUtils::endDraw(); @@ -400,6 +427,9 @@ void handleUpdateWarningScreen() { InputUtils::InputData input = InputUtils::getControllerInput(); if (input.trigger & VPAD_BUTTON_A) { break; + } else if (input.trigger & VPAD_BUTTON_X) { + gUpdatesBlocked = DeleteMLCUpdateDirectory(); + break; } else if (input.trigger & VPAD_BUTTON_B) { f = fopen(UPDATE_SKIP_PATH, "w"); if (f) { diff --git a/source/MenuUtils.h b/source/MenuUtils.h index 8f5fcd5..a99b2d1 100644 --- a/source/MenuUtils.h +++ b/source/MenuUtils.h @@ -13,8 +13,9 @@ #define COLOR_WHITE Color(0xffffffff) #define COLOR_BLACK Color(0, 0, 0, 255) #define COLOR_BACKGROUND COLOR_BLACK -#define COLOR_BACKGROUND_WARN Color(255, 40, 0, 255) +#define COLOR_BACKGROUND_WARN Color(255, 251, 4, 255) #define COLOR_TEXT COLOR_WHITE +#define COLOR_WARNING COLOR_BLACK #define COLOR_TEXT2 Color(0xB3ffffff) #define COLOR_AUTOBOOT Color(0xaeea00ff) #define COLOR_BORDER Color(204, 204, 204, 255) diff --git a/source/logger.h b/source/logger.h index 97a52c2..e2bc702 100644 --- a/source/logger.h +++ b/source/logger.h @@ -41,6 +41,7 @@ extern "C" { #define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, "## WARN## ", "", FMT, ##ARGS) #define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, "##ERROR## ", "", FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_INFO(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, "## INFO## ", "", FMT, ##ARGS) #define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, WHBLogPrintf, "##ERROR## ", "", FMT, ##ARGS); @@ -58,6 +59,7 @@ extern "C" { #define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "## WARN## ", "\n", FMT, ##ARGS) #define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##ERROR## ", "\n", FMT, ##ARGS) +#define DEBUG_FUNCTION_LINE_INFO(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "## INFO## ", "\n", FMT, ##ARGS) #define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, OSReport, "##ERROR## ", "\n", FMT, ##ARGS); diff --git a/source/main.cpp b/source/main.cpp index dfdae5b..5d9ca95 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -31,6 +31,8 @@ void clearScreen() { free(buffer); } +bool gUpdatesBlocked = false; + int32_t main(int32_t argc, char **argv) { initLogging(); DEBUG_FUNCTION_LINE("Hello from Autoboot Module"); @@ -76,7 +78,16 @@ int32_t main(int32_t argc, char **argv) { FSADirectoryHandle dirHandle{}; if (FSAOpenDir(client, "/vol/storage_mlc01/sys/update", &dirHandle) >= 0) { FSACloseDir(client, dirHandle); + gUpdatesBlocked = false; handleUpdateWarningScreen(); + } else { + FSAStat st{}; + if (FSAGetStat(client, "/vol/storage_mlc01/sys/update", &st) != FS_ERROR_OK) { + DEBUG_FUNCTION_LINE_INFO("Created \"/vol/storage_mlc01/sys/update\" as file"); + FSAFileHandle fd; + FSAOpenFileEx(client, "/vol/storage_mlc01/sys/update", "w", static_cast(0x666), FS_OPEN_FLAG_NONE, 0, &fd); + } + gUpdatesBlocked = true; } } else { DEBUG_FUNCTION_LINE_ERR("Failed to unlock FSA Client"); diff --git a/source/main.h b/source/main.h index 6f70f09..bf294a0 100644 --- a/source/main.h +++ b/source/main.h @@ -1 +1,3 @@ #pragma once + +extern bool gUpdatesBlocked; \ No newline at end of file diff --git a/source/utils.cpp b/source/utils.cpp index ef37365..3d77dec 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -1,5 +1,7 @@ #include "logger.h" +#include #include +#include bool GetTitleIdOfDisc(uint64_t *titleId, bool *discPresent) { if (discPresent) { @@ -30,4 +32,48 @@ bool GetTitleIdOfDisc(uint64_t *titleId, bool *discPresent) { } } return false; +} + +bool DeleteMLCUpdateDirectory() { + bool result = false; + auto client = FSAAddClient(nullptr); + if (client > 0) { + if (Mocha_UnlockFSClientEx(client) == MOCHA_RESULT_SUCCESS) { + if (FSARemove(client, "/vol/storage_mlc01/sys/update") != FS_ERROR_OK) { + DEBUG_FUNCTION_LINE_ERR("Failed to remove update directory"); + } else { + FSAFileHandle fd; + if (FSAOpenFileEx(client, "/vol/storage_mlc01/sys/update", "w", static_cast(0x666), FS_OPEN_FLAG_NONE, 0, &fd) != FS_ERROR_OK) { + DEBUG_FUNCTION_LINE_WARN("Failed to create update file"); + } + result = true; + } + } else { + DEBUG_FUNCTION_LINE_ERR("Failed to unlock FSA Client"); + } + FSADelClient(client); + } else { + DEBUG_FUNCTION_LINE_ERR("Failed to create FSA Client"); + } + return result; +} + +bool RestoreMLCUpdateDirectory() { + bool result = false; + auto client = FSAAddClient(nullptr); + if (client > 0) { + if (Mocha_UnlockFSClientEx(client) == MOCHA_RESULT_SUCCESS) { + FSARemove(client, "/vol/storage_mlc01/sys/update"); // Remove any existing files + if (FSAMakeDir(client, "/vol/storage_mlc01/sys/update", static_cast(0x666)) != FS_ERROR_OK) { + DEBUG_FUNCTION_LINE_WARN("Failed to restore update directory"); + } + result = true; + } else { + DEBUG_FUNCTION_LINE_ERR("Failed to unlock FSA Client"); + } + FSADelClient(client); + } else { + DEBUG_FUNCTION_LINE_ERR("Failed to create FSA Client"); + } + return result; } \ No newline at end of file diff --git a/source/utils.h b/source/utils.h index fd78205..571c994 100644 --- a/source/utils.h +++ b/source/utils.h @@ -28,4 +28,8 @@ std::string string_format(const std::string &format, Args... args) { return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside } -bool GetTitleIdOfDisc(uint64_t *titleId, bool *discPresent); \ No newline at end of file +bool GetTitleIdOfDisc(uint64_t *titleId, bool *discPresent); + +bool DeleteMLCUpdateDirectory(); + +bool RestoreMLCUpdateDirectory(); \ No newline at end of file