forked from Mirror/GodMode9
Allow injecting files into files
This commit is contained in:
parent
3a59f37fc9
commit
56ac8c1e68
80
source/fs.c
80
source/fs.c
@ -301,6 +301,86 @@ bool FileGetSha256(const char* path, u8* sha256) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FileInjectFile(const char* dest, const char* orig, u32 offset) {
|
||||||
|
VirtualFile dvfile;
|
||||||
|
VirtualFile ovfile;
|
||||||
|
FIL ofile;
|
||||||
|
FIL dfile;
|
||||||
|
size_t osize;
|
||||||
|
size_t dsize;
|
||||||
|
|
||||||
|
bool vdest;
|
||||||
|
bool vorig;
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
if (!CheckWritePermissions(dest)) return false;
|
||||||
|
|
||||||
|
// open destination
|
||||||
|
if (GetVirtualSource(dest)) {
|
||||||
|
vdest = true;
|
||||||
|
if (!FindVirtualFile(&dvfile, dest, 0))
|
||||||
|
return false;
|
||||||
|
dsize = dvfile.size;
|
||||||
|
} else {
|
||||||
|
vdest = false;
|
||||||
|
if (f_open(&dfile, dest, FA_WRITE | FA_OPEN_EXISTING) != FR_OK)
|
||||||
|
return false;
|
||||||
|
dsize = f_size(&dfile);
|
||||||
|
f_lseek(&dfile, offset);
|
||||||
|
f_sync(&dfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// open origin
|
||||||
|
if (GetVirtualSource(orig)) {
|
||||||
|
vorig = true;
|
||||||
|
if (!FindVirtualFile(&ovfile, orig, 0)) {
|
||||||
|
if (!vdest) f_close(&dfile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
osize = ovfile.size;
|
||||||
|
} else {
|
||||||
|
vorig = false;
|
||||||
|
if (f_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK) {
|
||||||
|
if (!vdest) f_close(&dfile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
osize = f_size(&ofile);
|
||||||
|
f_lseek(&ofile, 0);
|
||||||
|
f_sync(&ofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check file limits
|
||||||
|
if (offset + osize > dsize) {
|
||||||
|
ShowPrompt(false, "Operation would write beyond end of file");
|
||||||
|
if (!vdest) f_close(&dfile);
|
||||||
|
if (!vorig) f_close(&ofile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
for (size_t pos = 0; (pos < osize) && ret; pos += MAIN_BUFFER_SIZE) {
|
||||||
|
UINT read_bytes = min(MAIN_BUFFER_SIZE, osize - pos);
|
||||||
|
UINT bytes_read = read_bytes;
|
||||||
|
UINT bytes_written = read_bytes;
|
||||||
|
if ((!vorig && (f_read(&ofile, MAIN_BUFFER, read_bytes, &bytes_read) != FR_OK)) ||
|
||||||
|
(vorig && ReadVirtualFile(&ovfile, MAIN_BUFFER, pos, read_bytes, NULL) != 0))
|
||||||
|
ret = false;
|
||||||
|
if (!ShowProgress(pos + (bytes_read / 2), osize, orig))
|
||||||
|
ret = false;
|
||||||
|
if ((!vdest && (f_write(&dfile, MAIN_BUFFER, read_bytes, &bytes_written) != FR_OK)) ||
|
||||||
|
(vdest && WriteVirtualFile(&dvfile, MAIN_BUFFER, offset + pos, read_bytes, NULL) != 0))
|
||||||
|
ret = false;
|
||||||
|
if (bytes_read != bytes_written)
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
ShowProgress(1, 1, orig);
|
||||||
|
|
||||||
|
if (!vdest) f_close(&dfile);
|
||||||
|
if (!vorig) f_close(&ofile);
|
||||||
|
|
||||||
|
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, '/');
|
||||||
|
@ -59,6 +59,9 @@ size_t FileGetSize(const char* path);
|
|||||||
/** Get SHA-256 of file **/
|
/** Get SHA-256 of file **/
|
||||||
bool FileGetSha256(const char* path, u8* sha256);
|
bool FileGetSha256(const char* path, u8* sha256);
|
||||||
|
|
||||||
|
/** Inject file into file @offset **/
|
||||||
|
bool FileInjectFile(const char* dest, const char* orig, u32 offset);
|
||||||
|
|
||||||
/** 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);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "virtual.h"
|
#include "virtual.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
|
||||||
#define VERSION "0.5.4"
|
#define VERSION "0.5.5"
|
||||||
|
|
||||||
#define N_PANES 2
|
#define N_PANES 2
|
||||||
#define IMG_DRV "789I"
|
#define IMG_DRV "789I"
|
||||||
@ -438,6 +438,7 @@ 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);
|
||||||
|
bool injectable = (clipboard->n_entries == 1) && (clipboard->entry[0].type == T_FILE);
|
||||||
char pathstr[32 + 1];
|
char pathstr[32 + 1];
|
||||||
const char* optionstr[4];
|
const char* optionstr[4];
|
||||||
u32 n_opt = 2;
|
u32 n_opt = 2;
|
||||||
@ -445,10 +446,9 @@ u32 GodMode() {
|
|||||||
TruncateString(pathstr, curr_entry->path, 32, 8);
|
TruncateString(pathstr, curr_entry->path, 32, 8);
|
||||||
optionstr[0] = "Show in Hexeditor";
|
optionstr[0] = "Show in Hexeditor";
|
||||||
optionstr[1] = "Calculate SHA-256";
|
optionstr[1] = "Calculate SHA-256";
|
||||||
if (file_type && (PathToNumFS(curr_entry->path) == 0)) {
|
if (injectable) optionstr[n_opt++] = "Inject data @offset";
|
||||||
optionstr[2] = (file_type == IMG_NAND) ? "Mount as NAND image" : "Mount as FAT image";
|
if (file_type && (PathToNumFS(curr_entry->path) == 0))
|
||||||
n_opt = 3;
|
optionstr[n_opt++] = (file_type == IMG_NAND) ? "Mount as NAND image" : "Mount as FAT image";
|
||||||
}
|
|
||||||
|
|
||||||
u32 user_select = ShowSelectPrompt(n_opt, optionstr, pathstr);
|
u32 user_select = ShowSelectPrompt(n_opt, optionstr, pathstr);
|
||||||
if (user_select == 1) { // -> show in hex viewer
|
if (user_select == 1) { // -> show in hex viewer
|
||||||
@ -485,7 +485,7 @@ u32 GodMode() {
|
|||||||
strncpy(pathstr_prev, pathstr, 32 + 1);
|
strncpy(pathstr_prev, pathstr, 32 + 1);
|
||||||
memcpy(sha256_prev, sha256, 32);
|
memcpy(sha256_prev, sha256, 32);
|
||||||
}
|
}
|
||||||
} else if (user_select == 3) { // -> mount as image
|
} else if ((!injectable && (user_select == 3)) || (user_select == 4)) { // -> mount as image
|
||||||
DeinitExtFS();
|
DeinitExtFS();
|
||||||
u32 mount_state = MountImage(curr_entry->path);
|
u32 mount_state = MountImage(curr_entry->path);
|
||||||
InitExtFS();
|
InitExtFS();
|
||||||
@ -501,6 +501,13 @@ 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 (injectable && (user_select == 3)) { // -> inject data from clipboard
|
||||||
|
char origstr[24 + 1];
|
||||||
|
TruncateString(origstr, clipboard->entry[0].name, 24, 8);
|
||||||
|
u64 offset = ShowHexPrompt(0, 8, "Inject data from %s?\nSpecifiy offset below.", origstr);
|
||||||
|
if ((offset != (u64) -1) && !FileInjectFile(curr_entry->path, clipboard->entry[0].path, (u32) offset))
|
||||||
|
ShowPrompt(false, "Failed injecting %s", origstr);
|
||||||
|
clipboard->n_entries = 0;
|
||||||
}
|
}
|
||||||
} 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)))) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user