forked from Mirror/GodMode9
Persistent RAMdrive, not coupled to image handling
This commit is contained in:
parent
236e037229
commit
3b60fe2332
@ -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"
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
36
source/fatfs/ramdrive.c
Normal file
36
source/fatfs/ramdrive.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
8
source/fatfs/ramdrive.h
Normal file
8
source/fatfs/ramdrive.h
Normal file
@ -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);
|
@ -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" :
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user