mirror of
https://github.com/rvtr/TDT.git
synced 2025-10-31 13:51:07 -04:00
Rework backups
This commit is contained in:
parent
fc13fbeb89
commit
6d8fb9ca44
@ -1,5 +1,7 @@
|
|||||||
|
#include "install.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#include "rom.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "nand/nandio.h"
|
#include "nand/nandio.h"
|
||||||
@ -13,8 +15,8 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void generateList(Menu* m);
|
static void generateList(Menu* m);
|
||||||
|
static void printItem(Menu* m);
|
||||||
static int subMenu();
|
static int subMenu();
|
||||||
static void restore(Menu* m);
|
|
||||||
static bool delete(Menu* m);
|
static bool delete(Menu* m);
|
||||||
|
|
||||||
void backupMenu()
|
void backupMenu()
|
||||||
@ -43,6 +45,7 @@ void backupMenu()
|
|||||||
generateList(m);
|
generateList(m);
|
||||||
|
|
||||||
printMenu(m);
|
printMenu(m);
|
||||||
|
printItem(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keysDown() & KEY_B || m->itemCount <= 0)
|
if (keysDown() & KEY_B || m->itemCount <= 0)
|
||||||
@ -53,7 +56,7 @@ void backupMenu()
|
|||||||
switch (subMenu())
|
switch (subMenu())
|
||||||
{
|
{
|
||||||
case BACKUP_MENU_RESTORE:
|
case BACKUP_MENU_RESTORE:
|
||||||
restore(m);
|
install(m->items[m->cursor].value, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BACKUP_MENU_DELETE:
|
case BACKUP_MENU_DELETE:
|
||||||
@ -128,14 +131,13 @@ static void generateList(Menu* m)
|
|||||||
{
|
{
|
||||||
int count = 0;
|
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;
|
continue;
|
||||||
|
|
||||||
if (ent->d_type == DT_DIR)
|
if (ent->d_type == DT_DIR)
|
||||||
{
|
{
|
||||||
//current item is not on page
|
|
||||||
if (count < m->page * ITEMS_PER_PAGE)
|
if (count < m->page * ITEMS_PER_PAGE)
|
||||||
count += 1;
|
count += 1;
|
||||||
|
|
||||||
@ -146,12 +148,39 @@ static void generateList(Menu* m)
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char* path = (char*)malloc(strlen(BACKUP_PATH) + strlen(ent->d_name) + 8);
|
char* fpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(ent->d_name) + 8);
|
||||||
sprintf(path, "%s/%s", BACKUP_PATH, ent->d_name);
|
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;
|
||||||
|
|
||||||
free(path);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,64 +196,34 @@ static void generateList(Menu* m)
|
|||||||
if (m->cursor >= m->itemCount)
|
if (m->cursor >= m->itemCount)
|
||||||
m->cursor = m->itemCount - 1;
|
m->cursor = m->itemCount - 1;
|
||||||
|
|
||||||
|
printItem(m);
|
||||||
printMenu(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;
|
if (m->items[m->cursor].directory)
|
||||||
{
|
clearScreen(&topScreen);
|
||||||
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
|
else
|
||||||
{
|
printRomInfo(m->items[m->cursor].value);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool delete(Menu* m)
|
static bool delete(Menu* m)
|
||||||
{
|
{
|
||||||
if (!m) return false;
|
if (!m) return false;
|
||||||
|
|
||||||
|
char* label = m->items[m->cursor].label;
|
||||||
char* fpath = m->items[m->cursor].value;
|
char* fpath = m->items[m->cursor].value;
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
bool choice = NO;
|
bool choice = NO;
|
||||||
{
|
{
|
||||||
char str[] = "Are you sure you want to delete\n";
|
const char str[] = "Are you sure you want to delete\n";
|
||||||
char* msg = (char*)malloc(strlen(str) + strlen(fpath) + 4);
|
char* msg = (char*)malloc(strlen(str) + strlen(label) + 2);
|
||||||
sprintf(msg, "%s\n%s", str, fpath);
|
sprintf(msg, "%s%s?", str, label);
|
||||||
|
|
||||||
choice = choiceBox(msg);
|
choice = choiceBox(msg);
|
||||||
|
|
||||||
@ -239,7 +238,7 @@ static bool delete(Menu* m)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!dirExists(fpath))
|
if (access(fpath, F_OK) != 0)
|
||||||
{
|
{
|
||||||
messageBox("\x1B[31mFailed to delete backup.\n\x1B[47m");
|
messageBox("\x1B[31mFailed to delete backup.\n\x1B[47m");
|
||||||
}
|
}
|
||||||
@ -247,16 +246,28 @@ static bool delete(Menu* m)
|
|||||||
{
|
{
|
||||||
clearScreen(&bottomScreen);
|
clearScreen(&bottomScreen);
|
||||||
|
|
||||||
if (deleteDir(fpath))
|
//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;
|
result = true;
|
||||||
messagePrint("\x1B[42m\nBackup deleted.\n\x1B[47m");
|
messagePrint("\x1B[42m\nBackup deleted.\n\x1B[47m");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
messagePrint("\n\x1B[31mError deleting backup.\n\x1B[47m");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -160,7 +160,6 @@ static void generateList(Menu* m)
|
|||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
//scan /dsi/
|
|
||||||
while ( (ent = readdir(dir)) && !done)
|
while ( (ent = readdir(dir)) && !done)
|
||||||
{
|
{
|
||||||
if (ent->d_name[0] == '.')
|
if (ent->d_name[0] == '.')
|
||||||
@ -187,14 +186,12 @@ static void generateList(Menu* m)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (strstr(ent->d_name, ".nds") != NULL ||
|
if (strcasecmp(strrchr(ent->d_name, '.'), ".nds") == 0 ||
|
||||||
strstr(ent->d_name, ".app") != NULL ||
|
strcasecmp(strrchr(ent->d_name, '.'), ".app") == 0 ||
|
||||||
strstr(ent->d_name, ".dsi") != NULL ||
|
strcasecmp(strrchr(ent->d_name, '.'), ".dsi") == 0 ||
|
||||||
strstr(ent->d_name, ".cia") != NULL ||
|
strcasecmp(strrchr(ent->d_name, '.'), ".ids") == 0 ||
|
||||||
strstr(ent->d_name, ".NDS") != NULL ||
|
strcasecmp(strrchr(ent->d_name, '.'), ".srl") == 0 ||
|
||||||
strstr(ent->d_name, ".APP") != NULL ||
|
strcasecmp(strrchr(ent->d_name, '.'), ".cia") == 0)
|
||||||
strstr(ent->d_name, ".DSI") != NULL ||
|
|
||||||
strstr(ent->d_name, ".CIA") != NULL)
|
|
||||||
{
|
{
|
||||||
if (count < m->page * ITEMS_PER_PAGE)
|
if (count < m->page * ITEMS_PER_PAGE)
|
||||||
count += 1;
|
count += 1;
|
||||||
|
|||||||
@ -137,19 +137,6 @@ bool getRomCode(tDSiHeader* h, char* out)
|
|||||||
return true;
|
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)
|
void printRomInfo(char const* fpath)
|
||||||
{
|
{
|
||||||
clearScreen(&topScreen);
|
clearScreen(&topScreen);
|
||||||
|
|||||||
@ -12,7 +12,6 @@ bool getGameTitlePath(char const* fpath, char* out, bool full);
|
|||||||
|
|
||||||
bool getRomLabel(tDSiHeader* h, char* out);
|
bool getRomLabel(tDSiHeader* h, char* out);
|
||||||
bool getRomCode(tDSiHeader* h, char* out);
|
bool getRomCode(tDSiHeader* h, char* out);
|
||||||
bool getTitleId(tDSiHeader* h, u32* low, u32* high);
|
|
||||||
|
|
||||||
void printRomInfo(char const* fpath);
|
void printRomInfo(char const* fpath);
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include <nds/ndstypes.h>
|
#include <nds/ndstypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define BACKUP_PATH "sd:/titlebackup"
|
#define BACKUP_PATH "sd:/_nds/ntm/backup"
|
||||||
#define BYTES_PER_BLOCK (1024*128)
|
#define BYTES_PER_BLOCK (1024*128)
|
||||||
|
|
||||||
//printing
|
//printing
|
||||||
|
|||||||
@ -234,7 +234,7 @@ static void backup(Menu* m)
|
|||||||
|
|
||||||
{
|
{
|
||||||
//make backup folder name
|
//make backup folder name
|
||||||
char label[16];
|
char label[13];
|
||||||
getRomLabel(h, label);
|
getRomLabel(h, label);
|
||||||
|
|
||||||
char gamecode[5];
|
char gamecode[5];
|
||||||
@ -245,14 +245,14 @@ static void backup(Menu* m)
|
|||||||
|
|
||||||
//make sure dir is unused
|
//make sure dir is unused
|
||||||
char* dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 32);
|
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;
|
int try = 1;
|
||||||
while (dirExists(dstpath))
|
while (access(dstpath, F_OK) == 0)
|
||||||
{
|
{
|
||||||
try += 1;
|
try += 1;
|
||||||
sprintf(backname, "%s-%s(%d)", label, gamecode, try);
|
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);
|
free(dstpath);
|
||||||
@ -260,9 +260,9 @@ static void backup(Menu* m)
|
|||||||
|
|
||||||
bool choice = NO;
|
bool choice = NO;
|
||||||
{
|
{
|
||||||
char str[] = "Are you sure you want to backup\n";
|
const char str[] = "Are you sure you want to backup\n";
|
||||||
char* msg = (char*)malloc(strlen(str) + strlen(backname) + 1);
|
char* msg = (char*)malloc(strlen(str) + strlen(backname) + 2);
|
||||||
sprintf(msg, "%s%s", str, backname);
|
sprintf(msg, "%s%s?", str, backname);
|
||||||
|
|
||||||
choice = choiceBox(msg);
|
choice = choiceBox(msg);
|
||||||
|
|
||||||
@ -271,12 +271,8 @@ static void backup(Menu* m)
|
|||||||
|
|
||||||
if (choice == YES)
|
if (choice == YES)
|
||||||
{
|
{
|
||||||
u32 tid_low = 1;
|
char srcpath[30];
|
||||||
u32 tid_high = 1;
|
sprintf(srcpath, "%s:/title/%08lx/%08lx", sdnandMode ? "sd" : "nand", h->tid_high, h->tid_low);
|
||||||
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);
|
|
||||||
|
|
||||||
if (getSDCardFree() < getDirSize(srcpath, 0))
|
if (getSDCardFree() < getDirSize(srcpath, 0))
|
||||||
{
|
{
|
||||||
@ -284,42 +280,86 @@ static void backup(Menu* m)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char* dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 8);
|
|
||||||
sprintf(dstpath, "%s/%s", BACKUP_PATH, backname);
|
|
||||||
|
|
||||||
//create dirs
|
//create dirs
|
||||||
mkdir(BACKUP_PATH, 0777); // sd:/titlebackup
|
{
|
||||||
mkdir(dstpath, 0777); // sd:/titlebackup/App Name - XXXX
|
//create subdirectories
|
||||||
free(dstpath);
|
char backupPath[sizeof(BACKUP_PATH)];
|
||||||
|
strcpy(backupPath, BACKUP_PATH);
|
||||||
dstpath = (char*)malloc(strlen(BACKUP_PATH) + strlen(backname) + 16);
|
for (char *slash = strchr(backupPath, '/'); *slash; slash = strchr(slash + 1, '/'))
|
||||||
sprintf(dstpath, "%s/%s/%08x", BACKUP_PATH, backname, (unsigned int)tid_high);
|
{
|
||||||
|
char temp = *slash;
|
||||||
mkdir(dstpath, 0777); // sd:/titlebackup/App Name - XXXX/tid_high
|
*slash = '\0';
|
||||||
free(dstpath);
|
mkdir(backupPath, 0777);
|
||||||
|
*slash = temp;
|
||||||
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(backupPath, 0777); // sd:/_nds/ntm/backup
|
||||||
|
}
|
||||||
mkdir(dstpath, 0777); // sd:/titlebackup/App Name - XXXX/tid_high/tid_low
|
|
||||||
|
|
||||||
// iprintf("dst %s\nsrc %s", dstpath, srcpath);
|
|
||||||
// keyWait(KEY_A);
|
|
||||||
|
|
||||||
clearScreen(&bottomScreen);
|
clearScreen(&bottomScreen);
|
||||||
|
|
||||||
if (!copyDir(srcpath, dstpath))
|
char path[256], dstpath[256];
|
||||||
messagePrint("\x1B[31m\nBackup error.\x1B[47m");
|
|
||||||
else
|
//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");
|
messagePrint("\x1B[42m\nBackup finished.\x1B[47m");
|
||||||
|
}
|
||||||
free(dstpath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(srcpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(backname);
|
|
||||||
free(h);
|
free(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user