2020-04-26 00:20:26 +01:00
|
|
|
#include <string.h>
|
2019-11-21 19:54:18 +00:00
|
|
|
#include "tools.h"
|
2020-03-18 11:18:39 +00:00
|
|
|
#include "../gfx/gfxutils.h"
|
|
|
|
#include "../../libs/fatfs/ff.h"
|
|
|
|
#include "../../gfx/gfx.h"
|
2020-05-02 00:54:03 +01:00
|
|
|
#include "../../hid/hid.h"
|
2020-03-18 11:18:39 +00:00
|
|
|
#include "../../soc/gpio.h"
|
|
|
|
#include "../../utils/util.h"
|
|
|
|
#include "../../utils/types.h"
|
|
|
|
#include "../../libs/fatfs/diskio.h"
|
|
|
|
#include "../../storage/sdmmc.h"
|
|
|
|
#include "../../utils/sprintf.h"
|
|
|
|
#include "../../soc/fuse.h"
|
2020-03-18 23:11:18 +00:00
|
|
|
#include "../emmc/emmc.h"
|
2020-03-18 11:18:39 +00:00
|
|
|
#include "../common/common.h"
|
2020-03-18 22:58:32 +00:00
|
|
|
#include "../fs/fsactions.h"
|
2020-04-26 00:20:26 +01:00
|
|
|
#include "../fs/fsutils.h"
|
|
|
|
#include "../../mem/heap.h"
|
|
|
|
#include "../utils/utils.h"
|
2020-07-14 16:38:56 +01:00
|
|
|
#include "../fs/nca.h"
|
2019-12-03 16:11:08 +00:00
|
|
|
|
|
|
|
extern bool sd_mount();
|
|
|
|
extern void sd_unmount();
|
2019-12-09 10:56:30 +00:00
|
|
|
extern sdmmc_storage_t sd_storage;
|
2019-11-21 19:54:18 +00:00
|
|
|
|
|
|
|
void displayinfo(){
|
2020-03-18 11:18:39 +00:00
|
|
|
gfx_clearscreen();
|
2019-11-21 19:54:18 +00:00
|
|
|
|
2019-12-11 12:18:57 +00:00
|
|
|
FATFS *fs;
|
|
|
|
DWORD fre_clust, fre_sect, tot_sect;
|
|
|
|
u32 capacity;
|
2019-12-16 22:31:29 +00:00
|
|
|
u8 fuse_count = 0;
|
2020-01-30 22:53:27 +00:00
|
|
|
pkg1_info pkg1 = returnpkg1info();
|
2019-12-11 12:18:57 +00:00
|
|
|
int res;
|
2019-11-21 19:54:18 +00:00
|
|
|
|
2019-12-16 22:31:29 +00:00
|
|
|
for (u32 i = 0; i < 32; i++){
|
|
|
|
if ((fuse_read_odm(7) >> i) & 1)
|
|
|
|
fuse_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
SWAPCOLOR(COLOR_ORANGE);
|
|
|
|
|
2020-04-15 21:02:19 +01:00
|
|
|
gfx_printf("Fuse count: %d\nPKG1 id: '%s'\n", fuse_count, pkg1.id);
|
2020-04-14 09:25:31 +01:00
|
|
|
if (pkg1.ver >= 0)
|
|
|
|
gfx_printf("PKG1 version: %d\n", pkg1.ver);
|
|
|
|
|
|
|
|
gfx_printf("\n");
|
|
|
|
|
2019-12-11 12:18:57 +00:00
|
|
|
print_biskeys();
|
2019-11-21 19:54:18 +00:00
|
|
|
|
2019-12-16 22:31:29 +00:00
|
|
|
RESETCOLOR;
|
|
|
|
gfx_printf("\n-----\n\n");
|
|
|
|
|
|
|
|
SWAPCOLOR(COLOR_BLUE);
|
|
|
|
|
2019-12-11 12:18:57 +00:00
|
|
|
if (!sd_mount()){
|
|
|
|
gfx_printf("SD mount failed!\nFailed to display SD info\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
gfx_printf("Getting storage info: please wait...");
|
2019-12-03 16:11:08 +00:00
|
|
|
|
2019-12-11 12:18:57 +00:00
|
|
|
res = f_getfree("sd:", &fre_clust, &fs);
|
|
|
|
gfx_printf("\nResult getfree: %d\n\n", res);
|
2019-12-04 16:47:13 +00:00
|
|
|
|
2019-12-11 12:18:57 +00:00
|
|
|
tot_sect = (fs->n_fatent - 2) * fs->csize;
|
|
|
|
fre_sect = fre_clust * fs->csize;
|
|
|
|
capacity = sd_storage.csd.capacity;
|
2019-12-04 16:47:13 +00:00
|
|
|
|
2019-12-11 12:18:57 +00:00
|
|
|
gfx_printf("Entire sd:\nSectors: %d\nSpace total: %d MB\n\n", capacity, capacity / 2048);
|
|
|
|
gfx_printf("First partition on SD:\nSectors: %d\nSpace total: %d MB\nSpace free: %d MB\n\n", tot_sect, tot_sect / 2048, fre_sect / 2048);
|
|
|
|
}
|
2019-12-03 16:11:08 +00:00
|
|
|
|
2019-12-16 22:31:29 +00:00
|
|
|
RESETCOLOR;
|
2019-12-11 12:18:57 +00:00
|
|
|
gfx_printf("Press any key to continue");
|
2020-05-02 00:54:03 +01:00
|
|
|
hidWait();
|
2019-12-03 09:06:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void displaygpio(){
|
2020-03-18 11:18:39 +00:00
|
|
|
gfx_clearscreen();
|
2019-12-18 15:02:45 +00:00
|
|
|
gfx_printf("Updates gpio pins every 50ms:\nPress power to exit");
|
2019-12-03 09:06:11 +00:00
|
|
|
msleep(200);
|
|
|
|
while (1){
|
|
|
|
msleep(10);
|
|
|
|
gfx_con_setpos(0, 63);
|
|
|
|
|
|
|
|
for (int i = 0; i <= 30; i++){
|
|
|
|
gfx_printf("\nPort %d: ", i);
|
|
|
|
for (int i2 = 7; i2 >= 0; i2--)
|
|
|
|
gfx_printf("%d", gpio_read(i, (1 << i2)));
|
|
|
|
}
|
|
|
|
|
2020-05-02 00:54:03 +01:00
|
|
|
if (hidRead()->pow)
|
2019-12-03 09:06:11 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-12-03 16:11:08 +00:00
|
|
|
}
|
|
|
|
|
2020-07-14 16:38:56 +01:00
|
|
|
|
|
|
|
// bad code ahead aaaa
|
|
|
|
int dumpfirmware(int mmc, bool daybreak){
|
2019-12-11 13:45:30 +00:00
|
|
|
DIR dir;
|
|
|
|
FILINFO fno;
|
|
|
|
bool fail = false;
|
|
|
|
int ret, amount = 0;
|
2020-04-26 00:20:26 +01:00
|
|
|
char sysbase[] = "emmc:/Contents/registered";
|
|
|
|
char *syspathtemp, *syspath, *sdpath, *sdbase;
|
2020-01-30 22:53:27 +00:00
|
|
|
pkg1_info pkg1 = returnpkg1info();
|
2019-12-11 13:45:30 +00:00
|
|
|
u32 timer = get_tmr_s();
|
|
|
|
|
2020-03-18 11:18:39 +00:00
|
|
|
gfx_clearscreen();
|
2020-01-30 22:53:27 +00:00
|
|
|
connect_mmc(mmc);
|
2020-01-27 22:51:59 +00:00
|
|
|
mount_mmc("SYSTEM", 2);
|
2019-12-11 13:45:30 +00:00
|
|
|
|
2020-07-14 16:38:56 +01:00
|
|
|
if (daybreak){
|
|
|
|
if (!fsutil_checkfile("sd:/switch/prod.keys")){
|
|
|
|
SWAPCOLOR(COLOR_RED);
|
|
|
|
gfx_printf("prod.keys not found.\nPress any button to exit");
|
|
|
|
hidWait();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SetHeaderKey()){
|
|
|
|
SWAPCOLOR(COLOR_RED);
|
|
|
|
gfx_printf("Failed to find header key.\nPress any button to exit");
|
|
|
|
hidWait();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-30 22:53:27 +00:00
|
|
|
gfx_printf("PKG1 version: %d\n", pkg1.ver);
|
2019-12-11 13:45:30 +00:00
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
gfx_printf("Creating folders...\n");
|
|
|
|
f_mkdir("sd:/tegraexplorer");
|
|
|
|
f_mkdir("sd:/tegraexplorer/Firmware");
|
2019-12-11 13:45:30 +00:00
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
sdbase = calloc(32 + strlen(pkg1.id), sizeof(char));
|
|
|
|
sprintf(sdbase, "sd:/tegraexplorer/Firmware/%d (%s)", pkg1.ver, pkg1.id);
|
2020-07-14 16:38:56 +01:00
|
|
|
|
|
|
|
if (fsutil_checkfile(sdbase)){
|
|
|
|
SWAPCOLOR(COLOR_RED);
|
|
|
|
gfx_printf("Destination folder already exists.\nPress X to delete this folder, any other button to cancel\nPath: %s", sdbase);
|
|
|
|
|
|
|
|
Inputs *input = hidWait();
|
|
|
|
if (!input->x){
|
|
|
|
free(sdbase);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
SWAPCOLOR(COLOR_WHITE);
|
|
|
|
gfx_printf("\nDeleting folder..\n");
|
|
|
|
fsact_del_recursive(sdbase);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gfx_printf("\rOut: %s\n", sdbase);
|
2020-04-26 00:20:26 +01:00
|
|
|
f_mkdir(sdbase);
|
2019-12-11 13:45:30 +00:00
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
if ((ret = f_opendir(&dir, sysbase)))
|
|
|
|
fail = true;
|
2019-12-11 13:45:30 +00:00
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
gfx_printf("Starting dump...\n");
|
|
|
|
SWAPCOLOR(COLOR_GREEN);
|
|
|
|
|
|
|
|
printerrors = 0;
|
2019-12-11 13:45:30 +00:00
|
|
|
|
|
|
|
while(!f_readdir(&dir, &fno) && fno.fname[0] && !fail){
|
2020-04-26 00:20:26 +01:00
|
|
|
utils_copystring(fsutil_getnextloc(sysbase, fno.fname), &syspathtemp);
|
|
|
|
|
|
|
|
if (fno.fattrib & AM_DIR){
|
|
|
|
utils_copystring(fsutil_getnextloc(syspathtemp, "00"), &syspath);
|
|
|
|
}
|
2019-12-11 13:45:30 +00:00
|
|
|
else
|
2020-04-26 00:20:26 +01:00
|
|
|
syspath = syspathtemp;
|
2019-12-11 13:45:30 +00:00
|
|
|
|
2020-07-14 16:38:56 +01:00
|
|
|
if (daybreak){
|
|
|
|
u8 ContentType = GetNcaType(syspath);
|
|
|
|
|
|
|
|
if (ContentType < 0){
|
|
|
|
fail = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *temp;
|
|
|
|
utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &temp);
|
|
|
|
|
|
|
|
if (ContentType == 0x01){
|
|
|
|
sdpath = calloc(strlen(temp) + 6, 1);
|
|
|
|
strcpy(sdpath, temp);
|
|
|
|
memcpy(sdpath + strlen(temp) - 4, ".cnmt.nca", 10);
|
|
|
|
free(temp);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sdpath = temp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &sdpath);
|
|
|
|
|
|
|
|
|
2020-03-18 22:58:32 +00:00
|
|
|
ret = fsact_copy(syspath, sdpath, 0);
|
2019-12-11 13:45:30 +00:00
|
|
|
|
|
|
|
gfx_printf("%d %s\r", ++amount, fno.fname);
|
|
|
|
|
|
|
|
if (ret != 0)
|
|
|
|
fail = true;
|
2020-04-26 00:20:26 +01:00
|
|
|
|
|
|
|
free(sdpath);
|
2020-07-14 16:38:56 +01:00
|
|
|
free(syspathtemp);
|
|
|
|
if (syspath != syspathtemp)
|
|
|
|
free(syspath);
|
2019-12-11 13:45:30 +00:00
|
|
|
}
|
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
printerrors = 1;
|
|
|
|
|
2019-12-11 13:45:30 +00:00
|
|
|
if (fail)
|
|
|
|
gfx_printf("%k\n\nDump failed! Aborting (%d)", COLOR_RED, ret);
|
|
|
|
|
|
|
|
gfx_printf("%k\n\nPress any button to continue...\nTime taken: %ds", COLOR_WHITE, get_tmr_s() - timer);
|
2020-04-26 00:20:26 +01:00
|
|
|
free(sdbase);
|
2020-05-02 00:54:03 +01:00
|
|
|
hidWait();
|
2019-12-11 13:45:30 +00:00
|
|
|
|
|
|
|
return fail;
|
|
|
|
}
|
2020-05-09 12:52:46 +01:00
|
|
|
/*
|
2020-01-30 22:53:27 +00:00
|
|
|
void dumpusersaves(int mmc){
|
|
|
|
connect_mmc(mmc);
|
2020-01-27 22:51:59 +00:00
|
|
|
mount_mmc("USER", 2);
|
2020-03-18 11:18:39 +00:00
|
|
|
gfx_clearscreen();
|
2020-01-07 20:53:02 +00:00
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
gfx_printf("Creating folders...\n");
|
|
|
|
f_mkdir("sd:/tegraexplorer");
|
2020-01-07 20:53:02 +00:00
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
gfx_printf("Starting dump...\n");
|
2020-01-07 20:53:02 +00:00
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
SWAPCOLOR(COLOR_GREEN);
|
2020-01-07 20:53:02 +00:00
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
if(fsact_copy_recursive("emmc:/save", "sd:/tegraexplorer"))
|
|
|
|
return;
|
2020-01-07 20:53:02 +00:00
|
|
|
|
2020-04-26 00:20:26 +01:00
|
|
|
RESETCOLOR;
|
|
|
|
gfx_printf("\n\nSaves are located in SD:/tegraexplorer/save\n");
|
2020-01-07 20:53:02 +00:00
|
|
|
gfx_printf("Press any key to continue");
|
2020-05-02 00:54:03 +01:00
|
|
|
hidWait();
|
2020-01-07 20:53:02 +00:00
|
|
|
}
|
2020-05-09 12:52:46 +01:00
|
|
|
*/
|
2020-01-07 20:53:02 +00:00
|
|
|
|
2019-12-11 16:17:10 +00:00
|
|
|
int format(int mode){
|
2020-03-18 11:18:39 +00:00
|
|
|
gfx_clearscreen();
|
2019-12-03 16:11:08 +00:00
|
|
|
int res;
|
2019-12-09 10:56:30 +00:00
|
|
|
bool fatalerror = false;
|
2020-05-04 19:30:51 +01:00
|
|
|
DWORD plist[] = {666, 61145088, 0, 0};
|
2019-12-26 22:07:18 +00:00
|
|
|
u32 timer, totalsectors, alignedsectors, extrasectors;
|
2020-05-04 19:30:51 +01:00
|
|
|
u8 *work;
|
2019-12-12 17:46:27 +00:00
|
|
|
DWORD clustsize = 32768;
|
2019-12-03 16:11:08 +00:00
|
|
|
BYTE formatoptions = 0;
|
|
|
|
formatoptions |= (FM_FAT32);
|
2019-12-11 12:18:57 +00:00
|
|
|
//formatoptions |= (FM_SFD);
|
2019-12-03 16:11:08 +00:00
|
|
|
|
2020-01-27 22:51:59 +00:00
|
|
|
disconnect_mmc();
|
2019-12-09 10:56:30 +00:00
|
|
|
|
2019-12-11 13:45:30 +00:00
|
|
|
timer = get_tmr_s();
|
2019-12-09 10:56:30 +00:00
|
|
|
totalsectors = sd_storage.csd.capacity;
|
|
|
|
|
2020-05-04 19:30:51 +01:00
|
|
|
gfx_printf("Initializing...\n");
|
|
|
|
|
|
|
|
work = calloc(BUFSIZE, sizeof(BYTE));
|
|
|
|
|
|
|
|
if (work == NULL){
|
|
|
|
gfx_errDisplay("format", ERR_MEM_ALLOC_FAILED, 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-03-17 23:41:09 +00:00
|
|
|
if (mode == FORMAT_EMUMMC){
|
2019-12-17 12:50:02 +00:00
|
|
|
if (totalsectors < 83886080){
|
2019-12-18 15:02:45 +00:00
|
|
|
gfx_printf("%kYou seem to be running this on a <=32GB SD\nNot enough free space for emummc!", COLOR_RED);
|
2019-12-11 13:45:30 +00:00
|
|
|
fatalerror = true;
|
|
|
|
}
|
2019-12-17 12:50:02 +00:00
|
|
|
else {
|
2019-12-26 22:07:18 +00:00
|
|
|
totalsectors -= plist[1];
|
|
|
|
alignedsectors = (totalsectors / 2048) * 2048;
|
|
|
|
extrasectors = totalsectors - alignedsectors;
|
|
|
|
plist[0] = alignedsectors;
|
|
|
|
plist[1] += extrasectors;
|
|
|
|
gfx_printf("\nStarting SD partitioning:\nTotalSectors: %d\nPartition1 (SD): %d\nPartition2 (EMUMMC): %d\n", plist[0] + plist[1], plist[0], plist[1]);
|
2019-12-11 13:45:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
plist[0] = totalsectors;
|
|
|
|
plist[1] = 0;
|
2019-12-09 10:56:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!fatalerror){
|
|
|
|
gfx_printf("\nPartitioning SD...\n");
|
2020-05-04 19:30:51 +01:00
|
|
|
res = f_fdisk(0, plist, work);
|
2019-12-09 10:56:30 +00:00
|
|
|
|
|
|
|
if (res){
|
|
|
|
gfx_printf("%kf_fdisk returned %d!\n", COLOR_RED, res);
|
|
|
|
fatalerror = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gfx_printf("Done!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!fatalerror){
|
|
|
|
gfx_printf("\n\nFormatting Partition1...\n");
|
2020-05-04 19:30:51 +01:00
|
|
|
res = f_mkfs("0:", formatoptions, clustsize, work, BUFSIZE * sizeof(BYTE));
|
2019-12-09 10:56:30 +00:00
|
|
|
|
|
|
|
if (res){
|
|
|
|
gfx_printf("%kf_mkfs returned %d!\n", COLOR_RED, res);
|
|
|
|
fatalerror = true;
|
2019-12-03 16:11:08 +00:00
|
|
|
}
|
2019-12-09 10:56:30 +00:00
|
|
|
else
|
|
|
|
gfx_printf("Smells like a formatted SD\n\n");
|
2019-12-03 16:11:08 +00:00
|
|
|
}
|
|
|
|
|
2020-05-04 19:30:51 +01:00
|
|
|
free(work);
|
|
|
|
|
2019-12-09 10:56:30 +00:00
|
|
|
sd_unmount();
|
|
|
|
|
|
|
|
if (!fatalerror){
|
2019-12-03 16:11:08 +00:00
|
|
|
if (!sd_mount())
|
|
|
|
gfx_printf("%kSd failed to mount!\n", COLOR_ORANGE);
|
|
|
|
else {
|
|
|
|
gfx_printf("Sd mounted!\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-27 22:51:59 +00:00
|
|
|
connect_mmc(SYSMMC);
|
2019-12-11 13:45:30 +00:00
|
|
|
|
2019-12-03 16:11:08 +00:00
|
|
|
gfx_printf("\nPress any button to return%k\nTotal time taken: %ds", COLOR_WHITE, (get_tmr_s() - timer));
|
2020-05-02 00:54:03 +01:00
|
|
|
hidWait();
|
2019-12-11 16:17:10 +00:00
|
|
|
return fatalerror;
|
2019-11-21 19:54:18 +00:00
|
|
|
}
|