Added ability to calculate & compare file SHA-256

This commit is contained in:
d0k3 2016-04-25 02:46:32 +02:00
parent 369061cf5b
commit 663aa681f6
6 changed files with 140 additions and 8 deletions

View File

@ -2,6 +2,7 @@
#include "fs.h" #include "fs.h"
#include "virtual.h" #include "virtual.h"
#include "image.h" #include "image.h"
#include "sha.h"
#include "ff.h" #include "ff.h"
#define MAIN_BUFFER ((u8*)0x21200000) #define MAIN_BUFFER ((u8*)0x21200000)
@ -204,6 +205,53 @@ size_t FileGetSize(const char* path) {
return 0; return 0;
} }
bool FileGetSha256(const char* path, u8* sha256) {
bool ret = true;
sha_init(SHA256_MODE);
ShowProgress(0, 0, path);
if (GetVirtualSource(path)) { // for virtual files
VirtualFile vfile;
u32 fsize;
if (!FindVirtualFile(&vfile, path, 0))
return false;
fsize = vfile.size;
for (size_t pos = 0; (pos < fsize) && ret; pos += MAIN_BUFFER_SIZE) {
UINT read_bytes = min(MAIN_BUFFER_SIZE, fsize - pos);
if (ReadVirtualFile(&vfile, MAIN_BUFFER, pos, read_bytes, NULL) != 0)
ret = false;
if (!ShowProgress(pos + read_bytes, fsize, path))
ret = false;
sha_update(MAIN_BUFFER, read_bytes);
}
} else { // for regular FAT files
FIL file;
size_t fsize;
if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return false;
fsize = f_size(&file);
f_lseek(&file, 0);
f_sync(&file);
for (size_t pos = 0; (pos < fsize) && ret; pos += MAIN_BUFFER_SIZE) {
UINT bytes_read = 0;
if (f_read(&file, MAIN_BUFFER, MAIN_BUFFER_SIZE, &bytes_read) != FR_OK)
ret = false;
if (!ShowProgress(pos + bytes_read, fsize, path))
ret = false;
sha_update(MAIN_BUFFER, bytes_read);
}
f_close(&file);
}
ShowProgress(1, 1, path);
sha_get(sha256);
return ret;
}
bool PathCopyVirtual(const char* destdir, const char* orig) { bool PathCopyVirtual(const char* destdir, const char* orig) {
char dest[256]; // maximum path name length in FAT char dest[256]; // maximum path name length in FAT
char* oname = strrchr(orig, '/'); char* oname = strrchr(orig, '/');

View File

@ -47,6 +47,9 @@ size_t FileGetData(const char* path, u8* data, size_t size, size_t foffset);
/** Get size of file **/ /** Get size of file **/
size_t FileGetSize(const char* path); size_t FileGetSize(const char* path);
/** Get SHA-256 of file **/
bool FileGetSha256(const char* path, u8* sha256);
/** Recursively copy a file or directory **/ /** Recursively copy a file or directory **/
bool PathCopy(const char* destdir, const char* orig); bool PathCopy(const char* destdir, const char* orig);

View File

@ -336,8 +336,45 @@ u32 GodMode() {
} else cursor = 0; } else cursor = 0;
} else if ((pad_state & BUTTON_A) && (curr_entry->type == T_FILE)) { // process a file } else if ((pad_state & BUTTON_A) && (curr_entry->type == T_FILE)) { // process a file
u32 file_type = IdentifyImage(curr_entry->path); u32 file_type = IdentifyImage(curr_entry->path);
if (file_type && (PathToNumFS(curr_entry->path) == 0) && // try to mount image / only on SD char pathstr[32 + 1];
ShowPrompt(true, "This looks like a %s image\nTry to mount it?", (file_type == IMG_NAND) ? "NAND" : "FAT")) { const char* options[4];
u32 n_opt = 2;
TruncateString(pathstr, curr_entry->path, 32, 8);
options[0] = "Show in Hexviewer";
options[1] = "Calculate SHA-256";
if (file_type && (PathToNumFS(curr_entry->path) == 0)) {
options[2] = (file_type == IMG_NAND) ? "Mount as NAND image" : "Mount as FAT image";
n_opt = 3;
}
u32 user_select = ShowSelectPrompt(n_opt, options, pathstr);
if (user_select == 1) { // -> show in hex viewer
static bool show_instr = true;
if (show_instr) {
ShowPrompt(false, "HexViewer Controls:\n \n\x18\x19\x1A\x1B(+R) - Scroll\nR+Y - Switch view\nB - Exit\n");
show_instr = false;
}
HexViewer(curr_entry->path);
} else if (user_select == 2) { // -> calculate SHA-256
static char pathstr_prev[32 + 1] = { 0 };
static u8 sha256_prev[32] = { 0 };
u8 sha256[32];
if (!FileGetSha256(curr_entry->path, sha256)) {
ShowPrompt(false, "Calculating SHA-256: failed!");
} else {
ShowPrompt(false, "%s\n%08X%08X%08X%08X\n%08X%08X%08X%08X%s%s",
pathstr,
getbe32(sha256 + 0), getbe32(sha256 + 4),
getbe32(sha256 + 8), getbe32(sha256 + 12),
getbe32(sha256 + 16), getbe32(sha256 + 20),
getbe32(sha256 + 24), getbe32(sha256 + 28),
(memcmp(sha256, sha256_prev, 32) == 0) ? "\n \nIdentical with previous file:\n" : "",
(memcmp(sha256, sha256_prev, 32) == 0) ? pathstr_prev : "");
strncpy(pathstr_prev, pathstr, 32 + 1);
memcpy(sha256_prev, sha256, 32);
}
} else if (user_select == 3) { // -> mount as image
DeinitExtFS(); DeinitExtFS();
u32 mount_state = MountImage(curr_entry->path); u32 mount_state = MountImage(curr_entry->path);
InitExtFS(); InitExtFS();
@ -353,9 +390,6 @@ u32 GodMode() {
} }
if (clipboard->n_entries && (strcspn(clipboard->entry[0].path, IMG_DRV) == 0)) if (clipboard->n_entries && (strcspn(clipboard->entry[0].path, IMG_DRV) == 0))
clipboard->n_entries = 0; // remove invalid clipboard stuff clipboard->n_entries = 0; // remove invalid clipboard stuff
} else if (FileGetSize(curr_entry->path) &&
ShowPrompt(true, "Show HexViewer?\n \nControls:\n\x18\x19\x1A\x1B(+R) - Scroll\nR+Y - Switch view\nB - Exit\n")) {
HexViewer(curr_entry->path);
} }
} else if (*current_path && ((pad_state & BUTTON_B) || // one level down } else if (*current_path && ((pad_state & BUTTON_B) || // one level down
((pad_state & BUTTON_A) && (curr_entry->type == T_DOTDOT)))) { ((pad_state & BUTTON_A) && (curr_entry->type == T_DOTDOT)))) {

View File

@ -203,7 +203,7 @@ bool ShowPrompt(bool ask, const char *format, ...)
while (true) { while (true) {
u32 pad_state = InputWait(); u32 pad_state = InputWait();
if (pad_state & BUTTON_A) break; if (pad_state & BUTTON_A) break;
else if (ask && (pad_state & BUTTON_B)) { else if (pad_state & BUTTON_B) {
ret = false; ret = false;
break; break;
} }
@ -274,6 +274,51 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
return (lvl >= len); return (lvl >= len);
} }
u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) {
u32 str_width, str_height;
u32 x, y, yopt;
u32 sel = 0;
char str[512] = {}; // 512 should be more than enough
va_list va;
va_start(va, format);
vsnprintf(str, 512, format, va);
va_end(va);
if (n == 0) return 0; // check for low number of options
else if (n == 1) return ShowPrompt(true, "%s\n%s?", str, options[0]) ? 1 : 0;
str_width = GetDrawStringWidth(str);
str_height = GetDrawStringHeight(str) + (n * 12) + (3 * 10);
if (str_width < 18*8) str_width = 18 * 8;
x = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2;
y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2;
yopt = y + GetDrawStringHeight(str) + 8;
ClearScreenF(true, false, COLOR_STD_BG);
DrawStringF(true, x, y, COLOR_STD_FONT, COLOR_STD_BG, str);
DrawStringF(true, x, yopt + (n*12) + 10, COLOR_STD_FONT, COLOR_STD_BG, "(<A> select, <B> cancel)");
while (true) {
for (u32 i = 0; i < n; i++) {
DrawStringF(true, x, yopt + (12*i), (sel == i) ? COLOR_STD_FONT : COLOR_LIGHTGREY, COLOR_STD_BG, "%2.2s %s",
(sel == i) ? "->" : "", options[i]);
}
u32 pad_state = InputWait();
if (pad_state & BUTTON_DOWN) sel = (sel+1) % n;
else if (pad_state & BUTTON_UP) sel = (sel+n-1) % n;
else if (pad_state & BUTTON_A) break;
else if (pad_state & BUTTON_B) {
sel = n;
break;
}
}
ClearScreenF(true, false, COLOR_STD_BG);
return (sel >= n) ? 0 : sel + 1;
}
bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...) { bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...) {
const char* alphabet = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz(){}[]'`^,~!@#$%&0123456789=+-_."; const char* alphabet = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz(){}[]'`^,~!@#$%&0123456789=+-_.";
const u32 alphabet_size = strnlen(alphabet, 256); const u32 alphabet_size = strnlen(alphabet, 256);

View File

@ -30,6 +30,7 @@
#define COLOR_TINTEDBLUE RGB(0x60, 0x60, 0x80) #define COLOR_TINTEDBLUE RGB(0x60, 0x60, 0x80)
#define COLOR_TINTEDYELLOW RGB(0xD0, 0xD0, 0x60) #define COLOR_TINTEDYELLOW RGB(0xD0, 0xD0, 0x60)
#define COLOR_TINTEDGREEN RGB(0x70, 0x80, 0x70) #define COLOR_TINTEDGREEN RGB(0x70, 0x80, 0x70)
#define COLOR_LIGHTGREY RGB(0xB0, 0xB0, 0xB0)
#define COLOR_DARKGREY RGB(0x50, 0x50, 0x50) #define COLOR_DARKGREY RGB(0x50, 0x50, 0x50)
#define COLOR_DARKESTGREY RGB(0x20, 0x20, 0x20) #define COLOR_DARKESTGREY RGB(0x20, 0x20, 0x20)
@ -72,5 +73,6 @@ void FormatBytes(char* str, u64 bytes);
bool ShowPrompt(bool ask, const char *format, ...); bool ShowPrompt(bool ask, const char *format, ...);
bool ShowUnlockSequence(u32 seqlvl, const char *format, ...); bool ShowUnlockSequence(u32 seqlvl, const char *format, ...);
u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...);
bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...); bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...);
bool ShowProgress(u64 current, u64 total, const char* opstr); bool ShowProgress(u64 current, u64 total, const char* opstr);