Skip to content

Commit 1b8bd12

Browse files
committed
Added raw cart dumper (R+A on cart drive)
1 parent ba10ce9 commit 1b8bd12

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

arm9/source/godmode.c

+66
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "fs.h"
1111
#include "utils.h"
1212
#include "nand.h"
13+
#include "gamecart.h"
1314
#include "virtual.h"
1415
#include "vcart.h"
1516
#include "game.h"
@@ -959,6 +960,67 @@ u32 StandardCopy(u32* cursor, u32* scroll) {
959960
return 0;
960961
}
961962

963+
u32 CartRawDump(void) {
964+
CartData* cdata = (CartData*) malloc(sizeof(CartData));
965+
char dest[256];
966+
char cname[24];
967+
char bytestr[32];
968+
u64 dsize = 0;
969+
970+
if (!cdata ||(InitCartRead(cdata) != 0) || (GetCartName(cname, cdata) != 0)) {
971+
ShowPrompt(false, "Cart init failed!");
972+
free(cdata);
973+
return 1;
974+
}
975+
976+
// input dump size
977+
dsize = cdata->cart_size;
978+
FormatBytes(bytestr, dsize);
979+
dsize = ShowHexPrompt(dsize, 8, "Cart: %s\nDetected size: %s\n \nInput dump size below.", cname, bytestr);
980+
if (!dsize || (dsize == (u64) -1)) {
981+
free(cdata);
982+
return 1;
983+
}
984+
985+
// for NDS carts: ask for secure area encryption
986+
if (cdata->cart_type & CART_NTR)
987+
SetSecureAreaEncryption(
988+
!ShowPrompt(true, "Cart: %s\nNDS cart detected\nDecrypt the secure area?", cname));
989+
990+
// destination path
991+
snprintf(dest, 256, "%s/%s_%08llX.%s",
992+
OUTPUT_PATH, cname, dsize, (cdata->cart_type & CART_CTR) ? "3ds" : "nds");
993+
994+
// buffer allocation
995+
u8* buf = (u8*) malloc(STD_BUFFER_SIZE);
996+
if (!buf) { // this will not happen
997+
free(cdata);
998+
return 1;
999+
}
1000+
1001+
// actual cart dump
1002+
u32 ret = 0;
1003+
PathDelete(dest);
1004+
ShowProgress(0, 0, cname);
1005+
for (u64 p = 0; p < dsize; p += STD_BUFFER_SIZE) {
1006+
u64 len = min((dsize - p), STD_BUFFER_SIZE);
1007+
if ((ReadCartBytes(buf, p, len, cdata, false) != 0) ||
1008+
(fvx_qwrite(dest, buf, p, len, NULL) != FR_OK) ||
1009+
!ShowProgress(p, dsize, cname)) {
1010+
PathDelete(dest);
1011+
ret = 1;
1012+
break;
1013+
}
1014+
}
1015+
1016+
if (ret) ShowPrompt(false, "%s\nFailed dumping cart", cname);
1017+
else ShowPrompt(false, "%s\nDumped to %s", cname, OUTPUT_PATH);
1018+
1019+
free(buf);
1020+
free(cdata);
1021+
return ret;
1022+
}
1023+
9621024
u32 DirFileAttrMenu(const char* path, const char *name) {
9631025
bool drv = (path[2] == '\0');
9641026
bool vrt = (!drv); // will be checked below
@@ -2488,11 +2550,13 @@ u32 GodMode(int entrypoint) {
24882550
((GetMountState() == IMG_NAND) && (*(curr_entry->path) == '7')))) ? ++n_opt : -1;
24892551
int dirnfo = ++n_opt;
24902552
int stdcpy = (*current_path && strncmp(current_path, OUTPUT_PATH, 256) != 0) ? ++n_opt : -1;
2553+
int rawdump = (!*current_path && (DriveType(curr_entry->path) & DRV_CART)) ? ++n_opt : -1;
24912554
if (tman > 0) optionstr[tman-1] = "Open title manager";
24922555
if (srch_f > 0) optionstr[srch_f-1] = "Search for files...";
24932556
if (fixcmac > 0) optionstr[fixcmac-1] = "Fix CMACs for drive";
24942557
if (dirnfo > 0) optionstr[dirnfo-1] = (*current_path) ? "Show directory info" : "Show drive info";
24952558
if (stdcpy > 0) optionstr[stdcpy-1] = "Copy to " OUTPUT_PATH;
2559+
if (rawdump > 0) optionstr[rawdump-1] = "Dump to " OUTPUT_PATH;
24962560
char namestr[UTF_BUFFER_BYTESIZE(32)];
24972561
TruncateString(namestr, (*current_path) ? curr_entry->path : curr_entry->name, 32, 8);
24982562
int user_select = ShowSelectPrompt(n_opt, optionstr, "%s", namestr);
@@ -2527,6 +2591,8 @@ u32 GodMode(int entrypoint) {
25272591
}
25282592
} else if (user_select == stdcpy) {
25292593
StandardCopy(&cursor, &scroll);
2594+
} else if (user_select == rawdump) {
2595+
CartRawDump();
25302596
}
25312597
} else { // one level up
25322598
u32 user_select = 1;

0 commit comments

Comments
 (0)