diff --git a/arm9/source/filesys/fsperm.c b/arm9/source/filesys/fsperm.c index 16be16b..9a9af05 100644 --- a/arm9/source/filesys/fsperm.c +++ b/arm9/source/filesys/fsperm.c @@ -24,6 +24,16 @@ bool CheckWritePermissions(const char* path) { int drvtype = DriveType(path); u32 perm; + // create a standardized path string + char path_f[256]; + char* p = (char*) path; + path_f[255] = '\0'; + for (u32 i = 0; i < 255; i++) { + path_f[i] = *(p++); + while ((path_f[i] == '/') && (*p == '/')) p++; + if (!path_f[i]) break; + } + // check mounted image write permissions if ((drvtype & DRV_IMAGE) && !CheckWritePermissions(GetMountPath())) return false; // endless loop when mounted file inside image, but not possible @@ -43,11 +53,11 @@ bool CheckWritePermissions(const char* path) { 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 (strncasecmp(path, path_lvl3[i], 256) == 0) lvl = 3; + if (strncasecmp(path_f, path_lvl3[i], 256) == 0) lvl = 3; for (u32 i = 0; (i < sizeof(path_lvl2) / sizeof(char*)) && (lvl < 2); i++) - if (strncasecmp(path, path_lvl2[i], 256) == 0) lvl = 2; + if (strncasecmp(path_f, path_lvl2[i], 256) == 0) lvl = 2; for (u32 i = 0; (i < sizeof(path_lvl1) / sizeof(char*)) && (lvl < 1); i++) - if (strncasecmp(path, path_lvl1[i], 256) == 0) lvl = 1; + if (strncasecmp(path_f, path_lvl1[i], 256) == 0) lvl = 1; } if (!IS_UNLOCKED) { // changed SysNAND permission levels on locked systems if ((drvtype & DRV_CTRNAND) || (lvl == 2)) lvl = 3; @@ -60,7 +70,7 @@ bool CheckWritePermissions(const char* path) { 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 (strncasecmp(path, path_lvl1[i], 256) == 0) lvl = 1; + if (strncasecmp(path_f, path_lvl1[i], 256) == 0) lvl = 1; } perm = perms[lvl]; snprintf(area_name, 16, "EmuNAND (lvl%lu)", lvl); @@ -82,7 +92,7 @@ bool CheckWritePermissions(const char* path) { } else if (drvtype & DRV_MEMORY) { perm = PERM_MEMORY; snprintf(area_name, 16, "memory areas"); - } else if (strncasecmp(path, "0:/Nintendo 3DS", 15) == 0) { // this check could be better + } else if (strncasecmp(path_f, "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) { diff --git a/arm9/source/filesys/sddata.c b/arm9/source/filesys/sddata.c index 634975d..0bdef29 100644 --- a/arm9/source/filesys/sddata.c +++ b/arm9/source/filesys/sddata.c @@ -34,8 +34,9 @@ int alias_num (const TCHAR* path) { void dealias_path (TCHAR* alias, const TCHAR* path) { int num = alias_num(path); + u32 p_offs = (path[2] == '/' && ((path[3] == '/') || (path[3] == '\0'))) ? 3 : 2; if (num >= 0) // set alias (alias is assumed to be 256 byte) - snprintf(alias, 256, "%s%s", alias_path[num], path + 2); + snprintf(alias, 256, "%s%s", alias_path[num], path + p_offs); else strncpy(alias, path, 256); } diff --git a/arm9/source/utils/nandcmac.c b/arm9/source/utils/nandcmac.c index cc0292e..1e617f5 100644 --- a/arm9/source/utils/nandcmac.c +++ b/arm9/source/utils/nandcmac.c @@ -387,7 +387,7 @@ u32 CheckFixCmdCmac(const char* path, bool fix) { } } - // if fixing is enable, write back cmd file + // if fixing is enabled, write back cmd file if (fix && fixed && CheckWritePermissions(path) && (fvx_qwrite(path, cmd_data, 0, cmd_size, NULL) != FR_OK)) { free(cmd_data); @@ -432,7 +432,20 @@ u32 RecursiveFixFileCmacWorker(char* path) { } u32 RecursiveFixFileCmac(const char* path) { - char lpath[256] = { 0 }; - strncpy(lpath, path, 255); + // create a fixed up local path + // (this is highly path sensitive) + char lpath[256]; + char* p = (char*) path; + lpath[255] = '\0'; + for (u32 i = 0; i < 255; i++) { + lpath[i] = *(p++); + while ((lpath[i] == '/') && (*p == '/')) p++; + if (!lpath[i]) { + if (i && (lpath[i-1] == '/')) + lpath[i-1] = '\0'; + break; + } + } + return RecursiveFixFileCmacWorker(lpath); }