forked from Mirror/GodMode9
Scripting: 'fill' and 'fdummy' commands
This commit is contained in:
parent
c7d60879ae
commit
93f966e1da
@ -198,6 +198,23 @@ set ERRORMSG "SHA check failed (this was expected)"
|
||||
sha -o $[RENPATH] $[TESTPATH].sha
|
||||
set ERRORMSG ""
|
||||
|
||||
# 'fdummy' COMMAND
|
||||
# This command creates a dummy file of the specified size (size in hex)
|
||||
# Contents of the dummy file are undefined and existing files won't be overwritten
|
||||
set DUMMY 0:/testdir/dummy.bin
|
||||
fdummy $[DUMMY] 400
|
||||
|
||||
# 'fill' COMMAND
|
||||
# This command fills (a portition of) a file with the specified byte value
|
||||
# The syntax is: fill destination@x:y fillbyte
|
||||
# x: destination offset (in hex)
|
||||
# y: destination size, starting at x (in hex)
|
||||
# If x is not given, the full file size, starting from offset 0, is overwritten
|
||||
# If y is not given, everything starting from offset x is overwritten
|
||||
# -n / --no_cancel prevents user cancels (useful on critical operations)
|
||||
fill $[DUMMY]@100:100 FF
|
||||
fill $[DUMMY]@300 80
|
||||
|
||||
# 'fixcmac' COMMAND
|
||||
# Use this to fix the CMACs for a file or a whole folder (recursively)
|
||||
# This will count as success if a file does not contain a CMAC
|
||||
|
@ -270,10 +270,55 @@ bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_or
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool FileSetByte(const char* dest, u64 offset, u64 size, u8 fillbyte, u32* flags) {
|
||||
FIL dfile;
|
||||
bool allow_expand = (flags && (*flags & ALLOW_EXPAND));
|
||||
|
||||
if (!CheckWritePermissions(dest)) return false;
|
||||
|
||||
// open destination
|
||||
if (fvx_open(&dfile, dest, FA_WRITE | ((allow_expand) ? FA_OPEN_ALWAYS : FA_OPEN_EXISTING)) != FR_OK)
|
||||
return false;
|
||||
fvx_lseek(&dfile, offset);
|
||||
if (!size && (offset < fvx_size(&dfile)))
|
||||
size = fvx_size(&dfile) - offset;
|
||||
|
||||
// check file limits
|
||||
if (!allow_expand && (offset + size > fvx_size(&dfile))) {
|
||||
ShowPrompt(false, "Operation would write beyond end of file");
|
||||
fvx_close(&dfile);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = true;
|
||||
memset(MAIN_BUFFER, fillbyte, size);
|
||||
ShowProgress(0, 0, dest);
|
||||
for (u64 pos = 0; (pos < size) && ret; pos += MAIN_BUFFER_SIZE) {
|
||||
UINT write_bytes = min(MAIN_BUFFER_SIZE, size - pos);
|
||||
UINT bytes_written = write_bytes;
|
||||
if ((fvx_write(&dfile, MAIN_BUFFER, write_bytes, &bytes_written) != FR_OK) ||
|
||||
(write_bytes != bytes_written))
|
||||
ret = false;
|
||||
if (ret && !ShowProgress(pos + bytes_written, size, dest)) {
|
||||
if (flags && (*flags & NO_CANCEL)) {
|
||||
ShowPrompt(false, "Cancel is not allowed here");
|
||||
} else ret = !ShowPrompt(true, "B button detected. Cancel?");
|
||||
ShowProgress(0, 0, dest);
|
||||
ShowProgress(pos + bytes_written, size, dest);
|
||||
}
|
||||
}
|
||||
ShowProgress(1, 1, dest);
|
||||
|
||||
fvx_close(&dfile);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool FileCreateDummy(const char* cpath, const char* filename, u64 size) {
|
||||
char npath[256]; // 256 is the maximum length of a full path
|
||||
if (!CheckWritePermissions(cpath)) return false;
|
||||
snprintf(npath, 255, "%s/%s", cpath, filename);
|
||||
if (filename) snprintf(npath, 255, "%s/%s", cpath, filename);
|
||||
else snprintf(npath, 255, "%s", cpath);
|
||||
|
||||
// create dummy file (fail if already existing)
|
||||
// then, expand the file size via cluster preallocation
|
||||
|
@ -43,6 +43,9 @@ u32 FileFindData(const char* path, u8* data, u32 size_data, u32 offset_file);
|
||||
/** Inject file into file @offset **/
|
||||
bool FileInjectFile(const char* dest, const char* orig, u64 off_dest, u64 off_orig, u64 size, u32* flags);
|
||||
|
||||
/** Fill (a portion of) a file with a fillbyte **/
|
||||
bool FileSetByte(const char* dest, u64 offset, u64 size, u8 fillbyte, u32* flags);
|
||||
|
||||
/** Create a dummy file at dest **/
|
||||
bool FileCreateDummy(const char* cpath, const char* filename, u64 size);
|
||||
|
||||
|
@ -78,6 +78,8 @@ typedef enum {
|
||||
CMD_ID_CP,
|
||||
CMD_ID_MV,
|
||||
CMD_ID_INJECT,
|
||||
CMD_ID_FILL,
|
||||
CMD_ID_FDUMMY,
|
||||
CMD_ID_RM,
|
||||
CMD_ID_MKDIR,
|
||||
CMD_ID_MOUNT,
|
||||
@ -133,6 +135,8 @@ Gm9ScriptCmd cmd_list[] = {
|
||||
{ CMD_ID_CP , "cp" , 2, _FLG('h') | _FLG('w') | _FLG('k') | _FLG('s') | _FLG('n')},
|
||||
{ CMD_ID_MV , "mv" , 2, _FLG('w') | _FLG('k') | _FLG('s') | _FLG('n') },
|
||||
{ CMD_ID_INJECT , "inject" , 2, _FLG('n') },
|
||||
{ CMD_ID_FILL , "fill" , 2, 0 },
|
||||
{ CMD_ID_FDUMMY , "fdummy" , 2, 0 },
|
||||
{ CMD_ID_RM , "rm" , 1, 0 },
|
||||
{ CMD_ID_MKDIR , "mkdir" , 1, 0 },
|
||||
{ CMD_ID_MOUNT , "imgmount", 1, 0 },
|
||||
@ -661,7 +665,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
|
||||
// process arg0 @string
|
||||
u64 at_org = 0;
|
||||
u64 sz_org = 0;
|
||||
if ((id == CMD_ID_SHA) || (id == CMD_ID_SHAGET) || (id == CMD_ID_INJECT)) {
|
||||
if ((id == CMD_ID_SHA) || (id == CMD_ID_SHAGET) || (id == CMD_ID_INJECT) || (id == CMD_ID_FILL)) {
|
||||
char* atstr_org = strrchr(argv[0], '@');
|
||||
if (atstr_org) {
|
||||
*(atstr_org++) = '\0';
|
||||
@ -910,6 +914,28 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
|
||||
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_FILL) {
|
||||
u32 flags_ext = ALLOW_EXPAND;
|
||||
u8 fillbyte = 0;
|
||||
if ((strnlen(argv[1], _ARG_MAX_LEN) != 2) || !strntohex(argv[1], &fillbyte, 1)) {
|
||||
ret = false;
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "fillbyte fail");
|
||||
} else {
|
||||
if (flags & _FLG('n')) flags_ext |= NO_CANCEL;
|
||||
ret = FileSetByte(argv[0], at_org, sz_org, fillbyte, &flags_ext);
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "fill fail");
|
||||
}
|
||||
}
|
||||
else if (id == CMD_ID_FDUMMY) {
|
||||
u32 fsize;
|
||||
if (sscanf(argv[1], "%lX", &fsize) != 1) {
|
||||
ret = false;
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "bad filesize");
|
||||
} else {
|
||||
ret = FileCreateDummy(argv[0], NULL, fsize);
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "create dummy fail");
|
||||
}
|
||||
}
|
||||
else if (id == CMD_ID_RM) {
|
||||
char pathstr[_ERR_STR_LEN];
|
||||
TruncateString(pathstr, argv[0], 24, 8);
|
||||
|
Loading…
x
Reference in New Issue
Block a user