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)) (((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v))
// GodMode9 version // GodMode9 version
#define VERSION "0.9.9" #define VERSION "0.9.9.1"
// input / output paths // input / output paths
#define INPUT_PATHS "0:", "0:/files9", "1:/rw/files9" #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, ...) { bool ShowUnlockSequence(u32 seqlvl, const char *format, ...) {
const int seqcolors[6] = { COLOR_STD_FONT, COLOR_BRIGHTGREEN, COLOR_BRIGHTYELLOW, const int seqcolors[7] = { COLOR_STD_FONT, COLOR_BRIGHTGREEN, COLOR_BRIGHTYELLOW,
COLOR_RED, COLOR_BRIGHTBLUE, COLOR_DARKRED }; COLOR_ORANGE, COLOR_BRIGHTBLUE, COLOR_RED, COLOR_DARKRED };
const u32 sequences[6][5] = { const u32 sequences[7][5] = {
{ BUTTON_RIGHT, BUTTON_DOWN, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_A }, { BUTTON_RIGHT, BUTTON_DOWN, BUTTON_RIGHT, BUTTON_DOWN, BUTTON_A },
{ BUTTON_LEFT, BUTTON_DOWN, BUTTON_RIGHT, BUTTON_UP, 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_RIGHT, BUTTON_DOWN, BUTTON_UP, BUTTON_A },
{ BUTTON_LEFT, BUTTON_UP, BUTTON_RIGHT, 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_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' }, { '\x1A', '\x19', '\x1A', '\x19', 'A' },
{ '\x1B', '\x19', '\x1A', '\x18', 'A' }, { '\x1B', '\x19', '\x1A', '\x18', 'A' },
{ '\x1B', '\x1A', '\x19', '\x18', 'A' }, { '\x1B', '\x1A', '\x19', '\x18', 'A' },
{ '\x1B', '\x18', '\x1A', '\x18', 'A' }, { '\x1B', '\x18', '\x1A', '\x18', 'A' },
{ '\x1A', '\x19', '\x1B', '\x19', '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; const u32 len = 5;
u32 lvl = 0; u32 lvl = 0;

View File

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

View File

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

View File

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

View File

@ -2,8 +2,17 @@
#include "fsdrive.h" #include "fsdrive.h"
#include "virtual.h" #include "virtual.h"
#include "image.h" #include "image.h"
#include "nand.h"
#include "ui.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 // write permissions - careful with this
static u32 write_permissions = PERM_BASE; 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 return false; // endless loop when mounted file inside image, but not possible
// check drive type, get permission type // check drive type, get permission type
// TODO: handle entypoints other than A9LH (!!!)
if (drvtype & DRV_SYSNAND) { if (drvtype & DRV_SYSNAND) {
perm = PERM_SYSNAND; u32 perms[] = { PERM_SYS_LVL0, PERM_SYS_LVL1, PERM_SYS_LVL2, PERM_SYS_LVL3 };
snprintf(area_name, 16, "the SysNAND"); u32 lvl = (drvtype & (DRV_TWLNAND|DRV_ALIAS|DRV_CTRNAND)) ? 1 : 0;
// check virtual file flags (if any) if (drvtype & (DRV_CTRNAND|DRV_VIRTUAL)) { // check for paths
VirtualFile vfile; const char* path_lvl3[] = { PATH_SYS_LVL3 };
if (GetVirtualFile(&vfile, path) && (vfile.flags & VFLAG_A9LH_AREA)) { const char* path_lvl2[] = { PATH_SYS_LVL2 };
perm = PERM_A9LH; const char* path_lvl1[] = { PATH_SYS_LVL1 };
snprintf(area_name, 16, "A9LH regions"); 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) { } else if (drvtype & DRV_EMUNAND) {
perm = PERM_EMUNAND; u32 perms[] = { PERM_EMU_LVL0, PERM_EMU_LVL1 };
snprintf(area_name, 16, "the EmuNAND"); 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) { } else if (drvtype & DRV_GAME) {
perm = PERM_GAME; perm = PERM_GAME;
snprintf(area_name, 16, "game images"); snprintf(area_name, 16, "game images");
@ -44,15 +68,15 @@ bool CheckWritePermissions(const char* path) {
} else if (drvtype & DRV_MEMORY) { } else if (drvtype & DRV_MEMORY) {
perm = PERM_MEMORY; perm = PERM_MEMORY;
snprintf(area_name, 16, "memory areas"); 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; perm = PERM_SDDATA;
snprintf(area_name, 16, "SD system data"); snprintf(area_name, 16, "SD system data");
} else if (drvtype & DRV_SDCARD) { } else if (drvtype & DRV_SDCARD) {
perm = PERM_SDCARD; perm = PERM_SDCARD;
snprintf(area_name, 16, "the SD card"); snprintf(area_name, 16, "SD card");
} else if (drvtype & DRV_RAMDRIVE) { } else if (drvtype & DRV_RAMDRIVE) {
perm = PERM_RAMDRIVE; perm = PERM_RAMDRIVE;
snprintf(area_name, 16, "the RAM drive"); snprintf(area_name, 16, "RAM drive");
} else { } else {
return false; return false;
} }
@ -68,6 +92,19 @@ bool CheckWritePermissions(const char* path) {
return SetWritePermissions(perm, true); 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) { bool SetWritePermissions(u32 perm, bool add_perm) {
if ((write_permissions & perm) == perm) { // write permissions already given if ((write_permissions & perm) == perm) { // write permissions already given
if (!add_perm) write_permissions = perm; 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.")) if (!ShowUnlockSequence(1, "You want to enable SD card\nwriting permissions."))
return false; return false;
break; break;
case PERM_IMAGE:
if (!ShowUnlockSequence(1, "You want to enable image\nwriting permissions."))
return false;
break;
case PERM_RAMDRIVE: case PERM_RAMDRIVE:
if (!ShowUnlockSequence(1, "You want to enable RAM drive\nwriting permissions.")) if (!ShowUnlockSequence(1, "You want to enable RAM drive\nwriting permissions."))
return false; return false;
case PERM_EMUNAND: case PERM_EMU_LVL0:
if (!ShowUnlockSequence(2, "You want to enable EmuNAND\nwriting permissions.")) if (!ShowUnlockSequence(1, "You want to enable EmuNAND\nlvl0 writing permissions."))
return false; return false;
break; break;
case PERM_IMAGE: case PERM_SYS_LVL0:
if (!ShowUnlockSequence(2, "You want to enable image\nwriting permissions.")) if (!ShowUnlockSequence(1, "You want to enable SysNAND\nlvl0 writing permissions."))
return false; return false;
break; 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: case PERM_GAME:
ShowPrompt(false, "Unlock write permission for\ngame images is not allowed."); ShowPrompt(false, "Unlock write permission for\ngame images is not allowed.");
return false; return false;
@ -103,24 +160,20 @@ bool SetWritePermissions(u32 perm, bool add_perm) {
return false; return false;
break; break;
#ifndef SAFEMODE #ifndef SAFEMODE
case PERM_SYSNAND: case PERM_SYS_LVL2:
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nwriting permissions.\nThis enables you to do some\nreally dangerous stuff!")) 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_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!"))
return false; return false;
break; break;
case PERM_MEMORY: 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; return false;
break; break;
case PERM_SDDATA: case PERM_SYS_LVL3:
if (!ShowUnlockSequence(2, "You want to enable SD data\nwriting permissions.")) 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; return false;
break; break;
case PERM_ALL: case PERM_ALL: // maybe get rid of this (???)
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable ALL\nwriting permissions.\nThis enables you to do some\nreally dangerous stuff!")) 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; return false;
break; break;
default: default:
@ -128,9 +181,8 @@ bool SetWritePermissions(u32 perm, bool add_perm) {
return false; return false;
break; break;
#else #else
case PERM_ALL: case PERM_ALL: // dito (???)
perm &= ~(PERM_SYSNAND|PERM_MEMORY); if (!ShowUnlockSequence(2, "You want to enable ALL safe\nwriting permissions.\n \nThis enables you to modify\nsystem data, installations,\nuser data & savegames."))
if (!ShowUnlockSequence(2, "You want to enable EmuNAND &\nimage writing permissions.\nKeep backups, just in case."))
return false; return false;
break; break;
default: default:

View File

@ -4,22 +4,39 @@
// permission types // permission types
#define PERM_SDCARD (1<<0) #define PERM_SDCARD (1<<0)
#define PERM_RAMDRIVE (1<<1) #define PERM_IMAGE (1<<1)
#define PERM_EMUNAND (1<<2) #define PERM_RAMDRIVE (1<<2)
#define PERM_SYSNAND (1<<3) #define PERM_EMU_LVL0 (1<<3)
#define PERM_IMAGE (1<<4) #define PERM_EMU_LVL1 (PERM_EMU_LVL0|(1<<4))
#define PERM_MEMORY (1<<5) #define PERM_SYS_LVL0 (1<<5)
#define PERM_GAME (1<<6) // can't be enabled, placeholder #define PERM_SYS_LVL1 (PERM_SYS_LVL0|(1<<6))
#define PERM_XORPAD (1<<7) // can't be enabled, placeholder #define PERM_SYS_LVL2 (PERM_SYS_LVL1|(1<<7))
#define PERM_CART (1<<8) // can't be enabled, placeholder #define PERM_SYS_LVL3 (PERM_SYS_LVL2|(1<<8))
#define PERM_A9LH ((1<<9) | PERM_SYSNAND) #define PERM_SDDATA (PERM_SDCARD|(1<<9))
#define PERM_SDDATA ((1<<10) | PERM_SDCARD) #define PERM_MEMORY (1<<10)
#define PERM_BASE (PERM_SDCARD | PERM_RAMDRIVE) #define PERM_GAME (1<<11) // can't be enabled, placeholder
#define PERM_ALL (PERM_SDCARD | PERM_RAMDRIVE | PERM_EMUNAND | PERM_SYSNAND | PERM_IMAGE | PERM_MEMORY | PERM_SDDATA) #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 **/ /** Check if writing to this path is allowed **/
bool CheckWritePermissions(const char* path); bool CheckWritePermissions(const char* path);
/** Same as above, but for all containing objects **/
bool CheckDirWritePermissions(const char* path);
/** Set new write permissions */ /** Set new write permissions */
bool SetWritePermissions(u32 perm, bool add_perm); 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); else memset(mbr + 0x1CE, 0, 0x10);
// one last warning.... // 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; return false;
ShowString("Formatting SD, please wait..."); 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); ShowPrompt(false, "Origin equals destination:\n%s\n%s", origstr, deststr);
return false; return false;
} }
if ((dvfile.keyslot == ovfile.keyslot) && (dvfile.offset == ovfile.offset)) // this improves copy times if ((dvfile.keyslot == ovfile.keyslot) && (dvfile.offset == ovfile.offset))
dvfile.keyslot = ovfile.keyslot = 0xFF; dvfile.keyslot = ovfile.keyslot = 0xFF; // this improves copy times for virtual NAND
// check write permissions
if (!CheckWritePermissions(dest)) return false;
// unmount critical NAND drives // unmount critical NAND drives
DismountDriveType(DriveType(destdir)&(DRV_SYSNAND|DRV_EMUNAND|DRV_IMAGE)); 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)) if (!ShowPrompt(true, "Entry not found: %s\nInject into %s instead?", dest, dvfile.name))
return false; return false;
snprintf(dest, 255, "%s/%s", destdir, dvfile.name);
} else if (dvfile.size != osize) { // handling for differing sizes } else if (dvfile.size != osize) { // handling for differing sizes
char deststr[36 + 1]; char deststr[36 + 1];
char origstr[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 // 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))) { (!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 // the copy process takes place here
if (!ShowProgress(0, 0, orig)) return false; if (!ShowProgress(0, 0, orig)) return false;
if (vfile.flags & VFLAG_DIR) { // processing folders 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 // the copy process takes place here
if (!ShowProgress(0, 0, orig)) return false; if (!ShowProgress(0, 0, orig)) return false;
if (move && fa_stat(dest, NULL) != FR_OK) { // moving if dest not existing 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) { bool PathCopy(const char* destdir, const char* orig, u32* flags) {
if (!CheckWritePermissions(destdir)) return false; 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 ddrvtype = DriveType(destdir);
int odrvtype = DriveType(orig); int odrvtype = DriveType(orig);
if (!(ddrvtype & DRV_VIRTUAL)) { // FAT / virtual to FAT 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) { bool PathMove(const char* destdir, const char* orig, u32* flags) {
if (!CheckWritePermissions(destdir)) return false; 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 if (flags) *flags = *flags & ~(SKIP_CUR|OVERWRITE_CUR); // reset local flags
// moving only for regular FAT drives (= not alias drives) // moving only for regular FAT drives (= not alias drives)
if (!(DriveType(destdir) & DriveType(orig) & DRV_STDFAT)) { if (!(DriveType(destdir) & DriveType(orig) & DRV_STDFAT)) {
@ -718,8 +733,9 @@ bool PathDeleteWorker(char* fpath) {
bool PathDelete(const char* path) { bool PathDelete(const char* path) {
char fpath[256]; // 256 is the maximum length of a full 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); strncpy(fpath, path, 256);
ShowString("Deleting files, please wait...");
return PathDeleteWorker(fpath); 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 npath[256]; // 256 is the maximum length of a full path
char* oldname = strrchr(path, '/'); char* oldname = strrchr(path, '/');
if (!CheckWritePermissions(path)) return false; if (!CheckDirWritePermissions(path)) return false;
if (!oldname) return false; if (!oldname) return false;
oldname++; oldname++;
strncpy(npath, path, oldname - path); strncpy(npath, path, oldname - path);

View File

@ -19,7 +19,8 @@
#define N_PANES 2 #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_SIDE_BAR COLOR_DARKGREY
#define COLOR_MARKED COLOR_TINTEDYELLOW #define COLOR_MARKED COLOR_TINTEDYELLOW
#define COLOR_FILE COLOR_TINTEDGREEN #define COLOR_FILE COLOR_TINTEDGREEN
@ -1224,7 +1225,6 @@ u32 GodMode() {
if (n_marked) { if (n_marked) {
if (ShowPrompt(true, "Delete %u path(s)?", n_marked)) { if (ShowPrompt(true, "Delete %u path(s)?", n_marked)) {
u32 n_errors = 0; u32 n_errors = 0;
ShowString("Deleting files, please wait...");
for (u32 c = 0; c < current_dir->n_entries; c++) for (u32 c = 0; c < current_dir->n_entries; c++)
if (current_dir->entry[c].marked && !PathDelete(current_dir->entry[c].path)) if (current_dir->entry[c].marked && !PathDelete(current_dir->entry[c].path))
n_errors++; n_errors++;
@ -1235,7 +1235,6 @@ u32 GodMode() {
char namestr[36+1]; char namestr[36+1];
TruncateString(namestr, curr_entry->name, 28, 12); TruncateString(namestr, curr_entry->name, 28, 12);
if (ShowPrompt(true, "Delete \"%s\"?", namestr)) { if (ShowPrompt(true, "Delete \"%s\"?", namestr)) {
ShowString("Deleting %s\nPlease wait...", namestr);
if (!PathDelete(curr_entry->path)) if (!PathDelete(curr_entry->path))
ShowPrompt(false, "Failed deleting:\n%s", namestr); ShowPrompt(false, "Failed deleting:\n%s", namestr);
ClearScreenF(true, false, COLOR_STD_BG); ClearScreenF(true, false, COLOR_STD_BG);

View File

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