mirror of
https://github.com/rvtr/unlaunch-installer_dev.git
synced 2026-01-26 13:43:08 -05:00
Add key combo to uninstall unlaunch alongside the hnaa failsafe
This commit is contained in:
parent
027308e1f5
commit
593141e702
@ -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;
|
||||||
@ -158,22 +188,22 @@ int main(int argc, char **argv)
|
|||||||
messageBox("nand init \x1B[31mfailed\n\x1B[47m");
|
messageBox("nand init \x1B[31mfailed\n\x1B[47m");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (batteryLevel < 7 && !charging)
|
while (batteryLevel < 7 && !charging)
|
||||||
{
|
{
|
||||||
if (choiceBox("\x1B[47mBattery is too low!\nPlease plug in the console.\n\nContinue?") == NO)
|
if (choiceBox("\x1B[47mBattery is too low!\nPlease plug in the console.\n\nContinue?") == NO)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceList* deviceList = getDeviceList();
|
DeviceList* deviceList = getDeviceList();
|
||||||
|
|
||||||
const char* installerPath = (argc > 0) ? argv[0] : (deviceList ? deviceList->appname : "sd:/ntrboot.nds");
|
const char* installerPath = (argc > 0) ? argv[0] : (deviceList ? deviceList->appname : "sd:/ntrboot.nds");
|
||||||
|
|
||||||
if (!nitroFSInit(installerPath))
|
if (!nitroFSInit(installerPath))
|
||||||
{
|
{
|
||||||
messageBox("nitroFSInit()...\x1B[31mFailed\n\x1B[47m");
|
messageBox("nitroFSInit()...\x1B[31mFailed\n\x1B[47m");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileExists("sd:/unlaunch.dsi"))
|
if (fileExists("sd:/unlaunch.dsi"))
|
||||||
{
|
{
|
||||||
foundUnlaunchInstallerVersion = loadUnlaunchInstaller("sd:/unlaunch.dsi");
|
foundUnlaunchInstallerVersion = loadUnlaunchInstaller("sd:/unlaunch.dsi");
|
||||||
@ -184,7 +214,7 @@ int main(int argc, char **argv)
|
|||||||
"Attempting to use the bundled one.");
|
"Attempting to use the bundled one.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(foundUnlaunchInstallerVersion == INVALID)
|
if(foundUnlaunchInstallerVersion == INVALID)
|
||||||
{
|
{
|
||||||
foundUnlaunchInstallerVersion = loadUnlaunchInstaller("nitro:/unlaunch.dsi");
|
foundUnlaunchInstallerVersion = loadUnlaunchInstaller("nitro:/unlaunch.dsi");
|
||||||
@ -195,7 +225,7 @@ int main(int argc, char **argv)
|
|||||||
"Installing unlaunch won't be possible.");
|
"Installing unlaunch won't be possible.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fileExists("nitro:/unlaunch-patch.bin"))
|
if(fileExists("nitro:/unlaunch-patch.bin"))
|
||||||
{
|
{
|
||||||
splashSoundBinaryPatchPath = "nitro:/unlaunch-patch.bin";
|
splashSoundBinaryPatchPath = "nitro:/unlaunch-patch.bin";
|
||||||
@ -236,11 +266,11 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
// HWINFO_S may not always exist (PRE_IMPORT). Fill in defaults if that happens.
|
// HWINFO_S may not always exist (PRE_IMPORT). Fill in defaults if that happens.
|
||||||
}
|
}
|
||||||
|
|
||||||
// I own and know of many people with retail and dev prototypes
|
// I own and know of many people with retail and dev prototypes
|
||||||
// These can normally be identified by having the region set to ALL (0x41)
|
// These can normally be identified by having the region set to ALL (0x41)
|
||||||
retailConsole = (region != 0x41 && region != 0xFF);
|
retailConsole = (region != 0x41 && region != 0xFF);
|
||||||
|
|
||||||
unsigned long long tmdSize = getFileSizePath(hnaaTmdPath);
|
unsigned long long tmdSize = getFileSizePath(hnaaTmdPath);
|
||||||
if (tmdSize > 520)
|
if (tmdSize > 520)
|
||||||
{
|
{
|
||||||
@ -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;
|
||||||
@ -273,7 +305,7 @@ int main(int argc, char **argv)
|
|||||||
nandio_synchronize_fats();
|
nandio_synchronize_fats();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAIN_MENU_CUSTOM_BG:
|
case MAIN_MENU_CUSTOM_BG:
|
||||||
if(foundUnlaunchInstallerVersion != INVALID) {
|
if(foundUnlaunchInstallerVersion != INVALID) {
|
||||||
const char* customBg = backgroundMenu();
|
const char* customBg = backgroundMenu();
|
||||||
@ -289,13 +321,13 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAIN_MENU_TID_PATCHES:
|
case MAIN_MENU_TID_PATCHES:
|
||||||
if(foundUnlaunchInstallerVersion == v1_9 || foundUnlaunchInstallerVersion == v2_0) {
|
if(foundUnlaunchInstallerVersion == v1_9 || foundUnlaunchInstallerVersion == v2_0) {
|
||||||
disableAllPatches = !disableAllPatches;
|
disableAllPatches = !disableAllPatches;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAIN_MENU_SOUND_SPLASH_PATCHES:
|
case MAIN_MENU_SOUND_SPLASH_PATCHES:
|
||||||
if(foundUnlaunchInstallerVersion == v2_0 && !disableAllPatches && splashSoundBinaryPatchPath != NULL) {
|
if(foundUnlaunchInstallerVersion == v2_0 && !disableAllPatches && splashSoundBinaryPatchPath != NULL) {
|
||||||
enableSoundAndSplash = !enableSoundAndSplash;
|
enableSoundAndSplash = !enableSoundAndSplash;
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user