mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Allow mounting images from any FAT based drive
This commit is contained in:
parent
4df338b8a0
commit
9af01de7dc
@ -38,7 +38,7 @@
|
||||
(((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v))
|
||||
|
||||
// GodMode9 version
|
||||
#define VERSION "0.7.8"
|
||||
#define VERSION "0.7.9"
|
||||
|
||||
// buffer area defines (in use by godmode.c)
|
||||
#define DIR_BUFFER (0x21000000)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "image.h"
|
||||
#include "sddata.h"
|
||||
#include "platform.h"
|
||||
#include "ff.h"
|
||||
|
||||
@ -8,6 +9,8 @@ static u32 ramdrv_size = 0;
|
||||
static FIL mount_file;
|
||||
static u32 mount_state = 0;
|
||||
|
||||
static char mount_path[256] = { 0 };
|
||||
|
||||
|
||||
int ReadImageBytes(u8* buffer, u32 offset, u32 count) {
|
||||
UINT bytes_read;
|
||||
@ -23,7 +26,7 @@ int ReadImageBytes(u8* buffer, u32 offset, u32 count) {
|
||||
if (f_size(&mount_file) < offset) return -1;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -39,7 +42,7 @@ int WriteImageBytes(const u8* buffer, u32 offset, u32 count) {
|
||||
if (!mount_state) return FR_INVALID_OBJECT;
|
||||
if (f_tell(&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;
|
||||
}
|
||||
|
||||
@ -65,9 +68,13 @@ u32 GetMountState(void) {
|
||||
return mount_state;
|
||||
}
|
||||
|
||||
const char* GetMountPath(void) {
|
||||
return mount_path;
|
||||
}
|
||||
|
||||
u32 MountRamDrive(void) {
|
||||
if (mount_state && (mount_state != IMG_RAMDRV))
|
||||
f_close(&mount_file);
|
||||
fx_close(&mount_file);
|
||||
if (GetUnitPlatform() == PLATFORM_3DS) {
|
||||
ramdrv_buffer = RAMDRV_BUFFER_O3DS;
|
||||
ramdrv_size = RAMDRV_SIZE_O3DS;
|
||||
@ -75,19 +82,22 @@ u32 MountRamDrive(void) {
|
||||
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 = IdentifyFileType(path);
|
||||
u32 type = (path) ? IdentifyFileType(path) : 0;
|
||||
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_path = 0;
|
||||
}
|
||||
if (!path || !type) return 0;
|
||||
if (f_open(&mount_file, path, FA_READ | FA_WRITE | FA_OPEN_EXISTING) != FR_OK)
|
||||
if (!type) return 0;
|
||||
if (fx_open(&mount_file, path, FA_READ | FA_WRITE | FA_OPEN_EXISTING) != FR_OK)
|
||||
return 0;
|
||||
f_lseek(&mount_file, 0);
|
||||
f_sync(&mount_file);
|
||||
strncpy(mount_path, path, 255);
|
||||
return (mount_state = type);
|
||||
}
|
||||
|
@ -13,5 +13,6 @@ int SyncImage(void);
|
||||
|
||||
u64 GetMountSize(void);
|
||||
u32 GetMountState(void);
|
||||
const char* GetMountPath(void);
|
||||
u32 MountRamDrive(void);
|
||||
u32 MountImage(const char* path);
|
||||
|
@ -1,21 +1,22 @@
|
||||
#include "filetype.h"
|
||||
#include "sddata.h"
|
||||
#include "game.h"
|
||||
#include "ff.h"
|
||||
|
||||
u32 IdentifyFileType(const char* path) {
|
||||
u8 __attribute__((aligned(16))) header[0x200]; // minimum required size
|
||||
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;
|
||||
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);
|
||||
if ((fx_read(&file, header, 0x200, &bytes_read) != FR_OK) || (bytes_read != 0x200)) {
|
||||
fx_close(&file);
|
||||
return 0;
|
||||
}
|
||||
f_close(&file);
|
||||
fx_close(&file);
|
||||
|
||||
if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) &&
|
||||
(getbe64(header + 0x108) == (u64) 0) && (fsize >= 0x8FC8000)) {
|
||||
|
21
source/fs.c
21
source/fs.c
@ -221,6 +221,11 @@ bool CheckWritePermissions(const char* path) {
|
||||
int drvtype = DriveType(path);
|
||||
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) {
|
||||
perm = PERM_SYSNAND;
|
||||
snprintf(area_name, 16, "the SysNAND");
|
||||
@ -233,15 +238,15 @@ bool CheckWritePermissions(const char* path) {
|
||||
} else if (drvtype & DRV_EMUNAND) {
|
||||
perm = PERM_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) {
|
||||
perm = PERM_IMAGE;
|
||||
snprintf(area_name, 16, "images");
|
||||
} else if (drvtype & DRV_MEMORY) {
|
||||
perm = PERM_MEMORY;
|
||||
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)) {
|
||||
perm = PERM_SDDATA;
|
||||
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."))
|
||||
return false;
|
||||
break;
|
||||
case PERM_SDDATA:
|
||||
if (!ShowUnlockSequence(2, "You want to enable SD data\nwriting permissions."))
|
||||
return false;
|
||||
case PERM_GAME:
|
||||
ShowPrompt(false, "Unlock write permission for\ngame images is not allowed.");
|
||||
return false;
|
||||
break;
|
||||
#ifndef SAFEMODE
|
||||
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."))
|
||||
return false;
|
||||
break;
|
||||
case PERM_SDDATA:
|
||||
if (!ShowUnlockSequence(2, "You want to enable SD data\nwriting permissions."))
|
||||
return false;
|
||||
break;
|
||||
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!"))
|
||||
return false;
|
||||
|
@ -628,8 +628,11 @@ u32 GodMode() {
|
||||
int injectable = ((clipboard->n_entries == 1) &&
|
||||
(clipboard->entry[0].type == T_FILE) &&
|
||||
(file_drvtype & DRV_FAT) &&
|
||||
(strncmp(clipboard->entry[0].path, curr_entry->path, 256) != 0)) ? (int) ++n_opt : -1;
|
||||
int mountable = (file_type && (file_drvtype & DRV_SDCARD)) ? (int) ++n_opt : -1;
|
||||
(strncmp(clipboard->entry[0].path, curr_entry->path, 256) != 0)) ?
|
||||
(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;
|
||||
|
||||
TruncateString(pathstr, curr_entry->path, 32, 8);
|
||||
@ -692,6 +695,7 @@ u32 GodMode() {
|
||||
if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_IMAGE))
|
||||
clipboard->n_entries = 0; // remove last mounted image clipboard entries
|
||||
DeinitExtFS();
|
||||
InitExtFS();
|
||||
u32 mount_state = MountImage(curr_entry->path);
|
||||
InitExtFS();
|
||||
InitVGameDrive();
|
||||
|
Loading…
x
Reference in New Issue
Block a user