Better handling for locked files

This commit is contained in:
d0k3 2016-12-13 17:10:39 +01:00
parent 3b60fe2332
commit 1f98f88d87
4 changed files with 34 additions and 15 deletions

View File

@ -38,7 +38,7 @@ bool InitExtFS() {
bool InitImgFS(const char* path) { bool InitImgFS(const char* path) {
// deinit image filesystem // deinit image filesystem
for (u32 i = NORM_FS - 1; i >= NORM_FS - IMGN_FS; i--) { for (u32 i = (GetMountState() == IMG_NAND) ? NORM_FS - 1 : NORM_FS - IMGN_FS; i >= NORM_FS - IMGN_FS; i--) {
char fsname[8]; char fsname[8];
snprintf(fsname, 7, "%lu:", i); snprintf(fsname, 7, "%lu:", i);
if (!fs_mounted[i]) continue; if (!fs_mounted[i]) continue;
@ -53,6 +53,7 @@ bool InitImgFS(const char* path) {
for (u32 i = NORM_FS - IMGN_FS; i < NORM_FS; i++) { for (u32 i = NORM_FS - IMGN_FS; i < NORM_FS; i++) {
char fsname[8]; char fsname[8];
snprintf(fsname, 7, "%lu:", i); snprintf(fsname, 7, "%lu:", i);
if (fs_mounted[i]) continue;
fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK);
} }
return true; return true;

View File

@ -4,6 +4,7 @@
#include "fsperm.h" #include "fsperm.h"
#include "sddata.h" #include "sddata.h"
#include "virtual.h" #include "virtual.h"
#include "image.h"
#include "sha.h" #include "sha.h"
#include "sdmmc.h" #include "sdmmc.h"
#include "ff.h" #include "ff.h"
@ -75,13 +76,21 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size) {
return ret; return ret;
} }
bool FileCheck(const char* path) { bool FileUnlock(const char* path) {
FIL file; FIL file;
if (!(DriveType(path) & DRV_FAT)) return true; // can't really check this if (!(DriveType(path) & DRV_FAT)) return true; // can't really check this
if (fx_open(&file, path, FA_READ | FA_OPEN_EXISTING) == FR_OK) { if (fx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) {
fx_close(&file); char pathstr[32 + 1];
return true; TruncateString(pathstr, path, 32, 8);
} else return false; if (GetMountState() && (strncmp(path, GetMountPath(), 256) == 0) &&
(ShowPrompt(true, "%s\nFile is currently mounted.\nUnmount to unlock?", pathstr))) {
InitImgFS(NULL);
if (fx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return false;
} else return false;
}
fx_close(&file);
return true;
} }
bool FileSetData(const char* path, const u8* data, size_t size, size_t foffset, bool create) { bool FileSetData(const char* path, const u8* data, size_t size, size_t foffset, bool create) {
@ -285,7 +294,8 @@ bool FileInjectFile(const char* dest, const char* orig, u32 offset) {
osize = ovfile.size; osize = ovfile.size;
} else { } else {
vorig = false; vorig = false;
if (fx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK) { if ((fx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK) &&
(!FileUnlock(orig) || (fx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK))) {
if (!vdest) fx_close(&dfile); if (!vdest) fx_close(&dfile);
return false; return false;
} }
@ -419,8 +429,10 @@ bool PathCopyFatToVrt(const char* destdir, const char* orig) {
} }
// FAT file // FAT file
if (fx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK) if ((fx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK) &&
(!FileUnlock(orig) || (fx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK))) {
return false; return false;
}
f_lseek(&ofile, 0); f_lseek(&ofile, 0);
f_sync(&ofile); f_sync(&ofile);
@ -676,8 +688,12 @@ bool PathCopyWorker(char* dest, char* orig, u32* flags, bool move) {
FIL dfile; FIL dfile;
size_t fsize; size_t fsize;
if (fx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK) if (fx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK) {
return false; if (!FileUnlock(orig) || (fx_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK))
return false;
ShowProgress(0, 0, orig); // reinit progress bar
}
fsize = f_size(&ofile); fsize = f_size(&ofile);
if (GetFreeSpace(dest) < fsize) { if (GetFreeSpace(dest) < fsize) {
ShowPrompt(false, "Error: File is too big for destination"); ShowPrompt(false, "Error: File is too big for destination");

View File

@ -17,8 +17,8 @@ uint64_t GetSDCardSize();
/** Format the SD card **/ /** Format the SD card **/
bool FormatSDCard(u64 hidden_mb, u32 cluster_size); bool FormatSDCard(u64 hidden_mb, u32 cluster_size);
/** True if file exists and is not locked, false otherwise **/ /** Check for file lock, offer to unlock if possible **/
bool FileCheck(const char* path); bool FileUnlock(const char* path);
/** Create / open file and write the provided data to it **/ /** Create / open file and write the provided data to it **/
bool FileSetData(const char* path, const u8* data, size_t size, size_t foffset, bool create); bool FileSetData(const char* path, const u8* data, size_t size, size_t foffset, bool create);

View File

@ -573,7 +573,9 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
char pathstr[32 + 1]; char pathstr[32 + 1];
TruncateString(pathstr, curr_entry->path, 32, 8); TruncateString(pathstr, curr_entry->path, 32, 8);
if (!FileCheck(curr_entry->path)) ShowPrompt(false, "%s\nFile is currently locked", pathstr);
// check for file lock
if (!FileUnlock(curr_entry->path)) return 1;
// main menu processing // main menu processing
int n_opt = 0; int n_opt = 0;
@ -891,7 +893,7 @@ u32 GodMode() {
if (InitSDCardFS()) break; if (InitSDCardFS()) break;
ShowString("Reinitialising SD card failed!\n \n<R+Y+\x1B> for format menu\n<A> to retry, <B> to reboot"); ShowString("Reinitialising SD card failed!\n \n<R+Y+\x1B> for format menu\n<A> to retry, <B> to reboot");
} }
ClearScreenF(true, false, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);
InitEmuNandBase(); InitEmuNandBase();
InitExtFS(); InitExtFS();
GetDirContents(current_dir, current_path); GetDirContents(current_dir, current_path);
@ -1093,7 +1095,7 @@ u32 GodMode() {
if (!ShowPrompt(true, "Reinitialising SD card failed! Retry?")) if (!ShowPrompt(true, "Reinitialising SD card failed! Retry?"))
return exit_mode; return exit_mode;
} }
ClearScreenF(true, false, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);
InitEmuNandBase(); InitEmuNandBase();
InitExtFS(); InitExtFS();
GetDirContents(current_dir, current_path); GetDirContents(current_dir, current_path);