Start of rewrite

Based on lockpick_rcm 1.9.0
This commit is contained in:
SuchMemeManySkill
2020-12-23 17:39:22 +01:00
parent acef46781d
commit d6c4204027
441 changed files with 81040 additions and 11567 deletions

View File

@@ -1,120 +0,0 @@
#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_SCRIPT_LOOKUP_FAIL,
ERR_CANNOT_COPY_FILE_TO_FS_PART,
ERR_NO_DESTINATION,
ERR_INI_PARSE_FAIL,
ERR_IN_FUNC
};
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
};
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_RENAME,
FILE_DELETE,
FILE_PAYLOAD,
FILE_SCRIPT,
FILE_HEXVIEW,
FILE_DUMPBIS,
FILE_SIGN
};
extern menu_entry fs_menu_file[];
enum fs_menu_folder_return {
DIR_EXITFOLDER = 2,
DIR_COPYFOLDER,
DIR_DELETEFOLDER,
DIR_RENAME,
DIR_CREATE
};
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[];
extern menu_entry fwDump_typeMenu[];

View File

@@ -1,69 +0,0 @@
#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",
"FUNC LOOKUP FAIL",
"CANNOT COPY FILE TO FS PART",
"NO DESTINATION",
"INI PARSE FAIL",
"ERR IN FUNC"
};
/*
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

@@ -1,102 +0,0 @@
#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}}
};
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}},
{"Rename file", 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}},
{"Sign Save", COLOR_ORANGE, {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\n", COLOR_RED, {ISMENU}},
{"Rename folder", COLOR_BLUE, {ISMENU}},
{"Create folder", COLOR_BLUE, {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, {ISNULL | 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}}
};
menu_entry fwDump_typeMenu[] = {
{"Back\n", COLOR_WHITE, {ISMENU}},
{"Firmware format type:", COLOR_WHITE, {ISMENU | ISSKIP}},
{"Daybreak (prod.keys required!)", COLOR_BLUE, {ISMENU}},
{"ChoiNX", COLOR_VIOLET, {ISMENU}}
};

View File

@@ -1,61 +0,0 @@
#pragma once
#include "../../utils/types.h"
#define BIT(n) (1U << n)
#define ISDIR BIT(0)
#define ISMENU BIT(1)
#define SETSIZE(x) (x << 2)
#define ISNULL BIT(4)
#define ISHIDE BIT(5)
#define ISSKIP BIT(6)
#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 65536 //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;
union {
u8 property;
struct {
u8 isDir:1;
u8 isMenu:1;
u8 size:2;
u8 isNull:1;
u8 isHide:1;
u8 isSkip:1;
};
};
} menu_entry;
typedef struct {
const char *name;
u8 property;
} gpt_entry_rule;
#define isFS 0x80
#define isBOOT 0x2

View File

@@ -1,255 +0,0 @@
#include <string.h>
#include "emmc.h"
#include "../../mem/heap.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../utils/sprintf.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(sys_gpt);
LIST_INIT(emu_gpt);
u8 bis_key[4][32];
pkg1_info pkg1inf = {-1, ""};
short currentlyMounted = -1;
static bool _key_exists(const void *data) { return memcmp(data, zeros, 0x10); };
static void _generate_kek(u32 ks, const void *key_source, void *master_key, const void *kek_seed, const void *key_seed) {
if (!_key_exists(key_source) || !_key_exists(master_key) || !_key_exists(kek_seed))
return;
se_aes_key_set(ks, master_key, 0x10);
se_aes_unwrap_key(ks, ks, kek_seed);
se_aes_unwrap_key(ks, ks, key_source);
if (key_seed && _key_exists(key_seed))
se_aes_unwrap_key(ks, ks, key_seed);
}
void print_biskeys(){
gfx_printf("Bis_Key_00\n");
gfx_hexdump(0, bis_key[0], 32);
gfx_printf("Bis_Key_01\n");
gfx_hexdump(0, bis_key[1], 32);
gfx_printf("Bis_Key_02 & 03\n");
gfx_hexdump(0, bis_key[2], 32);
}
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);
if (connect_part(partition))
return 1;
if ((res = f_mount(&emmc, "emmc:", 1))) {
gfx_errDisplay("mount_mmc", res, 0);
return 1;
}
return 0;
}
void connect_mmc(short mmctype){
if (mmctype != currentlyMounted){
disconnect_mmc();
h_cfg.emummc_force_disable = 0;
switch (mmctype){
case SYSMMC:
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_BUS_WIDTH_8, SDHCI_TIMING_MMC_HS400);
h_cfg.emummc_force_disable = 1;
currentlyMounted = SYSMMC;
break;
case EMUMMC:
if (emummc_storage_init_mmc(&storage, &sdmmc)){
h_cfg.emummc_force_disable = 0;
currentlyMounted = EMUMMC;
}
break;
}
}
}
void disconnect_mmc(){
f_unmount("emmc:");
switch (currentlyMounted){
case SYSMMC:
sdmmc_storage_end(&storage);
break;
case EMUMMC:
emummc_storage_end(&storage);
break;
}
currentlyMounted = -1;
}
int dump_biskeys(){
u8 temp_key[0x10], device_key[0x10] = {0};
tsec_ctxt_t tsec_ctxt;
int retries = 0;
connect_mmc(SYSMMC);
// Read package1.
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.");
return -1;
}
bool found_tsec_fw = false;
for (const u32 *pos = (const u32 *)pkg1; (u8 *)pos < pkg1 + 0x40000; pos += 0x100 / sizeof(u32)) {
if (*pos == 0xCF42004D) {
tsec_ctxt.fw = (u8 *)pos;
found_tsec_fw = true;
break;
}
}
if (!found_tsec_fw) {
EPRINTF("Failed to locate TSEC firmware.");
return -1;
}
u8 tsec_keys[0x10] = {0};
tsec_key_data_t *key_data = (tsec_key_data_t *)(tsec_ctxt.fw + TSEC_KEY_DATA_ADDR);
tsec_ctxt.pkg1 = pkg1;
tsec_ctxt.size = 0x100 + key_data->blob0_size + key_data->blob1_size + key_data->blob2_size + key_data->blob3_size + key_data->blob4_size;
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700) {
// Exit after TSEC key generation.
*((vu16 *)((u32)tsec_ctxt.fw + 0x2DB5)) = 0x02F8;
}
int res = 0;
mc_disable_ahb_redirect();
while (tsec_query(tsec_keys, 0, &tsec_ctxt) < 0) {
memset(tsec_keys, 0x00, 0x10);
retries++;
if (retries > 15) {
res = -1;
break;
}
}
free(pkg1);
mc_enable_ahb_redirect();
if (res < 0) {
gfx_printf("ERROR %x dumping TSEC.\n", res);
return -1;
}
u32 sbk[4] = {FUSE(FUSE_PRIVATE_KEY0), FUSE(FUSE_PRIVATE_KEY1),
FUSE(FUSE_PRIVATE_KEY2), FUSE(FUSE_PRIVATE_KEY3)};
se_aes_key_set(8, tsec_keys, 0x10);
se_aes_key_set(9, sbk, 0x10);
se_aes_crypt_block_ecb(8, 0, temp_key, keyblob_key_source);
se_aes_crypt_block_ecb(9, 0, temp_key, temp_key);
se_aes_key_set(7, temp_key, 0x10);
se_aes_crypt_block_ecb(7, 0, device_key, per_console_key_source);
/* key = unwrap(source, wrapped_key):
key_set(ks, wrapped_key), block_ecb(ks, 0, key, source) -> final key in key
*/
if (_key_exists(device_key)) {
se_aes_key_set(8, device_key, 0x10);
se_aes_unwrap_key(8, 8, retail_specific_aes_key_source); // kek = unwrap(rsaks, devkey)
se_aes_crypt_block_ecb(8, 0, bis_key[0] + 0x00, bis_key_source[0] + 0x00); // bkey = unwrap(bkeys, kek)
se_aes_crypt_block_ecb(8, 0, bis_key[0] + 0x10, bis_key_source[0] + 0x10);
// kek = generate_kek(bkeks, devkey, aeskek, aeskey)
_generate_kek(8, bis_kek_source, device_key, aes_kek_generation_source, aes_key_generation_source);
se_aes_crypt_block_ecb(8, 0, bis_key[1] + 0x00, bis_key_source[1] + 0x00); // bkey = unwrap(bkeys, kek)
se_aes_crypt_block_ecb(8, 0, bis_key[1] + 0x10, bis_key_source[1] + 0x10);
se_aes_crypt_block_ecb(8, 0, bis_key[2] + 0x00, bis_key_source[2] + 0x00);
se_aes_crypt_block_ecb(8, 0, bis_key[2] + 0x10, bis_key_source[2] + 0x10);
memcpy(bis_key[3], bis_key[2], 0x20);
}
//sdmmc_storage_set_mmc_partition(&storage, 0);
//nx_emmc_gpt_parse(&sys_gpt, &storage);
pkg1inf.ver = pkg1_id->kb;
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,63 +0,0 @@
#pragma once
#include "../../utils/types.h"
#include "../../utils/list.h"
typedef struct _pkg1_info {
short ver;
char id[16];
} pkg1_info;
//int mount_emmc_partition(const char *part, int logicnumb);
int dump_biskeys();
void print_biskeys();
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};
static const u8 keyblob_key_source[0x10] = {
0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3};
//======================================Keys======================================//
// from Package1 -> Secure_Monitor
static const u8 aes_kek_generation_source[0x10] = {
0x4D, 0x87, 0x09, 0x86, 0xC4, 0x5D, 0x20, 0x72, 0x2F, 0xBA, 0x10, 0x53, 0xDA, 0x92, 0xE8, 0xA9};
static const u8 retail_specific_aes_key_source[0x10] = {
0xE2, 0xD6, 0xB8, 0x7A, 0x11, 0x9C, 0xB8, 0x80, 0xE8, 0x22, 0x88, 0x8A, 0x46, 0xFB, 0xA1, 0x95};
// from Package1ldr (or Secure_Monitor on 6.2.0)
static const u8 per_console_key_source[0x10] = {
0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78};
// from SPL
static const u8 aes_key_generation_source[0x10] = {
0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8};
// from FS
static const u8 bis_kek_source[0x10] = {
0x34, 0xC1, 0xA0, 0xC4, 0x82, 0x58, 0xF8, 0xB4, 0xFA, 0x9E, 0x5E, 0x6A, 0xDA, 0xFC, 0x7E, 0x4F};
static const u8 bis_key_source[3][0x20] = {
{
0xF8, 0x3F, 0x38, 0x6E, 0x2C, 0xD2, 0xCA, 0x32, 0xA8, 0x9A, 0xB9, 0xAA, 0x29, 0xBF, 0xC7, 0x48,
0x7D, 0x92, 0xB0, 0x3A, 0xA8, 0xBF, 0xDE, 0xE1, 0xA7, 0x4C, 0x3B, 0x6E, 0x35, 0xCB, 0x71, 0x06},
{
0x41, 0x00, 0x30, 0x49, 0xDD, 0xCC, 0xC0, 0x65, 0x64, 0x7A, 0x7E, 0xB4, 0x1E, 0xED, 0x9C, 0x5F,
0x44, 0x42, 0x4E, 0xDA, 0xB4, 0x9D, 0xFC, 0xD9, 0x87, 0x77, 0x24, 0x9A, 0xDC, 0x9F, 0x7C, 0xA4},
{
0x52, 0xC2, 0xE9, 0xEB, 0x09, 0xE3, 0xEE, 0x29, 0x32, 0xA1, 0x0C, 0x1F, 0xB6, 0xA0, 0x92, 0x6C,
0x4D, 0x12, 0xE1, 0x4B, 0x2A, 0x47, 0x4C, 0x1C, 0x09, 0xCB, 0x03, 0x59, 0xF0, 0x15, 0xF4, 0xE4}
};
/*
enum mmc_types {
SYSMMC = 0,
EMUMMC
};
*/

View File

@@ -1,183 +0,0 @@
#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 "../../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, 128);
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?\nBto cancel\n");
res = gfx_makewaitmenu("A 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

@@ -1,183 +0,0 @@
#include <string.h>
#include "emmc.h"
#include "../../mem/heap.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../hid/hid.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 "../utils/utils.h"
#include "../gfx/menu.h"
#include "../fs/fsmenu.h"
#include "emmcoperations.h"
#include "../fs/fsutils.h"
#include "../utils/menuUtils.h"
menu_entry *mmcMenuEntries = NULL;
extern sdmmc_storage_t storage;
extern emmc_part_t *system_part;
extern char *clipboard;
extern u8 clipboardhelper;
extern bool sd_mounted;
void addEntry(emmc_part_t *part, u8 property_GPT, int spot){
u32 storage = 0;
u8 property = 0;
if (property_GPT & isFS){
storage = (u32)(property_GPT & 0x7F);
property = ISDIR;
}
else {
u64 size = 0;
u32 sizes = 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 = 3;
property |= SETSIZE(sizes);
storage = (u32)size;
}
mu_copySingle(part->name, storage, property, &mmcMenuEntries[spot]);
}
int fillMmcMenu(short mmcType){
int count = 4, i;
if (mmcMenuEntries != NULL)
mu_clearObjects(&mmcMenuEntries);
link_t *gpt = selectGpt(mmcType);
LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link)
count++;
mu_createObjects(count, &mmcMenuEntries);
if (!sd_mounted)
sd_mount();
SETBIT(mmcmenu_filemenu[3].property, ISHIDE, !sd_mounted);
SETBIT(mmcmenu_start[1].property, ISHIDE, !sd_mounted);
for (i = 0; i < 4; i++)
mu_copySingle(mmcmenu_start[i].name, mmcmenu_start[i].storage, mmcmenu_start[i].property, &mmcMenuEntries[i]);
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);
*/
mu_copySingle(part.name, mmcmenu_filemenu[1].storage, mmcmenu_filemenu[1].property, &mmcmenu_filemenu[1]);
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.isNull){
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!");
hidWait();
}
}
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 | 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!");
hidWait();
break;
case 2:
if (!(clipboardhelper & ISDIR) && (clipboardhelper & OPERATIONCOPY)){
gfx_clearscreen();
if (!mmcFlashFile(clipboard, mmcType, true)){
gfx_printf("\nDone!");
hidWait();
}
clipboardhelper = 0;
}
else
gfx_errDisplay("mmcMenu", ERR_EMPTY_CLIPBOARD, 0);
break;
default:
handleEntries(mmcType, mmcMenuEntries[selection]);
break;
}
}
}

View File

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

View File

@@ -1,10 +0,0 @@
#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, bool warnings);
int emmcDumpPart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part);
int emmcRestorePart(char *path, sdmmc_storage_t *mmcstorage, emmc_part_t *part, bool warnings);

View File

@@ -1,228 +0,0 @@
#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 "../../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, bool warnings){
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(BUFSIZE, 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 && warnings){
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("File is too small for destination.\nDo you want to flash it anyway?\n\nB to Cancel\n");
u32 btnres = gfx_makewaitmenu(
"A to Confirm",
3
);
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, 128);
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_DESTINATION, 2);
free(path_local);
return NULL;
}
int mmcFlashFile(char *path, short mmcType, bool warnings){
emmc_part_t *part;
int res;
part = mmcFindPart(path, mmcType);
if (part != NULL){
res = emmcRestorePart(path, &storage, part, warnings);
emummc_storage_set_mmc_partition(&storage, 0);
return res;
}
return 1;
}

View File

@@ -1,7 +0,0 @@
#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

@@ -1,235 +0,0 @@
#include <string.h>
#include "entrymenu.h"
#include "../common/common.h"
#include "../../libs/fatfs/ff.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"
#include "../../hid/hid.h"
#include "../utils/menuUtils.h"
#include "savesign.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 B to cancel\n", filename);
if (gfx_makewaitmenu("Press A to delete", 2)){
f_unlink(path);
fsreader_readfolder(currentpath);
return 0;
}
else
return -1;
}
void viewbytes(char *path){
FIL in;
u8 *print;
u32 size;
QWORD offset = 0;
int res;
Inputs *input = hidRead();
while (input->buttons & (KEY_POW | KEY_B))
hidRead();
gfx_clearscreen();
print = malloc (1024);
if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("viewbytes", res, 1);
return;
}
while (1){
f_lseek(&in, offset * 16);
if ((res = f_read(&in, print, 1024 * sizeof(u8), &size))){
gfx_errDisplay("viewbytes", res, 2);
return;
}
gfx_con_setpos(0, 31);
gfx_hexdump(offset * 16, print, size * sizeof(u8));
input = hidRead();
if (!(input->buttons))
input = hidWait();
if (input->Ldown && 1024 * sizeof(u8) == size)
offset++;
if (input->Lup && offset > 0)
offset--;
if (input->buttons & (KEY_POW | KEY_B))
break;
}
f_close(&in);
free(print);
}
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;
char *tempchar;
/*
for (int i = 0; i < 2; i++)
if (fs_menu_file[i].name != NULL)
free(fs_menu_file[i].name);
utils_copystring(file.name, &fs_menu_file[0].name);
*/
mu_copySingle(file.name, fs_menu_file[0].storage, fs_menu_file[0].property, &fs_menu_file[0]);
if (fs_menu_file[1].name != NULL)
free(fs_menu_file[1].name);
fs_menu_file[1].name = malloc(16);
sprintf(fs_menu_file[1].name, "\nSize: %d %s", file.storage, gfx_file_size_names[file.size]);
if ((tempchar = fsutil_formatFileAttribs(fsutil_getnextloc(currentpath, file.name))) == NULL)
fs_menu_file[2].isHide = 1;
else {
fs_menu_file[2].isHide = 0;
mu_copySingle(tempchar, fs_menu_file[2].storage, fs_menu_file[2].property, &fs_menu_file[2]);
}
fs_menu_file[6].isHide = !hidConnected();
fs_menu_file[8].isHide = (!(strstr(file.name, ".bin") != NULL && file.size == 1) && strstr(file.name, ".rom") == NULL);
fs_menu_file[9].isHide = (strstr(file.name, ".te") == NULL);
fs_menu_file[11].isHide = (strstr(file.name, ".bis") == NULL);
fs_menu_file[12].isHide = (!!strcmp(currentpath, "emmc:/save"));
/*
SETBIT(fs_menu_file[6].property, ISHIDE, !hidConnected());
SETBIT(fs_menu_file[8].property, ISHIDE, !(strstr(file.name, ".bin") != NULL && file.size == 1) && strstr(file.name, ".rom") == NULL);
SETBIT(fs_menu_file[9].property, ISHIDE, strstr(file.name, ".te") == NULL);
SETBIT(fs_menu_file[11].property, ISHIDE, strstr(file.name, ".bis") == NULL);
*/
temp = menu_make(fs_menu_file, 13, "-- 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_RENAME:;
char *name, *curPath;
gfx_clearscreen();
gfx_printf("Renaming %s...\n\n", file.name);
name = utils_InputText(file.name, 39);
if (name == NULL)
break;
utils_copystring(fsutil_getnextloc(currentpath, file.name), &curPath);
temp = f_rename(curPath, fsutil_getnextloc(currentpath, name));
free(curPath);
free(name);
if (temp){
gfx_errDisplay("fileMenu", temp, 0);
break;
}
fsreader_readfolder(currentpath);
break;
case FILE_PAYLOAD:
launch_payload(fsutil_getnextloc(currentpath, file.name));
break;
case FILE_SCRIPT:
//ParseScript(fsutil_getnextloc(currentpath, file.name));
/*
gfx_printf(" %kRelease any buttons if held!", COLOR_RED);
while (hidRead()->buttons);
*/
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);
hidWait();
break;
case FILE_SIGN:
if (gfx_defaultWaitMenu("WARNING!\n\nThis should only be used if you know what signing and a save is\nDo not do this if you don't know what this does\n\nRequires you to have a prod.keys located in the switch folder\n", 5)){
gfx_clearscreen();
gfx_printf("Signing save...\n");
if (save_sign("sd:/switch/prod.keys", fsutil_getnextloc(currentpath, file.name))){
gfx_printf("Done!\nPress any key to exit");
hidWait();
}
}
break;
case -1:
return -1;
}
return 0;
}

View File

@@ -1,152 +0,0 @@
#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"
#include "../utils/utils.h"
#include "../../hid/hid.h"
#include "../utils/menuUtils.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, hidConn;
char *name;
hidConn = hidConnected();
res = strlen(currentpath);
fs_menu_folder[3].isHide = (*(currentpath + res - 1) == '/');
fs_menu_folder[4].isHide = (*(currentpath + res - 1) == '/');
fs_menu_folder[5].isHide = (*(currentpath + res - 1) == '/' || !hidConn);
fs_menu_folder[6].isHide = !hidConn;
/*
SETBIT(fs_menu_folder[3].property, ISHIDE, (*(currentpath + res - 1) == '/'));
SETBIT(fs_menu_folder[4].property, ISHIDE, (*(currentpath + res - 1) == '/'));
SETBIT(fs_menu_folder[5].property, ISHIDE, (*(currentpath + res - 1) == '/') || !hidConn);
SETBIT(fs_menu_folder[6].property, ISHIDE, !hidConn);
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' : '-');
}
*/
if ((name = fsutil_formatFileAttribs(currentpath)) == NULL){
fs_menu_folder[0].isHide = 1;
}
else {
fs_menu_folder[0].isHide = 0;
mu_copySingle(name, fs_menu_folder[0].storage, fs_menu_folder[0].property, &fs_menu_folder[0]);
}
res = menu_make(fs_menu_folder, 7, currentpath);
switch (res){
case DIR_EXITFOLDER:
case -1:
return -1;
case DIR_COPYFOLDER:
fsreader_writeclipboard(currentpath, OPERATIONCOPY | ISDIR);
break;
case DIR_DELETEFOLDER:
gfx_clearscreen();
if (gfx_defaultWaitMenu("Do you want to delete this folder?\nThe entire folder, with all subcontents will be deleted!", 2)){
gfx_clearscreen();
gfx_printf("\nDeleting folder, please wait...\n");
fsact_del_recursive(currentpath);
fsreader_writecurpath(fsutil_getprevloc(currentpath));
fsreader_readfolder(currentpath);
}
break;
case DIR_RENAME:;
char *prevLoc, *dirName;
dirName = strrchr(currentpath, '/') + 1;
gfx_clearscreen();
gfx_printf("Renaming %s...\n\n", dirName);
name = utils_InputText(dirName, 39);
if (name == NULL)
break;
utils_copystring(fsutil_getprevloc(currentpath), &prevLoc);
res = f_rename(currentpath, fsutil_getnextloc(prevLoc, name));
free(prevLoc);
free(name);
if (res){
gfx_errDisplay("folderMenu", res, 1);
break;
}
fsreader_writecurpath(fsutil_getprevloc(currentpath));
fsreader_readfolder(currentpath);
break;
case DIR_CREATE:;
gfx_clearscreen();
gfx_printf("Give a name for your new folder\n\n");
name = utils_InputText("New Folder", 39);
if (name == NULL)
break;
res = f_mkdir(fsutil_getnextloc(currentpath, name));
free(name);
if (res){
gfx_errDisplay("folderMenu", res, 1);
break;
}
fsreader_readfolder(currentpath);
break;
}
return 0;
}

View File

@@ -1,202 +0,0 @@
#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 "../../hid/hid.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 sizeRemaining, toCopy;
u8 *buff, toPrint = options & COPY_MODE_PRINT, toCancel = options & COPY_MODE_CANCEL;
u32 x, y, i = 11;
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 ((res = f_stat(locin, &in_info))){
gfx_errDisplay("copy", res, 3);
return 1;
}
if ((res = f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE))){
gfx_errDisplay("copy", res, 4);
return 1;
}
if (toPrint){
SWAPCOLOR(COLOR_GREEN);
gfx_printf("[ ]");
x += 16;
gfx_con_setpos(x, y);
}
buff = malloc (BUFSIZE);
sizeRemaining = f_size(&in);
const u64 totalsize = sizeRemaining;
while (sizeRemaining > 0){
toCopy = MIN(sizeRemaining, BUFSIZE);
if ((res = f_read(&in, buff, toCopy, NULL))){
gfx_errDisplay("copy", res, 5);
break;
}
if ((res = f_write(&out, buff, toCopy, NULL))){
gfx_errDisplay("copy", res, 6);
break;
}
sizeRemaining -= toCopy;
if (toPrint && (i > 16 || !sizeRemaining)){
gfx_printf("%3d%%", (u32)(((totalsize - sizeRemaining) * 100) / totalsize));
gfx_con_setpos(x, y);
}
if (toCancel && i > 16){
if (btn_read() & (BTN_VOL_DOWN | BTN_VOL_UP)){
f_unlink(locout);
break;
}
}
if (options){
if (i++ > 16)
i = 0;
}
}
if (toPrint){
RESETCOLOR;
gfx_con_setpos(x - 16, y);
}
f_close(&in);
f_close(&out);
free(buff);
f_chmod(locout, in_info.fattrib, 0x3A);
f_stat(locin, &in_info); //somehow stops fatfs from being weird
return res;
}
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, 720);
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, 720);
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

@@ -1,6 +0,0 @@
#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

@@ -1,93 +0,0 @@
#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 "../../mem/heap.h"
#include "../../storage/nx_emmc.h"
#include "../common/types.h"
#include "../utils/utils.h"
#include "fsactions.h"
void copy_fil_size(FIL* in_src, FIL* out_src, int size_src){
u8* buff;
buff = calloc(BUFSIZE, sizeof(u8));
int size = size_src;
int copysize;
while (size > 0){
copysize = MIN(BUFSIZE, 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);
}
const char *filenames[] = {
"BOOT0.bin",
"BOOT1.bin",
"BCPKG2-1-Normal-Main",
"BCPKG2-3-SafeMode-Main",
"BCPKG2-2-Normal-Sub",
"BCPKG2-4-SafeMode-Sub"
};
int extract_bis_file(char *path, char *outfolder){
FIL in;
int res;
char *tempPath;
BisFile header;
if ((res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING))){
gfx_errDisplay("extract_bis_file", res, 0);
return -1;
}
f_read(&in, &header, sizeof(BisFile), NULL);
for (int i = 0; i < 4; i++)
header.sizes[i] = FLIPU32(header.sizes[i]);
gfx_printf("Version: %s\n\n", header.version);
// Loop to actually extract stuff
for (int i = 0; i < 4; i++){
if (!(header.args & (BIT((7 - i)))))
continue;
gfx_printf("Extracting %s\n", filenames[i]);
gen_part(header.sizes[i], &in, fsutil_getnextloc(outfolder, filenames[i]));
}
// Loop to copy pkg2_1->2 and pkg2_3->4
for (int i = 4; i < 6; i++){
if (!(header.args & BIT((9 - i))))
continue;
utils_copystring(fsutil_getnextloc(outfolder, filenames[i - 2]), &tempPath);
gfx_printf("Copying %s\n", filenames[i]);
fsact_copy(tempPath, fsutil_getnextloc(outfolder, filenames[i]), COPY_MODE_PRINT);
RESETCOLOR;
free(tempPath);
}
gfx_printf("\n\nDone!\n");
f_close(&in);
return 0;
}

View File

@@ -1,123 +0,0 @@
#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"
#include "../utils/menuUtils.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, mu_countObjects(fsreader_files, 0, 0), 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() < 0)
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

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

View File

@@ -1,69 +0,0 @@
#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"
#include "../utils/menuUtils.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 addobject(char* name, int spot, u8 attribs){
u8 property = 0;
if (attribs & AM_DIR)
property |= ISDIR;
else
property |= ISNULL;
mu_copySingle(name, 0, property, &fsreader_files[spot]);
}
int fsreader_readfolder(const char *path){
DIR dir;
FILINFO fno;
int folderamount, res;
mu_clearObjects(&fsreader_files);
mu_createObjects(fsutil_getfolderentryamount(path) + 3, &fsreader_files);
for (folderamount = 0; folderamount < 3; folderamount++)
mu_copySingle(fs_menu_startdir[folderamount].name, fs_menu_startdir[folderamount].storage, fs_menu_startdir[folderamount].property, &fsreader_files[folderamount]);
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

@@ -1,10 +0,0 @@
#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

@@ -1,98 +0,0 @@
#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;
}
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;
}
char *fsutil_formatFileAttribs(char *path){
FILINFO attribs;
char *out;
out = malloc(16);
if (f_stat(path, &attribs))
return NULL;
sprintf(out, "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' : '-');
return out;
}

View File

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

View File

@@ -1,62 +0,0 @@
#include "keys.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../sec/se.h"
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../../config/ini.h"
#include "../common/common.h"
#include <string.h>
char *getKey(const char *search, link_t *inilist){
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, inilist, link){
if (ini_sec->type == INI_CHOICE){
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{
if (!strcmp(search, kv->key))
return kv->val;
}
}
}
return NULL;
}
u8 getHexSingle(const char c) {
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
}
u8 *getHex(const char *in){
u32 len = strlen(in), count = 0;
u8 *out = calloc(len / 2, sizeof(u8));
for (u32 i = 0; i < len; i += 2){
out[count++] = (u8)(getHexSingle(in[i]) << 4) | (getHexSingle(in[i + 1]));
}
return out;
}
u8 *GetKey(const char *keypath, const char *keyName){
LIST_INIT(inilist);
char *key;
u8 *hex = NULL;
if (!ini_parse(&inilist, keypath, false)){
gfx_errDisplay("GetKey", ERR_INI_PARSE_FAIL, 1);
goto out_free;
}
if ((key = getKey(keyName, &inilist)) == NULL){
gfx_errDisplay("GetKey", ERR_INI_PARSE_FAIL, 2);
goto out_free;
}
hex = getHex(key);
out_free:;
list_empty(&inilist);
return hex;
}

View File

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

View File

@@ -1,46 +0,0 @@
#include "nca.h"
#include "keys.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../sec/se.h"
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../../config/ini.h"
#include "../common/common.h"
#include <string.h>
int SetHeaderKey(){
u8 *header_key = GetKey("sd:/switch/prod.keys", "header_key");
if (header_key == NULL)
return -1;
se_aes_key_set(4, header_key + 0x00, 0x10);
se_aes_key_set(5, header_key + 0x10, 0x10);
return 0;
}
int GetNcaType(char *ncaPath){
FIL fp;
u32 read_bytes = 0;
if (f_open(&fp, ncaPath, FA_READ | FA_OPEN_EXISTING))
return -1;
u8 *dec_header = (u8*)malloc(0x600);
if (f_lseek(&fp, 0x200) || f_read(&fp, dec_header, 32, &read_bytes) || read_bytes != 32){
f_close(&fp);
free(dec_header);
return -1;
}
se_aes_xts_crypt(5,4,0,1,dec_header + 0x200, dec_header, 32, 1);
u8 ContentType = dec_header[0x205];
f_close(&fp);
free(dec_header);
return ContentType;
}

View File

@@ -1,4 +0,0 @@
#pragma once
int GetNcaType(char *ncaPath);
int SetHeaderKey();

View File

@@ -1,77 +0,0 @@
#include "savesign.h"
#include "keys.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../sec/se.h"
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../../config/ini.h"
#include "../common/common.h"
#include <string.h>
bool save_commit(const char *path, u8 *save_mac_key){
FIL file;
int res;
u8 *buf, hash[0x20], *cmac_data, cmac[0x10];
const u32 hashed_data_size = 0x3D00, cmac_data_size = 0x200;
bool success = false;
buf = malloc(hashed_data_size);
cmac_data = malloc(cmac_data_size);
if ((res = f_open(&file, path, FA_OPEN_EXISTING | FA_READ | FA_WRITE))){
gfx_errDisplay("save_commit", res, 1);
goto out_free;
}
f_lseek(&file, 0x300);
if ((res = f_read(&file, buf, hashed_data_size, NULL))){
gfx_errDisplay("save_commit", res, 2);
goto out_free;
}
se_calc_sha256(hash, buf, hashed_data_size);
f_lseek(&file, 0x108);
if ((res = f_write(&file, hash, sizeof(hash), NULL))){
gfx_errDisplay("save_commit", res, 3);
goto out_free;
}
f_lseek(&file, 0x100);
if ((res = f_read(&file, cmac_data, cmac_data_size, NULL))){
gfx_errDisplay("save_commit", res, 4);
goto out_free;
}
se_aes_key_set(3, save_mac_key, 0x10);
se_aes_cmac(3, cmac, 0x10, cmac_data, cmac_data_size);
f_lseek(&file, 0);
if ((res = f_write(&file, cmac, sizeof(cmac), NULL))){
gfx_errDisplay("save_commit", res, 5);
goto out_free;
}
success = true;
out_free:;
free(buf);
free(cmac_data);
f_close(&file);
return success;
}
bool save_sign(const char *keypath, const char *savepath){
u8 *key = GetKey(keypath, "save_mac_key");
if (key == NULL){
return false;
}
if (!save_commit(savepath, key))
return false;
return true;
}

View File

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

View File

@@ -1,183 +0,0 @@
#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"
#include "../../hid/hid.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_boxGrey(0, 703, 1279, 719, 0xFF);
gfx_boxGrey(0, 0, 1279, 15, 0xFF);
gfx_con_setpos(0, 0);
gfx_printf("Tegraexplorer v2.0.5 | Battery: %3d%%\n", battery >> 8);
RESETCOLOR;
}
u32 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 hidWait()->buttons;
}
u32 gfx_errDisplay(const 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_IN_FUNC)
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\n");
RESETCOLOR;
return hidWait()->buttons;
}
int gfx_makewaitmenu(const char *hiddenmessage, int timer){
u32 start = get_tmr_s();
Inputs *input = NULL;
while(1){
input = hidRead();
if (input->buttons & (KEY_VOLM | KEY_VOLP | KEY_B))
return 0;
if (start + timer > get_tmr_s())
gfx_printf("\r<Wait %d seconds> ", timer + start - get_tmr_s());
else if (input->a)
return 1;
else
gfx_printf("\r%s", hiddenmessage);
}
}
void gfx_printlength(int size, const 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(const char *in, int length, int endX){
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, endX, y + 15, 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);
*/
}
static u32 sideY = 0;
void _gfx_sideSetYAuto(){
u32 getX, getY;
gfx_con_getpos(&getX, &getY);
sideY = getY;
}
void gfx_sideSetY(u32 setY){
sideY = setY;
}
u32 gfx_sideGetY(){
return sideY;
}
void gfx_sideprintf(const char* message, ...){
va_list ap;
va_start(ap, message);
gfx_con_setpos(800, sideY);
gfx_vprintf(message, ap);
_gfx_sideSetYAuto();
va_end(ap);
}
void gfx_sideprintandclear(const char* message, int length){
gfx_con_setpos(800, sideY);
gfx_printandclear(message, length, 1279);
gfx_putc('\n');
_gfx_sideSetYAuto();
}
void gfx_drawScrollBar(int minView, int maxView, int count){
int curScrollCount = 1 + maxView - minView;
if (curScrollCount >= count)
return;
u32 barSize = (703 * (curScrollCount * 1000 / count)) / 1000;
u32 offsetSize = (703 * (minView * 1000 / count)) / 1000;
gfx_boxGrey(740, 16, 755, 702, 0x1B);
if ((16 + barSize + offsetSize) > 702)
gfx_boxGrey(740, 16 + offsetSize, 755, 702, 0x66);
else
gfx_boxGrey(740, 16 + offsetSize, 755, 16 + barSize + offsetSize, 0x66);
}
int gfx_defaultWaitMenu(const char *message, int time){
gfx_clearscreen();
SWAPCOLOR(COLOR_ORANGE);
gfx_printf("\n%s\n\nPress B to return\n", message);
SWAPCOLOR(COLOR_RED);
return gfx_makewaitmenu("Press A to continue", time);
}

View File

@@ -1,23 +0,0 @@
#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 SWAPALLCOLOR(fg, bg) gfx_printf("%k%K", fg, bg)
#define RESETCOLOR gfx_printf("%k%K", COLOR_WHITE, COLOR_DEFAULT)
void gfx_clearscreen();
u32 gfx_message(u32 color, const char* message, ...);
u32 gfx_errDisplay(const char *src_func, int err, int loc);
int gfx_makewaitmenu(const char *hiddenmessage, int timer);
void gfx_printlength(int size, const char *toprint);
void gfx_printandclear(const char *in, int length, int endX);
void gfx_sideSetY(u32 setY);
u32 gfx_sideGetY();
void gfx_sideprintf(const char* message, ...);
void gfx_sideprintandclear(const char* message, int length);
void gfx_drawScrollBar(int minView, int maxView, int count);
int gfx_defaultWaitMenu(const char *message, int time);
extern int printerrors;

View File

@@ -1,236 +0,0 @@
#include <string.h>
#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"
#include "../../hid/hid.h"
#include "../fs/fsutils.h"
#include "../utils/menuUtils.h"
extern void sd_unmount();
extern bool sd_inited;
#pragma GCC push_options
#pragma GCC optimize ("O2")
void _printentry(menu_entry *entry, bool highlighted, bool refresh, const char *path){
if (entry->isHide)
return;
u32 color = (entry->isMenu) ? entry->storage : ((entry->isDir) ? COLOR_WHITE : COLOR_VIOLET);
SWAPALLCOLOR((highlighted) ? COLOR_DEFAULT : color, (highlighted) ? color : COLOR_DEFAULT);
if (!(entry->isMenu))
gfx_printf("%c ", (entry->isDir) ? 30 : 31);
if (refresh)
gfx_printandclear(entry->name, 37, 720);
else
gfx_printlength(37, entry->name);
if (entry->property & (ISMENU | ISDIR))
gfx_printf("\n");
else {
if (entry->isNull){
u64 totalSize;
u32 sizeType = 0;
totalSize = fsutil_getfilesize(fsutil_getnextloc(path, entry->name));
while (totalSize > 1024){
totalSize /= 1024;
sizeType++;
}
if (sizeType > 3)
sizeType = 3;
entry->size = sizeType;
entry->storage = totalSize;
SETBIT(entry->property, ISNULL, 0);
}
SWAPALLCOLOR(COLOR_BLUE, COLOR_DEFAULT);
gfx_printf("\a%4d", entry->storage);
gfx_con.fntsz = 8;
gfx_printf("\n\e%s\n", gfx_file_size_names[entry->size]);
gfx_con.fntsz = 16;
}
}
bool disableB = false;
int menu_make(menu_entry *entries, int amount, const char *toptext){
int currentpos = 0, offset = 0, delay = 300, minscreen = 0, calculatedamount = 0, cursub = 0, temp;
u32 scrolltimer, timer, sideY;
bool refresh = true;
Inputs *input = hidRead();
input->buttons = 0;
gfx_clearscreen();
calculatedamount = mu_countObjects(entries, amount, ISMENU);
gfx_con_setpos(0, 16);
SWAPCOLOR(COLOR_GREEN);
gfx_printlength(42, toptext);
RESETCOLOR;
gfx_sideSetY(48);
char *currentfolder = strrchr(toptext, '/');
if (currentfolder != NULL){
if (calculatedamount)
gfx_sideprintf("%d items in current dir\n\n", calculatedamount);
gfx_sideprintf("Current directory:\n");
if (*(currentfolder + 1) != 0)
currentfolder++;
SWAPCOLOR(COLOR_GREEN);
gfx_sideprintandclear(currentfolder, 28);
gfx_sideprintf("\n\n\n");
}
for (;;){
gfx_con_setpos(0, 48);
timer = get_tmr_ms();
if (!currentpos)
cursub = 1;
else if (currentpos == amount - 1)
cursub = -1;
else
cursub = 0;
while (entries[currentpos].property & (ISSKIP | ISHIDE))
currentpos += cursub;
if (currentpos > (minscreen + SCREENMAXOFFSET)){
offset += currentpos - (minscreen + SCREENMAXOFFSET);
minscreen += currentpos - (minscreen + SCREENMAXOFFSET);
refresh = true;
}
else if (currentpos < minscreen){
offset -= minscreen - currentpos;
minscreen -= minscreen - currentpos;
refresh = true;
}
if (refresh || currentfolder == NULL || !calculatedamount){
for (int i = 0 + offset; i < amount && i < SCREENMAXOFFSET + 1 + offset; i++)
_printentry(&entries[i], (i == currentpos), refresh, toptext);
}
else {
temp = (currentpos - minscreen > 0) ? 0 : 16;
gfx_con_setpos(0, 32 + temp + (currentpos - minscreen) * 16);
if (!temp)
_printentry(&entries[currentpos - 1], false, false, toptext);
_printentry(&entries[currentpos], true, false, toptext);
if (currentpos < MIN(amount - 1, minscreen + SCREENMAXOFFSET))
_printentry(&entries[currentpos + 1], false, false, toptext);
}
RESETCOLOR;
sideY = gfx_sideGetY();
if (!(entries[currentpos].isMenu)){
gfx_sideprintf("Current selection:\n");
SWAPCOLOR(COLOR_YELLOW);
gfx_sideprintandclear(entries[currentpos].name, 28);
RESETCOLOR;
gfx_sideprintf("Type: %s", (entries[currentpos].isDir) ? "Dir " : "File");
gfx_sideSetY(sideY);
}
else
gfx_boxGrey(800, sideY, 1279, sideY + 48, 0x1B);
gfx_con_setpos(0, 703);
SWAPALLCOLOR(COLOR_DEFAULT, COLOR_WHITE);
gfx_printf("Time taken for screen draw: %dms ", get_tmr_ms() - timer);
if (refresh)
gfx_drawScrollBar(minscreen, minscreen + SCREENMAXOFFSET, amount);
refresh = false;
while (hidRead()->buttons & (KEY_B | KEY_A));
scrolltimer = get_tmr_ms();
while (1){
if (sd_inited && !!gpio_read(GPIO_PORT_Z, GPIO_PIN_1)){
gfx_errDisplay("menu", ERR_SD_EJECTED, 0);
sd_unmount();
return -1;
}
input = hidRead();
if (!(input->buttons & (KEY_A | KEY_LDOWN | KEY_LUP | KEY_B | KEY_RUP | KEY_RDOWN))){
delay = 300;
continue;
}
if (input->buttons & (KEY_RDOWN | KEY_RUP)){
delay = 1;
input->Lup = input->Rup;
input->Ldown = input->Rdown;
}
if (delay < 300){
if (scrolltimer + delay < get_tmr_ms()){
break;
}
}
else {
break;
}
}
if (input->a){
break;
}
if (input->b && !disableB){
currentpos = 0;
break;
}
if (delay > 46)
delay -= 45;
if (input->Lup && currentpos > 0)
cursub = -1;
else if (input->Ldown && currentpos < amount - 1)
cursub = 1;
else
cursub = 0;
if (cursub){
do {
currentpos += cursub;
} while (currentpos < amount - 1 && currentpos > 0 && entries[currentpos].property & (ISSKIP | ISHIDE));
}
}
minerva_periodic_training();
//return (mode) ? currentpos : entries[currentpos].property;
return currentpos;
}
#pragma GCC pop_options

View File

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

View File

@@ -1,183 +1,40 @@
#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"
#include "../storage/nx_sd.h"
//#include "../hid/joycon.h"
#include "mainMenu.h"
#include "../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../gfx/menu.h"
#include "tools.h"
#include "../hid/hid.h"
/*
extern bool sd_mount();
extern void sd_unmount();
*/
extern int launch_payload(char *path);
extern bool sd_inited;
extern bool sd_mounted;
extern bool disableB;
#include "../fs/menus/explorer.h"
#include <utils/btn.h>
#include <storage/nx_sd.h>
int res = 0, meter = 0;
void MainMenu_SDCard(){
fileexplorer("SD:/", 0);
}
void MainMenu_EMMC(){
if (gfx_defaultWaitMenu("You're about to enter EMMC\nModifying anything here can result in a BRICK!\n\nPlease only continue if you know what you're doing", 4)){
makeMmcMenu(SYSMMC);
}
}
void MainMenu_EMUMMC(){
makeMmcMenu(EMUMMC);
}
void MainMenu_MountSD(){
(sd_mounted) ? sd_unmount() : sd_mount();
}
void MainMenu_Tools(){
res = menu_make(mainmenu_tools, 4, "-- Tools Menu --");
switch(res){
case TOOLS_DISPLAY_INFO:
displayinfo();
break;
case TOOLS_DISPLAY_GPIO:
displaygpio();
break;
case TOOLS_DUMPFIRMWARE:
res = menu_make(fwDump_typeMenu, 4, "-- Fw Type --");
if (res >= 2)
dumpfirmware(SYSMMC, (res == 2));
break;
}
}
void MainMenu_SDFormat(){
res = menu_make(mainmenu_format, 3, "-- Format Menu --");
if (res > 0){
if(gfx_defaultWaitMenu("Are you sure you want to format your sd?\nThis will delete everything on your SD card!\nThis action is irreversible!", 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,
MenuEntry_t mainMenuEntries[] = {
{.R = 255, .G = 255, .B = 255, .skip = 1, .name = "-- Main Menu --"},
{.G = 255, .name = "SD:/"},
{.B = 255, .G = 255, .name = "Test Controllers"},
{.R = 255, .name = "Reboot to payload"}
};
void RunMenuOption(int option){
if (option != 7)
meter = 0;
if (option > 0)
mainmenu_functions[option - 1]();
void HandleSD(){
gfx_clearscreen();
if (!sd_mount()){
gfx_printf("Sd is not mounted!");
hidWait();
}
else
FileExplorer("sd:/");
}
void te_main(){
int setter;
//gfx_printf("Initing controller\n");
hidInit();
menuPaths mainMenuPaths[] = {
NULL,
HandleSD,
TestControllers,
RebootToPayload
};
//gfx_printf("Getting biskeys\n");
if (dump_biskeys() == -1){
gfx_errDisplay("dump_biskey", ERR_BISKEY_DUMP_FAILED, 0);
//mainmenu_main[1].property |= ISHIDE;
}
//gfx_printf("Mounting SD\n");
sd_mount();
//gfx_printf("Loading possible EMU\n");
if (emummc_load_cfg()){
mainmenu_main[2].property |= ISHIDE;
}
//gfx_printf("Dumping gpt\n");
dumpGpt();
//gfx_printf("Disconnecting EMMC\n");
disconnect_mmc();
//gfx_printf("Entering main menu\n");
void EnterMainMenu(){
while (1){
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);
disableB = true;
res = menu_make(mainmenu_main, 8, "-- Main Menu --") + 1;
disableB = false;
RunMenuOption(res);
FunctionMenuHandler(mainMenuEntries, 4, mainMenuPaths, false);
}
}
}

View File

@@ -1,53 +1,3 @@
#pragma once
#include "../utils/types.h"
#define MAINMENU_AMOUNT 12
/*
typedef struct _menu_item {
char name[50];
u32 color;
short internal_function;
short property;
} menu_item;
enum mainmenu_return {
SD_CARD = 1,
EMMC_SAF,
EMMC_SYS,
EMMC_USR,
EMUMMC_SAF,
EMUMMC_SYS,
EMUMMC_USR,
MOUNT_SD,
TOOLS,
SD_FORMAT,
CREDITS,
EXIT
};
enum shutdownmenu_return {
REBOOT_RCM = 1,
REBOOT_NORMAL,
POWER_OFF,
HEKATE,
AMS
};
enum toolsmenu_return {
DISPLAY_INFO = 1,
DISPLAY_GPIO,
DUMPFIRMWARE,
DUMPUSERSAVE,
DUMP_BOOT,
RESTORE_BOOT
};
enum formatmenu_return {
FORMAT_EMUMMC = 0,
FORMAT_ALL_FAT32
};
*/
void te_main();
void EnterMainMenu();

View File

@@ -1,664 +0,0 @@
#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 "../../hid/hid.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;
}
}
#pragma GCC push_options
#pragma GCC optimize ("Os")
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 INFUNC_FAIL;
gfx_printf("%d", toprintint);
}
else {
char *toprintstring;
if (parseStringInput(argv[i], &toprintstring))
return INFUNC_FAIL;
gfx_printf(toprintstring);
}
}
gfx_printf("\n");
return 0;
}
int part_print_int(){
int toprint;
if (parseIntInput(argv[0], &toprint))
return INFUNC_FAIL;
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 INFUNC_FAIL;
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 INFUNC_FAIL;
if (parseIntInput(argv[2], &right))
return INFUNC_FAIL;
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 INFUNC_FAIL;
}
int part_if(){
int condition;
if (parseIntInput(argv[0], &condition))
return INFUNC_FAIL;
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 INFUNC_FAIL;
getfollowingchar('{');
if (!condition)
skipbrackets();
return 0;
}
int part_Math(){
int left, right;
if (parseIntInput(argv[0], &left))
return INFUNC_FAIL;
if (parseIntInput(argv[2], &right))
return INFUNC_FAIL;
switch (argv[1][0]){
case '+':
return left + right;
case '-':
return left - right;
case '*':
return left * right;
case '/':
return left / right;
}
return INFUNC_FAIL;
}
int part_SetInt(){
int out;
parseIntInput(argv[0], &out);
return out;
}
int part_SetString(){
char *arg0;
if (parseStringInput(argv[0], &arg0))
return INFUNC_FAIL;
if (argv[1][0] != '$')
return INFUNC_FAIL;
str_str_add(argv[1], arg0);
return 0;
}
int part_SetStringIndex(){
int index;
char *out;
if (parseIntInput(argv[0], &index))
return INFUNC_FAIL;
if (argv[1][0] != '$')
return INFUNC_FAIL;
if (str_str_index(index, &out))
return INFUNC_FAIL;
str_str_add(argv[1], out);
return 0;
}
int part_goto(){
int target = 0;
if (parseIntInput(argv[0], &target))
return INFUNC_FAIL;
str_int_add("@RETURN", (int)f_tell(&scriptin));
f_lseek(&scriptin, target);
return 0;
}
int part_invert(){
int arg;
if (parseIntInput(argv[0], &arg))
return INFUNC_FAIL;
return (arg) ? 0 : 1;
}
int part_fs_exists(){
char *path;
if (parseStringInput(argv[0], &path))
return INFUNC_FAIL;
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 INFUNC_FAIL;
return 0;
}
int part_MountMMC(){
char *arg;
parseStringInput(argv[0], &arg);
return mount_mmc(arg, 2);
}
int part_Pause(){
Inputs *input = hidWaitMask(KEY_A | KEY_B | KEY_X | KEY_Y | KEY_POW | KEY_VOLP | KEY_VOLM | KEY_LUP | KEY_LDOWN | KEY_LLEFT | KEY_LRIGHT);
str_int_add("@BTN_POWER", input->pow);
str_int_add("@BTN_VOL+", input->volp);
str_int_add("@BTN_VOL-", input->volm);
str_int_add("@BTN_A", input->a);
str_int_add("@BTN_B", input->b);
str_int_add("@BTN_X", input->x);
str_int_add("@BTN_Y", input->y);
str_int_add("@BTN_UP", input->Lup);
str_int_add("@BTN_DOWN", input->Ldown);
str_int_add("@BTN_LEFT", input->Lleft);
str_int_add("@BTN_RIGHT", input->Lright);
str_int_add("@JOYCONN", hidConnected());
return input->buttons;
}
int part_addstrings(){
char *combined, *left, *middle;
if (parseStringInput(argv[0], &left))
return INFUNC_FAIL;
if (parseStringInput(argv[1], &middle))
return INFUNC_FAIL;
if (argv[2][0] != '$')
return INFUNC_FAIL;
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 INFUNC_FAIL;
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 INFUNC_FAIL;
return 0;
}
int part_Exit(){
forceExit = true;
return 0;
}
int part_fs_Move(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return INFUNC_FAIL;
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 INFUNC_FAIL;
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 INFUNC_FAIL;
return fsact_del_recursive(arg);
}
int part_fs_Copy(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return INFUNC_FAIL;
return fsact_copy(left, right, COPY_MODE_PRINT);
}
int part_fs_CopyRecursive(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return INFUNC_FAIL;
return fsact_copy_recursive(left, right);
}
int part_fs_MakeDir(){
char *arg;
if (parseStringInput(argv[0], &arg))
return INFUNC_FAIL;
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 INFUNC_FAIL;
if (f_opendir(&dir, path))
return INFUNC_FAIL;
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 INFUNC_FAIL;
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 INFUNC_FAIL;
if (parseIntInput(argv[1], &right))
return INFUNC_FAIL;
if (left > 78)
return INFUNC_FAIL;
if (right > 42)
return INFUNC_FAIL;
gfx_con_setpos(left * 16, right * 16);
return 0;
}
int part_stringcompare(){
char *left, *right;
if (parseStringInput(argv[0], &left))
return INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return INFUNC_FAIL;
return (strcmp(left, right)) ? 0 : 1;
}
int part_fs_combinePath(){
char *combined, *left, *middle;
if (parseStringInput(argv[0], &left))
return INFUNC_FAIL;
if (parseStringInput(argv[1], &middle))
return INFUNC_FAIL;
if (argv[2][0] != '$')
return INFUNC_FAIL;
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 INFUNC_FAIL;
if (parseStringInput(argv[1], &right))
return INFUNC_FAIL;
if (!strcmp(left, "BOOT")){
return emmcDumpBoot(right);
}
else {
return emmcDumpSpecific(left, right);
}
}
int part_mmc_restorePart(){
char *path;
if (parseStringInput(argv[0], &path))
return INFUNC_FAIL;
if (currentlyMounted < 0)
return INFUNC_FAIL;
return mmcFlashFile(path, currentlyMounted, false);
}
int part_fs_extractBisFile(){
char *path, *outfolder;
if (parseStringInput(argv[0], &path))
return INFUNC_FAIL;
if (parseStringInput(argv[1], &outfolder))
return INFUNC_FAIL;
return extract_bis_file(path, outfolder);
}
int part_clearscreen(){
gfx_clearscreen();
return 0;
}
int part_getPos(){
return (int)f_tell(&scriptin);
}
int part_subString(){
char *str, *sub;
int start, size;
if (parseStringInput(argv[0], &str))
return INFUNC_FAIL;
if (parseIntInput(argv[1], &start))
return INFUNC_FAIL;
if (parseIntInput(argv[2], &size))
return INFUNC_FAIL;
if (argv[3][0] != '$')
return INFUNC_FAIL;
if (start >= strlen(str))
return INFUNC_FAIL;
sub = utils_copyStringSize(str + start, size);
str_str_add(argv[3], sub);
free(sub);
return 0;
}
int part_inputString(){
char *start, *out;
int len;
if (parseStringInput(argv[0], &start))
return INFUNC_FAIL;
if (parseIntInput(argv[1], &len))
return INFUNC_FAIL;
if (argv[2][0] != '$')
return INFUNC_FAIL;
if (len > 39)
return INFUNC_FAIL;
out = utils_InputText(start, len);
if (out == NULL)
return 1;
str_str_add(argv[2], out);
free(out);
return 0;
}
int part_strLen(){
char *in;
if (parseStringInput(argv[0], &in))
return INFUNC_FAIL;
return strlen(in);
}
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},
{"subString", part_subString, 4},
{"inputString", part_inputString, 3},
{"stringLength", part_strLen, 1},
{"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}
};
#pragma GCC pop_options
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 == INFUNC_FAIL) ? -1 : 0;
}
}
return -2;
}

View File

@@ -1,13 +0,0 @@
#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

@@ -1,307 +0,0 @@
#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"
#include "../../hid/hid.h"
int countchars(const char* in, char target) {
u32 len = strlen(in);
u32 count = 0;
for (u32 i = 0; i < len; i++) {
if (in[i] == '"'){
while (in[++i] != '"'){
if (i >= len)
return -1;
}
}
if (in[i] == target)
count++;
}
return count;
}
char **argv = NULL;
u32 argc;
u32 splitargs(const char* in) {
// arg like '5, "6", @arg7'
u32 i = 0, count = 1, len = strlen(in), curcount = 0, begin, end;
count += countchars(in, ',');
if (!count)
return 0;
argv = calloc(count + 1, sizeof(char*));
while (i < len && curcount < count) {
if (in[i] == ' ' || in[i] == ','){
i++;
continue;
}
begin = i;
while (strrchr(" ,)", in[i]) == NULL){
if (in[i] == '"'){
begin = i + 1;
while (in[++i] != '"'){
if (in[i] == '\0')
return 0;
}
}
if (in[i] == '\0')
return 0;
i++;
}
end = i;
if (in[i - 1] == '"'){
end--;
}
argv[curcount++] = utils_copyStringSize(in + begin, (u32)(end - begin));
}
return curcount;
}
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();
}
functionparser();
res = run_function(funcbuff, &out);
if (res < 0){
printerrors = true;
//gfx_printf("%s|%s|%d", funcbuff, argv[0], argc);
//btn_wait();
int lineNumber = 1;
u64 end = f_tell(&scriptin);
f_lseek(&scriptin, 0);
while (f_tell(&scriptin) < end && !f_eof(&scriptin)){
if (getnextchar() == '\n')
lineNumber++;
}
gfx_errDisplay((res == -1) ? funcbuff : "run_function", (res == -1) ? ERR_IN_FUNC : ERR_SCRIPT_LOOKUP_FAIL, lineNumber);
forceExit = true;
//gfx_printf("Func: %s\nArg1: %s\n", funcbuff, argv[0]);
}
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("@JOYCONN", hidConnected());
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

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

View File

@@ -1,250 +0,0 @@
#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

@@ -1,34 +0,0 @@
#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

@@ -0,0 +1,29 @@
#include "tools.h"
#include "../gfx/gfx.h"
#include "../gfx/gfxutils.h"
#include "../gfx/menu.h"
#include "../hid/hid.h"
void TestControllers(){
gfx_clearscreen();
gfx_printf("Controller test screen. Return using b\n\n");
while (1){
Input_t *controller = hidRead();
if (controller->b)
return;
u32 buttons = controller->buttons;
for (int i = 0; i < 31; i++){
gfx_printf("%d", buttons & 1);
buttons >>= 1;
}
gfx_printf("\r");
}
}
extern int launch_payload(char *path);
void RebootToPayload(){
launch_payload("atmosphere/reboot_payload.bin");
}

View File

@@ -0,0 +1,4 @@
#pragma once
void RebootToPayload();
void TestControllers();

View File

@@ -1,41 +0,0 @@
#include "menuUtils.h"
#include "../../utils/types.h"
#include "../common/types.h"
#include "../../mem/heap.h"
#include "utils.h"
void mu_clearObjects(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 mu_createObjects(int size, menu_entry **menu){
(*menu) = calloc (size + 1, sizeof(menu_entry));
(*menu)[size].name = NULL;
}
int mu_countObjects(menu_entry *entries, u32 count, u8 propertyMask){
int amount = 0;
for (u32 i = 0; (count) ? i < count : entries[i].name != NULL; i++){
if (!(entries[i].property & propertyMask))
amount++;
}
return amount;
}
void mu_copySingle(char *name, u32 storage, u8 property, menu_entry *out){
if (out->name != NULL)
free(out->name);
utils_copystring(name, &out->name);
out->storage = storage;
out->property = property;
}

View File

@@ -1,8 +0,0 @@
#pragma once
#include "../../utils/types.h"
#include "../common/types.h"
void mu_createObjects(int size, menu_entry **menu);
void mu_clearObjects(menu_entry **menu);
int mu_countObjects(menu_entry *entries, u32 count, u8 propertyMask);
void mu_copySingle(char *name, u32 storage, u8 property, menu_entry *out);

View File

@@ -1,332 +0,0 @@
#include <string.h>
#include "tools.h"
#include "../gfx/gfxutils.h"
#include "../../libs/fatfs/ff.h"
#include "../../gfx/gfx.h"
#include "../../hid/hid.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"
#include "../fs/nca.h"
extern bool sd_mount();
extern void sd_unmount();
extern sdmmc_storage_t sd_storage;
void displayinfo(){
gfx_clearscreen();
FATFS *fs;
DWORD fre_clust, fre_sect, tot_sect;
u32 capacity;
u8 fuse_count = 0;
pkg1_info pkg1 = returnpkg1info();
int res;
for (u32 i = 0; i < 32; i++){
if ((fuse_read_odm(7) >> i) & 1)
fuse_count++;
}
SWAPCOLOR(COLOR_ORANGE);
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;
gfx_printf("\n-----\n\n");
SWAPCOLOR(COLOR_BLUE);
if (!sd_mount()){
gfx_printf("SD mount failed!\nFailed to display SD info\n");
}
else {
gfx_printf("Getting storage info: please wait...");
res = f_getfree("sd:", &fre_clust, &fs);
gfx_printf("\nResult getfree: %d\n\n", res);
tot_sect = (fs->n_fatent - 2) * fs->csize;
fre_sect = fre_clust * fs->csize;
capacity = sd_storage.csd.capacity;
gfx_printf("Entire sd:\nSectors: %d\nSpace total: %d MB\n\n", capacity, capacity / 2048);
gfx_printf("First partition on SD:\nSectors: %d\nSpace total: %d MB\nSpace free: %d MB\n\n", tot_sect, tot_sect / 2048, fre_sect / 2048);
}
RESETCOLOR;
gfx_printf("Press any key to continue");
hidWait();
}
void displaygpio(){
gfx_clearscreen();
gfx_printf("Updates gpio pins every 50ms:\nPress power to exit");
msleep(200);
while (1){
msleep(10);
gfx_con_setpos(0, 63);
for (int i = 0; i <= 30; i++){
gfx_printf("\nPort %d: ", i);
for (int i2 = 7; i2 >= 0; i2--)
gfx_printf("%d", gpio_read(i, (1 << i2)));
}
if (hidRead()->pow)
break;
}
}
// bad code ahead aaaa
int dumpfirmware(int mmc, bool daybreak){
DIR dir;
FILINFO fno;
bool fail = false;
int ret, amount = 0;
char sysbase[] = "emmc:/Contents/registered";
char *syspathtemp, *syspath, *sdpath, *sdbase;
pkg1_info pkg1 = returnpkg1info();
u32 timer = get_tmr_s();
gfx_clearscreen();
connect_mmc(mmc);
mount_mmc("SYSTEM", 2);
if (daybreak){
if (!fsutil_checkfile("sd:/switch/prod.keys")){
SWAPCOLOR(COLOR_RED);
gfx_printf("prod.keys not found.\nPress any button to exit");
hidWait();
return true;
}
if (SetHeaderKey()){
SWAPCOLOR(COLOR_RED);
gfx_printf("Failed to find header key.\nPress any button to exit");
hidWait();
return true;
}
}
gfx_printf("PKG1 version: %d\n", pkg1.ver);
gfx_printf("Creating folders...\n");
f_mkdir("sd:/tegraexplorer");
f_mkdir("sd:/tegraexplorer/Firmware");
sdbase = calloc(32 + strlen(pkg1.id), sizeof(char));
sprintf(sdbase, "sd:/tegraexplorer/Firmware/%d (%s)", pkg1.ver, pkg1.id);
if (fsutil_checkfile(sdbase)){
SWAPCOLOR(COLOR_RED);
gfx_printf("Destination folder already exists.\nPress X to delete this folder, any other button to cancel\nPath: %s", sdbase);
Inputs *input = hidWait();
if (!input->x){
free(sdbase);
return true;
}
else {
SWAPCOLOR(COLOR_WHITE);
gfx_printf("\nDeleting folder..\n");
fsact_del_recursive(sdbase);
}
}
gfx_printf("\rOut: %s\n", sdbase);
f_mkdir(sdbase);
if ((ret = f_opendir(&dir, sysbase)))
fail = true;
gfx_printf("Starting dump...\n");
SWAPCOLOR(COLOR_GREEN);
printerrors = 0;
while(!f_readdir(&dir, &fno) && fno.fname[0] && !fail){
utils_copystring(fsutil_getnextloc(sysbase, fno.fname), &syspathtemp);
if (fno.fattrib & AM_DIR){
utils_copystring(fsutil_getnextloc(syspathtemp, "00"), &syspath);
}
else
syspath = syspathtemp;
if (daybreak){
u8 ContentType = GetNcaType(syspath);
if (ContentType < 0){
fail = true;
continue;
}
char *temp;
utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &temp);
if (ContentType == 0x01){
sdpath = calloc(strlen(temp) + 6, 1);
strcpy(sdpath, temp);
memcpy(sdpath + strlen(temp) - 4, ".cnmt.nca", 10);
free(temp);
}
else {
sdpath = temp;
}
}
else
utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &sdpath);
ret = fsact_copy(syspath, sdpath, 0);
gfx_printf("%d %s\r", ++amount, fno.fname);
if (ret != 0)
fail = true;
free(sdpath);
free(syspathtemp);
if (syspath != syspathtemp)
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);
hidWait();
return fail;
}
/*
void dumpusersaves(int mmc){
connect_mmc(mmc);
mount_mmc("USER", 2);
gfx_clearscreen();
gfx_printf("Creating folders...\n");
f_mkdir("sd:/tegraexplorer");
gfx_printf("Starting dump...\n");
SWAPCOLOR(COLOR_GREEN);
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");
hidWait();
}
*/
int format(int mode){
gfx_clearscreen();
int res;
bool fatalerror = false;
DWORD plist[] = {666, 61145088, 0, 0};
u32 timer, totalsectors, alignedsectors, extrasectors;
u8 *work;
DWORD clustsize = 32768;
BYTE formatoptions = 0;
formatoptions |= (FM_FAT32);
//formatoptions |= (FM_SFD);
disconnect_mmc();
timer = get_tmr_s();
totalsectors = sd_storage.csd.capacity;
gfx_printf("Initializing...\n");
work = calloc(BUFSIZE, sizeof(BYTE));
if (work == NULL){
gfx_errDisplay("format", ERR_MEM_ALLOC_FAILED, 0);
return 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;
}
else {
totalsectors -= plist[1];
alignedsectors = (totalsectors / 2048) * 2048;
extrasectors = totalsectors - alignedsectors;
plist[0] = alignedsectors;
plist[1] += extrasectors;
gfx_printf("\nStarting SD partitioning:\nTotalSectors: %d\nPartition1 (SD): %d\nPartition2 (EMUMMC): %d\n", plist[0] + plist[1], plist[0], plist[1]);
}
}
else {
plist[0] = totalsectors;
plist[1] = 0;
}
if (!fatalerror){
gfx_printf("\nPartitioning SD...\n");
res = f_fdisk(0, plist, work);
if (res){
gfx_printf("%kf_fdisk returned %d!\n", COLOR_RED, res);
fatalerror = true;
}
else
gfx_printf("Done!\n");
}
if (!fatalerror){
gfx_printf("\n\nFormatting Partition1...\n");
res = f_mkfs("0:", formatoptions, clustsize, work, BUFSIZE * sizeof(BYTE));
if (res){
gfx_printf("%kf_mkfs returned %d!\n", COLOR_RED, res);
fatalerror = true;
}
else
gfx_printf("Smells like a formatted SD\n\n");
}
free(work);
sd_unmount();
if (!fatalerror){
if (!sd_mount())
gfx_printf("%kSd failed to mount!\n", COLOR_ORANGE);
else {
gfx_printf("Sd mounted!\n");
}
}
connect_mmc(SYSMMC);
gfx_printf("\nPress any button to return%k\nTotal time taken: %ds", COLOR_WHITE, (get_tmr_s() - timer));
hidWait();
return fatalerror;
}

View File

@@ -1,7 +0,0 @@
#pragma once
#include "../../utils/types.h"
void displayinfo();
void displaygpio();
int format(int mode);
int dumpfirmware(int mmc, bool daybreak);

View File

@@ -1,205 +0,0 @@
#include <string.h>
#include "utils.h"
#include "../common/common.h"
#include "../gfx/menu.h"
#include "../../storage/emummc.h"
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../../hid/hid.h"
#include "../../utils/util.h"
#include "../../utils/sprintf.h"
#include "../../libs/fatfs/ff.h"
#include "../fs/fsutils.h"
#include "../../mem/minerva.h"
#include "../../storage/nx_sd.h"
#include "../../gfx/di.h"
extern bool sd_mounted;
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);
}
void utils_takeScreenshot(){
static u32 timer = 0;
if (!minerva_cfg || !sd_mounted)
return;
if (timer + 3 < get_tmr_s())
timer = get_tmr_s();
else
return;
char *name, *path;
char basepath[] = "sd:/tegraexplorer/screenshots";
name = malloc(40);
sprintf(name, "Screenshot_%08X.bmp", get_tmr_us());
f_mkdir("sd:/tegraexplorer");
f_mkdir(basepath);
path = fsutil_getnextloc(basepath, name);
free(name);
const u32 file_size = 0x384000 + 0x36;
u8 *bitmap = malloc(file_size);
u32 *fb = malloc(0x384000);
u32 *fb_ptr = gfx_ctxt.fb;
for (int x = 1279; x >= 0; x--)
{
for (int y = 719; y >= 0; y--)
fb[y * 1280 + x] = *fb_ptr++;
}
memcpy(bitmap + 0x36, fb, 0x384000);
bmp_t *bmp = (bmp_t *)bitmap;
bmp->magic = 0x4D42;
bmp->size = file_size;
bmp->rsvd = 0;
bmp->data_off = 0x36;
bmp->hdr_size = 40;
bmp->width = 1280;
bmp->height = 720;
bmp->planes = 1;
bmp->pxl_bits = 32;
bmp->comp = 0;
bmp->img_size = 0x384000;
bmp->res_h = 2834;
bmp->res_v = 2834;
bmp->rsvd2 = 0;
sd_save_to_file(bitmap, file_size, path);
free(bitmap);
free(fb);
display_backlight_brightness(255, 1000);
msleep(100);
display_backlight_brightness(100, 1000);
}
char *utils_InputText(char *start, int maxLen){
if (!hidConnected())
return NULL;
int offset = -1, currentPos = 0, len;
char temp;
Inputs *input = hidRead();
u32 x, y;
gfx_printf("Add characters by pressing X\nRemove characters by pressing Y\nJoysticks for movement\nB to cancel, A to accept\n\n");
gfx_con_getpos(&x, &y);
if (strlen(start) > maxLen)
return NULL;
char *buff;
buff = calloc(maxLen + 1, sizeof(char));
strcpy(buff, start);
while (1){
offset = -1;
gfx_con_setpos(x, y);
for (int i = 0; i < 3; i++){
if (offset != 0){
SWAPCOLOR(0xFF666666);
gfx_con.fntsz = 8;
}
else {
SWAPCOLOR(COLOR_WHITE);
gfx_con.fntsz = 16;
}
for (int x = 0; x < strlen(buff); x++){
if (offset == 0 && x == currentPos){
gfx_printf("%k%c%k", COLOR_GREEN, buff[x], COLOR_WHITE);
}
else {
temp = buff[x] + offset;
if (!(temp >= 32 && temp <= 126))
temp = ' ';
gfx_putc(temp);
}
if (offset != 0)
gfx_puts(" ");
else
gfx_putc(' ');
}
gfx_putc('\n');
offset++;
}
if (input->buttons & (KEY_RDOWN | KEY_RUP))
hidRead();
else
hidWait();
len = strlen(buff);
if (input->buttons & (KEY_A | KEY_B))
break;
if (input->buttons & (KEY_LDOWN | KEY_RDOWN) && buff[currentPos] < 126){
temp = ++buff[currentPos];
while (strchr("\\\"*/:<=>?|+;=[]", temp) != NULL)
temp = ++buff[currentPos];
}
if (input->buttons & (KEY_LUP | KEY_RUP) && buff[currentPos] > 32){
temp = --buff[currentPos];
while (strchr("\\\"*/:<=>?|+;=[]", temp) != NULL)
temp = --buff[currentPos];
}
if (input->Lleft && currentPos > 0)
currentPos--;
if (input->Lright && currentPos < len - 1)
currentPos++;
if (input->x && maxLen > len){
buff[len] = '.';
buff[len + 1] = '\0';
}
if (input->y && len > 1){
buff[len - 1] = '\0';
if (currentPos == len - 1){
currentPos--;
}
gfx_boxGrey(0, y, 1279, y + 48, 0x1B);
}
}
gfx_con.fntsz = 16;
if (input->b){
free(buff);
return NULL;
}
return buff;
}
char *utils_copyStringSize(const char *in, int size){
if (size > strlen(in) || size < 0)
size = strlen(in);
char *out = calloc(size + 1, 1);
//strncpy(out, in, size);
memcpy(out, in, size);
return out;
}

View File

@@ -1,27 +0,0 @@
#pragma once
#include "../../utils/types.h"
typedef struct _bmp_t
{
u16 magic;
u32 size;
u32 rsvd;
u32 data_off;
u32 hdr_size;
u32 width;
u32 height;
u16 planes;
u16 pxl_bits;
u32 comp;
u32 img_size;
u32 res_h;
u32 res_v;
u64 rsvd2;
} __attribute__((packed)) bmp_t;
int utils_mmcMenu();
void utils_copystring(const char *in, char **out);
char *utils_InputText(char *start, int maxLen);
void utils_takeScreenshot();
char *utils_copyStringSize(const char *in, int size);