From 16755bffeac9862a618f072cf7cc3506aab69f26 Mon Sep 17 00:00:00 2001 From: RocketRobz Date: Thu, 26 Sep 2024 01:36:57 -0600 Subject: [PATCH] Prevent launching corrupt `.nds` files --- romsel_aktheme/arm9/source/fileBrowse.cpp | 10 +++++++--- romsel_aktheme/arm9/source/iconTitle.cpp | 7 +++++-- romsel_aktheme/arm9/source/ndsheaderbanner.cpp | 1 + romsel_aktheme/arm9/source/ndsheaderbanner.h | 1 + romsel_dsimenutheme/arm9/source/fileBrowse.cpp | 11 +++++++---- romsel_dsimenutheme/arm9/source/iconTitle.cpp | 2 ++ romsel_dsimenutheme/arm9/source/language.inl | 4 +++- romsel_dsimenutheme/arm9/source/ndsheaderbanner.cpp | 1 + romsel_dsimenutheme/arm9/source/ndsheaderbanner.h | 1 + .../nitrofiles/languages/en/language.ini | 4 +++- romsel_r4theme/arm9/source/fileBrowse.cpp | 7 ++++--- romsel_r4theme/arm9/source/iconTitle.cpp | 2 ++ romsel_r4theme/arm9/source/ndsheaderbanner.cpp | 1 + romsel_r4theme/arm9/source/ndsheaderbanner.h | 1 + 14 files changed, 39 insertions(+), 14 deletions(-) diff --git a/romsel_aktheme/arm9/source/fileBrowse.cpp b/romsel_aktheme/arm9/source/fileBrowse.cpp index 6c061dd1dc..d173267dde 100644 --- a/romsel_aktheme/arm9/source/fileBrowse.cpp +++ b/romsel_aktheme/arm9/source/fileBrowse.cpp @@ -437,6 +437,7 @@ void getGameInfo0(const int fileOffset, std::vector dirContents) { if (bnrRomType[0] != 0) { bnrWirelessIcon[0] = 0; + isValid[0] = true; isTwlm[0] = false; isDSiWare[0] = false; isHomebrew[0] = 0; @@ -531,6 +532,7 @@ void loadIcons(const int screenOffset, std::vector dirContents) { if (bnrRomType[n] != 0) { bnrWirelessIcon[n] = 0; + isValid[n] = true; isTwlm[n] = false; isDSiWare[n] = false; isHomebrew[n] = 0; @@ -642,6 +644,7 @@ void loadIconUp(const int screenOffset, std::vector dirContents) { if (bnrRomType[n] != 0) { bnrWirelessIcon[n] = 0; + isValid[n] = true; isTwlm[n] = false; isDSiWare[n] = false; isHomebrew[n] = 0; @@ -753,6 +756,7 @@ void loadIconDown(const int screenOffset, std::vector dirContents) { if (bnrRomType[n] != 0) { bnrWirelessIcon[n] = 0; + isValid[n] = true; isTwlm[n] = false; isDSiWare[n] = false; isHomebrew[n] = 0; @@ -1731,13 +1735,13 @@ std::string browseForFile(const std::vector extensionList) { if (ms().ak_viewMode == TWLSettings::EViewList) { cursorPosOnScreen = 0; } - if (!isTwlm[cursorPosOnScreen]) { + if (isValid[cursorPosOnScreen] && !isTwlm[cursorPosOnScreen]) { loadPerGameSettings(dirContents.at(fileOffset).name); } int hasAP = 0; bool proceedToLaunch = true; - if (isTwlm[cursorPosOnScreen] || (!isDSiWare[cursorPosOnScreen] && (!dsiFeatures() || bs().b4dsMode) && ms().secondaryDevice && bnrRomType[cursorPosOnScreen] == 0 && gameTid[cursorPosOnScreen][0] == 'D' && romUnitCode[cursorPosOnScreen] == 3 && requiresDonorRom[cursorPosOnScreen] != 51) + if (!isValid[cursorPosOnScreen] || isTwlm[cursorPosOnScreen] || (!isDSiWare[cursorPosOnScreen] && (!dsiFeatures() || bs().b4dsMode) && ms().secondaryDevice && bnrRomType[cursorPosOnScreen] == 0 && gameTid[cursorPosOnScreen][0] == 'D' && romUnitCode[cursorPosOnScreen] == 3 && requiresDonorRom[cursorPosOnScreen] != 51) || (isDSiWare[cursorPosOnScreen] && ((((!dsiFeatures() && (!sdFound() || !ms().dsiWareToSD)) || bs().b4dsMode) && ms().secondaryDevice && !dsiWareCompatibleB4DS()) || (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) != 0 && sys().arm7SCFGLocked() && !sys().dsiWramAccess() && !gameCompatibleMemoryPit()))) || (bnrRomType[cursorPosOnScreen] == 1 && (!ms().secondaryDevice || dsiFeatures() || ms().gbaBooter == TWLSettings::EGbaGbar2) && checkForGbaBiosRequirement())) { @@ -2205,7 +2209,7 @@ std::string browseForFile(const std::vector extensionList) { if (ms().ak_viewMode == TWLSettings::EViewList) { cursorPosOnScreen = 0; } - if (!isTwlm[cursorPosOnScreen] && !isDirectory[cursorPosOnScreen] && (bnrRomType[cursorPosOnScreen] == 0 || bnrRomType[cursorPosOnScreen] == 1 || bnrRomType[cursorPosOnScreen] == 3)) { + if (isValid[cursorPosOnScreen] && !isTwlm[cursorPosOnScreen] && !isDirectory[cursorPosOnScreen] && (bnrRomType[cursorPosOnScreen] == 0 || bnrRomType[cursorPosOnScreen] == 1 || bnrRomType[cursorPosOnScreen] == 3)) { perGameSettings(dirContents.at(fileOffset).name); cursorPosOnScreen = cursorPosOnScreenBak; refreshBanners(screenOffset, fileOffset, dirContents); diff --git a/romsel_aktheme/arm9/source/iconTitle.cpp b/romsel_aktheme/arm9/source/iconTitle.cpp index 05090174a0..9abc507db6 100644 --- a/romsel_aktheme/arm9/source/iconTitle.cpp +++ b/romsel_aktheme/arm9/source/iconTitle.cpp @@ -890,7 +890,7 @@ void clearTitle(int num) { cachedTitle[num] = blankTitle; } -void copyGameInfo(int numDst, int numSrc) +/* void copyGameInfo(int numDst, int numSrc) { bnriconPalLine[numDst] = bnriconPalLine[numSrc]; bnriconPalLoaded[numDst] = bnriconPalLoaded[numSrc]; @@ -899,6 +899,7 @@ void copyGameInfo(int numDst, int numSrc) bnrWirelessIcon[numDst] = bnrWirelessIcon[numSrc]; customIcon[numDst] = customIcon[numSrc]; tonccpy(gameTid[numDst], gameTid[numSrc], 4); + isValid[numDst] = isValid[numSrc]; isTwlm[numDst] = isTwlm[numSrc]; isDSiWare[numDst] = isDSiWare[numSrc]; isHomebrew[numDst] = isHomebrew[numSrc]; @@ -920,7 +921,7 @@ void copyGameInfo(int numDst, int numSrc) } bnriconisDSi[numDst] = bnriconisDSi[numSrc]; -} +} */ void getGameInfo(int num, bool isDir, const char* name, bool fromArgv) { @@ -930,6 +931,7 @@ void getGameInfo(int num, bool isDir, const char* name, bool fromArgv) bannerFlip[num] = GL_FLIP_NONE; bnrWirelessIcon[num] = 0; toncset(gameTid[num], 0, 4); + isValid[num] = false; isTwlm[num] = false; isDSiWare[num] = false; isHomebrew[num] = true; @@ -1192,6 +1194,7 @@ void getGameInfo(int num, bool isDir, const char* name, bool fromArgv) } tonccpy(gameTid[num], ndsHeader.gameCode, 4); + isValid[num] = (ndsHeader.arm9destination >= 0x02000000 && ndsHeader.arm9destination < 0x03000000 && ndsHeader.arm9executeAddress >= 0x02000000 && ndsHeader.arm9executeAddress < 0x03000000); isTwlm[num] = (strcmp(gameTid[num], "SRLA") == 0); romVersion[num] = ndsHeader.romversion; romUnitCode[num] = ndsHeader.unitCode; diff --git a/romsel_aktheme/arm9/source/ndsheaderbanner.cpp b/romsel_aktheme/arm9/source/ndsheaderbanner.cpp index 5a2860fa31..1a0b9fd1c7 100644 --- a/romsel_aktheme/arm9/source/ndsheaderbanner.cpp +++ b/romsel_aktheme/arm9/source/ndsheaderbanner.cpp @@ -565,6 +565,7 @@ int bannerFlip[8] = {GL_FLIP_NONE}; int bannerFlipPrev[8] = {GL_FLIP_NONE}; // bnriconisDSi[] +bool isValid[8] = {false}; bool isTwlm[8] = {false}; bool isDirectory[8] = {false}; int bnrRomType[8] = {0}; diff --git a/romsel_aktheme/arm9/source/ndsheaderbanner.h b/romsel_aktheme/arm9/source/ndsheaderbanner.h index 5642be8a90..4fa97ca60e 100644 --- a/romsel_aktheme/arm9/source/ndsheaderbanner.h +++ b/romsel_aktheme/arm9/source/ndsheaderbanner.h @@ -286,6 +286,7 @@ extern int bnriconframenumY[8]; extern int bannerFlip[8]; // bnriconisDSi[] +extern bool isValid[8]; extern bool isTwlm[8]; extern bool isDirectory[8]; extern int bnrRomType[8]; diff --git a/romsel_dsimenutheme/arm9/source/fileBrowse.cpp b/romsel_dsimenutheme/arm9/source/fileBrowse.cpp index f5f8544ba5..ae76e72de0 100644 --- a/romsel_dsimenutheme/arm9/source/fileBrowse.cpp +++ b/romsel_dsimenutheme/arm9/source/fileBrowse.cpp @@ -2370,7 +2370,9 @@ bool cannotLaunchMsg(const char *filename) { titleUpdate(false, filename, CURPOS); } const std::string *str = nullptr; - if (isTwlm[CURPOS]) { + if (!isValid[CURPOS]) { + str = (ms().secondaryDevice || ms().showMicroSd) ? &STR_CANNOT_LAUNCH_CORRUPT_TITLE_MICRO_SD : &STR_CANNOT_LAUNCH_CORRUPT_TITLE_SD; + } else if (isTwlm[CURPOS]) { str = &STR_TWLMENU_ALREADY_RUNNING; } else if (isUnlaunch[CURPOS]) { str = &STR_CANNOT_LAUNCH_WITH_THEME; @@ -2702,6 +2704,7 @@ void getFileInfo(SwitchState scrn, vector> dirContents, bool re if (bnrRomType[i] != 0) { bnrWirelessIcon[i] = 0; bnrSysSettings[i] = false; + isValid[i] = true; isTwlm[i] = false; isDSiWare[i] = false; isHomebrew[i] = 0; @@ -3647,12 +3650,12 @@ std::string browseForFile(const std::vector extensionList) { settingsChanged = false; return "null"; } else { - if (!isTwlm[CURPOS]) { + if (isValid[CURPOS] && !isTwlm[CURPOS]) { loadPerGameSettings(dirContents[scrn].at(CURPOS + PAGENUM * 40).name); } int hasAP = 0; bool proceedToLaunch = true; - if (isTwlm[CURPOS] || (isUnlaunch[CURPOS] && ms().theme == TWLSettings::ETheme3DS) || (!isDSiWare[CURPOS] && (!dsiFeatures() || bs().b4dsMode) && ms().secondaryDevice && bnrRomType[CURPOS] == 0 && gameTid[CURPOS][0] == 'D' && unitCode[CURPOS] == 3 && requiresDonorRom[CURPOS] != 51) + if (!isValid[CURPOS] || isTwlm[CURPOS] || (isUnlaunch[CURPOS] && ms().theme == TWLSettings::ETheme3DS) || (!isDSiWare[CURPOS] && (!dsiFeatures() || bs().b4dsMode) && ms().secondaryDevice && bnrRomType[CURPOS] == 0 && gameTid[CURPOS][0] == 'D' && unitCode[CURPOS] == 3 && requiresDonorRom[CURPOS] != 51) || (isDSiWare[CURPOS] && ((((!dsiFeatures() && (!sdFound() || !ms().dsiWareToSD)) || bs().b4dsMode) && ms().secondaryDevice && !dsiWareCompatibleB4DS()) || (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) != 0 && sys().arm7SCFGLocked() && !sys().dsiWramAccess() && !gameCompatibleMemoryPit()))) || (bnrRomType[CURPOS] == 1 && (!ms().secondaryDevice || dsiFeatures() || ms().gbaBooter == TWLSettings::EGbaGbar2) && checkForGbaBiosRequirement())) { @@ -4316,7 +4319,7 @@ std::string browseForFile(const std::vector extensionList) { bannerTextShown = false; } - if ((pressed & KEY_Y) && !ms().kioskMode && !isTwlm[CURPOS] && !isDirectory[CURPOS] && bannerTextShown && showSTARTborder) { + if ((pressed & KEY_Y) && !ms().kioskMode && isValid[CURPOS] && !isTwlm[CURPOS] && !isDirectory[CURPOS] && bannerTextShown && showSTARTborder) { perGameSettings(dirContents[scrn].at(CURPOS + PAGENUM * 40).name); bannerTextShown = false; } diff --git a/romsel_dsimenutheme/arm9/source/iconTitle.cpp b/romsel_dsimenutheme/arm9/source/iconTitle.cpp index 29cf1f668f..4e95ca4938 100644 --- a/romsel_dsimenutheme/arm9/source/iconTitle.cpp +++ b/romsel_dsimenutheme/arm9/source/iconTitle.cpp @@ -188,6 +188,7 @@ void getGameInfo(bool isDir, const char *name, int num, bool fromArgv) { bannerFlip[num] = GL_FLIP_NONE; bnrWirelessIcon[num] = 0; toncset(gameTid[num], 0, 4); + isValid[num] = false; isTwlm[num] = false; isUnlaunch[num] = false; isDSiWare[num] = false; @@ -452,6 +453,7 @@ void getGameInfo(bool isDir, const char *name, int num, bool fromArgv) { if (num < 40) { tonccpy(gameTid[num], ndsHeader.gameCode, 4); + isValid[num] = (ndsHeader.arm9destination >= 0x02000000 && ndsHeader.arm9destination < 0x03000000 && ndsHeader.arm9executeAddress >= 0x02000000 && ndsHeader.arm9executeAddress < 0x03000000); isTwlm[num] = (strcmp(gameTid[num], "SRLA") == 0); isUnlaunch[num] = (memcmp(ndsHeader.gameTitle, "UNLAUNCH.DSI", 12) == 0); romVersion[num] = ndsHeader.romversion; diff --git a/romsel_dsimenutheme/arm9/source/language.inl b/romsel_dsimenutheme/arm9/source/language.inl index 427ac3f0af..7e4d52639d 100644 --- a/romsel_dsimenutheme/arm9/source/language.inl +++ b/romsel_dsimenutheme/arm9/source/language.inl @@ -67,7 +67,9 @@ STRING(TWLMENU_ALREADY_RUNNING, "TWiLight Menu++ is\nalready running.") STRING(CANNOT_LAUNCH_WITHOUT_SD, "This game cannot be launched\nwithout an SD card.") STRING(CANNOT_LAUNCH_IN_DS_MODE, "This game cannot be launched\nin DS mode.") STRING(CANNOT_LAUNCH_HB_ON_3DS, "This homebrew cannot be\nlaunched on 3DS consoles.") -STRING(CANNOT_LAUNCH_WITH_THEME, "Cannot launch this title.\nPlease switch to different theme,\nthen try again.") +STRING(CANNOT_LAUNCH_WITH_THEME, "Cannot launch this title.\nPlease switch to a different theme,\nthen try again.") +STRING(CANNOT_LAUNCH_CORRUPT_TITLE_SD, "Cannot launch this title.\nEither the title or SD Card\nis corrupted.") +STRING(CANNOT_LAUNCH_CORRUPT_TITLE_MICRO_SD, "Cannot launch this title.\nEither the title or microSD Card\nis corrupted.") STRING(PRESS_B_RETURN, "Press \\B to return.") STRING(BAD_CLUSTER_SIZE, "Your SD card is not formatted\nusing 32KB clusters, this causes\nsome games to load very slowly.\nIt's recommended to reformat your\nSD card using 32KB clusters.") diff --git a/romsel_dsimenutheme/arm9/source/ndsheaderbanner.cpp b/romsel_dsimenutheme/arm9/source/ndsheaderbanner.cpp index 709ada4a63..663b98a93c 100644 --- a/romsel_dsimenutheme/arm9/source/ndsheaderbanner.cpp +++ b/romsel_dsimenutheme/arm9/source/ndsheaderbanner.cpp @@ -538,6 +538,7 @@ int bannerFlip[41] = {GL_FLIP_NONE}; int bannerFlipPrev[41] = {GL_FLIP_NONE}; // bnriconisDSi[] +bool isValid[40] = {false}; bool isTwlm[40] = {false}; bool isUnlaunch[40] = {false}; bool isDirectory[40] = {false}; diff --git a/romsel_dsimenutheme/arm9/source/ndsheaderbanner.h b/romsel_dsimenutheme/arm9/source/ndsheaderbanner.h index d4bf3eb814..3a6bc66274 100644 --- a/romsel_dsimenutheme/arm9/source/ndsheaderbanner.h +++ b/romsel_dsimenutheme/arm9/source/ndsheaderbanner.h @@ -285,6 +285,7 @@ extern int bnriconframenumY[41]; extern int bannerFlip[41]; // bnriconisDSi[] +extern bool isValid[40]; extern bool isTwlm[40]; extern bool isUnlaunch[40]; extern bool isDirectory[40]; diff --git a/romsel_dsimenutheme/nitrofiles/languages/en/language.ini b/romsel_dsimenutheme/nitrofiles/languages/en/language.ini index 6c4800e0cb..53441db880 100644 --- a/romsel_dsimenutheme/nitrofiles/languages/en/language.ini +++ b/romsel_dsimenutheme/nitrofiles/languages/en/language.ini @@ -64,7 +64,9 @@ TWLMENU_ALREADY_RUNNING = TWiLight Menu++ is\nalready running. CANNOT_LAUNCH_WITHOUT_SD = This game cannot be launched\nwithout an SD card. CANNOT_LAUNCH_IN_DS_MODE = This game cannot be launched\nin DS mode. CANNOT_LAUNCH_HB_ON_3DS = This homebrew cannot be\nlaunched on 3DS consoles. -CANNOT_LAUNCH_WITH_THEME = Cannot launch this title.\nPlease switch to different theme,\nthen try again. +CANNOT_LAUNCH_WITH_THEME = Cannot launch this title.\nPlease switch to a different theme,\nthen try again. +CANNOT_LAUNCH_CORRUPT_TITLE_SD = Cannot launch this title.\nEither the title or SD Card\nis corrupted. +CANNOT_LAUNCH_CORRUPT_TITLE_MICRO_SD = Cannot launch this title.\nEither the title or microSD Card\nis corrupted. PRESS_B_RETURN = Press \B to return. BAD_CLUSTER_SIZE = Your SD card is not formatted\nusing 32KB clusters, this causes\nsome games to load very slowly.\nIt's recommended to reformat your\nSD card using 32KB clusters. diff --git a/romsel_r4theme/arm9/source/fileBrowse.cpp b/romsel_r4theme/arm9/source/fileBrowse.cpp index bcf6f6fea8..9b06431b4d 100644 --- a/romsel_r4theme/arm9/source/fileBrowse.cpp +++ b/romsel_r4theme/arm9/source/fileBrowse.cpp @@ -1170,6 +1170,7 @@ std::string browseForFile(const std::vector extensionList) { if (bnrRomType != 0) { bnrWirelessIcon = 0; + isValid = true; isTwlm = false; isDSiWare = false; isHomebrew = 0; @@ -1250,13 +1251,13 @@ std::string browseForFile(const std::vector extensionList) { return "null"; } else { - if (!isTwlm) { + if (isValid && !isTwlm) { loadPerGameSettings(dirContents.at(fileOffset).name); } int hasAP = 0; bool proceedToLaunch = true; - if (isTwlm || (!isDSiWare && (!dsiFeatures() || bs().b4dsMode) && ms().secondaryDevice && bnrRomType == 0 && gameTid[0] == 'D' && romUnitCode == 3 && requiresDonorRom != 51) + if (!isValid || isTwlm || (!isDSiWare && (!dsiFeatures() || bs().b4dsMode) && ms().secondaryDevice && bnrRomType == 0 && gameTid[0] == 'D' && romUnitCode == 3 && requiresDonorRom != 51) || (isDSiWare && ((((!dsiFeatures() && (!sdFound() || !ms().dsiWareToSD)) || bs().b4dsMode) && ms().secondaryDevice && !dsiWareCompatibleB4DS()) || (isDSiMode() && memcmp(io_dldi_data->friendlyName, "CycloDS iEvolution", 18) != 0 && sys().arm7SCFGLocked() && !sys().dsiWramAccess() && !gameCompatibleMemoryPit()))) || (bnrRomType == 1 && (!ms().secondaryDevice || dsiFeatures() || ms().gbaBooter == TWLSettings::EGbaGbar2) && checkForGbaBiosRequirement())) { @@ -1675,7 +1676,7 @@ std::string browseForFile(const std::vector extensionList) { return "null"; } - if ((pressed & KEY_Y) && !ms().kioskMode && !isTwlm && !isDirectory && (bnrRomType == 0 || bnrRomType == 1 || bnrRomType == 3)) { + if ((pressed & KEY_Y) && !ms().kioskMode && isValid && !isTwlm && !isDirectory && (bnrRomType == 0 || bnrRomType == 1 || bnrRomType == 3)) { ms().cursorPosition[ms().secondaryDevice] = fileOffset; perGameSettings(dirContents.at(fileOffset).name); if (ms().theme == TWLSettings::EThemeGBC) { diff --git a/romsel_r4theme/arm9/source/iconTitle.cpp b/romsel_r4theme/arm9/source/iconTitle.cpp index d889ee8e75..54b7b80e50 100644 --- a/romsel_r4theme/arm9/source/iconTitle.cpp +++ b/romsel_r4theme/arm9/source/iconTitle.cpp @@ -906,6 +906,7 @@ void getGameInfo(bool isDir, const char* name, bool fromArgv) bannerFlip = GL_FLIP_NONE; bnrWirelessIcon = 0; toncset(gameTid, 0, 4); + isValid = false; isTwlm = false; isDSiWare = false; isHomebrew = true; @@ -1139,6 +1140,7 @@ void getGameInfo(bool isDir, const char* name, bool fromArgv) } tonccpy(gameTid, ndsHeader.gameCode, 4); + isValid = (ndsHeader.arm9destination >= 0x02000000 && ndsHeader.arm9destination < 0x03000000 && ndsHeader.arm9executeAddress >= 0x02000000 && ndsHeader.arm9executeAddress < 0x03000000); isTwlm = (strcmp(gameTid, "SRLA") == 0); romVersion = ndsHeader.romversion; romUnitCode = ndsHeader.unitCode; diff --git a/romsel_r4theme/arm9/source/ndsheaderbanner.cpp b/romsel_r4theme/arm9/source/ndsheaderbanner.cpp index 3634413b2b..484dfa09d4 100644 --- a/romsel_r4theme/arm9/source/ndsheaderbanner.cpp +++ b/romsel_r4theme/arm9/source/ndsheaderbanner.cpp @@ -553,6 +553,7 @@ int bannerFlip = GL_FLIP_NONE; int bannerFlipPrev = GL_FLIP_NONE; // bnriconisDSi[] +bool isValid = false; bool isTwlm = false; bool isDirectory = false; int bnrRomType = 0; diff --git a/romsel_r4theme/arm9/source/ndsheaderbanner.h b/romsel_r4theme/arm9/source/ndsheaderbanner.h index 50dae857f9..25e83095bd 100644 --- a/romsel_r4theme/arm9/source/ndsheaderbanner.h +++ b/romsel_r4theme/arm9/source/ndsheaderbanner.h @@ -284,6 +284,7 @@ extern int bnriconframenumY; extern int bannerFlip; // bnriconisDSi[] +extern bool isValid; extern bool isTwlm; extern bool isDirectory; extern int bnrRomType;