Working file copying routines

This commit is contained in:
d0k3 2016-03-02 17:22:44 +01:00
parent 2a53ee0a5b
commit df82754a6a
4 changed files with 54 additions and 37 deletions

View File

@ -264,22 +264,31 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
return (lvl >= len);
}
void ShowProgress(u64 current, u64 total, const char* opstr, bool clearscreen)
bool ShowProgress(u64 current, u64 total, const char* opstr)
{
static u32 last_prog_width = 0;
const u32 bar_width = 240;
const u32 bar_height = 12;
const u32 bar_pos_x = (SCREEN_WIDTH_TOP - bar_width) / 2;
const u32 bar_pos_y = (SCREEN_HEIGHT / 2) - bar_height - 2;
const u32 text_pos_y = (SCREEN_HEIGHT / 2);
const u32 bar_pos_y = (SCREEN_HEIGHT / 2) - bar_height - 2 - 10;
const u32 text_pos_y = bar_pos_y + bar_height + 2;
u32 prog_width = ((total > 0) && (current <= total)) ? (current * (bar_width-4)) / total : 0;
char tempstr[64];
if (clearscreen) ClearScreenF(true, false, COLOR_STD_BG);
DrawRectangleF(true, bar_pos_x, bar_pos_y, bar_width, bar_height, COLOR_DARKGREY);
DrawRectangleF(true, bar_pos_x + 1, bar_pos_y + 1, bar_width - 2, bar_height - 2, COLOR_STD_BG);
if (!current || last_prog_width > prog_width) {
ClearScreenF(true, false, COLOR_STD_BG);
DrawRectangleF(true, bar_pos_x, bar_pos_y, bar_width, bar_height, COLOR_STD_FONT);
DrawRectangleF(true, bar_pos_x + 1, bar_pos_y + 1, bar_width - 2, bar_height - 2, COLOR_STD_BG);
}
DrawRectangleF(true, bar_pos_x + 2, bar_pos_y + 2, prog_width, bar_height - 4, COLOR_STD_FONT);
ResizeString(tempstr, opstr, 28, 8, false);
DrawString(TOP_SCREEN0, tempstr, bar_pos_x, text_pos_y, COLOR_STD_FONT, COLOR_STD_BG);
DrawString(TOP_SCREEN1, tempstr, bar_pos_x, text_pos_y, COLOR_STD_FONT, COLOR_STD_BG);
DrawString(TOP_SCREEN0, "(hold B to cancel)", bar_pos_x + 2, text_pos_y + 14, COLOR_STD_FONT, COLOR_STD_BG);
DrawString(TOP_SCREEN1, "(hold B to cancel)", bar_pos_x + 2, text_pos_y + 14, COLOR_STD_FONT, COLOR_STD_BG);
last_prog_width = prog_width;
return !(~HID_STATE & BUTTON_B);
}

View File

@ -70,4 +70,4 @@ void FormatBytes(char* str, u64 bytes);
bool ShowPrompt(bool ask, const char *format, ...);
bool ShowUnlockSequence(u32 seqlvl, const char *format, ...);
void ShowProgress(u64 current, u64 total, const char* opstr, bool clearscreen);
bool ShowProgress(u64 current, u64 total, const char* opstr);

View File

@ -8,7 +8,7 @@ static FATFS* fs = (FATFS*)0x20316000;
// this is the main buffer
static u8* main_buffer = (u8*)0x21100000;
// this is the main buffer size
static size_t main_buffer_size = 128 * 1024;
static size_t main_buffer_size = 1 * 1024 * 1024;
// write permission level - careful with this
static u32 write_permission_level = 1;
@ -24,7 +24,7 @@ bool InitFS() {
#endif
for (numfs = 0; numfs < 7; numfs++) {
char fsname[8];
snprintf(fsname, 8, "%lu:", numfs);
snprintf(fsname, 7, "%lu:", numfs);
int res = f_mount(fs + numfs, fsname, 1);
if (res != FR_OK) {
if (numfs >= 4) break;
@ -115,35 +115,43 @@ bool FileCreate(const char* path, u8* data, u32 size) {
}
bool PathCopyWorker(char* dest, char* orig) {
FILINFO fno;
FILINFO fno = {.lfname = NULL};
bool ret = false;
if (f_stat(dest, &fno) != FR_OK) return false; // destination directory does not exist
if (!(fno.fattrib & AM_DIR)) return false; // destination is not a directory (must be at this point)
if (f_stat(orig, &fno) != FR_OK) return false; // origin does not exist
// get filename, build full destination path
// build full destination path (on top of destination directory)
char* oname = strrchr(orig, '/');
char* dname = dest + strnlen(dest, 256);
char* dname = dest + strnlen(dest, 255);
if (oname == NULL) return false; // not a proper origin path
oname++;
*(dname++) = '/';
strncpy(dname, oname, 256 - (dname - dest));
// check if destination is part of or equal origin
if (strncmp(dest, orig, strnlen(orig, 255)) == 0) {
if ((dest[strnlen(orig, 255)] == '/') || (dest[strnlen(orig, 255)] == '\0'))
return false;
}
// check if destination exists
if (f_stat(dest, NULL) == FR_OK) {
char tempstr[40];
TruncateString(tempstr, dest, 36, 8);
if (!ShowPrompt(true, "Destination already exists:\n%s\nOverwrite existing file(s)?"))
char namestr[40];
TruncateString(namestr, dest, 36, 8);
if (!ShowPrompt(true, "Destination already exists:\n%s\nOverwrite existing file(s)?", namestr))
return false;
}
// the copy process takes place here
ShowProgress(0, 0, orig, true);
if (!ShowProgress(0, 0, orig)) return false;
if (fno.fattrib & AM_DIR) { // processing folders...
DIR pdir;
char* fname = orig + strnlen(orig, 256);
// create the destination folder if it does not already exist
if ((f_stat(dest, NULL) != FR_OK) && (f_mkdir(dest) != FR_OK))
return false;
@ -153,9 +161,7 @@ bool PathCopyWorker(char* dest, char* orig) {
fno.lfname = fname;
fno.lfsize = 256 - (fname - orig);
ShowPrompt(false, "Made:\n%s\n%s", orig, dest);
while (f_readdir(&pdir, &fno) == FR_OK) {
ShowPrompt(false, "Trying:\n%s\n%s", orig, dest);
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
continue; // filter out virtual entries
if (fname[0] == 0)
@ -164,7 +170,6 @@ bool PathCopyWorker(char* dest, char* orig) {
ret = true;
break;
} else if (!PathCopyWorker(dest, orig)) {
ShowPrompt(false, "Failed:\n%s\n%s", orig, dest);
break;
}
}
@ -190,20 +195,24 @@ bool PathCopyWorker(char* dest, char* orig) {
for (size_t pos = 0; pos < fsize; pos += main_buffer_size) {
UINT bytes_read = 0;
UINT bytes_written = 0;
ShowProgress(pos, fsize, orig, false);
f_read(&ofile, main_buffer, main_buffer_size, &bytes_read);
if (!ShowProgress(pos + (bytes_read / 2), fsize, orig)) {
ret = false;
break;
}
f_write(&dfile, main_buffer, bytes_read, &bytes_written);
if (bytes_read != bytes_written) {
ret = false;
break;
}
}
ShowProgress(1, 1, orig, false);
ShowProgress(1, 1, orig);
f_close(&ofile);
f_close(&dfile);
}
*(--dname) = '\0';
return ret;
}
@ -211,13 +220,13 @@ bool PathCopy(const char* destdir, const char* orig) {
char fdpath[256]; // 256 is the maximum length of a full path
char fopath[256];
if (!CheckWritePermissions(destdir)) return false;
strncpy(fdpath, destdir, 256);
strncpy(fopath, orig, 256);
strncpy(fdpath, destdir, 255);
strncpy(fopath, orig, 255);
return PathCopyWorker(fdpath, fopath);
}
bool PathDeleteWorker(char* fpath) {
FILINFO fno;
FILINFO fno = {.lfname = NULL};
// this code handles directory content deletion
if (f_stat(fpath, &fno) != FR_OK) return false; // fpath does not exist

View File

@ -85,6 +85,8 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
void DrawDirContents(DirStruct* contents, u32 cursor) {
static u32 offset_disp = 0;
const int str_width = 39;
const u32 bar_height_min = 32;
const u32 bar_width = 2;
const u32 start_y = 2;
const u32 stp_y = 12;
const u32 pos_x = 0;
@ -114,9 +116,6 @@ void DrawDirContents(DirStruct* contents, u32 cursor) {
}
if (contents->n_entries > lines) { // draw position bar at the right
const u32 bar_height_min = 32;
const u32 bar_width = 2;
u32 bar_height = (lines * SCREEN_HEIGHT) / contents->n_entries;
if (bar_height < bar_height_min) bar_height = bar_height_min;
u32 bar_pos = ((u64) offset_disp * (SCREEN_HEIGHT - bar_height)) / (contents->n_entries - lines);
@ -124,7 +123,7 @@ void DrawDirContents(DirStruct* contents, u32 cursor) {
DrawRectangleF(false, SCREEN_WIDTH_BOT - bar_width, 0, bar_width, bar_pos, COLOR_STD_BG);
DrawRectangleF(false, SCREEN_WIDTH_BOT - bar_width, bar_pos + bar_height, bar_width, SCREEN_WIDTH_BOT - (bar_pos + bar_height), COLOR_STD_BG);
DrawRectangleF(false, SCREEN_WIDTH_BOT - bar_width, bar_pos, bar_width, bar_height, COLOR_SIDE_BAR);
}
} else DrawRectangleF(false, SCREEN_WIDTH_BOT - bar_width, 0, bar_width, SCREEN_HEIGHT, COLOR_STD_BG);
}
u32 GodMode() {
@ -217,10 +216,10 @@ u32 GodMode() {
if (n_errors) ShowPrompt(false, "Failed deleting %u/%u path(s)", n_errors, n_marked);
}
} else {
char namestr[20+1];
TruncateString(namestr, current_dir->entry[cursor].name, 20, 12);
char namestr[36+1];
TruncateString(namestr, current_dir->entry[cursor].name, 36, 12);
if ((ShowPrompt(true, "Delete \"%s\"?", namestr)) && !PathDelete(current_dir->entry[cursor].path))
ShowPrompt(false, "Failed deleting \"%s\"", namestr);
ShowPrompt(false, "Failed deleting:\n%s", namestr);
}
GetDirContents(current_dir, current_path);
if (cursor >= current_dir->n_entries)
@ -248,11 +247,11 @@ u32 GodMode() {
if (ShowPrompt(true, promptstr)) {
for (u32 c = 0; c < clipboard->n_entries; c++) {
if (!PathCopy(current_path, clipboard->entry[c].path)) {
char namestr[20+1];
TruncateString(namestr, clipboard->entry[c].name, 20, 12);
char namestr[36+1];
TruncateString(namestr, clipboard->entry[c].name, 36, 12);
if (c + 1 < clipboard->n_entries) {
if (!ShowPrompt(true, "Failed copying \"%s\"\nContinue?", namestr)) break;
} else ShowPrompt(false, "Failed copying \"%s\"\n", namestr);
if (!ShowPrompt(true, "Failed copying path:\n%s\nProcess remaining?", namestr)) break;
} else ShowPrompt(false, "Failed copying path:\n%s", namestr);
}
}
}