mirror of
https://github.com/suchmememanyskill/TegraExplorer.git
synced 2024-11-26 05:42:07 +00:00
add partition dumping
This commit is contained in:
parent
45d86a31b1
commit
db2e115fb0
7 changed files with 141 additions and 31 deletions
|
@ -26,7 +26,9 @@ const char *TEErrors[] = {
|
|||
[TE_ERR_SAME_LOC - 1] = "Same copy location",
|
||||
[TE_ERR_KEYDUMP_FAIL - 1] = "Keydump failed",
|
||||
[TE_ERR_PARTITION_NOT_FOUND - 1] = "Failed to find partition",
|
||||
[TE_ERR_PATH_IN_PATH - 1] = "Can't move/copy folder into itself"
|
||||
[TE_ERR_PATH_IN_PATH - 1] = "Can't move/copy folder into itself",
|
||||
[TE_ERR_EMMC_READ_FAIL - 1] = "Emmc/Emummc read failed",
|
||||
[TE_ERR_NO_SD - 1] = "No sd detected",
|
||||
};
|
||||
|
||||
const char *GetErrStr(u32 err){
|
||||
|
|
|
@ -17,6 +17,9 @@ enum {
|
|||
TE_ERR_KEYDUMP_FAIL,
|
||||
TE_ERR_PARTITION_NOT_FOUND,
|
||||
TE_ERR_PATH_IN_PATH,
|
||||
TE_ERR_EMMC_READ_FAIL,
|
||||
TE_ERR_EMMC_WRITE_FAIL,
|
||||
TE_ERR_NO_SD,
|
||||
};
|
||||
|
||||
#define newErrCode(err) (ErrCode_t) {err, __LINE__, __FILE__}
|
||||
|
|
84
source/storage/emmcfile.c
Normal file
84
source/storage/emmcfile.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include "emmcfile.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "emummc.h"
|
||||
#include "mountmanager.h"
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include "nx_emmc.h"
|
||||
#include <mem/heap.h>
|
||||
#include "../err.h"
|
||||
#include "../tegraexplorer/tconf.h"
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../hid/hid.h"
|
||||
#include <storage/nx_sd.h>
|
||||
#include <string.h>
|
||||
|
||||
// Uses default storage in nx_emmc.c
|
||||
// Expects the correct mmc & partition to be set
|
||||
ErrCode_t EmmcDumpToFile(const char *path, u32 lba_start, u32 lba_end){
|
||||
FIL fp;
|
||||
u32 curLba = lba_start;
|
||||
u32 totalSectors = lba_end - lba_start + 1;
|
||||
|
||||
int res = f_open(&fp, path, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (res){
|
||||
return newErrCode(res);
|
||||
}
|
||||
|
||||
ErrCode_t err = newErrCode(0);
|
||||
|
||||
u8 *buff = malloc(TConf.FSBuffSize);
|
||||
|
||||
u32 x, y;
|
||||
gfx_con_getpos(&x, &y);
|
||||
|
||||
while (totalSectors > 0){
|
||||
u32 num = MIN(totalSectors, TConf.FSBuffSize / NX_EMMC_BLOCKSIZE);
|
||||
if (!emummc_storage_read(&emmc_storage, curLba, num, buff)){
|
||||
err = newErrCode(TE_ERR_EMMC_READ_FAIL);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((res = f_write(&fp, buff, num * NX_EMMC_BLOCKSIZE, NULL))){
|
||||
err = newErrCode(res);
|
||||
break;
|
||||
}
|
||||
|
||||
curLba += num;
|
||||
totalSectors -= num;
|
||||
|
||||
u32 percent = ((curLba - lba_start) * 100) / ((lba_end - lba_start + 1));
|
||||
gfx_printf("[%3d%%]", percent);
|
||||
gfx_con_setpos(x, y);
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
free(buff);
|
||||
return err;
|
||||
}
|
||||
|
||||
ErrCode_t DumpEmmcPart(const char *path, const char *part){
|
||||
const u32 BOOT_PART_SIZE = emmc_storage.ext_csd.boot_mult << 17;
|
||||
|
||||
if (!sd_mount())
|
||||
return newErrCode(TE_ERR_NO_SD);
|
||||
|
||||
// maybe check for existing file here
|
||||
|
||||
if (!memcmp(part, "BOOT0", 5)){
|
||||
emummc_storage_set_mmc_partition(&emmc_storage, 1);
|
||||
return EmmcDumpToFile(path, 0, (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1);
|
||||
}
|
||||
else if (!memcmp(part, "BOOT1", 5)){
|
||||
emummc_storage_set_mmc_partition(&emmc_storage, 2);
|
||||
return EmmcDumpToFile(path, 0, (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1);
|
||||
}
|
||||
else {
|
||||
emummc_storage_set_mmc_partition(&emmc_storage, 0);
|
||||
|
||||
emmc_part_t *system_part = nx_emmc_part_find(GetCurGPT(), part);
|
||||
if (!system_part)
|
||||
return newErrCode(TE_ERR_PARTITION_NOT_FOUND);
|
||||
|
||||
return EmmcDumpToFile(path, system_part->lba_start, system_part->lba_end);
|
||||
}
|
||||
}
|
4
source/storage/emmcfile.h
Normal file
4
source/storage/emmcfile.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "../err.h"
|
||||
|
||||
ErrCode_t DumpEmmcPart(const char *path, const char *part);
|
|
@ -11,11 +11,15 @@
|
|||
#include "../fs/menus/explorer.h"
|
||||
#include "../err.h"
|
||||
#include "../tegraexplorer/tconf.h"
|
||||
#include "emmcfile.h"
|
||||
#include <storage/nx_sd.h>
|
||||
#include "../fs/fsutils.h"
|
||||
|
||||
MenuEntry_t GptMenuHeader[] = {
|
||||
{.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "<- Back"},
|
||||
{.optionUnion = COLORTORGB(COLOR_GREY) | SKIPBIT, .name = "Clipboard -> Partition"},
|
||||
{.optionUnion = COLORTORGB(COLOR_GREY) | SKIPBIT, .name = "\nBoot0/1"} // Should be blue when implemented
|
||||
{.optionUnion = COLORTORGB(COLOR_GREY) | SKIPBIT, .name = "Clipboard -> Partition\n"},
|
||||
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "BOOT0", .icon = 128, .showSize = 1, .size = 4, .sizeDef = 2},
|
||||
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "BOOT1", .icon = 128, .showSize = 1, .size = 4, .sizeDef = 2}
|
||||
};
|
||||
|
||||
const char *GptFSEntries[] = {
|
||||
|
@ -30,7 +34,7 @@ void GptMenu(u8 MMCType){
|
|||
return;
|
||||
|
||||
Vector_t GptMenu = newVec(sizeof(MenuEntry_t), 15);
|
||||
GptMenu.count = 3;
|
||||
GptMenu.count = ARR_LEN(GptMenuHeader);
|
||||
memcpy(GptMenu.data, GptMenuHeader, sizeof(MenuEntry_t) * ARR_LEN(GptMenuHeader));
|
||||
|
||||
link_t *gpt = GetCurGPT();
|
||||
|
@ -70,7 +74,7 @@ void GptMenu(u8 MMCType){
|
|||
|
||||
res = newMenu(&GptMenu, res, 40, 20, ALWAYSREDRAW | ENABLEB, GptMenu.count);
|
||||
|
||||
if (res < 3){
|
||||
if (res < 2){
|
||||
break;
|
||||
}
|
||||
else if (entries[res].icon == 127){
|
||||
|
@ -88,7 +92,25 @@ void GptMenu(u8 MMCType){
|
|||
}
|
||||
}
|
||||
else {
|
||||
DrawError(newErrCode(TE_ERR_UNIMPLEMENTED));
|
||||
if (!sd_mount())
|
||||
continue;
|
||||
|
||||
gfx_clearscreen();
|
||||
gfx_printf("Do you want to dump %s? ", entries[res].name);
|
||||
if (MakeYesNoHorzMenu(3, COLOR_DEFAULT)){
|
||||
gfx_putc('\n');
|
||||
RESETCOLOR;
|
||||
gfx_printf("Dumping %s... ", entries[res].name);
|
||||
|
||||
f_mkdir("sd:/tegraexplorer");
|
||||
f_mkdir("sd:/tegraexplorer/Dumps");
|
||||
|
||||
char *path = CombinePaths("sd:/tegraexplorer/Dumps", entries[res].name);
|
||||
|
||||
ErrCode_t a = DumpEmmcPart(path, entries[res].name);
|
||||
if (a.err)
|
||||
DrawError(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,12 +27,16 @@ void SetKeySlots(){
|
|||
|
||||
LIST_INIT(curGpt);
|
||||
|
||||
void disconnectMMC(){
|
||||
void unmountMMCPart(){
|
||||
if (TConf.connectedMMCMounted)
|
||||
f_unmount("bis:");
|
||||
TConf.connectedMMCMounted = 0;
|
||||
}
|
||||
|
||||
void disconnectMMC(){
|
||||
unmountMMCPart();
|
||||
|
||||
if (TConf.currentMMCConnected != MMC_CONN_None){
|
||||
TConf.connectedMMCMounted = 0;
|
||||
TConf.currentMMCConnected = MMC_CONN_None;
|
||||
emummc_storage_end(&emmc_storage);
|
||||
nx_emmc_gpt_free(&curGpt);
|
||||
|
@ -57,7 +61,8 @@ int connectMMC(u8 mmcType){
|
|||
}
|
||||
|
||||
ErrCode_t mountMMCPart(const char *partition){
|
||||
if (!TConf.connectedMMCMounted){
|
||||
unmountMMCPart();
|
||||
|
||||
emummc_storage_set_mmc_partition(&emmc_storage, 0); // why i have to do this twice beats me
|
||||
|
||||
emmc_part_t *system_part = nx_emmc_part_find(&curGpt, partition);
|
||||
|
@ -71,7 +76,7 @@ ErrCode_t mountMMCPart(const char *partition){
|
|||
return newErrCode(res);
|
||||
|
||||
TConf.connectedMMCMounted = 1;
|
||||
}
|
||||
|
||||
|
||||
return newErrCode(0);
|
||||
}
|
||||
|
@ -81,9 +86,3 @@ link_t *GetCurGPT(){
|
|||
return &curGpt;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void unmountMMCPart(){
|
||||
if (TConf.connectedMMCMounted)
|
||||
f_unmount("bis:");
|
||||
TConf.connectedMMCMounted = 0;
|
||||
}
|
|
@ -15,10 +15,6 @@
|
|||
#include <utils/util.h>
|
||||
#include "../fs/fsutils.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "../utils/utils.h"
|
||||
#include <mem/heap.h>
|
||||
|
||||
enum {
|
||||
MainExplore = 0,
|
||||
MainBrowseSd,
|
||||
|
|
Loading…
Reference in a new issue