diff --git a/source/common.h b/source/common.h index 889e512..0ea88cd 100644 --- a/source/common.h +++ b/source/common.h @@ -38,7 +38,7 @@ (((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v)) // GodMode9 version -#define VERSION "0.7.4" +#define VERSION "0.7.5" // buffer area defines (in use by godmode.c) #define DIR_BUFFER (0x21000000) diff --git a/source/fatfs/image.c b/source/fatfs/image.c index 3a92a7f..614b544 100644 --- a/source/fatfs/image.c +++ b/source/fatfs/image.c @@ -56,37 +56,6 @@ u32 GetMountState(void) { return mount_state; } -u32 IdentifyImage(const char* path) { - u8 header[0x200]; - FIL file; - if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) - return 0; - f_lseek(&file, 0); - f_sync(&file); - UINT fsize = f_size(&file); - UINT bytes_read; - if ((f_read(&file, header, 0x200, &bytes_read) != FR_OK) || (bytes_read != 0x200)) { - f_close(&file); - return 0; - } - f_close(&file); - if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) && - (getbe64(header + 0x108) == (u64) 0) && (fsize >= 0x8FC8000)) { - return IMG_NAND; - } else if (getbe16(header + 0x1FE) == 0x55AA) { // migt be FAT or MBR - if ((strncmp((char*) header + 0x36, "FAT12 ", 8) == 0) || (strncmp((char*) header + 0x36, "FAT16 ", 8) == 0) || - (strncmp((char*) header + 0x36, "FAT ", 8) == 0) || (strncmp((char*) header + 0x52, "FAT32 ", 8) == 0)) { - return IMG_FAT; // this is an actual FAT header - } else if (((getle32(header + 0x1BE + 0x8) + getle32(header + 0x1BE + 0xC)) < (fsize / 0x200)) && // check file size - (getle32(header + 0x1BE + 0x8) > 0) && (getle32(header + 0x1BE + 0xC) >= 0x800) && // check first partition sanity - ((header[0x1BE + 0x4] == 0x1) || (header[0x1BE + 0x4] == 0x4) || (header[0x1BE + 0x4] == 0x6) || // filesystem type - (header[0x1BE + 0x4] == 0xB) || (header[0x1BE + 0x4] == 0xC) || (header[0x1BE + 0x4] == 0xE))) { - return IMG_FAT; // this might be an MBR -> give it the benefit of doubt - } - } - return 0; -} - u32 MountRamDrive(void) { if (mount_state && (mount_state != IMG_RAMDRV)) f_close(&mount_file); @@ -101,14 +70,16 @@ u32 MountRamDrive(void) { } u32 MountImage(const char* path) { + u32 type = IdentifyFileType(path); if (mount_state) { if (mount_state != IMG_RAMDRV) f_close(&mount_file); mount_state = 0; } - if (!path || !IdentifyImage(path)) return 0; + if (!path || !type) return 0; + if ((type != IMG_FAT) && (type != IMG_NAND)) return 0; if (f_open(&mount_file, path, FA_READ | FA_WRITE | FA_OPEN_EXISTING) != FR_OK) return 0; f_lseek(&mount_file, 0); f_sync(&mount_file); - return (mount_state = IdentifyImage(path)); + return (mount_state = type); } diff --git a/source/fatfs/image.h b/source/fatfs/image.h index 98fd196..b6e1472 100644 --- a/source/fatfs/image.h +++ b/source/fatfs/image.h @@ -1,10 +1,9 @@ #pragma once #include "common.h" +#include "filetype.h" -#define IMG_FAT 1 -#define IMG_NAND 2 -#define IMG_RAMDRV 3 +#define IMG_RAMDRV 100 // just so there are no conflicts with file type defines int ReadImageSectors(u8* buffer, u32 sector, u32 count); int WriteImageSectors(const u8* buffer, u32 sector, u32 count); @@ -12,6 +11,5 @@ int SyncImage(void); u64 GetMountSize(void); u32 GetMountState(void); -u32 IdentifyImage(const char* path); u32 MountRamDrive(void); u32 MountImage(const char* path); diff --git a/source/filetype.c b/source/filetype.c new file mode 100644 index 0000000..972f5e7 --- /dev/null +++ b/source/filetype.c @@ -0,0 +1,35 @@ +#include "filetype.h" +#include "ff.h" + +u32 IdentifyFileType(const char* path) { + u8 header[0x200]; // minimum required size + FIL file; + if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) + return 0; + f_lseek(&file, 0); + f_sync(&file); + UINT fsize = f_size(&file); + UINT bytes_read; + if ((f_read(&file, header, 0x200, &bytes_read) != FR_OK) || (bytes_read != 0x200)) { + f_close(&file); + return 0; + } + f_close(&file); + + if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) && + (getbe64(header + 0x108) == (u64) 0) && (fsize >= 0x8FC8000)) { + return IMG_NAND; // NAND image + } else if (getbe16(header + 0x1FE) == 0x55AA) { // migt be FAT or MBR + if ((strncmp((char*) header + 0x36, "FAT12 ", 8) == 0) || (strncmp((char*) header + 0x36, "FAT16 ", 8) == 0) || + (strncmp((char*) header + 0x36, "FAT ", 8) == 0) || (strncmp((char*) header + 0x52, "FAT32 ", 8) == 0)) { + return IMG_FAT; // this is an actual FAT header + } else if (((getle32(header + 0x1BE + 0x8) + getle32(header + 0x1BE + 0xC)) < (fsize / 0x200)) && // check file size + (getle32(header + 0x1BE + 0x8) > 0) && (getle32(header + 0x1BE + 0xC) >= 0x800) && // check first partition sanity + ((header[0x1BE + 0x4] == 0x1) || (header[0x1BE + 0x4] == 0x4) || (header[0x1BE + 0x4] == 0x6) || // filesystem type + (header[0x1BE + 0x4] == 0xB) || (header[0x1BE + 0x4] == 0xC) || (header[0x1BE + 0x4] == 0xE))) { + return IMG_FAT; // this might be an MBR -> give it the benefit of doubt + } + } // more to come + + return 0; +} diff --git a/source/filetype.h b/source/filetype.h new file mode 100644 index 0000000..2e2d053 --- /dev/null +++ b/source/filetype.h @@ -0,0 +1,8 @@ +#pragma once + +#include "common.h" + +#define IMG_FAT 1 +#define IMG_NAND 2 + +u32 IdentifyFileType(const char* path); diff --git a/source/godmode.c b/source/godmode.c index a342406..c49ff91 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -622,7 +622,7 @@ u32 GodMode() { const char* optionstr[5]; u32 n_opt = 2; - u32 file_type = IdentifyImage(curr_entry->path); + u32 file_type = IdentifyFileType(curr_entry->path); u32 file_drvtype = DriveType(curr_entry->path); int injectable = ((clipboard->n_entries == 1) && (clipboard->entry[0].type == T_FILE) &&