From 664e7a2090618db14d23161d7906cd21c00b6a27 Mon Sep 17 00:00:00 2001 From: Edoardo Lolletti Date: Thu, 25 Apr 2024 17:11:14 +0200 Subject: [PATCH] Remove not needed NTM files --- arm9/src/backupmenu.c | 275 ------------- arm9/src/install.c | 871 ----------------------------------------- arm9/src/install.h | 8 - arm9/src/installmenu.c | 320 --------------- arm9/src/main.c | 156 +------- arm9/src/main.h | 15 +- arm9/src/maketmd.c | 191 --------- arm9/src/maketmd.h | 9 - arm9/src/menu.c | 3 + arm9/src/nand/nandio.c | 3 +- arm9/src/rom.c | 296 -------------- arm9/src/rom.h | 23 -- arm9/src/sav.c | 93 ----- arm9/src/sav.h | 38 -- arm9/src/storage.c | 417 +------------------- arm9/src/storage.h | 34 -- arm9/src/testmenu.c | 75 ---- arm9/src/titlemenu.c | 523 ------------------------- arm9/src/unlaunch.c | 17 +- 19 files changed, 29 insertions(+), 3338 deletions(-) delete mode 100644 arm9/src/backupmenu.c delete mode 100644 arm9/src/install.c delete mode 100644 arm9/src/install.h delete mode 100644 arm9/src/installmenu.c delete mode 100644 arm9/src/maketmd.c delete mode 100644 arm9/src/maketmd.h delete mode 100644 arm9/src/rom.c delete mode 100644 arm9/src/rom.h delete mode 100644 arm9/src/sav.c delete mode 100644 arm9/src/sav.h delete mode 100644 arm9/src/testmenu.c delete mode 100644 arm9/src/titlemenu.c diff --git a/arm9/src/backupmenu.c b/arm9/src/backupmenu.c deleted file mode 100644 index d968f5a..0000000 --- a/arm9/src/backupmenu.c +++ /dev/null @@ -1,275 +0,0 @@ -#include "install.h" -#include "main.h" -#include "menu.h" -#include "rom.h" -#include "storage.h" -#include "message.h" -#include "nand/nandio.h" -#include -#include - -enum { - BACKUP_MENU_RESTORE, - BACKUP_MENU_DELETE, - BACKUP_MENU_BACK -}; - -static void generateList(Menu* m); -static void printItem(Menu* m); -static int subMenu(); -static bool delete(Menu* m); - -void backupMenu() -{ - clearScreen(&topScreen); - - Menu* m = newMenu(); - setMenuHeader(m, "BACKUP MENU"); - generateList(m); - - //no files found - if (m->itemCount <= 0) - { - messageBox("\x1B[33mNo backups found.\n\x1B[47m"); - } - else - { - while (!programEnd) - { - swiWaitForVBlank(); - scanKeys(); - - if (moveCursor(m)) - { - if (m->changePage != 0) - generateList(m); - - printMenu(m); - printItem(m); - } - - if (keysDown() & KEY_B || m->itemCount <= 0) - break; - - else if (keysDown() & KEY_A) - { - switch (subMenu()) - { - case BACKUP_MENU_RESTORE: - install(m->items[m->cursor].value, false); - break; - - case BACKUP_MENU_DELETE: - { - if (delete(m)) - { - resetMenu(m); - generateList(m); - } - } - break; - } - - printMenu(m); - } - } - } - - freeMenu(m); -} - -static int subMenu() -{ - int result = -1; - - Menu* m = newMenu(); - - addMenuItem(m, "Restore", NULL, 0); - addMenuItem(m, "Delete", NULL, 0); - addMenuItem(m, "Back - [B]", NULL, 0); - - printMenu(m); - - while (!programEnd) - { - swiWaitForVBlank(); - scanKeys(); - - if (moveCursor(m)) - printMenu(m); - - if (keysDown() & KEY_B) - break; - - else if (keysDown() & KEY_A) - { - result = m->cursor; - break; - } - } - - freeMenu(m); - return result; -} - -static void generateList(Menu* m) -{ - if (!m) return; - - //reset menu - clearMenu(m); - - m->page += sign(m->changePage); - m->changePage = 0; - - bool done = false; - - struct dirent* ent; - DIR* dir = opendir(BACKUP_PATH); - - if (dir) - { - int count = 0; - - while ( (ent = readdir(dir)) && !done) - { - if (ent->d_name[0] == '.') - continue; - - if (ent->d_type == DT_DIR) - { - if (count < m->page * ITEMS_PER_PAGE) - count += 1; - - else - { - if (m->itemCount >= ITEMS_PER_PAGE) - done = true; - - else - { - char* fpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(ent->d_name) + 8); - sprintf(fpath, "%s/%s", BACKUP_PATH, ent->d_name); - - addMenuItem(m, ent->d_name, fpath, 1); - } - } - } - else - { - if (strcasecmp(strrchr(ent->d_name, '.'), ".nds") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".app") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".dsi") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".ids") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".srl") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".cia") == 0) - { - if (count < m->page * ITEMS_PER_PAGE) - count += 1; - - else - { - if (m->itemCount >= ITEMS_PER_PAGE) - done = true; - - else - { - char* fpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(ent->d_name) + 8); - sprintf(fpath, "%s/%s", BACKUP_PATH, ent->d_name); - - addMenuItem(m, ent->d_name, fpath, 0); - - free(fpath); - } - } - } - } - } - } - - closedir(dir); - - sortMenuItems(m); - - m->nextPage = done; - - if (m->cursor >= m->itemCount) - m->cursor = m->itemCount - 1; - - printItem(m); - printMenu(m); -} - -static void printItem(Menu* m) -{ - if (!m) return; - if (m->itemCount <= 0) return; - - if (m->items[m->cursor].directory) - clearScreen(&topScreen); - else - printRomInfo(m->items[m->cursor].value); -} - -static bool delete(Menu* m) -{ - if (!m) return false; - - char* label = m->items[m->cursor].label; - char* fpath = m->items[m->cursor].value; - - bool result = false; - bool choice = NO; - { - const char str[] = "Are you sure you want to delete\n"; - char* msg = (char*)malloc(strlen(str) + strlen(label) + 2); - sprintf(msg, "%s%s?", str, label); - - choice = choiceBox(msg); - - free(msg); - } - - if (choice == YES) - { - if (!fpath) - { - messageBox("\x1B[31mFailed to delete backup.\n\x1B[47m"); - } - else - { - if (access(fpath, F_OK) != 0) - { - messageBox("\x1B[31mFailed to delete backup.\n\x1B[47m"); - } - else - { - clearScreen(&bottomScreen); - - //app - remove(fpath); - - //tmd - strcpy(strrchr(fpath, '.'), ".tmd"); - remove(fpath); - - //public save - strcpy(strrchr(fpath, '.'), ".pub"); - remove(fpath); - - //private save - strcpy(strrchr(fpath, '.'), ".prv"); - remove(fpath); - - //banner save - strcpy(strrchr(fpath, '.'), ".bnr"); - remove(fpath); - - result = true; - messagePrint("\x1B[42m\nBackup deleted.\n\x1B[47m"); - } - } - } - - return result; -} \ No newline at end of file diff --git a/arm9/src/install.c b/arm9/src/install.c deleted file mode 100644 index e9a9dfd..0000000 --- a/arm9/src/install.c +++ /dev/null @@ -1,871 +0,0 @@ -#include "install.h" -#include "sav.h" -#include "main.h" -#include "message.h" -#include "maketmd.h" -#include "nand/crypto.h" -#include "nand/nandio.h" -#include "nand/ticket0.h" -#include "rom.h" -#include "storage.h" -#include -#include -#include - -static bool _titleIsUsed(tDSiHeader* h) -{ - if (!h) return false; - - char path[64]; - sprintf(path, "%s:/title/%08x/%08x/", sdnandMode ? "sd" : "nand", (unsigned int)h->tid_high, (unsigned int)h->tid_low); - - return dirExists(path); -} - -//patch homebrew roms if gameCode is #### or null -static bool _patchGameCode(tDSiHeader* h) -{ - if (!h) return false; - - if ((strcmp(h->ndshdr.gameCode, "####") == 0 && h->tid_low == 0x23232323) || (!*h->ndshdr.gameCode && h->tid_low == 0)) - { - iprintf("Fixing Game Code..."); - swiWaitForVBlank(); - - //set as standard app - h->tid_high = 0x00030004; - - do { - do { - //generate a random game code - for (int i = 0; i < 4; i++) - h->ndshdr.gameCode[i] = 'A' + (rand() % 26); - } - while (h->ndshdr.gameCode[0] == 'A'); //first letter shouldn't be A - - //correct title id - h->tid_low = ( (h->ndshdr.gameCode[0] << 24) | (h->ndshdr.gameCode[1] << 16) | (h->ndshdr.gameCode[2] << 8) | h->ndshdr.gameCode[3] ); - } - while (_titleIsUsed(h)); - - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - return true; - } - - return false; -} - -static bool _iqueHack(tDSiHeader* h) -{ - if (!h) return false; - - if (h->ndshdr.reserved1[8] == 0x80) - { - iprintf("iQue Hack..."); - - h->ndshdr.reserved1[8] = 0x00; - - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - return true; - } - - return false; -} - -static unsigned long long _getSaveDataSize(tDSiHeader* h) -{ - unsigned long long size = 0; - - if (h) - { - size += h->public_sav_size; - size += h->private_sav_size; - - //banner.sav - if (h->appflags & 0x4) - size += 0x4000; - } - - return size; -} - -static bool _checkSdSpace(unsigned long long size) -{ - iprintf("Enough room on SD card?..."); - swiWaitForVBlank(); - - if (getSDCardFree() < size) - { - iprintf("\x1B[31m"); //red - iprintf("No\n"); - iprintf("\x1B[47m"); //white - return false; - } - - iprintf("\x1B[42m"); //green - iprintf("Yes\n"); - iprintf("\x1B[47m"); //white - return true; -} - -static bool _checkDsiSpace(unsigned long long size, bool systemApp) -{ - iprintf("Enough room on DSi?..."); - swiWaitForVBlank(); - - //ensure there's at least 1 MiB free, to leave margin for error - if (((systemApp ? getDsiRealFree() : getDsiFree()) < size) || (((systemApp ? getDsiRealFree() : getDsiFree()) - size) < (1 << 20))) - { - iprintf("\x1B[31m"); //red - iprintf("No\n"); - iprintf("\x1B[47m"); //white - return false; - } - - iprintf("\x1B[42m"); //green - iprintf("Yes\n"); - iprintf("\x1B[47m"); //white - return true; -} - -static bool _openMenuSlot() -{ - iprintf("Open DSi menu slot?..."); - swiWaitForVBlank(); - - if (getMenuSlotsFree() <= 0) - { - iprintf("\x1B[31m"); //red - iprintf("No\n"); - iprintf("\x1B[47m"); //white - return false; - } - - iprintf("\x1B[42m"); //green - iprintf("Yes\n"); - iprintf("\x1B[47m"); //white - return true; -} - -static void _createPublicSav(tDSiHeader* h, char* dataPath) -{ - if (!h) return; - - if (h->public_sav_size > 0) - { - iprintf("Creating public.sav..."); - swiWaitForVBlank(); - - if (!dataPath) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - char* publicPath = (char*)malloc(strlen(dataPath) + strlen("/public.sav") + 1); - sprintf(publicPath, "%s/public.sav", dataPath); - - FILE* f = fopen(publicPath, "wb"); - - if (!f) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - fseek(f, h->public_sav_size-1, SEEK_SET); - fputc(0, f); - initFatHeader(f); - - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - } - - fclose(f); - free(publicPath); - } - } -} - -static void _createPrivateSav(tDSiHeader* h, char* dataPath) -{ - if (!h) return; - - if (h->private_sav_size > 0) - { - iprintf("Creating private.sav..."); - swiWaitForVBlank(); - - if (!dataPath) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - char* privatePath = (char*)malloc(strlen(dataPath) + strlen("/private.sav") + 1); - sprintf(privatePath, "%s/private.sav", dataPath); - - FILE* f = fopen(privatePath, "wb"); - - if (!f) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - fseek(f, h->private_sav_size-1, SEEK_SET); - fputc(0, f); - initFatHeader(f); - - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - } - - fclose(f); - free(privatePath); - } - } -} - -static void _createBannerSav(tDSiHeader* h, char* dataPath) -{ - if (!h) return; - - if (h->appflags & 0x4) - { - iprintf("Creating banner.sav..."); - swiWaitForVBlank(); - - if (!dataPath) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - char* bannerPath = (char*)malloc(strlen(dataPath) + strlen("/banner.sav") + 1); - sprintf(bannerPath, "%s/banner.sav", dataPath); - - FILE* f = fopen(bannerPath, "wb"); - - if (!f) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - fseek(f, 0x4000 - 1, SEEK_SET); - fputc(0, f); - - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - } - - fclose(f); - free(bannerPath); - } - } -} - -static void _createTicket(tDSiHeader *h, char* ticketPath) -{ - if (!h) return; - - iprintf("Forging ticket..."); - swiWaitForVBlank(); - - if (!ticketPath) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - const u32 encryptedSize = sizeof(ticket_v0_t) + 0x20; - u8 *buffer = (u8*)memalign(4, encryptedSize); //memalign might be needed for encryption, but not sure - memset(buffer, 0, encryptedSize); - ticket_v0_t *ticket = (ticket_v0_t*)buffer; - ticket->sig_type[0] = 0x00; - ticket->sig_type[1] = 0x01; - ticket->sig_type[2] = 0x00; - ticket->sig_type[3] = 0x01; - strcpy(ticket->issuer, "Root-CA00000001-XS00000006"); - PUT_UINT32_BE(h->tid_high, ticket->title_id, 0); - PUT_UINT32_BE(h->tid_low, ticket->title_id, 4); - memset(ticket->content_access_permissions, 0xFF, 0x20); - - // Encrypt - if (dsi_es_block_crypt(buffer, encryptedSize, ENCRYPT) != 0) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - free(buffer); - return; - } - - FILE *file = fopen(ticketPath, "wb"); - if (!file) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - free(buffer); - return; - } - - if (fwrite(buffer, 1, encryptedSize, file) != encryptedSize) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - } - - free(buffer); - fclose(file); - } -} - -bool install(char* fpath, bool systemTitle) -{ - bool result = false; - - //check battery level - while (batteryLevel < 7 && !charging) - { - if (choiceBox("\x1B[47mBattery is too low!\nPlease plug in the console.\n\nContinue?") == NO) - return false; - } - - //start installation - clearScreen(&bottomScreen); - - tDSiHeader* h = getRomHeader(fpath); - - if (!h) - { - iprintf("\x1B[31m"); //red - iprintf("Error: "); - iprintf("\x1B[33m"); //yellow - iprintf("Could not open file.\n"); - iprintf("\x1B[47m"); //white - goto error; - } - else - { - bool fixHeader = false; - - if (_patchGameCode(h)) - fixHeader = true; - - //title id must be one of these - if (h->tid_high == 0x00030004 || // DSiWare - h->tid_high == 0x00030005 || // "unimportant" system titles - h->tid_high == 0x00030011 || // SRLs in the TWL SDK - h->tid_high == 0x00030015 || // system titles - h->tid_high == 0x00030017) // Launcher - {} - else - { - iprintf("\x1B[31m"); //red - iprintf("Error: "); - iprintf("\x1B[33m"); //yellow - iprintf("This is not a DSi rom.\n"); - iprintf("\x1B[47m"); //white - goto error; - } - - //patch dev titles to system titles on SysNAND. - // - //software released through the TWL SDK usually comes as a TAD and an SRL - //things like NandFiler have a TAD with a TID of 0x00030015 and an SRL with 0x00030011 - //the TAD is the installable version, so I'm assuming that 0x00030015 is what the console wants to see on NAND - //this changes the SRL TID accordingly - //not entirely sure why there's even any difference. I think the installed TAD and SRL the same as each other (minus the TID) - if(!sdnandMode && h->tid_high == 0x00030011) - { - h->tid_high = 0x00030015; - fixHeader = true; - } - - //offer to patch system titles to normal DSiWare on SysNAND - if(!sdnandMode && h->tid_high != 0x00030004 && h->tid_high != 0x00030017) //do not allow patching home menus to be normal DSiWare! This will trigger "ERROR! - 0x0000000000000008 HWINFO_SECURE" on prototype launchers. May also cause issues on the prod versions. - { - if(choiceBox("This is set as a system/dev\ntitle, would you like to patch\nit to be a normal DSiWare?\n\nThis is safer, but invalidates\nRSA checks and may not work.\n\nIf the title is homebrew this isstrongly recommended.") == YES) - { - h->tid_high = 0x00030004; - fixHeader = true; - } - } - - //offer to patch home menus to be system titles on SysNAND - if(!sdnandMode && h->tid_high == 0x00030017) - { - if(choiceBox("This title is a home menu.\nWould you like to patch it to bea system title?\n\nThis is safer and prevents your\nhome menu from being hidden.") == YES) - { - h->tid_high = 0x00030015; - fixHeader = true; - } - } - - //no system titles without Unlaunch - if (!unlaunchFound && h->tid_high != 0x00030004) - { - iprintf("\x1B[31m"); //red - iprintf("Error: "); - iprintf("\x1B[33m"); //yellow - iprintf("This title cannot be\ninstalled without Unlaunch.\n"); - iprintf("\x1B[47m"); //white - goto error; - } - - //blacklisted titles - { - //tid without region - u32 tidLow = (h->tid_low & 0xFFFFFF00); - if (!sdnandMode && ( - (h->tid_high == 0x00030005 && ( - tidLow == 0x484e4400 || // DS Download Play - tidLow == 0x484e4500 || // PictoChat - tidLow == 0x484e4900 || // Nintendo DSi Camera - tidLow == 0x484e4a00 || // Nintendo Zone - tidLow == 0x484e4b00 // Nintendo DSi Sound - )) || (h->tid_high == 0x00030011 && ( - tidLow == 0x30535500 || // Twl SystemUpdater - tidLow == 0x34544e00 || // TwlNmenu - tidLow == 0x54574c00 // TWL EVA - )) || (h->tid_high == 0x00030015 && ( - tidLow == 0x484e4200 || // System Settings - tidLow == 0x484e4600 || // Nintendo DSi Shop - tidLow == 0x34544e00 // TwlNmenu - )) || (h->tid_high == 0x00030017 && ( - tidLow == 0x484e4100 // Launcher - ))) && ( - (h->tid_low & 0xFF) == region || // Only blacklist console region, or the following programs that have all-region codes: - h->tid_low == 0x484e4541 || // PictoChat - h->tid_low == 0x484e4441 || // Download Play - h->tid_low == 0x30535541 || // Twl SystemUpdater (iirc one version fits in NAND) - h->tid_low == 0x34544e41 || // TwlNmenu (blocking due to potential to uninstall system titles) - h->tid_low == 0x54574c41 || // TWL EVA - region == 0 //if the region check failed somehow, blacklist everything - )) - { - //check if title exists, if it does then show any error - //otherwise allow reinstalling it - char path[PATH_MAX]; - sprintf(path, "nand:/title/%08lx/%08lx/content/title.tmd", h->tid_high, h->tid_low); - if (access(path, F_OK) == 0) - { - iprintf("\x1B[31m"); //red - iprintf("Error: "); - iprintf("\x1B[33m"); //yellow - iprintf("This title cannot be\ninstalled to SysNAND.\n"); - iprintf("\x1B[47m"); //white - goto error; - } - } - } - - //confirmation message - { - const char system[] = "\x1B[41mWARNING:\x1B[47m This is a system app,\ninstalling it is potentially\nmore risky than regular DSiWare.\n\x1B[33m"; - const char areYouSure[] = "Are you sure you want to install\n"; - char* msg = (char*)malloc(strlen(system) + strlen(areYouSure) + strlen(fpath) + 2); - if (sdnandMode || h->tid_high == 0x00030004) - sprintf(msg, "%s%s?\n", areYouSure, fpath); - else - sprintf(msg, "%s%s%s?\n", system, areYouSure, fpath); - - bool choice = choiceBox(msg); - free(msg); - - if (choice == NO) - return false; - } - - if (!sdnandMode && !nandio_unlock_writing()) - return false; - - clearScreen(&bottomScreen); - iprintf("Installing %s\n\n", fpath); swiWaitForVBlank(); - - //check for legit TMD, if found we'll generate a ticket which increases the size - int extensionPos = strrchr(fpath, '.') - fpath; - char tmdPath[PATH_MAX]; - strcpy(tmdPath, fpath); - strcpy(tmdPath + extensionPos, ".tmd"); - //DSi TMDs are 520, TMDs from NUS are 2,312. If 2,312 we can simply trim it to 520 - int tmdSize = getFileSizePath(tmdPath); - bool tmdFound = (tmdSize == 520) || (tmdSize == 2312); - if (access(tmdPath, F_OK) == 0 && !tmdFound) - { - if (choicePrint("Incorrect TMD.\nInstall anyway?") == YES) - tmdFound = false; - else - goto error; - } - else if(!sdnandMode && !unlaunchPatches && access(tmdPath, F_OK) != 0) - { - if (choicePrint("TMD not found, game cannot be\nplayed without Unlaunch's\nlauncher patches.\nSee wiki for how to get a TMD.\n\nInstall anyway?") == YES) - tmdFound = false; - else - goto error; - } - - //get install size - iprintf("Install Size: "); - swiWaitForVBlank(); - - u32 clusterSize = getDsiClusterSize(); - unsigned long long fileSize = getRomSize(fpath), fileSizeOnDisk = fileSize; - if ((fileSizeOnDisk % clusterSize) != 0) - fileSizeOnDisk += clusterSize - (fileSizeOnDisk % clusterSize); - //file + saves + TMD (rounded up to cluster size) - unsigned long long installSize = fileSizeOnDisk + _getSaveDataSize(h) + clusterSize; - if (tmdFound) installSize += clusterSize; //ticket, rounded up to cluster size - - printBytes(installSize); - iprintf("\n"); - - if (sdnandMode && !_checkSdSpace(installSize)) - goto error; - - //system title patch - if (systemTitle) - { - iprintf("System Title Patch..."); - swiWaitForVBlank(); - h->tid_high = 0x00030015; - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - - fixHeader = true; - } - - //check that there's space on nand - if (!_checkDsiSpace(installSize, (h->tid_high != 0x00030004))) - { - if (sdnandMode && choicePrint("Install as system title?")) - { - h->tid_high = 0x00030015; - fixHeader = true; - } - else - { - goto error; - } - } - - //check for saves - char pubPath[PATH_MAX]; - strcpy(pubPath, fpath); - strcpy(pubPath + extensionPos, ".pub"); - bool pubFound = getFileSizePath(pubPath) == h->public_sav_size; - if (access(pubPath, F_OK) == 0 && !pubFound) - { - if (choicePrint("Incorrect public save.\nInstall anyway?") == YES) - pubFound = false; - else - goto error; - } - - char prvPath[PATH_MAX]; - strcpy(prvPath, fpath); - strcpy(prvPath + extensionPos, ".prv"); - bool prvFound = getFileSizePath(prvPath) == h->private_sav_size; - if (access(prvPath, F_OK) == 0 && !prvFound) - { - if (choicePrint("Incorrect private save.\nInstall anyway?") == YES) - prvFound = false; - else - goto error; - } - - char bnrPath[PATH_MAX]; - strcpy(bnrPath, fpath); - strcpy(bnrPath + extensionPos, ".bnr"); - bool bnrFound = getFileSizePath(bnrPath) == 0x4000; - if (access(bnrPath, F_OK) == 0 && !bnrFound) - { - if (choicePrint("Incorrect banner save.\nInstall anyway?") == YES) - bnrFound = false; - else - goto error; - } - - if (_iqueHack(h)) - fixHeader = true; - - if (fixHeader && tmdFound) - { - if (choicePrint("Legit TMD cannot be used.\nInstall anyway?") == YES) - tmdFound = false; - else - goto error; - } - - //create title directory /title/XXXXXXXX/XXXXXXXX - char dirPath[32]; - mkdir(sdnandMode ? "sd:/title" : "nand:/title", 0777); - - sprintf(dirPath, "%s:/title/%08x", sdnandMode ? "sd" : "nand", (unsigned int)h->tid_high); - mkdir(dirPath, 0777); - - sprintf(dirPath, "%s:/title/%08x/%08x", sdnandMode ? "sd" : "nand", (unsigned int)h->tid_high, (unsigned int)h->tid_low); - - //check if title is free - if (_titleIsUsed(h)) - { - char msg[64]; - sprintf(msg, "Title %08x is already used.\nInstall anyway?", (unsigned int)h->tid_low); - - if (choicePrint(msg) == NO) - goto error; - - else - { - iprintf("\nDeleting:\n"); - deleteDir(dirPath); - iprintf("\n"); - } - } - - if (!_openMenuSlot()) - goto error; - - mkdir(dirPath, 0777); - - //content folder /title/XXXXXXXX/XXXXXXXXX/content - { - char contentPath[64]; - sprintf(contentPath, "%s/content", dirPath); - - mkdir(contentPath, 0777); - - u8 appVersion = 0; - if (tmdFound) - { - FILE *file = fopen(tmdPath, "rb"); - if (file) - { - fseek(file, 0x1E7, SEEK_SET); - fread(&appVersion, sizeof(appVersion), 1, file); - fclose(file); - } - } - - //create 000000##.app - { - iprintf("Creating 000000%02x.app...", appVersion); - swiWaitForVBlank(); - - char appPath[80]; - sprintf(appPath, "%s/000000%02x.app", contentPath, appVersion); - - //copy nds file to app - { - int result = 0; - - if (!romIsCia(fpath)) - result = copyFile(fpath, appPath); - else - result = copyFilePart(fpath, 0x3900, fileSize, appPath); - - if (result != 0) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[33m"); //yellow - iprintf("%s\n", appPath); - iprintf("%s\n", strerror(errno)); - iprintf("\x1B[47m"); //white - - goto error; - } - - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - } - - //pad out banner if it is the last part of the file - { - if (h->ndshdr.bannerOffset > (fileSize - 0x23C0)) - { - iprintf("Padding banner..."); - swiWaitForVBlank(); - - if (padFile(appPath, h->ndshdr.bannerOffset + 0x23C0 - fileSize) == false) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - } - } - } - - //update header - { - if (fixHeader) - { - iprintf("Fixing header..."); - swiWaitForVBlank(); - - //fix header checksum - h->ndshdr.headerCRC16 = swiCRC16(0xFFFF, h, 0x15E); - - //fix RSA signature - u8 buffer[20]; - swiSHA1Calc(&buffer, h, 0xE00); - memcpy(&(h->rsa_signature[0x6C]), buffer, 20); - - FILE* f = fopen(appPath, "r+"); - - if (!f) - { - iprintf("\x1B[31m"); //red - iprintf("Failed\n"); - iprintf("\x1B[47m"); //white - } - else - { - fseek(f, 0, SEEK_SET); - fwrite(h, sizeof(tDSiHeader), 1, f); - - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - } - - fclose(f); - } - } - - //make/copy TMD - char newTmdPath[80]; - sprintf(newTmdPath, "%s/title.tmd", contentPath); - if (tmdFound) - { - if (copyFilePart(tmdPath, 0, 520, newTmdPath) != 0) - goto error; - } - else - { - if (maketmd(appPath, newTmdPath) != 0) - goto error; - } - } - } - - //data folder - { - char dataPath[64]; - sprintf(dataPath, "%s/data", dirPath); - - mkdir(dataPath, 0777); - - if (pubFound) - { - char newPubPath[80]; - sprintf(newPubPath, "%s/public.sav", dataPath); - copyFile(pubPath, newPubPath); - } - else - { - _createPublicSav(h, dataPath); - } - - if (prvFound) - { - char newPrvPath[80]; - sprintf(newPrvPath, "%s/private.sav", dataPath); - copyFile(prvPath, newPrvPath); - } - else - { - _createPrivateSav(h, dataPath); - } - - if (bnrFound) - { - char newBnrPath[80]; - sprintf(newBnrPath, "%s/banner.sav", dataPath); - copyFile(bnrPath, newBnrPath); - } - else - { - _createBannerSav(h, dataPath); - } - } - - //ticket folder /ticket/XXXXXXXX - if (tmdFound) - { - //ensure folders exist - char ticketPath[32]; - siprintf(ticketPath, "%s:/ticket", sdnandMode ? "sd" : "nand"); - mkdir(ticketPath, 0777); - siprintf(ticketPath, "%s/%08lx", ticketPath, h->tid_high); - mkdir(ticketPath, 0777); - - //actual tik path - siprintf(ticketPath, "%s/%08lx.tik", ticketPath, h->tid_low); - - if (access(ticketPath, F_OK) != 0 || (choicePrint("Ticket already exists.\nKeep it? (recommended)") == NO && choicePrint("Are you sure?") == YES)) - _createTicket(h, ticketPath); - } - - //end - result = true; - iprintf("\x1B[42m"); //green - iprintf("\nInstallation complete.\n"); - iprintf("\x1B[47m"); //white - iprintf("Back - [B]\n"); - keyWait(KEY_A | KEY_B); - - goto complete; - } - -error: - messagePrint("\x1B[31m\nInstallation failed.\n\x1B[47m"); - -complete: - free(h); - - if (!sdnandMode) - nandio_lock_writing(); - - return result; -} \ No newline at end of file diff --git a/arm9/src/install.h b/arm9/src/install.h deleted file mode 100644 index 5cab1c2..0000000 --- a/arm9/src/install.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef INSTALL_H -#define INSTALL_H - -#include - -bool install(char* fpath, bool systemTitle); - -#endif \ No newline at end of file diff --git a/arm9/src/installmenu.c b/arm9/src/installmenu.c deleted file mode 100644 index 380a12f..0000000 --- a/arm9/src/installmenu.c +++ /dev/null @@ -1,320 +0,0 @@ -#include "main.h" -#include "rom.h" -#include "install.h" -#include "menu.h" -#include "storage.h" -#include "message.h" -#include - -enum { - INSTALL_MENU_INSTALL, - INSTALL_MENU_SYSTEM_TITLE, - INSTALL_MENU_DELETE, - INSTALL_MENU_BACK -}; - -static char currentDir[512] = ""; - -static void generateList(Menu* m); -static void printItem(Menu* m); -static int subMenu(); -static bool delete(Menu* m); - -static void _setHeader(Menu* m) -{ - if (!m) return; - if (currentDir[0] == '\0') - setMenuHeader(m, "sd:/"); - else - setMenuHeader(m, currentDir); -} - -void installMenu() -{ - Menu* m = newMenu(); - _setHeader(m); - generateList(m); - - //no files found -/* if (m->itemCount <= 0) - { - clearScreen(&bottomScreen); - - iprintf("\x1B[31m"); //red - iprintf("No files found.\n"); - iprintf("\x1B[47m"); //white - iprintf("\nBack - [B]\n"); - - keyWait(KEY_B | KEY_A | KEY_START); - } - else*/ - { - while (!programEnd) - { - swiWaitForVBlank(); - scanKeys(); - - if (moveCursor(m)) - { - if (m->changePage != 0) - generateList(m); - - printMenu(m); - printItem(m); - } - - //back - if (keysDown() & KEY_B) - { - char* ptr = strrchr(currentDir, '/'); - - if (ptr) - { - *ptr = '\0'; - _setHeader(m); - resetMenu(m); - generateList(m); - printMenu(m); - } - else - { - break; - } - } - - else if (keysDown() & KEY_X) - break; - - //selection - else if (keysDown() & KEY_A) - { - if (m->itemCount > 0) - { - if (m->items[m->cursor].directory == false) - { - //nds file - switch (subMenu()) - { - case INSTALL_MENU_INSTALL: - install(m->items[m->cursor].value, false); - break; - - case INSTALL_MENU_SYSTEM_TITLE: - if (sdnandMode) - install(m->items[m->cursor].value, true); - break; - - case INSTALL_MENU_DELETE: - { - if (delete(m)) - { - resetMenu(m); - generateList(m); - } - } - break; - - case INSTALL_MENU_BACK: - break; - } - } - else - { - //directory - sprintf(currentDir, "%s", m->items[m->cursor].value); - _setHeader(m); - resetMenu(m); - generateList(m); - } - - printMenu(m); - } - } - } - } - - freeMenu(m); -} - -static void generateList(Menu* m) -{ - if (!m) return; - - //reset menu - clearMenu(m); - - m->page += sign(m->changePage); - m->changePage = 0; - - bool done = false; - - struct dirent* ent; - DIR* dir = NULL; - - if (currentDir[0] == '\0') - dir = opendir("sd:/"); - else - dir = opendir(currentDir); - - if (dir) - { - int count = 0; - - while ( (ent = readdir(dir)) && !done) - { - if (ent->d_name[0] == '.') - continue; - - if (ent->d_type == DT_DIR) - { - if (count < m->page * ITEMS_PER_PAGE) - count += 1; - - else - { - if (m->itemCount >= ITEMS_PER_PAGE) - done = true; - - else - { - char* fpath = (char*)malloc(strlen(currentDir) + strlen(ent->d_name) + 8); - sprintf(fpath, "%s/%s", currentDir, ent->d_name); - - addMenuItem(m, ent->d_name, fpath, 1); - } - } - } - else - { - if (strcasecmp(strrchr(ent->d_name, '.'), ".nds") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".app") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".dsi") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".ids") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".srl") == 0 || - strcasecmp(strrchr(ent->d_name, '.'), ".cia") == 0) - { - if (count < m->page * ITEMS_PER_PAGE) - count += 1; - - else - { - if (m->itemCount >= ITEMS_PER_PAGE) - done = true; - - else - { - char* fpath = (char*)malloc(strlen(currentDir) + strlen(ent->d_name) + 8); - sprintf(fpath, "%s/%s", currentDir, ent->d_name); - - addMenuItem(m, ent->d_name, fpath, 0); - - free(fpath); - } - } - } - } - } - } - - closedir(dir); - - sortMenuItems(m); - - m->nextPage = done; - - if (m->cursor >= m->itemCount) - m->cursor = m->itemCount - 1; - - printItem(m); - printMenu(m); -} - -static void printItem(Menu* m) -{ - if (!m) return; - if (m->itemCount <= 0) return; - - if (m->items[m->cursor].directory) - clearScreen(&topScreen); - else - printRomInfo(m->items[m->cursor].value); -} - -static int subMenu() -{ - int result = -1; - - Menu* m = newMenu(); - - addMenuItem(m, "Install", NULL, 0); - addMenuItem(m, sdnandMode ? "Install as System Title" : "\x1B[37m[Disabled]\x1B[47m", NULL, 0); - addMenuItem(m, "Delete", NULL, 0); - addMenuItem(m, "Back - [B]", NULL, 0); - - printMenu(m); - - while (!programEnd) - { - swiWaitForVBlank(); - scanKeys(); - - if (moveCursor(m)) - printMenu(m); - - if (keysDown() & KEY_B) - { - result = -1; - break; - } - - else if (keysDown() & KEY_A) - { - result = m->cursor; - break; - } - } - - freeMenu(m); - return result; -} - -static bool delete(Menu* m) -{ - if (!m) return false; - - char* fpath = m->items[m->cursor].value; - - bool result = false; - bool choice = NO; - { - char str[] = "Are you sure you want to delete\n"; - char* msg = (char*)malloc(strlen(str) + strlen(fpath) + 1); - sprintf(msg, "%s%s", str, fpath); - - choice = choiceBox(msg); - - free(msg); - } - - if (choice == YES) - { - if (!fpath) - { - messageBox("\x1B[31mCould not delete file.\x1B[47m"); - } - else - { - if (remove(fpath) == 0) - { - result = true; - messageBox("\x1B[42mFile deleted.\x1B[47m"); - } - else - { - messageBox("\x1B[31mCould not delete file.\x1B[47m"); - } - } - } - - return result; -} \ No newline at end of file diff --git a/arm9/src/main.c b/arm9/src/main.c index 8f730a5..d27fa33 100644 --- a/arm9/src/main.c +++ b/arm9/src/main.c @@ -9,34 +9,21 @@ #include #include -bool programEnd = false; -bool sdnandMode = true; -bool retailLauncherTmdPresentAndToBePatched = true; -bool retailConsole = true; -bool unlaunchInstallerFound = false; -bool unlaunchFound = false; -bool unlaunchPatches = false; -bool devkpFound = false; -bool launcherDSiFound = false; +volatile bool programEnd = false; +static bool unlaunchFound = false; +static bool retailLauncherTmdPresentAndToBePatched = true; +static bool retailConsole = true; +static bool unlaunchInstallerFound = false; bool arm7Exiting = false; bool charging = false; u8 batteryLevel = 0; -u8 region = 0xFF; PrintConsole topScreen; PrintConsole bottomScreen; enum { - MAIN_MENU_MODE, - MAIN_MENU_INSTALL, MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL, MAIN_MENU_SAFE_UNLAUNCH_INSTALL, - MAIN_MENU_TITLES, - MAIN_MENU_BACKUP, - MAIN_MENU_TEST, - MAIN_MENU_FIX, - MAIN_MENU_DATA_MANAGEMENT, - MAIN_MENU_LANGUAGE_PATCHER, MAIN_MENU_EXIT }; @@ -78,20 +65,10 @@ static int _mainMenu(int cursor) Menu* m = newMenu(); setMenuHeader(m, "MAIN MENU"); - char modeStr[32], datamanStr[32], launcherStr[32]; - sprintf(modeStr, "Mode: %s", sdnandMode ? "SDNAND" : "\x1B[41mSysNAND\x1B[47m"); - sprintf(datamanStr, "\x1B[%02omEnable Data Management", devkpFound ? 037 : 047); - sprintf(launcherStr, "\x1B[%02omUninstall region mod", launcherDSiFound ? 047 : 037); - addMenuItem(m, modeStr, NULL, 0); - addMenuItem(m, "Install", NULL, 0); - addMenuItem(m, "Safe unlaunch uninstall", NULL, 0); - addMenuItem(m, "Safe unlaunch install", NULL, 0); - addMenuItem(m, "Titles", NULL, 0); - addMenuItem(m, "Restore", NULL, 0); - addMenuItem(m, "Test", NULL, 0); - addMenuItem(m, "Fix FAT copy mismatch", NULL, 0); - addMenuItem(m, datamanStr, NULL, 0); - addMenuItem(m, launcherStr, NULL, 0); + char uninstallStr[32]; + sprintf(uninstallStr, "\x1B[%02omSafe unlaunch uninstall", unlaunchFound ? 047 : 037); + addMenuItem(m, uninstallStr, NULL, 0); + addMenuItem(m, "\x1B[47mSafe unlaunch install", NULL, 0); addMenuItem(m, "\x1B[47mExit", NULL, 0); m->cursor = cursor; @@ -132,40 +109,6 @@ void fifoHandlerBattery(u32 value32, void* userdata) charging = (value32 & BIT(7)) != 0; } -bool checkIfUnlaunchHasPatches(const char* path) -{ - //check if launcher patches are enabled - const static u32 tidValues[][2] = { - // {location, value} - {0xE439, 0x382E3176}, // 1.8 - {0xB07C, 0x17484E41}, // 1.9 - {0xB099, 0x17484E41}, // 2.0 (Normal) - {0xB079, 0x484E1841}, // 2.0 (Patched) - }; - - bool patched = false; - - FILE *tmd = fopen(path, "rb"); - if (tmd) - { - for (int i = 0; i < sizeof(tidValues) / sizeof(tidValues[0]); i++) - { - if (fseek(tmd, tidValues[i][0], SEEK_SET) == 0) - { - u32 tidVal; - fread(&tidVal, sizeof(u32), 1, tmd); - if (tidVal == tidValues[i][1]) - { - patched = true; - break; - } - } - } - } - fclose(tmd); - return patched; -} - int main(int argc, char **argv) { srand(time(0)); @@ -196,9 +139,10 @@ int main(int argc, char **argv) return 0; } - unlaunchInstallerFound = (access("sd:/unlaunch.dsi", F_OK) == 0); + unlaunchInstallerFound = fileExists("sd:/unlaunch.dsi"); //check for unlaunch and region + u8 region = 0xff; char retailLauncherTmdPath[64]; const char* hnaaTmdPath = "nand:/title/00030017/484e4141/content/title.tmd"; { @@ -218,7 +162,6 @@ int main(int argc, char **argv) if (tmdSize > 520) { unlaunchFound = true; - unlaunchPatches = checkIfUnlaunchHasPatches(retailLauncherTmdPath); } else if(tmdSize != 520) { @@ -242,26 +185,10 @@ int main(int argc, char **argv) if (tmdSize > 520) { unlaunchFound = true; - unlaunchPatches = checkIfUnlaunchHasPatches(hnaaTmdPath); } } - - if (!unlaunchFound) - { - messageBox("Unlaunch not found. TMD files\nwill be required and there\nis a greater risk something\ncould go wrong.\n\nSee \x1B[46mhttps://dsi.cfw.guide/\x1B[47m to\ninstall."); - } - else if (!unlaunchPatches) - { - messageBox("Unlaunch's Launcher Patches are\nnot enabled. You will need to\nprovide TMD files or reinstall.\n\n\x1B[46mhttps://dsi.cfw.guide/\x1B[47m"); - } } - //check for dev.kp (Data Management visible) - devkpFound = (access("sd:/sys/dev.kp", F_OK) == 0); - - //check for launcher.dsi (Language patcher) - launcherDSiFound = (access("nand:/launcher.dsi", F_OK) == 0); - messageBox("\x1B[41mWARNING:\x1B[47m This tool can write to\nyour internal NAND!\n\nThis always has a risk, albeit\nlow, of \x1B[41mbricking\x1B[47m your system\nand should be done with caution!\n\nIf you have not yet done so,\nyou should make a NAND backup."); messageBox("If you are following a video\nguide, please stop.\n\nVideo guides for console moddingare often outdated or straight\nup incorrect to begin with.\n\nThe recommended guide for\nmodding your DSi is:\n\n\x1B[46mhttps://dsi.cfw.guide/\x1B[47m\n\nFor more information on using\nNTM, see the official wiki:\n\n\x1B[46mhttps://github.com/Epicpkmn11/\n\t\t\t\t\t\t\t\tNTM/wiki\x1B[47m"); @@ -274,15 +201,6 @@ int main(int argc, char **argv) switch (cursor) { - case MAIN_MENU_MODE: - sdnandMode = !sdnandMode; - devkpFound = (access(sdnandMode ? "sd:/sys/dev.kp" : "nand:/sys/dev.kp", F_OK) == 0); - break; - - case MAIN_MENU_INSTALL: - installMenu(); - break; - case MAIN_MENU_SAFE_UNLAUNCH_UNINSTALL: if(!unlaunchFound) { @@ -291,6 +209,7 @@ int main(int argc, char **argv) if(uninstallUnlaunch(retailConsole, retailLauncherTmdPath)) { messageBox("Uninstall successful!\n"); + unlaunchFound = false; } else { messageBox("\x1B[31mError:\x1B[33m Uninstall failed\n"); } @@ -306,6 +225,7 @@ int main(int argc, char **argv) if(installUnlaunch(retailConsole, retailLauncherTmdPresentAndToBePatched ? retailLauncherTmdPath : NULL)) { messageBox("Install successful!\n"); + unlaunchFound = true; } else { messageBox("\x1B[31mError:\x1B[33m Install failed\n"); } @@ -313,56 +233,6 @@ int main(int argc, char **argv) } break; - case MAIN_MENU_TITLES: - titleMenu(); - break; - - case MAIN_MENU_BACKUP: - backupMenu(); - break; - - case MAIN_MENU_TEST: - testMenu(); - break; - - case MAIN_MENU_FIX: - if (nandio_unlock_writing()) - { - nandio_force_fat_fix(); - nandio_lock_writing(); - messageBox("Mismatch in FAT copies will be\nfixed on close.\n"); - } - break; - - case MAIN_MENU_DATA_MANAGEMENT: - if (!devkpFound && (choiceBox("Make Data Management visible\nin System Settings?") == YES) && (sdnandMode || nandio_unlock_writing())) - { - //ensure sys folder exists - if(access(sdnandMode ? "sd:/sys" : "nand:/sys", F_OK) != 0) - mkdir(sdnandMode ? "sd:/sys" : "nand:/sys", 0777); - - //create empty file - FILE *file = fopen(sdnandMode ? "sd:/sys/dev.kp" : "nand:/sys/dev.kp", "wb"); - fclose(file); - - if(!sdnandMode) - nandio_lock_writing(); - devkpFound = (access(sdnandMode ? "sd:/sys/dev.kp" : "nand:/sys/dev.kp", F_OK) == 0); - messageBox("Data Management is now visible\nin System Settings.\n"); - } - break; - case MAIN_MENU_LANGUAGE_PATCHER: - if (launcherDSiFound && (choiceBox("Uninstall the language patched\nDSi Menu? (launcher.dsi)") == YES) && nandio_unlock_writing()) - { - //delete launcher.dsi - remove("nand:/launcher.dsi"); - - nandio_lock_writing(); - launcherDSiFound = (access("nand:/launcher.dsi", F_OK) == 0); - messageBox("The language patched DSi Menu\nhas been removed.\n"); - } - break; - case MAIN_MENU_EXIT: programEnd = true; break; diff --git a/arm9/src/main.h b/arm9/src/main.h index a24c906..99a0799 100644 --- a/arm9/src/main.h +++ b/arm9/src/main.h @@ -5,26 +5,13 @@ #include #include -extern bool programEnd; -extern bool sdnandMode; -extern bool unlaunchFound; -extern bool unlaunchPatches; +extern volatile bool programEnd; extern bool charging; extern u8 batteryLevel; -extern u8 region; - -void installMenu(); -void titleMenu(); -void backupMenu(); -void testMenu(); extern PrintConsole topScreen; extern PrintConsole bottomScreen; void clearScreen(PrintConsole* screen); -#define abs(X) ( (X) < 0 ? -(X): (X) ) -#define sign(X) ( ((X) > 0) - ((X) < 0) ) -#define repeat(X) for (int _I_ = 0; _I_ < (X); _I_++) - #endif \ No newline at end of file diff --git a/arm9/src/maketmd.c b/arm9/src/maketmd.c deleted file mode 100644 index 6467995..0000000 --- a/arm9/src/maketmd.c +++ /dev/null @@ -1,191 +0,0 @@ -/*--------------------------------------------------------------------------------- - -maketmd.cpp -- TMD Creator for DSiWare Homebrew - -Copyright (C) 2018 - Przemyslaw Skryjomski (Tuxality) - -Big thanks to: - Apache Thunder - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you -must not claim that you wrote the original software. If you use -this software in a product, an acknowledgment in the product -documentation would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - ----------------------------------------------------------------------------------*/ - -/* September 2018 - Jeff - Translated from C++ to C and uses libnds instead of openssl - Original: github.com/Tuxality/maketmd -*/ - -#include "maketmd.h" -#include -#include -#include -#include -#include -#include - -//#define TMD_CREATOR_VER "0.2" - -#define TMD_SIZE 0x208 -#define SHA_BUFFER_SIZE 0x200 -#define SHA_DIGEST_LENGTH 0x14 - -void tmd_create(uint8_t* tmd, FILE* app) -{ - // Phase 1 - offset 0x18C (Title ID, first part) - { - fseek(app, 0x234, SEEK_SET); - - uint32_t value; - fread(&value, 4, 1, app); - value = __bswap32(value); - - memcpy(tmd + 0x18c, &value, 4); - } - - // Phase 2 - offset 0x190 (Title ID, second part) - { - // We can take this also from 0x230, but reversed - fseek(app, 0x0C, SEEK_SET); - fread((char*)&tmd[0x190], 4, 1, app); - } - - // Phase 3 - offset 0x198 (Group ID = '01') - { - fseek(app, 0x10, SEEK_SET); - fread((char*)&tmd[0x198], 2, 1, app); - } - - // Phase 4 - offset 0x1AA (fill-in 0x80 value, 0x10 times) - { - for (size_t i = 0; i<0x10; i++) - { - tmd[0x1AA + i] = 0x80; - } - } - - // Phase 5 - offset 0x1DE (number of contents = 1) - { - tmd[0x1DE] = 0x00; - tmd[0x1DF] = 0x01; - } - - // Phase 6 - offset 0x1EA (type of content = 1) - { - tmd[0x1EA] = 0x00; - tmd[0x1EB] = 0x01; - } - - // Phase 7 - offset, 0x1EC (file size, 8B) - uint32_t filesize = 0; - uint32_t fileread = 0; - { - fseek(app, 0, SEEK_END); - filesize = ftell(app); - uint32_t size = __bswap32(filesize); - - // We only use 4B for size as for now - memcpy((tmd + 0x1F0), &size, sizeof(u32)); - } - - // Phase 8 - offset, 0x1F4 (SHA1 sum, 20B) - { - // Makes use of libnds - fseek(app, 0, SEEK_SET); - - uint8_t buffer[SHA_BUFFER_SIZE] = { 0 }; - uint32_t buffer_read = 0; - - swiSHA1context_t ctx; - swiSHA1Init(&ctx); - - do { - buffer_read = fread((char*)&buffer[0], 1, SHA_BUFFER_SIZE, app); - fileread += buffer_read; - - swiSHA1Update(&ctx, buffer, buffer_read); - - printProgressBar((float)fileread / (float)filesize); - } - while (buffer_read == SHA_BUFFER_SIZE); - - clearProgressBar(); - consoleSelect(&bottomScreen); - - swiSHA1Final(buffer, &ctx); - - //Store SHA1 sum - memcpy((tmd + 0x1F4), buffer, SHA_DIGEST_LENGTH); - } -} - -int maketmd(char* input, char* tmdPath) -{ - iprintf("MakeTMD for DSiWare Homebrew\n"); - iprintf("by Przemyslaw Skryjomski\n\t(Tuxality)\n"); - - if (input == NULL || tmdPath == NULL) - { - iprintf("\x1B[33m"); //yellow - iprintf("\nUsage: %s file.app \n", "maketmd"); - iprintf("\x1B[47m"); //white - return 1; - } - - // APP file (input) - FILE* app = fopen(input, "rb"); - - if (!app) - { - iprintf("\x1B[31m"); //red - iprintf("Error at opening %s for reading.\n", input); - iprintf("\x1B[47m"); //white - return 1; - } - - // TMD file (output) - FILE* tmd = fopen(tmdPath, "wb"); - - if (!tmd) - { - fclose(app); - iprintf("\x1B[31m"); //white - iprintf("Error at opening %s for writing.\n", tmdPath); - iprintf("\x1B[47m"); //white - return 1; - } - - // Allocate memory for TMD - uint8_t* tmd_template = (uint8_t*)malloc(sizeof(uint8_t) * TMD_SIZE); - memset(tmd_template, 0, sizeof(uint8_t) * TMD_SIZE); // zeroed - - // Prepare TMD template then write to file - tmd_create(tmd_template, app); - fwrite((const char*)(&tmd_template[0]), TMD_SIZE, 1, tmd); - - // Free allocated memory for TMD - free(tmd_template); - - // This is done in dtor, but we additionally flush tmd. - fclose(app); - fclose(tmd); - - return 0; -} \ No newline at end of file diff --git a/arm9/src/maketmd.h b/arm9/src/maketmd.h deleted file mode 100644 index a40d20d..0000000 --- a/arm9/src/maketmd.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef MAKETMD_H -#define MAKETMD_H - -#include "main.h" -#include "storage.h" - -int maketmd(char* input, char* tmdPath); - -#endif \ No newline at end of file diff --git a/arm9/src/menu.c b/arm9/src/menu.c index 1c6ec19..25b4817 100644 --- a/arm9/src/menu.c +++ b/arm9/src/menu.c @@ -1,6 +1,9 @@ #include "menu.h" #include "main.h" +#define sign(X) ( ((X) > 0) - ((X) < 0) ) +#define repeat(X) for (int _I_ = 0; _I_ < (X); _I_++) + Menu* newMenu() { Menu* m = (Menu*)malloc(sizeof(Menu)); diff --git a/arm9/src/nand/nandio.c b/arm9/src/nand/nandio.c index e63cafe..c2ca1f3 100644 --- a/arm9/src/nand/nandio.c +++ b/arm9/src/nand/nandio.c @@ -264,8 +264,7 @@ bool nandio_lock_writing() bool nandio_unlock_writing() { - if (writingLocked && randomConfirmBox("Writing to NAND is locked!\nIf you're sure you understand\nthe risk, input the sequence\nbelow.")) - writingLocked = false; + writingLocked = false; return !writingLocked; } diff --git a/arm9/src/rom.c b/arm9/src/rom.c deleted file mode 100644 index fab9ddc..0000000 --- a/arm9/src/rom.c +++ /dev/null @@ -1,296 +0,0 @@ -#include "rom.h" -#include "main.h" -#include "storage.h" -#include -#include -#include -#include - -tDSiHeader* getRomHeader(char const* fpath) -{ - if (!fpath) return NULL; - - tDSiHeader* h = NULL; - FILE* f = fopen(fpath, "rb"); - - if (f) - { - h = (tDSiHeader*)malloc(sizeof(tDSiHeader)); - - if (h) - { - if (romIsCia(fpath)) - fseek(f, 0x3900, SEEK_SET); - else - fseek(f, 0, SEEK_SET); - - fread(h, sizeof(tDSiHeader), 1, f); - } - - fclose(f); - } - - return h; -} - -tNDSBanner* getRomBanner(char const* fpath) -{ - if (!fpath) return NULL; - - tDSiHeader* h = getRomHeader(fpath); - tNDSBanner* b = NULL; - - if (h) - { - FILE* f = fopen(fpath, "rb"); - - if (f) - { - b = (tNDSBanner*)malloc(sizeof(tNDSBanner)); - - if (b) - { - if (romIsCia(fpath)) - fseek(f, 0x3900, SEEK_SET); - else - fseek(f, 0, SEEK_SET); - - fseek(f, h->ndshdr.bannerOffset, SEEK_CUR); - fread(b, sizeof(tNDSBanner), 1, f); - } - } - - free(h); - fclose(f); - } - - return b; -} - -bool getGameTitle(tNDSBanner* b, char* out, bool full) -{ - if (!b) return false; - if (!out) return false; - - //get system language - int lang = PersonalData->language; - - //not japanese or chinese - if (lang == 0 || lang == 6) - lang = 1; - - //read title - u16 c; - for (int i = 0; i < 128; i++) - { - c = b->titles[lang][i]; - - //remove accents - if (c == 0x00F3) - c = 'o'; - - if (c == 0x00E1) - c = 'a'; - - out[i] = (char)c; - - if (!full && out[i] == '\n') - { - out[i] = '\0'; - break; - } - } - out[128] = '\0'; - - return true; -} - -bool getGameTitlePath(char const* fpath, char* out, bool full) -{ - if (!fpath) return false; - if (!out) return false; - - tNDSBanner* b = getRomBanner(fpath); - bool result = getGameTitle(b, out, full); - - free(b); - return result; -} - -bool getRomLabel(tDSiHeader* h, char* out) -{ - if (!h) return false; - if (!out) return false; - - sprintf(out, "%.12s", h->ndshdr.gameTitle); - - return true; -} - -bool getRomCode(tDSiHeader* h, char* out) -{ - if (!h) return false; - if (!out) return false; - - sprintf(out, "%.4s", h->ndshdr.gameCode); - - return true; -} - -void printRomInfo(char const* fpath) -{ - clearScreen(&topScreen); - - if (!fpath) return; - - tDSiHeader* h = getRomHeader(fpath); - tNDSBanner* b = getRomBanner(fpath); - - if (!isDsiHeader(h)) - { - iprintf("Could not read dsi header.\n"); - } - else - { - if (!b) - { - iprintf("Could not read banner.\n"); - } - else - { - //proper title - { - char gameTitle[128+1]; - getGameTitle(b, gameTitle, true); - - iprintf("%s\n\n", gameTitle); - } - - //file size - { - iprintf("Size: "); - unsigned long long romSize = getRomSize(fpath); - printBytes(romSize); - //size in blocks, rounded up - iprintf(" (%lld blocks)\n", ((romSize / BYTES_PER_BLOCK) * BYTES_PER_BLOCK + BYTES_PER_BLOCK) / BYTES_PER_BLOCK); - } - - iprintf("Label: %.12s\n", h->ndshdr.gameTitle); - iprintf("Game Code: %.4s\n", h->ndshdr.gameCode); - - //system type - { - iprintf("Unit Code: "); - - switch (h->ndshdr.unitCode) - { - case 0: iprintf("NDS"); break; - case 2: iprintf("NDS+DSi"); break; - case 3: iprintf("DSi"); break; - default: iprintf("unknown"); - } - - iprintf("\n"); - } - - //application type - { - iprintf("Program Type: "); - - switch (h->ndshdr.reserved1[7]) - { - case 0x3: iprintf("Normal"); break; - case 0xB: iprintf("Sys"); break; - case 0xF: iprintf("Debug/Sys"); break; - default: iprintf("unknown"); - } - - iprintf("\n"); - } - - //DSi title ids - { - if (h->tid_high == 0x00030004 || - h->tid_high == 0x00030005 || - h->tid_high == 0x00030011 || // TID for software in TWL SDK - h->tid_high == 0x00030015 || - h->tid_high == 0x00030017 || - h->tid_high == 0x00030000) - { - iprintf("Title ID: %08x %08x\n", (unsigned int)h->tid_high, (unsigned int)h->tid_low); - } - } - - //print full file path - iprintf("\n%s\n", fpath); - - //print extra files - int extensionPos = strrchr(fpath, '.') - fpath; - char temp[PATH_MAX]; - strcpy(temp, fpath); - strcpy(temp + extensionPos, ".tmd"); - //DSi TMDs are 520, TMDs from NUS are 2,312. If 2,312 we can simply trim it to 520 - int tmdSize = getFileSizePath(temp); - if (access(temp, F_OK) == 0) - printf("\t\x1B[%om%s\n\x1B[47m", (tmdSize == 520 || tmdSize == 2312) ? 047 : 041, strrchr(temp, '/') + 1); - - strcpy(temp + extensionPos, ".pub"); - if (access(temp, F_OK) == 0) - printf("\t\x1B[%om%s\n\x1B[47m", (getFileSizePath(temp) == h->public_sav_size) ? 047 : 041, strrchr(temp, '/') + 1); - - strcpy(temp + extensionPos, ".prv"); - if (access(temp, F_OK) == 0) - printf("\t\x1B[%om%s\n\x1B[47m", (getFileSizePath(temp) == h->private_sav_size) ? 047 : 041, strrchr(temp, '/') + 1); - - strcpy(temp + extensionPos, ".bnr"); - if (access(temp, F_OK) == 0) - printf("\t\x1B[%om%s\n\x1B[47m", (getFileSizePath(temp) == 0x4000) ? 047 : 041, strrchr(temp, '/') + 1); - } - } - - free(b); - free(h); -} - -unsigned long long getRomSize(char const* fpath) -{ - if (!fpath) return 0; - - unsigned long long size = 0; - FILE* f = fopen(fpath, "rb"); - - if (f) - { - //cia - if (romIsCia(fpath)) - { - unsigned char bytes[4] = { 0 }; - fseek(f, 0x38D0, SEEK_SET); - fread(bytes, 4, 1, f); - size = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]; - } - else - { - fseek(f, 0, SEEK_END); - size = ftell(f); - } - } - - fclose(f); - return size; -} - -bool romIsCia(char const* fpath) -{ - if (!fpath) return false; - return (strstr(fpath, ".cia") != NULL || strstr(fpath, ".CIA") != NULL); -} - -bool isDsiHeader(tDSiHeader* h) -{ - if (!h) return false; - - u16 crc16 = swiCRC16(0xFFFF, h, 0x15E); - - return h->ndshdr.headerCRC16 == crc16; -} \ No newline at end of file diff --git a/arm9/src/rom.h b/arm9/src/rom.h deleted file mode 100644 index 9fc07d5..0000000 --- a/arm9/src/rom.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef ROM_H -#define ROM_H - -#include -#include - -tDSiHeader* getRomHeader(char const* fpath); -tNDSBanner* getRomBanner(char const* fpath); - -bool getGameTitle(tNDSBanner* b, char* out, bool full); -bool getGameTitlePath(char const* fpath, char* out, bool full); - -bool getRomLabel(tDSiHeader* h, char* out); -bool getRomCode(tDSiHeader* h, char* out); - -void printRomInfo(char const* fpath); - -unsigned long long getRomSize(char const* fpath); - -bool romIsCia(char const* fpath); -bool isDsiHeader(tDSiHeader* h); - -#endif \ No newline at end of file diff --git a/arm9/src/sav.c b/arm9/src/sav.c deleted file mode 100644 index ed27cd2..0000000 --- a/arm9/src/sav.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "sav.h" -#include -#include - -#define align(v, a) (((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v)) - -bool initFatHeader(FILE* f) -{ - if (!f) - return false; - - //get size - fseek(f, 0, SEEK_END); - u32 size = ftell(f); - - //based on GodMode9 - //https://github.com/d0k3/GodMode9/blob/d8d43c14f3317423c677b1c7e0987bcb9bbd7299/arm9/source/game/nds.c#L47-L105 - const u16 sectorSize = 0x200; - - //fit maximum sectors for the size - const u16 maxSectors = size / sectorSize; - u16 sectorCount = 1; - u16 secPerTrk = 1; - u16 numHeads = 1; - u16 sectorCountNext = 0; - while (sectorCountNext <= maxSectors) - { - sectorCountNext = secPerTrk * (numHeads + 1) * (numHeads + 1); - if (sectorCountNext <= maxSectors) - { - numHeads++; - sectorCount = sectorCountNext; - - secPerTrk++; - sectorCountNext = secPerTrk * numHeads * numHeads; - if (sectorCountNext <= maxSectors) - { - sectorCount = sectorCountNext; - } - } - } - sectorCountNext = (secPerTrk + 1) * numHeads * numHeads; - if (sectorCountNext <= maxSectors) - { - secPerTrk++; - sectorCount = sectorCountNext; - } - - u8 secPerCluster = (sectorCount > (8 << 10)) ? 8 : (sectorCount > (1 << 10) ? 4 : 1); - - u16 rootEntryCount = size < 0x8C000 ? 0x20 : 0x200; - - u16 totalClusters = align(sectorCount, secPerCluster) / secPerCluster; - u32 fatBytes = (align(totalClusters, 2) / 2) * 3; // 2 sectors -> 3 byte - u16 fatSize = align(fatBytes, sectorSize) / sectorSize; - - - FATHeader* h = (FATHeader*)malloc(sizeof(FATHeader)); - - h->BS_JmpBoot[0] = 0xE9; - h->BS_JmpBoot[1] = 0; - h->BS_JmpBoot[2] = 0; - - memcpy(h->BS_OEMName, "MSWIN4.1", 8); - - h->BPB_BytesPerSec = sectorSize; - h->BPB_SecPerClus = secPerCluster; - h->BPB_RsvdSecCnt = 0x0001; - h->BPB_NumFATs = 0x02; - h->BPB_RootEntCnt = rootEntryCount; - h->BPB_TotSec16 = sectorCount; - h->BPB_Media = 0xF8; // "hard drive" - h->BPB_FATSz16 = fatSize; - h->BPB_SecPerTrk = secPerTrk; - h->BPB_NumHeads = numHeads; - h->BPB_HiddSec = 0x00000000; - h->BPB_TotSec32 = 0x00000000; - h->BS_DrvNum = 0x05; - h->BS_Reserved1 = 0x00; - h->BS_BootSig = 0x29; - h->BS_VolID = 0x12345678; - memcpy(h->BS_VolLab, "VOLUMELABEL", 11); - memcpy(h->BS_FilSysType,"FAT12 ", 8); - memset(h->BS_BootCode, 0, sizeof(h->BS_BootCode)); - h->BS_BootSign = 0xAA55; - - fseek(f, 0, SEEK_SET); - fwrite(h, sizeof(FATHeader), 1, f); - - free(h); - - return true; -} \ No newline at end of file diff --git a/arm9/src/sav.h b/arm9/src/sav.h deleted file mode 100644 index 514f342..0000000 --- a/arm9/src/sav.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SAV_H -#define SAV_H - -#include -#include -//http://elm-chan.org/docs/fat_e.html - -#pragma pack(push, 1) -typedef struct -{ - u8 BS_JmpBoot[3]; //0x0000 - u8 BS_OEMName[8]; //0x0003 - u16 BPB_BytesPerSec; //0x000B - u8 BPB_SecPerClus; //0x000D - u16 BPB_RsvdSecCnt; //0x000E - u8 BPB_NumFATs; - u16 BPB_RootEntCnt; - u16 BPB_TotSec16; - u8 BPB_Media; - u16 BPB_FATSz16; - u16 BPB_SecPerTrk; - u16 BPB_NumHeads; - u32 BPB_HiddSec; - u32 BPB_TotSec32; - u8 BS_DrvNum; - u8 BS_Reserved1; - u8 BS_BootSig; - u32 BS_VolID; - u8 BS_VolLab[11]; - u8 BS_FilSysType[8]; - u8 BS_BootCode[448]; - u16 BS_BootSign; -} FATHeader; -#pragma pack(push, 0) - -bool initFatHeader(FILE* f); - -#endif \ No newline at end of file diff --git a/arm9/src/storage.c b/arm9/src/storage.c index d2aecd1..334127b 100644 --- a/arm9/src/storage.c +++ b/arm9/src/storage.c @@ -6,26 +6,10 @@ #define TITLE_LIMIT 39 -//printing -void printBytes(unsigned long long bytes) -{ - if (bytes < 1024) - iprintf("%dB", (unsigned int)bytes); - - else if (bytes < 1024 * 1024) - printf("%.2fKB", (float)bytes / 1024.f); - - else if (bytes < 1024 * 1024 * 1024) - printf("%.2fMB", (float)bytes / 1024.f / 1024.f); - - else - printf("%.2fGB", (float)bytes / 1024.f / 1024.f / 1024.f); -} - //progress bar static int lastBars = 0; -void printProgressBar(float percent) +static void printProgressBar(float percent) { if (percent < 0.f) percent = 0.f; if (percent > 1.f) percent = 1.f; @@ -59,7 +43,7 @@ void printProgressBar(float percent) } } -void clearProgressBar() +static void clearProgressBar() { lastBars = 0; consoleSelect(&topScreen); @@ -69,14 +53,7 @@ void clearProgressBar() //files bool fileExists(char const* path) { - if (!path) return false; - - FILE* f = fopen(path, "rb"); - if (!f) - return false; - - fclose(f); - return true; + return access(path, F_OK) == 0; } int copyFile(char const* src, char const* dst) @@ -175,25 +152,6 @@ unsigned long long getFileSizePath(char const* path) return size; } -bool padFile(char const* path, int size) -{ - if (!path) return false; - - FILE* f = fopen(path, "ab"); - if (!f) - { - return false; - } - else - { - for (int i = 0; i < size; i++) - fputc('\0', f); - } - - fclose(f); - return true; -} - bool toggleFileReadOnly(const char* path, bool readOnly) { int fatAttributes = FAT_getAttr(path); @@ -217,236 +175,6 @@ bool writeToFile(FILE* fd, const char* buffer, size_t size) return toWrite == 0; } -//directories -bool dirExists(char const* path) -{ - if (!path) return false; - - DIR* dir = opendir(path); - - if (!dir) - return false; - - closedir(dir); - return true; -} - -bool copyDir(char const* src, char const* dst) -{ - if (!src || !dst) return false; - -// iprintf("copyDir\n%s\n%s\n\n", src, dst); - - bool result = true; - - DIR* dir = opendir(src); - struct dirent* ent; - - if (!dir) - { - return false; - } - else - { - while ( (ent = readdir(dir)) ) - { - if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0) - continue; - - if (ent->d_type == DT_DIR) - { - char* dsrc = (char*)malloc(strlen(src) + strlen(ent->d_name) + 4); - sprintf(dsrc, "%s/%s", src, ent->d_name); - - char* ddst = (char*)malloc(strlen(dst) + strlen(ent->d_name) + 4); - sprintf(ddst, "%s/%s", dst, ent->d_name); - - mkdir(ddst, 0777); - if (!copyDir(dsrc, ddst)) - result = false; - - free(ddst); - free(dsrc); - } - else - { - char* fsrc = (char*)malloc(strlen(src) + strlen(ent->d_name) + 4); - sprintf(fsrc, "%s/%s", src, ent->d_name); - - char* fdst = (char*)malloc(strlen(dst) + strlen(ent->d_name) + 4); - sprintf(fdst, "%s/%s", dst, ent->d_name); - -// iprintf("%s\n%s\n\n", fsrc, fdst); - iprintf("%s -> \n%s...", fsrc, fdst); - - int ret = copyFile(fsrc, fdst); - - if (ret != 0) - { - iprintf("\x1B[31m"); //red - iprintf("Fail\n"); - iprintf("\x1B[33m"); //yellow - - iprintf("%s\n", strerror(errno)); -/* - switch (ret) - { - case 1: - iprintf("Empty input path.\n"); - break; - - case 2: - iprintf("Empty output path.\n"); - break; - - case 3: - iprintf("Error opening input file.\n"); - break; - - case 4: - iprintf("Error opening output file.\n"); - break; - } -*/ - iprintf("\x1B[47m"); //white - result = false; - } - else - { - iprintf("\x1B[42m"); //green - iprintf("Done\n"); - iprintf("\x1B[47m"); //white - } - - free(fdst); - free(fsrc); - } - } - } - - closedir(dir); - return result; -} - -bool deleteDir(char const* path) -{ - if (!path) return false; - - if (strcmp("/", path) == 0) - { - //oh fuck no - return false; - } - - bool result = true; - - DIR* dir = opendir(path); - struct dirent* ent; - - if (!dir) - { - result = false; - } - else - { - while ( (ent = readdir(dir)) ) - { - if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0) - continue; - - if (ent->d_type == DT_DIR) - { - //Delete directory - char subpath[512]; - sprintf(subpath, "%s/%s", path, ent->d_name); - - if (!deleteDir(subpath)) - result = false; - } - else - { - //Delete file - char fpath[512]; - sprintf(fpath, "%s/%s", path, ent->d_name); - - iprintf("%s...", fpath); - if (remove(fpath) != 0) - { - iprintf("\x1B[31m"); - iprintf("Fail\n"); - iprintf("\x1B[47m"); - result = false; - } - else - { - iprintf("\x1B[42m"); - iprintf("Done\n"); - iprintf("\x1B[47m"); - } - } - } - } - - closedir(dir); - - iprintf("%s...", path); - if (remove(path) != 0) - { - iprintf("\x1B[31m"); - iprintf("Fail\n"); - iprintf("\x1B[47m"); - result = false; - } - else - { - iprintf("\x1B[42m"); - iprintf("Done\n"); - iprintf("\x1B[47m"); - } - - return result; -} - -unsigned long long getDirSize(const char* path, u32 blockSize) -{ - if (!path) return 0; - - unsigned long long size = 0; - DIR* dir = opendir(path); - struct dirent* ent; - - if (dir) - { - while ((ent = readdir(dir))) - { - if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0) - continue; - - if (ent->d_type == DT_DIR) - { - char fullpath[512]; - sprintf(fullpath, "%s/%s", path, ent->d_name); - - size += getDirSize(fullpath, blockSize); - } - else - { - char fullpath[260]; - sprintf(fullpath, "%s/%s", path, ent->d_name); - - size += getFileSizePath(fullpath); - - // If we've specified a block size, round up to it - if ((size % blockSize) != 0) - size += blockSize - (size % blockSize); - } - } - } - - closedir(dir); - return size; -} - bool safeCreateDir(const char* path) { if (((mkdir(path, 0777) == 0) || errno == EEXIST)) @@ -458,142 +186,3 @@ bool safeCreateDir(const char* path) messageBox(errorStr); return false; } - -//home menu -int getMenuSlots() -{ - //Assume the home menu has a hard limit on slots - //Find a better way to do this - return TITLE_LIMIT; -} - -int getMenuSlotsFree() -{ - //Get number of open menu slots by subtracting the number of directories in the title folders - //Find a better way to do this - const int NUM_OF_DIRS = 4; - const char* dirs[] = { - "00030004", - "00030005", - "00030015", - "00030017" - }; - - int freeSlots = getMenuSlots(); - - DIR* dir; - struct dirent* ent; - - for (int i = 0; i < NUM_OF_DIRS; i++) - { - char path[256]; - sprintf(path, "%s:/title/%s", sdnandMode ? "sd" : "nand", dirs[i]); - - dir = opendir(path); - - if (dir) - { - while ( (ent = readdir(dir)) != NULL ) - { - if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0) - continue; - - if (ent->d_type == DT_DIR) - freeSlots -= 1; - } - } - - closedir(dir); - } - - return freeSlots; -} - -//SD card -bool sdIsInserted() -{ - //Find a better way to do this. - return true; -} - -unsigned long long getSDCardSize() -{ - if (sdIsInserted()) - { - struct statvfs st; - if (statvfs("sd:/", &st) == 0) - return st.f_bsize * st.f_blocks; - } - - return 0; -} - -unsigned long long getSDCardFree() -{ - if (sdIsInserted()) - { - struct statvfs st; - if (statvfs("sd:/", &st) == 0) - return st.f_bsize * st.f_bavail; - } - - return 0; -} - -//internal storage -unsigned long long getDsiSize() -{ - //The DSi has 256MB of internal storage. Some is unavailable and used by other things. - //An empty DSi reads 1024 open blocks - return 1024 * BYTES_PER_BLOCK; -} - -unsigned long long getDsiFree() -{ - u32 blockSize = getDsiClusterSize(); - - //Get free space by subtracting file sizes in nand folders - unsigned long long size = getDsiSize(); - unsigned long long appSize = getDirSize(sdnandMode ? "sd:/title/00030004" : "nand:/title/00030004", blockSize); - - //subtract, but don't go under 0 - if (appSize > size) - { - size = 0; - } - else - { - size -= appSize; - } - - unsigned long long realFree = getDsiRealFree(); - - return (realFree < size) ? realFree : size; -} - -unsigned long long getDsiRealSize() -{ - struct statvfs st; - if (statvfs(sdnandMode ? "sd:/" : "nand:/", &st) == 0) - return st.f_bsize * st.f_blocks; - - return 0; -} - -unsigned long long getDsiRealFree() -{ - struct statvfs st; - if (statvfs(sdnandMode ? "sd:/" : "nand:/", &st) == 0) - return st.f_bsize * st.f_bavail; - - return 0; -} - -u32 getDsiClusterSize() -{ - struct statvfs st; - if (statvfs(sdnandMode ? "sd:/" : "nand:/", &st) == 0) - return st.f_bsize; - - return 0; -} diff --git a/arm9/src/storage.h b/arm9/src/storage.h index 7529c5e..e258749 100644 --- a/arm9/src/storage.h +++ b/arm9/src/storage.h @@ -4,50 +4,16 @@ #include #include -#define BACKUP_PATH "sd:/_nds/ntm/backup" -#define BYTES_PER_BLOCK (1024*128) - -//printing -void printBytes(unsigned long long bytes); - -//progress bar -void printProgressBar(float percent); -void clearProgressBar(); - //Files bool fileExists(char const* path); int copyFile(char const* src, char const* dst); int copyFilePart(char const* src, u32 offset, u32 size, char const* dst); unsigned long long getFileSize(FILE* f); unsigned long long getFileSizePath(char const* path); -bool padFile(char const* path, int size); bool toggleFileReadOnly(const char* path, bool readOnly); bool writeToFile(FILE* fd, const char* buffer, size_t size); //Directories -bool dirExists(char const* path); -bool copyDir(char const* src, char const* dst); -bool deleteDir(char const* path); -unsigned long long getDirSize(char const* path, u32 blockSize); bool safeCreateDir(const char* path); -//home menu -int getMenuSlots(); -int getMenuSlotsFree(); -#define getMenuSlotsUsed() (getMenuSlots() - getMenuSlotsFree()) - -//SD card -bool sdIsInserted(); -unsigned long long getSDCardSize(); -unsigned long long getSDCardFree(); -#define getSDCardUsedSpace() (getSDCardSize() - getSDCardFree()) - -//internal storage -unsigned long long getDsiSize(); -unsigned long long getDsiFree(); -unsigned long long getDsiRealSize(); -unsigned long long getDsiRealFree(); -u32 getDsiClusterSize(); -#define getDsiUsed() (getDSIStorageSize() - getDSIStorageFree()) - #endif \ No newline at end of file diff --git a/arm9/src/testmenu.c b/arm9/src/testmenu.c deleted file mode 100644 index bae29fa..0000000 --- a/arm9/src/testmenu.c +++ /dev/null @@ -1,75 +0,0 @@ -#include "main.h" -#include "message.h" -#include "storage.h" - -void testMenu() -{ - //top screen - clearScreen(&topScreen); - iprintf("Storage Check Test\n\n"); - - //bottom screen - clearScreen(&bottomScreen); - - unsigned int free = 0; - unsigned int size = 0; - - //home menu slots - { - iprintf("Free Home Menu Slots:\n"); - - free = getMenuSlotsFree(); - iprintf("\t%d / ", free); - - size = getMenuSlots(); - iprintf("%d\n", size); - } - - //dsi menu - { - iprintf("\nFree DSi Menu Space:\n\t"); - - free = getDsiFree(); - printBytes(free); - iprintf(" / "); - - size = getDsiSize(); - printBytes(size); - iprintf("\n"); - - iprintf("\t%d / %d blocks\n", free / BYTES_PER_BLOCK, size / BYTES_PER_BLOCK); - } - - //nand - if (!sdnandMode) - { - iprintf("\nFree NAND Space:\n\t"); - - free = getDsiRealFree(); - printBytes(free); - iprintf(" / "); - - size = getDsiRealSize(); - printBytes(size); - iprintf("\n"); - } - - //SD Card - { - iprintf("\nFree SD Space:\n\t"); - - unsigned long long sdfree = getSDCardFree(); - printBytes(sdfree); - iprintf(" / "); - - unsigned long long sdsize = getSDCardSize(); - printBytes(sdsize); - iprintf("\n"); - - printf("\t%d / %d blocks\n", (unsigned int)(sdfree / BYTES_PER_BLOCK), (unsigned int)(sdsize / BYTES_PER_BLOCK)); - } - - //end - iprintf("\nBack - [B]\n"); - keyWait(KEY_B); -} \ No newline at end of file diff --git a/arm9/src/titlemenu.c b/arm9/src/titlemenu.c deleted file mode 100644 index cb8d18d..0000000 --- a/arm9/src/titlemenu.c +++ /dev/null @@ -1,523 +0,0 @@ -#include "main.h" -#include "rom.h" -#include "menu.h" -#include "message.h" -#include "nand/nandio.h" -#include "storage.h" -#include - -enum { - TITLE_MENU_BACKUP, - TITLE_MENU_DELETE, - TITLE_MENU_READ_ONLY, - TITLE_MENU_BACK -}; - -static bool readOnly = false; - -static void generateList(Menu* m); -static void printItem(Menu* m); -static int subMenu(); -static void backup(Menu* m); -static bool delete(Menu* m); -static void toggleReadOnly(Menu* m); - -void titleMenu() -{ - Menu* m = newMenu(); - setMenuHeader(m, "INSTALLED TITLES"); - generateList(m); - - //no titles - if (m->itemCount <= 0) - { - messageBox("No titles found."); - } - else - { - while (!programEnd) - { - swiWaitForVBlank(); - scanKeys(); - - if (moveCursor(m)) - { - if (m->changePage != 0) - generateList(m); - - printMenu(m); - printItem(m); - } - - if (keysDown() & KEY_B || m->itemCount <= 0) - break; - - else if (keysDown() & KEY_A) - { - readOnly = FAT_getAttr(m->items[m->cursor].value) & ATTR_READONLY; - - switch (subMenu()) - { - case TITLE_MENU_BACKUP: - backup(m); - break; - - case TITLE_MENU_DELETE: - { - if (delete(m)) - { - resetMenu(m); - generateList(m); - } - } - break; - case TITLE_MENU_READ_ONLY: - toggleReadOnly(m); - break; - } - - printMenu(m); - } - } - } - - freeMenu(m); -} - -static void generateList(Menu* m) -{ - if (!m) return; - - const int NUM_OF_DIRS = 4; - const char* dirs[] = { - "00030004", - "00030005", - "00030015", - "00030017" - }; - - const char* blacklist[4][6] = { - { // 00030004 - NULL //nothing blacklisted - }, - { // 00030005 - "484e44", // DS Download Play - "484e45", // PictoChat - "484e49", // Nintendo DSi Camera - "484e4a", // Nintendo Zone - "484e4b", // Nintendo DSi Sound - NULL - }, - { // 00030015 - "484e42", // System Settings - "484e46", // Nintendo DSi Shop - NULL - }, - { // 00030017 - "484e41", // Launcher - NULL - } - }; - - //Reset menu - clearMenu(m); - - m->page += sign(m->changePage); - m->changePage = 0; - - bool done = false; - int count = 0; //used to skip to the right page - - //search each category directory /title/XXXXXXXX - for (int i = 0; i < NUM_OF_DIRS && done == false; i++) - { - char* dirPath = (char*)malloc(strlen(dirs[i])+15); - sprintf(dirPath, "%s:/title/%s", sdnandMode ? "sd" : "nand", dirs[i]); - - struct dirent* ent; - DIR* dir = opendir(dirPath); - - if (dir) - { - while ( (ent = readdir(dir)) && done == false) - { - if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0) - continue; - - //blacklisted titles - if (!sdnandMode) - { - //if the region check somehow failed blacklist all-non DSiWare - if (region == 0 && i > 0) continue; - - bool blacklisted = false; - for (int j = 0; blacklist[i][j] != NULL; j++) - { - char titleId[9]; - sprintf(titleId, "%s%02x", blacklist[i][j], region); - if (strcmp(titleId, ent->d_name) == 0) - blacklisted = true; - - // also blacklist specific all-region titles - if ((strcmp("484e4441", ent->d_name) == 0) || // Download Play - (strcmp("484e4541", ent->d_name) == 0) || // PictoChat - (strcmp("34544e41", ent->d_name) == 0)) // TwlNmenu - blacklisted = true; - } - if (blacklisted) continue; - } - - if (ent->d_type == DT_DIR) - { - //scan content folder /title/XXXXXXXX/content - char* contentPath = (char*)malloc(strlen(dirPath) + strlen(ent->d_name) + 20); - sprintf(contentPath, "%s/%s/content", dirPath, ent->d_name); - - struct dirent* subent; - DIR* subdir = opendir(contentPath); - - if (subdir) - { - while ( (subent = readdir(subdir)) && done == false) - { - if (strcmp(".", subent->d_name) == 0 || strcmp("..", subent->d_name) == 0) - continue; - - if (subent->d_type != DT_DIR) - { - //found .app file - if (strstr(subent->d_name, ".app") != NULL) - { - //current item is not on page - if (count < m->page * ITEMS_PER_PAGE) - count += 1; - - else - { - if (m->itemCount >= ITEMS_PER_PAGE) - done = true; - - else - { - //found requested title - char* path = (char*)malloc(strlen(contentPath) + strlen(subent->d_name) + 10); - sprintf(path, "%s/%s", contentPath, subent->d_name); - - char title[128]; - getGameTitlePath(path, title, false); - - addMenuItem(m, title, path, 0); - - free(path); - } - } - } - } - } - } - - closedir(subdir); - free(contentPath); - } - } - } - - closedir(dir); - free(dirPath); - } - - sortMenuItems(m); - - m->nextPage = done; - - if (m->cursor >= m->itemCount) - m->cursor = m->itemCount - 1; - - printItem(m); - printMenu(m); -} - -static void printItem(Menu* m) -{ - if (!m) return; - printRomInfo(m->items[m->cursor].value); -} - -static int subMenu() -{ - int result = -1; - - Menu* m = newMenu(); - - addMenuItem(m, "Backup", NULL, 0); - addMenuItem(m, "Delete", NULL, 0); - addMenuItem(m, readOnly ? "Mark not read-only" : "Mark read-only", NULL, 0); - addMenuItem(m, "Back - [B]", NULL, 0); - - printMenu(m); - - while (!programEnd) - { - swiWaitForVBlank(); - scanKeys(); - - if (moveCursor(m)) - printMenu(m); - - if (keysDown() & KEY_B) - break; - - else if (keysDown() & KEY_A) - { - result = m->cursor; - break; - } - } - - freeMenu(m); - return result; -} - -static void backup(Menu* m) -{ - char* fpath = m->items[m->cursor].value; - char *backname = NULL; - - tDSiHeader* h = getRomHeader(fpath); - - { - //make backup folder name - char label[13]; - getRomLabel(h, label); - - char gamecode[5]; - getRomCode(h, gamecode); - - backname = (char*)malloc(strlen(label) + strlen(gamecode) + 16); - sprintf(backname, "%s-%s", label, gamecode); - - //make sure dir is unused - char* dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 32); - sprintf(dstpath, "%s/%s.nds", BACKUP_PATH, backname); - - int try = 1; - while (access(dstpath, F_OK) == 0) - { - try += 1; - sprintf(backname, "%s-%s(%d)", label, gamecode, try); - sprintf(dstpath, "%s/%s.nds", BACKUP_PATH, backname); - } - - free(dstpath); - } - - bool choice = NO; - { - const char str[] = "Are you sure you want to backup\n"; - char* msg = (char*)malloc(strlen(str) + strlen(backname) + 2); - sprintf(msg, "%s%s?", str, backname); - - choice = choiceBox(msg); - - free(msg); - } - - if (choice == YES) - { - char srcpath[30]; - sprintf(srcpath, "%s:/title/%08lx/%08lx", sdnandMode ? "sd" : "nand", h->tid_high, h->tid_low); - - if (getSDCardFree() < getDirSize(srcpath, 0)) - { - messageBox("Not enough space on SD."); - } - else - { - //create dirs - { - //create subdirectories - char backupPath[sizeof(BACKUP_PATH)]; - strcpy(backupPath, BACKUP_PATH); - for (char *slash = strchr(backupPath, '/'); slash; slash = strchr(slash + 1, '/')) - { - char temp = *slash; - *slash = '\0'; - mkdir(backupPath, 0777); - *slash = temp; - } - mkdir(backupPath, 0777); // sd:/_nds/ntm/backup - } - - clearScreen(&bottomScreen); - - char path[256], dstpath[256]; - - //tmd - sprintf(path, "%s/content/title.tmd", srcpath); - sprintf(dstpath, "%s/%s.tmd", BACKUP_PATH, backname); - if (access(path, F_OK) == 0) - { - //get app version - FILE *tmd = fopen(path, "rb"); - if (tmd) - { - u8 appVersion[4]; - fseek(tmd, 0x1E4, SEEK_SET); - fread(&appVersion, 1, 4, tmd); - fclose(tmd); - - iprintf("%s -> \n%s...\n", path, dstpath); - copyFile(path, dstpath); - - //app - sprintf(path, "%s/content/%02x%02x%02x%02x.app", srcpath, appVersion[0], appVersion[1], appVersion[2], appVersion[3]); - sprintf(dstpath, "%s/%s.nds", BACKUP_PATH, backname); - if (access(path, F_OK) == 0) - { - iprintf("%s -> \n%s...\n", path, dstpath); - copyFile(path, dstpath); - } - } - } - - //public save - sprintf(path, "%s/data/public.sav", srcpath); - sprintf(dstpath, "%s/%s.pub", BACKUP_PATH, backname); - if (access(path, F_OK) == 0) - { - iprintf("%s -> \n%s...\n", path, dstpath); - copyFile(path, dstpath); - } - - //private save - sprintf(path, "%s/data/private.sav", srcpath); - sprintf(dstpath, "%s/%s.prv", BACKUP_PATH, backname); - if (access(path, F_OK) == 0) - { - iprintf("%s -> \n%s...\n", path, dstpath); - copyFile(path, dstpath); - } - - //banner save - sprintf(path, "%s/data/banner.sav", srcpath); - sprintf(dstpath, "%s/%s.bnr", BACKUP_PATH, backname); - if (access(path, F_OK) == 0) - { - iprintf("%s -> \n%s...\n", path, dstpath); - copyFile(path, dstpath); - } - - messagePrint("\x1B[42m\nBackup finished.\x1B[47m"); - } - } - - free(h); -} - -static bool delete(Menu* m) -{ - if (!m) return false; - - char* fpath = m->items[m->cursor].value; - - bool result = false; - bool choice = NO; - { - //get app title - char title[128]; - getGameTitlePath(m->items[m->cursor].value, title, false); - - char str[] = "Are you sure you want to delete\n"; - char* msg = (char*)malloc(strlen(str) + strlen(title) + 8); - sprintf(msg, "%s%s", str, title); - - choice = choiceBox(msg); - - free(msg); - } - - if (choice == YES) - { - if (!fpath) - { - messageBox("Failed to delete title.\n"); - } - else - { - char dirPath[64]; - sprintf(dirPath, "%.*s", sdnandMode ? 27 : 29, fpath); - - if (!dirExists(dirPath)) - { - messageBox("Failed to delete title.\n"); - } - else - { - if (!sdnandMode && !nandio_unlock_writing()) - return false; - - clearScreen(&bottomScreen); - - if (deleteDir(dirPath)) - { - result = true; - messagePrint("\nTitle deleted.\n"); - } - else - { - messagePrint("\nTitle could not be deleted.\n"); - } - - if (!sdnandMode) - nandio_lock_writing(); - } - } - } - - return result; -} - -static void toggleReadOnly(Menu* m) -{ - if (!m) return; - - tDSiHeader* h = getRomHeader(m->items[m->cursor].value); - - char path[256]; - char srcpath[30]; - sprintf(srcpath, "%s:/title/%08lx/%08lx", sdnandMode ? "sd" : "nand", h->tid_high, h->tid_low); - - if (!sdnandMode && !nandio_unlock_writing()) return; - - //app - strcpy(path, m->items[m->cursor].value); - if (access(path, F_OK) == 0) - FAT_setAttr(path, FAT_getAttr(path) ^ ATTR_READONLY); - - //tmd - sprintf(path, "%s/content/title.tmd", srcpath); - if (access(path, F_OK) == 0) - FAT_setAttr(path, FAT_getAttr(path) ^ ATTR_READONLY); - - //public save - sprintf(path, "%s/data/public.sav", srcpath); - if (access(path, F_OK) == 0) - FAT_setAttr(path, FAT_getAttr(path) ^ ATTR_READONLY); - - //private save - sprintf(path, "%s/data/private.sav", srcpath); - if (access(path, F_OK) == 0) - FAT_setAttr(path, FAT_getAttr(path) ^ ATTR_READONLY); - - //banner save - sprintf(path, "%s/data/banner.sav", srcpath); - if (access(path, F_OK) == 0) - FAT_setAttr(path, FAT_getAttr(path) ^ ATTR_READONLY); - - if (!sdnandMode) - nandio_lock_writing(); - - free(h); - - messageBox("Title's read-only status\nsuccesfully toggled."); -} diff --git a/arm9/src/unlaunch.c b/arm9/src/unlaunch.c index da665fb..c99fc64 100644 --- a/arm9/src/unlaunch.c +++ b/arm9/src/unlaunch.c @@ -7,6 +7,7 @@ static char unlaunchInstallerBuffer[0x30000]; static const char* hnaaTmdPath = "nand:/title/00030017/484e4141/content/title.tmd"; +static const char* hnaaBackupTmdPath = "nand:/title/00030017/484e4141/content/title.tmd.bak"; bool isLauncherTmdPatched(const char* path) { @@ -110,16 +111,14 @@ static bool patchMainTmd(const char* path) static bool restoreProtoTmd(const char* path) { - bool hnaaBackupExists = false; - hnaaBackupExists = (access("nand:/title/00030017/484e4141/content/title.tmd.bak", F_OK) == 0); - if (!hnaaBackupExists) + if (!fileExists(hnaaBackupTmdPath)) { messageBox("\x1B[31mError:\x1B[33m No original tmd found!\nCan't uninstall unlaunch.\n"); return false; } remove(path); - copyFile("nand:/title/00030017/484e4141/content/title.tmd.bak", path); - remove("nand:/title/00030017/484e4141/content/title.tmd.bak"); + rename(hnaaBackupTmdPath, path); + toggleFileReadOnly(path, false); return true; } @@ -170,7 +169,7 @@ static bool installUnlaunchRetailConsole(const char* retailLauncherTmdPath) } // We have to remove write protect otherwise reinstalling will fail. - if (access(hnaaTmdPath, F_OK) == 0 && !toggleFileReadOnly(hnaaTmdPath, false)) { + if (fileExists(hnaaTmdPath) && !toggleFileReadOnly(hnaaTmdPath, false)) { messageBox("\x1B[31mError:\x1B[33m Can't remove launcher tmd write protect\n"); return false; } @@ -240,15 +239,15 @@ static bool installUnlaunchProtoConsole(void) // Likely factory rejects that never had production firmware flashed. // We have to remove write protect otherwise reinstalling will fail. - if (access(hnaaTmdPath, F_OK) == 0 && !toggleFileReadOnly(hnaaTmdPath, false)) { + if (fileExists(hnaaTmdPath) && !toggleFileReadOnly(hnaaTmdPath, false)) { messageBox("\x1B[31mError:\x1B[33m Can't remove launcher tmd write protect\n"); return false; } - bool hnaaBackupExists = (access("nand:/title/00030017/484e4141/content/title.tmd.bak", F_OK) == 0); + bool hnaaBackupExists = fileExists(hnaaBackupTmdPath); // Back up the TMD since we'll be writing to it directly. if (!hnaaBackupExists) { - rename(hnaaTmdPath, "nand:/title/00030017/484e4141/content/title.tmd.bak"); + rename(hnaaTmdPath, hnaaBackupTmdPath); // Mark backup tmd as readonly, just to be sure toggleFileReadOnly("nand:/title/00030017/484e4141/content/title.tmd.bak", true); }