Add key combo to uninstall unlaunch alongside the hnaa failsafe

This commit is contained in:
Edoardo Lolletti 2024-04-27 19:09:23 +02:00
parent 027308e1f5
commit 593141e702
3 changed files with 78 additions and 20 deletions

View File

@ -22,6 +22,7 @@ static const char* splashSoundBinaryPatchPath = NULL;
static const char* customBgPath = NULL; static const char* customBgPath = NULL;
volatile bool charging = false; volatile bool charging = false;
volatile u8 batteryLevel = 0; volatile u8 batteryLevel = 0;
static bool wantsUnsafeUnlaunchUninstall = false;
PrintConsole topScreen; PrintConsole topScreen;
PrintConsole bottomScreen; PrintConsole bottomScreen;
@ -32,7 +33,8 @@ enum {
MAIN_MENU_TID_PATCHES, MAIN_MENU_TID_PATCHES,
MAIN_MENU_SOUND_SPLASH_PATCHES, MAIN_MENU_SOUND_SPLASH_PATCHES,
MAIN_MENU_SAFE_UNLAUNCH_INSTALL, MAIN_MENU_SAFE_UNLAUNCH_INSTALL,
MAIN_MENU_EXIT MAIN_MENU_EXIT,
MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL_NO_BACKUP,
}; };
static void setupScreens() static void setupScreens()
@ -92,12 +94,17 @@ static int mainMenu(int cursor)
addMenuItem(m, soundPatchesStr, NULL, foundUnlaunchInstallerVersion == v2_0 && !disableAllPatches && splashSoundBinaryPatchPath != NULL, false); addMenuItem(m, soundPatchesStr, NULL, foundUnlaunchInstallerVersion == v2_0 && !disableAllPatches && splashSoundBinaryPatchPath != NULL, false);
addMenuItem(m, installUnlaunchStr, NULL, foundUnlaunchInstallerVersion != INVALID && !unlaunchFound, false); addMenuItem(m, installUnlaunchStr, NULL, foundUnlaunchInstallerVersion != INVALID && !unlaunchFound, false);
addMenuItem(m, "Exit", NULL, true, false); addMenuItem(m, "Exit", NULL, true, false);
if(wantsUnsafeUnlaunchUninstall)
addMenuItem(m, "Uninstall unlaunch no backup", NULL, unlaunchFound, false);
m->cursor = cursor; m->cursor = cursor;
//bottom screen //bottom screen
printMenu(m); printMenu(m);
int konamiCode = 0;
bool konamiCodeCooldown = false;
while (!programEnd) while (!programEnd)
{ {
swiWaitForVBlank(); swiWaitForVBlank();
@ -108,6 +115,29 @@ static int mainMenu(int cursor)
if (keysDown() & KEY_A) if (keysDown() & KEY_A)
break; break;
if(wantsUnsafeUnlaunchUninstall)
continue;
int held = keysHeld();
if ((held & (KEY_L | KEY_R | KEY_Y)) == (KEY_L | KEY_R | KEY_Y))
{
if(held == (KEY_L | KEY_R | KEY_Y) && !konamiCodeCooldown)
{
konamiCodeCooldown = true;
++konamiCode;
}
}
else
{
konamiCodeCooldown = false;
}
if (konamiCode == 5)
{
wantsUnsafeUnlaunchUninstall = true;
addMenuItem(m, "Uninstall unlaunch no backup", NULL, unlaunchFound, false);
}
} }
int result = m->cursor; int result = m->cursor;
@ -260,8 +290,10 @@ int main(int argc, char **argv)
switch (cursor) switch (cursor)
{ {
case MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL: case MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL:
case MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL_NO_BACKUP:
if(unlaunchFound && nandio_unlock_writing()) { if(unlaunchFound && nandio_unlock_writing()) {
if(uninstallUnlaunch(retailConsole, hnaaUnlaunchFound, retailLauncherTmdPath)) bool unsafeUninstall = wantsUnsafeUnlaunchUninstall && cursor == MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL_NO_BACKUP;
if(uninstallUnlaunch(retailConsole, hnaaUnlaunchFound, retailLauncherTmdPath, unsafeUninstall))
{ {
messageBox("Uninstall successful!\n"); messageBox("Uninstall successful!\n");
unlaunchFound = false; unlaunchFound = false;

View File

@ -65,7 +65,7 @@ bool isLauncherTmdPatched(const char* path)
return c == 0x47; return c == 0x47;
} }
static bool restoreMainTmd(const char* path, bool hasHNAABackup) static bool restoreMainTmd(const char* path, bool hasHNAABackup, bool removeHNAABackup)
{ {
FILE* launcherTmd = fopen(path, "r+b"); FILE* launcherTmd = fopen(path, "r+b");
if(!launcherTmd) if(!launcherTmd)
@ -83,6 +83,20 @@ static bool restoreMainTmd(const char* path, bool hasHNAABackup)
fseek(launcherTmd, -1, SEEK_CUR); fseek(launcherTmd, -1, SEEK_CUR);
c = 0x48; c = 0x48;
fwrite(&c, 1, 1, launcherTmd); fwrite(&c, 1, 1, launcherTmd);
fclose(launcherTmd);
if(removeHNAABackup && hasHNAABackup)
{
if(!toggleFileReadOnly(hnaaTmdPath, false))
{
messageBox("\x1B[31mError:\x1B[33m Failed to mark unlaunch's title.tmd as writable\nLeaving as is\n");
}
else
{
remove(hnaaTmdPath);
rmdir("nand:/title/00030017/484e4141/content");
rmdir("nand:/title/00030017/484e4141");
}
}
} }
else if(c != 0x47) else if(c != 0x47)
{ {
@ -93,7 +107,7 @@ static bool restoreMainTmd(const char* path, bool hasHNAABackup)
// This is also a good idea to make sure the tmd is 520b. // This is also a good idea to make sure the tmd is 520b.
// You will have a much higher brick risk if something goes wrong with a tmd over 520b. // You will have a much higher brick risk if something goes wrong with a tmd over 520b.
// See: http://docs.randommeaninglesscharacters.com/unlaunch.html // See: http://docs.randommeaninglesscharacters.com/unlaunch.html
if(!hasHNAABackup) if(!hasHNAABackup && !removeHNAABackup)
{ {
auto choiceString = [&]{ auto choiceString = [&]{
if(installerVersion != INVALID) if(installerVersion != INVALID)
@ -129,6 +143,19 @@ static bool restoreMainTmd(const char* path, bool hasHNAABackup)
} }
} }
} }
if(removeHNAABackup && hasHNAABackup)
{
if(!toggleFileReadOnly(hnaaTmdPath, false))
{
messageBox("\x1B[31mError:\x1B[33m Failed to mark unlaunch's title.tmd as writable\nLeaving as is\n");
}
else
{
remove(hnaaTmdPath);
rmdir("nand:/title/00030017/484e4141/content");
rmdir("nand:/title/00030017/484e4141");
}
}
if (ftruncate(fileno(launcherTmd), 520) != 0) { if (ftruncate(fileno(launcherTmd), 520) != 0) {
messageBox("\x1B[31mError:\x1B[33m Failed to remove unlaunch\n"); messageBox("\x1B[31mError:\x1B[33m Failed to remove unlaunch\n");
fclose(launcherTmd); fclose(launcherTmd);
@ -141,7 +168,6 @@ static bool restoreMainTmd(const char* path, bool hasHNAABackup)
fclose(launcherTmd); fclose(launcherTmd);
return false; return false;
} }
fclose(launcherTmd);
return true; return true;
} }
@ -188,7 +214,7 @@ static bool restoreProtoTmd(const char* path)
return true; return true;
} }
bool uninstallUnlaunch(bool retailConsole, bool hasHNAABackup, const char* retailLauncherTmdPath) bool uninstallUnlaunch(bool retailConsole, bool hasHNAABackup, const char* retailLauncherTmdPath, bool removeHNAABackup)
{ {
// TODO: handle retailLauncherTmdPresentAndToBePatched = false on retail consoles // TODO: handle retailLauncherTmdPresentAndToBePatched = false on retail consoles
if (retailConsole) { if (retailConsole) {
@ -196,7 +222,7 @@ bool uninstallUnlaunch(bool retailConsole, bool hasHNAABackup, const char* retai
{ {
return false; return false;
} }
if (!restoreMainTmd(retailLauncherTmdPath, hasHNAABackup)) if (!restoreMainTmd(retailLauncherTmdPath, hasHNAABackup, removeHNAABackup))
{ {
return false; return false;
} }

View File

@ -15,7 +15,7 @@ typedef enum UNLAUNCH_VERSION {
const char* getUnlaunchVersionString(UNLAUNCH_VERSION); const char* getUnlaunchVersionString(UNLAUNCH_VERSION);
bool uninstallUnlaunch(bool notProto, bool hasHNAABackup, const char* retailLauncherTmdPath); bool uninstallUnlaunch(bool notProto, bool hasHNAABackup, const char* retailLauncherTmdPath, bool removeHNAABackup);
bool installUnlaunch(bool retailConsole, const char* retailLauncherTmdPath, bool disableAllPatches, const char* splashSoundBinaryPatchPath, const char* customBackgroundPath); bool installUnlaunch(bool retailConsole, const char* retailLauncherTmdPath, bool disableAllPatches, const char* splashSoundBinaryPatchPath, const char* customBackgroundPath);
bool isLauncherTmdPatched(const char* path); bool isLauncherTmdPatched(const char* path);