Compare commits

..

58 Commits
1.3.2 ... 1.5.2

Author SHA1 Message Date
Such Meme, Many Skill
adc9d2e5bf Bump version 2020-04-26 01:28:11 +02:00
Such Meme, Many Skill
317e4b2038 Reduce file size + cleanup + add coreboot.rom file booting 2020-04-26 01:20:26 +02:00
Such Meme, Many Skill
bd99e2a138 Optimise screen scroll a bit, Edit display of filesizes 2020-04-23 14:40:55 +02:00
Such Meme, Many Skill
4c4a6511f3 Merge hekate changes
25ff127404
2020-04-23 13:54:48 +02:00
Such Meme, Many Skill
2bbcf63bd9 Fix restore% on e(mu)mmc partition restores 2020-04-23 13:40:29 +02:00
Such Meme, Many Skill
78722d9a90 Fix calc bug in partition size calculation 2020-04-22 12:23:18 +02:00
Such Meme, Many Skill
e24f8ad722 [Script] Make printf accept multiple args 2020-04-15 22:02:19 +02:00
Such Meme, Many Skill
28fb01b155 See pkg1 version on biskey dump failure 2020-04-14 10:25:31 +02:00
Such Meme, Many Skill
b8b37e78ba Hotfix for 10.0.0 2020-04-14 09:40:37 +02:00
Such Meme, Many Skill
82a4d03985 Bump version 2020-04-12 22:22:40 +02:00
Such Meme, Many Skill
195d9797fe Add that inside functions no "" are required for <=>+-/* 2020-04-12 20:31:32 +02:00
Such Meme, Many Skill
15e1210179 [script] Remove jump list & add if_check that works like if(check()) 2020-04-12 19:21:09 +02:00
Such Meme, Many Skill
e892e69929 don't hardcode locations where info should be parsed from 2020-04-08 17:33:34 +02:00
Such Meme, Many Skill
7e8e3ece66 [Script] Add clearscreen 2020-04-05 22:01:07 +02:00
Such Meme, Many Skill
b5a9d94d35 Bump version
+ Bugfix
2020-04-05 17:25:35 +02:00
Such Meme, Many Skill
f95b6e399f Bugfix + add fs_extractBisFile (to scripts) 2020-04-05 17:07:11 +02:00
Such Meme, Many Skill
6551930233 cleanup of mmc restores/dumps 2020-04-05 16:07:25 +02:00
suchmememanyskill
c2a2694baf Merge pull request #13 from suchmememanyskill/dynamic_mmc_mounting
Dynamic mmc mounting
2020-04-05 00:38:02 +02:00
Such Meme, Many Skill
03df13f34c don't forget to reset the clipboard helper 2020-04-05 00:33:12 +02:00
Such Meme, Many Skill
070f9c676d Bugfixes + relocate tools: dump bis 2020-04-05 00:22:23 +02:00
Such Meme, Many Skill
7dc3500a17 [script] add mmc_dumpPart() and mmc_restorePart() 2020-04-04 23:41:09 +02:00
Such Meme, Many Skill
97bbe2a333 Add partition restoring via clipboard 2020-04-04 22:15:13 +02:00
Such Meme, Many Skill
a6eaa1ec51 Implement dumping of partitions 2020-04-04 18:40:27 +02:00
Such Meme, Many Skill
f93cc0ff44 Get a basic gpt menu 2020-04-04 16:49:47 +02:00
suchmememanyskill
ee145ca9aa Merge pull request #11 from suchmememanyskill/script-rewrite
Finish script rewrite
2020-04-03 19:24:22 +02:00
Such Meme, Many Skill
8832b240a4 Add fs_combinePath() 2020-04-03 19:07:42 +02:00
Such Meme, Many Skill
744f90611a Fix commas causing issues, fix some freeze cases 2020-04-01 23:44:28 +02:00
Such Meme, Many Skill
440a921980 small fixes 2020-04-01 19:43:37 +02:00
Such Meme, Many Skill
d0799e3cd1 Rename some variables 2020-04-01 16:48:36 +02:00
Such Meme, Many Skill
5b32937f8f add stringcompare function, fix some returns 2020-04-01 16:37:32 +02:00
Such Meme, Many Skill
f438827263 add more functions 2020-04-01 13:57:25 +02:00
Such Meme, Many Skill
0e60746179 Add fs functions: Rewrite should be done 2020-04-01 00:41:55 +02:00
Such Meme, Many Skill
0e39c8dda9 add more functions 2020-04-01 00:17:45 +02:00
Such Meme, Many Skill
45a732c388 add functions, fix bugs 2020-03-31 22:01:20 +02:00
Such Meme, Many Skill
034384622f Add strings 2020-03-31 20:13:39 +02:00
Such Meme, Many Skill
9efbbc9317 Add functions, Add goto's 2020-03-31 17:58:09 +02:00
Such Meme, Many Skill
30afcddd3a more functions, cleanup and simple error checking 2020-03-31 15:34:19 +02:00
Such Meme, Many Skill
38f349618f Add functions and int vars 2020-03-31 14:24:34 +02:00
Such Meme, Many Skill
33a64abfb0 Small fixes 2020-03-31 00:16:46 +02:00
Such Meme, Many Skill
c4783fc2ca Cleanup 2020-03-31 00:09:23 +02:00
Such Meme, Many Skill
887972d67c Add arg recognition + more command reading 2020-03-30 22:40:59 +02:00
Such Meme, Many Skill
9aff029ee4 Start script rewrite 2020-03-30 20:15:07 +02:00
Such Meme, Many Skill
bfcdc2ffd5 Ignore menu entries in entries count and include sd ejection detection 2020-03-22 22:56:36 +01:00
Such Meme, Many Skill
e4ae9d9d7c (untested) should hide errors in scripts 2020-03-21 20:31:22 +01:00
Such Meme, Many Skill
d255dcf665 Cleanup 2020-03-19 23:01:30 +01:00
Such Meme, Many Skill
f1a4b05524 Bump version 2020-03-19 16:19:56 +01:00
Such Meme, Many Skill
d5c23ebf96 Reorder BIS menu options 2020-03-19 16:17:36 +01:00
Such Meme, Many Skill
4e1368faaf Re-implement bis restoring 2020-03-19 16:11:18 +01:00
Such Meme, Many Skill
2d6411f60a Add more general error codes & re-implement bis dumping 2020-03-19 13:00:42 +01:00
Such Meme, Many Skill
7191743f5d Reorganise emmc.c/h and rename main menu c file 2020-03-19 00:11:18 +01:00
Such Meme, Many Skill
9d36f741d9 Day2 of restructuring/rewriting 2020-03-18 23:58:32 +01:00
Such Meme, Many Skill
ff618bc285 Move over script and tools 2020-03-18 12:18:39 +01:00
Such Meme, Many Skill
c60eb4b722 Fix compile error, oops 2020-03-18 00:58:23 +01:00
Such Meme, Many Skill
6aed4ad7b3 Start gfx rewrite & reorganize TE 2020-03-18 00:41:09 +01:00
Such Meme, Many Skill
761ceb7dbe Misc changes 2020-03-17 00:26:35 +01:00
Such Meme, Many Skill
3f6d1b532c (Attempt at) Implement restoring bis
1 switch was harmed in the making of this commit
2020-03-15 12:35:18 +01:00
Such Meme, Many Skill
144dc3a3f5 Implement bis dumping 2020-03-14 15:03:08 +01:00
Such Meme, Many Skill
5cb50722cf [Scripting] Add CheckPath command 2020-03-11 21:01:57 +01:00
74 changed files with 4061 additions and 1840 deletions

View File

@@ -10,7 +10,7 @@ include $(DEVKITARM)/base_rules
IPL_LOAD_ADDR := 0x40003000
LPVERSION_MAJOR := 2
LPVERSION_MINOR := 3
LPVERSION_MINOR := 5
LPVERSION_BUGFX := 2
################################################################################

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -37,12 +37,12 @@ void set_default_configuration()
h_cfg.autoboot = 0;
h_cfg.autoboot_list = 0;
h_cfg.bootwait = 3;
h_cfg.verification = 1;
h_cfg.se_keygen_done = 0;
h_cfg.sbar_time_keeping = 0;
h_cfg.backlight = 100;
h_cfg.autohosoff = 0;
h_cfg.autonogc = 1;
h_cfg.updater2p = 0;
h_cfg.brand = NULL;
h_cfg.tagline = NULL;
h_cfg.errors = 0;
@@ -50,7 +50,7 @@ void set_default_configuration()
h_cfg.rcm_patched = true;
h_cfg.emummc_force_disable = false;
sd_power_cycle_time_start = 0xFFFFFFF;
sd_power_cycle_time_start = 0;
}
int create_config_entry()
@@ -96,9 +96,6 @@ int create_config_entry()
f_puts("\nbootwait=", &fp);
itoa(h_cfg.bootwait, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\nverification=", &fp);
itoa(h_cfg.verification, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\nbacklight=", &fp);
itoa(h_cfg.backlight, lbuf, 10);
f_puts(lbuf, &fp);
@@ -108,6 +105,9 @@ int create_config_entry()
f_puts("\nautonogc=", &fp);
itoa(h_cfg.autonogc, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\nupdater2p=", &fp);
itoa(h_cfg.updater2p, lbuf, 10);
f_puts(lbuf, &fp);
if (h_cfg.brand)
{
f_puts("\nbrand=", &fp);
@@ -281,10 +281,11 @@ void config_autoboot()
LIST_INIT(ini_sections);
u8 max_entries = 30;
u32 boot_text_size = 512;
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 5));
u32 *boot_values = (u32 *)malloc(sizeof(u32) * max_entries);
char *boot_text = (char *)malloc(512 * max_entries);
char *boot_text = (char *)malloc(boot_text_size * max_entries);
for (u32 j = 0; j < max_entries; j++)
boot_values[j] = j;
@@ -330,12 +331,12 @@ void config_autoboot()
else
{
if (h_cfg.autoboot != (i - 4) || h_cfg.autoboot_list)
boot_text[(i - 4) * 512] = ' ';
boot_text[(i - 4) * boot_text_size] = ' ';
else
boot_text[(i - 4) * 512] = '*';
strcpy(boot_text + (i - 4) * 512 + 1, ini_sec->name);
ments[i].caption = &boot_text[(i - 4) * 512];
boot_text[(i - 4) * boot_text_size] = '*';
strcpy(boot_text + (i - 4) * boot_text_size + 1, ini_sec->name);
ments[i].caption = &boot_text[(i - 4) * boot_text_size];
}
ments[i].type = ini_sec->type;
ments[i].data = &boot_values[i - 4];
@@ -391,10 +392,11 @@ void config_bootdelay()
gfx_con_setpos(0, 0);
u32 delay_entries = 6;
u32 delay_text_size = 32;
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (delay_entries + 3));
u32 *delay_values = (u32 *)malloc(sizeof(u32) * delay_entries);
char *delay_text = (char *)malloc(32 * delay_entries);
char *delay_text = (char *)malloc(delay_text_size * delay_entries);
for (u32 j = 0; j < delay_entries; j++)
delay_values[j] = j;
@@ -415,14 +417,14 @@ void config_bootdelay()
for (i = 1; i < delay_entries; i++)
{
if (h_cfg.bootwait != i)
delay_text[i * 32] = ' ';
delay_text[i * delay_text_size] = ' ';
else
delay_text[i * 32] = '*';
delay_text[i * 32 + 1] = i + '0';
strcpy(delay_text + i * 32 + 2, " seconds");
delay_text[i * delay_text_size] = '*';
delay_text[i * delay_text_size + 1] = i + '0';
strcpy(delay_text + i * delay_text_size + 2, " seconds");
ments[i + 2].type = MENT_DATA;
ments[i + 2].caption = delay_text + i * 32;
ments[i + 2].caption = delay_text + (i * delay_text_size);
ments[i + 2].data = &delay_values[i];
}
@@ -445,69 +447,17 @@ void config_bootdelay()
btn_wait();
}
void config_verification()
{
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * 6);
u32 *vr_values = (u32 *)malloc(sizeof(u32) * 3);
char *vr_text = (char *)malloc(64 * 3);
for (u32 j = 0; j < 3; j++)
{
vr_values[j] = j;
ments[j + 2].type = MENT_DATA;
ments[j + 2].data = &vr_values[j];
}
ments[0].type = MENT_BACK;
ments[0].caption = "Back";
ments[1].type = MENT_CHGLINE;
strcpy(vr_text, " Disable (Fastest - Unsafe)");
strcpy(vr_text + 64, " Sparse (Fast - Safe)");
strcpy(vr_text + 128, " Full (Slow - Safe)");
for (u32 i = 0; i < 3; i++)
{
if (h_cfg.verification != i)
vr_text[64 * i] = ' ';
else
vr_text[64 * i] = '*';
ments[2 + i].caption = vr_text + (i * 64);
}
memset(&ments[5], 0, sizeof(ment_t));
menu_t menu = {ments, "Backup & Restore verification", 0, 0};
u32 *temp_verification = (u32 *)tui_do_menu(&menu);
if (temp_verification != NULL)
{
h_cfg.verification = *(u32 *)temp_verification;
_save_config();
}
free(ments);
free(vr_values);
free(vr_text);
if (temp_verification == NULL)
return;
btn_wait();
}
void config_backlight()
{
gfx_clear_grey(0x1B);
gfx_con_setpos(0, 0);
u32 bri_text_size = 8;
u32 bri_entries = 11;
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (bri_entries + 3));
u32 *bri_values = (u32 *)malloc(sizeof(u32) * bri_entries);
char *bri_text = (char *)malloc(8 * bri_entries);
char *bri_text = (char *)malloc(bri_text_size * bri_entries);
for (u32 j = 1; j < bri_entries; j++)
bri_values[j] = j * 10;
@@ -521,20 +471,20 @@ void config_backlight()
for (i = 1; i < bri_entries; i++)
{
if ((h_cfg.backlight / 20) != i)
bri_text[i * 32] = ' ';
bri_text[i * bri_text_size] = ' ';
else
bri_text[i * 32] = '*';
bri_text[i * bri_text_size] = '*';
if (i < 10)
{
bri_text[i * 32 + 1] = i + '0';
strcpy(bri_text + i * 32 + 2, "0%");
bri_text[i * bri_text_size + 1] = i + '0';
strcpy(bri_text + i * bri_text_size + 2, "0%");
}
else
strcpy(bri_text + i * 32 + 1, "100%");
strcpy(bri_text + i * bri_text_size + 1, "100%");
ments[i + 1].type = MENT_DATA;
ments[i + 1].caption = bri_text + i * 32;
ments[i + 1].caption = bri_text + (i * bri_text_size);
ments[i + 1].data = &bri_values[i];
}

View File

@@ -25,10 +25,10 @@ typedef struct _hekate_config
u32 autoboot;
u32 autoboot_list;
u32 bootwait;
u32 verification;
u32 backlight;
u32 autohosoff;
u32 autonogc;
u32 updater2p;
char *brand;
char *tagline;
// Global temporary config.
@@ -40,16 +40,10 @@ typedef struct _hekate_config
u32 errors;
} hekate_config;
typedef enum
{
ERR_LIBSYS_LP0 = (1 << 0),
} hsysmodule_t;
void set_default_configuration();
int create_config_entry();
void config_autoboot();
void config_bootdelay();
void config_verification();
void config_backlight();
void config_auto_hos_poweroff();
void config_nogc();

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -44,7 +44,8 @@ static char *_strdup(char *str)
u32 _find_section_name(char *lbuf, u32 lblen, char schar)
{
u32 i;
for (i = 0; i < lblen && lbuf[i] != schar && lbuf[i] != '\n' && lbuf[i] != '\r'; i++)
// Depends on 'FF_USE_STRFUNC 2' that removes \r.
for (i = 0; i < lblen && lbuf[i] != schar && lbuf[i] != '\n'; i++)
;
lbuf[i] = 0;
@@ -123,8 +124,8 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
f_gets(lbuf, 512, &fp);
lblen = strlen(lbuf);
// Remove trailing newline.
if (lbuf[lblen - 1] == '\n' || lbuf[lblen - 1] == '\r')
// Remove trailing newline. Depends on 'FF_USE_STRFUNC 2' that removes \r.
if (lblen && lbuf[lblen - 1] == '\n')
lbuf[lblen - 1] = 0;
if (lblen > 2 && lbuf[0] == '[') // Create new section.
@@ -134,24 +135,22 @@ int ini_parse(link_t *dst, char *ini_path, bool is_dir)
csec = _ini_create_section(dst, csec, &lbuf[1], INI_CHOICE);
list_init(&csec->kvs);
}
else if (lblen > 2 && lbuf[0] == '{') //Create new caption.
else if (lblen > 1 && lbuf[0] == '{') // Create new caption. Support empty caption '{}'.
{
_find_section_name(lbuf, lblen, '}');
csec = _ini_create_section(dst, csec, &lbuf[1], INI_CAPTION);
csec->color = 0xFF0AB9E6;
}
else if (lblen > 2 && lbuf[0] == '#') //Create empty lines and comments.
else if (lblen > 2 && lbuf[0] == '#') // Create comment.
{
_find_section_name(lbuf, lblen, '\0');
csec = _ini_create_section(dst, csec, &lbuf[1], INI_COMMENT);
}
else if (lblen < 2)
else if (lblen < 2) // Create empty line.
{
csec = _ini_create_section(dst, csec, NULL, INI_NEWLINE);
}
else if (csec && csec->type == INI_CHOICE) //Extract key/value.
else if (csec && csec->type == INI_CHOICE) // Extract key/value.
{
u32 i = _find_section_name(lbuf, lblen, '=');

View File

@@ -269,6 +269,12 @@ void gfx_putc(char c)
if (gfx_con.y > gfx_ctxt.height - 8)
gfx_con.y = 0;
}
else if (c == '\e')
gfx_con.x = 672;
else if (c == '\a')
gfx_con.x = 608;
else if (c == '\r')
gfx_con.x = 0;
break;
}
@@ -513,11 +519,17 @@ void gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos
}
}
void gfx_boxGrey(int x0, int y0, int x1, int y1, u8 shade){
for (int y = y0; y <= y1; y++){
memset(gfx_ctxt.fb + y * gfx_ctxt.stride + x0, shade, (x1 - x0) * 4);
}
}
void gfx_box(int x0, int y0, int x1, int y1, u32 color){
int i = y0;
while(y1 >= i){
gfx_line(x0, i, x1, i, color);
i++;
for (int x = x0; x < x1 + 1; x++){
for (int y = y0; y < y1 + 1; y++){
gfx_set_pixel(x, y, color);
}
}
}

View File

@@ -50,6 +50,7 @@ void gfx_set_rect_rgb(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_
void gfx_set_rect_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
void gfx_render_bmp_argb(const u32 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos_y);
void gfx_box(int x0, int y0, int x1, int y1, u32 color);
void gfx_boxGrey(int x0, int y0, int x1, int y1, u8 shade);
// Global gfx console and context.
gfx_ctxt_t gfx_ctxt;

View File

@@ -42,6 +42,7 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20190531152432", 8, {0x29c50, 0x6a73, 0, 8, 12, HASH_ORDER_700_9xx, 0x5563, 0x1d437} }, //8.1.0
{ "20190809135709", 9, {0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_9xx, 0x6495, 0x1d807} }, //9.0.0 - 9.0.1
{ "20191021113848", 10,{0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_9xx, 0x6495, 0x1d807} }, //9.1.0
{ "20200303104606", 11,{0x2ec10, 0x5573, 0, 1, 12, HASH_ORDER_700_9xx, 0x6495, 0x1d807} }, //10.0.0, May or may not be accurate. I just need to feed tsec anyway so this doesn't matter
{ NULL } //End.
};

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
@@ -41,14 +41,34 @@ static u32 _pkg2_calc_kip1_size(pkg2_kip1_t *kip1)
void pkg2_get_newkern_info(u8 *kern_data)
{
u32 info_op = *(u32 *)(kern_data + PKG2_NEWKERN_GET_INI1);
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + PKG2_NEWKERN_GET_INI1; // Parse ADR and PC.
u32 pkg2_newkern_ini1_off = 0;
pkg2_newkern_ini1_start = 0;
// Find static OP offset that is close to INI1 offset.
u32 counter_ops = 0x100;
while (counter_ops)
{
if (*(u32 *)(kern_data + 0x100 - counter_ops) == PKG2_NEWKERN_GET_INI1_HEURISTIC)
{
pkg2_newkern_ini1_off = 0x100 - counter_ops + 12; // OP found. Add 12 for the INI1 offset.
break;
}
counter_ops -= 4;
}
// Offset not found?
if (!counter_ops)
return;
u32 info_op = *(u32 *)(kern_data + pkg2_newkern_ini1_off);
pkg2_newkern_ini1_val = ((info_op & 0xFFFF) >> 3) + pkg2_newkern_ini1_off; // Parse ADR and PC.
pkg2_newkern_ini1_start = *(u32 *)(kern_data + pkg2_newkern_ini1_val);
pkg2_newkern_ini1_end = *(u32 *)(kern_data + pkg2_newkern_ini1_val + 0x8);
}
}
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
{
u8 *ptr;
// Check for new pkg2 type.
@@ -56,6 +76,9 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
{
pkg2_get_newkern_info(pkg2->data);
if (!pkg2_newkern_ini1_start)
return false;
ptr = pkg2->data + pkg2_newkern_ini1_start;
*new_pkg2 = true;
}
@@ -75,6 +98,8 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2)
ptr += ki->size;
DPRINTF(" kip1 %d:%s @ %08X (%08X)\n", i, kip1->name, (u32)kip1, ki->size);
}
return true;
}
int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp)

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (C) 2018-2019 CTCaer
* Copyright (C) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -26,7 +26,7 @@
#define PKG2_SEC_KERNEL 0
#define PKG2_SEC_INI1 1
#define PKG2_NEWKERN_GET_INI1 0x44
#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;
@@ -87,7 +87,7 @@ typedef struct _pkg2_kip1_info_t
link_t link;
} pkg2_kip1_info_t;
void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
bool pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
int pkg2_decompress_kip(pkg2_kip1_info_t* ki, u32 sectsToDecomp);
pkg2_hdr_t *pkg2_decrypt(void *data);

View File

@@ -38,27 +38,18 @@
#include "utils/dirlist.h"
#include "utils/sprintf.h"
#include "utils/util.h"
#include "tegraexplorer/te.h"
#include "tegraexplorer/mainmenu.h"
//#include "keys/keys.h"
sdmmc_t sd_sdmmc;
sdmmc_storage_t sd_storage;
__attribute__ ((aligned (16))) FATFS sd_fs;
static bool sd_mounted, sd_inited;
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;
bool return_sd_mounted(int value){
switch(value){
case 10:
return sd_inited;
default:
return sd_mounted;
}
}
bool sd_mount()
{
if (sd_mounted)
@@ -146,11 +137,13 @@ int sd_save_to_file(void *buf, u32 size, const char *filename)
#define PATCHED_RELOC_SZ 0x94
#define PATCHED_RELOC_STACK 0x40007000
#define PATCHED_RELOC_ENTRY 0x40010000
#define EXT_PAYLOAD_ADDR 0xC03C0000
#define EXT_PAYLOAD_ADDR 0xC0000000
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
#define COREBOOT_ADDR (0xD0000000 - 0x100000)
#define COREBOOT_END_ADDR 0xD0000000
#define CBFS_DRAM_EN_ADDR 0x4003e000
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM"
static void *coreboot_addr;
void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
{
@@ -165,7 +158,7 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
if (payload_size == 0x7000)
{
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock
memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), coreboot_addr, 0x7000); //Bootblock
*(vu32 *)CBFS_DRAM_EN_ADDR = CBFS_DRAM_MAGIC;
}
}
@@ -195,7 +188,10 @@ int launch_payload(char *path)
if (size < 0x30000)
buf = (void *)RCM_PAYLOAD_ADDR;
else
buf = (void *)COREBOOT_ADDR;
{
coreboot_addr = (void *)(COREBOOT_END_ADDR - size);
buf = coreboot_addr;
}
if (f_read(&fp, buf, size, NULL))
{
@@ -351,7 +347,7 @@ void dump_sysnand()
{
h_cfg.emummc_force_disable = true;
b_cfg.extra_cfg &= ~EXTRA_CFG_DUMP_EMUMMC;
dump_keys();
//dump_keys();
}
void dump_emunand()
@@ -360,7 +356,7 @@ void dump_emunand()
return;
emu_cfg.enabled = 1;
b_cfg.extra_cfg |= EXTRA_CFG_DUMP_EMUMMC;
dump_keys();
//dump_keys();
}
ment_t ment_top[] = {

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018 M4xw
*
* This program is free software; you can redistribute it and/or modify it
@@ -29,7 +30,7 @@ static void _heap_create(heap_t *heap, u32 start)
// Node info is before node address.
static u32 _heap_alloc(heap_t *heap, u32 size)
{
hnode_t *node, *new;
hnode_t *node, *new_node;
// Align to cache line size.
size = ALIGN(size, sizeof(hnode_t));
@@ -49,22 +50,29 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
node = heap->first;
while (true)
{
// Check if there's available unused node.
if (!node->used && (size <= node->size))
{
// Size and offset of the new unused node.
u32 new_size = node->size - size;
new = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + size);
// If there's aligned leftover space, create a new node.
// If there's aligned unused space from the old node,
// create a new one and set the leftover size.
if (new_size >= (sizeof(hnode_t) << 2))
{
new->size = new_size - sizeof(hnode_t);
new->used = 0;
new->next = node->next;
new->next->prev = new;
new->prev = node;
node->next = new;
new_node->size = new_size - sizeof(hnode_t);
new_node->used = 0;
new_node->next = node->next;
// Check that we are not on first node.
if (new_node->next)
new_node->next->prev = new_node;
new_node->prev = node;
node->next = new_node;
}
else
else // Unused node size is just enough.
size += new_size;
node->size = size;
@@ -72,20 +80,23 @@ static u32 _heap_alloc(heap_t *heap, u32 size)
return (u32)node + sizeof(hnode_t);
}
// No unused node found, try the next one.
if (node->next)
node = node->next;
else
break;
}
new = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
new->used = 1;
new->size = size;
new->prev = node;
new->next = NULL;
node->next = new;
// No unused node found, create a new one.
new_node = (hnode_t *)((u32)node + sizeof(hnode_t) + node->size);
new_node->used = 1;
new_node->size = size;
new_node->prev = node;
new_node->next = NULL;
node->next = new_node;
return (u32)new + sizeof(hnode_t);
return (u32)new_node + sizeof(hnode_t);
}
static void _heap_free(heap_t *heap, u32 addr)
@@ -101,6 +112,7 @@ static void _heap_free(heap_t *heap, u32 addr)
{
node->prev->size += node->size + sizeof(hnode_t);
node->prev->next = node->next;
if (node->next)
node->next->prev = node->prev;
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,

View File

@@ -34,6 +34,7 @@ u32 minerva_init()
minerva_cfg = NULL;
mtc_config_t *mtc_cfg = (mtc_config_t *)&nyx_str->mtc_cfg;
memset(mtc_cfg, 0, sizeof(mtc_config_t));
// Set table to nyx storage.
mtc_cfg->mtc_table = (emc_table_t *)&nyx_str->mtc_table;
@@ -46,6 +47,8 @@ u32 minerva_init()
// Ensure that Minerva is new.
if (mtc_cfg->init_done == MTC_INIT_MAGIC)
minerva_cfg = (void *)ep_addr;
else
mtc_cfg->init_done = 0;
if (!minerva_cfg)
return 1;

View File

@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018 balika011
* Copyright (c) 2019 CTCaer
* Copyright (c) 2019-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -696,7 +696,6 @@ sdram_params_t *sdram_get_params_patched()
void sdram_init()
{
//TODO: sdram_id should be in [0,4].
const sdram_params_t *params = (const sdram_params_t *)sdram_get_params();
// Set DRAM voltage.

View File

@@ -4,7 +4,7 @@
*
* Copyright (c) 2011 Samsung Electronics
* MyungJoo Ham <myungjoo.ham@samsung.com>
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -96,14 +96,17 @@ enum MAX17050_reg {
MAX17050_K_empty0 = 0x3B,
MAX17050_TaskPeriod = 0x3C,
MAX17050_FSTAT = 0x3D,
MAX17050_TIMER = 0x3E,
MAX17050_SHDNTIMER = 0x3F,
MAX17050_QRTbl30 = 0x42,
MAX17050_dQacc = 0x45,
MAX17050_dPacc = 0x46,
MAX17050_VFSOC0 = 0x48,
Max17050_QH0 = 0x4C,
MAX17050_QH = 0x4D,
MAX17050_QL = 0x4E,
@@ -111,6 +114,8 @@ enum MAX17050_reg {
MAX17050_MaxVolt = 0x51, // Custom ID. Not to be sent to i2c.
MAX17050_VFSOC0Enable = 0x60,
MAX17050_MODELEnable1 = 0x62,
MAX17050_MODELEnable2 = 0x63,
MAX17050_MODELChrTbl = 0x80,

View File

@@ -137,6 +137,7 @@ int max77620_regulator_enable(u32 id, int enable)
return 1;
}
// LDO only.
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags)
{
if (id > REGULATOR_MAX)
@@ -168,9 +169,9 @@ void max77620_config_default()
_max77620_try_set_reg(MAX77620_REG_SD_CFG2, 4);
}
void max77620_low_battery_monitor_config()
void max77620_low_battery_monitor_config(bool enable)
{
_max77620_try_set_reg(MAX77620_REG_CNFGGLBL1,
MAX77620_CNFGGLBL1_LBDAC_EN | MAX77620_CNFGGLBL1_MPPLD |
MAX77620_CNFGGLBL1_LBDAC_EN | (enable ? MAX77620_CNFGGLBL1_MPPLD : 0) |
MAX77620_CNFGGLBL1_LBHYST_200 | MAX77620_CNFGGLBL1_LBDAC_2800);
}

View File

@@ -33,7 +33,7 @@
* ldo2 | SDMMC1 | 50000 | 800000 | 1800000 | 3300000 |
* ldo3 | GC ASIC | 50000 | 800000 | 3100000 | 3100000 | 3.1V (pcv)
* ldo4 | RTC | 12500 | 800000 | 850000 | 850000 |
* ldo5 | GC ASIC | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
* ldo5 | GC Card | 50000 | 800000 | 1800000 | 1800000 | 1.8V (pcv)
* ldo6 | Touch, ALS | 50000 | 800000 | 2900000 | 2900000 | 2.9V
* ldo7 | XUSB | 50000 | 800000 | 1050000 | 1050000 |
* ldo8 | XUSB, DC | 50000 | 800000 | 1050000 | 1050000 |
@@ -113,6 +113,6 @@ int max77620_regulator_set_voltage(u32 id, u32 mv);
int max77620_regulator_enable(u32 id, int enable);
int max77620_regulator_set_volt_and_flags(u32 id, u32 mv, u8 flags);
void max77620_config_default();
void max77620_low_battery_monitor_config();
void max77620_low_battery_monitor_config(bool enable);
#endif

View File

@@ -1,7 +1,8 @@
/*
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
*
* Copyright (c) 2018 CTCaer
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2019-2020 shchmue
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -75,3 +76,94 @@ void max77620_rtc_stop_alarm()
// Update RTC clock from RTC regs.
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE);
}
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time)
{
u32 tmp, edays, year, month, day;
// Set time.
time->sec = epoch % 60;
epoch /= 60;
time->min = epoch % 60;
epoch /= 60;
time->hour = epoch % 24;
epoch /= 24;
// Calculate base date values.
tmp = (u32)(((u64)4 * epoch + 102032) / 146097 + 15);
tmp = (u32)((u64)epoch + 2442113 + tmp - (tmp >> 2));
year = (20 * tmp - 2442) / 7305;
edays = tmp - 365 * year - (year >> 2);
month = edays * 1000 / 30601;
day = edays - month * 30 - month * 601 / 1000;
// Month/Year offset.
if(month < 14)
{
year -= 4716;
month--;
}
else
{
year -= 4715;
month -= 13;
}
// Set date.
time->year = year;
time->month = month;
time->day = day;
// Set weekday.
time->weekday = 0; //! TODO.
}
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding)
{
u32 year, month, epoch;
//Year
year = time->year;
//Month of year
month = time->month;
if (!hos_encoding)
{
// Month/Year offset.
if(month < 3)
{
month += 12;
year--;
}
}
else
{
year -= 2000;
month++;
// Month/Year offset.
if(month < 3)
{
month += 9;
year--;
}
else
month -= 3;
}
epoch = (365 * year) + (year >> 2) - (year / 100) + (year / 400); // Years to days.
if (!hos_encoding)
{
epoch += (30 * month) + (3 * (month + 1) / 5) + time->day; // Months to days.
epoch -= 719561; // Epoch time is 1/1/1970.
}
else
epoch += (30 * month) + ((3 * month + 2) / 5) + 59 + time->day; // Months to days.
epoch *= 86400; // Days to seconds.
epoch += (3600 * time->hour) + (60 * time->min) + time->sec; // Add hours, minutes and seconds.
return epoch;
}

View File

@@ -71,5 +71,7 @@ typedef struct _rtc_time_t {
void max77620_rtc_get_time(rtc_time_t *time);
void max77620_rtc_stop_alarm();
void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time);
u32 max77620_rtc_date_to_epoch(const rtc_time_t *time, bool hos_encoding);
#endif /* _MFD_MAX77620_RTC_H_ */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -39,6 +39,7 @@
extern sdmmc_t sd_sdmmc;
extern boot_cfg_t b_cfg;
extern volatile nyx_storage_t *nyx_str;
/*
* CLK_OSC - 38.4 MHz crystal.
@@ -78,8 +79,8 @@ void _config_gpios()
PINMUX_AUX(PINMUX_AUX_UART3_TX) = 0;
// Set Joy-Con IsAttached direction.
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE;
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE;
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
// Set pin mode for Joy-Con IsAttached and UARTB/C TX pins.
#if !defined (DEBUG_UART_PORT) || DEBUG_UART_PORT != UART_B
@@ -109,7 +110,7 @@ void _config_gpios()
gpio_output_enable(GPIO_PORT_X, GPIO_PIN_7, GPIO_OUTPUT_DISABLE);
// Configure HOME as inputs.
// PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_PULL_UP | PINMUX_INPUT_ENABLE;
// PINMUX_AUX(PINMUX_AUX_BUTTON_HOME) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
// gpio_config(GPIO_PORT_Y, GPIO_PIN_1, GPIO_MODE_GPIO);
}
@@ -160,7 +161,7 @@ void _mbist_workaround()
// Enable specific clocks and disable all others.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_H) = 0xC0; // Enable clock PMC, FUSE.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80000130; // Enable clock RTC, TMR, GPIO, BPMP_CACHE.
//CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80400130; // Keep USB data ON.
//CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) = 0x80400130; // Keep USBD ON.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_U) = 0x1F00200; // Enable clock CSITE, IRAMA, IRAMB, IRAMC, IRAMD, BPMP_CACHE_RAM.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) = 0x80400808; // Enable clock MSELECT, APB2APE, SPDIF_DOUBLER, SE.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_W) = 0x402000FC; // Enable clock PCIERX0, PCIERX1, PCIERX2, PCIERX3, PCIERX4, PCIERX5, ENTROPY, MC1.
@@ -184,6 +185,9 @@ void _mbist_workaround()
void _config_se_brom()
{
// Enable fuse clock.
clock_enable_fuse(true);
// Skip SBK/SSK if sept was run.
if (!(b_cfg.boot_cfg & BOOT_CFG_SEPT_RUN))
{
@@ -217,10 +221,19 @@ void _config_se_brom()
void _config_regulators()
{
// Disable low battery shutdown monitor.
max77620_low_battery_monitor_config(false);
// Disable SDMMC1 IO power.
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
max77620_regulator_enable(REGULATOR_LDO2, 0);
sd_power_cycle_time_start = get_tmr_ms();
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_CNFGBBC, MAX77620_CNFGBBC_RESISTOR_1K);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1,
(1 << 6) | (3 << MAX77620_ONOFFCNFG1_MRT_SHIFT)); // PWR delay for forced shutdown off.
// Configure all Flexible Power Sequencers.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG0,
(7 << MAX77620_FPS_TIME_PERIOD_SHIFT));
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_CFG1,
@@ -236,10 +249,10 @@ void _config_regulators()
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_FPS_GPIO3,
(4 << MAX77620_FPS_TIME_PERIOD_SHIFT) | (2 << MAX77620_FPS_PD_PERIOD_SHIFT)); // 3.x+
// Set vdd_core voltage to 1.125V
// Set vdd_core voltage to 1.125V.
max77620_regulator_set_voltage(REGULATOR_SD0, 1125000);
// Fix CPU/GPU after a Linux warmboot.
// Fix CPU/GPU after a L4T warmboot.
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO5, 2);
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_GPIO6, 2);
@@ -256,9 +269,6 @@ void _config_regulators()
i2c_send_byte(I2C_5, MAX77621_GPU_I2C_ADDR, MAX77621_CONTROL2_REG,
MAX77621_T_JUNCTION_120 | MAX77621_FT_ENABLE | MAX77621_CKKADV_TRIP_75mV_PER_US_HIST_DIS |
MAX77621_CKKADV_TRIP_150mV_PER_US | MAX77621_INDUCTOR_NOMINAL);
// Enable low battery shutdown monitor for < 2800mV.
max77620_low_battery_monitor_config();
}
void config_hw()
@@ -312,6 +322,7 @@ void reconfig_hw_workaround(bool extra_reconfig, u32 magic)
bpmp_mmu_disable();
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
minerva_change_freq(FREQ_204);
nyx_str->mtc_cfg.init_done = 0;
// Re-enable clocks to Audio Processing Engine as a workaround to hanging.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= (1 << 10); // Enable AHUB clock.

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -19,7 +20,7 @@
#include "i2c.h"
#include "../utils/util.h"
static u32 i2c_addrs[] = {
static const u32 i2c_addrs[] = {
0x7000C000, 0x7000C400, 0x7000C500,
0x7000C700, 0x7000D000, 0x7000D100
};
@@ -121,6 +122,11 @@ int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size)
return _i2c_send_pkt(idx, x, tmp, size + 1);
}
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x)
{
return _i2c_recv_pkt(idx, buf, size, x);
}
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y)
{
int res = _i2c_send_pkt(idx, x, (u8 *)&y, 1);

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -39,6 +40,7 @@
void i2c_init(u32 idx);
int i2c_send_buf_small(u32 idx, u32 x, u32 y, u8 *buf, u32 size);
int i2c_recv_buf(u8 *buf, u32 size, u32 idx, u32 x);
int i2c_recv_buf_small(u8 *buf, u32 size, u32 idx, u32 x, u32 y);
int i2c_send_byte(u32 idx, u32 x, u32 y, u8 b);
u8 i2c_recv_byte(u32 idx, u32 x, u32 y);

View File

@@ -31,7 +31,7 @@ void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage)
for (u32 i = 0; i < hdr->num_part_ents; i++)
{
gpt_entry_t *ent = (gpt_entry_t *)(buf + (hdr->part_ent_lba - 1) * NX_EMMC_BLOCKSIZE + i * sizeof(gpt_entry_t));
emmc_part_t *part = (emmc_part_t *)malloc(sizeof(emmc_part_t));
emmc_part_t *part = (emmc_part_t *)calloc(sizeof(emmc_part_t), 1);
part->lba_start = ent->lba_start;
part->lba_end = ent->lba_end;
part->attrs = ent->attrs;

View File

@@ -0,0 +1,113 @@
#pragma once
#include "types.h"
extern const char *gfx_file_size_names[];
extern const char *menu_sd_states[];
extern const char *emmc_fs_entries[];
extern const char *utils_err_codes[];
//extern const char *pkg2names[];
extern const char *mainmenu_credits;
enum utils_err_codes_te_call {
ERR_SAME_LOC = 50,
ERR_DISK_WRITE_FAILED,
ERR_EMPTY_CLIPBOARD,
ERR_FOLDER_ROOT = 54,
ERR_DEST_PART_OF_SRC,
ERR_PART_NOT_FOUND,
ERR_BISKEY_DUMP_FAILED,
ERR_MEM_ALLOC_FAILED,
ERR_EMMC_READ_FAILED,
ERR_EMMC_WRITE_FAILED,
ERR_FILE_TOO_BIG_FOR_DEST,
ERR_SD_EJECTED,
ERR_PARSE_FAIL,
ERR_CANNOT_COPY_FILE_TO_FS_PART,
ERR_NO_DESTENATION
};
extern const char *utils_err_codes_te[];
enum mainmenu_main_return {
MAIN_SDCARD = 0,
MAIN_EMMC_SAF,
MAIN_EMMC_SYS,
MAIN_EMMC_USR,
MAIN_EMUMMC_SAF,
MAIN_EMUMMC_SYS,
MAIN_EMUMMC_USR,
MAIN_MOUNT_SD,
MAIN_TOOLS,
MAIN_SD_FORMAT,
MAIN_CREDITS,
MAIN_EXIT
};
extern menu_entry mainmenu_main[];
enum mainmenu_shutdown_return {
SHUTDOWN_REBOOT_RCM = 1,
SHUTDOWN_REBOOT_NORMAL,
SHUTDOWN_POWER_OFF,
SHUTDOWN_HEKATE,
SHUTDOWN_AMS
};
extern menu_entry mainmenu_shutdown[];
enum mainmenu_tools_return {
TOOLS_DISPLAY_INFO = 1,
TOOLS_DISPLAY_GPIO,
TOOLS_DUMPFIRMWARE,
TOOLS_DUMPUSERSAVE
};
extern menu_entry mainmenu_tools[];
enum mainmenu_format_return {
FORMAT_ALL_FAT32 = 1,
FORMAT_EMUMMC
};
extern menu_entry mainmenu_format[];
enum mmc_types {
SYSMMC = 1,
EMUMMC
};
extern menu_entry utils_mmcChoice[];
enum fs_menu_file_return {
FILE_COPY = 4,
FILE_MOVE,
FILE_DELETE,
FILE_PAYLOAD,
FILE_SCRIPT,
FILE_HEXVIEW,
FILE_DUMPBIS
};
extern menu_entry fs_menu_file[];
enum fs_menu_folder_return {
DIR_EXITFOLDER = 2,
DIR_COPYFOLDER,
DIR_DELETEFOLDER
};
extern menu_entry fs_menu_folder[];
enum fs_menu_startdir_return {
FILEMENU_RETURN = 0,
FILEMENU_CLIPBOARD,
FILEMENU_CURFOLDER
};
extern menu_entry fs_menu_startdir[];
extern gpt_entry_rule gpt_fs_rules[];
extern menu_entry mmcmenu_start[];
extern menu_entry mmcmenu_filemenu[];

View File

@@ -0,0 +1,67 @@
#include "common.h"
const char *gfx_file_size_names[] = {
"B ",
"KB",
"MB",
"GB"
};
const char *menu_sd_states[] = {
"\nUnmount SD",
"\nMount SD"
};
const char *emmc_fs_entries[] = {
"SAFE",
"SYSTEM",
"USER"
};
const char *utils_err_codes[] = {
"OK",
"I/O ERROR",
"NO DISK",
"NOT READY",
"NO FILE",
"NO PATH",
"PATH INVALID",
"ACCESS DENIED",
"ACCESS DENIED",
"INVALID PTR",
"PROTECTED",
"INVALID DRIVE",
"NO MEM",
"NO FAT",
"MKFS ABORT"
};
const char *utils_err_codes_te[] = { // these start at 50
"SAME LOC",
"DISK WRITE FAILED",
"EMPTY CLIPBOARD",
"DEFENITION OF INSANITY",
"FOLDER ROOT",
"DEST PART OF SRC",
"PART NOT FOUND",
"BISKEY DUMP FAILED",
"MEM ALLOC FAILED",
"EMMC READ FAILED",
"EMMC WRITE FAILED",
"FILE TOO BIG FOR DEST",
"SD EJECTED",
"PARSING FAILED",
"CANNOT COPY FILE TO FS PART",
"NO DESTENATION"
};
/*
const char *pkg2names[] = {
"BCPKG2-1-Normal-Main",
"BCPKG2-2-Normal-Sub",
"BCPKG2-3-SafeMode-Main",
"BCPKG2-4-SafeMode-Sub",
"BCPKG2-5-Repair-Main",
"BCPKG2-6-Repair-Sub"
};
*/
const char *mainmenu_credits = "\nTegraexplorer, made by:\nSuch Meme, Many Skill\n\nProject based on:\nLockpick_RCM\nHekate\n\nCool people:\nshchmue\ndennthecafebabe\nDax";

View File

@@ -0,0 +1,92 @@
#include "common.h"
#include "types.h"
menu_entry mainmenu_main[] = {
{"[SD:/] SD CARD", COLOR_GREEN, ISMENU},
{"[EMMC:/] EMMC", COLOR_ORANGE, ISMENU},
{"[EMMC:/] EMUMMC", COLOR_BLUE, ISMENU},
{"\nMount/Unmount SD", COLOR_WHITE, ISMENU},
{"Tools", COLOR_VIOLET, ISMENU},
{"SD format", COLOR_VIOLET, ISMENU},
{"\nCredits", COLOR_WHITE, ISMENU},
{"Exit", COLOR_WHITE, ISMENU}
};
menu_entry mainmenu_shutdown[] = {
{"Back", COLOR_WHITE, ISMENU},
{"\nReboot to RCM", COLOR_VIOLET, ISMENU},
{"Reboot normally", COLOR_ORANGE, ISMENU},
{"Power off\n", COLOR_BLUE, ISMENU},
{"Reboot to Hekate", COLOR_GREEN, ISMENU},
{"Reboot to Atmosphere", COLOR_GREEN, ISMENU}
};
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}
};
menu_entry mainmenu_format[] = {
{"Back\n", COLOR_WHITE, ISMENU},
{"Format entire SD to FAT32", COLOR_RED, ISMENU},
{"Format for EmuMMC setup (FAT32/RAW)", COLOR_RED, ISMENU}
};
menu_entry utils_mmcChoice[] = {
{"Back\n", COLOR_WHITE, ISMENU},
{"SysMMC", COLOR_ORANGE, ISMENU},
{"EmuMMC", COLOR_BLUE, ISMENU}
};
menu_entry fs_menu_file[] = {
{NULL, COLOR_GREEN, ISMENU | ISSKIP},
{NULL, COLOR_VIOLET, ISMENU | ISSKIP},
{NULL, COLOR_VIOLET, ISMENU | ISSKIP},
{"\n\n\nBack", COLOR_WHITE, ISMENU},
{"\nCopy to clipboard", COLOR_BLUE, ISMENU},
{"Move to clipboard", COLOR_BLUE, ISMENU},
{"\nDelete file\n", COLOR_RED, ISMENU},
{"Launch Payload", COLOR_ORANGE, ISMENU},
{"Launch Script", COLOR_YELLOW, ISMENU},
{"View Hex", COLOR_GREEN, ISMENU},
{"\nExtract BIS", COLOR_YELLOW, ISMENU}
};
menu_entry fs_menu_folder[] = {
{NULL, COLOR_VIOLET, ISMENU | ISSKIP},
{"\nBack", COLOR_WHITE, ISMENU},
{"Return to main menu\n", COLOR_BLUE, ISMENU},
{"Copy to clipboard", COLOR_VIOLET, ISMENU},
{"Delete folder", COLOR_RED, ISMENU}
};
menu_entry fs_menu_startdir[] = {
{"Folder -> previous folder ", COLOR_ORANGE, ISMENU},
{"Clipboard -> Current folder", COLOR_ORANGE, ISMENU},
{"Current folder menu ", COLOR_ORANGE, ISMENU}
};
gpt_entry_rule gpt_fs_rules[] = {
{"PRODINFOF", 0 | isFS},
{"SAFE", 1 | isFS },
{"SYSTEM", 2 | isFS},
{"USER", 3 | isFS},
{NULL, 0}
};
menu_entry mmcmenu_start[] = {
{"Back", COLOR_ORANGE, ISMENU},
{"Dump File Partitions", COLOR_ORANGE, ISMENU},
{"Clipboard -> Partition\n", COLOR_ORANGE, ISMENU},
{"BOOT0/1", COLOR_BLUE, isBOOT | ISMENU}
};
menu_entry mmcmenu_filemenu[] = {
{"Part:", COLOR_ORANGE, ISSKIP | ISMENU},
{NULL, COLOR_VIOLET, ISSKIP | ISMENU},
{"\nBack", COLOR_WHITE, ISMENU},
{"Dump to SD", COLOR_YELLOW, ISMENU}
};

View File

@@ -0,0 +1,54 @@
#pragma once
#include "../../utils/types.h"
#define ISDIR (1 << 0)
#define ISARC (1 << 1)
#define ISHIDE (1 << 8)
#define ISMENU (1 << 9)
#define ISSKIP (1 << 10)
#define ISGB (1 << 7)
#define ISMB (1 << 6)
#define ISKB (1 << 5)
#define ISB (1 << 4)
#define SETBIT(object, shift, value) ((value) ? (object |= shift) : (object &= ~shift))
/* Bit table for property as a file:
0000 0001: Directory bit
0000 0010: Archive bit (or hideme)
0001 0000: Size component is a Byte
0010 0000: Size component is a KiloByte
0100 0000: Size component is a MegaByte
1000 0000: Size component is a GigaByte : note that this won't surpass gigabytes, but i don't expect people to have a single file that's a terrabyte big
*/
#define COPY_MODE_PRINT 0x1
#define COPY_MODE_CANCEL 0x2
#define BUFSIZE 32768
#define OPERATIONCOPY 0x2
#define OPERATIONMOVE 0x4
#define PART_BOOT 0x1
#define PART_PKG2 0x2
#define BOOT0_ARG 0x80
#define BOOT1_ARG 0x40
#define BCPKG2_1_ARG 0x20
#define BCPKG2_3_ARG 0x10
typedef struct {
char *name;
u32 storage;
u16 property;
} menu_entry;
typedef struct {
const char *name;
u8 property;
} gpt_entry_rule;
#define isFS 0x80
#define isBOOT 0x2

View File

@@ -1,34 +1,37 @@
#include <string.h>
#include "../mem/heap.h"
#include "gfx.h"
#include "fs.h"
#include "emmc.h"
#include "../utils/types.h"
#include "../libs/fatfs/ff.h"
#include "../utils/sprintf.h"
#include "../utils/btn.h"
#include "../gfx/gfx.h"
#include "../utils/util.h"
#include "../hos/pkg1.h"
#include "../storage/sdmmc.h"
#include "../storage/nx_emmc.h"
#include "../sec/tsec.h"
#include "../soc/t210.h"
#include "../soc/fuse.h"
#include "../mem/mc.h"
#include "../sec/se.h"
#include "../soc/hw_init.h"
#include "../mem/emc.h"
#include "../mem/sdram.h"
#include "../storage/emummc.h"
#include "../config/config.h"
#include "../../mem/heap.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../gfx/gfx.h"
#include "../../utils/util.h"
#include "../../hos/pkg1.h"
#include "../../storage/sdmmc.h"
#include "../../storage/nx_emmc.h"
#include "../../sec/tsec.h"
#include "../../soc/t210.h"
#include "../../soc/fuse.h"
#include "../../mem/mc.h"
#include "../../sec/se.h"
#include "../../soc/hw_init.h"
#include "../../mem/emc.h"
#include "../../mem/sdram.h"
#include "../../storage/emummc.h"
#include "../../config/config.h"
#include "../common/common.h"
#include "../gfx/gfxutils.h"
#include "../../utils/list.h"
#include "../../mem/heap.h"
sdmmc_storage_t storage;
emmc_part_t *system_part;
sdmmc_t sdmmc;
extern hekate_config h_cfg;
__attribute__ ((aligned (16))) FATFS emmc;
LIST_INIT(gpt);
LIST_INIT(sys_gpt);
LIST_INIT(emu_gpt);
u8 bis_key[4][32];
pkg1_info pkg1inf = {-1, ""};
@@ -61,21 +64,31 @@ pkg1_info returnpkg1info(){
return pkg1inf;
}
int connect_part(const char *partition){
sdmmc_storage_set_mmc_partition(&storage, 0);
system_part = nx_emmc_part_find(selectGpt(currentlyMounted), partition);
if (!system_part) {
gfx_errDisplay("connect_mmc_part", ERR_PART_NOT_FOUND, 0);
return 1;
}
return 0;
}
int mount_mmc(const char *partition, const int biskeynumb){
int res;
f_unmount("emmc:");
se_aes_key_set(8, bis_key[biskeynumb] + 0x00, 0x10);
se_aes_key_set(9, bis_key[biskeynumb] + 0x10, 0x10);
system_part = nx_emmc_part_find(&gpt, partition);
if (!system_part) {
gfx_printf("Failed to locate %s partition.", partition);
return -1;
}
if (connect_part(partition))
return 1;
if (f_mount(&emmc, "emmc:", 1)) {
gfx_printf("Mount failed of %s.", partition);
return -1;
if ((res = f_mount(&emmc, "emmc:", 1))) {
gfx_errDisplay("mount_mmc", res, 0);
return 1;
}
return 0;
@@ -126,6 +139,7 @@ int dump_biskeys(){
u8 *pkg1 = (u8 *)malloc(0x40000);
sdmmc_storage_set_mmc_partition(&storage, 1);
sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1);
strncpy(pkg1inf.id, pkg1 + 0x10, 14);
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
if (!pkg1_id) {
EPRINTF("Unknown pkg1 version.");
@@ -202,9 +216,8 @@ int dump_biskeys(){
memcpy(bis_key[3], bis_key[2], 0x20);
}
sdmmc_storage_set_mmc_partition(&storage, 0);
// Parse eMMC GPT.
nx_emmc_gpt_parse(&gpt, &storage);
//sdmmc_storage_set_mmc_partition(&storage, 0);
//nx_emmc_gpt_parse(&sys_gpt, &storage);
se_aes_key_set(8, bis_key[2] + 0x00, 0x10);
se_aes_key_set(9, bis_key[2] + 0x10, 0x10);
@@ -213,3 +226,33 @@ int dump_biskeys(){
strcpy(pkg1inf.id, pkg1_id->id);
return 0;
}
void dumpGpt(){
connect_mmc(SYSMMC);
sdmmc_storage_set_mmc_partition(&storage, 0);
nx_emmc_gpt_parse(&sys_gpt, &storage);
if (emu_cfg.enabled){
connect_mmc(EMUMMC);
emummc_storage_set_mmc_partition(&storage, 0);
nx_emmc_gpt_parse(&emu_gpt, &storage);
}
}
link_t *selectGpt(short mmcType){
switch(mmcType){
case SYSMMC:
return &sys_gpt;
case EMUMMC:
return &emu_gpt;
}
return NULL;
}
int checkGptRules(char *in){
for (int i = 0; gpt_fs_rules[i].name != NULL; i++){
if (!strcmp(in, gpt_fs_rules[i].name))
return gpt_fs_rules[i].property;
}
return 0;
}

View File

@@ -1,4 +1,6 @@
#pragma once
#include "../../utils/types.h"
#include "../../utils/list.h"
typedef struct _pkg1_info {
short ver;
@@ -13,7 +15,10 @@ pkg1_info returnpkg1info();
int mount_mmc(const char *partition, const int biskeynumb);
void connect_mmc(short mmctype);
void disconnect_mmc();
int connect_part(const char *partition);
void dumpGpt();
link_t *selectGpt(short mmcType);
int checkGptRules(char *in);
static const u8 zeros[0x10] = {0};
@@ -50,7 +55,9 @@ static const u8 bis_key_source[3][0x20] = {
0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4}
};
/*
enum mmc_types {
SYSMMC = 0,
EMUMMC
};
*/

View File

@@ -0,0 +1,184 @@
#include <string.h>
#include "emmcoperations.h"
#include "../../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../../utils/types.h"
#include "emmc.h"
#include "../../storage/emummc.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../mem/heap.h"
#include "../../storage/nx_emmc.h"
#include "../common/types.h"
#include "../utils/utils.h"
#include "../fs/fsutils.h"
extern sdmmc_storage_t storage;
extern emmc_part_t *system_part;
int emmcDumpPart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
FIL fp;
u8 *buf;
u32 lba_curr = part->lba_start;
u32 bytesWritten = 0;
u32 totalSectors = part->lba_end - part->lba_start + 1;
u64 totalSize = (u64)((u64)totalSectors << 9);
u32 num = 0;
u32 pct = 0;
int res;
gfx_printf("Initializing\r");
buf = calloc(BUFSIZE, sizeof(u8));
if (!buf){
gfx_errDisplay("dump_emmc_part", ERR_MEM_ALLOC_FAILED, 1);
return -1;
}
if ((res = f_open(&fp, path, FA_CREATE_ALWAYS | FA_WRITE))){
gfx_errDisplay("dump_emmc_part", res, 2);
return -1;
}
f_lseek(&fp, totalSize);
f_lseek(&fp, 0);
while (totalSectors > 0){
num = MIN(totalSectors, 64);
if (!emummc_storage_read(mmcstorage, lba_curr, num, buf)){
gfx_errDisplay("dump_emmc_part", ERR_EMMC_READ_FAILED, 3);
return -1;
}
if ((res = f_write(&fp, buf, num * NX_EMMC_BLOCKSIZE, NULL))){
gfx_errDisplay("dump_emmc_part", res, 4);
return -1;
}
pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start);
gfx_printf("Progress: %d%%\r", pct);
lba_curr += num;
totalSectors -= num;
bytesWritten += num * NX_EMMC_BLOCKSIZE;
}
gfx_printf(" \r");
f_close(&fp);
free(buf);
return 0;
}
int existsCheck(char *path){
int res = 0;
if (fsutil_checkfile(path)){
gfx_printf("File already exists! Overwrite?\nVol +/- to cancel\n");
res = gfx_makewaitmenu("Power to continue", 3);
gfx_printf("\r \r");
return res;
}
return 1;
}
/*
int dump_emmc_parts(u16 parts, u8 mmctype){
char *path;
char basepath[] = "sd:/tegraexplorer/partition_dumps";
f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/partition_dumps");
connect_mmc(mmctype);
gfx_clearscreen();
if (parts & PART_BOOT){
emmc_part_t bootPart;
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
memset(&bootPart, 0, sizeof(bootPart));
bootPart.lba_start = 0;
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
for (int i = 0; i < 2; i++){
strcpy(bootPart.name, "BOOT");
bootPart.name[4] = (u8)('0' + i);
bootPart.name[5] = 0;
emummc_storage_set_mmc_partition(&storage, i + 1);
utils_copystring(fsutil_getnextloc(basepath, bootPart.name), &path);
if (!existsCheck(path))
continue;
gfx_printf("Dumping %s\n", bootPart.name);
dump_emmc_part(path, &storage, &bootPart);
free(path);
}
emummc_storage_set_mmc_partition(&storage, 0);
}
if (parts & PART_PKG2){
for (int i = 0; i < 6; i++){
utils_copystring(fsutil_getnextloc(basepath, pkg2names[i]), &path);
gfx_printf("Dumping %s\n", pkg2names[i]);
emmcDumpSpecific(pkg2names[i], path);
free(path);
}
}
gfx_printf("\nDone!");
btn_wait();
return 0;
}
*/
int emmcDumpBoot(char *basePath){
emmc_part_t bootPart;
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
char *path;
memset(&bootPart, 0, sizeof(emmc_part_t));
bootPart.lba_start = 0;
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
for (int i = 0; i < 2; i++){
strcpy(bootPart.name, "BOOT");
bootPart.name[4] = (u8)('0' + i);
bootPart.name[5] = 0;
emummc_storage_set_mmc_partition(&storage, i + 1);
utils_copystring(fsutil_getnextloc(basePath, bootPart.name), &path);
if (!existsCheck(path))
continue;
SWAPCOLOR(COLOR_BLUE);
gfx_printf("Dumping %s\n", bootPart.name);
RESETCOLOR;
emmcDumpPart(path, &storage, &bootPart);
free(path);
}
emummc_storage_set_mmc_partition(&storage, 0);
return 0;
}
int emmcDumpSpecific(char *part, char *path){
if (!existsCheck(path))
return 0;
emummc_storage_set_mmc_partition(&storage, 0);
if (connect_part(part)){
gfx_errDisplay("dump_emmc_specific", ERR_PART_NOT_FOUND, 0);
return 1;
}
SWAPCOLOR(COLOR_VIOLET);
gfx_printf("Dumping %s\n", part);
RESETCOLOR;
emmcDumpPart(path, &storage, system_part);
return 0;
}

View File

@@ -0,0 +1,176 @@
#include <string.h>
#include "emmc.h"
#include "../../mem/heap.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/btn.h"
#include "../../gfx/gfx.h"
#include "../../utils/util.h"
#include "../../storage/nx_emmc.h"
#include "../../mem/mc.h"
#include "../../mem/emc.h"
#include "../../storage/emummc.h"
#include "../../config/config.h"
#include "../common/common.h"
#include "../gfx/gfxutils.h"
#include "../../utils/list.h"
#include "../../mem/heap.h"
#include "emmcmenu.h"
#include "../fs/fsreader.h"
#include "../utils/utils.h"
#include "../gfx/menu.h"
#include "../fs/fsmenu.h"
#include "emmcoperations.h"
#include "../fs/fsutils.h"
menu_entry *mmcMenuEntries = NULL;
extern sdmmc_storage_t storage;
extern emmc_part_t *system_part;
extern char *clipboard;
extern u8 clipboardhelper;
void addEntry(emmc_part_t *part, u8 property, int spot){
if (mmcMenuEntries[spot].name != NULL){
free(mmcMenuEntries[spot].name);
}
utils_copystring(part->name, &mmcMenuEntries[spot].name);
if (property & isFS){
mmcMenuEntries[spot].storage = (u32)(property & 0x7F);
mmcMenuEntries[spot].property = ISDIR;
}
else {
u64 size = 0;
int sizes = 0;
mmcMenuEntries[spot].property = 0;
size = (u64)(part->lba_end + 1 - part->lba_start);
size *= (u64)NX_EMMC_BLOCKSIZE;
while (size > 1024){
size /= 1024;
sizes++;
}
if (sizes > 3)
sizes = 0;
mmcMenuEntries[spot].property |= (1 << (4 + sizes));
mmcMenuEntries[spot].storage = (u32)size;
}
}
int fillMmcMenu(short mmcType){
int count = 4, i;
if (mmcMenuEntries != NULL)
clearfileobjects(&mmcMenuEntries);
link_t *gpt = selectGpt(mmcType);
LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link)
count++;
createfileobjects(count, &mmcMenuEntries);
for (i = 0; i < 4; i++){
utils_copystring(mmcmenu_start[i].name, &mmcMenuEntries[i].name);
mmcMenuEntries[i].property = mmcmenu_start[i].property;
mmcMenuEntries[i].storage = mmcmenu_start[i].storage;
}
LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link){
addEntry(part, checkGptRules(part->name), i++);
}
return count;
}
int handleEntries(short mmcType, menu_entry part){
int res = 0;
if (part.property & ISDIR){
if (returnpkg1info().ver < 0){
gfx_errDisplay("emmcMakeMenu", ERR_BISKEY_DUMP_FAILED, 0);
return -1;
}
if (!mount_mmc(part.name, part.storage))
fileexplorer("emmc:/", 1);
}
else {
if (mmcmenu_filemenu[1].name != NULL)
free(mmcmenu_filemenu[1].name);
utils_copystring(part.name, &mmcmenu_filemenu[1].name);
if ((menu_make(mmcmenu_filemenu, 4, "-- RAW PARTITION --")) < 3)
return 0;
f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/partition_dumps");
gfx_clearscreen();
if (part.property & isBOOT){
res = emmcDumpBoot("sd:/tegraexplorer/partition_dumps");
}
else {
//gfx_printf("Dumping %s...\n", part.name);
res = emmcDumpSpecific(part.name, fsutil_getnextloc("sd:/tegraexplorer/partition_dumps", part.name));
}
if (!res){
gfx_printf("\nDone!");
btn_wait();
}
}
return 0;
}
int makeMmcMenu(short mmcType){
int count, selection;
count = fillMmcMenu(mmcType);
connect_mmc(mmcType);
while (1){
selection = menu_make(mmcMenuEntries, count, (mmcType == SYSMMC) ? "-- SYSMMC --" : "-- EMUMMC --");
switch(selection){
case -1:
case 0:
return 0;
case 1:
gfx_clearscreen();
f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/partition_dumps");
for (int i = 0; i < count; i++){
if (mmcMenuEntries[i].property & ISMENU || mmcMenuEntries[i].property & ISDIR)
continue;
//gfx_printf("Dumping %s...\n", mmcMenuEntries[i].name);
emmcDumpSpecific(mmcMenuEntries[i].name, fsutil_getnextloc("sd:/tegraexplorer/partition_dumps", mmcMenuEntries[i].name));
}
gfx_printf("\nDone!");
btn_wait();
break;
case 2:
if (!(clipboardhelper & ISDIR) && (clipboardhelper & OPERATIONCOPY)){
gfx_clearscreen();
if (!mmcFlashFile(clipboard, mmcType)){
gfx_printf("\nDone!");
btn_wait();
}
clipboardhelper = 0;
}
else
gfx_errDisplay("mmcMenu", ERR_EMPTY_CLIPBOARD, 0);
break;
default:
handleEntries(mmcType, mmcMenuEntries[selection]);
break;
}
}
}

View File

@@ -0,0 +1,3 @@
#pragma once
int makeMmcMenu(short mmcType);

View File

@@ -0,0 +1,10 @@
#pragma once
#include "../../utils/types.h"
#include "../../storage/nx_emmc.h"
int emmcDumpSpecific(char *part, char *path);
int emmcDumpBoot(char *basePath);
int mmcFlashFile(char *path, short mmcType);
int emmcDumpPart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);

View File

@@ -0,0 +1,229 @@
#include <string.h>
#include "emmcoperations.h"
#include "../../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../../utils/types.h"
#include "emmc.h"
#include "../../storage/emummc.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../mem/heap.h"
#include "../../storage/nx_emmc.h"
#include "../common/types.h"
#include "../utils/utils.h"
#include "../fs/fsutils.h"
extern sdmmc_storage_t storage;
extern emmc_part_t *system_part;
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part){
FIL fp;
FILINFO fno;
u8 *buf;
u32 lba_curr = part->lba_start;
u64 bytesWritten = 0;
u32 totalSectorsDest = part->lba_end - part->lba_start + 1;
u64 totalSizeDest = (u64)((u64)totalSectorsDest << 9);
u64 totalSize;
u32 num = 0;
u32 pct = 0;
int res;
gfx_printf("Initializing\r");
buf = calloc(16384, sizeof(u8));
if (!buf){
gfx_errDisplay("restore_emmc_part", ERR_MEM_ALLOC_FAILED, 1);
return -1;
}
if ((res = f_stat(path, &fno))){
gfx_errDisplay("restore_emmc_part", res, 2);
return -1;
}
totalSize = fno.fsize;
u64 totalSectors = totalSize / NX_EMMC_BLOCKSIZE;
if (totalSize > totalSizeDest){
gfx_errDisplay("restore_emmc_part", ERR_FILE_TOO_BIG_FOR_DEST, 3);
return -1;
}
gfx_printf("Flashing %s\n", part->name);
if (totalSize < totalSizeDest){
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("File is too small for destenation.\nDo you want to flash it anyway?\n\nVol +/- to Cancel\n");
u8 btnres = gfx_makewaitmenu(
"Power to Confirm",
2
);
RESETCOLOR;
if (!btnres){
gfx_printf("\nCancelled: %s\n\n", part->name);
return 0;
}
else
gfx_printf("\nFlashing %s\n", part->name);
}
if ((res = f_open(&fp, path, FA_OPEN_ALWAYS | FA_READ))){
gfx_errDisplay("restore_emmc_part", res, 4);
return -1;
}
while (totalSectors > 0){
num = MIN(totalSectors, 32);
if ((res = f_read(&fp, buf, num * NX_EMMC_BLOCKSIZE, NULL))){
gfx_errDisplay("restore_emmc_part", res, 5);
return -1;
}
if (!emummc_storage_write(mmcstorage, lba_curr, num, buf)){
gfx_errDisplay("restore_emmc_part", ERR_EMMC_WRITE_FAILED, 2);
return -1;
}
lba_curr += num;
totalSectors -= num;
bytesWritten += (u64)(num * NX_EMMC_BLOCKSIZE);
pct = (u64)(bytesWritten * (u64)100) / (u64)(fno.fsize);
gfx_printf("Progress: %d%%\r", pct);
}
gfx_printf(" \r");
f_close(&fp);
free(buf);
return 0;
}
// function replaced by new mmc implementation. Will be removed at some point
/*
int restore_emmc_file(char *path, const char *target, u8 partition, u8 mmctype){
connect_mmc(mmctype);
if (partition){
emmc_part_t bootPart;
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
memset(&bootPart, 0, sizeof(bootPart));
bootPart.lba_start = 0;
bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
strcpy(bootPart.name, target);
emummc_storage_set_mmc_partition(&storage, partition);
restore_emmc_part(path, &storage, &bootPart);
}
else {
if (connect_part(target)){
gfx_errDisplay("restore_emmc_part", ERR_PART_NOT_FOUND, 0);
return -1;
}
restore_emmc_part(path, &storage, system_part);
}
return 0;
}
int restore_bis_using_file(char *path, u8 mmctype){
f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/bis");
gfx_clearscreen();
if (extract_bis_file(path, "sd:/tegraexplorer/bis"))
return -1;
SWAPBGCOLOR(COLOR_RED);
SWAPCOLOR(COLOR_DEFAULT);
gfx_printf("\nAre you sure you want to flash these files\nThis could leave your switch unbootable!\nTarget is SysMMC\n\nVol +/- to cancel\n");
if (!gfx_makewaitmenu(
"Power to confirm",
10
))
{
return 0;
}
RESETCOLOR;
gfx_printf("\nRestoring BIS...\n\n");
restore_emmc_file("sd:/tegraexplorer/bis/BOOT0.bin", "BOOT0", 1, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BOOT1.bin", "BOOT1", 2, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-1-Normal-Main", pkg2names[0], 0, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-1-Normal-Main", pkg2names[1], 0, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-3-SafeMode-Main", pkg2names[2], 0, mmctype);
restore_emmc_file("sd:/tegraexplorer/bis/BCPKG2-3-SafeMode-Main", pkg2names[3], 0, mmctype);
gfx_printf("\n\nDone!\nPress any button to return");
btn_wait();
return 0;
}
*/
emmc_part_t *mmcFindPart(char *path, short mmcType){
char *filename, *extention, *path_local;
emmc_part_t *part;
utils_copystring(path, &path_local);
filename = strrchr(path_local, '/') + 1;
extention = strrchr(path_local, '.');
if (extention != NULL)
*extention = '\0';
if (checkGptRules(filename)){
gfx_errDisplay("mmcFindPart", ERR_CANNOT_COPY_FILE_TO_FS_PART, 1);
free(path_local);
return NULL;
}
part = nx_emmc_part_find(selectGpt(mmcType), filename);
if (part != NULL){
emummc_storage_set_mmc_partition(&storage, 0);
free(path_local);
return part;
}
if (!strcmp(filename, "BOOT0") || !strcmp(filename, "BOOT1")){
const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17;
part = calloc(1, sizeof(emmc_part_t));
part->lba_start = 0;
part->lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1;
strcpy(part->name, filename);
emummc_storage_set_mmc_partition(&storage, (!strcmp(filename, "BOOT0")) ? 1 : 2);
free(path_local);
return part;
}
//gfx_printf("Path: %s\nFilename: %s", path, filename);
//btn_wait();
gfx_errDisplay("mmcFindPart", ERR_NO_DESTENATION, 2);
free(path_local);
return NULL;
}
int mmcFlashFile(char *path, short mmcType){
emmc_part_t *part;
int res;
part = mmcFindPart(path, mmcType);
if (part != NULL){
res = emmcRestorePart(path, &storage, part);
emummc_storage_set_mmc_partition(&storage, 0);
return res;
}
return 1;
}

View File

@@ -1,453 +0,0 @@
#include <string.h>
#include "../mem/heap.h"
#include "gfx.h"
#include "fs.h"
#include "../utils/types.h"
#include "../libs/fatfs/ff.h"
#include "../utils/sprintf.h"
#include "../utils/btn.h"
#include "../gfx/gfx.h"
#include "../utils/util.h"
#include "io.h"
#include "script.h"
fs_entry *fileobjects;
char rootpath[10] = "";
char *currentpath = "";
char *clipboard = "";
u8 clipboardhelper = 0;
extern const char sizevalues[4][3];
extern int launch_payload(char *path);
menu_item explfilemenu[11] = {
{"-- File Menu --", COLOR_BLUE, -1, 0},
{"FILE", COLOR_GREEN, -1, 0},
{"\nSIZE", COLOR_VIOLET, -1, 0},
{"ATTRIB", COLOR_VIOLET, -1, 0},
{"\n\n\nBack", COLOR_WHITE, -1, 1},
{"\nCopy to clipboard", COLOR_BLUE, COPY, 1},
{"Move to clipboard", COLOR_BLUE, MOVE, 1},
{"\nDelete file\n", COLOR_RED, DELETE, 1},
{"Launch Payload", COLOR_ORANGE, PAYLOAD, 1},
{"Launch Script", COLOR_YELLOW, SCRIPT, 1},
{"View Hex", COLOR_GREEN, HEXVIEW, 1}
};
menu_item explfoldermenu[6] = {
{"-- Folder Menu --\n", COLOR_BLUE, -1, 0},
{"ATTRIB", COLOR_VIOLET, -1, 0},
{"\n\nBack", COLOR_WHITE, -1, 1},
{"Return to main menu\n", COLOR_BLUE, EXITFOLDER, 1},
{"Copy to clipboard", COLOR_VIOLET, COPYFOLDER, 1},
{"Delete folder", COLOR_RED, DELETEFOLDER, 1}
};
void writecurpath(const char *in){
if (currentpath != NULL)
free(currentpath);
size_t len = strlen(in) + 1;
currentpath = (char*) malloc (len);
strcpy(currentpath, in);
strcpy(currentpath, in);
}
void writeclipboard(const char *in, bool move, bool folder){
if (clipboard != NULL)
free(clipboard);
clipboardhelper = 0;
if (move)
clipboardhelper |= (OPERATIONMOVE);
else
clipboardhelper |= (OPERATIONCOPY);
if (folder)
clipboardhelper |= (ISDIR);
size_t len = strlen(in) + 1;
clipboard = (char*) malloc (len);
strcpy(clipboard, in);
strcpy(clipboard, in);
}
char *getnextloc(const char *current, const char *add){
static char *ret;
if (ret != NULL){
free(ret);
ret = NULL;
}
size_t size = strlen(current) + strlen(add) + 1;
ret = (char*) malloc (size);
if (!strcmp(rootpath, current))
sprintf(ret, "%s%s", current, add);
else
sprintf(ret, "%s/%s", current, add);
return ret;
}
char *getprevloc(char *current){
static char *ret;
char *temp;
if (ret != NULL){
free(ret);
ret = NULL;
}
size_t size = strlen(current) + 1;
ret = (char*) malloc (size);
strcpy(ret, current);
temp = strrchr(ret, '/');
memset(temp, '\0', 1);
if (strlen(rootpath) > strlen(ret))
strcpy(ret, rootpath);
return ret;
}
int getfileobjamount(){
int amount = 0;
while (fileobjects[amount].name != NULL)
amount++;
return amount;
}
fs_entry getfileobj(int spot){
return fileobjects[spot];
}
void copyfile(const char *path, const char *outfolder){
char *filename = strrchr(path, '/') + 1;
char *outstring;
int res;
clearscreen();
makestring(getnextloc(outfolder, filename), &outstring);
gfx_printf("Note:\nTo stop the transfer hold Vol-\n\n%s\nProgress: ", outstring);
if (!strcmp(path, outstring)){
message(COLOR_RED, "\nIn and out are the same!");
}
else if (clipboardhelper & OPERATIONMOVE){
if (strcmp(rootpath, "emmc:/")){
f_rename(path, outstring);
readfolder(currentpath);
}
else
message(COLOR_RED, "\nMoving in emummc is not allowed!");
}
else if (clipboardhelper & OPERATIONCOPY) {
res = copy(path, outstring, true, true);
if (res){
gfx_printf("\n\n%kSomething went wrong while copying!\n\nErrcode: %d%k", COLOR_RED, res, COLOR_WHITE);
btn_wait();
}
readfolder(currentpath);
}
else {
message(COLOR_RED, "\nClipboard is empty!");
}
free (outstring);
clipboardhelper = 0;
}
void addobject(char* name, int spot, bool isfol, bool isarc){
size_t length = strlen(name) + 1;
u64 size = 0;
int sizes = 0;
fileobjects[spot].property = 0;
if (fileobjects[spot].name != NULL){
free(fileobjects[spot].name);
fileobjects[spot].name = NULL;
}
fileobjects[spot].name = (char*) malloc (length);
strlcpy(fileobjects[spot].name, name, length);
if (isfol)
fileobjects[spot].property |= (ISDIR);
else {
size = getfilesize(getnextloc(currentpath, name));
while (size > 1024){
size /= 1024;
sizes++;
}
if (sizes > 3)
sizes = 0;
fileobjects[spot].property |= (1 << (4 + sizes));
fileobjects[spot].size = size;
}
if (isarc)
fileobjects[spot].property |= (ISARC);
}
void clearfileobjects(){
if (fileobjects != NULL){
for (int i = 0; fileobjects[i].name != NULL; i++){
free(fileobjects[i].name);
fileobjects[i].name = NULL;
}
free(fileobjects);
fileobjects = NULL;
}
}
void createfileobjects(int size){
fileobjects = calloc (size + 1, sizeof(fs_entry));
fileobjects[size].name = NULL;
}
int readfolder(const char *path){
DIR dir;
FILINFO fno;
int folderamount = 0, res;
clearfileobjects();
createfileobjects(getfolderentryamount(path));
if ((res = f_opendir(&dir, path))){
message(COLOR_RED, "Error during f_opendir: %d", res);
return -1;
}
while (!f_readdir(&dir, &fno) && fno.fname[0]){
addobject(fno.fname, folderamount++, (fno.fattrib & AM_DIR), (fno.fattrib & AM_ARC));
}
f_closedir(&dir);
return folderamount;
}
int delfile(const char *path, const char *filename){
char *tempmessage;
size_t tempmessagesize = strlen(filename) + 65;
tempmessage = (char*) malloc (tempmessagesize);
sprintf(tempmessage, "Are you sure you want to delete:\n%s\n\nPress vol+/- to cancel\n", filename);
if (makewaitmenu(tempmessage, "Press power to delete", 3)){
f_unlink(path);
readfolder(currentpath);
return 0;
}
else
return -1;
}
void copyfolder(char *in, char *out){
bool fatalerror = false;
int res;
if (!strcmp(in, rootpath)){
message(COLOR_RED, "\nIn is root\nAborting!");
fatalerror = true;
}
if (strstr(out, in) != NULL && !fatalerror){
message(COLOR_RED, "\nOut is a part of in!\nAborting!");
fatalerror = true;
}
if (!strcmp(in, out) && !fatalerror){
message(COLOR_RED, "\nIn is the same as out!\nAborting!");
fatalerror = true;
}
if (!fatalerror){
clearscreen();
gfx_printf("\nCopying folder, please wait\n");
if ((res = copy_recursive(in, out)))
message(COLOR_RED, "copy_recursive() failed!\nErrcode %d", res);
readfolder(currentpath);
}
clipboardhelper = 0;
}
int filemenu(fs_entry file){
int temp;
FILINFO attribs;
strlcpy(explfilemenu[1].name, file.name, 43);
for (temp = 4; temp < 8; temp++)
if ((file.property & (1 << temp)))
break;
sprintf(explfilemenu[2].name, "\nSize: %d %s", file.size, sizevalues[temp - 4]);
if (f_stat(getnextloc(currentpath, file.name), &attribs))
explfilemenu[3].property = -1;
else {
explfilemenu[3].property = 0;
sprintf(explfilemenu[3].name, "Attribs: %c%c%c%c",
(attribs.fattrib & AM_RDO) ? 'R' : '-',
(attribs.fattrib & AM_SYS) ? 'S' : '-',
(attribs.fattrib & AM_HID) ? 'H' : '-',
(attribs.fattrib & AM_ARC) ? 'A' : '-');
}
if (strstr(file.name, ".bin") != NULL && file.size & ISKB){
explfilemenu[8].property = 1;
}
else
explfilemenu[8].property = -1;
if (strstr(file.name, ".tegrascript") != NULL)
explfilemenu[9].property = 1;
else
explfilemenu[9].property = -1;
temp = makemenu(explfilemenu, 11);
switch (temp){
case COPY:
writeclipboard(getnextloc(currentpath, file.name), false, false);
break;
case MOVE:
writeclipboard(getnextloc(currentpath, file.name), true, false);
break;
case DELETE:
delfile(getnextloc(currentpath, file.name), file.name);
break;
case PAYLOAD:
launch_payload(getnextloc(currentpath, file.name));
break;
case SCRIPT:
ParseScript(getnextloc(currentpath, file.name));
break;
case HEXVIEW:
viewbytes(getnextloc(currentpath, file.name));
break;
}
return 0;
}
int foldermenu(){
int res;
FILINFO attribs;
if (!strcmp(rootpath, currentpath)){
explfoldermenu[4].property = -1;
explfoldermenu[5].property = -1;
}
else {
explfoldermenu[4].property = 1;
explfoldermenu[5].property = 1;
}
if (f_stat(currentpath, &attribs))
explfoldermenu[1].property = -1;
else {
explfoldermenu[1].property = 0;
sprintf(explfoldermenu[1].name, "Attribs: %c%c%c%c",
(attribs.fattrib & AM_RDO) ? 'R' : '-',
(attribs.fattrib & AM_SYS) ? 'S' : '-',
(attribs.fattrib & AM_HID) ? 'H' : '-',
(attribs.fattrib & AM_ARC) ? 'A' : '-');
}
res = makemenu(explfoldermenu, 6);
switch (res){
case EXITFOLDER:
return -1;
case DELETEFOLDER:
if (makewaitmenu("Do you want to delete this folder?\nThe entire folder, with all subcontents\n will be deleted!!!\n\nPress vol+/- to cancel\n", "Press power to contine...", 3)){
clearscreen();
gfx_printf("\nDeleting folder, please wait...\n");
if ((res = del_recursive(currentpath))){
message(COLOR_RED, "Error during del_recursive()! %d", res);
}
writecurpath(getprevloc(currentpath));
readfolder(currentpath);
}
break;
case COPYFOLDER:
writeclipboard(currentpath, false, true);
break;
}
return 0;
}
void fileexplorer(const char *startpath){
int res, tempint;
bool breakfree = false;
if (!strcmp(rootpath, "emmc:/") && !strcmp(startpath, "emmc:/"))
clipboardhelper = 0;
strcpy(rootpath, startpath);
writecurpath(startpath);
readfolder(currentpath);
if (strcmp(rootpath, "emmc:/"))
explfilemenu[6].property = 1;
else
explfilemenu[6].property = -1;
while (1){
res = makefilemenu(fileobjects, getfileobjamount(), currentpath);
if (res < 1){
switch (res){
case -2:
if (!strcmp(rootpath, currentpath))
breakfree = true;
else {
writecurpath(getprevloc(currentpath));
readfolder(currentpath);
}
break;
case -1:
if (clipboardhelper & ISDIR)
copyfolder(clipboard, currentpath);
else
copyfile(clipboard, currentpath);
break;
case 0:
tempint = foldermenu();
if (tempint == -1)
breakfree = true;
break;
}
}
else {
if (fileobjects[res - 1].property & ISDIR){
writecurpath(getnextloc(currentpath, fileobjects[res - 1].name));
readfolder(currentpath);
}
else {
filemenu(fileobjects[res - 1]);
}
}
if (breakfree)
break;
}
}

View File

@@ -1,49 +0,0 @@
#pragma once
#include "../utils/types.h"
#define ISDIR (1 << 0)
#define ISARC (1 << 1)
#define ISGB (1 << 7)
#define ISMB (1 << 6)
#define ISKB (1 << 5)
#define ISB (1 << 4)
#define OPERATIONCOPY (1 << 1)
#define OPERATIONMOVE (1 << 2)
#define BUFSIZE 32768
/* Bit table for property:
0000 0001: Directory bit
0000 0010: Archive bit
0001 0000: Size component is a Byte
0010 0000: Size component is a KiloByte
0100 0000: Size component is a MegaByte
1000 0000: Size component is a GigaByte : note that this won't surpass gigabytes, but i don't expect people to have a single file that's a terrabyte big
*/
typedef struct _fs_entry {
char* name;
u16 size;
u8 property;
} fs_entry;
enum filemenuoptions {
COPY = 1,
MOVE,
DELETE,
PAYLOAD,
SCRIPT,
HEXVIEW
};
enum foldermenuoptions {
EXITFOLDER = 1,
DELETEFOLDER,
COPYFOLDER
};
int readfolder(const char *path);
void fileexplorer(const char *startpath);
char *getnextloc(const char *current, const char *add);

View File

@@ -0,0 +1,7 @@
#pragma once
#include "../common/types.h"
int filemenu(menu_entry file);
void copyfile(const char *src_in, const char *outfolder);
int foldermenu();
void copyfolder(char *in, char *out);

View File

@@ -0,0 +1,184 @@
#include <string.h>
#include "entrymenu.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/btn.h"
#include "../../gfx/gfx.h"
#include "fsutils.h"
#include "fsactions.h"
#include "../utils/utils.h"
#include "../gfx/gfxutils.h"
#include "../../mem/heap.h"
#include "fsreader.h"
#include "../gfx/menu.h"
#include "../common/types.h"
#include "../../utils/sprintf.h"
#include "../script/parser.h"
#include "../emmc/emmcoperations.h"
extern char *currentpath;
extern char *clipboard;
extern u8 clipboardhelper;
extern int launch_payload(char *path);
int delfile(const char *path, const char *filename){
gfx_clearscreen();
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("Are you sure you want to delete:\n%s\n\nPress vol+/- to cancel\n", filename);
if (gfx_makewaitmenu("Press power to delete", 3)){
f_unlink(path);
fsreader_readfolder(currentpath);
return 0;
}
else
return -1;
}
void viewbytes(char *path){
FIL in;
u8 print[2048];
u32 size;
QWORD offset = 0;
int res;
gfx_clearscreen();
if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("viewbytes", res, 1);
return;
}
while (btn_read() & BTN_POWER);
while (1){
f_lseek(&in, offset * 16);
if ((res = f_read(&in, &print, 2048 * sizeof(u8), &size))){
gfx_errDisplay("viewbytes", res, 2);
return;
}
gfx_con_setpos(0, 31);
gfx_hexdump(offset * 16, print, size * sizeof(u8));
res = btn_read();
if (!res)
res = btn_wait();
if (res & BTN_VOL_DOWN && 2048 * sizeof(u8) == size)
offset++;
if (res & BTN_VOL_UP && offset > 0)
offset--;
if (res & BTN_POWER)
break;
}
f_close(&in);
}
void copyfile(const char *src_in, const char *outfolder){
char *in, *out, *filename;
int res;
gfx_clearscreen();
utils_copystring(src_in, &in);
utils_copystring(strrchr(in, '/') + 1, &filename);
utils_copystring(fsutil_getnextloc(outfolder, filename), &out);
gfx_printf("Note:\nTo stop the transfer hold Vol-\n\n%s\nProgress: ", filename);
if (!strcmp(in, out)){
gfx_errDisplay("gfxcopy", ERR_SAME_LOC, 1);
return;
}
if (clipboardhelper & OPERATIONMOVE){
if ((res = f_rename(in, out))){
gfx_errDisplay("gfxcopy", res, 2);
return;
}
}
else if (clipboardhelper & OPERATIONCOPY) {
if (fsact_copy(in, out, COPY_MODE_CANCEL | COPY_MODE_PRINT))
return;
}
else {
gfx_errDisplay("gfxcopy", ERR_EMPTY_CLIPBOARD, 3);
return;
}
free(in);
free(out);
free(filename);
fsreader_readfolder(currentpath);
}
int filemenu(menu_entry file){
int temp;
FILINFO attribs;
for (int i = 0; i < 3; i++)
if (fs_menu_file[i].name != NULL)
free(fs_menu_file[i].name);
utils_copystring(file.name, &fs_menu_file[0].name);
fs_menu_file[1].name = malloc(16);
fs_menu_file[2].name = malloc(16);
for (temp = 4; temp < 8; temp++)
if ((file.property & (1 << temp)))
break;
sprintf(fs_menu_file[1].name, "\nSize: %d %s", file.storage, gfx_file_size_names[temp - 4]);
if (f_stat(fsutil_getnextloc(currentpath, file.name), &attribs))
SETBIT(fs_menu_file[2].property, ISHIDE, 1);
else {
SETBIT(fs_menu_file[2].property, ISHIDE, 0);
sprintf(fs_menu_file[2].name, "Attribs: %c%c%c%c",
(attribs.fattrib & AM_RDO) ? 'R' : '-',
(attribs.fattrib & AM_SYS) ? 'S' : '-',
(attribs.fattrib & AM_HID) ? 'H' : '-',
(attribs.fattrib & AM_ARC) ? 'A' : '-');
}
SETBIT(fs_menu_file[7].property, ISHIDE, !(strstr(file.name, ".bin") != NULL && file.property & ISKB) && strstr(file.name, ".rom") == NULL);
SETBIT(fs_menu_file[8].property, ISHIDE, strstr(file.name, ".te") == NULL);
SETBIT(fs_menu_file[10].property, ISHIDE, strstr(file.name, ".bis") == NULL);
temp = menu_make(fs_menu_file, 11, "-- File Menu --");
switch (temp){
case FILE_COPY:
fsreader_writeclipboard(fsutil_getnextloc(currentpath, file.name), OPERATIONCOPY);
break;
case FILE_MOVE:
fsreader_writeclipboard(fsutil_getnextloc(currentpath, file.name), OPERATIONMOVE);
break;
case FILE_DELETE:
delfile(fsutil_getnextloc(currentpath, file.name), file.name);
break;
case FILE_PAYLOAD:
launch_payload(fsutil_getnextloc(currentpath, file.name));
break;
case FILE_SCRIPT:
//ParseScript(fsutil_getnextloc(currentpath, file.name));
runScript(fsutil_getnextloc(currentpath, file.name));
fsreader_readfolder(currentpath);
break;
case FILE_HEXVIEW:
viewbytes(fsutil_getnextloc(currentpath, file.name));
break;
case FILE_DUMPBIS:
gfx_clearscreen();
extract_bis_file(fsutil_getnextloc(currentpath, file.name), currentpath);
fsreader_readfolder(currentpath);
btn_wait();
break;
case -1:
return -1;
}
return 0;
}

View File

@@ -0,0 +1,90 @@
#include <string.h>
#include "entrymenu.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../mem/heap.h"
#include "../gfx/menu.h"
#include "fsreader.h"
#include "../gfx/gfxutils.h"
#include "fsactions.h"
#include "fsutils.h"
#include "../../utils/sprintf.h"
extern char *currentpath;
extern char *clipboard;
extern u8 clipboardhelper;
void copyfolder(char *in, char *out){
int res;
res = strlen(in);
if ((*(in + res - 1) == '/')){
gfx_errDisplay("copyfolder", ERR_FOLDER_ROOT, 1);
}
else if (strstr(out, in) != NULL){
gfx_errDisplay("copyfolder", ERR_DEST_PART_OF_SRC, 2);
}
else if (!strcmp(in, out)){
gfx_errDisplay("copyfolder", ERR_SAME_LOC, 3);
}
else {
gfx_clearscreen();
gfx_printf("\nCopying folder, please wait\n");
fsact_copy_recursive(in, out);
fsreader_readfolder(currentpath);
}
clipboardhelper = 0;
}
int foldermenu(){
int res;
FILINFO attribs;
if (fs_menu_folder[0].name != NULL)
free(fs_menu_folder[0].name);
fs_menu_folder[0].name = malloc(16);
res = strlen(currentpath);
SETBIT(fs_menu_folder[3].property, ISHIDE, (*(currentpath + res - 1) == '/'));
SETBIT(fs_menu_folder[4].property, ISHIDE, (*(currentpath + res - 1) == '/'));
if (f_stat(currentpath, &attribs))
SETBIT(fs_menu_folder[0].property, ISHIDE, 1);
else {
SETBIT(fs_menu_folder[0].property, ISHIDE, 0);
sprintf(fs_menu_folder[0].name, "Attribs: %c%c%c%c",
(attribs.fattrib & AM_RDO) ? 'R' : '-',
(attribs.fattrib & AM_SYS) ? 'S' : '-',
(attribs.fattrib & AM_HID) ? 'H' : '-',
(attribs.fattrib & AM_ARC) ? 'A' : '-');
}
res = menu_make(fs_menu_folder, 5, currentpath);
switch (res){
case DIR_EXITFOLDER:
case -1:
return -1;
case DIR_COPYFOLDER:
fsreader_writeclipboard(currentpath, OPERATIONCOPY | ISDIR);
break;
case DIR_DELETEFOLDER:
gfx_clearscreen();
gfx_printf("Do you want to delete this folder?\nThe entire folder, with all subcontents\n will be deleted!!!\n\nPress vol+/- to cancel\n");
if (gfx_makewaitmenu("Press power to contine...", 3)){
gfx_clearscreen();
gfx_printf("\nDeleting folder, please wait...\n");
fsact_del_recursive(currentpath);
fsreader_writecurpath(fsutil_getprevloc(currentpath));
fsreader_readfolder(currentpath);
}
break;
}
return 0;
}

View File

@@ -0,0 +1,193 @@
#include <string.h>
#include "fsactions.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../utils/utils.h"
#include "../../mem/heap.h"
#include "../../utils/btn.h"
#include "fsutils.h"
int fsact_copy(const char *locin, const char *locout, u8 options){
FIL in, out;
FILINFO in_info;
u64 sizeoffile, sizecopied = 0, totalsize;
UINT temp1, temp2;
u8 *buff;
unsigned int x, y, i = 0;
int res;
gfx_con_getpos(&x, &y);
if (!strcmp(locin, locout)){
gfx_errDisplay("copy", ERR_SAME_LOC, 1);
return 1;
}
if ((res = f_open(&in, locin, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("copy", res, 2);
return 1;
}
if (f_stat(locin, &in_info)){
gfx_errDisplay("copy", res, 3);
return 1;
}
if (f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE)){
gfx_errDisplay("copy", res, 4);
return 1;
}
buff = malloc (BUFSIZE);
sizeoffile = f_size(&in);
totalsize = sizeoffile;
while (sizeoffile > 0){
if ((res = f_read(&in, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp1))){
gfx_errDisplay("copy", res, 5);
return 1;
}
if ((res = f_write(&out, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp2))){
gfx_errDisplay("copy", res, 6);
return 1;
}
if (temp1 != temp2){
gfx_errDisplay("copy", ERR_DISK_WRITE_FAILED, 7);
return 1;
}
sizeoffile -= temp1;
sizecopied += temp1;
if (options & COPY_MODE_PRINT && 10 > i++){
gfx_printf("%k[%d%%]%k", COLOR_GREEN, ((sizecopied * 100) / totalsize) ,COLOR_WHITE);
gfx_con_setpos(x, y);
i = 0;
if (options & COPY_MODE_CANCEL)
if (btn_read() & BTN_VOL_DOWN){
f_unlink(locout);
break;
}
}
}
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_stat(locin, &in_info); //somehow stops fatfs from being weird
return 0;
}
int fsact_del_recursive(char *path){
DIR dir;
FILINFO fno;
int res;
u32 x, y;
char *localpath = NULL;
gfx_con_getpos(&x, &y);
utils_copystring(path, &localpath);
if ((res = f_opendir(&dir, localpath))){
gfx_errDisplay("del_recursive", res, 1);
return 1;
}
while (!f_readdir(&dir, &fno) && fno.fname[0]){
if (fno.fattrib & AM_DIR){
fsact_del_recursive(fsutil_getnextloc(localpath, fno.fname));
}
else {
SWAPCOLOR(COLOR_RED);
gfx_printf("\r");
gfx_printandclear(fno.fname, 37);
if ((res = f_unlink(fsutil_getnextloc(localpath, fno.fname)))){
gfx_errDisplay("del_recursive", res, 2);
return 1;
}
}
}
f_closedir(&dir);
if ((res = f_unlink(localpath))){
gfx_errDisplay("del_recursive", res, 3);
return 1;
}
free(localpath);
return 0;
}
int fsact_copy_recursive(char *path, char *dstpath){
DIR dir;
FILINFO fno;
int res;
u32 x, y;
char *startpath = NULL, *destpath = NULL, *destfoldername = NULL, *temp = NULL;
gfx_con_getpos(&x, &y);
utils_copystring(path, &startpath);
utils_copystring(strrchr(path, '/') + 1, &destfoldername);
utils_copystring(fsutil_getnextloc(dstpath, destfoldername), &destpath);
if ((res = f_opendir(&dir, startpath))){
gfx_errDisplay("copy_recursive", res, 1);
return 1;
}
f_mkdir(destpath);
while (!f_readdir(&dir, &fno) && fno.fname[0]){
if (fno.fattrib & AM_DIR){
fsact_copy_recursive(fsutil_getnextloc(startpath, fno.fname), destpath);
}
else {
SWAPCOLOR(COLOR_GREEN);
gfx_printf("\r");
gfx_printandclear(fno.fname, 37);
utils_copystring(fsutil_getnextloc(startpath, fno.fname), &temp);
if ((res = fsact_copy(temp, fsutil_getnextloc(destpath, fno.fname), COPY_MODE_PRINT))){
gfx_errDisplay("copy_recursive", res, 2);
return 1;
}
free(temp);
}
}
f_closedir(&dir);
if ((res = (f_stat(startpath, &fno)))){
gfx_errDisplay("copy_recursive", res, 3);
return 1;
}
if ((res = f_chmod(destpath, fno.fattrib, 0x3A))){
gfx_errDisplay("copy_recursive", res, 4);
return 1;
}
free(startpath);
free(destpath);
free(destfoldername);
return 0;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "../../utils/types.h"
int fsact_copy(const char *locin, const char *locout, u8 options);
int fsact_del_recursive(char *path);
int fsact_copy_recursive(char *path, char *dstpath);

View File

@@ -0,0 +1,110 @@
#include "fsutils.h"
#include <string.h>
#include "../../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../../utils/types.h"
#include "../../storage/emummc.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../mem/heap.h"
#include "../../storage/nx_emmc.h"
#include "../common/types.h"
#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));
int size = size_src;
int copysize;
while (size > 0){
copysize = MIN(16834, size);
f_read(in_src, buff, copysize, NULL);
f_write(out_src, buff, copysize, NULL);
size -= copysize;
}
free(buff);
}
void gen_part(int size, FIL* in, char *path){
FIL out;
f_open(&out, path, FA_WRITE | FA_CREATE_ALWAYS);
copy_fil_size(in, &out, size);
f_close(&out);
}
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;
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);
for (int i = 0; i < 4; i++){
f_read(&in, temp, 4, NULL);
filesizes[i] = DecodeInt(temp);
}
gfx_printf("Version: %s\n\n", version);
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);
RESETCOLOR;
free(tempPath);
}
gfx_printf("\n\nDone!\n");
f_close(&in);
return 0;
}

View File

@@ -0,0 +1,122 @@
#include <string.h>
#include "fsmenu.h"
#include "fsreader.h"
#include "../gfx/menu.h"
#include "../gfx/gfxutils.h"
#include "fsutils.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.h"
#include "entrymenu.h"
extern char *currentpath;
extern char *clipboard;
extern u8 clipboardhelper;
int lastentry = 0;
void fileexplorer(const char *startpath, int type){
int res;
if (lastentry > 0 && lastentry == type)
clipboardhelper = 0;
if (clipboardhelper & OPERATIONMOVE)
clipboardhelper = 0;
lastentry = type;
fsreader_writecurpath(startpath);
fsreader_readfolder(currentpath);
/*
if (strcmp(rootpath, "emmc:/"))
explfilemenu[6].property = 1;
else
explfilemenu[6].property = -1;
*/
while (1){
res = menu_make(fsreader_files, fsutil_getfileobjamount(fsreader_files), currentpath);
switch (res){
case FILEMENU_RETURN:
if (!strcmp(startpath, currentpath))
return;
else {
fsreader_writecurpath(fsutil_getprevloc(currentpath));
fsreader_readfolder(currentpath);
}
break;
case FILEMENU_CLIPBOARD:
if (clipboardhelper & ISDIR)
copyfolder(clipboard, currentpath);
else
copyfile(clipboard, currentpath);
clipboardhelper = 0;
break;
case FILEMENU_CURFOLDER:
if (foldermenu())
return;
break;
case -1:
return;
default:
if(fsreader_files[res].property & ISDIR){
fsreader_writecurpath(fsutil_getnextloc(currentpath, fsreader_files[res].name));
fsreader_readfolder(currentpath);
}
else
if(filemenu(fsreader_files[res]))
return;
break;
}
}
/*
while (1){
res = makefilemenu(fileobjects, getfileobjamount(), currentpath);
if (res < 1){
switch (res){
case -2:
if (!strcmp(rootpath, currentpath))
breakfree = true;
else {
writecurpath(getprevloc(currentpath));
readfolder(currentpath);
}
break;
case -1:
if (clipboardhelper & ISDIR)
copyfolder(clipboard, currentpath);
else
copyfile(clipboard, currentpath);
break;
case 0:
tempint = foldermenu();
if (tempint == -1)
breakfree = true;
break;
}
}
else {
if (fileobjects[res - 1].property & ISDIR){
writecurpath(getnextloc(currentpath, fileobjects[res - 1].name));
readfolder(currentpath);
}
else {
filemenu(fileobjects[res - 1]);
}
}
if (breakfree)
break;
}
*/
}

View File

@@ -0,0 +1,3 @@
#pragma once
void fileexplorer(const char *startpath, int type);

View File

@@ -0,0 +1,106 @@
#include "fsreader.h"
#include "../common/types.h"
#include "../common/common.h"
#include "fsutils.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../gfx/gfxutils.h"
#include "../utils/utils.h"
#include "../../mem/heap.h"
menu_entry *fsreader_files = NULL;
char *currentpath = NULL;
char *clipboard = NULL;
u8 clipboardhelper = 0;
void fsreader_writecurpath(const char *in){
if (currentpath != NULL)
free(currentpath);
utils_copystring(in, &currentpath);
}
void fsreader_writeclipboard(const char *in, u8 args){
if (clipboard != NULL)
free(clipboard);
clipboardhelper = args;
utils_copystring(in, &clipboard);
}
void clearfileobjects(menu_entry **menu){
if ((*menu) != NULL){
for (int i = 0; (*menu)[i].name != NULL; i++){
free((*menu)[i].name);
(*menu)[i].name = NULL;
}
free((*menu));
(*menu) = NULL;
}
}
void createfileobjects(int size, menu_entry **menu){
(*menu) = calloc (size + 1, sizeof(menu_entry));
(*menu)[size].name = NULL;
}
void addobject(char* name, int spot, u8 attribs){
u64 size = 0;
int sizes = 0;
fsreader_files[spot].property = 0;
if (fsreader_files[spot].name != NULL){
free(fsreader_files[spot].name);
fsreader_files[spot].name = NULL;
}
utils_copystring(name, &(fsreader_files[spot].name));
if (attribs & AM_DIR)
fsreader_files[spot].property |= (ISDIR);
else {
size = fsutil_getfilesize(fsutil_getnextloc(currentpath, name));
while (size > 1024){
size /= 1024;
sizes++;
}
if (sizes > 3)
sizes = 0;
fsreader_files[spot].property |= (1 << (4 + sizes));
fsreader_files[spot].storage = size;
}
if (attribs & AM_ARC)
fsreader_files[spot].property |= (ISARC);
}
int fsreader_readfolder(const char *path){
DIR dir;
FILINFO fno;
int folderamount, res;
clearfileobjects(&fsreader_files);
createfileobjects(fsutil_getfolderentryamount(path) + 3, &fsreader_files);
for (folderamount = 0; folderamount < 3; folderamount++){
utils_copystring(fs_menu_startdir[folderamount].name, &(fsreader_files[folderamount].name));
fsreader_files[folderamount].storage = fs_menu_startdir[folderamount].storage;
fsreader_files[folderamount].property = fs_menu_startdir[folderamount].property;
}
if ((res = f_opendir(&dir, path))){
gfx_errDisplay("readfolder", res, 0);
return -1;
}
while (!f_readdir(&dir, &fno) && fno.fname[0]){
addobject(fno.fname, folderamount++, fno.fattrib);
}
f_closedir(&dir);
return folderamount;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include "../common/types.h"
extern menu_entry *fsreader_files;
void fsreader_writecurpath(const char *in);
void fsreader_writeclipboard(const char *in, u8 args);
int fsreader_readfolder(const char *path);
void createfileobjects(int size, menu_entry **menu);
void clearfileobjects(menu_entry **menu);

View File

@@ -0,0 +1,90 @@
#include <string.h>
#include "fsutils.h"
#include "../utils/utils.h"
#include "../common/types.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../mem/heap.h"
#include "../../utils/sprintf.h"
#include "../gfx/gfxutils.h"
char *fsutil_getnextloc(const char *current, const char *add){
static char *ret;
if (ret != NULL){
free(ret);
ret = NULL;
}
size_t size = strlen(current) + strlen(add) + 2;
ret = (char*) malloc (size);
if (current[strlen(current) - 1] == '/')
sprintf(ret, "%s%s", current, add);
else
sprintf(ret, "%s/%s", current, add);
return ret;
}
char *fsutil_getprevloc(char *current){
static char *ret;
char *temp;
if (ret != NULL){
free(ret);
ret = NULL;
}
utils_copystring(current, &ret);
temp = strrchr(ret, '/');
if (*(temp - 1) == ':')
temp++;
*temp = '\0';
return ret;
}
int fsutil_getfileobjamount(menu_entry *entries){
int amount = 0;
while (entries[amount].name != NULL)
amount++;
return amount;
}
bool fsutil_checkfile(char* path){
FRESULT fr;
FILINFO fno;
fr = f_stat(path, &fno);
return !(fr & FR_NO_FILE);
}
u64 fsutil_getfilesize(char *path){
FILINFO fno;
f_stat(path, &fno);
return fno.fsize;
}
int fsutil_getfolderentryamount(const char *path){
DIR dir;
FILINFO fno;
int folderamount = 0, res;
if ((res = f_opendir(&dir, path))){
gfx_errDisplay("fsutil_getdircount", res, 0);
return -1;
}
while (!f_readdir(&dir, &fno) && fno.fname[0]){
folderamount++;
}
f_closedir(&dir);
return folderamount;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "../common/types.h"
#include "../../utils/types.h"
char *fsutil_getnextloc(const char *current, const char *add);
char *fsutil_getprevloc(char *current);
int fsutil_getfileobjamount(menu_entry *entries);
bool fsutil_checkfile(char* path);
u64 fsutil_getfilesize(char *path);
int fsutil_getfolderentryamount(const char *path);
int extract_bis_file(char *path, char *outfolder);

View File

@@ -1,252 +0,0 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "../gfx/gfx.h"
#include "te.h"
#include "../utils/btn.h"
#include "../utils/util.h"
#include "gfx.h"
#include "fs.h"
#include "../mem/minerva.h"
#include "../power/max17050.h"
#include <stdarg.h>
const char fixedoptions[3][50] = {
"Folder -> previous folder ",
"Clipboard -> Current folder ",
"Current folder menu "
};
const char sizevalues[4][3] = {
"B ",
"KB",
"MB",
"GB"
};
void clearscreen(){
int battery = 0;
max17050_get_property(MAX17050_RepSOC, &battery);
gfx_clear_grey(0x1B);
SWAPCOLOR(COLOR_DEFAULT);
SWAPBGCOLOR(COLOR_WHITE);
gfx_box(0, 1263, 719, 1279, COLOR_WHITE);
gfx_con_setpos(0, 1263);
gfx_printf("Move: Vol+/- | Select: Pow | Battery: %3d%%", battery >> 8);
gfx_box(0, 0, 719, 15, COLOR_WHITE);
gfx_con_setpos(0, 0);
gfx_printf("Tegraexplorer v1.3.2\n");
RESETCOLOR;
}
int message(u32 color, const char* message, ...){
va_list ap;
va_start(ap, message);
clearscreen();
SWAPCOLOR(color);
gfx_vprintf(message, ap);
va_end(ap);
return btn_wait();
}
int makemenu(menu_item menu[], int menuamount){
int currentpos = 1, i, res;
clearscreen();
while (1){
gfx_con_setpos(0, 31);
if (currentpos == 1){
while (currentpos < menuamount && menu[currentpos - 1].property < 1)
currentpos++;
}
if (currentpos == menuamount){
while (currentpos > 1 && menu[currentpos - 1].property < 1)
currentpos--;
}
for (i = 0; i < menuamount; i++){
if (menu[i].property < 0)
continue;
if (i == currentpos - 1)
gfx_printf("%k%K%s%K\n", COLOR_DEFAULT, COLOR_WHITE, menu[i].name, COLOR_DEFAULT);
else
gfx_printf("%k%s\n", menu[i].color, menu[i].name);
}
gfx_printf("\n%k%s", COLOR_WHITE, menuamount);
res = btn_wait();
if (res & BTN_VOL_UP && currentpos > 1){
currentpos--;
while(menu[currentpos - 1].property < 1 && currentpos > 1)
currentpos--;
}
else if (res & BTN_VOL_DOWN && currentpos < menuamount){
currentpos++;
while(menu[currentpos - 1].property < 1 && currentpos < menuamount)
currentpos++;
}
else if (res & BTN_POWER)
return menu[currentpos - 1].internal_function;
}
}
void printbytes(u8 print[], u32 size, u32 offset){
gfx_con_setpos(0, 31);
gfx_hexdump(offset, print, size * sizeof(u8));
}
int makewaitmenu(char *initialmessage, char *hiddenmessage, int timer){
clearscreen();
int res;
u32 start = get_tmr_s();
gfx_printf(initialmessage);
while(1){
res = btn_read();
if (res & BTN_VOL_DOWN || res & BTN_VOL_UP)
return 0;
if (start + timer > get_tmr_s())
gfx_printf("\r<Wait %d seconds> ", timer + start - get_tmr_s());
else if (res & BTN_POWER)
return 1;
else
gfx_printf("\r%k%s%k", COLOR_RED, hiddenmessage, COLOR_WHITE);
}
}
void gfx_print_length(int size, char *toprint){
char *temp;
temp = (char*) malloc (size + 1);
if (strlen(toprint) > size){
strlcpy(temp, toprint, size);
memset(temp + size - 3, '.', 3);
memset(temp + size, '\0', 1);
}
else
strcpy(temp, toprint);
gfx_printf("%s", temp);
free(temp);
}
void printfsentry(fs_entry file, bool highlight, bool refresh){
int size = 0;
char *display;
int length;
display = (char*) malloc (38);
memset(display + 37, '\0', 1);
if (strlen(file.name) > 37){
strlcpy(display, file.name, 37);
memset(display + 34, '.', 3);
}
else
strcpy(display, file.name);
if (highlight)
gfx_printf("%K%k", COLOR_WHITE, COLOR_DEFAULT);
else
RESETCOLOR;
if (file.property & ISDIR)
gfx_printf("%s", display);
else {
for (size = 4; size < 8; size++)
if ((file.property & (1 << size)))
break;
SWAPCOLOR(COLOR_VIOLET);
gfx_printf("%s", display);
}
RESETCOLOR;
if (refresh){
length = strlen(display);
for (int i = 0; i < (42 - length); i++)
gfx_printf(" ");
}
if (file.property & ISDIR)
gfx_printf("\n");
else {
SWAPCOLOR(COLOR_BLUE);
gfx_printf("\a%d\e%s", file.size, sizevalues[size - 4]);
}
free(display);
}
int makefilemenu(fs_entry *files, int amount, char *path){
int currentpos = -2, i, res = 0, offset = 0, quickoffset = 300;
u32 timer;
bool refresh = false;
clearscreen();
gfx_con_setpos(544, 0);
gfx_printf("%K%k%d files\n%K%k%s%k\n\n", COLOR_WHITE, COLOR_DEFAULT, amount, COLOR_DEFAULT, COLOR_GREEN, path, COLOR_DEFAULT);
while (1){
gfx_con_setpos(0, 47);
timer = get_tmr_ms();
for (i = -3 + offset; i < amount && i < 60 + offset; i++){
if (i < 0){
if (i == currentpos - 1)
gfx_printf("%k%K%s%K\n", COLOR_ORANGE, COLOR_WHITE, fixedoptions[i + 3], COLOR_DEFAULT);
else
gfx_printf("%k%K%s\n", COLOR_ORANGE, COLOR_DEFAULT, fixedoptions[i + 3]);
}
else
printfsentry(files[i], (i == currentpos - 1), refresh);
}
refresh = false;
gfx_printf("\n%k%K %s %s\n\nTime taken for screen draw: %dms ", COLOR_BLUE, COLOR_DEFAULT, (offset + 60 < amount) ? "v" : " ", (offset > 0) ? "^" : " ", get_tmr_ms() - timer);
if (quickoffset == 300)
res = btn_wait();
else {
msleep(quickoffset);
res = btn_read();
}
if (res == 0)
quickoffset = 300;
else if (quickoffset > 46)
quickoffset -= 45;
if ((res & BTN_VOL_UP) && currentpos > -2){
currentpos--;
if (offset != 0 && currentpos < offset - 2){
offset--;
refresh = true;
}
}
if ((res & BTN_VOL_DOWN) && currentpos < amount){
currentpos++;
if (currentpos - offset > 60){
offset++;
refresh = true;
}
}
if (res & BTN_POWER)
return currentpos;
}
minerva_periodic_training();
}

View File

@@ -1,15 +0,0 @@
#pragma once
#include "te.h"
#include "fs.h"
#define SWAPCOLOR(color) gfx_printf("%k", color)
#define SWAPBGCOLOR(color) gfx_printf("%K", color)
#define RESETCOLOR gfx_printf("%k%K", COLOR_WHITE, COLOR_DEFAULT)
int makemenu(menu_item menu[], int menuamount);
int message(u32 color, const char* message, ...);
void clearscreen();
int makefilemenu(fs_entry *files, int amount, char *path);
void printbytes(u8 print[], u32 size, u32 offset);
int makewaitmenu(char *initialmessage, char *hiddenmessage, int timer);
void gfx_print_length(int size, char *toprint);

View File

@@ -0,0 +1,139 @@
#include "gfxutils.h"
#include <string.h>
#include <stdarg.h>
#include "menu.h"
#include "../../gfx/gfx.h"
#include "../../power/max17050.h"
#include "../../utils/btn.h"
#include "../../utils/util.h"
#include "../../mem/heap.h"
#include "../common/common.h"
int printerrors = true;
void gfx_clearscreen(){
int battery = 0;
max17050_get_property(MAX17050_RepSOC, &battery);
gfx_clear_grey(0x1B);
SWAPCOLOR(COLOR_DEFAULT);
SWAPBGCOLOR(COLOR_WHITE);
gfx_box(0, 1263, 719, 1279, COLOR_WHITE);
gfx_con_setpos(0, 1263);
gfx_printf("Move: Vol+/- | Select: Pow | Battery: %3d%%", battery >> 8);
gfx_box(0, 0, 719, 15, COLOR_WHITE);
gfx_con_setpos(0, 0);
gfx_printf("Tegraexplorer v1.5.2\n");
RESETCOLOR;
}
int gfx_message(u32 color, const char* message, ...){
va_list ap;
va_start(ap, message);
gfx_clearscreen();
SWAPCOLOR(color);
gfx_vprintf(message, ap);
va_end(ap);
return btn_wait();
}
int gfx_errDisplay(char *src_func, int err, int loc){
if (!printerrors)
return 0;
gfx_clearscreen();
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("\nAn error occured:\n\n");
gfx_printf("Function: %s\nErrcode: %d\n", src_func, err);
if (err < 15)
gfx_printf("Desc: %s\n", utils_err_codes[err]);
else if (err >= ERR_SAME_LOC && err <= ERR_NO_DESTENATION)
gfx_printf("Desc: %s\n", utils_err_codes_te[err - 50]);
if (loc)
gfx_printf("Loc: %d\n", loc);
gfx_printf("\nPress any button to return");
RESETCOLOR;
while (btn_read() != 0);
return btn_wait();
}
int gfx_makewaitmenu(char *hiddenmessage, int timer){
int res;
u32 start = get_tmr_s();
while (btn_read() != 0);
while(1){
res = btn_read();
if (res & BTN_VOL_DOWN || res & BTN_VOL_UP)
return 0;
if (start + timer > get_tmr_s())
gfx_printf("\r<Wait %d seconds> ", timer + start - get_tmr_s());
else if (res & BTN_POWER)
return 1;
else
gfx_printf("\r%s", hiddenmessage);
}
}
void gfx_printlength(int size, char *toprint){
char *temp;
temp = (char*) malloc (size + 1);
if (strlen(toprint) > size){
strlcpy(temp, toprint, size);
memset(temp + size - 3, '.', 3);
memset(temp + size, '\0', 1);
}
else
strcpy(temp, toprint);
gfx_printf("%s", temp);
free(temp);
}
void gfx_printandclear(char *in, int length){
u32 x, y;
gfx_printlength(length, in);
gfx_con_getpos(&x, &y);
RESETCOLOR;
/*
for (int i = (703 - x) / 16; i > 0; i--)
gfx_printf(" ");
*/
gfx_boxGrey(x, y, 703, y + 16, 0x1B);
gfx_con_setpos(x, y);
//gfx_box(x, y, 719, y + 16, COLOR_DEFAULT);
/*
u8 color = 0x1B;
gfx_set_rect_grey(&color, 719 - x, 16, x, y);
*/
}
void gfx_printfilesize(int size, char *type){
SWAPCOLOR(COLOR_VIOLET);
gfx_printf("\a%4d\e%s", size, type);
RESETCOLOR;
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "../../gfx/gfx.h"
#include "../../utils/types.h"
#define SWAPCOLOR(color) gfx_printf("%k", color)
#define SWAPBGCOLOR(color) gfx_printf("%K", color)
#define RESETCOLOR gfx_printf("%k%K", COLOR_WHITE, COLOR_DEFAULT)
void gfx_clearscreen();
int gfx_message(u32 color, const char* message, ...);
int gfx_errDisplay(char *src_func, int err, int loc);
int gfx_makewaitmenu(char *hiddenmessage, int timer);
void gfx_printlength(int size, char *toprint);
void gfx_printandclear(char *in, int length);
void gfx_printfilesize(int size, char *type);
extern int printerrors;

View File

@@ -0,0 +1,168 @@
#include "menu.h"
#include "gfxutils.h"
#include "../common/types.h"
#include "../../utils/btn.h"
#include "../common/common.h"
#include "../../utils/util.h"
#include "../../mem/minerva.h"
#include "../../soc/gpio.h"
extern void sd_unmount();
extern bool sd_inited;
void _printentry(menu_entry entry, bool highlighted, bool refresh){
int size;
u32 color = (entry.property & ISMENU) ? entry.storage : ((entry.property & ISDIR) ? COLOR_WHITE : COLOR_VIOLET);
/*
if (entry.property & ISMENU)
SWAPCOLOR(entry.storage);
else if (entry.property & ISDIR)
SWAPCOLOR(COLOR_WHITE);
else {
SWAPCOLOR(COLOR_VIOLET);
}
*/
if (!(entry.property & ISMENU && entry.property & ISDIR)){
for (size = 4; size < 8; size++)
if ((entry.property & (1 << size)))
break;
}
/*
if (highlighted){
SWAPBGCOLOR(COLOR_WHITE);
if ((entry.property & ISMENU) ? entry.storage == COLOR_WHITE : entry.property & ISDIR)
SWAPCOLOR(COLOR_DEFAULT);
}
else
SWAPBGCOLOR(COLOR_DEFAULT);
*/
SWAPCOLOR((highlighted) ? COLOR_DEFAULT : color);
SWAPBGCOLOR((highlighted) ? color : COLOR_DEFAULT);
if (refresh)
gfx_printandclear(entry.name, 37);
else
gfx_printlength(37, entry.name);
if (entry.property & ISDIR || entry.property & ISMENU)
gfx_printf("\n");
else {
SWAPCOLOR(COLOR_BLUE);
SWAPBGCOLOR(COLOR_DEFAULT);
gfx_printf("\a%4d", entry.storage);
gfx_con.fntsz = 8;
gfx_printf("\n\e%s\n", gfx_file_size_names[size - 4]);
gfx_con.fntsz = 16;
}
}
int menu_make(menu_entry *entries, int amount, char *toptext){
int currentpos = 0, res = 0, offset = 0, delay = 300, minscreen = 0, maxscreen = 59, calculatedamount = 0;
u32 scrolltimer, timer;
bool refresh = false;
gfx_clearscreen();
for (int i = 0; i < amount; i++)
if (!(entries[i].property & ISMENU))
calculatedamount++;
gfx_con_setpos(512, 0);
if (calculatedamount){
SWAPCOLOR(COLOR_DEFAULT);
SWAPBGCOLOR(COLOR_WHITE);
gfx_printf("%3d entries\n", calculatedamount);
RESETCOLOR;
}
else
gfx_printf("\n");
SWAPCOLOR(COLOR_GREEN);
gfx_printlength(42, toptext);
RESETCOLOR;
while (!(res & BTN_POWER)){
gfx_con_setpos(0, 47);
timer = get_tmr_ms();
refresh = false;
if (!currentpos){
while (currentpos < amount && entries[currentpos].property & (ISSKIP | ISHIDE))
currentpos++;
}
if (currentpos == amount - 1){
while (currentpos >= 1 && entries[currentpos].property & (ISSKIP | ISHIDE))
currentpos--;
}
if (currentpos > maxscreen){
offset += currentpos - maxscreen;
minscreen += currentpos - maxscreen;
maxscreen += currentpos - maxscreen;
refresh = true;
}
if (currentpos < minscreen){
offset -= minscreen - currentpos;
maxscreen -= minscreen - currentpos;
minscreen -= minscreen - currentpos;
refresh = true;
}
for (int i = 0 + offset; i < amount && i < 60 + offset; i++)
if (!(entries[i].property & ISHIDE))
_printentry(entries[i], (i == currentpos), refresh);
gfx_printf("\n%k%K %s %s\n\nTime taken for screen draw: %dms", COLOR_BLUE, COLOR_DEFAULT, (offset + 60 < amount) ? "v" : " ", (offset > 0) ? "^" : " ", get_tmr_ms() - timer);
while (btn_read() & BTN_POWER);
res = 0;
while (!res){
if (sd_inited && !!gpio_read(GPIO_PORT_Z, GPIO_PIN_1)){
gfx_errDisplay("menu", ERR_SD_EJECTED, 0);
sd_unmount();
return -1;
}
res = btn_read();
if (!res)
delay = 300;
if (delay < 300){
scrolltimer = get_tmr_ms();
while (res){
if (scrolltimer + delay <= get_tmr_ms())
break;
res = btn_read();
}
}
if (delay > 46 && res)
delay -= 45;
}
if (res & BTN_VOL_UP && currentpos >= 1){
currentpos--;
while(entries[currentpos].property & (ISSKIP | ISHIDE) && currentpos >= 1)
currentpos--;
}
else if (res & BTN_VOL_DOWN && currentpos < amount - 1){
currentpos++;
while(entries[currentpos].property & (ISSKIP | ISHIDE) && currentpos < amount - 1)
currentpos++;
}
}
minerva_periodic_training();
//return (mode) ? currentpos : entries[currentpos].property;
return currentpos;
}

View File

@@ -0,0 +1,4 @@
#pragma once
#include "../common/types.h"
int menu_make(menu_entry *entries, int amount, char *toptext);

View File

@@ -1,255 +0,0 @@
#include <string.h>
#include "../mem/heap.h"
#include "gfx.h"
#include "fs.h"
#include "../utils/types.h"
#include "../libs/fatfs/ff.h"
#include "../utils/sprintf.h"
#include "../utils/btn.h"
#include "../gfx/gfx.h"
#include "../utils/util.h"
#include "io.h"
bool checkfile(char* path){
FRESULT fr;
FILINFO fno;
fr = f_stat(path, &fno);
return !(fr & FR_NO_FILE);
}
void viewbytes(char *path){
FIL in;
u8 print[2048];
u32 size;
QWORD offset = 0;
int res;
clearscreen();
res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING);
if (res != FR_OK){
message(COLOR_RED, "File Opening Failed\nErrcode %d", res);
return;
}
msleep(200);
while (1){
f_lseek(&in, offset * 16);
res = f_read(&in, &print, 2048 * sizeof(u8), &size);
if (res != FR_OK){
message(COLOR_RED, "Reading Failed!\nErrcode %d", res);
return;
}
printbytes(print, size, offset * 16);
res = btn_read();
if (!res)
res = btn_wait();
if (res & BTN_VOL_DOWN && 2048 * sizeof(u8) == size)
offset++;
if (res & BTN_VOL_UP && offset > 0)
offset--;
if (res & BTN_POWER)
break;
}
f_close(&in);
}
int copy(const char *locin, const char *locout, bool print, bool canCancel){
FIL in, out;
FILINFO in_info;
u64 sizeoffile, sizecopied = 0, totalsize;
UINT temp1, temp2;
u8 *buff;
unsigned int x, y, i = 0;
int res;
gfx_con_getpos(&x, &y);
if (!strcmp(locin, locout)){
return 21;
}
if ((res = f_open(&in, locin, FA_READ | FA_OPEN_EXISTING))){
return 22;
}
if (f_stat(locin, &in_info))
return 22;
if (f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE)){
return 23;
}
buff = malloc (BUFSIZE);
sizeoffile = f_size(&in);
totalsize = sizeoffile;
while (sizeoffile > 0){
if ((res = f_read(&in, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp1)))
return res;
if ((res = f_write(&out, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp2)))
return res;
if (temp1 != temp2)
return 24;
sizeoffile -= temp1;
sizecopied += temp1;
if (print && 10 > i++){
gfx_printf("%k[%d%%]%k", COLOR_GREEN, ((sizecopied * 100) / totalsize) ,COLOR_WHITE);
gfx_con_setpos(x, y);
i = 0;
if (canCancel)
if (btn_read() & BTN_VOL_DOWN){
f_unlink(locout);
break;
}
}
}
f_close(&in);
f_close(&out);
free(buff);
if ((res = f_chmod(locout, in_info.fattrib, 0x3A)))
return res;
f_stat(locin, &in_info); //somehow stops fatfs from being weird
return 0;
}
u64 getfilesize(char *path){
FILINFO fno;
f_stat(path, &fno);
return fno.fsize;
}
int getfolderentryamount(const char *path){
DIR dir;
FILINFO fno;
int folderamount = 0;
if ((f_opendir(&dir, path))){
return -1;
}
while (!f_readdir(&dir, &fno) && fno.fname[0]){
folderamount++;
}
f_closedir(&dir);
return folderamount;
}
void makestring(char *in, char **out){
*out = (char *) malloc (strlen(in) + 1);
strcpy(*out, in);
}
int del_recursive(char *path){
DIR dir;
FILINFO fno;
int res;
u32 x, y;
char *localpath = NULL;
gfx_con_getpos(&x, &y);
makestring(path, &localpath);
if ((res = f_opendir(&dir, localpath))){
//message(COLOR_RED, "Error during f_opendir: %d", res);
return -1;
}
while (!f_readdir(&dir, &fno) && fno.fname[0]){
if (fno.fattrib & AM_DIR){
del_recursive(getnextloc(localpath, fno.fname));
}
else {
gfx_box(0, y, 719, y + 16, COLOR_DEFAULT);
SWAPCOLOR(COLOR_RED);
gfx_printf("\r");
gfx_print_length(37, fno.fname);
gfx_printf(" ");
if ((res = f_unlink(getnextloc(localpath, fno.fname))))
return res;
}
}
f_closedir(&dir);
if ((res = f_unlink(localpath))){
return res;
}
free(localpath);
return 0;
}
int copy_recursive(char *path, char *dstpath){
DIR dir;
FILINFO fno;
int res;
u32 x, y;
char *startpath = NULL, *destpath = NULL, *destfoldername = NULL, *temp = NULL;
gfx_con_getpos(&x, &y);
makestring(path, &startpath);
makestring(strrchr(path, '/') + 1, &destfoldername);
destpath = (char*) malloc (strlen(dstpath) + strlen(destfoldername) + 2);
sprintf(destpath, (dstpath[strlen(dstpath) - 1] == '/') ? "%s%s" : "%s/%s", dstpath, destfoldername);
if ((res = f_opendir(&dir, startpath))){
message(COLOR_RED, "Error during f_opendir: %d", res);
return 21;
}
f_mkdir(destpath);
while (!f_readdir(&dir, &fno) && fno.fname[0]){
if (fno.fattrib & AM_DIR){
copy_recursive(getnextloc(startpath, fno.fname), destpath);
}
else {
gfx_box(0, y, 719, y + 16, COLOR_DEFAULT);
SWAPCOLOR(COLOR_GREEN);
gfx_printf("\r");
gfx_print_length(37, fno.fname);
gfx_printf(" ");
makestring(getnextloc(startpath, fno.fname), &temp);
if ((res = copy(temp, getnextloc(destpath, fno.fname), true, false))){
return res;
}
free(temp);
}
}
f_closedir(&dir);
if (f_stat(startpath, &fno))
return 22;
if ((res = f_chmod(destpath, fno.fattrib, 0x3A)))
return res;
free(startpath);
free(destpath);
free(destfoldername);
return 0;
}

View File

@@ -1,10 +0,0 @@
#pragma once
bool checkfile(char* path);
void viewbytes(char *path);
int copy(const char *locin, const char *locout, bool print, bool canCancel);
u64 getfilesize(char *path);
int getfolderentryamount(const char *path);
void makestring(char *in, char **out);
int del_recursive(char *path);
int copy_recursive(char *path, char *dstpath);

View File

@@ -0,0 +1,186 @@
#include <stdio.h>
#include <string.h>
#include "mainmenu.h"
#include "../utils/util.h"
#include "utils/tools.h"
#include "../utils/btn.h"
#include "emmc/emmc.h"
#include "../storage/emummc.h"
#include "script/functions.h"
#include "common/common.h"
#include "gfx/menu.h"
#include "utils/utils.h"
#include "gfx/gfxutils.h"
#include "fs/fsutils.h"
#include "fs/fsmenu.h"
#include "emmc/emmcoperations.h"
#include "emmc/emmcmenu.h"
extern bool sd_mount();
extern void sd_unmount();
extern int launch_payload(char *path);
extern bool sd_inited;
extern bool sd_mounted;
int res = 0, meter = 0;
void MainMenu_SDCard(){
fileexplorer("SD:/", 0);
}
void MainMenu_EMMC(){
gfx_clearscreen();
gfx_printf("You're about to enter EMMC\nModifying anything here\n can result in a BRICK!\n\nPlease only continue\n if you know what you're doing\n\nPress Vol+/- to return\n");
if (gfx_makewaitmenu("Press Power to enter", 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);
}
void MainMenu_MountSD(){
(sd_mounted) ? sd_unmount() : sd_mount();
}
void MainMenu_Tools(){
//res = makemenu(toolsmenu, 8);
res = menu_make(mainmenu_tools, 5, "-- Tools Menu --");
switch(res){
case TOOLS_DISPLAY_INFO:
displayinfo();
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){
gfx_clearscreen();
gfx_printf("Are you sure you want to format your sd?\nThis will delete everything on your SD card\nThis action is irreversible!\n\nPress Vol+/- to cancel\n");
if(gfx_makewaitmenu("Press Power to continue", 10)){
if (format(res)){
sd_unmount();
}
}
}
}
void MainMenu_Credits(){
if (++meter >= 3)
gfx_errDisplay("credits", 53, 0);
gfx_message(COLOR_WHITE, mainmenu_credits);
}
void MainMenu_Exit(){
if (sd_mounted){
SETBIT(mainmenu_shutdown[4].property, ISHIDE, !fsutil_checkfile("/bootloader/update.bin"));
SETBIT(mainmenu_shutdown[5].property, ISHIDE, !fsutil_checkfile("/atmosphere/reboot_payload.bin"));
}
else {
for (int i = 4; i <= 5; i++)
SETBIT(mainmenu_shutdown[i].property, ISHIDE, 1);
}
res = menu_make(mainmenu_shutdown, 6, "-- Shutdown Menu --");
switch(res){
case SHUTDOWN_REBOOT_RCM:
reboot_rcm();
case SHUTDOWN_REBOOT_NORMAL:
reboot_normal();
case SHUTDOWN_POWER_OFF:
power_off();
case SHUTDOWN_HEKATE:
launch_payload("/bootloader/update.bin");
case SHUTDOWN_AMS:
launch_payload("/atmosphere/reboot_payload.bin");
} //todo declock bpmp
}
func_void_ptr mainmenu_functions[] = {
MainMenu_SDCard,
MainMenu_EMMC,
MainMenu_EMUMMC,
MainMenu_MountSD,
MainMenu_Tools,
MainMenu_SDFormat,
MainMenu_Credits,
MainMenu_Exit,
};
void RunMenuOption(int option){
if (option != 7)
meter = 0;
if (option > 0)
mainmenu_functions[option - 1]();
}
void te_main(){
int setter;
if (dump_biskeys() == -1){
gfx_errDisplay("dump_biskey", ERR_BISKEY_DUMP_FAILED, 0);
//mainmenu_main[1].property |= ISHIDE;
}
if (emummc_load_cfg()){
mainmenu_main[2].property |= ISHIDE;
}
dumpGpt();
disconnect_mmc();
while (1){
//fillmainmenu();
setter = sd_mounted;
if (emu_cfg.enabled){
SETBIT(mainmenu_main[2].property, ISHIDE, !setter);
}
SETBIT(mainmenu_main[0].property, ISHIDE, !setter);
mainmenu_main[3].name = (menu_sd_states[!setter]);
setter = sd_inited;
SETBIT(mainmenu_main[5].property, ISHIDE, !setter);
res = menu_make(mainmenu_main, 8, "-- Main Menu --") + 1;
RunMenuOption(res);
}
}

View File

@@ -2,8 +2,8 @@
#include "../utils/types.h"
#define MAINMENU_AMOUNT 12
#define CREDITS_MESSAGE "\nTegraexplorer, made by:\nSuch Meme, Many Skill\n\nProject based on:\nLockpick_RCM\nHekate\n\nCool people:\nshchmue\ndennthecafebabe\nDax"
/*
typedef struct _menu_item {
char name[50];
u32 color;
@@ -11,6 +11,7 @@ typedef struct _menu_item {
short property;
} menu_item;
enum mainmenu_return {
SD_CARD = 1,
EMMC_SAF,
@@ -38,12 +39,15 @@ enum toolsmenu_return {
DISPLAY_INFO = 1,
DISPLAY_GPIO,
DUMPFIRMWARE,
DUMPUSERSAVE
DUMPUSERSAVE,
DUMP_BOOT,
RESTORE_BOOT
};
enum formatmenu_return {
FORMAT_EMUMMC = 0,
FORMAT_ALL_FAT32
};
*/
void te_main();

View File

@@ -1,277 +0,0 @@
#include <string.h>
#include "../mem/heap.h"
#include "gfx.h"
#include "fs.h"
#include "io.h"
#include "emmc.h"
#include "../utils/types.h"
#include "../libs/fatfs/ff.h"
#include "../utils/sprintf.h"
#include "../utils/btn.h"
#include "../gfx/gfx.h"
#include "../utils/util.h"
#include "../storage/emummc.h"
#include "script.h"
#include <stdlib.h>
char func[11] = "", args[2][128] = {"", ""};
int res, errcode;
const int scriptver = 131;
bool forceExit = false;
u32 currentcolor;
void Part_SetColor(){
if (strcmpcheck(args[0], "RED"))
currentcolor = COLOR_RED;
else if (strcmpcheck(args[0], "ORANGE"))
currentcolor = COLOR_ORANGE;
else if (strcmpcheck(args[0], "YELLOW"))
currentcolor = COLOR_YELLOW;
else if (strcmpcheck(args[0], "GREEN"))
currentcolor = COLOR_GREEN;
else if (strcmpcheck(args[0], "BLUE"))
currentcolor = COLOR_BLUE;
else if (strcmpcheck(args[0], "VIOLET"))
currentcolor = COLOR_VIOLET;
else if (strcmpcheck(args[0], "WHITE"))
currentcolor = COLOR_WHITE;
}
void Part_Wait(){
int waitamount, begintime;
SWAPCOLOR(currentcolor);
waitamount = atoi(args[0]);
begintime = get_tmr_s();
while (begintime + waitamount > get_tmr_s()){
gfx_printf("\r<Wait %d seconds> ", (begintime + waitamount) - get_tmr_s());
}
gfx_printf("\r \r");
}
void Part_VersionCheck(){
int givenversion = atoi(args[0]);
if (givenversion > scriptver){
gfx_printf("Script required version is too high\nUpdate TegraExplorer!");
btn_wait();
forceExit = true;
}
}
void Part_Move(){
errcode = f_rename(args[0], args[1]);
if (errcode)
f_rename(args[0], args[1]);
}
void Part_Delete(){
errcode = f_unlink(args[0]);
if (errcode)
f_unlink(args[0]);
}
void Part_DeleteRecursive(){
errcode = del_recursive(args[0]);
}
void Part_Copy(){
errcode = copy(args[0], args[1], true, false);
}
void Part_RecursiveCopy(){
errcode = copy_recursive(args[0], args[1]);
}
void Part_MakeFolder(){
errcode = f_mkdir(args[0]);
if (errcode)
f_mkdir(args[0]);
}
void Part_ConnectMMC(){
if (strcmpcheck(args[0], "SYSMMC"))
connect_mmc(SYSMMC);
if (strcmpcheck(args[0], "EMUMMC"))
connect_mmc(EMUMMC);
}
void Part_MountMMC(){
errcode = mount_mmc(args[0], 2);
}
void Part_Print(){
RESETCOLOR;
SWAPCOLOR(currentcolor);
gfx_printf("%s\n", args[0]);
}
void Part_ErrorPrint(){
RESETCOLOR;
SWAPCOLOR(COLOR_RED);
gfx_printf("Errorcode: %d\n", errcode);
}
void Part_Exit(){
forceExit = true;
}
u8 buttons_pressed = 0;
void Part_WaitOnUser(){
buttons_pressed = btn_wait();
}
script_parts parts[] = {
{"COPY", Part_Copy, 2},
{"COPY-R", Part_RecursiveCopy, 2},
{"MKDIR", Part_MakeFolder, 1},
{"CON_MMC", Part_ConnectMMC, 1},
{"MNT_MMC", Part_MountMMC, 1},
{"PRINT", Part_Print, 1},
{"ERRPRINT", Part_ErrorPrint, 0},
{"EXIT", Part_Exit, 0},
{"PAUSE", Part_WaitOnUser, 0},
{"DEL", Part_Delete, 1},
{"DEL-R", Part_DeleteRecursive, 1},
{"MOVE", Part_Move, 2},
{"VERSION", Part_VersionCheck, 1},
{"WAIT", Part_Wait, 1},
{"COLOR", Part_SetColor, 1},
{"NULL", NULL, -1}
};
int ParsePart(){
int i;
for (i = 0; parts[i].arg_amount != -1; i++){
if (strcmpcheck(func, parts[i].name))
return i;
}
gfx_printf("Parsing error...\nPress any key to continue");
btn_wait();
forceExit = true;
return -1;
}
FIL in;
UINT endByte = 0;
char GetNextByte(){
char single;
f_read(&in, &single, sizeof(char), &endByte);
if (sizeof(char) != endByte)
forceExit = true;
return single;
}
void ParseScript(char* path){
char currentchar;
int strlength;
bool inifstatement = false;
forceExit = false;
currentcolor = COLOR_WHITE;
clearscreen();
res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING);
if (res != FR_OK){
message(COLOR_RED, "File Opening Failed\nErrcode %d", res);
return;
}
while (!forceExit){
currentchar = GetNextByte();
if (endByte == 0 || currentchar == (char)EOF)
break;
switch(currentchar){
case '{':
if (!inifstatement)
while (currentchar != '}')
currentchar = GetNextByte();
break;
case '}':
if (inifstatement)
inifstatement = false;
break;
case '<':
strlength = 0;
currentchar = GetNextByte();
while (currentchar != '>'){
func[strlength++] = currentchar;
currentchar = GetNextByte();
}
func[strlength] = '\0';
res = ParsePart();
if (res == -1)
break;
for (int i = 0; i < parts[res].arg_amount; i++){
while (currentchar != 0x22)
currentchar = GetNextByte();
strlength = 0;
currentchar = GetNextByte();
while (currentchar != 0x22){
args[i][strlength++] = currentchar;
currentchar = GetNextByte();
}
args[i][strlength] = '\0';
if (i < parts[res].arg_amount)
currentchar = GetNextByte();
}
parts[res].handler();
break;
case '$':
strlength = 0;
currentchar = GetNextByte();
while (currentchar != '$'){
func[strlength++] = currentchar;
currentchar = GetNextByte();
}
func[strlength] = '\0';
if (strcmpcheck(func, "ERROR") || strcmpcheck(func, "TRUE")){
inifstatement = (errcode);
}
else if (strcmpcheck(func, "NOERROR") || strcmpcheck(func, "FALSE")){
inifstatement = (!errcode);
}
else if (strcmpcheck(func, "BTN_POWER")){
inifstatement = (buttons_pressed & BTN_POWER);
}
else if (strcmpcheck(func, "BTN_VOL+")){
inifstatement = (buttons_pressed & BTN_VOL_UP);
}
else if (strcmpcheck(func, "BTN_VOL-")){
inifstatement = (buttons_pressed & BTN_VOL_DOWN);
}
else if (strcmpcheck(func, "EMUMMC")){
inifstatement = (emu_cfg.enabled);
}
else if (strcmpcheck(func, "NOEMUMMC")){
inifstatement = (!emu_cfg.enabled);
}
if (inifstatement)
while(currentchar != '{')
currentchar = GetNextByte();
break;
}
}
f_close(&in);
}

View File

@@ -1,11 +0,0 @@
#pragma once
#define strcmpcheck(x, y) (!strcmp(x, y))
typedef void (*part_handler)();
typedef struct _script_parts {
char name[11];
part_handler handler;
short arg_amount;
} script_parts;
void ParseScript(char* path);

View File

@@ -0,0 +1,594 @@
#include <string.h>
#include <stdlib.h>
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../emmc/emmc.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../gfx/gfx.h"
#include "../../utils/util.h"
#include "../../storage/emummc.h"
#include "parser.h"
#include "../common/common.h"
#include "../fs/fsactions.h"
#include "variables.h"
#include "../utils/utils.h"
#include "functions.h"
#include "../fs/fsutils.h"
#include "../../utils/sprintf.h"
#include "../fs/fsactions.h"
#include "../emmc/emmcoperations.h"
#include "../emmc/emmcmenu.h"
extern FIL scriptin;
extern char **argv;
extern u32 argc;
extern int forceExit;
extern short currentlyMounted;
int parseIntInput(char *in, int *out){
if (in[0] == '@'){
if (str_int_find(in, out))
return -1;
}
else
*out = atoi(in);
return 0;
}
/*
int parseJmpInput(char *in, u64 *out){
if (in[0] == '?'){
if (str_jmp_find(in, out))
return -1;
else
return 0;
}
else
return -1;
}
*/
int parseStringInput(char *in, char **out){
if (in[0] == '$'){
if (str_str_find(in, out))
return -1;
else
return 0;
}
else{
*out = in;
return 0;
}
}
u32 currentcolor = COLOR_WHITE;
int part_printf(){
SWAPCOLOR(currentcolor);
for (int i = 0; i < argc; i++){
if (argv[i][0] == '@'){
int toprintint;
if (parseIntInput(argv[i], &toprintint))
return -1;
gfx_printf("%d", toprintint);
}
else {
char *toprintstring;
if (parseStringInput(argv[i], &toprintstring))
return -1;
gfx_printf(toprintstring);
}
}
gfx_printf("\n");
return 0;
}
int part_print_int(){
int toprint;
if (parseIntInput(argv[0], &toprint))
return -1;
SWAPCOLOR(currentcolor);
gfx_printf("%s: %d\n", argv[0], toprint);
return 0;
}
int part_Wait(){
int arg;
u32 begintime;
SWAPCOLOR(currentcolor);
if (parseIntInput(argv[0], &arg))
return -1;
begintime = get_tmr_s();
while (begintime + arg > get_tmr_s()){
gfx_printf("\r<Wait %d seconds> ", (begintime + arg) - get_tmr_s());
}
gfx_printf("\r \r");
return 0;
}
int part_Check(){
int left, right;
if (parseIntInput(argv[0], &left))
return -1;
if (parseIntInput(argv[2], &right))
return -1;
if (!strcmp(argv[1], "=="))
return (left == right);
else if (!strcmp(argv[1], "!="))
return (left != right);
else if (!strcmp(argv[1], ">="))
return (left >= right);
else if (!strcmp(argv[1], "<="))
return (left <= right);
else if (!strcmp(argv[1], ">"))
return (left > right);
else if (!strcmp(argv[1], "<"))
return (left < right);
else
return -1;
}
int part_if(){
int condition;
if (parseIntInput(argv[0], &condition))
return -1;
getfollowingchar('{');
if (!condition)
skipbrackets();
return 0;
/*
if (condition)
return 0;
else {
skipbrackets();
return 0;
}
*/
}
int part_if_args(){
int condition;
if ((condition = part_Check()) < 0)
return -1;
getfollowingchar('{');
if (!condition)
skipbrackets();
return 0;
}
int part_Math(){
int left, right;
if (parseIntInput(argv[0], &left))
return -1;
if (parseIntInput(argv[2], &right))
return -1;
switch (argv[1][0]){
case '+':
return left + right;
case '-':
return left - right;
case '*':
return left * right;
case '/':
return left / right;
}
return -1;
}
int part_SetInt(){
int out;
parseIntInput(argv[0], &out);
return out;
}
int part_SetString(){
char *arg0;
if (parseStringInput(argv[0], &arg0))
return -1;
if (argv[1][0] != '$')
return -1;
str_str_add(argv[1], arg0);
return 0;
}
int part_SetStringIndex(){
int index;
char *out;
if (parseIntInput(argv[0], &index))
return -1;
if (argv[1][0] != '$')
return -1;
if (str_str_index(index, &out))
return -1;
str_str_add(argv[1], out);
return 0;
}
int part_goto(){
int target = 0;
if (parseIntInput(argv[0], &target))
return -1;
f_lseek(&scriptin, target);
return 0;
}
int part_invert(){
int arg;
if (parseIntInput(argv[0], &arg))
return -1;
return (arg) ? 0 : 1;
}
int part_fs_exists(){
char *path;
if (parseStringInput(argv[0], &path))
return -1;
return fsutil_checkfile(path);
}
int part_ConnectMMC(){
char *arg;
parseStringInput(argv[0], &arg);
if (!strcmp(arg, "SYSMMC"))
connect_mmc(SYSMMC);
else if (!strcmp(arg, "EMUMMC"))
connect_mmc(EMUMMC);
else
return -1;
return 0;
}
int part_MountMMC(){
char *arg;
parseStringInput(argv[0], &arg);
return mount_mmc(arg, 2);
}
int part_Pause(){
int res;
while (btn_read() != 0);
res = btn_wait();
str_int_add("@BTN_POWER", (res & BTN_POWER));
str_int_add("@BTN_VOL+", (res & BTN_VOL_UP));
str_int_add("@BTN_VOL-", (res & BTN_VOL_DOWN));
return res;
}
int part_addstrings(){
char *combined, *left, *middle;
if (parseStringInput(argv[0], &left))
return -1;
if (parseStringInput(argv[1], &middle))
return -1;
if (argv[2][0] != '$')
return -1;
combined = calloc(strlen(left) + strlen(middle) + 1, sizeof(char));
sprintf(combined, "%s%s", left, middle);
str_str_add(argv[2], combined);
free(combined);
return 0;
}
int part_setColor(){
char *arg;
if (parseStringInput(argv[0], &arg))
return -1;
if (!strcmp(arg, "RED"))
currentcolor = COLOR_RED;
else if (!strcmp(arg, "ORANGE"))
currentcolor = COLOR_ORANGE;
else if (!strcmp(arg, "YELLOW"))
currentcolor = COLOR_YELLOW;
else if (!strcmp(arg, "GREEN"))
currentcolor = COLOR_GREEN;
else if (!strcmp(arg, "BLUE"))
currentcolor = COLOR_BLUE;
else if (!strcmp(arg, "VIOLET"))
currentcolor = COLOR_VIOLET;
else if (!strcmp(arg, "WHITE"))
currentcolor = COLOR_WHITE;
else
return -1;
return 0;
}
int part_Exit(){
forceExit = true;
return 0;
}
int part_fs_Move(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
if (parseStringInput(argv[1], &right))
return -1;
int res;
res = f_rename(left, right);
if (res)
res = f_rename(left, right);
return res;
}
int part_fs_Delete(){
char *arg;
if (parseStringInput(argv[0], &arg))
return -1;
int res;
res = f_unlink(arg);
if (res)
res = f_unlink(arg);
return res;
}
int part_fs_DeleteRecursive(){
char *arg;
if (parseStringInput(argv[0], &arg))
return -1;
return fsact_del_recursive(arg);
}
int part_fs_Copy(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
if (parseStringInput(argv[1], &right))
return -1;
return fsact_copy(left, right, COPY_MODE_PRINT);
}
int part_fs_CopyRecursive(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
if (parseStringInput(argv[1], &right))
return -1;
return fsact_copy_recursive(left, right);
}
int part_fs_MakeDir(){
char *arg;
if (parseStringInput(argv[0], &arg))
return -1;
int res;
res = f_mkdir(arg);
if (res)
res = f_mkdir(arg);
return res;
}
DIR dir;
FILINFO fno;
int isdirvalid = false;
int part_fs_OpenDir(){
char *path;
if (parseStringInput(argv[0], &path))
return -1;
if (f_opendir(&dir, path))
return -1;
isdirvalid = true;
str_int_add("@ISDIRVALID", isdirvalid);
return 0;
}
int part_fs_CloseDir(){
if (!isdirvalid)
return 0;
f_closedir(&dir);
isdirvalid = false;
str_int_add("@ISDIRVALID", isdirvalid);
return 0;
}
int part_fs_ReadDir(){
if (!isdirvalid)
return -1;
if (!f_readdir(&dir, &fno) && fno.fname[0]){
str_str_add("$FILENAME", fno.fname);
str_int_add("@ISDIR", (fno.fattrib & AM_DIR) ? 1 : 0);
}
else {
part_fs_CloseDir();
}
return 0;
}
int part_setPrintPos(){
int left, right;
if (parseIntInput(argv[0], &left))
return -1;
if (parseIntInput(argv[1], &right))
return -1;
if (left > 42)
return -1;
if (right > 78)
return -1;
gfx_con_setpos(left * 16, right * 16);
return 0;
}
int part_stringcompare(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
if (parseStringInput(argv[1], &right))
return -1;
return (strcmp(left, right)) ? 0 : 1;
}
int part_fs_combinePath(){
char *combined, *left, *middle;
if (parseStringInput(argv[0], &left))
return -1;
if (parseStringInput(argv[1], &middle))
return -1;
if (argv[2][0] != '$')
return -1;
combined = fsutil_getnextloc(left, middle);
str_str_add(argv[2], combined);
free(combined);
return 0;
}
int part_mmc_dumpPart(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return -1;
if (parseStringInput(argv[1], &right))
return -1;
if (!strcmp(left, "BOOT")){
return emmcDumpBoot(right);
}
else {
return emmcDumpSpecific(left, right);
}
}
int part_mmc_restorePart(){
char *path;
if (parseStringInput(argv[0], &path))
return -1;
if (currentlyMounted < 0)
return -1;
return mmcFlashFile(path, currentlyMounted);
}
int part_fs_extractBisFile(){
char *path, *outfolder;
if (parseStringInput(argv[0], &path))
return -1;
if (parseStringInput(argv[1], &outfolder))
return -1;
return extract_bis_file(path, outfolder);
}
int part_clearscreen(){
gfx_clearscreen();
return 0;
}
int part_getPos(){
return (int)f_tell(&scriptin);
}
str_fnc_struct functions[] = {
{"printf", part_printf, 255},
{"printInt", part_print_int, 1},
{"setPrintPos", part_setPrintPos, 2},
{"clearscreen", part_clearscreen, 0},
{"if", part_if, 1},
{"if", part_if_args, 3}, // function overloading
{"math", part_Math, 3},
{"check", part_Check, 3},
{"setInt", part_SetInt, 1},
{"goto", part_goto, 1},
{"setString", part_SetString, 2},
{"setStringIndex", part_SetStringIndex, 2},
{"setColor", part_setColor, 1},
{"combineStrings", part_addstrings, 3},
{"compareStrings", part_stringcompare, 2},
{"invert", part_invert, 1},
{"fs_exists", part_fs_exists, 1},
{"fs_move", part_fs_Move, 2},
{"fs_mkdir", part_fs_MakeDir, 1},
{"fs_del", part_fs_Delete, 1},
{"fs_delRecursive", part_fs_DeleteRecursive, 1},
{"fs_copy", part_fs_Copy, 2},
{"fs_copyRecursive", part_fs_CopyRecursive, 2},
{"fs_openDir", part_fs_OpenDir, 1},
{"fs_closeDir", part_fs_CloseDir, 0},
{"fs_readDir", part_fs_ReadDir, 0},
{"fs_combinePath", part_fs_combinePath, 3},
{"fs_extractBisFile", part_fs_extractBisFile, 2},
{"mmc_connect", part_ConnectMMC, 1},
{"mmc_mount", part_MountMMC, 1},
{"mmc_dumpPart", part_mmc_dumpPart, 2},
{"mmc_restorePart", part_mmc_restorePart, 1},
{"getPosition", part_getPos, 0},
{"pause", part_Pause, 0},
{"wait", part_Wait, 1},
{"exit", part_Exit, 0},
{NULL, NULL, 0}
};
int run_function(char *func_name, int *out){
for (u32 i = 0; functions[i].key != NULL; i++){
if (!strcmp(functions[i].key, func_name)){
if (argc != functions[i].arg_count && functions[i].arg_count != 255)
continue;
*out = functions[i].value();
return (*out < 0) ? -1 : 0;
}
}
return -1;
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include "../../utils/types.h"
typedef void (*func_void_ptr)();
typedef int (*func_int_ptr)();
typedef struct {
char *key;
func_int_ptr value;
u8 arg_count;
} str_fnc_struct;
int run_function(char *func_name, int *out);

View File

@@ -0,0 +1,310 @@
#include <string.h>
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../emmc/emmc.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../gfx/gfx.h"
#include "../../utils/util.h"
#include "../../storage/emummc.h"
#include "parser.h"
#include "../common/common.h"
#include "../fs/fsactions.h"
#include "functions.h"
#include "variables.h"
#include "../fs/fsreader.h"
#include "../utils/utils.h"
u32 countchars(char* in, char target) {
u32 len = strlen(in);
u32 count = 0;
for (u32 i = 0; i < len; i++) {
if (in[i] == '"'){
i++;
while (in[i] != '"'){
i++;
if (i >= len)
return -1;
}
}
if (in[i] == target)
count++;
}
return count;
}
char **argv = NULL;
u32 argc;
u32 splitargs(char* in) {
// arg like '5, "6", @arg7'
u32 i, current = 0, count = 1, len = strlen(in), curcount = 0;
if ((count += countchars(in, ',')) < 0){
return 0;
}
/*
if (argv != NULL) {
for (i = 0; argv[i] != NULL; i++)
free(argv[i]);
free(argv);
}
*/
argv = calloc(count + 1, sizeof(char*));
for (i = 0; i < count; i++)
argv[i] = calloc(96, sizeof(char));
for (i = 0; i < len && curcount < count; i++) {
if (in[i] == ',') {
curcount++;
current = 0;
}
else if (in[i] == '@' || in[i] == '$' || in[i] == '?') {
while (in[i] != ',' && in[i] != ' ' && in[i] != ')' && i < len) {
argv[curcount][current++] = in[i++];
}
i--;
}
else if ((in[i] >= '0' && in[i] <= '9') || (in[i] >= '<' && in[i] <= '>') || in[i] == '+' || in[i] == '-' || in[i] == '*' || in[i] == '/')
argv[curcount][current++] = in[i];
else if (in[i] == '"') {
i++;
while (in[i] != '"') {
argv[curcount][current++] = in[i++];
}
}
}
return count;
}
FIL scriptin;
UINT endByte = 0;
int forceExit = false;
char currentchar = 0;
char getnextchar(){
f_read(&scriptin, &currentchar, sizeof(char), &endByte);
if (sizeof(char) != endByte)
forceExit = true;
//gfx_printf("|%c|", currentchar);
return currentchar;
}
void getfollowingchar(char end){
while (currentchar != end && !f_eof(&scriptin)){
if (currentchar == '"'){
while (getnextchar() != '"' && !f_eof(&scriptin));
}
getnextchar();
}
}
void getnextvalidchar(){
while ((!((currentchar >= '?' && currentchar <= 'Z') || (currentchar >= 'a' && currentchar <= 'z') || currentchar == '#') && !f_eof(&scriptin)) /*|| currentchar == ';' */)
getnextchar();
}
char *makestr(u32 size, char ignore){
char *str;
u32 count = 0;
str = calloc(size + 1, sizeof(char));
for (u32 i = 0; i < size; i++){
getnextchar();
if (ignore != 0 && ignore == currentchar)
continue;
str[count++] = currentchar;
}
return str;
}
char *readtilchar(char end, char ignore){
FSIZE_t offset, size;
offset = f_tell(&scriptin);
getfollowingchar(end);
size = f_tell(&scriptin) - offset;
if (size <= 0)
return NULL;
f_lseek(&scriptin, offset - 1);
return makestr((u32)size, ignore);
}
char *funcbuff = NULL;
void functionparser(){
char *unsplitargs;
/*
if (funcbuff != NULL)
free(funcbuff);
*/
funcbuff = readtilchar('(', ' ');
getfollowingchar('(');
getnextchar();
unsplitargs = readtilchar(')', 0);
if (unsplitargs != NULL){
argc = splitargs(unsplitargs);
getnextchar();
}
else {
argc = 0;
}
getnextchar();
free(unsplitargs);
}
char *gettargetvar(){
char *variable = NULL;
variable = readtilchar('=', ' ');
getfollowingchar('=');
getnextchar();
return variable;
}
void mainparser(){
char *variable = NULL;
int res, out = 0;
getnextvalidchar();
if (f_eof(&scriptin))
return;
if (currentchar == '#'){
getfollowingchar('\n');
return;
}
if (currentchar == '@'){
variable = gettargetvar();
getnextvalidchar();
}
/*
if (currentchar == '?'){
char *jumpname;
jumpname = readtilchar(';', ' ');
getnextchar();
str_jmp_add(jumpname, f_tell(&scriptin));
getfollowingchar('\n');
return;
}
*/
functionparser();
res = run_function(funcbuff, &out);
if (res < 0){
printerrors = true;
//gfx_printf("%s|%s|%d", funcbuff, argv[0], argc);
//btn_wait();
gfx_errDisplay("mainparser", ERR_PARSE_FAIL, f_tell(&scriptin));
forceExit = true;
//gfx_printf("Func: %s\nArg1: %s\n", funcbuff, argv[0]);
}
else {
str_int_add("@RESULT", out);
if (variable != NULL)
str_int_add(variable, out);
}
//gfx_printf("\nGoing to next func %c\n", currentchar);
if (funcbuff != NULL){
free(funcbuff);
funcbuff = NULL;
}
if (argv != NULL) {
for (int i = 0; argv[i] != NULL; i++)
free(argv[i]);
free(argv);
argv = NULL;
}
if (variable != NULL){
free(variable);
}
}
void skipbrackets(){
u32 bracketcounter = 0;
getfollowingchar('{');
getnextchar();
while ((currentchar != '}' || bracketcounter != 0) && !f_eof(&scriptin)){
if (currentchar == '{')
bracketcounter++;
else if (currentchar == '}')
bracketcounter--;
getnextchar();
}
}
extern u32 currentcolor;
extern char *currentpath;
void runScript(char *path){
int res;
char *path_local = NULL;
forceExit = false;
currentchar = 0;
currentcolor = COLOR_WHITE;
gfx_clearscreen();
utils_copystring(path, &path_local);
res = f_open(&scriptin, path, FA_READ | FA_OPEN_EXISTING);
if (res != FR_OK){
gfx_errDisplay("ParseScript", res, 1);
return;
}
printerrors = false;
//add builtin vars
str_int_add("@EMUMMC", emu_cfg.enabled);
str_int_add("@RESULT", 0);
str_int_add("@BTN_POWER", 0);
str_int_add("@BTN_VOL+", 0);
str_int_add("@BTN_VOL-", 0);
str_str_add("$CURRENTPATH", currentpath);
//str_int_printall();
while (!f_eof(&scriptin) && !forceExit){
mainparser();
}
printerrors = true;
//str_int_printall();
f_close(&scriptin);
str_int_clear();
//str_jmp_clear();
str_str_clear();
free(path_local);
//btn_wait();
}

View File

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

View File

@@ -0,0 +1,250 @@
#include <string.h>
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../emmc/emmc.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.h"
#include "../../utils/btn.h"
#include "../../gfx/gfx.h"
#include "../../utils/util.h"
#include "../../storage/emummc.h"
#include "parser.h"
#include "../common/common.h"
#include "../fs/fsactions.h"
#include "variables.h"
#include "../utils/utils.h"
static dict_str_int *str_int_table = NULL;
static dict_str_str *str_str_table = NULL;
//static dict_str_loc *str_jmp_table = NULL;
int str_int_add(char *key, int value){
char *key_local;
dict_str_int *keyvaluepair;
utils_copystring(key, &key_local);
keyvaluepair = calloc(1, sizeof(dict_str_int));
keyvaluepair->key = key_local;
keyvaluepair->value = value;
keyvaluepair->next = NULL;
if (str_int_table == NULL){
str_int_table = keyvaluepair;
}
else {
dict_str_int *temp;
temp = str_int_table;
while (temp != NULL){
if (!strcmp(temp->key, key_local)){
free(keyvaluepair);
free(key_local);
temp->value = value;
return 0;
}
if (temp->next == NULL){
temp->next = keyvaluepair;
return 0;
}
temp = temp->next;
}
}
return 0;
}
int str_int_find(char *key, int *out){
dict_str_int *temp;
temp = str_int_table;
while (temp != NULL){
if (!strcmp(temp->key, key)){
*out = temp->value;
return 0;
}
temp = temp->next;
}
return -1;
}
void str_int_clear(){
dict_str_int *cur, *next;
cur = str_int_table;
while (cur != NULL){
next = cur->next;
free(cur->key);
free(cur);
cur = next;
}
str_int_table = NULL;
}
void str_int_printall(){
dict_str_int *temp;
temp = str_int_table;
while (temp != NULL){
gfx_printf("%s -> %d\n", temp->key, temp->value);
temp = temp->next;
}
}
/*
int str_jmp_add(char *key, u64 value){
char *key_local;
dict_str_loc *keyvaluepair;
//gfx_printf("Adding |%s|\n", key_local);
utils_copystring(key, &key_local);
keyvaluepair = calloc(1, sizeof(dict_str_loc));
keyvaluepair->key = key_local;
keyvaluepair->value = value;
keyvaluepair->next = NULL;
if (str_jmp_table == NULL){
str_jmp_table = keyvaluepair;
}
else {
dict_str_loc *temp;
temp = str_jmp_table;
while (temp != NULL){
if (!strcmp(temp->key, key_local)){
free(keyvaluepair);
free(key_local);
temp->value = value;
return 0;
}
if (temp->next == NULL){
temp->next = keyvaluepair;
return 0;
}
temp = temp->next;
}
}
return 0;
}
int str_jmp_find(char *key, u64 *out){
dict_str_loc *temp;
temp = str_jmp_table;
//gfx_printf("Searching |%s|\n", key);
while (temp != NULL){
if (!strcmp(temp->key, key)){
//gfx_printf("Key found!\n", temp->value);
*out = temp->value;
return 0;
}
temp = temp->next;
}
//gfx_printf("no key!\n");
return -1;
}
void str_jmp_clear(){
dict_str_loc *cur, *next;
cur = str_jmp_table;
while (cur != NULL){
next = cur->next;
free(cur->key);
free(cur);
cur = next;
}
str_jmp_table = NULL;
}
*/
int str_str_add(char *key, char *value){
char *key_local, *value_local;
dict_str_str *keyvaluepair;
//gfx_printf("Adding |%s|\n", key_local);
utils_copystring(value, &value_local);
utils_copystring(key, &key_local);
keyvaluepair = calloc(1, sizeof(dict_str_str));
keyvaluepair->key = key_local;
keyvaluepair->value = value_local;
keyvaluepair->next = NULL;
if (str_str_table == NULL){
str_str_table = keyvaluepair;
}
else {
dict_str_str *temp;
temp = str_str_table;
while (temp != NULL){
if (!strcmp(temp->key, key_local)){
free(keyvaluepair);
free(key_local);
free(temp->value);
temp->value = value_local;
return 0;
}
if (temp->next == NULL){
temp->next = keyvaluepair;
return 0;
}
temp = temp->next;
}
}
return 0;
}
int str_str_find(char *key, char **out){
dict_str_str *temp;
temp = str_str_table;
while (temp != NULL){
if (!strcmp(temp->key, key)){
*out = temp->value;
return 0;
}
temp = temp->next;
}
return -1;
}
int str_str_index(int index, char **out){
dict_str_str *temp;
temp = str_str_table;
for (int i = 0; i < index; i++){
if (temp == NULL)
return -1;
temp = temp->next;
}
if (temp == NULL)
return -1;
*out = temp->value;
return 0;
}
void str_str_clear(){
dict_str_str *cur, *next;
cur = str_str_table;
while (cur != NULL){
next = cur->next;
free(cur->key);
free(cur->value);
free(cur);
cur = next;
}
str_str_table = NULL;
}

View File

@@ -0,0 +1,34 @@
#pragma once
#include "../../utils/types.h"
typedef struct _dict_str_int {
char *key;
int value;
struct _dict_str_int *next;
} dict_str_int;
typedef struct _dict_str_str {
char *key;
char *value;
struct _dict_str_str *next;
} dict_str_str;
typedef struct _dict_str_loc {
char *key;
u64 value;
struct _dict_str_loc *next;
} dict_str_loc;
int str_int_add(char *key, int value);
int str_int_find(char *key, int *out);
void str_int_clear();
void str_int_printall();
/*
int str_jmp_add(char *key, u64 value);
int str_jmp_find(char *key, u64 *out);
void str_jmp_clear();
*/
int str_str_add(char *key, char *value);
int str_str_find(char *key, char **out);
int str_str_index(int index, char **out);
void str_str_clear();

View File

@@ -1,249 +0,0 @@
#include <stdio.h>
#include <string.h>
#include "te.h"
#include "gfx.h"
#include "../utils/util.h"
#include "tools.h"
#include "fs.h"
#include "io.h"
#include "../utils/btn.h"
#include "emmc.h"
#include "../storage/emummc.h"
#include "script.h"
extern bool sd_mount();
extern void sd_unmount();
extern bool return_sd_mounted(int value);
extern int launch_payload(char *path);
menu_item mainmenu[MAINMENU_AMOUNT] = {
{"[SD:/] SD CARD\n", COLOR_GREEN, SD_CARD, 1},
{"[SYSTEM:/] EMMC", COLOR_ORANGE, EMMC_SYS, 1},
{"[USER:/] EMMC", COLOR_ORANGE, EMMC_USR, 1},
{"[SAFE:/] EMMC", COLOR_ORANGE, EMMC_SAF, 1},
{"\n[SYSTEM:/] EMUMMC", COLOR_BLUE, EMUMMC_SYS, 1},
{"[USER:/] EMUMMC", COLOR_BLUE, EMUMMC_USR, 1},
{"[SAFE:/] EMUMMC", COLOR_BLUE, EMUMMC_SAF, 1},
{"\nMount/Unmount SD", COLOR_WHITE, MOUNT_SD, 1},
{"Tools", COLOR_VIOLET, TOOLS, 1},
{"SD format", COLOR_VIOLET, SD_FORMAT, 1},
{"\nCredits", COLOR_WHITE, CREDITS, 1},
{"Exit", COLOR_WHITE, EXIT, 1}
};
menu_item shutdownmenu[7] = {
{"-- EXIT --\n", COLOR_ORANGE, -1, 0},
{"Back", COLOR_WHITE, -1, 1},
{"\nReboot to RCM", COLOR_VIOLET, REBOOT_RCM, 1},
{"Reboot normally", COLOR_ORANGE, REBOOT_NORMAL, 1},
{"Power off\n", COLOR_BLUE, POWER_OFF, 1},
{"Reboot to Hekate", COLOR_GREEN, HEKATE, -1},
{"Reboot to Atmosphere", COLOR_GREEN, AMS, -1}
};
menu_item toolsmenu[6] = {
{"-- TOOLS --\n", COLOR_VIOLET, -1, 0},
{"Back", COLOR_WHITE, -1, 1},
{"\nDisplay Console Info", COLOR_GREEN, DISPLAY_INFO, 1},
{"Display GPIO pins", COLOR_VIOLET, DISPLAY_GPIO, 1},
{"Dump Firmware", COLOR_BLUE, DUMPFIRMWARE, 1},
{"Dump User Saves", COLOR_YELLOW, DUMPUSERSAVE, 1}
};
menu_item formatmenu[4] = {
{"-- FORMAT SD --\n", COLOR_RED, -1, 0},
{"Back\n", COLOR_WHITE, -1, 1},
{"Format entire SD to FAT32", COLOR_RED, FORMAT_ALL_FAT32, 1},
{"Format for EmuMMC setup (FAT32/RAW)", COLOR_RED, FORMAT_EMUMMC, 1}
};
menu_item mmcChoice[3] = {
{"Back\n", COLOR_WHITE, -1, 1},
{"SysMMC", COLOR_ORANGE, SYSMMC, 1},
{"EmuMMC", COLOR_BLUE, EMUMMC, 1}
};
const char emmc_entries[3][8] = {
"SAFE",
"SYSTEM",
"USER"
};
int res = 0;
void MainMenu_SDCard(){
fileexplorer("SD:/");
}
void MainMenu_EMMC(){
if (makewaitmenu("You're about to enter EMMC\nModifying anything here\n can result in a BRICK!\n\nPlease only continue\n if you know what you're doing\n\nPress Vol+/- to return\n", "Press Power to enter", 4)){
connect_mmc(SYSMMC);
if (!mount_mmc(emmc_entries[res - 2], res - 1))
fileexplorer("emmc:/");
else
message(COLOR_RED, "EMMC failed to mount!");
}
}
void MainMenu_EMUMMC(){
connect_mmc(EMUMMC);
if (!mount_mmc(emmc_entries[res - 5], res - 4))
fileexplorer("emmc:/");
else
message(COLOR_RED, "EMUMMC failed to mount!");
}
void MainMenu_MountSD(){
if (return_sd_mounted(1))
sd_unmount();
else
sd_mount();
}
void MainMenu_Tools(){
res = makemenu(toolsmenu, 6);
switch(res){
case DISPLAY_INFO:
displayinfo();
break;
case DISPLAY_GPIO:
displaygpio();
break;
case DUMPFIRMWARE:
dumpfirmware(SYSMMC);
break;
case DUMPUSERSAVE:
if (mainmenu[4].property >= 0){
if ((res = makemenu(mmcChoice, 3)) >= 0)
dumpusersaves(res);
}
else
dumpusersaves(SYSMMC);
break;
}
}
void MainMenu_SDFormat(){
res = makemenu(formatmenu, 4);
if (res >= 0){
if(makewaitmenu("Are you sure you want to format your sd?\nThis will delete everything on your SD card\nThis action is irreversible!\n\nPress Vol+/- to cancel\n", "Press Power to continue", 10)){
if (format(res)){
sd_unmount();
}
}
}
}
void MainMenu_Credits(){
message(COLOR_WHITE, CREDITS_MESSAGE);
}
void MainMenu_Exit(){
if (return_sd_mounted(1)){
shutdownmenu[5].property = (checkfile("/bootloader/update.bin")) ? 1 : -1;
shutdownmenu[6].property = (checkfile("/atmosphere/reboot_payload.bin")) ? 1 : -1;
}
else {
shutdownmenu[5].property = -1;
shutdownmenu[6].property = -1;
}
res = makemenu(shutdownmenu, 7);
switch(res){
case REBOOT_RCM:
reboot_rcm();
case REBOOT_NORMAL:
reboot_normal();
case POWER_OFF:
power_off();
case HEKATE:
launch_payload("/bootloader/update.bin");
case AMS:
launch_payload("/atmosphere/reboot_payload.bin");
} //todo declock bpmp
}
part_handler mainmenu_functions[] = {
MainMenu_SDCard,
MainMenu_EMMC,
MainMenu_EMMC,
MainMenu_EMMC,
MainMenu_EMUMMC,
MainMenu_EMUMMC,
MainMenu_EMUMMC,
MainMenu_MountSD,
MainMenu_Tools,
MainMenu_SDFormat,
MainMenu_Credits,
MainMenu_Exit,
};
void RunMenuOption(int option){
if (option > 0)
mainmenu_functions[option - 1]();
}
void fillmainmenu(){
int i;
for (i = 0; i < MAINMENU_AMOUNT; i++){
switch (i + 1) {
case 5:
case 6:
case 7:
if (mainmenu[i].property == -2)
continue;
case 1:
case 10:
if (return_sd_mounted(i + 1))
mainmenu[i].property = 1;
else
mainmenu[i].property = -1;
break;
case 8:
if (return_sd_mounted(1)){
mainmenu[i].property = 2;
strcpy(mainmenu[i].name, "\nUnmount SD");
}
else {
mainmenu[i].property = 1;
strcpy(mainmenu[i].name, "\nMount SD");
}
break;
}
}
}
void te_main(){
if (dump_biskeys() == -1){
message(COLOR_RED, "Biskeys failed to dump!\nEmmc will not be mounted!");
mainmenu[1].property = -1;
mainmenu[2].property = -1;
mainmenu[3].property = -1;
}
if (emummc_load_cfg()){
mainmenu[4].property = -2;
mainmenu[5].property = -2;
mainmenu[6].property = -2;
}
disconnect_mmc();
while (1){
fillmainmenu();
res = makemenu(mainmenu, MAINMENU_AMOUNT);
RunMenuOption(res);
}
}

View File

@@ -1,25 +1,29 @@
#include <string.h>
#include "tools.h"
#include "gfx.h"
#include "../libs/fatfs/ff.h"
#include "../gfx/gfx.h"
#include "../utils/btn.h"
#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"
#include "emmc.h"
#include "fs.h"
#include "io.h"
#include "../gfx/gfxutils.h"
#include "../../libs/fatfs/ff.h"
#include "../../gfx/gfx.h"
#include "../../utils/btn.h"
#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"
#include "../emmc/emmc.h"
#include "../common/common.h"
#include "../fs/fsactions.h"
#include "../fs/fsutils.h"
#include "../../mem/heap.h"
#include "../utils/utils.h"
extern bool sd_mount();
extern void sd_unmount();
extern sdmmc_storage_t sd_storage;
void displayinfo(){
clearscreen();
gfx_clearscreen();
FATFS *fs;
DWORD fre_clust, fre_sect, tot_sect;
@@ -35,7 +39,12 @@ void displayinfo(){
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("Fuse count: %d\nPKG1 version: %d\nPKG1 id: %s\n\n", fuse_count, pkg1.ver, pkg1.id);
gfx_printf("Fuse count: %d\nPKG1 id: '%s'\n", fuse_count, pkg1.id);
if (pkg1.ver >= 0)
gfx_printf("PKG1 version: %d\n", pkg1.ver);
gfx_printf("\n");
print_biskeys();
RESETCOLOR;
@@ -67,7 +76,7 @@ void displayinfo(){
void displaygpio(){
int res;
clearscreen();
gfx_clearscreen();
gfx_printf("Updates gpio pins every 50ms:\nPress power to exit");
msleep(200);
while (1){
@@ -91,88 +100,91 @@ int dumpfirmware(int mmc){
FILINFO fno;
bool fail = false;
int ret, amount = 0;
char path[100] = "emmc:/Contents/registered";
char sdfolderpath[100] = "";
char syspath[100] = "";
char sdpath[100] = "";
char sysbase[] = "emmc:/Contents/registered";
char *syspathtemp, *syspath, *sdpath, *sdbase;
pkg1_info pkg1 = returnpkg1info();
u32 timer = get_tmr_s();
clearscreen();
gfx_clearscreen();
connect_mmc(mmc);
mount_mmc("SYSTEM", 2);
gfx_printf("PKG1 version: %d\n", pkg1.ver);
ret = f_mkdir("sd:/tegraexplorer");
gfx_printf("Creating sd:/tegraexplorer %d\n", ret);
gfx_printf("Creating folders...\n");
f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/Firmware");
ret = f_mkdir("sd:/tegraexplorer/Firmware");
gfx_printf("Creating sd:/tegraexplorer/Firmware %d\n", ret);
sdbase = calloc(32 + strlen(pkg1.id), sizeof(char));
sprintf(sdbase, "sd:/tegraexplorer/Firmware/%d (%s)", pkg1.ver, pkg1.id);
gfx_printf("Out: %s\n", sdbase);
f_mkdir(sdbase);
sprintf(sdfolderpath, "sd:/tegraexplorer/Firmware/%d (%s)", pkg1.ver, pkg1.id);
ret = f_mkdir(sdfolderpath);
gfx_printf("Creating %s %d\n", sdfolderpath, ret);
if ((ret = f_opendir(&dir, sysbase)))
fail = true;
ret = f_opendir(&dir, path);
gfx_printf("Result opening system:/ %d\n\n%k", ret, COLOR_GREEN);
gfx_printf("Starting dump...\n");
SWAPCOLOR(COLOR_GREEN);
printerrors = 0;
while(!f_readdir(&dir, &fno) && fno.fname[0] && !fail){
sprintf(sdpath, "%s/%s", sdfolderpath, fno.fname);
utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &sdpath);
utils_copystring(fsutil_getnextloc(sysbase, fno.fname), &syspathtemp);
if (fno.fattrib & AM_DIR)
sprintf(syspath, "%s/%s/00", path, fno.fname);
if (fno.fattrib & AM_DIR){
utils_copystring(fsutil_getnextloc(syspathtemp, "00"), &syspath);
free(syspathtemp);
}
else
sprintf(syspath, "%s/%s", path, fno.fname);
syspath = syspathtemp;
ret = copy(syspath, sdpath, false, false);
ret = fsact_copy(syspath, sdpath, 0);
gfx_printf("%d %s\r", ++amount, fno.fname);
if (ret != 0)
fail = true;
free(sdpath);
free(syspath);
}
printerrors = 1;
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);
free(sdbase);
btn_wait();
return fail;
}
void dumpusersaves(int mmc){
int res;
connect_mmc(mmc);
mount_mmc("USER", 2);
clearscreen();
gfx_clearscreen();
res = f_mkdir("sd:/tegraexplorer");
gfx_printf("Creating sd:/tegraexplorer, res: %d\nCopying:\n", res);
gfx_printf("Creating folders...\n");
f_mkdir("sd:/tegraexplorer");
gfx_printf("Starting dump...\n");
SWAPCOLOR(COLOR_GREEN);
res = copy_recursive("emmc:/save", "sd:/tegraexplorer");
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("\rResult copy_recursive() %d\n\n", res);
if (res){
SWAPCOLOR(COLOR_RED);
gfx_printf("Dump failed!\n");
}
else
gfx_printf("Saves are located in SD:/tegraexplorer/save\n");
if(fsact_copy_recursive("emmc:/save", "sd:/tegraexplorer"))
return;
RESETCOLOR;
gfx_printf("\n\nSaves are located in SD:/tegraexplorer/save\n");
gfx_printf("Press any key to continue");
btn_wait();
}
int format(int mode){
clearscreen();
gfx_clearscreen();
int res;
bool fatalerror = false;
DWORD plist[] = {666, 61145088};
@@ -188,7 +200,7 @@ int format(int mode){
timer = get_tmr_s();
totalsectors = sd_storage.csd.capacity;
if (mode == 0){
if (mode == FORMAT_EMUMMC){
if (totalsectors < 83886080){
gfx_printf("%kYou seem to be running this on a <=32GB SD\nNot enough free space for emummc!", COLOR_RED);
fatalerror = true;

View File

@@ -0,0 +1,19 @@
#include <string.h>
#include "utils.h"
#include "../common/common.h"
#include "../gfx/menu.h"
#include "../../storage/emummc.h"
#include "../../mem/heap.h"
int utils_mmcMenu(){
if (emu_cfg.enabled)
return menu_make(utils_mmcChoice, 3, "-- Choose MMC --");
else
return SYSMMC;
}
void utils_copystring(const char *in, char **out){
int len = strlen(in) + 1;
*out = (char *) malloc (len);
strcpy(*out, in);
}

View File

@@ -0,0 +1,4 @@
#pragma once
int utils_mmcMenu();
void utils_copystring(const char *in, char **out);

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2019 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -25,11 +26,12 @@
#define _PAGEOFF(x) ((x) & 0xFFFFF000)
#define _ADRP(r, o) 0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F)
#define _BL(a, o) 0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
#define _B(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF)
#define _MOVKX(r, i, s) 0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
#define _MOVZX(r, i, s) 0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F)
#define _ADRP(r, o) (0x90000000 | ((((o) >> 12) & 0x3) << 29) | ((((o) >> 12) & 0x1FFFFC) << 3) | ((r) & 0x1F))
#define _BL(a, o) (0x94000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
#define _B(a, o) (0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF))
#define _MOVKX(r, i, s) (0xF2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
#define _MOVZX(r, i, s) (0xD2800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
#define _MOVZW(r, i, s) (0x52800000 | (((s) & 0x30) << 17) | (((i) & 0xFFFF) << 5) | ((r) & 0x1F))
#define _NOP() 0xD503201F
#endif

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2020 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -33,9 +34,10 @@
#define LIST_FOREACH_SAFE(iter, list) \
for(link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next)
/*! Iterate over all list members. */
/*! Iterate over all list members and make sure that the list has at least one entry. */
#define LIST_FOREACH_ENTRY(etype, iter, list, mn) \
for(etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn))
if ((list)->next != (list)) \
for(etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn))
typedef struct _link_t
{

View File

@@ -33,15 +33,22 @@ typedef struct _cfg_op_t
u32 val;
} cfg_op_t;
typedef struct _nyx_info_t
{
u32 rsvd;
u32 errors;
} nyx_info_t;
typedef struct _nyx_storage_t
{
u32 version;
u32 cfg;
u8 irama[0x8000];
u8 hekate[0x30000];
u8 rsvd[0x800000];
u8 rsvd[0x800000 - sizeof(nyx_info_t)];
nyx_info_t info;
mtc_config_t mtc_cfg;
emc_table_t mtc_table;
emc_table_t mtc_table[10];
} nyx_storage_t;
u32 get_tmr_us();