Compare commits

...

19 Commits

Author SHA1 Message Date
Such Meme, Many Skill
b91c36d3fa Fastfs testing 2020-05-19 17:54:21 +02:00
Such Meme, Many Skill
a8e86c2de3 Don't forget to take results 2020-05-17 23:42:53 +02:00
Such Meme, Many Skill
6934e1422f Various improvements to scripting lang
- Errors will now be more precise, there are now 2 separate errors for a function lookup failure and a failure inside a function
- Errors will now show which line number they failed at, instead of the character offset
- Minus values are not considered errors anymore, however, printing them does not work well
- Gotos now make a @RETURN variable to make making functions easier
2020-05-15 20:17:31 +02:00
Such Meme, Many Skill
f49245e4ab Fix hidden copies messing with screen positions 2020-05-15 16:20:52 +02:00
Such Meme, Many Skill
9075f20854 Clean up bisfile extraction 2020-05-15 16:07:23 +02:00
Such Meme, Many Skill
6bc474a981 Bump version 2020-05-10 21:56:11 +02:00
Such Meme, Many Skill
91536268ad Fix compiling issues (hopefully) 2020-05-10 21:51:30 +02:00
Such Meme, Many Skill
b484dc11d8 Hopefully fix partitioning issues & clean up menu control code 2020-05-10 11:41:16 +02:00
Such Meme, Many Skill
14a3a39c01 Remove dumping user saves from tools
This has been replaced by a script: https://github.com/suchmememanyskill/TegraScript/blob/master/scripts/savedumper.te
2020-05-09 13:52:46 +02:00
Such Meme, Many Skill
6868ef3536 Reset print pos after copying a file 2020-05-09 12:21:34 +02:00
Such Meme, Many Skill
97810335ed fix a bug that basically has no effect
thanks shchmue for pointing that out :smug:
2020-05-09 00:26:02 +02:00
Such Meme, Many Skill
43617ef511 Add save signing 2020-05-09 00:22:35 +02:00
Such Meme, Many Skill
19fe7f15a9 Fix (not) asking to make sure to flash in scripts 2020-05-08 20:57:26 +02:00
Such Meme, Many Skill
73ca98c6a8 Merge remote-tracking branch 'origin/master' 2020-05-04 22:36:13 +02:00
Such Meme, Many Skill
12eecd2466 Update readme 2020-05-04 22:36:07 +02:00
suchmememanyskill
40cb293db3 Try no.4 2020-05-04 21:54:39 +02:00
suchmememanyskill
f09a098c77 Try no.3 2020-05-04 21:35:29 +02:00
suchmememanyskill
30f0e88d0a Attempt no.2 2020-05-04 21:32:05 +02:00
suchmememanyskill
c4c5d57af3 Test github actions 2020-05-04 21:24:49 +02:00
43 changed files with 687 additions and 230 deletions

36
.github/workflows/builder.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: TegraExplorer builder
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install devkitpro
run: |
wget https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb
sudo dpkg -i devkitpro-pacman.deb
sudo dkp-pacman -S switch-dev --noconfirm
sudo dkp-pacman -S devkitARM --noconfirm
- name: Build TegraExplorer
run: |
echo # SETTING PATH #
export DEVKITPRO=/opt/devkitpro
export DEVKITARM=${DEVKITPRO}/devkitARM
export DEVKITPPC=${DEVKITPRO}/devkitPPC
export PATH=${DEVKITPRO}/tools/bin:$PATH
echo # MAKE #
make -j$(nproc)
- uses: actions/upload-artifact@master
with:
name: TegraExplorer
path: output/TegraExplorer.bin

View File

@@ -11,7 +11,7 @@ include $(DEVKITARM)/base_rules
IPL_LOAD_ADDR := 0x40008000
LPVERSION_MAJOR := 3
LPVERSION_MINOR := 0
LPVERSION_BUGFX := 1
LPVERSION_BUGFX := 2
################################################################################

View File

@@ -1,33 +1,62 @@
# TegraExplorer
A payload-based file explorer for your switch!
![TegraExplorer builder](https://github.com/suchmememanyskill/TegraExplorer/workflows/TegraExplorer%20builder/badge.svg)
## Usage
1. Get your favorite payload injector
2. Inject TegraExplorer as a payload
Navigate around the menus using the vol+, vol- and power buttons
Navigate around the menus using the joycons.
A: Select
B: Back
Left Joystick up/down (Dpad or joystick): navigate menus up/down
Right Joystick up/down: fast menu navigation up/down
Capture (Minerva only): Take a screenshot
L3/R3 (Press joysticks in): Recalibrate centerpoint
If you do not have your joycons connected:
Power -> A
Vol+ -> Left Joystick up
Vol- -> Left Joystick down
## Functions
- Navigate the SD card
- Navigate the System partition of your sysnand/sysmmc
- Navigate the System partition of your sysmmc and emummc
- Interact with files
- Deleting, copying or moving files
- Deleting, copying, renaming and moving files
- Launching payloads files
- Viewing the hex data of a file
- Launching special [TegraScript](https://github.com/suchmememanyskill/TegraScript) files
- Renaming files
- Interacting with folders
- Deleting or copying folders
- Deleting, copying or renaming folders
- Creating folders
- Dumping your current firmware to sd
- Formatting the sd card
*and more*
## Support
For general CFW support, go to the [Nintendo Homebrew](https://discord.gg/C29hYvh) discord
For question specifically for TegraExplorer, go to [my discord](https://discord.gg/aH9rsuP)
# Credits
## Credits
Based on [Lockpick_RCM](https://github.com/shchmue/Lockpick_RCM), and thus also based on [Hekate](https://github.com/CTCaer/hekate)
Lots of help from:
Awesome people who helped with this project:
- shchmue
- Denn
- Dennthecafebabe
Other awesome people:
- PhazonicRidley
- Dax
- Huhen
- Bleck9999
- Exelix
## Screenshots
![Preview](/preview.png)

BIN
preview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -64,7 +64,7 @@ ini_sec_t *_ini_create_section(link_t *dst, ini_sec_t *csec, char *name, u8 type
return csec;
}
int ini_parse(link_t *dst, char *ini_path, bool is_dir)
int ini_parse(link_t *dst, const char *ini_path, bool is_dir)
{
u32 lblen;
u32 pathlen = strlen(ini_path);
@@ -73,6 +73,7 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
char *filelist = NULL;
FIL fp;
ini_sec_t *csec = NULL;
bool firstIniRun = true;
char *filename = (char *)malloc(256);
@@ -116,10 +117,17 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
do
{
if (firstIniRun){
firstIniRun = false;
strcpy(lbuf, "[Unknown]");
lblen = 9;
}
else {
// Fetch one line.
lbuf[0] = 0;
f_gets(lbuf, 512, &fp);
lblen = strlen(lbuf);
}
// Remove trailing newline. Depends on 'FF_USE_STRFUNC 2' that removes \r.
if (lblen && lbuf[lblen - 1] == '\n')

View File

@@ -43,7 +43,7 @@ typedef struct _ini_sec_t
u32 color;
} ini_sec_t;
int ini_parse(link_t *dst, char *ini_path, bool is_dir);
int ini_parse(link_t *dst, const char *ini_path, bool is_dir);
char *ini_check_payload_section(ini_sec_t *cfg);
#endif

View File

@@ -20,6 +20,9 @@
#include <string.h>
#include "gfx.h"
gfx_ctxt_t gfx_ctxt;
gfx_con_t gfx_con;
static const u8 _gfx_font[] = {
0x00, 0x0C, 0x12, 0x7E, 0x42, 0x42, 0x7E, 0x00, // Char 030 (folder)
0x00, 0x0E, 0x12, 0x22, 0x22, 0x22, 0x3E, 0x00, // Char 031 (file)

View File

@@ -61,7 +61,7 @@ void gfx_boxGrey(int x0, int y0, int x1, int y1, u8 shade);
*/
// Global gfx console and context.
gfx_ctxt_t gfx_ctxt;
gfx_con_t gfx_con;
extern gfx_ctxt_t gfx_ctxt;
extern gfx_con_t gfx_con;
#endif

View File

@@ -31,6 +31,10 @@
#define DEBUG_PRINTING*/
#define DPRINTF(...)
u32 pkg2_newkern_ini1_val;
u32 pkg2_newkern_ini1_start;
u32 pkg2_newkern_ini1_end;
static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
{
u32 size = sizeof(pkg2_kip1_t);

View File

@@ -28,9 +28,9 @@
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // Offset of OP + 12 is the INI1 offset.
u32 pkg2_newkern_ini1_val;
u32 pkg2_newkern_ini1_start;
u32 pkg2_newkern_ini1_end;
extern u32 pkg2_newkern_ini1_val;
extern u32 pkg2_newkern_ini1_start;
extern u32 pkg2_newkern_ini1_end;
typedef struct _pkg2_hdr_t
{

View File

@@ -108,7 +108,7 @@ static inline int _emmc_xts(u32 ks1, u32 ks2, u32 enc, u8 *tweak, bool regen_twe
pdst += 0x10;
}
se_aes_crypt_ecb(ks2, enc, dst, secsize, src, secsize);
se_aes_crypt_ecb(ks2, enc, dst, secsize, dst, secsize);
pdst = (u8 *)dst;

View File

@@ -42,8 +42,8 @@
#include "../../storage/sdmmc.h"
extern sdmmc_storage_t sd_storage;
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
//#define EFSPRINTF(...)
//#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
#define EFSPRINTF(...)
/*--------------------------------------------------------------------------
@@ -4056,7 +4056,216 @@ FRESULT f_write (
LEAVE_FF(fs, FR_OK);
}
#ifdef FF_FASTFS
/*-----------------------------------------------------------------------*/
/* Fast Read Aligned Sized File Without a Cache */
/*-----------------------------------------------------------------------*/
#if FF_USE_FASTSEEK
FRESULT f_read_fast (
FIL* fp, /* Pointer to the file object */
const void* buff, /* Pointer to the data to be written */
UINT btr /* Number of bytes to read */
)
{
if (btr % 65536 != 0)
return f_read(fp, buff, btr, NULL);
FRESULT res;
FATFS *fs;
UINT csize_bytes;
DWORD clst;
UINT count = 0;
FSIZE_t work_sector = 0;
FSIZE_t sector_base = 0;
BYTE *wbuff = (BYTE*)buff;
// TODO support sector reading inside a cluster
res = validate(&fp->obj, &fs); /* Check validity of the file object */
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
EFSPRINTF("FOV");
LEAVE_FF(fs, res); /* Check validity */
}
if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
FSIZE_t remain = fp->obj.objsize - fp->fptr;
if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
csize_bytes = fs->csize * SS(fs);
if (!fp->fptr) { /* On the top of the file? */
clst = fp->obj.sclust; /* Follow from the origin */
} else {
if (fp->cltbl) clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); }
}
if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst; /* Set working cluster */
sector_base = clst2sect(fs, fp->clust);
count += fs->csize;
btr -= csize_bytes;
fp->fptr += csize_bytes;
while (btr) {
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
if (clst < 2) { EFSPRINTF("CCHK2"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DSKC"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst;
work_sector = clst2sect(fs, fp->clust);
if ((work_sector - sector_base) == count) count += fs->csize;
else {
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
wbuff += count * SS(fs);
sector_base = work_sector;
count = fs->csize;
}
fp->fptr += MIN(btr, csize_bytes);
btr -= MIN(btr, csize_bytes);
// TODO: what about if data is smaller than cluster?
// Must read-write back that cluster.
if (!btr) { /* Final cluster/sectors read. */
if (disk_read(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
}
}
LEAVE_FF(fs, FR_OK);
}
#endif
#endif
#ifdef FF_FASTFS
/*-----------------------------------------------------------------------*/
/* Fast Write Aligned Sized File Without a Cache */
/*-----------------------------------------------------------------------*/
#if FF_USE_FASTSEEK
FRESULT f_write_fast (
FIL* fp, /* Pointer to the file object */
const void* buff, /* Pointer to the data to be written */
UINT btw /* Number of bytes to write */
)
{
if (btw % 65536 != 0)
return f_write(fp, buff, btw, NULL);
FRESULT res;
FATFS *fs;
UINT csize_bytes;
DWORD clst;
UINT count = 0;
FSIZE_t work_sector = 0;
FSIZE_t sector_base = 0;
const BYTE *wbuff = (const BYTE*)buff;
// TODO support sector writing inside a cluster
res = validate(&fp->obj, &fs); /* Check validity of the file object */
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) {
EFSPRINTF("FOV");
LEAVE_FF(fs, res); /* Check validity */
}
if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
/* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */
if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {
btw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr);
}
csize_bytes = fs->csize * SS(fs);
if (!fp->fptr) { /* On the top of the file? */
clst = fp->obj.sclust; /* Follow from the origin */
} else {
if (fp->cltbl) clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
else { EFSPRINTF("CLTBL"); ABORT(fs, FR_CLTBL_NO_INIT); }
}
if (clst < 2) { EFSPRINTF("CCHK"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DERR"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst; /* Set working cluster */
sector_base = clst2sect(fs, fp->clust);
count += fs->csize;
btw -= csize_bytes;
fp->fptr += csize_bytes;
while (btw) {
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
if (clst < 2) { EFSPRINTF("CCHK2"); ABORT(fs, FR_INT_ERR); }
else if (clst == 0xFFFFFFFF) { EFSPRINTF("DERR"); ABORT(fs, FR_DISK_ERR); }
fp->clust = clst;
work_sector = clst2sect(fs, fp->clust);
if ((work_sector - sector_base) == count) count += fs->csize;
else {
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
wbuff += count * SS(fs);
sector_base = work_sector;
count = fs->csize;
}
fp->fptr += MIN(btw, csize_bytes);
btw -= MIN(btw, csize_bytes);
// what about if data is smaller than cluster?
// Probably must read-write back that cluster.
if (!btw) { /* Final cluster/sectors write. */
if (disk_write(fs->pdrv, wbuff, sector_base, count) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
}
}
fp->flag |= FA_MODIFIED; /* Set file change flag */
LEAVE_FF(fs, FR_OK);
}
#endif
#endif
#ifdef FF_FASTFS
#if FF_USE_FASTSEEK
/*-----------------------------------------------------------------------*/
/* Seek File Read/Write Pointer */
/*-----------------------------------------------------------------------*/
DWORD *f_expand_cltbl (
FIL* fp, /* Pointer to the file object */
UINT tblsz, /* Size of table */
FSIZE_t ofs /* File pointer from top of file */
)
{
if (fp->flag & FA_WRITE) f_lseek(fp, ofs); /* Expand file if write is enabled */
if (!fp->cltbl) { /* Allocate memory for cluster link table */
fp->cltbl = (DWORD *)ff_memalloc(tblsz);
fp->cltbl[0] = tblsz;
}
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
ff_memfree(fp->cltbl);
fp->cltbl = NULL;
EFSPRINTF("CLTBLSZ");
return NULL;
}
f_lseek(fp, 0);
return fp->cltbl;
}
#endif
#endif
/*-----------------------------------------------------------------------*/
@@ -4169,6 +4378,13 @@ FRESULT f_close (
#endif
}
}
if (fp->cltbl != NULL){
ff_memfree(fp->cltbl);
fp->cltbl = NULL;
}
return res;
}
@@ -6114,9 +6330,6 @@ FRESULT f_fdisk (
DWORD sz_disk, p_sect, b_cyl, b_sect;
FRESULT res;
BYTE *empty_buff;
empty_buff = ff_memcalloc(sizeof(BYTE), 16384);
stat = disk_initialize(pdrv);
if (stat & STA_NOINIT) return FR_NOT_READY;
if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
@@ -6169,14 +6382,14 @@ FRESULT f_fdisk (
st_dword(p + 8, b_sect); /* Start sector in LBA */
st_dword(p + 12, p_sect); /* Number of sectors */
/* Next partition */
b_sect += p_sect;
for (int cursect = 0; cursect < 1024; cursect++){
disk_write(pdrv, empty_buff, b_sect + (32 * cursect), 32);
for (u32 cursect = 0; cursect < 512; cursect++){
disk_write(pdrv, buf + 0x4000, b_sect + (64 * cursect), 64);
}
b_sect += p_sect;
}
st_word(p, 0xAA55); /* MBR signature (always at offset 510) */
ff_memfree(empty_buff);
/* Write it to the MBR */
res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;

View File

@@ -246,7 +246,10 @@ typedef enum {
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
FR_INVALID_PARAMETER, /* (19) Given parameter is invalid */
#ifdef FF_FASTFS
FR_CLTBL_NO_INIT /* (20) The cluster table for fast seek/read/write was not created */
#endif
} FRESULT;
@@ -288,6 +291,11 @@ int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
#ifdef FF_FASTFS
FRESULT f_read_fast (FIL* fp, const void* buff, UINT btr); /* Fast read data from the file */
FRESULT f_write_fast (FIL* fp, const void* buff, UINT btw); /* Fast write data to the file */
DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs); /* Expand file and populate cluster table */
#endif
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err)

View File

@@ -42,7 +42,13 @@
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define FF_FASTFS 1
#ifdef FF_FASTFS
#define FF_USE_FASTSEEK 1
#else
#define FF_USE_FASTSEEK 0
#endif
/* This option switches fast seek function. (0:Disable or 1:Enable) */
@@ -287,3 +293,5 @@
/*--- End of configuration options ---*/

View File

@@ -44,10 +44,10 @@
//#include "keys/keys.h"
sdmmc_t sd_sdmmc;
sdmmc_storage_t sd_storage;
__attribute__ ((aligned (16))) FATFS sd_fs;
bool sd_mounted, sd_inited;
//sdmmc_t sd_sdmmc;
//sdmmc_storage_t sd_storage;
//__attribute__ ((aligned (16))) FATFS sd_fs;
//bool sd_mounted, sd_inited;
volatile nyx_storage_t *nyx_str = (nyx_storage_t *)NYX_STORAGE_ADDR;
hekate_config h_cfg;
boot_cfg_t __attribute__((section ("._boot_cfg"))) b_cfg;

View File

@@ -27,6 +27,7 @@
#include "../soc/t210.h"
extern volatile nyx_storage_t *nyx_str;
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init()
{

View File

@@ -57,7 +57,7 @@ typedef enum
FREQ_1600 = 1600000
} minerva_freq_t;
void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
extern void (*minerva_cfg)(mtc_config_t *mtc_cfg, void *);
u32 minerva_init();
void minerva_change_freq(minerva_freq_t freq);
void minerva_periodic_training();

View File

@@ -32,6 +32,7 @@ extern sdmmc_storage_t sd_storage;
extern FATFS sd_fs;
extern hekate_config h_cfg;
emummc_cfg_t emu_cfg;
extern bool sd_mount();
extern void sd_unmount();

View File

@@ -47,7 +47,7 @@ typedef struct _emummc_cfg_t
int fs_ver;
} emummc_cfg_t;
emummc_cfg_t emu_cfg;
extern emummc_cfg_t emu_cfg;
bool emummc_load_cfg();
int emummc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc);

View File

@@ -25,6 +25,10 @@
bool sd_mounted = false, sd_inited = false;
static u32 sd_mode = SD_UHS_SDR82;
sdmmc_t sd_sdmmc;
sdmmc_storage_t sd_storage;
FATFS sd_fs;
u32 sd_get_mode()
{
return sd_mode;

View File

@@ -30,9 +30,9 @@ enum
SD_UHS_SDR82 = 3,
};
sdmmc_t sd_sdmmc;
sdmmc_storage_t sd_storage;
FATFS sd_fs;
extern sdmmc_t sd_sdmmc;
extern sdmmc_storage_t sd_storage;
extern FATFS sd_fs;
u32 sd_get_mode();
int sd_init_retry(bool power_cycle);

View File

@@ -21,7 +21,7 @@
#include "../utils/types.h"
#include "sdmmc_driver.h"
u32 sd_power_cycle_time_start;
extern u32 sd_power_cycle_time_start;
typedef enum _sdmmc_type
{

View File

@@ -29,6 +29,11 @@
#include "../soc/t210.h"
#include "../utils/util.h"
#pragma GCC push_options
#pragma GCC optimize ("Os")
u32 sd_power_cycle_time_start;
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
#define DPRINTF(...)
@@ -1158,6 +1163,8 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type, int a
return 0;
}
#pragma GCC pop_options
void sdmmc_end(sdmmc_t *sdmmc)
{
if (!sdmmc->clock_stopped)

View File

@@ -21,9 +21,11 @@ enum utils_err_codes_te_call {
ERR_EMMC_WRITE_FAILED,
ERR_FILE_TOO_BIG_FOR_DEST,
ERR_SD_EJECTED,
ERR_PARSE_FAIL,
ERR_SCRIPT_LOOKUP_FAIL,
ERR_CANNOT_COPY_FILE_TO_FS_PART,
ERR_NO_DESTINATION
ERR_NO_DESTINATION,
ERR_INI_PARSE_FAIL,
ERR_IN_FUNC
};
extern const char *utils_err_codes_te[];
@@ -58,8 +60,7 @@ extern menu_entry mainmenu_shutdown[];
enum mainmenu_tools_return {
TOOLS_DISPLAY_INFO = 1,
TOOLS_DISPLAY_GPIO,
TOOLS_DUMPFIRMWARE,
TOOLS_DUMPUSERSAVE
TOOLS_DUMPFIRMWARE
};
extern menu_entry mainmenu_tools[];
@@ -86,7 +87,8 @@ enum fs_menu_file_return {
FILE_PAYLOAD,
FILE_SCRIPT,
FILE_HEXVIEW,
FILE_DUMPBIS
FILE_DUMPBIS,
FILE_SIGN
};
extern menu_entry fs_menu_file[];

View File

@@ -50,9 +50,11 @@ const char *utils_err_codes_te[] = { // these start at 50
"EMMC WRITE FAILED",
"FILE TOO BIG FOR DEST",
"SD EJECTED",
"PARSING FAILED",
"FUNC LOOKUP FAIL",
"CANNOT COPY FILE TO FS PART",
"NO DESTINATION"
"NO DESTINATION",
"INI PARSE FAIL",
"ERR IN FUNC"
};
/*
const char *pkg2names[] = {

View File

@@ -25,8 +25,7 @@ menu_entry mainmenu_tools[] = {
{"Back", COLOR_WHITE, {ISMENU}},
{"\nDisplay Console Info", COLOR_GREEN, {ISMENU}},
{"Display GPIO pins", COLOR_VIOLET, {ISMENU}},
{"Dump Firmware", COLOR_BLUE, {ISMENU}},
{"Dump User Saves", COLOR_YELLOW, {ISMENU}}
{"Dump Firmware", COLOR_BLUE, {ISMENU}}
};
menu_entry mainmenu_format[] = {
@@ -53,7 +52,8 @@ menu_entry fs_menu_file[] = {
{"Launch Payload", COLOR_ORANGE, {ISMENU}},
{"Launch Script", COLOR_YELLOW, {ISMENU}},
{"View Hex", COLOR_GREEN, {ISMENU}},
{"\nExtract BIS", COLOR_YELLOW, {ISMENU}}
{"\nExtract BIS", COLOR_YELLOW, {ISMENU}},
{"Sign Save", COLOR_ORANGE, {ISMENU}}
};
menu_entry fs_menu_folder[] = {

View File

@@ -159,7 +159,7 @@ int makeMmcMenu(short mmcType){
case 2:
if (!(clipboardhelper & ISDIR) && (clipboardhelper & OPERATIONCOPY)){
gfx_clearscreen();
if (!mmcFlashFile(clipboard, mmcType)){
if (!mmcFlashFile(clipboard, mmcType, true)){
gfx_printf("\nDone!");
hidWait();
}

View File

@@ -4,7 +4,7 @@
int emmcDumpSpecific(char *part, char *path);
int emmcDumpBoot(char *basePath);
int mmcFlashFile(char *path, short mmcType);
int mmcFlashFile(char *path, short mmcType, bool warnings);
int emmcDumpPart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part, bool warnings);

View File

@@ -17,7 +17,7 @@
extern sdmmc_storage_t storage;
extern emmc_part_t *system_part;
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part, bool warnings){
FIL fp;
FILINFO fno;
u8 *buf;
@@ -54,10 +54,10 @@ int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
gfx_printf("Flashing %s\n", part->name);
if (totalSize < totalSizeDest){
if (totalSize < totalSizeDest && warnings){
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("File is too small for destination.\nDo you want to flash it anyway?\n\nB to Cancel\n");
u8 btnres = gfx_makewaitmenu(
u32 btnres = gfx_makewaitmenu(
"A to Confirm",
3
);
@@ -214,13 +214,13 @@ emmc_part_t *mmcFindPart(char *path, short mmcType){
return NULL;
}
int mmcFlashFile(char *path, short mmcType){
int mmcFlashFile(char *path, short mmcType, bool warnings){
emmc_part_t *part;
int res;
part = mmcFindPart(path, mmcType);
if (part != NULL){
res = emmcRestorePart(path, &storage, part);
res = emmcRestorePart(path, &storage, part, warnings);
emummc_storage_set_mmc_partition(&storage, 0);
return res;
}

View File

@@ -16,6 +16,7 @@
#include "../emmc/emmcoperations.h"
#include "../../hid/hid.h"
#include "../utils/menuUtils.h"
#include "savesign.h"
extern char *currentpath;
extern char *clipboard;
@@ -150,6 +151,7 @@ int filemenu(menu_entry file){
fs_menu_file[8].isHide = (!(strstr(file.name, ".bin") != NULL && file.size == 1) && strstr(file.name, ".rom") == NULL);
fs_menu_file[9].isHide = (strstr(file.name, ".te") == NULL);
fs_menu_file[11].isHide = (strstr(file.name, ".bis") == NULL);
fs_menu_file[12].isHide = (!!strcmp(currentpath, "emmc:/save"));
/*
SETBIT(fs_menu_file[6].property, ISHIDE, !hidConnected());
@@ -158,7 +160,7 @@ int filemenu(menu_entry file){
SETBIT(fs_menu_file[11].property, ISHIDE, strstr(file.name, ".bis") == NULL);
*/
temp = menu_make(fs_menu_file, 12, "-- File Menu --");
temp = menu_make(fs_menu_file, 13, "-- File Menu --");
switch (temp){
case FILE_COPY:
fsreader_writeclipboard(fsutil_getnextloc(currentpath, file.name), OPERATIONCOPY);
@@ -189,7 +191,6 @@ int filemenu(menu_entry file){
break;
}
fsreader_readfolder(currentpath);
break;
case FILE_PAYLOAD:
launch_payload(fsutil_getnextloc(currentpath, file.name));
@@ -203,7 +204,6 @@ int filemenu(menu_entry file){
*/
runScript(fsutil_getnextloc(currentpath, file.name));
fsreader_readfolder(currentpath);
break;
case FILE_HEXVIEW:
viewbytes(fsutil_getnextloc(currentpath, file.name));
@@ -211,12 +211,23 @@ int filemenu(menu_entry file){
case FILE_DUMPBIS:
gfx_clearscreen();
extract_bis_file(fsutil_getnextloc(currentpath, file.name), currentpath);
fsreader_readfolder(currentpath);
hidWait();
break;
case FILE_SIGN:
if (gfx_defaultWaitMenu("WARNING!\n\nThis should only be used if you know what signing and a save is\nDo not do this if you don't know what this does\n\nRequires you to have a prod.keys located in the switch folder\n", 5)){
gfx_clearscreen();
gfx_printf("Signing save...\n");
if (save_sign("sd:/switch/prod.keys", fsutil_getnextloc(currentpath, file.name))){
gfx_printf("Done!\nPress any key to exit");
hidWait();
}
}
break;
case -1:
return -1;
}
fsreader_readfolder(currentpath);
return 0;
}

View File

@@ -15,9 +15,8 @@ int fsact_copy(const char *locin, const char *locout, u8 options){
FIL in, out;
FILINFO in_info;
u64 sizeRemaining, toCopy;
UINT temp1, temp2;
u8 *buff, toPrint = options & COPY_MODE_PRINT, toCancel = options & COPY_MODE_CANCEL;
u32 x, y, i = 11;
u32 x, y, i = 11, toSpeed;
int res;
gfx_con_getpos(&x, &y);
@@ -32,12 +31,12 @@ int fsact_copy(const char *locin, const char *locout, u8 options){
return 1;
}
if (f_stat(locin, &in_info)){
if ((res = f_stat(locin, &in_info))){
gfx_errDisplay("copy", res, 3);
return 1;
}
if (f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE)){
if ((res = f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE))){
gfx_errDisplay("copy", res, 4);
return 1;
}
@@ -53,22 +52,20 @@ int fsact_copy(const char *locin, const char *locout, u8 options){
sizeRemaining = f_size(&in);
const u64 totalsize = sizeRemaining;
DWORD *clmt_in = f_expand_cltbl(&in, BUFSIZE / 4, 0);
DWORD *clmt_out = f_expand_cltbl(&out, BUFSIZE / 4, totalsize);
while (sizeRemaining > 0){
toCopy = MIN(sizeRemaining, BUFSIZE);
if ((res = f_read(&in, buff, toCopy, &temp1))){
if ((res = f_read_fast(&in, buff, toCopy))){
gfx_errDisplay("copy", res, 5);
return 1;
break;
}
if ((res = f_write(&out, buff, toCopy, &temp2))){
if ((res = f_write_fast(&out, buff, toCopy))){
gfx_errDisplay("copy", res, 6);
return 1;
}
if (temp1 != temp2){
gfx_errDisplay("copy", ERR_DISK_WRITE_FAILED, 7);
return 1;
break;
}
sizeRemaining -= toCopy;
@@ -91,19 +88,19 @@ int fsact_copy(const char *locin, const char *locout, u8 options){
}
}
RESETCOLOR;
if (toPrint){
RESETCOLOR;
gfx_con_setpos(x - 16, y);
}
f_close(&in);
f_close(&out);
free(buff);
if ((res = f_chmod(locout, in_info.fattrib, 0x3A))){
gfx_errDisplay("copy", res, 8);
return 1;
}
f_chmod(locout, in_info.fattrib, 0x3A);
f_stat(locin, &in_info); //somehow stops fatfs from being weird
return 0;
return res;
}
int fsact_del_recursive(char *path){

View File

@@ -13,25 +13,15 @@
#include "../utils/utils.h"
#include "fsactions.h"
u32 DecodeInt(u8* data) {
u32 out = 0;
for (int i = 0; i < 4; i++) {
out |= (data[i] << ((3 - i) * 8));
}
return out;
}
void copy_fil_size(FIL* in_src, FIL* out_src, int size_src){
u8* buff;
buff = calloc(16384, sizeof(u8));
buff = calloc(BUFSIZE, sizeof(u8));
int size = size_src;
int copysize;
while (size > 0){
copysize = MIN(16834, size);
copysize = MIN(BUFSIZE, size);
f_read(in_src, buff, copysize, NULL);
f_write(out_src, buff, copysize, NULL);
size -= copysize;
@@ -48,56 +38,50 @@ void gen_part(int size, FIL* in, char *path){
f_close(&out);
}
const char *filenames[] = {
"BOOT0.bin",
"BOOT1.bin",
"BCPKG2-1-Normal-Main",
"BCPKG2-3-SafeMode-Main",
"BCPKG2-2-Normal-Sub",
"BCPKG2-4-SafeMode-Sub"
};
int extract_bis_file(char *path, char *outfolder){
FIL in;
int res;
u8 version[0x10];
u8 args;
u8 temp[0x4];
u32 filesizes[4];
char *tempPath;
BisFile header;
if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("extract_bis_file", res, 0);
return -1;
}
f_read(&in, version, 0x10, NULL);
f_read(&in, &args, 1, NULL);
f_read(&in, &header, sizeof(BisFile), NULL);
for (int i = 0; i < 4; i++)
header.sizes[i] = FLIPU32(header.sizes[i]);
gfx_printf("Version: %s\n\n", header.version);
// Loop to actually extract stuff
for (int i = 0; i < 4; i++){
f_read(&in, temp, 4, NULL);
filesizes[i] = DecodeInt(temp);
if (!(header.args & (BIT((7 - i)))))
continue;
gfx_printf("Extracting %s\n", filenames[i]);
gen_part(header.sizes[i], &in, fsutil_getnextloc(outfolder, filenames[i]));
}
gfx_printf("Version: %s\n\n", version);
// Loop to copy pkg2_1->2 and pkg2_3->4
for (int i = 4; i < 6; i++){
if (!(header.args & BIT((9 - i))))
continue;
if (args & BOOT0_ARG){
gfx_printf("\nExtracting BOOT0\n");
gen_part(filesizes[0], &in, fsutil_getnextloc(outfolder, "BOOT0.bin"));
}
if (args & BOOT1_ARG){
gfx_printf("Extracting BOOT1\n");
gen_part(filesizes[1], &in, fsutil_getnextloc(outfolder, "BOOT1.bin"));
}
if (args & BCPKG2_1_ARG){
utils_copystring(fsutil_getnextloc(outfolder, "BCPKG2-1-Normal-Main"), &tempPath);
gfx_printf("Extracting BCPKG2_1/2\n");
gen_part(filesizes[2], &in, tempPath);
fsact_copy(tempPath, fsutil_getnextloc(outfolder, "BCPKG2-2-Normal-Sub"), COPY_MODE_PRINT);
RESETCOLOR;
free(tempPath);
}
if (args & BCPKG2_3_ARG){
utils_copystring(fsutil_getnextloc(outfolder, "BCPKG2-3-SafeMode-Main"), &tempPath);
gfx_printf("Extracting BCPKG2_3/4\n");
gen_part(filesizes[3], &in, tempPath);
fsact_copy(tempPath, fsutil_getnextloc(outfolder, "BCPKG2-4-SafeMode-Sub"), COPY_MODE_PRINT);
utils_copystring(fsutil_getnextloc(outfolder, filenames[i - 2]), &tempPath);
gfx_printf("Copying %s\n", filenames[i]);
fsact_copy(tempPath, fsutil_getnextloc(outfolder, filenames[i]), COPY_MODE_PRINT);
RESETCOLOR;
free(tempPath);
}

View File

@@ -2,6 +2,14 @@
#include "../common/types.h"
#include "../../utils/types.h"
typedef struct {
u8 version[0x10];
u8 args;
u32 sizes[4];
} __attribute__((__packed__)) BisFile;
#define FLIPU32(in) ((in >> 24) & 0xFF) | ((in >> 8) & 0xFF00) | ((in << 8) & 0xFF0000) | ((in << 24) & 0xFF000000)
char *fsutil_getnextloc(const char *current, const char *add);
char *fsutil_getprevloc(char *current);
bool fsutil_checkfile(char* path);

View File

@@ -0,0 +1,123 @@
#include "savesign.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../sec/se.h"
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../../config/ini.h"
#include "../common/common.h"
#include <string.h>
bool save_commit(const char *path, u8 *save_mac_key){
FIL file;
int res;
u8 *buf, hash[0x20], *cmac_data, cmac[0x10];
const u32 hashed_data_size = 0x3D00, cmac_data_size = 0x200;
bool success = false;
buf = malloc(hashed_data_size);
cmac_data = malloc(cmac_data_size);
if ((res = f_open(&file, path, FA_OPEN_EXISTING | FA_READ | FA_WRITE))){
gfx_errDisplay("save_commit", res, 1);
goto out_free;
}
f_lseek(&file, 0x300);
if ((res = f_read(&file, buf, hashed_data_size, NULL))){
gfx_errDisplay("save_commit", res, 2);
goto out_free;
}
se_calc_sha256(hash, buf, hashed_data_size);
f_lseek(&file, 0x108);
if ((res = f_write(&file, hash, sizeof(hash), NULL))){
gfx_errDisplay("save_commit", res, 3);
goto out_free;
}
f_lseek(&file, 0x100);
if ((res = f_read(&file, cmac_data, cmac_data_size, NULL))){
gfx_errDisplay("save_commit", res, 4);
goto out_free;
}
se_aes_key_set(3, save_mac_key, 0x10);
se_aes_cmac(3, cmac, 0x10, cmac_data, cmac_data_size);
f_lseek(&file, 0);
if ((res = f_write(&file, cmac, sizeof(cmac), NULL))){
gfx_errDisplay("save_commit", res, 5);
goto out_free;
}
success = true;
out_free:;
free(buf);
free(cmac_data);
f_close(&file);
return success;
}
char *getKey(const char *search, link_t *inilist){
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, inilist, link){
if (ini_sec->type == INI_CHOICE){
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{
if (!strcmp(search, kv->key))
return kv->val;
}
}
}
return NULL;
}
u8 getHexSingle(const char c) {
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
}
u8 *getHex(const char *in){
u32 len = strlen(in), count = 0;
u8 *out = calloc(len / 2, sizeof(u8));
for (u32 i = 0; i < len; i += 2){
out[count++] = (u8)(getHexSingle(in[i]) << 4) | (getHexSingle(in[i + 1]));
}
return out;
}
bool save_sign(const char *keypath, const char *savepath){
LIST_INIT(inilist);
char *key;
u8 *hex;
bool success = false;
if (!ini_parse(&inilist, keypath, false)){
gfx_errDisplay("save_sign", ERR_INI_PARSE_FAIL, 1);
goto out_free;
}
if ((key = getKey("save_mac_key", &inilist)) == NULL){
gfx_errDisplay("save_sign", ERR_INI_PARSE_FAIL, 2);
goto out_free;
}
hex = getHex(key);
if (!save_commit(savepath, hex))
goto out_free;
success = true;
out_free:;
list_empty(&inilist);
return success;
}

View File

@@ -0,0 +1,4 @@
#pragma once
#include "../../utils/types.h"
bool save_sign(const char *keypath, const char *savepath);

View File

@@ -23,7 +23,7 @@ void gfx_clearscreen(){
gfx_boxGrey(0, 703, 1279, 719, 0xFF);
gfx_boxGrey(0, 0, 1279, 15, 0xFF);
gfx_con_setpos(0, 0);
gfx_printf("Tegraexplorer v2.0.1 | Battery: %3d%%\n", battery >> 8);
gfx_printf("Tegraexplorer v2.0.2 | Battery: %3d%%\n", battery >> 8);
RESETCOLOR;
}
@@ -52,7 +52,7 @@ u32 gfx_errDisplay(const char *src_func, int err, int loc){
if (err < 15)
gfx_printf("Desc: %s\n", utils_err_codes[err]);
else if (err >= ERR_SAME_LOC && err <= ERR_NO_DESTINATION)
else if (err >= ERR_SAME_LOC && err <= ERR_IN_FUNC)
gfx_printf("Desc: %s\n", utils_err_codes_te[err - 50]);
if (loc)

View File

@@ -167,8 +167,8 @@ int menu_make(menu_entry *entries, int amount, const char *toptext){
while (hidRead()->buttons & (KEY_B | KEY_A));
input->buttons = 0;
while (!(input->buttons & (KEY_A | KEY_LDOWN | KEY_LUP | KEY_B | KEY_RUP | KEY_RDOWN))){
scrolltimer = get_tmr_ms();
while (1){
if (sd_inited && !!gpio_read(GPIO_PORT_Z, GPIO_PIN_1)){
gfx_errDisplay("menu", ERR_SD_EJECTED, 0);
sd_unmount();
@@ -177,33 +177,39 @@ int menu_make(menu_entry *entries, int amount, const char *toptext){
input = hidRead();
if (!(input->buttons & (KEY_A | KEY_LDOWN | KEY_LUP | KEY_B | KEY_RUP | KEY_RDOWN)))
if (!(input->buttons & (KEY_A | KEY_LDOWN | KEY_LUP | KEY_B | KEY_RUP | KEY_RDOWN))){
delay = 300;
if (delay < 300){
scrolltimer = get_tmr_ms();
while (input->buttons & (KEY_A | KEY_LDOWN | KEY_LUP | KEY_B | KEY_RUP | KEY_RDOWN)){
if (scrolltimer + delay <= get_tmr_ms())
break;
input = hidRead();
}
continue;
}
if (delay > 46 && input->buttons & (KEY_A | KEY_LDOWN | KEY_LUP | KEY_B | KEY_RUP | KEY_RDOWN))
delay -= 45;
if (input->buttons & (KEY_RUP | KEY_RDOWN))
if (input->buttons & (KEY_RDOWN | KEY_RUP)){
delay = 1;
input->Lup = input->Rup;
input->Ldown = input->Rdown;
}
if (delay < 300){
if (scrolltimer + delay < get_tmr_ms()){
break;
}
}
else {
break;
}
}
if (input->buttons & (KEY_LUP | KEY_RUP) && currentpos >= 1){
if (delay > 46)
delay -= 45;
if (input->Lup && currentpos >= 1){
currentpos--;
while(entries[currentpos].property & (ISSKIP | ISHIDE) && currentpos >= 1)
currentpos--;
}
else if (input->buttons & (KEY_LDOWN | KEY_RDOWN) && currentpos < amount - 1){
else if (input->Ldown && currentpos < amount - 1){
currentpos++;
while(entries[currentpos].property & (ISSKIP | ISHIDE) && currentpos < amount - 1)
currentpos++;

View File

@@ -37,24 +37,12 @@ void MainMenu_SDCard(){
void MainMenu_EMMC(){
if (gfx_defaultWaitMenu("You're about to enter EMMC\nModifying anything here can result in a BRICK!\n\nPlease only continue if you know what you're doing", 4)){
/*
connect_mmc(SYSMMC);
if (!mount_mmc(emmc_fs_entries[res - 2], res - 1))
fileexplorer("emmc:/", 1);
*/
makeMmcMenu(SYSMMC);
}
}
void MainMenu_EMUMMC(){
/*
connect_mmc(EMUMMC);
if (!mount_mmc(emmc_fs_entries[res - 5], res - 4))
fileexplorer("emmc:/", 1);
*/
makeMmcMenu(EMUMMC);
makeMmcMenu(EMUMMC);
}
void MainMenu_MountSD(){
@@ -62,8 +50,7 @@ void MainMenu_MountSD(){
}
void MainMenu_Tools(){
//res = makemenu(toolsmenu, 8);
res = menu_make(mainmenu_tools, 5, "-- Tools Menu --");
res = menu_make(mainmenu_tools, 4, "-- Tools Menu --");
switch(res){
case TOOLS_DISPLAY_INFO:
@@ -71,21 +58,14 @@ void MainMenu_Tools(){
break;
case TOOLS_DISPLAY_GPIO:
displaygpio();
//makeMmcMenu(SYSMMC);
break;
case TOOLS_DUMPFIRMWARE:
dumpfirmware(SYSMMC);
break;
case TOOLS_DUMPUSERSAVE:
if ((res = utils_mmcMenu()) > 0)
dumpusersaves(res);
break;
}
}
void MainMenu_SDFormat(){
//res = makemenu(formatmenu, 4);
res = menu_make(mainmenu_format, 3, "-- Format Menu --");
if (res > 0){

View File

@@ -74,14 +74,14 @@ int part_printf(){
if (argv[i][0] == '@'){
int toprintint;
if (parseIntInput(argv[i], &toprintint))
return -1;
return INFUNC_FAIL;
gfx_printf("%d", toprintint);
}
else {
char *toprintstring;
if (parseStringInput(argv[i], &toprintstring))
return -1;
return INFUNC_FAIL;
gfx_printf(toprintstring);
}
@@ -94,7 +94,7 @@ int part_printf(){
int part_print_int(){
int toprint;
if (parseIntInput(argv[0], &toprint))
return -1;
return INFUNC_FAIL;
SWAPCOLOR(currentcolor);
gfx_printf("%s: %d\n", argv[0], toprint);
@@ -107,7 +107,7 @@ int part_Wait(){
SWAPCOLOR(currentcolor);
if (parseIntInput(argv[0], &arg))
return -1;
return INFUNC_FAIL;
begintime = get_tmr_s();
@@ -122,9 +122,9 @@ int part_Wait(){
int part_Check(){
int left, right;
if (parseIntInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseIntInput(argv[2], &right))
return -1;
return INFUNC_FAIL;
if (!strcmp(argv[1], "=="))
return (left == right);
@@ -139,13 +139,13 @@ int part_Check(){
else if (!strcmp(argv[1], "<"))
return (left < right);
else
return -1;
return INFUNC_FAIL;
}
int part_if(){
int condition;
if (parseIntInput(argv[0], &condition))
return -1;
return INFUNC_FAIL;
getfollowingchar('{');
@@ -167,7 +167,7 @@ int part_if(){
int part_if_args(){
int condition;
if ((condition = part_Check()) < 0)
return -1;
return INFUNC_FAIL;
getfollowingchar('{');
@@ -180,9 +180,9 @@ int part_if_args(){
int part_Math(){
int left, right;
if (parseIntInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseIntInput(argv[2], &right))
return -1;
return INFUNC_FAIL;
switch (argv[1][0]){
case '+':
@@ -194,7 +194,7 @@ int part_Math(){
case '/':
return left / right;
}
return -1;
return INFUNC_FAIL;
}
int part_SetInt(){
@@ -206,9 +206,9 @@ int part_SetInt(){
int part_SetString(){
char *arg0;
if (parseStringInput(argv[0], &arg0))
return -1;
return INFUNC_FAIL;
if (argv[1][0] != '$')
return -1;
return INFUNC_FAIL;
str_str_add(argv[1], arg0);
return 0;
@@ -218,11 +218,11 @@ int part_SetStringIndex(){
int index;
char *out;
if (parseIntInput(argv[0], &index))
return -1;
return INFUNC_FAIL;
if (argv[1][0] != '$')
return -1;
return INFUNC_FAIL;
if (str_str_index(index, &out))
return -1;
return INFUNC_FAIL;
str_str_add(argv[1], out);
return 0;
@@ -231,7 +231,10 @@ int part_SetStringIndex(){
int part_goto(){
int target = 0;
if (parseIntInput(argv[0], &target))
return -1;
return INFUNC_FAIL;
str_int_add("@RETURN", (int)f_tell(&scriptin));
f_lseek(&scriptin, target);
return 0;
}
@@ -239,14 +242,14 @@ int part_goto(){
int part_invert(){
int arg;
if (parseIntInput(argv[0], &arg))
return -1;
return INFUNC_FAIL;
return (arg) ? 0 : 1;
}
int part_fs_exists(){
char *path;
if (parseStringInput(argv[0], &path))
return -1;
return INFUNC_FAIL;
return fsutil_checkfile(path);
}
@@ -260,7 +263,7 @@ int part_ConnectMMC(){
else if (!strcmp(arg, "EMUMMC"))
connect_mmc(EMUMMC);
else
return -1;
return INFUNC_FAIL;
return 0;
}
@@ -292,11 +295,11 @@ int part_Pause(){
int part_addstrings(){
char *combined, *left, *middle;
if (parseStringInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseStringInput(argv[1], &middle))
return -1;
return INFUNC_FAIL;
if (argv[2][0] != '$')
return -1;
return INFUNC_FAIL;
combined = calloc(strlen(left) + strlen(middle) + 1, sizeof(char));
sprintf(combined, "%s%s", left, middle);
@@ -309,7 +312,7 @@ int part_addstrings(){
int part_setColor(){
char *arg;
if (parseStringInput(argv[0], &arg))
return -1;
return INFUNC_FAIL;
if (!strcmp(arg, "RED"))
currentcolor = COLOR_RED;
@@ -326,7 +329,7 @@ int part_setColor(){
else if (!strcmp(arg, "WHITE"))
currentcolor = COLOR_WHITE;
else
return -1;
return INFUNC_FAIL;
return 0;
}
@@ -340,9 +343,9 @@ int part_fs_Move(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return -1;
return INFUNC_FAIL;
int res;
res = f_rename(left, right);
@@ -356,7 +359,7 @@ int part_fs_Delete(){
char *arg;
if (parseStringInput(argv[0], &arg))
return -1;
return INFUNC_FAIL;
int res;
res = f_unlink(arg);
@@ -370,7 +373,7 @@ int part_fs_DeleteRecursive(){
char *arg;
if (parseStringInput(argv[0], &arg))
return -1;
return INFUNC_FAIL;
return fsact_del_recursive(arg);
}
@@ -379,9 +382,9 @@ int part_fs_Copy(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return -1;
return INFUNC_FAIL;
return fsact_copy(left, right, COPY_MODE_PRINT);
}
@@ -390,9 +393,9 @@ int part_fs_CopyRecursive(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return -1;
return INFUNC_FAIL;
return fsact_copy_recursive(left, right);
}
@@ -401,7 +404,7 @@ int part_fs_MakeDir(){
char *arg;
if (parseStringInput(argv[0], &arg))
return -1;
return INFUNC_FAIL;
int res;
res = f_mkdir(arg);
@@ -418,10 +421,10 @@ int part_fs_OpenDir(){
char *path;
if (parseStringInput(argv[0], &path))
return -1;
return INFUNC_FAIL;
if (f_opendir(&dir, path))
return -1;
return INFUNC_FAIL;
isdirvalid = true;
str_int_add("@ISDIRVALID", isdirvalid);
@@ -440,7 +443,7 @@ int part_fs_CloseDir(){
int part_fs_ReadDir(){
if (!isdirvalid)
return -1;
return INFUNC_FAIL;
if (!f_readdir(&dir, &fno) && fno.fname[0]){
str_str_add("$FILENAME", fno.fname);
@@ -457,16 +460,16 @@ int part_setPrintPos(){
int left, right;
if (parseIntInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseIntInput(argv[1], &right))
return -1;
return INFUNC_FAIL;
if (left > 78)
return -1;
return INFUNC_FAIL;
if (right > 42)
return -1;
return INFUNC_FAIL;
gfx_con_setpos(left * 16, right * 16);
return 0;
@@ -476,9 +479,9 @@ int part_stringcompare(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return -1;
return INFUNC_FAIL;
return (strcmp(left, right)) ? 0 : 1;
}
@@ -486,11 +489,11 @@ int part_stringcompare(){
int part_fs_combinePath(){
char *combined, *left, *middle;
if (parseStringInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseStringInput(argv[1], &middle))
return -1;
return INFUNC_FAIL;
if (argv[2][0] != '$')
return -1;
return INFUNC_FAIL;
combined = fsutil_getnextloc(left, middle);
@@ -503,9 +506,9 @@ int part_mmc_dumpPart(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
return INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return -1;
return INFUNC_FAIL;
if (!strcmp(left, "BOOT")){
return emmcDumpBoot(right);
@@ -519,21 +522,21 @@ int part_mmc_restorePart(){
char *path;
if (parseStringInput(argv[0], &path))
return -1;
return INFUNC_FAIL;
if (currentlyMounted < 0)
return -1;
return INFUNC_FAIL;
return mmcFlashFile(path, currentlyMounted);
return mmcFlashFile(path, currentlyMounted, false);
}
int part_fs_extractBisFile(){
char *path, *outfolder;
if (parseStringInput(argv[0], &path))
return -1;
return INFUNC_FAIL;
if (parseStringInput(argv[1], &outfolder))
return -1;
return INFUNC_FAIL;
return extract_bis_file(path, outfolder);
}
@@ -547,6 +550,8 @@ int part_getPos(){
return (int)f_tell(&scriptin);
}
str_fnc_struct functions[] = {
{"printf", part_printf, 255},
{"printInt", part_print_int, 1},
@@ -596,8 +601,8 @@ int run_function(char *func_name, int *out){
continue;
*out = functions[i].value();
return (*out < 0) ? -1 : 0;
return (*out == INFUNC_FAIL) ? -1 : 0;
}
}
return -1;
return -2;
}

View File

@@ -220,7 +220,16 @@ void mainparser(){
printerrors = true;
//gfx_printf("%s|%s|%d", funcbuff, argv[0], argc);
//btn_wait();
gfx_errDisplay("mainparser", ERR_PARSE_FAIL, f_tell(&scriptin));
int lineNumber = 1;
u64 end = f_tell(&scriptin);
f_lseek(&scriptin, 0);
while (f_tell(&scriptin) < end && !f_eof(&scriptin)){
if (getnextchar() == '\n')
lineNumber++;
}
gfx_errDisplay((res == -1) ? funcbuff : "run_function", (res == -1) ? ERR_IN_FUNC : ERR_SCRIPT_LOOKUP_FAIL, lineNumber);
forceExit = true;
//gfx_printf("Func: %s\nArg1: %s\n", funcbuff, argv[0]);
}
@@ -277,7 +286,9 @@ void runScript(char *path){
gfx_clearscreen();
utils_copystring(path, &path_local);
res = f_open(&scriptin, path, FA_READ | FA_OPEN_EXISTING);
DWORD *clmt_in = f_expand_cltbl(&scriptin, BUFSIZE / 4, 0);
if (res != FR_OK){
gfx_errDisplay("ParseScript", res, 1);
return;

View File

@@ -1,5 +1,7 @@
#pragma once
#define INFUNC_FAIL (int)0xC0000000
void runScript(char *path);
void skipbrackets();
void getfollowingchar(char end);

View File

@@ -159,7 +159,7 @@ int dumpfirmware(int mmc){
return fail;
}
/*
void dumpusersaves(int mmc){
connect_mmc(mmc);
mount_mmc("USER", 2);
@@ -180,6 +180,7 @@ void dumpusersaves(int mmc){
gfx_printf("Press any key to continue");
hidWait();
}
*/
int format(int mode){
gfx_clearscreen();

View File

@@ -4,4 +4,3 @@ void displayinfo();
void displaygpio();
int format(int mode);
int dumpfirmware(int mmc);
void dumpusersaves(int mmc);