Completely revised permission system

This commit is contained in:
d0k3 2017-02-15 16:34:25 +01:00
parent f606fec7ea
commit a9d778823f
10 changed files with 167 additions and 74 deletions

View File

@ -38,7 +38,7 @@
(((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v))
// GodMode9 version
#define VERSION "0.9.9"
#define VERSION "0.9.9.1"
// input / output paths
#define INPUT_PATHS "0:", "0:/files9", "1:/rw/files9"

View File

@ -215,23 +215,25 @@ bool ShowPrompt(bool ask, const char *format, ...)
}
bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
const int seqcolors[6] = { COLOR_STD_FONT, COLOR_BRIGHTGREEN, COLOR_BRIGHTYELLOW,
COLOR_RED, COLOR_BRIGHTBLUE, COLOR_DARKRED };
const u32 sequences[6][5] = {
const int seqcolors[7] = { COLOR_STD_FONT, COLOR_BRIGHTGREEN, COLOR_BRIGHTYELLOW,
COLOR_ORANGE, COLOR_BRIGHTBLUE, COLOR_RED, COLOR_DARKRED };
const u32 sequences[7][5] = {
{ BUTTON_RIGHT, BUTTON_DOWN, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_A },
{ BUTTON_LEFT, BUTTON_DOWN, BUTTON_RIGHT, BUTTON_UP, BUTTON_A },
{ BUTTON_LEFT, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_UP, BUTTON_A },
{ BUTTON_LEFT, BUTTON_UP, BUTTON_RIGHT, BUTTON_UP, BUTTON_A },
{ BUTTON_RIGHT, BUTTON_DOWN, BUTTON_LEFT, BUTTON_DOWN, BUTTON_A },
{ BUTTON_DOWN, BUTTON_LEFT, BUTTON_UP, BUTTON_LEFT, BUTTON_A }
{ BUTTON_DOWN, BUTTON_LEFT, BUTTON_UP, BUTTON_LEFT, BUTTON_A },
{ BUTTON_UP, BUTTON_DOWN, BUTTON_LEFT, BUTTON_RIGHT, BUTTON_A }
};
const char seqsymbols[6][5] = {
const char seqsymbols[7][5] = {
{ '\x1A', '\x19', '\x1A', '\x19', 'A' },
{ '\x1B', '\x19', '\x1A', '\x18', 'A' },
{ '\x1B', '\x1A', '\x19', '\x18', 'A' },
{ '\x1B', '\x18', '\x1A', '\x18', 'A' },
{ '\x1A', '\x19', '\x1B', '\x19', 'A' },
{ '\x19', '\x1B', '\x18', '\x1B', 'A' }
{ '\x19', '\x1B', '\x18', '\x1B', 'A' },
{ '\x18', '\x19', '\x1B', '\x1A', 'A' }
};
const u32 len = 5;
u32 lvl = 0;

View File

@ -32,6 +32,7 @@
#define COLOR_BLUE RGB(0x00, 0x00, 0xFF)
#define COLOR_YELLOW RGB(0xFF, 0xFF, 0x00)
#define COLOR_CYAN RGB(0xFF, 0x00, 0xFF)
#define COLOR_ORANGE RGB(0xFF, 0xA5, 0x00)
#define COLOR_BRIGHTRED RGB(0xFF, 0x30, 0x30)
#define COLOR_DARKRED RGB(0x80, 0x00, 0x00)

View File

@ -15,7 +15,7 @@ int DriveType(const char* path) {
int pdrv = GetMountedFSNum(path);
if (CheckAliasDrive(path)) {
type = DRV_FAT | DRV_ALIAS;
type = DRV_FAT | DRV_ALIAS | ((*path == 'A') ? DRV_SYSNAND : DRV_EMUNAND);
} else if (*search_pattern && *search_path && (strncmp(path, "Z:", 3) == 0)) {
type = DRV_SEARCH;
} else if ((pdrv >= 0) && (pdrv < NORM_FS)) {
@ -23,10 +23,14 @@ int DriveType(const char* path) {
type = DRV_FAT | DRV_SDCARD | DRV_STDFAT;
} else if ((pdrv == 9) && !(GetMountState() & IMG_NAND)) {
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 == 1) {
type = DRV_FAT | DRV_SYSNAND | DRV_CTRNAND | DRV_STDFAT;
} else if ((pdrv == 2) || (pdrv == 3)) {
type = DRV_FAT | DRV_SYSNAND | DRV_TWLNAND | DRV_STDFAT;
} else if (pdrv == 4) {
type = DRV_FAT | DRV_EMUNAND | DRV_CTRNAND | DRV_STDFAT;
} else if ((pdrv == 5) || (pdrv == 6)) {
type = DRV_FAT | DRV_EMUNAND | DRV_TWLNAND | DRV_STDFAT;
} else if ((pdrv >= 7) && (pdrv <= 9) &&
(GetMountState() & (IMG_FAT|IMG_NAND))) {
type = DRV_FAT | DRV_IMAGE | DRV_STDFAT;

View File

@ -15,15 +15,17 @@
#define DRV_SDCARD (1<<2)
#define DRV_SYSNAND (1<<3)
#define DRV_EMUNAND (1<<4)
#define DRV_IMAGE (1<<5)
#define DRV_XORPAD (1<<6)
#define DRV_RAMDRIVE (1<<7)
#define DRV_MEMORY (1<<8)
#define DRV_GAME (1<<9)
#define DRV_CART (1<<10)
#define DRV_ALIAS (1<<11)
#define DRV_SEARCH (1<<12)
#define DRV_STDFAT (1<<13) // standard FAT drive without limitations
#define DRV_CTRNAND (1<<5)
#define DRV_TWLNAND (1<<6)
#define DRV_IMAGE (1<<7)
#define DRV_XORPAD (1<<8)
#define DRV_RAMDRIVE (1<<9)
#define DRV_MEMORY (1<<10)
#define DRV_GAME (1<<11)
#define DRV_CART (1<<12)
#define DRV_ALIAS (1<<13)
#define DRV_SEARCH (1<<14)
#define DRV_STDFAT (1<<15) // standard FAT drive without limitations
#define FS_DRVNAME \
"SDCARD", \

View File

@ -2,8 +2,17 @@
#include "fsdrive.h"
#include "virtual.h"
#include "image.h"
#include "nand.h"
#include "ui.h"
#define PATH_SYS_LVL1 "S:/twln.bin", "S:/twlp.bin"
#define PATH_SYS_LVL2 "1:/rw/sys/LocalFriendCodeSeed_B", "1:/rw/sys/SecureInfo_A", "1:/rw/sys/SecureInfo_B", \
"1:/private/movable.sed", "S:/ctrnand_fat.bin", "S:/ctrnand_full.bin"
#define PATH_SYS_LVL3 "S:/firm0.bin", "S:/firm1.bin", "S:/nand.bin", "S:/nand_minsize.bin", "S:/nand_hdr.bin", \
"S:/sector0x96.bin", "S:/twlmbr.bin"
#define PATH_EMU_LVL1 "E:/ctrnand_fat.bin", "E:/ctrnand_full.bin", "E:/nand.bin", "E:/nand_minsize.bin", "E:/nand_hdr.bin"
#define PATH_PERM_CHK "E:", "S:", "1:/rw/sys", "1:/private"
// write permissions - careful with this
static u32 write_permissions = PERM_BASE;
@ -17,18 +26,33 @@ bool CheckWritePermissions(const char* path) {
return false; // endless loop when mounted file inside image, but not possible
// check drive type, get permission type
// TODO: handle entypoints other than A9LH (!!!)
if (drvtype & DRV_SYSNAND) {
perm = PERM_SYSNAND;
snprintf(area_name, 16, "the SysNAND");
// check virtual file flags (if any)
VirtualFile vfile;
if (GetVirtualFile(&vfile, path) && (vfile.flags & VFLAG_A9LH_AREA)) {
perm = PERM_A9LH;
snprintf(area_name, 16, "A9LH regions");
u32 perms[] = { PERM_SYS_LVL0, PERM_SYS_LVL1, PERM_SYS_LVL2, PERM_SYS_LVL3 };
u32 lvl = (drvtype & (DRV_TWLNAND|DRV_ALIAS|DRV_CTRNAND)) ? 1 : 0;
if (drvtype & (DRV_CTRNAND|DRV_VIRTUAL)) { // check for paths
const char* path_lvl3[] = { PATH_SYS_LVL3 };
const char* path_lvl2[] = { PATH_SYS_LVL2 };
const char* path_lvl1[] = { PATH_SYS_LVL1 };
for (u32 i = 0; (i < sizeof(path_lvl3) / sizeof(char*)) && (lvl < 3); i++)
if (strncmp(path, path_lvl3[i], 256) == 0) lvl = 3;
for (u32 i = 0; (i < sizeof(path_lvl2) / sizeof(char*)) && (lvl < 2); i++)
if (strncmp(path, path_lvl2[i], 256) == 0) lvl = 2;
for (u32 i = 0; (i < sizeof(path_lvl1) / sizeof(char*)) && (lvl < 1); i++)
if (strncmp(path, path_lvl1[i], 256) == 0) lvl = 1;
}
perm = perms[lvl];
snprintf(area_name, 16, "SysNAND (lvl%lu)", lvl);
} else if (drvtype & DRV_EMUNAND) {
perm = PERM_EMUNAND;
snprintf(area_name, 16, "the EmuNAND");
u32 perms[] = { PERM_EMU_LVL0, PERM_EMU_LVL1 };
u32 lvl = (drvtype & (DRV_ALIAS|DRV_CTRNAND)) ? 1 : 0;
if (drvtype & DRV_VIRTUAL) { // check for paths
const char* path_lvl1[] = { PATH_EMU_LVL1 };
for (u32 i = 0; (i < sizeof(path_lvl1) / sizeof(char*)) && (lvl < 1); i++)
if (strncmp(path, path_lvl1[i], 256) == 0) lvl = 1;
}
perm = perms[lvl];
snprintf(area_name, 16, "EmuNAND (lvl%lu)", lvl);
} else if (drvtype & DRV_GAME) {
perm = PERM_GAME;
snprintf(area_name, 16, "game images");
@ -44,15 +68,15 @@ bool CheckWritePermissions(const char* path) {
} else if (drvtype & DRV_MEMORY) {
perm = PERM_MEMORY;
snprintf(area_name, 16, "memory areas");
} else if ((drvtype & DRV_ALIAS) || (strncmp(path, "0:/Nintendo 3DS", 15) == 0)) {
} else if (strncmp(path, "0:/Nintendo 3DS", 15) == 0) { // this check could be better
perm = PERM_SDDATA;
snprintf(area_name, 16, "SD system data");
} else if (drvtype & DRV_SDCARD) {
perm = PERM_SDCARD;
snprintf(area_name, 16, "the SD card");
snprintf(area_name, 16, "SD card");
} else if (drvtype & DRV_RAMDRIVE) {
perm = PERM_RAMDRIVE;
snprintf(area_name, 16, "the RAM drive");
snprintf(area_name, 16, "RAM drive");
} else {
return false;
}
@ -68,6 +92,19 @@ bool CheckWritePermissions(const char* path) {
return SetWritePermissions(perm, true);
}
bool CheckDirWritePermissions(const char* path) {
const char* path_chk[] = { PATH_SYS_LVL3, PATH_SYS_LVL2, PATH_SYS_LVL1, PATH_EMU_LVL1 };
for (u32 i = 0; i < sizeof(path_chk) / sizeof(char*); i++) {
const char* path_cmp = path_chk[i];
u32 p = 0;
for (; p < 256; p++)
if (!path[p] || !path_cmp[p] || (path[p] != path_cmp[p])) break;
if (!path[p] && (path_cmp[p] == '/'))
return CheckWritePermissions(path_cmp); // special dir, check object
}
return CheckWritePermissions(path); // not a special dir, just check path
}
bool SetWritePermissions(u32 perm, bool add_perm) {
if ((write_permissions & perm) == perm) { // write permissions already given
if (!add_perm) write_permissions = perm;
@ -83,17 +120,37 @@ bool SetWritePermissions(u32 perm, bool add_perm) {
if (!ShowUnlockSequence(1, "You want to enable SD card\nwriting permissions."))
return false;
break;
case PERM_IMAGE:
if (!ShowUnlockSequence(1, "You want to enable image\nwriting permissions."))
return false;
break;
case PERM_RAMDRIVE:
if (!ShowUnlockSequence(1, "You want to enable RAM drive\nwriting permissions."))
return false;
case PERM_EMUNAND:
if (!ShowUnlockSequence(2, "You want to enable EmuNAND\nwriting permissions."))
case PERM_EMU_LVL0:
if (!ShowUnlockSequence(1, "You want to enable EmuNAND\nlvl0 writing permissions."))
return false;
break;
case PERM_IMAGE:
if (!ShowUnlockSequence(2, "You want to enable image\nwriting permissions."))
case PERM_SYS_LVL0:
if (!ShowUnlockSequence(1, "You want to enable SysNAND\nlvl0 writing permissions."))
return false;
break;
case PERM_EMU_LVL1:
if (!ShowUnlockSequence(2, "You want to enable EmuNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nrecoverable system data,\nuser data & savegames."))
return false;
break;
case PERM_SYS_LVL1:
if (!ShowUnlockSequence(2, "You want to enable SysNAND\nlvl1 writing permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames."))
return false;
break;
case PERM_SDDATA:
if (!ShowUnlockSequence(2, "You want to enable SD data\nwriting permissions.\n \nThis enables you to modify\ninstallations, user data &\nsavegames."))
return false;
break;
case PERM_CART:
ShowPrompt(false, "Unlock write permission for\ngame carts is not allowed.");
return false;
break;
case PERM_GAME:
ShowPrompt(false, "Unlock write permission for\ngame images is not allowed.");
return false;
@ -103,24 +160,20 @@ bool SetWritePermissions(u32 perm, bool add_perm) {
return false;
break;
#ifndef SAFEMODE
case PERM_SYSNAND:
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nwriting permissions.\nThis enables you to do some\nreally dangerous stuff!"))
return false;
break;
case PERM_A9LH:
if (!ShowUnlockSequence(5, "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable A9LH area\nwriting permissions.\nThis enables you to OVERWRITE\nyour A9LH installation!"))
case PERM_SYS_LVL2:
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nlvl2 writing permissions.\n \nThis enables you to modify\nirrecoverable system data!"))
return false;
break;
case PERM_MEMORY:
if (!ShowUnlockSequence(4, "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\nWriting to certain areas may\nlead to unexpected results."))
if (!ShowUnlockSequence(4, "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\n nWriting to certain areas may\nlead to unexpected results."))
return false;
break;
case PERM_SDDATA:
if (!ShowUnlockSequence(2, "You want to enable SD data\nwriting permissions."))
case PERM_SYS_LVL3:
if (!ShowUnlockSequence(5, "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable SysNAND\nlvl3 writing permissions.\n \nThis enables you to OVERWRITE\nyour A9LH installation and\nBRICK your console!"))
return false;
break;
case PERM_ALL:
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable ALL\nwriting permissions.\nThis enables you to do some\nreally dangerous stuff!"))
case PERM_ALL: // maybe get rid of this (???)
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable ALL\nwriting permissions.\n \nThis enables you to do some\nreally dangerous stuff!"))
return false;
break;
default:
@ -128,9 +181,8 @@ bool SetWritePermissions(u32 perm, bool add_perm) {
return false;
break;
#else
case PERM_ALL:
perm &= ~(PERM_SYSNAND|PERM_MEMORY);
if (!ShowUnlockSequence(2, "You want to enable EmuNAND &\nimage writing permissions.\nKeep backups, just in case."))
case PERM_ALL: // dito (???)
if (!ShowUnlockSequence(2, "You want to enable ALL safe\nwriting permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames."))
return false;
break;
default:

View File

@ -4,22 +4,39 @@
// permission types
#define PERM_SDCARD (1<<0)
#define PERM_RAMDRIVE (1<<1)
#define PERM_EMUNAND (1<<2)
#define PERM_SYSNAND (1<<3)
#define PERM_IMAGE (1<<4)
#define PERM_MEMORY (1<<5)
#define PERM_GAME (1<<6) // can't be enabled, placeholder
#define PERM_XORPAD (1<<7) // can't be enabled, placeholder
#define PERM_CART (1<<8) // can't be enabled, placeholder
#define PERM_A9LH ((1<<9) | PERM_SYSNAND)
#define PERM_SDDATA ((1<<10) | PERM_SDCARD)
#define PERM_BASE (PERM_SDCARD | PERM_RAMDRIVE)
#define PERM_ALL (PERM_SDCARD | PERM_RAMDRIVE | PERM_EMUNAND | PERM_SYSNAND | PERM_IMAGE | PERM_MEMORY | PERM_SDDATA)
#define PERM_IMAGE (1<<1)
#define PERM_RAMDRIVE (1<<2)
#define PERM_EMU_LVL0 (1<<3)
#define PERM_EMU_LVL1 (PERM_EMU_LVL0|(1<<4))
#define PERM_SYS_LVL0 (1<<5)
#define PERM_SYS_LVL1 (PERM_SYS_LVL0|(1<<6))
#define PERM_SYS_LVL2 (PERM_SYS_LVL1|(1<<7))
#define PERM_SYS_LVL3 (PERM_SYS_LVL2|(1<<8))
#define PERM_SDDATA (PERM_SDCARD|(1<<9))
#define PERM_MEMORY (1<<10)
#define PERM_GAME (1<<11) // can't be enabled, placeholder
#define PERM_XORPAD (1<<12) // can't be enabled, placeholder
#define PERM_CART (1<<13) // can't be enabled, placeholder
#define PERM_BASE (PERM_SDCARD | PERM_IMAGE | PERM_RAMDRIVE | PERM_EMU_LVL0 | PERM_SYS_LVL0)
#ifndef SAFEMODE
#define PERM_ALL (PERM_BASE | PERM_SDDATA | PERM_EMU_LVL1 | PERM_SYS_LVL2 | PERM_MEMORY)
#else
#define PERM_ALL (PERM_BASE | PERM_SDDATA | PERM_EMU_LVL1 | PERM_SYS_LVL1)
#endif
// permission levels / colors
#define PERM_BLUE (GetWritePermissions()&PERM_MEMORY)
#define PERM_RED (GetWritePermissions()&(PERM_SYS_LVL3&~PERM_SYS_LVL2))
#define PERM_ORANGE (GetWritePermissions()&(PERM_SYS_LVL2&~PERM_SYS_LVL1))
#define PERM_YELLOW (GetWritePermissions()&((PERM_SYS_LVL1&~PERM_SYS_LVL0)|(PERM_EMU_LVL1&~PERM_EMU_LVL0)|(PERM_SDDATA&~PERM_SDCARD)))
#define PERM_GREEN (GetWritePermissions()&(PERM_SDCARD|PERM_IMAGE|PERM_RAMDRIVE|PERM_EMU_LVL0|PERM_SYS_LVL0))
/** Check if writing to this path is allowed **/
bool CheckWritePermissions(const char* path);
/** Same as above, but for all containing objects **/
bool CheckDirWritePermissions(const char* path);
/** Set new write permissions */
bool SetWritePermissions(u32 perm, bool add_perm);

View File

@ -57,7 +57,7 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) {
else memset(mbr + 0x1CE, 0, 0x10);
// one last warning....
if (!ShowUnlockSequence(3, "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.\n"))
if (!ShowUnlockSequence(6, "!WARNING!\n \nProceeding will format this SD.\nThis will irreversibly delete\nALL data on it.\n"))
return false;
ShowString("Formatting SD, please wait...");
@ -270,8 +270,11 @@ bool PathCopyVrtToVrt(const char* destdir, const char* orig) {
ShowPrompt(false, "Origin equals destination:\n%s\n%s", origstr, deststr);
return false;
}
if ((dvfile.keyslot == ovfile.keyslot) && (dvfile.offset == ovfile.offset)) // this improves copy times
dvfile.keyslot = ovfile.keyslot = 0xFF;
if ((dvfile.keyslot == ovfile.keyslot) && (dvfile.offset == ovfile.offset))
dvfile.keyslot = ovfile.keyslot = 0xFF; // this improves copy times for virtual NAND
// check write permissions
if (!CheckWritePermissions(dest)) return false;
// unmount critical NAND drives
DismountDriveType(DriveType(destdir)&(DRV_SYSNAND|DRV_EMUNAND|DRV_IMAGE));
@ -318,6 +321,7 @@ bool PathCopyFatToVrt(const char* destdir, const char* orig) {
}
if (!ShowPrompt(true, "Entry not found: %s\nInject into %s instead?", dest, dvfile.name))
return false;
snprintf(dest, 255, "%s/%s", destdir, dvfile.name);
} else if (dvfile.size != osize) { // handling for differing sizes
char deststr[36 + 1];
char origstr[36 + 1];
@ -336,6 +340,9 @@ bool PathCopyFatToVrt(const char* destdir, const char* orig) {
}
}
// check write permissions
if (!CheckWritePermissions(dest)) return false;
// FAT file
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))) {
@ -418,6 +425,10 @@ bool PathCopyVrtToFat(char* dest, char* orig, u32* flags) {
}
}
// check destination write permission (SysNAND CTRNAND only)
if ((*dest == '1') && (!flags || (*flags & (OVERWRITE_CUR|OVERWRITE_ALL))) &&
!CheckWritePermissions(dest)) return false;
// the copy process takes place here
if (!ShowProgress(0, 0, orig)) return false;
if (vfile.flags & VFLAG_DIR) { // processing folders
@ -549,6 +560,10 @@ bool PathCopyWorker(char* dest, char* orig, u32* flags, bool move) {
}
}
// check destination write permission (SysNAND CTRNAND only)
if ((*dest == '1') && (!flags || (*flags & (OVERWRITE_CUR|OVERWRITE_ALL))) &&
!CheckWritePermissions(dest)) return false;
// the copy process takes place here
if (!ShowProgress(0, 0, orig)) return false;
if (move && fa_stat(dest, NULL) != FR_OK) { // moving if dest not existing
@ -646,7 +661,7 @@ 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 (flags) *flags = *flags & ~(SKIP_CUR|OVERWRITE_CUR); // reset local flags
int ddrvtype = DriveType(destdir);
int odrvtype = DriveType(orig);
if (!(ddrvtype & DRV_VIRTUAL)) { // FAT / virtual to FAT
@ -668,7 +683,7 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) {
bool PathMove(const char* destdir, const char* orig, u32* flags) {
if (!CheckWritePermissions(destdir)) return false;
if (!CheckWritePermissions(orig)) return false;
if (!CheckDirWritePermissions(orig)) return false; // check orig FULL DIR permissions
if (flags) *flags = *flags & ~(SKIP_CUR|OVERWRITE_CUR); // reset local flags
// moving only for regular FAT drives (= not alias drives)
if (!(DriveType(destdir) & DriveType(orig) & DRV_STDFAT)) {
@ -718,8 +733,9 @@ bool PathDeleteWorker(char* fpath) {
bool PathDelete(const char* path) {
char fpath[256]; // 256 is the maximum length of a full path
if (!CheckWritePermissions(path)) return false;
if (!CheckDirWritePermissions(path)) return false;
strncpy(fpath, path, 256);
ShowString("Deleting files, please wait...");
return PathDeleteWorker(fpath);
}
@ -727,7 +743,7 @@ bool PathRename(const char* path, const char* newname) {
char npath[256]; // 256 is the maximum length of a full path
char* oldname = strrchr(path, '/');
if (!CheckWritePermissions(path)) return false;
if (!CheckDirWritePermissions(path)) return false;
if (!oldname) return false;
oldname++;
strncpy(npath, path, oldname - path);

View File

@ -19,7 +19,8 @@
#define N_PANES 2
#define COLOR_TOP_BAR ((GetWritePermissions() & (PERM_A9LH&~PERM_SYSNAND)) ? COLOR_DARKRED : (GetWritePermissions() & PERM_SYSNAND) ? COLOR_RED : (GetWritePermissions() & PERM_MEMORY) ? COLOR_BRIGHTBLUE : (GetWritePermissions() & (PERM_EMUNAND|PERM_IMAGE)) ? COLOR_BRIGHTYELLOW : GetWritePermissions() ? COLOR_BRIGHTGREEN : COLOR_WHITE)
#define COLOR_TOP_BAR (PERM_RED ? COLOR_RED : PERM_ORANGE ? COLOR_ORANGE : PERM_BLUE ? COLOR_BRIGHTBLUE : \
PERM_YELLOW ? COLOR_BRIGHTYELLOW : PERM_GREEN ? COLOR_GREEN : COLOR_WHITE)
#define COLOR_SIDE_BAR COLOR_DARKGREY
#define COLOR_MARKED COLOR_TINTEDYELLOW
#define COLOR_FILE COLOR_TINTEDGREEN
@ -1224,7 +1225,6 @@ u32 GodMode() {
if (n_marked) {
if (ShowPrompt(true, "Delete %u path(s)?", n_marked)) {
u32 n_errors = 0;
ShowString("Deleting files, please wait...");
for (u32 c = 0; c < current_dir->n_entries; c++)
if (current_dir->entry[c].marked && !PathDelete(current_dir->entry[c].path))
n_errors++;
@ -1235,7 +1235,6 @@ u32 GodMode() {
char namestr[36+1];
TruncateString(namestr, curr_entry->name, 28, 12);
if (ShowPrompt(true, "Delete \"%s\"?", namestr)) {
ShowString("Deleting %s\nPlease wait...", namestr);
if (!PathDelete(curr_entry->path))
ShowPrompt(false, "Failed deleting:\n%s", namestr);
ClearScreenF(true, false, COLOR_STD_BG);

View File

@ -122,7 +122,7 @@ u32 SafeRestoreNandDump(const char* path) {
ShowPrompt(false, "Error: A9LH not detected.");
return 1;
}
if (!SetWritePermissions(PERM_SYSNAND, true)) return 1;
if (!SetWritePermissions(PERM_SYS_LVL2, true)) return 1;
// open file, get size
if (fvx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)