diff --git a/source/fs.c b/source/fs.c index 8d050e1..9a8dadc 100644 --- a/source/fs.c +++ b/source/fs.c @@ -88,24 +88,58 @@ void SetFSSearch(const char* pattern, const char* path) { int PathToNumFS(const char* path) { int fsnum = *path - (int) '0'; if ((fsnum < 0) || (fsnum >= NORM_FS) || (path[1] != ':')) { - if (!GetVirtualSource(path) && + // this check is not required + /* if (!GetVirtualSource(path) && !CheckAliasDrive(path) && !IsSearchDrive(path)) - ShowPrompt(false, "Invalid path (%s)", path); + ShowPrompt(false, "Invalid path (%s)", path); */ return -1; } return fsnum; } -bool IsMountedFS(const char* path) { - int fsnum = PathToNumFS(path); - return ((fsnum >= 0) && (fsnum < NORM_FS)) ? fs_mounted[fsnum] : false; -} - bool IsSearchDrive(const char* path) { return *search_pattern && *search_path && (strncmp(path, "Z:", 3) == 0); } +int DriveType(const char* path) { + int type = DRV_UNKNOWN; + int pdrv = PathToNumFS(path); + + if ((pdrv >= 0) && (pdrv < NORM_FS)) { + if (!fs_mounted[pdrv]) { + type = DRV_UNKNOWN; + } else if (pdrv == 0) { + type = DRV_FAT | DRV_SDCARD | DRV_STDFAT; + } else if ((pdrv == 7) && (GetMountState() == IMG_RAMDRV)) { + type = DRV_FAT | DRV_RAMDRIVE | DRV_STDFAT; + } else if ((pdrv >= 1) && (pdrv <= 3)) { + type = DRV_FAT | DRV_SYSNAND | DRV_STDFAT; + } else if ((pdrv >= 4) && (pdrv <= 6)) { + type = DRV_FAT | DRV_EMUNAND | DRV_STDFAT; + } else if ((pdrv >= 7) && (pdrv <= 9)) { + type = DRV_FAT | DRV_IMAGE | DRV_STDFAT; + } + } else if (CheckVirtualDrive(path)) { + int vsrc = GetVirtualSource(path); + if (vsrc == VRT_SYSNAND) { + type = DRV_VIRTUAL | DRV_SYSNAND; + } else if (vsrc == VRT_EMUNAND) { + type = DRV_VIRTUAL | DRV_EMUNAND; + } else if (vsrc == VRT_IMGNAND) { + type = DRV_VIRTUAL | DRV_IMAGE; + } else if (vsrc == VRT_MEMORY) { + type = DRV_VIRTUAL | DRV_MEMORY; + } + } else if (CheckAliasDrive(path)) { + type = DRV_FAT | DRV_ALIAS; + } else if (IsSearchDrive(path)) { + type = DRV_SEARCH; + } + + return type; +} + uint64_t GetSDCardSize() { if (sdmmc_sdcard_init() != 0) return 0; return (u64) getMMCDevice(1)->total_size * 512; @@ -165,16 +199,16 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size) { bool CheckWritePermissions(const char* path) { char area_name[16]; - int pdrv = PathToNumFS(path); + int drvtype = DriveType(path); u32 perm; - if (pdrv == 0) { + if (drvtype & DRV_SDCARD) { perm = PERM_SDCARD; snprintf(area_name, 16, "the SD card"); - } else if ((pdrv == 7) && (GetMountState() == IMG_RAMDRV)) { + } else if (drvtype & DRV_RAMDRIVE) { perm = PERM_RAMDRIVE; snprintf(area_name, 16, "the RAM drive"); - } else if (((pdrv >= 1) && (pdrv <= 3)) || (GetVirtualSource(path) == VRT_SYSNAND)) { + } else if (drvtype & DRV_SYSNAND) { perm = PERM_SYSNAND; snprintf(area_name, 16, "the SysNAND"); // check virtual file flags (if any) @@ -183,13 +217,13 @@ bool CheckWritePermissions(const char* path) { perm = PERM_A9LH; snprintf(area_name, 16, "A9LH regions"); } - } else if (((pdrv >= 4) && (pdrv <= 6)) || (GetVirtualSource(path) == VRT_EMUNAND)) { + } else if (drvtype & DRV_EMUNAND) { perm = PERM_EMUNAND; snprintf(area_name, 16, "the EmuNAND"); - } else if (((pdrv >= 7) && (pdrv <= 9)) || (GetVirtualSource(path) == VRT_IMGNAND)) { + } else if (drvtype & DRV_IMAGE) { perm = PERM_IMAGE; snprintf(area_name, 16, "images"); - } else if (GetVirtualSource(path) == VRT_MEMORY) { + } else if (drvtype & DRV_MEMORY) { perm = PERM_MEMORY; snprintf(area_name, 16, "memory areas"); } else { @@ -291,8 +325,9 @@ bool GetTempFileName(char* path) { } bool FileSetData(const char* path, const u8* data, size_t size, size_t foffset, bool create) { + int drvtype = DriveType(path); if (!CheckWritePermissions(path)) return false; - if ((PathToNumFS(path) >= 0) || (CheckAliasDrive(path))) { + if (drvtype & DRV_FAT) { UINT bytes_written = 0; FIL file; if (fa_open(&file, path, FA_WRITE | (create ? FA_CREATE_ALWAYS : FA_OPEN_ALWAYS)) != FR_OK) @@ -301,7 +336,7 @@ bool FileSetData(const char* path, const u8* data, size_t size, size_t foffset, f_write(&file, data, size, &bytes_written); f_close(&file); return (bytes_written == size); - } else if (GetVirtualSource(path)) { + } else if (drvtype & DRV_VIRTUAL) { VirtualFile vfile; if (!FindVirtualFile(&vfile, path, 0)) return 0; @@ -310,9 +345,9 @@ bool FileSetData(const char* path, const u8* data, size_t size, size_t foffset, return false; } -size_t FileGetData(const char* path, u8* data, size_t size, size_t foffset) -{ - if ((PathToNumFS(path) >= 0) || (CheckAliasDrive(path))) { +size_t FileGetData(const char* path, u8* data, size_t size, size_t foffset) { + int drvtype = DriveType(path); + if (drvtype & DRV_FAT) { UINT bytes_read = 0; FIL file; if (fa_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) @@ -324,7 +359,7 @@ size_t FileGetData(const char* path, u8* data, size_t size, size_t foffset) } f_close(&file); return bytes_read; - } else if (GetVirtualSource(path)) { + } else if (drvtype & DRV_VIRTUAL) { u32 bytes_read = 0; VirtualFile vfile; if (!FindVirtualFile(&vfile, path, 0)) @@ -335,12 +370,13 @@ size_t FileGetData(const char* path, u8* data, size_t size, size_t foffset) } size_t FileGetSize(const char* path) { - if ((PathToNumFS(path) >= 0) || (CheckAliasDrive(path))) { + int drvtype = DriveType(path); + if (drvtype & DRV_FAT) { FILINFO fno; if (fa_stat(path, &fno) != FR_OK) return 0; return fno.fsize; - } else if (GetVirtualSource(path)) { + } else if (drvtype & DRV_VIRTUAL) { VirtualFile vfile; if (!FindVirtualFile(&vfile, path, 0)) return 0; @@ -354,7 +390,7 @@ bool FileGetSha256(const char* path, u8* sha256) { sha_init(SHA256_MODE); ShowProgress(0, 0, path); - if (GetVirtualSource(path)) { // for virtual files + if (DriveType(path) & DRV_VIRTUAL) { // for virtual files VirtualFile vfile; u32 fsize; @@ -446,7 +482,7 @@ bool FileInjectFile(const char* dest, const char* orig, u32 offset) { } // open destination - if (GetVirtualSource(dest)) { + if (DriveType(dest) & DRV_VIRTUAL) { vdest = true; if (!FindVirtualFile(&dvfile, dest, 0)) return false; @@ -461,7 +497,7 @@ bool FileInjectFile(const char* dest, const char* orig, u32 offset) { } // open origin - if (GetVirtualSource(orig)) { + if (DriveType(orig) & DRV_VIRTUAL) { vorig = true; if (!FindVirtualFile(&ovfile, orig, 0)) { if (!vdest) f_close(&dfile); @@ -517,6 +553,8 @@ bool PathCopyVirtual(const char* destdir, const char* orig, u32* flags) { char* oname = strrchr(orig, '/'); char deststr[36 + 1]; char origstr[36 + 1]; + int ddrvtype = DriveType(destdir); + int odrvtype = DriveType(orig); bool ret = true; if (oname == NULL) return false; // not a proper origin path @@ -526,7 +564,7 @@ bool PathCopyVirtual(const char* destdir, const char* orig, u32* flags) { TruncateString(deststr, dest, 36, 8); TruncateString(origstr, orig, 36, 8); - if (GetVirtualSource(dest) && GetVirtualSource(orig)) { // virtual to virtual + if ((ddrvtype & DRV_VIRTUAL) && (odrvtype & DRV_VIRTUAL)) { // virtual to virtual VirtualFile dvfile; VirtualFile ovfile; u32 osize; @@ -560,7 +598,7 @@ bool PathCopyVirtual(const char* destdir, const char* orig, u32* flags) { } ShowProgress(1, 1, orig); InitExtFS(); - } else if (GetVirtualSource(dest)) { // SD card to virtual (other FAT not allowed!) + } else if (ddrvtype & DRV_VIRTUAL) { // SD card to virtual (other FAT not allowed!) VirtualFile dvfile; FIL ofile; u32 osize; @@ -613,7 +651,7 @@ bool PathCopyVirtual(const char* destdir, const char* orig, u32* flags) { ShowProgress(1, 1, orig); f_close(&ofile); InitExtFS(); - } else if (GetVirtualSource(orig)) { // virtual to any file system + } else if (odrvtype & DRV_VIRTUAL) { // virtual to any file system VirtualFile ovfile; FIL dfile; u32 osize; @@ -841,9 +879,11 @@ bool PathCopyWorker(char* dest, char* orig, u32* flags, bool move) { bool PathCopy(const char* destdir, const char* orig, u32* flags) { if (!CheckWritePermissions(destdir)) return false; if (flags) *flags = *flags & ~(SKIP_CUR|OVERWRITE_CUR); // reset local flags - if (GetVirtualSource(destdir) || GetVirtualSource(orig)) { + int ddrvtype = DriveType(destdir); + int odrvtype = DriveType(orig); + if ((ddrvtype | odrvtype) & DRV_VIRTUAL) { // users are inventive... - if ((PathToNumFS(orig) > 0) && GetVirtualSource(destdir)) { + if (!(odrvtype & (DRV_SDCARD|DRV_VIRTUAL)) && (ddrvtype & DRV_VIRTUAL)) { ShowPrompt(false, "Only files from SD card are accepted"); return false; } @@ -862,7 +902,8 @@ bool PathMove(const char* destdir, const char* orig, u32* flags) { if (!CheckWritePermissions(destdir)) return false; if (!CheckWritePermissions(orig)) return false; if (flags) *flags = *flags & ~(SKIP_CUR|OVERWRITE_CUR); // reset local flags - if ((PathToNumFS(destdir) < 0) || (PathToNumFS(orig) < 0)) { + // moving only for regular FAT drives (= not alias drives) + if (!(DriveType(destdir) & DriveType(orig) & DRV_STDFAT)) { ShowPrompt(false, "Error: Moving is not possible here"); return false; } else { @@ -1051,9 +1092,7 @@ bool GetRootDirContentsWorker(DirStruct* contents) { // virtual root objects hacked in for (u32 pdrv = 0; (pdrv < NORM_FS+VIRT_FS) && (n_entries < MAX_ENTRIES); pdrv++) { DirEntry* entry = &(contents->entry[n_entries]); - if ((pdrv < NORM_FS) && !fs_mounted[pdrv]) continue; - else if ((pdrv >= NORM_FS) && (!CheckAliasDrive(drvnum[pdrv])) && - (!CheckVirtualDrive(drvnum[pdrv])) && !(IsSearchDrive(drvnum[pdrv]))) continue; + if (!DriveType(drvnum[pdrv])) continue; // drive not available memset(entry->path, 0x00, 64); snprintf(entry->path + 0, 4, drvnum[pdrv]); snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], drvname[pdrv]); @@ -1148,7 +1187,7 @@ void SearchDirContents(DirStruct* contents, const char* path, const char* patter contents->entry->type = T_DOTDOT; contents->entry->size = 0; contents->n_entries = 1; - if (GetVirtualSource(path)) { + if (DriveType(path) & DRV_VIRTUAL) { if (!GetVirtualDirContentsWorker(contents, path, pattern)) contents->n_entries = 0; } else { @@ -1162,7 +1201,7 @@ void SearchDirContents(DirStruct* contents, const char* path, const char* patter } void GetDirContents(DirStruct* contents, const char* path) { - if (*search_pattern && *search_path && IsSearchDrive(path)) { + if (IsSearchDrive(path)) { ShowString("Searching, please wait..."); SearchDirContents(contents, search_path, search_pattern, true); ClearScreenF(true, false, COLOR_STD_BG); diff --git a/source/fs.h b/source/fs.h index bf7ddd3..a15063d 100644 --- a/source/fs.h +++ b/source/fs.h @@ -11,6 +11,22 @@ typedef enum { #define MAX_ENTRIES 1024 +// primary drive types +#define DRV_UNKNOWN (0<<0) +#define DRV_FAT (1<<0) +#define DRV_VIRTUAL (1<<1) +// secondary drive types +#define DRV_SDCARD (1<<3) +#define DRV_SYSNAND (1<<4) +#define DRV_EMUNAND (1<<5) +#define DRV_IMAGE (1<<6) +#define DRV_RAMDRIVE (1<<7) +#define DRV_MEMORY (1<<8) +#define DRV_ALIAS (1<<9) +#define DRV_SEARCH (1<<10) +#define DRV_STDFAT (1<<11) // standard FAT drive without limitiations + +// permission types #define PERM_SDCARD (1<<0) #define PERM_RAMDRIVE (1<<1) #define PERM_EMUNAND (1<<2) @@ -21,6 +37,7 @@ typedef enum { #define PERM_BASE (PERM_SDCARD | PERM_RAMDRIVE) #define PERM_ALL (PERM_SDCARD | PERM_RAMDRIVE | PERM_EMUNAND | PERM_SYSNAND | PERM_IMAGE | PERM_MEMORY) +// move / copy flags #define ASK_ALL (1<<0) #define SKIP_ALL (1<<1) #define OVERWRITE_ALL (1<<2) @@ -112,11 +129,8 @@ uint64_t GetTotalSpace(const char* path); /** Return the offset - in sectors - of the FAT partition on the drive **/ uint64_t GetPartitionOffsetSector(const char* path); -/** Helper function to get drive number from path */ -int PathToNumFS(const char* path); - -/** Check if drive is mounted */ -bool IsMountedFS(const char* path); +/** Function to identify the type of a drive **/ +int DriveType(const char* path); /** Check for soecial search drive **/ bool IsSearchDrive(const char* path); diff --git a/source/godmode.c b/source/godmode.c index 2c7e2cd..b8bd862 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -5,10 +5,9 @@ #include "platform.h" #include "nand.h" #include "virtual.h" -#include "alias.h" #include "image.h" -#define VERSION "0.6.9" +#define VERSION "0.7.0" #define N_PANES 2 #define IMG_DRV "789I" @@ -85,7 +84,16 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c ResizeString(tempstr, "(dir)", 160 / FONT_WIDTH_EXT, 8, false); } else if (curr_entry->type == T_DOTDOT) { snprintf(tempstr, 21, "%20s", ""); - } else { + } else if (curr_entry->type == T_ROOT) { + int drvtype = DriveType(curr_entry->path); + char drvstr[32]; + snprintf(drvstr, 31, "(%s%s)", + ((drvtype & DRV_SDCARD) ? "SD" : (drvtype & DRV_RAMDRIVE) ? "RAMDrive" : + (drvtype & DRV_SYSNAND) ? "SysNAND" : (drvtype & DRV_EMUNAND) ? "EmuNAND" : (drvtype & DRV_IMAGE) ? "Image" : + (drvtype & DRV_MEMORY) ? "Memory" : (drvtype & DRV_ALIAS) ? "Alias" : (drvtype & DRV_SEARCH) ? "Search" : ""), + ((drvtype & DRV_FAT) ? " FAT" : (drvtype & DRV_VIRTUAL) ? " Virtual" : "")); + ResizeString(tempstr, drvstr, 160 / FONT_WIDTH_EXT, 8, false); + }else { char numstr[32]; char bytestr[32]; FormatNumber(numstr, curr_entry->size); @@ -553,6 +561,8 @@ u32 GodMode() { clipboard->n_entries = 0; memset(panedata, 0x00, 0x10000); while (true) { // this is the main loop + int curr_drvtype = DriveType(current_path); + // basic sanity checking if (!current_dir->n_entries) { // current dir is empty -> revert to root *current_path = '\0'; @@ -592,7 +602,7 @@ u32 GodMode() { } } else { // one level up u32 user_select = 1; - if (IsSearchDrive(current_path)) { // special menu for search drive + if (curr_drvtype & DRV_SEARCH) { // special menu for search drive const char* optionstr[2] = { "Open this folder", "Open containing folder" }; char pathstr[32 + 1]; TruncateString(pathstr, curr_entry->path, 32, 8); @@ -617,12 +627,13 @@ u32 GodMode() { u32 n_opt = 2; u32 file_type = IdentifyImage(curr_entry->path); + u32 file_drvtype = DriveType(curr_entry->path); int injectable = ((clipboard->n_entries == 1) && (clipboard->entry[0].type == T_FILE) && - (PathToNumFS(clipboard->entry[0].path) >= 0) && + (file_drvtype & DRV_FAT) && (strncmp(clipboard->entry[0].path, curr_entry->path, 256) != 0)) ? (int) ++n_opt : -1; - int mountable = (file_type && (PathToNumFS(curr_entry->path) == 0)) ? (int) ++n_opt : -1; - int searchdrv = IsSearchDrive(current_path) ? (int) ++n_opt : -1; + int mountable = (file_type && (file_drvtype & DRV_SDCARD)) ? (int) ++n_opt : -1; + int searchdrv = (curr_drvtype & DRV_SEARCH) ? (int) ++n_opt : -1; TruncateString(pathstr, curr_entry->path, 32, 8); optionstr[0] = "Show in Hexeditor"; @@ -653,7 +664,7 @@ u32 GodMode() { bool write_sha = false; snprintf(sha_path, 256, "%s.sha", curr_entry->path); have_sha = (FileGetData(sha_path, sha256_file, 32, 0) == 32); - write_sha = !have_sha && (PathToNumFS(curr_entry->path) == 0); // writing only on SD + write_sha = !have_sha && (file_drvtype & DRV_SDCARD); // writing only on SD if (ShowPrompt(write_sha, "%s\n%016llX%016llX\n%016llX%016llX%s%s%s%s%s", pathstr, getbe64(sha256 + 0), getbe64(sha256 + 8), getbe64(sha256 + 16), getbe64(sha256 + 24), (have_sha) ? "\nSHA verification: " : "", @@ -680,7 +691,7 @@ u32 GodMode() { DeinitExtFS(); u32 mount_state = MountImage(curr_entry->path); InitExtFS(); - if (!mount_state || !(IsMountedFS("7:")|IsMountedFS("8:")|IsMountedFS("9:"))) { + if (!mount_state || !(DriveType("7:")||DriveType("8:")||DriveType("9:"))) { ShowPrompt(false, "Mounting image: failed"); DeinitExtFS(); MountImage(NULL); @@ -796,9 +807,9 @@ u32 GodMode() { SetWritePermissions((GetWritePermissions() > PERM_BASE) ? PERM_BASE : PERM_ALL, false); } } else if (!switched) { // standard unswitched command set - if (GetVirtualSource(current_path) && (pad_state & BUTTON_X)) { + if ((curr_drvtype & DRV_VIRTUAL) && (pad_state & BUTTON_X)) { ShowPrompt(false, "Not allowed in virtual path"); - } else if (CheckAliasDrive(current_path) && (pad_state & BUTTON_X)) { + } else if ((curr_drvtype & DRV_ALIAS) && (pad_state & BUTTON_X)) { ShowPrompt(false, "Not allowed in alias path"); } else if (pad_state & BUTTON_X) { // delete a file u32 n_marked = 0; @@ -839,7 +850,7 @@ u32 GodMode() { } if (clipboard->n_entries) last_clipboard_size = clipboard->n_entries; - } else if (IsSearchDrive(current_path) && (pad_state & BUTTON_Y)) { + } else if ((curr_drvtype & DRV_SEARCH) && (pad_state & BUTTON_Y)) { ShowPrompt(false, "Not allowed in search drive"); } else if (pad_state & BUTTON_Y) { // paste files const char* optionstr[2] = { "Copy path(s)", "Move path(s)" }; @@ -851,7 +862,7 @@ u32 GodMode() { TruncateString(namestr, clipboard->entry[0].name, 20, 12); snprintf(promptstr, 64, "Paste \"%s\" here?", namestr); } else snprintf(promptstr, 64, "Paste %lu paths here?", clipboard->n_entries); - user_select = ((PathToNumFS(clipboard->entry[0].path) >= 0) && (PathToNumFS(current_path) >= 0)) ? + user_select = ((DriveType(clipboard->entry[0].path) & curr_drvtype & DRV_STDFAT)) ? ShowSelectPrompt(2, optionstr, promptstr) : (ShowPrompt(true, promptstr) ? 1 : 0); if (user_select) { for (u32 c = 0; c < clipboard->n_entries; c++) { @@ -875,9 +886,9 @@ u32 GodMode() { ClearScreenF(true, false, COLOR_STD_BG); } } else { // switched command set - if (GetVirtualSource(current_path) && (pad_state & (BUTTON_X|BUTTON_Y))) { + if ((curr_drvtype & DRV_VIRTUAL) && (pad_state & (BUTTON_X|BUTTON_Y))) { ShowPrompt(false, "Not allowed in virtual path"); - } else if (CheckAliasDrive(current_path) && (pad_state & (BUTTON_X|BUTTON_Y))) { + } else if ((curr_drvtype & DRV_ALIAS) && (pad_state & (BUTTON_X|BUTTON_Y))) { ShowPrompt(false, "Not allowed in alias path"); } else if ((pad_state & BUTTON_X) && (curr_entry->type != T_DOTDOT)) { // rename a file char newname[256];