Allow mounting images from any FAT based drive

This commit is contained in:
d0k3 2016-11-29 16:33:56 +01:00
parent 4df338b8a0
commit 9af01de7dc
6 changed files with 45 additions and 20 deletions

View File

@ -38,7 +38,7 @@
(((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v)) (((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v))
// GodMode9 version // GodMode9 version
#define VERSION "0.7.8" #define VERSION "0.7.9"
// buffer area defines (in use by godmode.c) // buffer area defines (in use by godmode.c)
#define DIR_BUFFER (0x21000000) #define DIR_BUFFER (0x21000000)

View File

@ -1,4 +1,5 @@
#include "image.h" #include "image.h"
#include "sddata.h"
#include "platform.h" #include "platform.h"
#include "ff.h" #include "ff.h"
@ -8,6 +9,8 @@ static u32 ramdrv_size = 0;
static FIL mount_file; static FIL mount_file;
static u32 mount_state = 0; static u32 mount_state = 0;
static char mount_path[256] = { 0 };
int ReadImageBytes(u8* buffer, u32 offset, u32 count) { int ReadImageBytes(u8* buffer, u32 offset, u32 count) {
UINT bytes_read; UINT bytes_read;
@ -23,7 +26,7 @@ int ReadImageBytes(u8* buffer, u32 offset, u32 count) {
if (f_size(&mount_file) < offset) return -1; if (f_size(&mount_file) < offset) return -1;
f_lseek(&mount_file, offset); f_lseek(&mount_file, offset);
} }
ret = f_read(&mount_file, buffer, count, &bytes_read); ret = fx_read(&mount_file, buffer, count, &bytes_read);
return (ret != 0) ? (int) ret : (bytes_read != count) ? -1 : 0; return (ret != 0) ? (int) ret : (bytes_read != count) ? -1 : 0;
} }
@ -39,7 +42,7 @@ int WriteImageBytes(const u8* buffer, u32 offset, u32 count) {
if (!mount_state) return FR_INVALID_OBJECT; if (!mount_state) return FR_INVALID_OBJECT;
if (f_tell(&mount_file) != offset) if (f_tell(&mount_file) != offset)
f_lseek(&mount_file, offset); f_lseek(&mount_file, offset);
ret = f_write(&mount_file, buffer, count, &bytes_written); ret = fx_write(&mount_file, buffer, count, &bytes_written);
return (ret != 0) ? (int) ret : (bytes_written != count) ? -1 : 0; return (ret != 0) ? (int) ret : (bytes_written != count) ? -1 : 0;
} }
@ -65,9 +68,13 @@ u32 GetMountState(void) {
return mount_state; return mount_state;
} }
const char* GetMountPath(void) {
return mount_path;
}
u32 MountRamDrive(void) { u32 MountRamDrive(void) {
if (mount_state && (mount_state != IMG_RAMDRV)) if (mount_state && (mount_state != IMG_RAMDRV))
f_close(&mount_file); fx_close(&mount_file);
if (GetUnitPlatform() == PLATFORM_3DS) { if (GetUnitPlatform() == PLATFORM_3DS) {
ramdrv_buffer = RAMDRV_BUFFER_O3DS; ramdrv_buffer = RAMDRV_BUFFER_O3DS;
ramdrv_size = RAMDRV_SIZE_O3DS; ramdrv_size = RAMDRV_SIZE_O3DS;
@ -75,19 +82,22 @@ u32 MountRamDrive(void) {
ramdrv_buffer = RAMDRV_BUFFER_N3DS; ramdrv_buffer = RAMDRV_BUFFER_N3DS;
ramdrv_size = RAMDRV_SIZE_N3DS; ramdrv_size = RAMDRV_SIZE_N3DS;
} }
*mount_path = 0;
return (mount_state = IMG_RAMDRV); return (mount_state = IMG_RAMDRV);
} }
u32 MountImage(const char* path) { u32 MountImage(const char* path) {
u32 type = IdentifyFileType(path); u32 type = (path) ? IdentifyFileType(path) : 0;
if (mount_state) { if (mount_state) {
if (mount_state != IMG_RAMDRV) f_close(&mount_file); if (mount_state != IMG_RAMDRV) fx_close(&mount_file);
mount_state = 0; mount_state = 0;
*mount_path = 0;
} }
if (!path || !type) return 0; if (!type) return 0;
if (f_open(&mount_file, path, FA_READ | FA_WRITE | FA_OPEN_EXISTING) != FR_OK) if (fx_open(&mount_file, path, FA_READ | FA_WRITE | FA_OPEN_EXISTING) != FR_OK)
return 0; return 0;
f_lseek(&mount_file, 0); f_lseek(&mount_file, 0);
f_sync(&mount_file); f_sync(&mount_file);
strncpy(mount_path, path, 255);
return (mount_state = type); return (mount_state = type);
} }

View File

@ -13,5 +13,6 @@ int SyncImage(void);
u64 GetMountSize(void); u64 GetMountSize(void);
u32 GetMountState(void); u32 GetMountState(void);
const char* GetMountPath(void);
u32 MountRamDrive(void); u32 MountRamDrive(void);
u32 MountImage(const char* path); u32 MountImage(const char* path);

View File

@ -1,21 +1,22 @@
#include "filetype.h" #include "filetype.h"
#include "sddata.h"
#include "game.h" #include "game.h"
#include "ff.h" #include "ff.h"
u32 IdentifyFileType(const char* path) { u32 IdentifyFileType(const char* path) {
u8 __attribute__((aligned(16))) header[0x200]; // minimum required size u8 __attribute__((aligned(16))) header[0x200]; // minimum required size
FIL file; FIL file;
if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) if (fx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return 0; return 0;
f_lseek(&file, 0); f_lseek(&file, 0);
f_sync(&file); f_sync(&file);
UINT fsize = f_size(&file); UINT fsize = f_size(&file);
UINT bytes_read; UINT bytes_read;
if ((f_read(&file, header, 0x200, &bytes_read) != FR_OK) || (bytes_read != 0x200)) { if ((fx_read(&file, header, 0x200, &bytes_read) != FR_OK) || (bytes_read != 0x200)) {
f_close(&file); fx_close(&file);
return 0; return 0;
} }
f_close(&file); fx_close(&file);
if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) && if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) &&
(getbe64(header + 0x108) == (u64) 0) && (fsize >= 0x8FC8000)) { (getbe64(header + 0x108) == (u64) 0) && (fsize >= 0x8FC8000)) {

View File

@ -221,6 +221,11 @@ bool CheckWritePermissions(const char* path) {
int drvtype = DriveType(path); int drvtype = DriveType(path);
u32 perm; u32 perm;
// check mounted image write permissions
if ((drvtype & DRV_IMAGE) && !CheckWritePermissions(GetMountPath()))
return false; // endless loop when mounted file inside image, but not possible
// check drive type, get permission type
if (drvtype & DRV_SYSNAND) { if (drvtype & DRV_SYSNAND) {
perm = PERM_SYSNAND; perm = PERM_SYSNAND;
snprintf(area_name, 16, "the SysNAND"); snprintf(area_name, 16, "the SysNAND");
@ -233,15 +238,15 @@ bool CheckWritePermissions(const char* path) {
} else if (drvtype & DRV_EMUNAND) { } else if (drvtype & DRV_EMUNAND) {
perm = PERM_EMUNAND; perm = PERM_EMUNAND;
snprintf(area_name, 16, "the EmuNAND"); snprintf(area_name, 16, "the EmuNAND");
} else if (drvtype & DRV_GAME) {
perm = PERM_GAME;
snprintf(area_name, 16, "game images");
} else if (drvtype & DRV_IMAGE) { } else if (drvtype & DRV_IMAGE) {
perm = PERM_IMAGE; perm = PERM_IMAGE;
snprintf(area_name, 16, "images"); snprintf(area_name, 16, "images");
} else if (drvtype & DRV_MEMORY) { } else if (drvtype & DRV_MEMORY) {
perm = PERM_MEMORY; perm = PERM_MEMORY;
snprintf(area_name, 16, "memory areas"); snprintf(area_name, 16, "memory areas");
} else if (drvtype & DRV_GAME) {
perm = PERM_GAME;
snprintf(area_name, 16, "game images");
} else if ((drvtype & DRV_ALIAS) || (strncmp(path, "0:/Nintendo 3DS", 15) == 0)) { } else if ((drvtype & DRV_ALIAS) || (strncmp(path, "0:/Nintendo 3DS", 15) == 0)) {
perm = PERM_SDDATA; perm = PERM_SDDATA;
snprintf(area_name, 16, "SD system data"); snprintf(area_name, 16, "SD system data");
@ -292,9 +297,9 @@ bool SetWritePermissions(u32 perm, bool add_perm) {
if (!ShowUnlockSequence(2, "You want to enable image\nwriting permissions.")) if (!ShowUnlockSequence(2, "You want to enable image\nwriting permissions."))
return false; return false;
break; break;
case PERM_SDDATA: case PERM_GAME:
if (!ShowUnlockSequence(2, "You want to enable SD data\nwriting permissions.")) ShowPrompt(false, "Unlock write permission for\ngame images is not allowed.");
return false; return false;
break; break;
#ifndef SAFEMODE #ifndef SAFEMODE
case PERM_SYSNAND: case PERM_SYSNAND:
@ -309,6 +314,10 @@ bool SetWritePermissions(u32 perm, bool add_perm) {
if (!ShowUnlockSequence(4, "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\nWriting to certain areas may\nlead to unexpected results.")) if (!ShowUnlockSequence(4, "!Better be careful!\n \nYou want to enable memory\nwriting permissions.\nWriting to certain areas may\nlead to unexpected results."))
return false; return false;
break; break;
case PERM_SDDATA:
if (!ShowUnlockSequence(2, "You want to enable SD data\nwriting permissions."))
return false;
break;
case PERM_ALL: case PERM_ALL:
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable ALL\nwriting permissions.\nThis enables you to do some\nreally dangerous stuff!")) if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable ALL\nwriting permissions.\nThis enables you to do some\nreally dangerous stuff!"))
return false; return false;

View File

@ -628,8 +628,11 @@ u32 GodMode() {
int injectable = ((clipboard->n_entries == 1) && int injectable = ((clipboard->n_entries == 1) &&
(clipboard->entry[0].type == T_FILE) && (clipboard->entry[0].type == T_FILE) &&
(file_drvtype & DRV_FAT) && (file_drvtype & DRV_FAT) &&
(strncmp(clipboard->entry[0].path, curr_entry->path, 256) != 0)) ? (int) ++n_opt : -1; (strncmp(clipboard->entry[0].path, curr_entry->path, 256) != 0)) ?
int mountable = (file_type && (file_drvtype & DRV_SDCARD)) ? (int) ++n_opt : -1; (int) ++n_opt : -1;
int mountable = (file_type && (file_drvtype & DRV_FAT) &&
!(file_drvtype & (DRV_IMAGE|DRV_RAMDRIVE))) ?
(int) ++n_opt : -1;
int searchdrv = (curr_drvtype & DRV_SEARCH) ? (int) ++n_opt : -1; int searchdrv = (curr_drvtype & DRV_SEARCH) ? (int) ++n_opt : -1;
TruncateString(pathstr, curr_entry->path, 32, 8); TruncateString(pathstr, curr_entry->path, 32, 8);
@ -692,6 +695,7 @@ u32 GodMode() {
if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE)) if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE))
clipboard->n_entries = 0; // remove last mounted image clipboard entries clipboard->n_entries = 0; // remove last mounted image clipboard entries
DeinitExtFS(); DeinitExtFS();
InitExtFS();
u32 mount_state = MountImage(curr_entry->path); u32 mount_state = MountImage(curr_entry->path);
InitExtFS(); InitExtFS();
InitVGameDrive(); InitVGameDrive();