mirror of
https://github.com/suchmememanyskill/TegraExplorer.git
synced 2024-11-22 11:56:42 +00:00
Add biskey dumping + more menus
Thanks shchmue :D Also can now mount and unmount the sd via the tools menu
This commit is contained in:
parent
7a35d2b00c
commit
f3808edb40
8 changed files with 221 additions and 25 deletions
|
@ -16,12 +16,19 @@
|
||||||
#include "../soc/t210.h"
|
#include "../soc/t210.h"
|
||||||
#include "../sec/se.h"
|
#include "../sec/se.h"
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
#include "../keys/key_sources.inl"
|
#include "../hos/pkg1.h"
|
||||||
|
#include "../storage/nx_emmc.h"
|
||||||
|
#include "../sec/tsec.h"
|
||||||
|
#include "../soc/t210.h"
|
||||||
|
#include "../soc/fuse.h"
|
||||||
|
#include "../mem/mc.h"
|
||||||
|
|
||||||
extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
|
extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
|
||||||
extern boot_cfg_t b_cfg;
|
extern boot_cfg_t b_cfg;
|
||||||
extern bool sd_mount();
|
extern bool sd_mount();
|
||||||
extern void sd_unmount();
|
extern void sd_unmount();
|
||||||
|
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);
|
||||||
|
|
||||||
int launch_payload(char *path, bool update)
|
int launch_payload(char *path, bool update)
|
||||||
{
|
{
|
||||||
|
@ -79,4 +86,106 @@ int launch_payload(char *path, bool update)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 4;
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_biskeys(u8 bis_key[4][32]){
|
||||||
|
tsec_ctxt_t tsec_ctxt;
|
||||||
|
sdmmc_t sdmmc;
|
||||||
|
sdmmc_storage_t storage;
|
||||||
|
u8 temp_key[0x10], device_key[0x10] = {0};
|
||||||
|
|
||||||
|
int retries = 0;
|
||||||
|
|
||||||
|
sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1);
|
||||||
|
if (!pkg1_id) {
|
||||||
|
EPRINTF("Unknown pkg1 version.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
|
@ -12,4 +12,42 @@
|
||||||
#define EMC_BASE 0x7001B000
|
#define EMC_BASE 0x7001B000
|
||||||
#define EMC(off) _REG(EMC_BASE, off)
|
#define EMC(off) _REG(EMC_BASE, off)
|
||||||
|
|
||||||
int launch_payload(char *path, int update);
|
#include "../utils/types.h"
|
||||||
|
|
||||||
|
int launch_payload(char *path, int update);
|
||||||
|
void dump_biskeys(u8 bis_key[4][32]);
|
||||||
|
|
||||||
|
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}
|
||||||
|
};
|
|
@ -16,7 +16,11 @@ extern bool sd_mount();
|
||||||
extern void sd_unmount();
|
extern void sd_unmount();
|
||||||
|
|
||||||
void meme_main(){
|
void meme_main(){
|
||||||
utils_gfx_init();
|
utils_gfx_init();
|
||||||
|
//dump_keys();
|
||||||
|
|
||||||
|
u8 bis_keys[4][0x20] = {0};
|
||||||
|
dump_biskeys(bis_keys);
|
||||||
|
|
||||||
sdmmc_storage_t storage;
|
sdmmc_storage_t storage;
|
||||||
sdmmc_t sdmmc;
|
sdmmc_t sdmmc;
|
||||||
|
@ -29,6 +33,7 @@ void meme_main(){
|
||||||
unsigned int muhbits[1000];
|
unsigned int muhbits[1000];
|
||||||
bool sd_mounted = false;
|
bool sd_mounted = false;
|
||||||
sd_mounted = sd_mount();
|
sd_mounted = sd_mount();
|
||||||
|
if (!sd_mounted) messagebox("\nSD INIT FAILED");
|
||||||
|
|
||||||
while (1){
|
while (1){
|
||||||
int i = 0, ret = 0;
|
int i = 0, ret = 0;
|
||||||
|
@ -36,19 +41,53 @@ void meme_main(){
|
||||||
addchartoarray("[SD:/] SD card", options, i);
|
addchartoarray("[SD:/] SD card", options, i);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else messagebox("\nSD INIT FAILED");
|
//addchartoarray("[emmc:/] SYSTEM", options, i);
|
||||||
addchartoarray("\nAbout", options, i);
|
addchartoarray("\nTools", options, i);
|
||||||
addchartoarray("Exit", options, i+1);
|
addchartoarray("About", options, i+1);
|
||||||
|
addchartoarray("Exit", options, i+2);
|
||||||
|
|
||||||
meme_clearscreen();
|
meme_clearscreen();
|
||||||
ret = gfx_menulist(32, options, (i + 2));
|
ret = gfx_menulist(32, options, (i + 3));
|
||||||
|
|
||||||
if (strcmp(options[ret - 1], "[SD:/] SD card") == 0){
|
if (strcmp(options[ret - 1], "[SD:/] SD card") == 0){
|
||||||
sdexplorer(itemsinfolder, muhbits);
|
sdexplorer(itemsinfolder, muhbits, "sd:/");
|
||||||
}
|
}
|
||||||
else if (strcmp(options[ret - 1], "\nAbout") == 0){
|
else if (strcmp(options[ret - 1], "About") == 0){
|
||||||
messagebox(ABOUT_MESSAGE);
|
messagebox(ABOUT_MESSAGE);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(options[ret - 1], "[emmc:/] SYSTEM") == 0){
|
||||||
|
sdexplorer(itemsinfolder, muhbits, "emmc:/");
|
||||||
|
}
|
||||||
|
else if (strcmp(options[ret - 1], "\nTools") == 0){
|
||||||
|
meme_clearscreen();
|
||||||
|
addchartoarray("Back", options, 0);
|
||||||
|
addchartoarray("\nPrint BISKEYS", options, 1);
|
||||||
|
if (!sd_mounted) addchartoarray("Mount SD", options, 2);
|
||||||
|
else addchartoarray("Unmount SD", options, 2);
|
||||||
|
ret = gfx_menulist(32, options, 3);
|
||||||
|
switch(ret){
|
||||||
|
case 2:
|
||||||
|
meme_clearscreen();
|
||||||
|
gfx_printf("\nBisKey 0:\n");
|
||||||
|
gfx_hexdump(0, bis_keys[0], 0x20 * sizeof(u8));
|
||||||
|
gfx_printf("\n\nBisKey 1:\n");
|
||||||
|
gfx_hexdump(0, bis_keys[1], 0x20 * sizeof(u8));
|
||||||
|
gfx_printf("\n\nBisKey 2 + 3:\n");
|
||||||
|
gfx_hexdump(0, bis_keys[2], 0x20 * sizeof(u8));
|
||||||
|
btn_wait();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (sd_mounted){
|
||||||
|
sd_unmount();
|
||||||
|
sd_mounted = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sd_mounted = sd_mount();
|
||||||
|
if (!sd_mounted) messagebox("\nSD INIT FAILED");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
meme_clearscreen();
|
meme_clearscreen();
|
||||||
addchartoarray("Back", options, 0);
|
addchartoarray("Back", options, 0);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define ABOUT_MESSAGE "\nCreator: Such Meme, Many Skill#2921\nCool guy: Denn\nTesters: PhazonicRidley, huhen\n\n\nProject based on code from:\n- Lockpick_RCM\n- Hekate"
|
#define ABOUT_MESSAGE "\nCreator: Such Meme, Many Skill#2921\nCool people: Denn, shchmue\nTesters: PhazonicRidley, huhen\n\n\nProject based on Lockpick_RCM\n With additional code from Hekate"
|
||||||
|
|
||||||
void meme_main();
|
void meme_main();
|
|
@ -61,25 +61,33 @@ int _openfilemenu(char *path, char *clipboardpath){
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdexplorer(char *items[], unsigned int *muhbits){
|
void sdexplorer(char *items[], unsigned int *muhbits, char *rootpath){
|
||||||
int value = 1;
|
int value = 1;
|
||||||
int copymode = -1;
|
int copymode = -1;
|
||||||
int folderamount = 0;
|
int folderamount = 0;
|
||||||
char path[PATHSIZE] = "sd:/";
|
char path[PATHSIZE] = "sd:/";
|
||||||
|
strcpy(path, rootpath);
|
||||||
|
char app[20], rpp[20];
|
||||||
char clipboard[PATHSIZE] = "";
|
char clipboard[PATHSIZE] = "";
|
||||||
int temp = -1;
|
int temp = -1;
|
||||||
|
strcpy(app, rootpath);
|
||||||
|
strcpy(rpp, app);
|
||||||
|
removepartpath(rpp, "rpp");
|
||||||
//static const u32 colors[8] = {COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_VIOLET, COLOR_DEFAULT, COLOR_WHITE};
|
//static const u32 colors[8] = {COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREEN, COLOR_BLUE, COLOR_VIOLET, COLOR_DEFAULT, COLOR_WHITE};
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
gfx_clear_grey(0x1B);
|
gfx_clear_grey(0x1B);
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
gfx_box(0, 0, 719, 15, COLOR_WHITE);
|
gfx_box(0, 0, 719, 15, COLOR_WHITE);
|
||||||
folderamount = readfolder(items, muhbits, path);
|
folderamount = readfolder(items, muhbits, path);
|
||||||
gfx_printf("%k%pTegraExplorer %d\n%k%p", COLOR_DEFAULT, COLOR_WHITE, folderamount - 2, COLOR_WHITE, COLOR_DEFAULT);
|
gfx_printf("%k%pTegraExplorer - %s", COLOR_DEFAULT, COLOR_WHITE, app);
|
||||||
|
gfx_con_setpos(39 * 16, 0);
|
||||||
|
gfx_printf("%d\n%k%p", folderamount - 2, COLOR_WHITE, COLOR_DEFAULT);
|
||||||
value = fileexplorergui(items, muhbits, path, folderamount);
|
value = fileexplorergui(items, muhbits, path, folderamount);
|
||||||
|
|
||||||
if (value == 1) {
|
if (value == 1) {
|
||||||
if (strcmp("sd:/", path) == 0) break;
|
if (strcmp(app, path) == 0) break;
|
||||||
else removepartpath(path);
|
else removepartpath(path, rpp);
|
||||||
}
|
}
|
||||||
else if (value == 2) {
|
else if (value == 2) {
|
||||||
if (copymode != -1){
|
if (copymode != -1){
|
||||||
|
@ -88,12 +96,12 @@ void sdexplorer(char *items[], unsigned int *muhbits){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(muhbits[value - 1] & OPTION1) addpartpath(path, items[value - 1]);
|
if(muhbits[value - 1] & OPTION1) addpartpath(path, items[value - 1], app);
|
||||||
else {
|
else {
|
||||||
addpartpath(path, items[value - 1]);
|
addpartpath(path, items[value - 1], app);
|
||||||
temp = _openfilemenu(path, clipboard);
|
temp = _openfilemenu(path, clipboard);
|
||||||
if (temp != -1) copymode = temp;
|
if (temp != -1) copymode = temp;
|
||||||
removepartpath(path);
|
removepartpath(path, rpp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void sdexplorer(char *items[], unsigned int *muhbits);
|
void sdexplorer(char *items[], unsigned int *muhbits, char *rootpath);
|
|
@ -17,15 +17,17 @@ void utils_gfx_init(){
|
||||||
gfx_con_setpos(0, 0);
|
gfx_con_setpos(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void removepartpath(char *path){
|
void removepartpath(char *path, char *root){
|
||||||
char *ret;
|
char *ret;
|
||||||
|
char temproot[20];
|
||||||
ret = strrchr(path, '/');
|
ret = strrchr(path, '/');
|
||||||
memset(ret, '\0', 1);
|
memset(ret, '\0', 1);
|
||||||
if (strcmp(path, "sd:") == 0) strcpy(path, "sd:/");
|
sprintf(temproot, "%s%s", root, "/");
|
||||||
|
if (strcmp(path, root) == 0) strcpy(path, temproot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addpartpath(char *path, char *add){
|
void addpartpath(char *path, char *add, char *root){
|
||||||
if (strcmp(path, "sd:/") != 0) strcat(path, "/");
|
if (strcmp(path, root) != 0) strcat(path, "/");
|
||||||
strcat(path, add);
|
strcat(path, add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +133,7 @@ int copy(const char *src, const char *dst){
|
||||||
|
|
||||||
kbwritten = kbwritten + (BUFFSIZ / 1024);
|
kbwritten = kbwritten + (BUFFSIZ / 1024);
|
||||||
mbwritten = kbwritten / 1024;
|
mbwritten = kbwritten / 1024;
|
||||||
percentage = (mbwritten * 100) / (totalsize / 1024 / 1024);
|
percentage = (mbwritten * 100) / ((totalsize / 1024) / 1024);
|
||||||
|
|
||||||
gfx_printf("Written %dMB [%k%d%k%%]\r", mbwritten, COLOR_GREEN, percentage, COLOR_WHITE);
|
gfx_printf("Written %dMB [%k%d%k%%]\r", mbwritten, COLOR_GREEN, percentage, COLOR_WHITE);
|
||||||
size = size - BUFFSIZ;
|
size = size - BUFFSIZ;
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
#define PATHSIZE 512
|
#define PATHSIZE 512
|
||||||
|
|
||||||
void utils_gfx_init();
|
void utils_gfx_init();
|
||||||
void removepartpath(char *path);
|
void removepartpath(char *path, char *root);
|
||||||
void addpartpath(char *path, char *add);
|
void addpartpath(char *path, char *add, char *root);
|
||||||
int readfolder(char *items[], unsigned int *muhbits, const char *path);
|
int readfolder(char *items[], unsigned int *muhbits, const char *path);
|
||||||
int copy(const char *src, const char *dst);
|
int copy(const char *src, const char *dst);
|
||||||
void addchartoarray(char *add, char *items[], int spot);
|
void addchartoarray(char *add, char *items[], int spot);
|
||||||
|
|
Loading…
Reference in a new issue