diff --git a/source/common/common.h b/source/common/common.h index 39a3f3e..b869373 100644 --- a/source/common/common.h +++ b/source/common/common.h @@ -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" diff --git a/source/common/ui.c b/source/common/ui.c index 2eeb6a7..b466963 100644 --- a/source/common/ui.c +++ b/source/common/ui.c @@ -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; diff --git a/source/common/ui.h b/source/common/ui.h index 61aa4c9..1d99ab8 100644 --- a/source/common/ui.h +++ b/source/common/ui.h @@ -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) diff --git a/source/fs/fsdrive.c b/source/fs/fsdrive.c index 4a0c0f7..d129efe 100644 --- a/source/fs/fsdrive.c +++ b/source/fs/fsdrive.c @@ -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; diff --git a/source/fs/fsdrive.h b/source/fs/fsdrive.h index 5d31741..82d3364 100644 --- a/source/fs/fsdrive.h +++ b/source/fs/fsdrive.h @@ -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", \ diff --git a/source/fs/fsperm.c b/source/fs/fsperm.c index dd8e109..b273314 100644 --- a/source/fs/fsperm.c +++ b/source/fs/fsperm.c @@ -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: diff --git a/source/fs/fsperm.h b/source/fs/fsperm.h index 8c537d7..782f291 100644 --- a/source/fs/fsperm.h +++ b/source/fs/fsperm.h @@ -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); diff --git a/source/fs/fsutil.c b/source/fs/fsutil.c index 0ac9dda..35fe4a8 100644 --- a/source/fs/fsutil.c +++ b/source/fs/fsutil.c @@ -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); diff --git a/source/godmode.c b/source/godmode.c index 84139dd..ae63c9b 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -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); diff --git a/source/nand/nandutil.c b/source/nand/nandutil.c index ac56714..70a164a 100644 --- a/source/nand/nandutil.c +++ b/source/nand/nandutil.c @@ -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)