diff --git a/source/common.h b/source/common.h index 5a1b785..70f0519 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.8.6" +#define VERSION "0.8.7" // input / output paths #define INPUT_PATHS "0:", "0:/files9", "0:/Decrypt9" diff --git a/source/fatfs/diskio.c b/source/fatfs/diskio.c index b681256..44ead3f 100644 --- a/source/fatfs/diskio.c +++ b/source/fatfs/diskio.c @@ -9,6 +9,7 @@ #include "diskio.h" /* FatFs lower layer API */ #include "image.h" +#include "ramdrive.h" #include "nand.h" #include "sdmmc.h" @@ -18,6 +19,7 @@ #define TYPE_IMGNAND NAND_IMGNAND #define TYPE_SDCARD (1<<4) #define TYPE_IMAGE (1<<5) +#define TYPE_RAMDRV (1<<6) #define SUBTYPE_CTRN 0 #define SUBTYPE_CTRN_N 1 @@ -37,7 +39,7 @@ typedef struct { BYTE keyslot; } SubtypeDesc; -FATpartition DriveInfo[11] = { +FATpartition DriveInfo[12] = { { TYPE_SDCARD, SUBTYPE_NONE }, // 0 - SDCARD { TYPE_SYSNAND, SUBTYPE_CTRN }, // 1 - SYSNAND CTRNAND { TYPE_SYSNAND, SUBTYPE_TWLN }, // 2 - SYSNAND TWLN @@ -48,7 +50,8 @@ FATpartition DriveInfo[11] = { { TYPE_IMGNAND, SUBTYPE_CTRN }, // 7 - IMGNAND CTRNAND { TYPE_IMGNAND, SUBTYPE_TWLN }, // 8 - IMGNAND TWLN { TYPE_IMGNAND, SUBTYPE_TWLP }, // 9 - IMGNAND TWLP - { TYPE_IMAGE, SUBTYPE_NONE } // X - IMAGE + { TYPE_IMAGE, SUBTYPE_NONE }, // X - IMAGE + { TYPE_RAMDRV, SUBTYPE_NONE } // Y - RAMDRIVE }; SubtypeDesc SubTypes[5] = { @@ -75,7 +78,7 @@ static inline BYTE get_partition_type( ) { if ((pdrv >= 7) && !nand_type_img) // special handling for FAT images - return (pdrv == 7) ? TYPE_IMAGE : TYPE_NONE; + return (pdrv == 7) ? TYPE_IMAGE : (pdrv == 9) ? TYPE_RAMDRV : TYPE_NONE; return DriveInfo[pdrv].type; } @@ -140,10 +143,12 @@ DSTATUS disk_initialize ( if (!nand_type_emu) return STA_NOINIT|STA_NODISK; } else if (pdrv < 10) { UINT mount_state = GetMountState(); - if ((mount_state != IMG_NAND) && (mount_state != IMG_FAT) && (mount_state != IMG_RAMDRV)) - return STA_NOINIT|STA_NODISK; - nand_type_img = CheckNandType(NAND_IMGNAND); - if ((!nand_type_img) && (pdrv != 7)) return STA_NOINIT|STA_NODISK; + nand_type_img = (mount_state == IMG_NAND) ? CheckNandType(NAND_IMGNAND) : 0; + if (!nand_type_img) { + if ((pdrv == 7) && (mount_state != IMG_FAT)) return STA_NOINIT|STA_NODISK; + else if (pdrv == 8) return STA_NOINIT|STA_NODISK; + else if (pdrv == 9) InitRamDrive(); + } } return RES_OK; } @@ -172,6 +177,9 @@ DRESULT disk_read ( } else if (type == TYPE_IMAGE) { if (ReadImageSectors(buff, sector, count)) return RES_PARERR; + } else if (type == TYPE_RAMDRV) { + if (ReadRamDriveSectors(buff, sector, count)) + return RES_PARERR; } else { SubtypeDesc* subtype = get_subtype_desc(pdrv); BYTE keyslot = subtype->keyslot; @@ -209,6 +217,9 @@ DRESULT disk_write ( } else if (type == TYPE_IMAGE) { if (WriteImageSectors(buff, sector, count)) return RES_PARERR; + } else if (type == TYPE_RAMDRV) { + if (WriteRamDriveSectors(buff, sector, count)) + return RES_PARERR; } else { SubtypeDesc* subtype = get_subtype_desc(pdrv); BYTE keyslot = subtype->keyslot; @@ -249,12 +260,14 @@ DRESULT disk_ioctl ( *((DWORD*) buff) = getMMCDevice(1)->total_size; } else if (type == TYPE_IMAGE) { // FAT image *((DWORD*) buff) = GetMountSize() / 0x200; + } else if (type == TYPE_RAMDRV) { // RAM drive + *((DWORD*) buff) = GetRamDriveSize() / 0x200; } else if (type != TYPE_NONE) { // NAND *((DWORD*) buff) = get_subtype_desc(pdrv)->size; } return RES_OK; case GET_BLOCK_SIZE: - *((DWORD*) buff) = (type == TYPE_IMAGE) ? 0x1 : 0x2000; + *((DWORD*) buff) = ((type == TYPE_IMAGE) || (type == TYPE_RAMDRV)) ? 0x1 : 0x2000; return RES_OK; case CTRL_SYNC: if ((type == TYPE_IMAGE) || (type == TYPE_IMGNAND)) diff --git a/source/fatfs/image.c b/source/fatfs/image.c index 42cb2ac..d9e09d3 100644 --- a/source/fatfs/image.c +++ b/source/fatfs/image.c @@ -1,11 +1,7 @@ #include "image.h" #include "sddata.h" -#include "platform.h" #include "ff.h" -static u8* ramdrv_buffer = NULL; -static u32 ramdrv_size = 0; - static FIL mount_file; static u32 mount_state = 0; @@ -16,11 +12,6 @@ int ReadImageBytes(u8* buffer, u64 offset, u64 count) { UINT bytes_read; UINT ret; if (!count) return -1; - if (mount_state == IMG_RAMDRV) { - if ((offset + count) > ramdrv_size) return -1; - memcpy(buffer, ramdrv_buffer + (offset), count); - return 0; - } if (!mount_state) return FR_INVALID_OBJECT; if (f_tell(&mount_file) != offset) { if (f_size(&mount_file) < offset) return -1; @@ -34,11 +25,6 @@ int WriteImageBytes(const u8* buffer, u64 offset, u64 count) { UINT bytes_written; UINT ret; if (!count) return -1; - if (mount_state == IMG_RAMDRV) { - if ((offset + count) > ramdrv_size) return -1; - memcpy(ramdrv_buffer + (offset), buffer, count); - return 0; - } if (!mount_state) return FR_INVALID_OBJECT; if (f_tell(&mount_file) != offset) f_lseek(&mount_file, offset); @@ -55,13 +41,11 @@ int WriteImageSectors(const u8* buffer, u32 sector, u32 count) { } int SyncImage(void) { - return (mount_state == IMG_RAMDRV) ? FR_OK : - mount_state ? f_sync(&mount_file) : FR_INVALID_OBJECT; + return mount_state ? f_sync(&mount_file) : FR_INVALID_OBJECT; } u64 GetMountSize(void) { - return (mount_state == IMG_RAMDRV) ? ramdrv_size : - mount_state ? f_size(&mount_file) : 0; + return mount_state ? f_size(&mount_file) : 0; } u32 GetMountState(void) { @@ -72,24 +56,10 @@ const char* GetMountPath(void) { return mount_path; } -u32 MountRamDrive(void) { - if (mount_state && (mount_state != IMG_RAMDRV)) - fx_close(&mount_file); - if (GetUnitPlatform() == PLATFORM_3DS) { - ramdrv_buffer = RAMDRV_BUFFER_O3DS; - ramdrv_size = RAMDRV_SIZE_O3DS; - } else { - ramdrv_buffer = RAMDRV_BUFFER_N3DS; - ramdrv_size = RAMDRV_SIZE_N3DS; - } - *mount_path = 0; - return (mount_state = IMG_RAMDRV); -} - u32 MountImage(const char* path) { u32 type = (path) ? IdentifyFileType(path) : 0; if (mount_state) { - if (mount_state != IMG_RAMDRV) fx_close(&mount_file); + fx_close(&mount_file); mount_state = 0; *mount_path = 0; } diff --git a/source/fatfs/image.h b/source/fatfs/image.h index 12af93d..63a9023 100644 --- a/source/fatfs/image.h +++ b/source/fatfs/image.h @@ -3,8 +3,6 @@ #include "common.h" #include "filetype.h" -#define IMG_RAMDRV 100 // just so there are no conflicts with file type defines - int ReadImageBytes(u8* buffer, u64 offset, u64 count); int WriteImageBytes(const u8* buffer, u64 offset, u64 count); int ReadImageSectors(u8* buffer, u32 sector, u32 count); @@ -14,5 +12,4 @@ int SyncImage(void); u64 GetMountSize(void); u32 GetMountState(void); const char* GetMountPath(void); -u32 MountRamDrive(void); u32 MountImage(const char* path); diff --git a/source/fatfs/ramdrive.c b/source/fatfs/ramdrive.c new file mode 100644 index 0000000..9b84004 --- /dev/null +++ b/source/fatfs/ramdrive.c @@ -0,0 +1,36 @@ +#include "ramdrive.h" +#include "platform.h" + +static u8* ramdrv_buffer = NULL; +static u32 ramdrv_size = 0; + +int ReadRamDriveSectors(u8* buffer, u32 sector, u32 count) { + u64 offset = sector * 0x200; + u64 btr = count * 0x200; + if (!ramdrv_buffer) return -1; + if ((offset + btr) > ramdrv_size) return -1; + memcpy(buffer, ramdrv_buffer + offset, btr); + return 0; +} +int WriteRamDriveSectors(const u8* buffer, u32 sector, u32 count) { + u64 offset = sector * 0x200; + u64 btw = count * 0x200; + if (!ramdrv_buffer) return -1; + if ((offset + btw) > ramdrv_size) return -1; + memcpy(ramdrv_buffer + offset, buffer, btw); + return 0; +} + +u64 GetRamDriveSize(void) { + return ramdrv_size; +} + +void InitRamDrive(void) { + if (GetUnitPlatform() == PLATFORM_3DS) { + ramdrv_buffer = RAMDRV_BUFFER_O3DS; + ramdrv_size = RAMDRV_SIZE_O3DS; + } else { + ramdrv_buffer = RAMDRV_BUFFER_N3DS; + ramdrv_size = RAMDRV_SIZE_N3DS; + } +} \ No newline at end of file diff --git a/source/fatfs/ramdrive.h b/source/fatfs/ramdrive.h new file mode 100644 index 0000000..4a2d722 --- /dev/null +++ b/source/fatfs/ramdrive.h @@ -0,0 +1,8 @@ +#pragma once + +#include "common.h" + +int ReadRamDriveSectors(u8* buffer, u32 sector, u32 count); +int WriteRamDriveSectors(const u8* buffer, u32 sector, u32 count); +u64 GetRamDriveSize(void); +void InitRamDrive(void); diff --git a/source/fs/fsdrive.c b/source/fs/fsdrive.c index 03e76c4..85d8fe7 100644 --- a/source/fs/fsdrive.c +++ b/source/fs/fsdrive.c @@ -21,7 +21,7 @@ int DriveType(const char* path) { } else if ((pdrv >= 0) && (pdrv < NORM_FS)) { if (pdrv == 0) { type = DRV_FAT | DRV_SDCARD | DRV_STDFAT; - } else if ((pdrv == 7) && (GetMountState() == IMG_RAMDRV)) { + } 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; @@ -69,9 +69,10 @@ bool GetRootDirContentsWorker(DirStruct* contents) { if (!DriveType(drvnum[pdrv])) continue; // drive not available memset(entry->path, 0x00, 64); snprintf(entry->path + 0, 4, drvnum[pdrv]); - if ((pdrv == 7) && ((GetMountState() == IMG_FAT) || (GetMountState() == IMG_RAMDRV))) - snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], // FAT image / RAM drive special handling - (GetMountState() == IMG_FAT) ? "FAT IMAGE" : "RAMDRIVE"); + if ((pdrv == 7) && (GetMountState() == IMG_FAT)) // FAT image handling + snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], "FAT IMAGE"); + else if ((pdrv == 9) && (GetMountState() != IMG_NAND)) // RAM drive handling + snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], "RAMDRIVE"); else if (pdrv == 10) // Game drive special handling snprintf(entry->path + 4, 32, "[%s] %s %s", drvnum[pdrv], (GetMountState() == GAME_CIA ) ? "CIA" : diff --git a/source/fs/fsinit.c b/source/fs/fsinit.c index 04965c7..f193569 100644 --- a/source/fs/fsinit.c +++ b/source/fs/fsinit.c @@ -25,6 +25,11 @@ bool InitExtFS() { snprintf(fsname, 7, "%lu:", i); if (fs_mounted[i]) continue; fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); + if (!fs_mounted[i] && (i == NORM_FS - 1) && (GetMountState() != IMG_NAND)) { + f_mkfs(fsname, FM_ANY, 0, MAIN_BUFFER, MAIN_BUFFER_SIZE); // format ramdrive if required + f_mount(NULL, fsname, 1); + fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK); + } } SetupNandSdDrive("A:", "0:", "1:/private/movable.sed", 0); SetupNandSdDrive("B:", "0:", "4:/private/movable.sed", 1); @@ -53,23 +58,6 @@ bool InitImgFS(const char* path) { return true; } -bool InitRamDriveFS() { - u32 pdrv = NORM_FS - IMGN_FS; - char fsname[8]; - snprintf(fsname, 7, "%lu:", pdrv); - - InitImgFS(NULL); - MountRamDrive(); - fs_mounted[pdrv] = (f_mount(fs + pdrv, fsname, 1) == FR_OK); - if (!fs_mounted[pdrv] && (GetMountState() == IMG_RAMDRV)) { - f_mkfs(fsname, FM_ANY, 0, MAIN_BUFFER, MAIN_BUFFER_SIZE); // format ramdrive if required - f_mount(NULL, fsname, 1); - fs_mounted[pdrv] = (f_mount(fs + pdrv, fsname, 1) == FR_OK); - } - - return true; -} - void DeinitExtFS() { SetupNandSdDrive(NULL, NULL, NULL, 0); SetupNandSdDrive(NULL, NULL, NULL, 1); @@ -80,7 +68,7 @@ void DeinitExtFS() { f_mount(NULL, fsname, 1); fs_mounted[i] = false; } - if ((i == NORM_FS - IMGN_FS) && (GetMountState() != IMG_RAMDRV)) { // unmount image + if (i == NORM_FS - IMGN_FS) { // unmount image MountImage(NULL); InitVGameDrive(); } @@ -88,10 +76,8 @@ void DeinitExtFS() { } void DeinitSDCardFS() { - if (GetMountState() != IMG_RAMDRV) { - MountImage(NULL); - InitVGameDrive(); - } + MountImage(NULL); + InitVGameDrive(); if (fs_mounted[0]) { f_mount(NULL, "0:", 1); fs_mounted[0] = false; diff --git a/source/fs/fsinit.h b/source/fs/fsinit.h index 6ef4d2b..a400276 100644 --- a/source/fs/fsinit.h +++ b/source/fs/fsinit.h @@ -12,9 +12,6 @@ bool InitExtFS(); // mount and init image file system bool InitImgFS(const char* path); -// init RAM drive filesystem (unmounts image) -bool InitRamDriveFS(); - // deinitialize external filesystem void DeinitExtFS(); diff --git a/source/godmode.c b/source/godmode.c index 8415ec7..e076f23 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -139,8 +139,7 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c "L - MARK files (use with \x18\x19\x1A\x1B)\nX - DELETE / [+R] RENAME file(s)\nY - PASTE file(s) / [+R] CREATE dir\n") : ((GetWritePermissions() > PERM_BASE) ? "R+Y - Relock write permissions\nR+B - Unmount SD card\n" : "R+Y - Unlock write permissions\nR+B - Unmount SD card\n"), - (*curr_path) ? "" : ((GetMountState() == IMG_RAMDRV) ? "R+X - Unmount RAM drive\n" : - (GetMountState()) ? "R+X - Unmount image\n" : "R+X - Mount RAM drive\n"), + (*curr_path) ? "" : "R+X - Reinit filesystem\n", (*curr_path) ? "R+A - Search directory\n" : "R+A - Search drive\n", "R+L - Make a Screenshot\n", "R+\x1B\x1A - Switch to prev/next pane\n", @@ -652,10 +651,10 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur // auto select when there is only one option user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, pathstr) : n_opt; if (user_select == mount) { // -> mount file as image - if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & (DRV_IMAGE|DRV_RAMDRIVE))) + if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE)) clipboard->n_entries = 0; // remove last mounted image clipboard entries InitImgFS(curr_entry->path); - if (!(DriveType("7:")||DriveType("8:")||DriveType("9:")||DriveType("G:"))) { + if (!(DriveType("7:")||DriveType("G:"))) { ShowPrompt(false, "Mounting image: failed"); InitImgFS(NULL); } else { @@ -663,7 +662,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur *current_path = '\0'; GetDirContents(current_dir, current_path); for (u32 i = 0; i < current_dir->n_entries; i++) { - if (strspn(current_dir->entry[i].path, "789GI") == 0) + if (strspn(current_dir->entry[i].path, "7GI") == 0) continue; strncpy(current_path, current_dir->entry[i].path, 256); GetDirContents(current_dir, current_path); @@ -937,11 +936,14 @@ u32 GodMode() { // highly specific commands if (!*current_path) { // in the root folder... - if (switched && (pad_state & BUTTON_X)) { // unmount image - if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & (DRV_IMAGE|DRV_RAMDRIVE))) + if (switched && (pad_state & BUTTON_X)) { // reinit file system / unmount image + if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE)) clipboard->n_entries = 0; // remove last mounted image clipboard entries - if (!GetMountState()) InitRamDriveFS(); - else InitImgFS(NULL); + DeinitExtFS(); + DeinitSDCardFS(); + InitSDCardFS(); + InitExtFS(); + ClearScreenF(false, true, COLOR_STD_BG); GetDirContents(current_dir, current_path); } else if (switched && (pad_state & BUTTON_Y)) { SetWritePermissions((GetWritePermissions() > PERM_BASE) ? PERM_BASE : PERM_ALL, false);