diff --git a/source/fs/fsutil.c b/source/fs/fsutil.c index f498c32..0486b53 100644 --- a/source/fs/fsutil.c +++ b/source/fs/fsutil.c @@ -11,8 +11,8 @@ #include "ff.h" #include "ui.h" -#define SKIP_CUR (1UL<<4) -#define OVERWRITE_CUR (1UL<<5) +#define SKIP_CUR (1UL<<6) +#define OVERWRITE_CUR (1UL<<7) // Volume2Partition resolution table PARTITION VolToPart[] = { @@ -686,6 +686,7 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) { int ddrvtype = DriveType(destdir); int odrvtype = DriveType(orig); if (!(ddrvtype & DRV_VIRTUAL)) { // FAT / virtual to FAT + if (flags && (*flags & BUILD_PATH)) DirBuilder(destdir); char fdpath[256]; // 256 is the maximum length of a full path char fopath[256]; strncpy(fdpath, destdir, 255); @@ -713,6 +714,7 @@ bool PathMove(const char* destdir, const char* orig, u32* flags) { ShowPrompt(false, "Error: Moving is not possible here"); return false; } else { + if (flags && (*flags & BUILD_PATH)) DirBuilder(destdir); char fdpath[256]; // 256 is the maximum length of a full path char fopath[256]; strncpy(fdpath, destdir, 255); @@ -775,6 +777,27 @@ bool PathRename(const char* path, const char* newname) { return (f_rename(path, npath) == FR_OK); } +bool DirBuilderWorker(char* dest) { + DIR tmp_dir; + if (fa_opendir(&tmp_dir, dest) != FR_OK) { + char* slash = strrchr(dest, '/'); + if (!slash) return false; + *slash = '\0'; + if (!DirBuilderWorker(dest)) return false; + *slash = '/'; + return (fa_mkdir(dest) == FR_OK); + } else { + f_closedir(&tmp_dir); + return true; + } +} + +bool DirBuilder(const char* destdir) { + char fdpath[256]; // 256 is the maximum length of a full path + strncpy(fdpath, destdir, 255); + return DirBuilderWorker(destdir); +} + bool DirCreate(const char* cpath, const char* dirname) { char npath[256]; // 256 is the maximum length of a full path if (!CheckWritePermissions(cpath)) return false; diff --git a/source/fs/fsutil.h b/source/fs/fsutil.h index 7c94b60..687cd3b 100644 --- a/source/fs/fsutil.h +++ b/source/fs/fsutil.h @@ -8,9 +8,11 @@ // move / copy flags #define OVERRIDE_PERM (1UL<<0) -#define ASK_ALL (1UL<<1) -#define SKIP_ALL (1UL<<2) -#define OVERWRITE_ALL (1UL<<3) +#define CALC_SHA (1UL<<1) +#define BUILD_PATH (1UL<<2) +#define ASK_ALL (1UL<<3) +#define SKIP_ALL (1UL<<4) +#define OVERWRITE_ALL (1UL<<5) /** Return total size of SD card **/ uint64_t GetSDCardSize(); @@ -54,6 +56,9 @@ bool PathDelete(const char* path); /** Rename file / folder in path to new name **/ bool PathRename(const char* path, const char* newname); +/** Recursively build a directory **/ +bool DirBuilder(const char* destdir); + /** Create a new directory in cpath **/ bool DirCreate(const char* cpath, const char* dirname); diff --git a/source/game/gameutil.c b/source/game/gameutil.c index 2d60ab0..6b3daa4 100644 --- a/source/game/gameutil.c +++ b/source/game/gameutil.c @@ -1006,6 +1006,7 @@ u32 CryptGameFile(const char* path, bool inplace, bool encrypt) { if (!inplace) { // ensure the output dir exists + // warning: this will only build output dirs in the root dir (!!!) if ((f_stat(OUTPUT_PATH, NULL) != FR_OK) && (f_mkdir(OUTPUT_PATH) != FR_OK)) return 1; } @@ -1334,6 +1335,7 @@ u32 BuildCiaFromGameFile(const char* path, bool force_legit) { f_unlink(dest); // remove the file if it already exists // ensure the output dir exists + // warning: this will only build output dirs in the root dir (!!!) if ((f_stat(OUTPUT_PATH, NULL) != FR_OK) && (f_mkdir(OUTPUT_PATH) != FR_OK)) return 1; @@ -1358,6 +1360,9 @@ u32 BuildNcchInfoXorpads(const char* destdir, const char* path) { UINT bt; if (!CheckWritePermissions(destdir)) return 1; + // warning: this will only build output dirs in the root dir (!!!) + if ((f_stat(destdir, NULL) != FR_OK) && (f_mkdir(destdir) != FR_OK)) + return 1; NcchInfoHeader info; u32 version = 0; diff --git a/source/godmode.c b/source/godmode.c index 0de65dd..bdd3f96 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -720,7 +720,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur } return FileHandlerMenu(current_path, cursor, scroll, current_dir, clipboard); } else if (user_select == copystd) { // -> copy to OUTPUT_PATH - u32 flags = 0; + u32 flags = BUILD_PATH; if ((n_marked > 1) && ShowPrompt(true, "Copy all %lu selected files?", n_marked)) { u32 n_success = 0; for (u32 i = 0; i < current_dir->n_entries; i++) {