diff --git a/source/fs.c b/source/fs.c index 868d88f..cb29598 100644 --- a/source/fs.c +++ b/source/fs.c @@ -52,14 +52,19 @@ void DeinitFS() { } } -bool CheckWritePermissions(const char* path) { - u32 pdrv = (*path) - '0'; - - if ((pdrv > 6) || (*(path+1) != ':')) { +int PathToNumFS(const char* path) { + int fsnum = *path - (int) '0'; + if ((fsnum < 0) || (fsnum >= MAX_FS) || (path[1] != ':')) { ShowPrompt(false, "Invalid path"); - return false; + return -1; } - + return fsnum; +} + +bool CheckWritePermissions(const char* path) { + int pdrv = PathToNumFS(path); + if (pdrv < 0) return false; + if ((pdrv >= 1) && (pdrv <= 3) && (write_permission_level < 3)) { if (ShowPrompt(true, "Writing to the SysNAND is locked!\nUnlock it now?")) return SetWritePermissions(3); @@ -465,25 +470,28 @@ uint64_t GetFreeSpace(const char* path) DWORD free_clusters; FATFS *fs_ptr; char fsname[4] = { '\0' }; - int fsnum = -1; + int pdrv = PathToNumFS(path); + if (pdrv < 0) return -1; - strncpy(fsname, path, 2); - fsnum = *fsname - (int) '0'; - if ((fsnum < 0) || (fsnum >= 7) || (fsname[1] != ':')) - return -1; + snprintf(fsname, 3, "%i:", pdrv); if (f_getfree(fsname, &free_clusters, &fs_ptr) != FR_OK) return -1; - return (uint64_t) free_clusters * fs[fsnum].csize * _MAX_SS; + return (uint64_t) free_clusters * fs[pdrv].csize * _MAX_SS; } uint64_t GetTotalSpace(const char* path) { - int fsnum = -1; + int pdrv = PathToNumFS(path); + if (pdrv < 0) return -1; - fsnum = *path - (int) '0'; - if ((fsnum < 0) || (fsnum >= 7) || (path[1] != ':')) - return -1; - - return (uint64_t) (fs[fsnum].n_fatent - 2) * fs[fsnum].csize * _MAX_SS; + return (uint64_t) (fs[pdrv].n_fatent - 2) * fs[pdrv].csize * _MAX_SS; +} + +uint64_t GetPartitionOffsetSector(const char* path) +{ + int pdrv = PathToNumFS(path); + if (pdrv < 0) return -1; + + return (uint64_t) fs[pdrv].fatbase; } diff --git a/source/fs.h b/source/fs.h index 2fb456f..32d0d14 100644 --- a/source/fs.h +++ b/source/fs.h @@ -67,5 +67,11 @@ uint64_t GetFreeSpace(const char* path); /** Gets total spacein filesystem in bytes */ 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); + /** Helper function for copying DirEntry structs */ void DirEntryCpy(DirEntry* dest, const DirEntry* orig); diff --git a/source/godmode.c b/source/godmode.c index 0a97043..d9de023 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -146,6 +146,7 @@ u32 GodMode() { if (!ShowPrompt(true, "Initialising SD card failed! Retry?")) return exit_mode; } + InitEmuNandBase(); InitNandCrypto(); InitNandFS(); @@ -193,6 +194,7 @@ u32 GodMode() { if (!ShowPrompt(true, "Reinitialising SD card failed! Retry?")) return exit_mode; } + InitEmuNandBase(); InitNandFS(); GetDirContents(current_dir, current_path); cursor = 0; diff --git a/source/nand/nand.c b/source/nand/nand.c index 86ea2eb..5ac5d20 100644 --- a/source/nand/nand.c +++ b/source/nand/nand.c @@ -165,6 +165,23 @@ u8 CheckNandType(bool check_emunand) return NAND_TYPE_UNK; } +bool InitEmuNandBase(void) +{ + if (GetPartitionOffsetSector("0:") <= getMMCDevice(0)->total_size) + return false; + + emunand_base_sector = 0x000000; // GW type EmuNAND + if (CheckNandType(true) != NAND_TYPE_UNK) + return true; + + emunand_base_sector = 0x000001; // RedNAND type EmuNAND + if (CheckNandType(true) != NAND_TYPE_UNK) + return true; + + emunand_base_sector = 0x000000; + return false; +} + u32 GetEmuNandBase(void) { return emunand_base_sector; diff --git a/source/nand/nand.h b/source/nand/nand.h index 42179df..9faad22 100644 --- a/source/nand/nand.h +++ b/source/nand/nand.h @@ -15,6 +15,7 @@ int WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, bool u8 CheckNandType(bool check_emunand); +bool InitEmuNandBase(void); u32 GetEmuNandBase(void); u32 SwitchEmuNandBase(int start_sector);