From 0ccce0cb3284f7c2ce73beb658e47d6845a3f4e6 Mon Sep 17 00:00:00 2001 From: d0k3 Date: Wed, 23 Aug 2017 01:24:55 +0200 Subject: [PATCH] Scripting: Allow inject command to expand or create files fixes #177 --- HelloScript.gm9 | 3 +++ source/filesys/fsscript.c | 18 ++++++++---------- source/filesys/fsutil.c | 9 +++++---- source/filesys/fsutil.h | 7 ++++--- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/HelloScript.gm9 b/HelloScript.gm9 index 77d939c..9c33af1 100644 --- a/HelloScript.gm9 +++ b/HelloScript.gm9 @@ -121,6 +121,9 @@ sha $[RENPATH] $[TESTPATH].sha # x: origin offset (in hex) # y: origin size, starting at x (in hex) # z: destination offset (in hex) +# If destination does not exist or z is not given, a new destination file will be created(!) +# If x is not given, the full origin file size is used to inject +# If y is not given, everything starting from x is used to inject # -n / --no_cancel prevents user cancels (useful on critical operations) inject S:/nand_hdr.bin@100:4 $[RENPATH]@200 # offsets and sizes are in hex # As we just deliberately corrupted our test file, the subsequent SHA check will fail diff --git a/source/filesys/fsscript.c b/source/filesys/fsscript.c index 209a046..99a9450 100644 --- a/source/filesys/fsscript.c +++ b/source/filesys/fsscript.c @@ -394,17 +394,15 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) { sz_org = 0; } } - if (!atstr_dst) { - ret = false; - if (err_str) snprintf(err_str, _ERR_STR_LEN, "missing dest offset"); - } else { - u32 flags_ext = 0; - u64 at_dst = 0; + u64 at_dst = 0; + if (atstr_dst) { *(atstr_dst++) = '\0'; - if (flags & _FLG('n')) flags_ext |= NO_CANCEL; - ret = ((sscanf(atstr_dst, "%llX", &at_dst) == 1) && FileInjectFile(argv[1], argv[0], at_dst, at_org, sz_org, &flags_ext)); - if (err_str) snprintf(err_str, _ERR_STR_LEN, "inject fail"); - } + if (sscanf(atstr_dst, "%llX", &at_dst) != 1) at_dst = 0; + } else fvx_unlink(argv[1]); // force new file when no offset is given + u32 flags_ext = ALLOW_EXPAND; + if (flags & _FLG('n')) flags_ext |= NO_CANCEL; + ret = FileInjectFile(argv[1], argv[0], at_dst, at_org, sz_org, &flags_ext); + if (err_str) snprintf(err_str, _ERR_STR_LEN, "inject fail"); } else if (id == CMD_ID_RM) { char pathstr[_ERR_STR_LEN]; TruncateString(pathstr, argv[0], 24, 8); diff --git a/source/filesys/fsutil.c b/source/filesys/fsutil.c index 6ae68f4..5f202bc 100644 --- a/source/filesys/fsutil.c +++ b/source/filesys/fsutil.c @@ -11,8 +11,8 @@ #include "ff.h" #include "ui.h" -#define SKIP_CUR (1UL<<8) -#define OVERWRITE_CUR (1UL<<9) +#define SKIP_CUR (1UL<< 9) +#define OVERWRITE_CUR (1UL<<10) #define _MAX_FS_OPT 8 // max file selector options @@ -204,6 +204,7 @@ u32 FileFindData(const char* path, u8* data, u32 size_data, u32 offset_file) { bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_orig, u64 size, u32* flags) { FIL ofile; FIL dfile; + bool allow_expand = (flags && (*flags & ALLOW_EXPAND)); if (!CheckWritePermissions(dest)) return false; if (strncmp(dest, orig, 256) == 0) { @@ -212,7 +213,7 @@ bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_or } // open destination / origin - if (fvx_open(&dfile, dest, FA_WRITE | FA_OPEN_EXISTING) != FR_OK) + if (fvx_open(&dfile, dest, FA_WRITE | ((allow_expand) ? FA_OPEN_ALWAYS : FA_OPEN_EXISTING)) != FR_OK) return false; if ((fvx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK) && (!FileUnlock(orig) || (fvx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK))) { @@ -225,7 +226,7 @@ bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_or size = fvx_size(&ofile) - off_orig; // check file limits - if (off_dest + size > fvx_size(&dfile)) { + if (!allow_expand && (off_dest + size > fvx_size(&dfile))) { ShowPrompt(false, "Operation would write beyond end of file"); fvx_close(&dfile); fvx_close(&ofile); diff --git a/source/filesys/fsutil.h b/source/filesys/fsutil.h index f6d461f..79aeb34 100644 --- a/source/filesys/fsutil.h +++ b/source/filesys/fsutil.h @@ -8,9 +8,10 @@ #define SILENT (1UL<<2) #define CALC_SHA (1UL<<3) #define BUILD_PATH (1UL<<4) -#define ASK_ALL (1UL<<5) -#define SKIP_ALL (1UL<<6) -#define OVERWRITE_ALL (1UL<<7) +#define ALLOW_EXPAND (1UL<<5) +#define ASK_ALL (1UL<<6) +#define SKIP_ALL (1UL<<7) +#define OVERWRITE_ALL (1UL<<8) /** Return total size of SD card **/ uint64_t GetSDCardSize();