diff --git a/arm9/src/backupmenu.c b/arm9/src/backupmenu.c index c923ce8..c4afa8a 100644 --- a/arm9/src/backupmenu.c +++ b/arm9/src/backupmenu.c @@ -1,5 +1,7 @@ +#include "install.h" #include "main.h" #include "menu.h" +#include "rom.h" #include "storage.h" #include "message.h" #include "nand/nandio.h" @@ -13,8 +15,8 @@ enum { }; static void generateList(Menu* m); +static void printItem(Menu* m); static int subMenu(); -static void restore(Menu* m); static bool delete(Menu* m); void backupMenu() @@ -43,6 +45,7 @@ void backupMenu() generateList(m); printMenu(m); + printItem(m); } if (keysDown() & KEY_B || m->itemCount <= 0) @@ -53,7 +56,7 @@ void backupMenu() switch (subMenu()) { case BACKUP_MENU_RESTORE: - restore(m); + install(m->items[m->cursor].value, false); break; case BACKUP_MENU_DELETE: @@ -62,11 +65,11 @@ void backupMenu() { resetMenu(m); generateList(m); - } + } } break; } - + printMenu(m); } } @@ -119,7 +122,7 @@ static void generateList(Menu* m) m->page += sign(m->changePage); m->changePage = 0; - bool done = false; + bool done = false; struct dirent* ent; DIR* dir = opendir(BACKUP_PATH); @@ -128,17 +131,16 @@ static void generateList(Menu* m) { int count = 0; - while ( (ent = readdir(dir)) && done == false) + while ( (ent = readdir(dir)) && !done) { - if (strcmp(".", ent->d_name) == 0 || strcmp("..", ent->d_name) == 0) + if (ent->d_name[0] == '.') continue; if (ent->d_type == DT_DIR) { - //current item is not on page if (count < m->page * ITEMS_PER_PAGE) - count += 1; - + count += 1; + else { if (m->itemCount >= ITEMS_PER_PAGE) @@ -146,13 +148,40 @@ static void generateList(Menu* m) else { - char* path = (char*)malloc(strlen(BACKUP_PATH) + strlen(ent->d_name) + 8); - sprintf(path, "%s/%s", BACKUP_PATH, ent->d_name); + 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, path, 0); + 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); - free(path); - } + addMenuItem(m, ent->d_name, fpath, 0); + + free(fpath); + } + } } } } @@ -167,64 +196,34 @@ static void generateList(Menu* m) if (m->cursor >= m->itemCount) m->cursor = m->itemCount - 1; + printItem(m); printMenu(m); } -static void restore(Menu* m) +static void printItem(Menu* m) { - char* fpath = m->items[m->cursor].value; + if (!m) return; + if (m->itemCount <= 0) return; - bool choice = NO; - { - char str[] = "Are you sure you want to restore\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[31mFailed to restore backup.\n\x1B[47m"); - } - else - { - if (!sdnandMode && !nandio_unlock_writing()) - return; - - clearScreen(&bottomScreen); - - if (!copyDir(fpath, sdnandMode ? "sd:/title" : "nand:/title")) - { - messagePrint("\x1B[31m\nFailed to restore backup.\n\x1B[47m"); - } - else - { - messagePrint("\x1B[42m\nBackup restored.\n\x1B[47m"); - } - - if (!sdnandMode) - nandio_lock_writing(); - } - } + 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; { - char str[] = "Are you sure you want to delete\n"; - char* msg = (char*)malloc(strlen(str) + strlen(fpath) + 4); - sprintf(msg, "%s\n%s", str, fpath); + 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); @@ -239,7 +238,7 @@ static bool delete(Menu* m) } else { - if (!dirExists(fpath)) + if (access(fpath, F_OK) != 0) { messageBox("\x1B[31mFailed to delete backup.\n\x1B[47m"); } @@ -247,15 +246,27 @@ static bool delete(Menu* m) { clearScreen(&bottomScreen); - if (deleteDir(fpath)) - { - result = true; - messagePrint("\x1B[42m\nBackup deleted.\n\x1B[47m"); - } - else - { - messagePrint("\n\x1B[31mError deleting backup.\n\x1B[47m"); - } + //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"); } } } diff --git a/arm9/src/installmenu.c b/arm9/src/installmenu.c index eca7309..8521494 100644 --- a/arm9/src/installmenu.c +++ b/arm9/src/installmenu.c @@ -160,7 +160,6 @@ static void generateList(Menu* m) { int count = 0; - //scan /dsi/ while ( (ent = readdir(dir)) && !done) { if (ent->d_name[0] == '.') @@ -187,14 +186,12 @@ static void generateList(Menu* m) } else { - if (strstr(ent->d_name, ".nds") != NULL || - strstr(ent->d_name, ".app") != NULL || - strstr(ent->d_name, ".dsi") != NULL || - strstr(ent->d_name, ".cia") != NULL || - strstr(ent->d_name, ".NDS") != NULL || - strstr(ent->d_name, ".APP") != NULL || - strstr(ent->d_name, ".DSI") != NULL || - strstr(ent->d_name, ".CIA") != NULL) + 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; diff --git a/arm9/src/rom.c b/arm9/src/rom.c index 9590a9d..e44a5c7 100644 --- a/arm9/src/rom.c +++ b/arm9/src/rom.c @@ -137,19 +137,6 @@ bool getRomCode(tDSiHeader* h, char* out) return true; } -bool getTitleId(tDSiHeader* h, u32* low, u32* high) -{ - if (!h) return false; - - if (low != NULL) - *low = h->tid_low; - - if (high != NULL) - *high = h->tid_high; - - return true; -} - void printRomInfo(char const* fpath) { clearScreen(&topScreen); diff --git a/arm9/src/rom.h b/arm9/src/rom.h index 97f322b..9fc07d5 100644 --- a/arm9/src/rom.h +++ b/arm9/src/rom.h @@ -12,7 +12,6 @@ bool getGameTitlePath(char const* fpath, char* out, bool full); bool getRomLabel(tDSiHeader* h, char* out); bool getRomCode(tDSiHeader* h, char* out); -bool getTitleId(tDSiHeader* h, u32* low, u32* high); void printRomInfo(char const* fpath); diff --git a/arm9/src/storage.h b/arm9/src/storage.h index 811d6a8..4578b9a 100644 --- a/arm9/src/storage.h +++ b/arm9/src/storage.h @@ -4,7 +4,7 @@ #include #include -#define BACKUP_PATH "sd:/titlebackup" +#define BACKUP_PATH "sd:/_nds/ntm/backup" #define BYTES_PER_BLOCK (1024*128) //printing diff --git a/arm9/src/titlemenu.c b/arm9/src/titlemenu.c index e71134e..c0e758d 100644 --- a/arm9/src/titlemenu.c +++ b/arm9/src/titlemenu.c @@ -228,13 +228,13 @@ static int subMenu() static void backup(Menu* m) { char* fpath = m->items[m->cursor].value; - char* backname = NULL; + char *backname = NULL; tDSiHeader* h = getRomHeader(fpath); { //make backup folder name - char label[16]; + char label[13]; getRomLabel(h, label); char gamecode[5]; @@ -245,14 +245,14 @@ static void backup(Menu* m) //make sure dir is unused char* dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 32); - sprintf(dstpath, "%s/%s", BACKUP_PATH, backname); + sprintf(dstpath, "%s/%s.nds", BACKUP_PATH, backname); int try = 1; - while (dirExists(dstpath)) + while (access(dstpath, F_OK) == 0) { try += 1; sprintf(backname, "%s-%s(%d)", label, gamecode, try); - sprintf(dstpath, "%s/%s", BACKUP_PATH, backname); + sprintf(dstpath, "%s/%s.nds", BACKUP_PATH, backname); } free(dstpath); @@ -260,10 +260,10 @@ static void backup(Menu* m) bool choice = NO; { - char str[] = "Are you sure you want to backup\n"; - char* msg = (char*)malloc(strlen(str) + strlen(backname) + 1); - sprintf(msg, "%s%s", str, backname); - + 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); @@ -271,12 +271,8 @@ static void backup(Menu* m) if (choice == YES) { - u32 tid_low = 1; - u32 tid_high = 1; - getTitleId(h, &tid_low, &tid_high); - - char* srcpath = (char*)malloc(strlen("nand:/title/") + 32); - sprintf(srcpath, "%s:/title/%08x/%08x", sdnandMode ? "sd" : "nand", (unsigned int)tid_high, (unsigned int)tid_low); + char srcpath[30]; + sprintf(srcpath, "%s:/title/%08lx/%08lx", sdnandMode ? "sd" : "nand", h->tid_high, h->tid_low); if (getSDCardFree() < getDirSize(srcpath, 0)) { @@ -284,42 +280,86 @@ static void backup(Menu* m) } else { - char* dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 8); - sprintf(dstpath, "%s/%s", BACKUP_PATH, backname); - //create dirs - mkdir(BACKUP_PATH, 0777); // sd:/titlebackup - mkdir(dstpath, 0777); // sd:/titlebackup/App Name - XXXX - free(dstpath); - - dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 16); - sprintf(dstpath, "%s/%s/%08x", BACKUP_PATH, backname, (unsigned int)tid_high); - - mkdir(dstpath, 0777); // sd:/titlebackup/App Name - XXXX/tid_high - free(dstpath); - - dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 32); - sprintf(dstpath, "%s/%s/%08x/%08x", BACKUP_PATH, backname, (unsigned int)tid_high, (unsigned int)tid_low); - - mkdir(dstpath, 0777); // sd:/titlebackup/App Name - XXXX/tid_high/tid_low - -// iprintf("dst %s\nsrc %s", dstpath, srcpath); -// keyWait(KEY_A); + { + //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); - if (!copyDir(srcpath, dstpath)) - messagePrint("\x1B[31m\nBackup error.\x1B[47m"); - else - messagePrint("\x1B[42m\nBackup finished.\x1B[47m"); + char path[256], dstpath[256]; - free(dstpath); + //tmd + sprintf(path, "%s/content/title.tmd", srcpath); + sprintf(dstpath, "%s/%s.tmd", BACKUP_PATH, backname); + nocashMessage(path); + nocashMessage(dstpath); + if (access(path, F_OK) == 0) + { + //get app version + FILE *tmd = fopen(path, "rb"); + if (tmd) + { + u8 appVersion; + fseek(tmd, 0x1E7, SEEK_SET); + fread(&appVersion, sizeof(appVersion), 1, tmd); + fclose(tmd); + + iprintf("%s -> \n%s...\n", path, dstpath); + copyFile(path, dstpath); + + //app + sprintf(path, "%s/content/000000%02x.app", srcpath, appVersion); + 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(srcpath); } - free(backname); free(h); }