mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Cleanup and reorganize fs.c / fs.h
This commit is contained in:
parent
4dc92abef6
commit
020b1b74b2
4
Makefile
4
Makefile
@ -21,9 +21,9 @@ ifeq ($(MODE),safe)
|
|||||||
export TARGET := SafeMode9
|
export TARGET := SafeMode9
|
||||||
endif
|
endif
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := source source/crypto source/fatfs source/nand source/virtual source/game source/abstraction
|
SOURCES := source source/fs source/crypto source/fatfs source/nand source/virtual source/game source/abstraction
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := source source/font source/crypto source/fatfs source/nand source/virtual source/game
|
INCLUDES := source source/font source/fs source/crypto source/fatfs source/nand source/virtual source/game
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
|
125
source/fs.h
125
source/fs.h
@ -1,125 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
#include "dir.h"
|
|
||||||
|
|
||||||
// primary drive types
|
|
||||||
#define DRV_UNKNOWN (0<<0)
|
|
||||||
#define DRV_FAT (1<<0)
|
|
||||||
#define DRV_VIRTUAL (1<<1)
|
|
||||||
// secondary drive types
|
|
||||||
#define DRV_SDCARD (1<<2)
|
|
||||||
#define DRV_SYSNAND (1<<3)
|
|
||||||
#define DRV_EMUNAND (1<<4)
|
|
||||||
#define DRV_IMAGE (1<<5)
|
|
||||||
#define DRV_XORPAD (1<<6)
|
|
||||||
#define DRV_RAMDRIVE (1<<7)
|
|
||||||
#define DRV_MEMORY (1<<8)
|
|
||||||
#define DRV_GAME (1<<9)
|
|
||||||
#define DRV_ALIAS (1<<10)
|
|
||||||
#define DRV_SEARCH (1<<11)
|
|
||||||
#define DRV_STDFAT (1<<12) // standard FAT drive without limitations
|
|
||||||
|
|
||||||
// permission types
|
|
||||||
#define PERM_SDCARD (1<<0)
|
|
||||||
#define PERM_RAMDRIVE (1<<1)
|
|
||||||
#define PERM_EMUNAND (1<<2)
|
|
||||||
#define PERM_SYSNAND (1<<3)
|
|
||||||
#define PERM_IMAGE (1<<4)
|
|
||||||
#define PERM_MEMORY (1<<5)
|
|
||||||
#define PERM_GAME (1<<6) // can't be enabled, placeholder
|
|
||||||
#define PERM_XORPAD (1<<7) // can't be enabled, placeholder
|
|
||||||
#define PERM_A9LH ((1<<8) | PERM_SYSNAND)
|
|
||||||
#define PERM_SDDATA ((1<<9) | PERM_SDCARD)
|
|
||||||
#define PERM_BASE (PERM_SDCARD | PERM_RAMDRIVE)
|
|
||||||
#define PERM_ALL (PERM_SDCARD | PERM_RAMDRIVE | PERM_EMUNAND | PERM_SYSNAND | PERM_IMAGE | PERM_MEMORY | PERM_SDDATA)
|
|
||||||
|
|
||||||
// move / copy flags
|
|
||||||
#define ASK_ALL (1<<0)
|
|
||||||
#define SKIP_ALL (1<<1)
|
|
||||||
#define OVERWRITE_ALL (1<<2)
|
|
||||||
|
|
||||||
bool InitSDCardFS();
|
|
||||||
bool InitExtFS();
|
|
||||||
bool InitImgFS(const char* path);
|
|
||||||
bool InitRamDriveFS();
|
|
||||||
void DeinitExtFS();
|
|
||||||
void DeinitSDCardFS();
|
|
||||||
|
|
||||||
/** Set search pattern / path for special Z: drive **/
|
|
||||||
void SetFSSearch(const char* pattern, const char* path);
|
|
||||||
|
|
||||||
/** Return total size of SD card **/
|
|
||||||
uint64_t GetSDCardSize();
|
|
||||||
|
|
||||||
/** Format the SD card **/
|
|
||||||
bool FormatSDCard(u64 hidden_mb, u32 cluster_size);
|
|
||||||
|
|
||||||
/** Check if writing to this path is allowed **/
|
|
||||||
bool CheckWritePermissions(const char* path);
|
|
||||||
|
|
||||||
/** Set new write permissions */
|
|
||||||
bool SetWritePermissions(u32 perm, bool add_perm);
|
|
||||||
|
|
||||||
/** Get write permissions */
|
|
||||||
u32 GetWritePermissions();
|
|
||||||
|
|
||||||
/** True if file exists and is not locked, false otherwise **/
|
|
||||||
bool FileCheck(const char* path);
|
|
||||||
|
|
||||||
/** Create / open file and write the provided data to it **/
|
|
||||||
bool FileSetData(const char* path, const u8* data, size_t size, size_t foffset, bool create);
|
|
||||||
|
|
||||||
/** Read data from file@offset **/
|
|
||||||
size_t FileGetData(const char* path, u8* data, size_t size, size_t foffset);
|
|
||||||
|
|
||||||
/** Get size of file **/
|
|
||||||
size_t FileGetSize(const char* path);
|
|
||||||
|
|
||||||
/** Get SHA-256 of file **/
|
|
||||||
bool FileGetSha256(const char* path, u8* sha256);
|
|
||||||
|
|
||||||
/** Find data in file **/
|
|
||||||
u32 FileFindData(const char* path, u8* data, u32 size, u32 offset);
|
|
||||||
|
|
||||||
/** Inject file into file @offset **/
|
|
||||||
bool FileInjectFile(const char* dest, const char* orig, u32 offset);
|
|
||||||
|
|
||||||
/** Recursively copy a file or directory **/
|
|
||||||
bool PathCopy(const char* destdir, const char* orig, u32* flags);
|
|
||||||
|
|
||||||
/** Recursively move a file or directory **/
|
|
||||||
bool PathMove(const char* destdir, const char* orig, u32* flags);
|
|
||||||
|
|
||||||
/** Recursively delete a file or directory **/
|
|
||||||
bool PathDelete(const char* path);
|
|
||||||
|
|
||||||
/** Rename file / folder in path to new name **/
|
|
||||||
bool PathRename(const char* path, const char* newname);
|
|
||||||
|
|
||||||
/** Create a new directory in cpath **/
|
|
||||||
bool DirCreate(const char* cpath, const char* dirname);
|
|
||||||
|
|
||||||
/** Create a screenshot of the current framebuffer **/
|
|
||||||
void CreateScreenshot();
|
|
||||||
|
|
||||||
/** Search under a given path **/
|
|
||||||
void SearchDirContents(DirStruct* contents, const char* path, const char* pattern, bool recursive);
|
|
||||||
|
|
||||||
/** Get directory content under a given path **/
|
|
||||||
void GetDirContents(DirStruct* contents, const char* path);
|
|
||||||
|
|
||||||
/** Gets remaining space in filesystem in bytes */
|
|
||||||
uint64_t GetFreeSpace(const char* path);
|
|
||||||
|
|
||||||
/** Gets total spacein filesystem in bytes */
|
|
||||||
uint64_t GetTotalSpace(const char* path);
|
|
||||||
|
|
||||||
/** Return the offset - in sectors - of the FAT partition on the drive **/
|
|
||||||
uint64_t GetPartitionOffsetSector(const char* path);
|
|
||||||
|
|
||||||
/** Function to identify the type of a drive **/
|
|
||||||
int DriveType(const char* path);
|
|
||||||
|
|
||||||
/** Check for special search drive **/
|
|
||||||
bool IsSearchDrive(const char* path);
|
|
@ -1,4 +1,4 @@
|
|||||||
#include "dir.h"
|
#include "fsdir.h"
|
||||||
|
|
||||||
void DirEntryCpy(DirEntry* dest, const DirEntry* orig) {
|
void DirEntryCpy(DirEntry* dest, const DirEntry* orig) {
|
||||||
memcpy(dest, orig, sizeof(DirEntry));
|
memcpy(dest, orig, sizeof(DirEntry));
|
200
source/fs/fsdrive.c
Normal file
200
source/fs/fsdrive.c
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
#include "fsdrive.h"
|
||||||
|
#include "fsinit.h"
|
||||||
|
#include "virtual.h"
|
||||||
|
#include "sddata.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "ff.h"
|
||||||
|
|
||||||
|
// last search pattern & path
|
||||||
|
static char search_pattern[256] = { 0 };
|
||||||
|
static char search_path[256] = { 0 };
|
||||||
|
|
||||||
|
int DriveType(const char* path) {
|
||||||
|
int type = DRV_UNKNOWN;
|
||||||
|
int pdrv = GetMountedFSNum(path);
|
||||||
|
|
||||||
|
if (CheckAliasDrive(path)) {
|
||||||
|
type = DRV_FAT | DRV_ALIAS;
|
||||||
|
} else if (*search_pattern && *search_path && (strncmp(path, "Z:", 3) == 0)) {
|
||||||
|
type = DRV_SEARCH;
|
||||||
|
} else if ((pdrv >= 0) && (pdrv < NORM_FS)) {
|
||||||
|
if (pdrv == 0) {
|
||||||
|
type = DRV_FAT | DRV_SDCARD | DRV_STDFAT;
|
||||||
|
} else if ((pdrv == 7) && (GetMountState() == IMG_RAMDRV)) {
|
||||||
|
type = DRV_FAT | DRV_RAMDRIVE | DRV_STDFAT;
|
||||||
|
} else if ((pdrv >= 1) && (pdrv <= 3)) {
|
||||||
|
type = DRV_FAT | DRV_SYSNAND | DRV_STDFAT;
|
||||||
|
} else if ((pdrv >= 4) && (pdrv <= 6)) {
|
||||||
|
type = DRV_FAT | DRV_EMUNAND | DRV_STDFAT;
|
||||||
|
} else if ((pdrv >= 7) && (pdrv <= 9) &&
|
||||||
|
((GetMountState() == IMG_FAT) || (GetMountState() == IMG_NAND))) {
|
||||||
|
type = DRV_FAT | DRV_IMAGE | DRV_STDFAT;
|
||||||
|
}
|
||||||
|
} else if (CheckVirtualDrive(path)) {
|
||||||
|
int vsrc = GetVirtualSource(path);
|
||||||
|
if (vsrc == VRT_SYSNAND) {
|
||||||
|
type = DRV_VIRTUAL | DRV_SYSNAND;
|
||||||
|
} else if (vsrc == VRT_EMUNAND) {
|
||||||
|
type = DRV_VIRTUAL | DRV_EMUNAND;
|
||||||
|
} else if (vsrc == VRT_IMGNAND) {
|
||||||
|
type = DRV_VIRTUAL | DRV_IMAGE;
|
||||||
|
} else if (vsrc == VRT_XORPAD) {
|
||||||
|
type = DRV_VIRTUAL | DRV_XORPAD;
|
||||||
|
} else if (vsrc == VRT_MEMORY) {
|
||||||
|
type = DRV_VIRTUAL | DRV_MEMORY;
|
||||||
|
} else if (vsrc == VRT_GAME) {
|
||||||
|
type = DRV_VIRTUAL | DRV_GAME | DRV_IMAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFSSearch(const char* pattern, const char* path) {
|
||||||
|
if (pattern && path) {
|
||||||
|
strncpy(search_pattern, pattern, 256);
|
||||||
|
strncpy(search_path, path, 256);
|
||||||
|
} else *search_pattern = *search_path = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetRootDirContentsWorker(DirStruct* contents) {
|
||||||
|
static const char* drvname[] = { FS_DRVNAME };
|
||||||
|
static const char* drvnum[] = { FS_DRVNUM };
|
||||||
|
u32 n_entries = 0;
|
||||||
|
|
||||||
|
// virtual root objects hacked in
|
||||||
|
for (u32 pdrv = 0; (pdrv < NORM_FS+VIRT_FS) && (n_entries < MAX_DIR_ENTRIES); pdrv++) {
|
||||||
|
DirEntry* entry = &(contents->entry[n_entries]);
|
||||||
|
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");
|
||||||
|
else if (pdrv == 10) // Game drive special handling
|
||||||
|
snprintf(entry->path + 4, 32, "[%s] %s %s", drvnum[pdrv],
|
||||||
|
(GetMountState() == GAME_CIA ) ? "CIA" :
|
||||||
|
(GetMountState() == GAME_NCSD ) ? "NCSD" :
|
||||||
|
(GetMountState() == GAME_NCCH ) ? "NCCH" :
|
||||||
|
(GetMountState() == GAME_EXEFS) ? "EXEFS" :
|
||||||
|
(GetMountState() == GAME_ROMFS) ? "ROMFS" : "UNK", drvname[pdrv]);
|
||||||
|
else snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], drvname[pdrv]);
|
||||||
|
entry->name = entry->path + 4;
|
||||||
|
entry->size = GetTotalSpace(entry->path);
|
||||||
|
entry->type = T_ROOT;
|
||||||
|
entry->marked = 0;
|
||||||
|
n_entries++;
|
||||||
|
}
|
||||||
|
contents->n_entries = n_entries;
|
||||||
|
|
||||||
|
return contents->n_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetDirContentsWorker(DirStruct* contents, char* fpath, int fnsize, const char* pattern, bool recursive) {
|
||||||
|
DIR pdir;
|
||||||
|
FILINFO fno;
|
||||||
|
char* fname = fpath + strnlen(fpath, fnsize - 1);
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
if (fa_opendir(&pdir, fpath) != FR_OK)
|
||||||
|
return false;
|
||||||
|
(fname++)[0] = '/';
|
||||||
|
|
||||||
|
while (f_readdir(&pdir, &fno) == FR_OK) {
|
||||||
|
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
|
||||||
|
continue; // filter out virtual entries
|
||||||
|
strncpy(fname, fno.fname, (fnsize - 1) - (fname - fpath));
|
||||||
|
if (fno.fname[0] == 0) {
|
||||||
|
ret = true;
|
||||||
|
break;
|
||||||
|
} else if (!pattern || MatchName(pattern, fname)) {
|
||||||
|
DirEntry* entry = &(contents->entry[contents->n_entries]);
|
||||||
|
strncpy(entry->path, fpath, 256);
|
||||||
|
entry->name = entry->path + (fname - fpath);
|
||||||
|
if (fno.fattrib & AM_DIR) {
|
||||||
|
entry->type = T_DIR;
|
||||||
|
entry->size = 0;
|
||||||
|
} else {
|
||||||
|
entry->type = T_FILE;
|
||||||
|
entry->size = fno.fsize;
|
||||||
|
}
|
||||||
|
entry->marked = 0;
|
||||||
|
if (contents->n_entries >= MAX_DIR_ENTRIES) {
|
||||||
|
ret = true; // Too many entries, still okay
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
contents->n_entries++;
|
||||||
|
}
|
||||||
|
if (recursive && (fno.fattrib & AM_DIR)) {
|
||||||
|
if (!GetDirContentsWorker(contents, fpath, fnsize, pattern, recursive))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f_closedir(&pdir);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchDirContents(DirStruct* contents, const char* path, const char* pattern, bool recursive) {
|
||||||
|
contents->n_entries = 0;
|
||||||
|
if (!(*path)) { // root directory
|
||||||
|
if (!GetRootDirContentsWorker(contents))
|
||||||
|
contents->n_entries = 0; // not required, but so what?
|
||||||
|
} else {
|
||||||
|
// create virtual '..' entry
|
||||||
|
contents->entry->name = contents->entry->path + 8;
|
||||||
|
strncpy(contents->entry->path, "*?*?*", 8);
|
||||||
|
strncpy(contents->entry->name, "..", 4);
|
||||||
|
contents->entry->type = T_DOTDOT;
|
||||||
|
contents->entry->size = 0;
|
||||||
|
contents->n_entries = 1;
|
||||||
|
// search the path
|
||||||
|
char fpath[256]; // 256 is the maximum length of a full path
|
||||||
|
strncpy(fpath, path, 256);
|
||||||
|
if (DriveType(path) & DRV_VIRTUAL) {
|
||||||
|
if (!GetVirtualDirContents(contents, fpath, 256, pattern, recursive))
|
||||||
|
contents->n_entries = 0;
|
||||||
|
} else {
|
||||||
|
if (!GetDirContentsWorker(contents, fpath, 256, pattern, recursive))
|
||||||
|
contents->n_entries = 0;
|
||||||
|
}
|
||||||
|
SortDirStruct(contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetDirContents(DirStruct* contents, const char* path) {
|
||||||
|
if (DriveType(path) & DRV_SEARCH) {
|
||||||
|
ShowString("Searching, please wait...");
|
||||||
|
SearchDirContents(contents, search_path, search_pattern, true);
|
||||||
|
ClearScreenF(true, false, COLOR_STD_BG);
|
||||||
|
} else SearchDirContents(contents, path, NULL, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t GetFreeSpace(const char* path)
|
||||||
|
{
|
||||||
|
DWORD free_clusters;
|
||||||
|
FATFS* fsptr;
|
||||||
|
char fsname[4] = { '\0' };
|
||||||
|
int pdrv = GetMountedFSNum(path);
|
||||||
|
FATFS* fsobj = GetMountedFSObject(path);
|
||||||
|
if ((pdrv < 0) || !fsobj) return 0;
|
||||||
|
|
||||||
|
snprintf(fsname, 3, "%i:", pdrv);
|
||||||
|
if (f_getfree(fsname, &free_clusters, &fsptr) != FR_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (uint64_t) free_clusters * fsobj->csize * _MAX_SS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t GetTotalSpace(const char* path)
|
||||||
|
{
|
||||||
|
FATFS* fsobj = GetMountedFSObject(path);
|
||||||
|
return (fsobj) ? ((uint64_t) (fsobj->n_fatent - 2) * fsobj->csize * _MAX_SS) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t GetPartitionOffsetSector(const char* path)
|
||||||
|
{
|
||||||
|
FATFS* fsobj = GetMountedFSObject(path);
|
||||||
|
return (fsobj) ? (uint64_t) fsobj->volbase : 0;
|
||||||
|
}
|
58
source/fs/fsdrive.h
Normal file
58
source/fs/fsdrive.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "fsdir.h"
|
||||||
|
|
||||||
|
#define NORM_FS 10
|
||||||
|
#define IMGN_FS 3 // image normal filesystems
|
||||||
|
#define VIRT_FS 9
|
||||||
|
|
||||||
|
// primary drive types
|
||||||
|
#define DRV_UNKNOWN (0<<0)
|
||||||
|
#define DRV_FAT (1<<0)
|
||||||
|
#define DRV_VIRTUAL (1<<1)
|
||||||
|
// secondary drive types
|
||||||
|
#define DRV_SDCARD (1<<2)
|
||||||
|
#define DRV_SYSNAND (1<<3)
|
||||||
|
#define DRV_EMUNAND (1<<4)
|
||||||
|
#define DRV_IMAGE (1<<5)
|
||||||
|
#define DRV_XORPAD (1<<6)
|
||||||
|
#define DRV_RAMDRIVE (1<<7)
|
||||||
|
#define DRV_MEMORY (1<<8)
|
||||||
|
#define DRV_GAME (1<<9)
|
||||||
|
#define DRV_ALIAS (1<<10)
|
||||||
|
#define DRV_SEARCH (1<<11)
|
||||||
|
#define DRV_STDFAT (1<<12) // standard FAT drive without limitations
|
||||||
|
|
||||||
|
#define FS_DRVNAME \
|
||||||
|
"SDCARD", \
|
||||||
|
"SYSNAND CTRNAND", "SYSNAND TWLN", "SYSNAND TWLP", \
|
||||||
|
"EMUNAND CTRNAND", "EMUNAND TWLN", "EMUNAND TWLP", \
|
||||||
|
"IMGNAND CTRNAND", "IMGNAND TWLN", "IMGNAND TWLP", \
|
||||||
|
"GAME IMAGE", \
|
||||||
|
"SYSNAND SD", "EMUNAND SD", \
|
||||||
|
"SYSNAND VIRTUAL", "EMUNAND VIRTUAL", "IMGNAND VIRTUAL", \
|
||||||
|
"NAND XORPADS", \
|
||||||
|
"MEMORY VIRTUAL", \
|
||||||
|
"LAST SEARCH" \
|
||||||
|
|
||||||
|
#define FS_DRVNUM \
|
||||||
|
"0:", "1:", "2:", "3:", "4:", "5:", "6:", "7:", "8:", "9:", "G:", "A:", "B:", "S:", "E:", "I:", "X:", "M:", "Z:"
|
||||||
|
|
||||||
|
/** Function to identify the type of a drive **/
|
||||||
|
int DriveType(const char* path);
|
||||||
|
|
||||||
|
/** Set search pattern / path for special Z: drive **/
|
||||||
|
void SetFSSearch(const char* pattern, const char* path);
|
||||||
|
|
||||||
|
/** Get directory content under a given path **/
|
||||||
|
void GetDirContents(DirStruct* contents, const char* path);
|
||||||
|
|
||||||
|
/** Gets remaining space in filesystem in bytes */
|
||||||
|
uint64_t GetFreeSpace(const char* path);
|
||||||
|
|
||||||
|
/** Gets total spacein filesystem in bytes */
|
||||||
|
uint64_t GetTotalSpace(const char* path);
|
||||||
|
|
||||||
|
/** Return the offset - in sectors - of the FAT partition on the drive **/
|
||||||
|
uint64_t GetPartitionOffsetSector(const char* path);
|
126
source/fs/fsinit.c
Normal file
126
source/fs/fsinit.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include "fsinit.h"
|
||||||
|
#include "fsdrive.h"
|
||||||
|
#include "virtual.h"
|
||||||
|
#include "vgame.h"
|
||||||
|
#include "sddata.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "ff.h"
|
||||||
|
|
||||||
|
// don't use this area for anything else!
|
||||||
|
static FATFS* fs = (FATFS*)0x20316000;
|
||||||
|
|
||||||
|
// currently open file systems
|
||||||
|
static bool fs_mounted[NORM_FS] = { false };
|
||||||
|
|
||||||
|
bool InitSDCardFS() {
|
||||||
|
fs_mounted[0] = (f_mount(fs, "0:", 1) == FR_OK);
|
||||||
|
return fs_mounted[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InitExtFS() {
|
||||||
|
if (!fs_mounted[0])
|
||||||
|
return false;
|
||||||
|
for (u32 i = 1; i < NORM_FS; i++) {
|
||||||
|
char fsname[8];
|
||||||
|
snprintf(fsname, 7, "%lu:", i);
|
||||||
|
if (fs_mounted[i]) continue;
|
||||||
|
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);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InitImgFS(const char* path) {
|
||||||
|
// deinit image filesystem
|
||||||
|
for (u32 i = NORM_FS - 1; i >= NORM_FS - IMGN_FS; i--) {
|
||||||
|
char fsname[8];
|
||||||
|
snprintf(fsname, 7, "%lu:", i);
|
||||||
|
if (!fs_mounted[i]) continue;
|
||||||
|
f_mount(NULL, fsname, 1);
|
||||||
|
fs_mounted[i] = false;
|
||||||
|
}
|
||||||
|
// (re)mount image, done if path == NULL
|
||||||
|
MountImage(path);
|
||||||
|
InitVGameDrive();
|
||||||
|
if (!GetMountState()) return false;
|
||||||
|
// reinit image filesystem
|
||||||
|
for (u32 i = NORM_FS - IMGN_FS; i < NORM_FS; i++) {
|
||||||
|
char fsname[8];
|
||||||
|
snprintf(fsname, 7, "%lu:", i);
|
||||||
|
fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
for (u32 i = NORM_FS - 1; i > 0; i--) {
|
||||||
|
if (fs_mounted[i]) {
|
||||||
|
char fsname[8];
|
||||||
|
snprintf(fsname, 7, "%lu:", i);
|
||||||
|
f_mount(NULL, fsname, 1);
|
||||||
|
fs_mounted[i] = false;
|
||||||
|
}
|
||||||
|
if ((i == NORM_FS - IMGN_FS) && (GetMountState() != IMG_RAMDRV)) { // unmount image
|
||||||
|
MountImage(NULL);
|
||||||
|
InitVGameDrive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeinitSDCardFS() {
|
||||||
|
if (GetMountState() != IMG_RAMDRV) {
|
||||||
|
MountImage(NULL);
|
||||||
|
InitVGameDrive();
|
||||||
|
}
|
||||||
|
if (fs_mounted[0]) {
|
||||||
|
f_mount(NULL, "0:", 1);
|
||||||
|
fs_mounted[0] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DismountDriveType(u32 type) { // careful with this - no safety checks
|
||||||
|
if (type & DriveType(GetMountPath()))
|
||||||
|
InitImgFS(NULL); // image is mounted from type -> unmount image drive, too
|
||||||
|
for (u32 i = NORM_FS - 1; i > 0; i--) {
|
||||||
|
char fsname[8];
|
||||||
|
snprintf(fsname, 7, "%lu:", i);
|
||||||
|
if (!fs_mounted[i] || !(type & DriveType(fsname)))
|
||||||
|
continue;
|
||||||
|
f_mount(NULL, fsname, 1);
|
||||||
|
fs_mounted[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetMountedFSNum(const char* path) {
|
||||||
|
char alias[256];
|
||||||
|
dealias_path(alias, path);
|
||||||
|
int fsnum = *alias - (int) '0';
|
||||||
|
if ((fsnum < 0) || (fsnum >= NORM_FS) || (alias[1] != ':') || !fs_mounted[fsnum])
|
||||||
|
return -1;
|
||||||
|
return fsnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
FATFS* GetMountedFSObject(const char* path) {
|
||||||
|
int fsnum = GetMountedFSNum(path);
|
||||||
|
return (fsnum >= 0) ? fs + fsnum : NULL;
|
||||||
|
}
|
31
source/fs/fsinit.h
Normal file
31
source/fs/fsinit.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "ff.h"
|
||||||
|
|
||||||
|
// init SD card filesystem - required for everything else
|
||||||
|
bool InitSDCardFS();
|
||||||
|
|
||||||
|
// init fill external fileystem
|
||||||
|
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();
|
||||||
|
|
||||||
|
// deinitialize SD card filesystem
|
||||||
|
void DeinitSDCardFS();
|
||||||
|
|
||||||
|
// dismount drives of a certain type
|
||||||
|
void DismountDriveType(u32 type);
|
||||||
|
|
||||||
|
// get number of mounted file system (only for FATFS filesystems)
|
||||||
|
int GetMountedFSNum(const char* path);
|
||||||
|
|
||||||
|
// get mounted file system object (only for FATFS filesystems)
|
||||||
|
FATFS* GetMountedFSObject(const char* path);
|
147
source/fs/fsperm.c
Normal file
147
source/fs/fsperm.c
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#include "fsperm.h"
|
||||||
|
#include "fsdrive.h"
|
||||||
|
#include "virtual.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
// write permissions - careful with this
|
||||||
|
static u32 write_permissions = PERM_BASE;
|
||||||
|
|
||||||
|
bool CheckWritePermissions(const char* path) {
|
||||||
|
char area_name[16];
|
||||||
|
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");
|
||||||
|
// check virtual file flags (if any)
|
||||||
|
VirtualFile vfile;
|
||||||
|
if (GetVirtualFile(&vfile, path) && (vfile.flags & VFLAG_A9LH_AREA)) {
|
||||||
|
perm = PERM_A9LH;
|
||||||
|
snprintf(area_name, 16, "A9LH regions");
|
||||||
|
}
|
||||||
|
} 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_XORPAD) {
|
||||||
|
perm = PERM_XORPAD;
|
||||||
|
snprintf(area_name, 16, "XORpads");
|
||||||
|
} 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_ALIAS) || (strncmp(path, "0:/Nintendo 3DS", 15) == 0)) {
|
||||||
|
perm = PERM_SDDATA;
|
||||||
|
snprintf(area_name, 16, "SD system data");
|
||||||
|
} else if (drvtype & DRV_SDCARD) {
|
||||||
|
perm = PERM_SDCARD;
|
||||||
|
snprintf(area_name, 16, "the SD card");
|
||||||
|
} else if (drvtype & DRV_RAMDRIVE) {
|
||||||
|
perm = PERM_RAMDRIVE;
|
||||||
|
snprintf(area_name, 16, "the RAM drive");
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check permission, return if already set
|
||||||
|
if ((write_permissions & perm) == perm)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// ask the user
|
||||||
|
if (!ShowPrompt(true, "Writing to %s is locked!\nUnlock it now?", area_name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return SetWritePermissions(perm, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetWritePermissions(u32 perm, bool add_perm) {
|
||||||
|
if ((write_permissions & perm) == perm) { // write permissions already given
|
||||||
|
if (!add_perm) write_permissions = perm;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (perm) {
|
||||||
|
case PERM_BASE:
|
||||||
|
if (!ShowUnlockSequence(1, "You want to enable base\nwriting permissions."))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case PERM_SDCARD:
|
||||||
|
if (!ShowUnlockSequence(1, "You want to enable SD card\nwriting permissions."))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case PERM_RAMDRIVE:
|
||||||
|
if (!ShowUnlockSequence(1, "You want to enable RAM drive\nwriting permissions."))
|
||||||
|
return false;
|
||||||
|
case PERM_EMUNAND:
|
||||||
|
if (!ShowUnlockSequence(2, "You want to enable EmuNAND\nwriting permissions."))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case PERM_IMAGE:
|
||||||
|
if (!ShowUnlockSequence(2, "You want to enable image\nwriting permissions."))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case PERM_GAME:
|
||||||
|
ShowPrompt(false, "Unlock write permission for\ngame images is not allowed.");
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case PERM_XORPAD:
|
||||||
|
ShowPrompt(false, "Unlock write permission for\nXORpad drive is not allowed.");
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
#ifndef SAFEMODE
|
||||||
|
case PERM_SYSNAND:
|
||||||
|
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nwriting permissions.\nThis enables you to do some\nreally dangerous stuff!"))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case PERM_A9LH:
|
||||||
|
if (!ShowUnlockSequence(5, "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable A9LH area\nwriting permissions.\nThis enables you to OVERWRITE\nyour A9LH installation!"))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case PERM_MEMORY:
|
||||||
|
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;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ShowPrompt(false, "Unlock write permission is not allowed.");
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
case PERM_ALL:
|
||||||
|
perm &= ~(PERM_SYSNAND|PERM_MEMORY);
|
||||||
|
if (!ShowUnlockSequence(2, "You want to enable EmuNAND &\nimage writing permissions.\nKeep backups, just in case."))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ShowPrompt(false, "Can't unlock write permission.\nTry GodMode9 instead!");
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
write_permissions = add_perm ? write_permissions | perm : perm;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetWritePermissions() {
|
||||||
|
return write_permissions;
|
||||||
|
}
|
26
source/fs/fsperm.h
Normal file
26
source/fs/fsperm.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
// permission types
|
||||||
|
#define PERM_SDCARD (1<<0)
|
||||||
|
#define PERM_RAMDRIVE (1<<1)
|
||||||
|
#define PERM_EMUNAND (1<<2)
|
||||||
|
#define PERM_SYSNAND (1<<3)
|
||||||
|
#define PERM_IMAGE (1<<4)
|
||||||
|
#define PERM_MEMORY (1<<5)
|
||||||
|
#define PERM_GAME (1<<6) // can't be enabled, placeholder
|
||||||
|
#define PERM_XORPAD (1<<7) // can't be enabled, placeholder
|
||||||
|
#define PERM_A9LH ((1<<8) | PERM_SYSNAND)
|
||||||
|
#define PERM_SDDATA ((1<<9) | PERM_SDCARD)
|
||||||
|
#define PERM_BASE (PERM_SDCARD | PERM_RAMDRIVE)
|
||||||
|
#define PERM_ALL (PERM_SDCARD | PERM_RAMDRIVE | PERM_EMUNAND | PERM_SYSNAND | PERM_IMAGE | PERM_MEMORY | PERM_SDDATA)
|
||||||
|
|
||||||
|
/** Check if writing to this path is allowed **/
|
||||||
|
bool CheckWritePermissions(const char* path);
|
||||||
|
|
||||||
|
/** Set new write permissions */
|
||||||
|
bool SetWritePermissions(u32 perm, bool add_perm);
|
||||||
|
|
||||||
|
/** Get write permissions */
|
||||||
|
u32 GetWritePermissions();
|
@ -1,16 +1,13 @@
|
|||||||
#include "ui.h"
|
#include "fsutil.h"
|
||||||
#include "fs.h"
|
#include "fsinit.h"
|
||||||
#include "virtual.h"
|
#include "fsdrive.h"
|
||||||
#include "vgame.h"
|
#include "fsperm.h"
|
||||||
#include "sddata.h"
|
#include "sddata.h"
|
||||||
#include "image.h"
|
#include "virtual.h"
|
||||||
#include "sha.h"
|
#include "sha.h"
|
||||||
#include "sdmmc.h"
|
#include "sdmmc.h"
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
|
#include "ui.h"
|
||||||
#define NORM_FS 10
|
|
||||||
#define IMGN_FS 3 // image normal filesystems
|
|
||||||
#define VIRT_FS 9
|
|
||||||
|
|
||||||
#define SKIP_CUR (1<<3)
|
#define SKIP_CUR (1<<3)
|
||||||
#define OVERWRITE_CUR (1<<4)
|
#define OVERWRITE_CUR (1<<4)
|
||||||
@ -21,191 +18,6 @@ PARTITION VolToPart[] = {
|
|||||||
{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}
|
{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
// don't use this area for anything else!
|
|
||||||
static FATFS* fs = (FATFS*)0x20316000;
|
|
||||||
|
|
||||||
// write permissions - careful with this
|
|
||||||
static u32 write_permissions = PERM_BASE;
|
|
||||||
|
|
||||||
// number of currently open file systems
|
|
||||||
static bool fs_mounted[NORM_FS] = { false };
|
|
||||||
|
|
||||||
// last search pattern & path
|
|
||||||
static char search_pattern[256] = { 0 };
|
|
||||||
static char search_path[256] = { 0 };
|
|
||||||
|
|
||||||
bool InitSDCardFS() {
|
|
||||||
fs_mounted[0] = (f_mount(fs, "0:", 1) == FR_OK);
|
|
||||||
return fs_mounted[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitExtFS() {
|
|
||||||
if (!fs_mounted[0])
|
|
||||||
return false;
|
|
||||||
for (u32 i = 1; i < NORM_FS; i++) {
|
|
||||||
char fsname[8];
|
|
||||||
snprintf(fsname, 7, "%lu:", i);
|
|
||||||
if (fs_mounted[i]) continue;
|
|
||||||
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);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitImgFS(const char* path) {
|
|
||||||
// deinit image filesystem
|
|
||||||
for (u32 i = NORM_FS - 1; i >= NORM_FS - IMGN_FS; i--) {
|
|
||||||
char fsname[8];
|
|
||||||
snprintf(fsname, 7, "%lu:", i);
|
|
||||||
if (!fs_mounted[i]) continue;
|
|
||||||
f_mount(NULL, fsname, 1);
|
|
||||||
fs_mounted[i] = false;
|
|
||||||
}
|
|
||||||
// (re)mount image, done if path == NULL
|
|
||||||
MountImage(path);
|
|
||||||
InitVGameDrive();
|
|
||||||
if (!GetMountState()) return false;
|
|
||||||
// reinit image filesystem
|
|
||||||
for (u32 i = NORM_FS - IMGN_FS; i < NORM_FS; i++) {
|
|
||||||
char fsname[8];
|
|
||||||
snprintf(fsname, 7, "%lu:", i);
|
|
||||||
fs_mounted[i] = (f_mount(fs + i, fsname, 1) == FR_OK);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
for (u32 i = NORM_FS - 1; i > 0; i--) {
|
|
||||||
if (fs_mounted[i]) {
|
|
||||||
char fsname[8];
|
|
||||||
snprintf(fsname, 7, "%lu:", i);
|
|
||||||
f_mount(NULL, fsname, 1);
|
|
||||||
fs_mounted[i] = false;
|
|
||||||
}
|
|
||||||
if ((i == NORM_FS - IMGN_FS) && (GetMountState() != IMG_RAMDRV)) { // unmount image
|
|
||||||
MountImage(NULL);
|
|
||||||
InitVGameDrive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeinitSDCardFS() {
|
|
||||||
if (GetMountState() != IMG_RAMDRV) {
|
|
||||||
MountImage(NULL);
|
|
||||||
InitVGameDrive();
|
|
||||||
}
|
|
||||||
if (fs_mounted[0]) {
|
|
||||||
f_mount(NULL, "0:", 1);
|
|
||||||
fs_mounted[0] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DismountDriveType(u32 type) { // careful with this - no safety checks
|
|
||||||
if (type & DriveType(GetMountPath()))
|
|
||||||
InitImgFS(NULL); // image is mounted from type -> unmount image drive, too
|
|
||||||
for (u32 i = NORM_FS - 1; i > 0; i--) {
|
|
||||||
char fsname[8];
|
|
||||||
snprintf(fsname, 7, "%lu:", i);
|
|
||||||
if (!fs_mounted[i] || !(type & DriveType(fsname)))
|
|
||||||
continue;
|
|
||||||
f_mount(NULL, fsname, 1);
|
|
||||||
fs_mounted[i] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetFSSearch(const char* pattern, const char* path) {
|
|
||||||
if (pattern && path) {
|
|
||||||
strncpy(search_pattern, pattern, 256);
|
|
||||||
strncpy(search_path, path, 256);
|
|
||||||
} else *search_pattern = *search_path = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
int PathToNumFS(const char* path) {
|
|
||||||
int fsnum = *path - (int) '0';
|
|
||||||
if ((fsnum < 0) || (fsnum >= NORM_FS) || (path[1] != ':')) {
|
|
||||||
// this check is not required
|
|
||||||
/* if (!GetVirtualSource(path) &&
|
|
||||||
!CheckAliasDrive(path) &&
|
|
||||||
!IsSearchDrive(path))
|
|
||||||
ShowPrompt(false, "Invalid path (%s)", path); */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return fsnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PathToNumFSA(const char* path) {
|
|
||||||
char alias[256];
|
|
||||||
dealias_path(alias, path);
|
|
||||||
return PathToNumFS(alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsSearchDrive(const char* path) {
|
|
||||||
return *search_pattern && *search_path && (strncmp(path, "Z:", 3) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DriveType(const char* path) {
|
|
||||||
int type = DRV_UNKNOWN;
|
|
||||||
int pdrv = PathToNumFS(path);
|
|
||||||
|
|
||||||
if ((pdrv >= 0) && (pdrv < NORM_FS)) {
|
|
||||||
if (!fs_mounted[pdrv]) {
|
|
||||||
type = DRV_UNKNOWN;
|
|
||||||
} else if (pdrv == 0) {
|
|
||||||
type = DRV_FAT | DRV_SDCARD | DRV_STDFAT;
|
|
||||||
} else if ((pdrv == 7) && (GetMountState() == IMG_RAMDRV)) {
|
|
||||||
type = DRV_FAT | DRV_RAMDRIVE | DRV_STDFAT;
|
|
||||||
} else if ((pdrv >= 1) && (pdrv <= 3)) {
|
|
||||||
type = DRV_FAT | DRV_SYSNAND | DRV_STDFAT;
|
|
||||||
} else if ((pdrv >= 4) && (pdrv <= 6)) {
|
|
||||||
type = DRV_FAT | DRV_EMUNAND | DRV_STDFAT;
|
|
||||||
} else if ((pdrv >= 7) && (pdrv <= 9) &&
|
|
||||||
((GetMountState() == IMG_FAT) || (GetMountState() == IMG_NAND))) {
|
|
||||||
type = DRV_FAT | DRV_IMAGE | DRV_STDFAT;
|
|
||||||
}
|
|
||||||
} else if (CheckVirtualDrive(path)) {
|
|
||||||
int vsrc = GetVirtualSource(path);
|
|
||||||
if (vsrc == VRT_SYSNAND) {
|
|
||||||
type = DRV_VIRTUAL | DRV_SYSNAND;
|
|
||||||
} else if (vsrc == VRT_EMUNAND) {
|
|
||||||
type = DRV_VIRTUAL | DRV_EMUNAND;
|
|
||||||
} else if (vsrc == VRT_IMGNAND) {
|
|
||||||
type = DRV_VIRTUAL | DRV_IMAGE;
|
|
||||||
} else if (vsrc == VRT_XORPAD) {
|
|
||||||
type = DRV_VIRTUAL | DRV_XORPAD;
|
|
||||||
} else if (vsrc == VRT_MEMORY) {
|
|
||||||
type = DRV_VIRTUAL | DRV_MEMORY;
|
|
||||||
} else if (vsrc == VRT_GAME) {
|
|
||||||
type = DRV_VIRTUAL | DRV_GAME | DRV_IMAGE;
|
|
||||||
}
|
|
||||||
} else if (CheckAliasDrive(path)) {
|
|
||||||
type = DRV_FAT | DRV_ALIAS;
|
|
||||||
} else if (IsSearchDrive(path)) {
|
|
||||||
type = DRV_SEARCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t GetSDCardSize() {
|
uint64_t GetSDCardSize() {
|
||||||
if (sdmmc_sdcard_init() != 0) return 0;
|
if (sdmmc_sdcard_init() != 0) return 0;
|
||||||
return (u64) getMMCDevice(1)->total_size * 512;
|
return (u64) getMMCDevice(1)->total_size * 512;
|
||||||
@ -255,156 +67,17 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// format the SD card
|
// format the SD card
|
||||||
f_mount(fs, "0:", 1);
|
InitSDCardFS();
|
||||||
UINT c_size = cluster_size;
|
UINT c_size = cluster_size;
|
||||||
bool ret = (f_mkfs("0:", FM_FAT32, c_size, MAIN_BUFFER, MAIN_BUFFER_SIZE) == FR_OK) && (f_setlabel("0:GM9SD") == FR_OK);
|
bool ret = (f_mkfs("0:", FM_FAT32, c_size, MAIN_BUFFER, MAIN_BUFFER_SIZE) == FR_OK) && (f_setlabel("0:GM9SD") == FR_OK);
|
||||||
f_mount(NULL, "0:", 1);
|
DeinitSDCardFS();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckWritePermissions(const char* path) {
|
|
||||||
char area_name[16];
|
|
||||||
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");
|
|
||||||
// check virtual file flags (if any)
|
|
||||||
VirtualFile vfile;
|
|
||||||
if (GetVirtualFile(&vfile, path) && (vfile.flags & VFLAG_A9LH_AREA)) {
|
|
||||||
perm = PERM_A9LH;
|
|
||||||
snprintf(area_name, 16, "A9LH regions");
|
|
||||||
}
|
|
||||||
} 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_XORPAD) {
|
|
||||||
perm = PERM_XORPAD;
|
|
||||||
snprintf(area_name, 16, "XORpads");
|
|
||||||
} 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_ALIAS) || (strncmp(path, "0:/Nintendo 3DS", 15) == 0)) {
|
|
||||||
perm = PERM_SDDATA;
|
|
||||||
snprintf(area_name, 16, "SD system data");
|
|
||||||
} else if (drvtype & DRV_SDCARD) {
|
|
||||||
perm = PERM_SDCARD;
|
|
||||||
snprintf(area_name, 16, "the SD card");
|
|
||||||
} else if (drvtype & DRV_RAMDRIVE) {
|
|
||||||
perm = PERM_RAMDRIVE;
|
|
||||||
snprintf(area_name, 16, "the RAM drive");
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check permission, return if already set
|
|
||||||
if ((write_permissions & perm) == perm)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// ask the user
|
|
||||||
if (!ShowPrompt(true, "Writing to %s is locked!\nUnlock it now?", area_name))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return SetWritePermissions(perm, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SetWritePermissions(u32 perm, bool add_perm) {
|
|
||||||
if ((write_permissions & perm) == perm) { // write permissions already given
|
|
||||||
if (!add_perm) write_permissions = perm;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (perm) {
|
|
||||||
case PERM_BASE:
|
|
||||||
if (!ShowUnlockSequence(1, "You want to enable base\nwriting permissions."))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case PERM_SDCARD:
|
|
||||||
if (!ShowUnlockSequence(1, "You want to enable SD card\nwriting permissions."))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case PERM_RAMDRIVE:
|
|
||||||
if (!ShowUnlockSequence(1, "You want to enable RAM drive\nwriting permissions."))
|
|
||||||
return false;
|
|
||||||
case PERM_EMUNAND:
|
|
||||||
if (!ShowUnlockSequence(2, "You want to enable EmuNAND\nwriting permissions."))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case PERM_IMAGE:
|
|
||||||
if (!ShowUnlockSequence(2, "You want to enable image\nwriting permissions."))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case PERM_GAME:
|
|
||||||
ShowPrompt(false, "Unlock write permission for\ngame images is not allowed.");
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case PERM_XORPAD:
|
|
||||||
ShowPrompt(false, "Unlock write permission for\nXORpad drive is not allowed.");
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
#ifndef SAFEMODE
|
|
||||||
case PERM_SYSNAND:
|
|
||||||
if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nwriting permissions.\nThis enables you to do some\nreally dangerous stuff!"))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case PERM_A9LH:
|
|
||||||
if (!ShowUnlockSequence(5, "!THIS IS YOUR ONLY WARNING!\n \nYou want to enable A9LH area\nwriting permissions.\nThis enables you to OVERWRITE\nyour A9LH installation!"))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case PERM_MEMORY:
|
|
||||||
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;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ShowPrompt(false, "Unlock write permission is not allowed.");
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
case PERM_ALL:
|
|
||||||
perm &= ~(PERM_SYSNAND|PERM_MEMORY);
|
|
||||||
if (!ShowUnlockSequence(2, "You want to enable EmuNAND &\nimage writing permissions.\nKeep backups, just in case."))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ShowPrompt(false, "Can't unlock write permission.\nTry GodMode9 instead!");
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
write_permissions = add_perm ? write_permissions | perm : perm;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GetWritePermissions() {
|
|
||||||
return write_permissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileCheck(const char* path) {
|
bool FileCheck(const char* path) {
|
||||||
FIL file;
|
FIL file;
|
||||||
if (PathToNumFSA(path) < 0) return true;
|
if (!(DriveType(path) & DRV_FAT)) return true; // can't really check this
|
||||||
if (fx_open(&file, path, FA_READ | FA_OPEN_EXISTING) == FR_OK) {
|
if (fx_open(&file, path, FA_READ | FA_OPEN_EXISTING) == FR_OK) {
|
||||||
fx_close(&file);
|
fx_close(&file);
|
||||||
return true;
|
return true;
|
||||||
@ -1065,7 +738,7 @@ bool PathMove(const char* destdir, const char* orig, u32* flags) {
|
|||||||
char fopath[256];
|
char fopath[256];
|
||||||
strncpy(fdpath, destdir, 255);
|
strncpy(fdpath, destdir, 255);
|
||||||
strncpy(fopath, orig, 255);
|
strncpy(fopath, orig, 255);
|
||||||
bool same_drv = (PathToNumFS(orig) == PathToNumFS(destdir));
|
bool same_drv = (strncmp(orig, destdir, 2) == 0);
|
||||||
bool res = PathCopyWorker(fdpath, fopath, flags, same_drv);
|
bool res = PathCopyWorker(fdpath, fopath, flags, same_drv);
|
||||||
if (res && (!flags || !(*flags&SKIP_CUR))) PathDelete(orig);
|
if (res && (!flags || !(*flags&SKIP_CUR))) PathDelete(orig);
|
||||||
return res;
|
return res;
|
||||||
@ -1157,160 +830,3 @@ void CreateScreenshot() {
|
|||||||
memcpy(buffer + (y*400 + x + 40) * 3, BOT_SCREEN + (x*240 + y) * 3, 3);
|
memcpy(buffer + (y*400 + x + 40) * 3, BOT_SCREEN + (x*240 + y) * 3, 3);
|
||||||
FileSetData(filename, MAIN_BUFFER, 54 + (400 * 240 * 3 * 2), 0, true);
|
FileSetData(filename, MAIN_BUFFER, 54 + (400 * 240 * 3 * 2), 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetRootDirContentsWorker(DirStruct* contents) {
|
|
||||||
static const char* drvname[] = {
|
|
||||||
"SDCARD",
|
|
||||||
"SYSNAND CTRNAND", "SYSNAND TWLN", "SYSNAND TWLP",
|
|
||||||
"EMUNAND CTRNAND", "EMUNAND TWLN", "EMUNAND TWLP",
|
|
||||||
"IMGNAND CTRNAND", "IMGNAND TWLN", "IMGNAND TWLP",
|
|
||||||
"GAME IMAGE",
|
|
||||||
"SYSNAND SD", "EMUNAND SD",
|
|
||||||
"SYSNAND VIRTUAL", "EMUNAND VIRTUAL", "IMGNAND VIRTUAL",
|
|
||||||
"NAND XORPADS",
|
|
||||||
"MEMORY VIRTUAL",
|
|
||||||
"LAST SEARCH"
|
|
||||||
};
|
|
||||||
static const char* drvnum[] = {
|
|
||||||
"0:", "1:", "2:", "3:", "4:", "5:", "6:", "7:", "8:", "9:", "G:", "A:", "B:", "S:", "E:", "I:", "X:", "M:", "Z:"
|
|
||||||
};
|
|
||||||
u32 n_entries = 0;
|
|
||||||
|
|
||||||
// virtual root objects hacked in
|
|
||||||
for (u32 pdrv = 0; (pdrv < NORM_FS+VIRT_FS) && (n_entries < MAX_DIR_ENTRIES); pdrv++) {
|
|
||||||
DirEntry* entry = &(contents->entry[n_entries]);
|
|
||||||
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");
|
|
||||||
else if (pdrv == 10) // Game drive special handling
|
|
||||||
snprintf(entry->path + 4, 32, "[%s] %s %s", drvnum[pdrv],
|
|
||||||
(GetMountState() == GAME_CIA ) ? "CIA" :
|
|
||||||
(GetMountState() == GAME_NCSD ) ? "NCSD" :
|
|
||||||
(GetMountState() == GAME_NCCH ) ? "NCCH" :
|
|
||||||
(GetMountState() == GAME_EXEFS) ? "EXEFS" :
|
|
||||||
(GetMountState() == GAME_ROMFS) ? "ROMFS" : "UNK", drvname[pdrv]);
|
|
||||||
else snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], drvname[pdrv]);
|
|
||||||
entry->name = entry->path + 4;
|
|
||||||
entry->size = GetTotalSpace(entry->path);
|
|
||||||
entry->type = T_ROOT;
|
|
||||||
entry->marked = 0;
|
|
||||||
n_entries++;
|
|
||||||
}
|
|
||||||
contents->n_entries = n_entries;
|
|
||||||
|
|
||||||
return contents->n_entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetDirContentsWorker(DirStruct* contents, char* fpath, int fnsize, const char* pattern, bool recursive) {
|
|
||||||
DIR pdir;
|
|
||||||
FILINFO fno;
|
|
||||||
char* fname = fpath + strnlen(fpath, fnsize - 1);
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
if (fa_opendir(&pdir, fpath) != FR_OK)
|
|
||||||
return false;
|
|
||||||
(fname++)[0] = '/';
|
|
||||||
|
|
||||||
while (f_readdir(&pdir, &fno) == FR_OK) {
|
|
||||||
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
|
|
||||||
continue; // filter out virtual entries
|
|
||||||
strncpy(fname, fno.fname, (fnsize - 1) - (fname - fpath));
|
|
||||||
if (fno.fname[0] == 0) {
|
|
||||||
ret = true;
|
|
||||||
break;
|
|
||||||
} else if (!pattern || MatchName(pattern, fname)) {
|
|
||||||
DirEntry* entry = &(contents->entry[contents->n_entries]);
|
|
||||||
strncpy(entry->path, fpath, 256);
|
|
||||||
entry->name = entry->path + (fname - fpath);
|
|
||||||
if (fno.fattrib & AM_DIR) {
|
|
||||||
entry->type = T_DIR;
|
|
||||||
entry->size = 0;
|
|
||||||
} else {
|
|
||||||
entry->type = T_FILE;
|
|
||||||
entry->size = fno.fsize;
|
|
||||||
}
|
|
||||||
entry->marked = 0;
|
|
||||||
if (contents->n_entries >= MAX_DIR_ENTRIES) {
|
|
||||||
ret = true; // Too many entries, still okay
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
contents->n_entries++;
|
|
||||||
}
|
|
||||||
if (recursive && (fno.fattrib & AM_DIR)) {
|
|
||||||
if (!GetDirContentsWorker(contents, fpath, fnsize, pattern, recursive))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f_closedir(&pdir);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SearchDirContents(DirStruct* contents, const char* path, const char* pattern, bool recursive) {
|
|
||||||
contents->n_entries = 0;
|
|
||||||
if (!(*path)) { // root directory
|
|
||||||
if (!GetRootDirContentsWorker(contents))
|
|
||||||
contents->n_entries = 0; // not required, but so what?
|
|
||||||
} else {
|
|
||||||
// create virtual '..' entry
|
|
||||||
contents->entry->name = contents->entry->path + 8;
|
|
||||||
strncpy(contents->entry->path, "*?*?*", 8);
|
|
||||||
strncpy(contents->entry->name, "..", 4);
|
|
||||||
contents->entry->type = T_DOTDOT;
|
|
||||||
contents->entry->size = 0;
|
|
||||||
contents->n_entries = 1;
|
|
||||||
// search the path
|
|
||||||
char fpath[256]; // 256 is the maximum length of a full path
|
|
||||||
strncpy(fpath, path, 256);
|
|
||||||
if (DriveType(path) & DRV_VIRTUAL) {
|
|
||||||
if (!GetVirtualDirContents(contents, fpath, 256, pattern, recursive))
|
|
||||||
contents->n_entries = 0;
|
|
||||||
} else {
|
|
||||||
if (!GetDirContentsWorker(contents, fpath, 256, pattern, recursive))
|
|
||||||
contents->n_entries = 0;
|
|
||||||
}
|
|
||||||
SortDirStruct(contents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetDirContents(DirStruct* contents, const char* path) {
|
|
||||||
if (IsSearchDrive(path)) {
|
|
||||||
ShowString("Searching, please wait...");
|
|
||||||
SearchDirContents(contents, search_path, search_pattern, true);
|
|
||||||
ClearScreenF(true, false, COLOR_STD_BG);
|
|
||||||
} else SearchDirContents(contents, path, NULL, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t GetFreeSpace(const char* path)
|
|
||||||
{
|
|
||||||
DWORD free_clusters;
|
|
||||||
FATFS *fs_ptr;
|
|
||||||
char fsname[4] = { '\0' };
|
|
||||||
int pdrv = PathToNumFSA(path);
|
|
||||||
if (pdrv < 0) return 0;
|
|
||||||
|
|
||||||
snprintf(fsname, 3, "%i:", pdrv);
|
|
||||||
if (f_getfree(fsname, &free_clusters, &fs_ptr) != FR_OK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (uint64_t) free_clusters * fs[pdrv].csize * _MAX_SS;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t GetTotalSpace(const char* path)
|
|
||||||
{
|
|
||||||
int pdrv = PathToNumFSA(path);
|
|
||||||
if (pdrv < 0) return 0;
|
|
||||||
|
|
||||||
return (uint64_t) (fs[pdrv].n_fatent - 2) * fs[pdrv].csize * _MAX_SS;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t GetPartitionOffsetSector(const char* path)
|
|
||||||
{
|
|
||||||
int pdrv = PathToNumFSA(path);
|
|
||||||
if (pdrv < 0) return -1;
|
|
||||||
|
|
||||||
return (uint64_t) fs[pdrv].volbase;
|
|
||||||
}
|
|
57
source/fs/fsutil.h
Normal file
57
source/fs/fsutil.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
// temporary
|
||||||
|
// #include "fsinit.h"
|
||||||
|
// #include "fsdrive.h"
|
||||||
|
// #include "fsperm.h"
|
||||||
|
|
||||||
|
// move / copy flags
|
||||||
|
#define ASK_ALL (1<<0)
|
||||||
|
#define SKIP_ALL (1<<1)
|
||||||
|
#define OVERWRITE_ALL (1<<2)
|
||||||
|
|
||||||
|
/** Return total size of SD card **/
|
||||||
|
uint64_t GetSDCardSize();
|
||||||
|
|
||||||
|
/** Format the SD card **/
|
||||||
|
bool FormatSDCard(u64 hidden_mb, u32 cluster_size);
|
||||||
|
|
||||||
|
/** True if file exists and is not locked, false otherwise **/
|
||||||
|
bool FileCheck(const char* path);
|
||||||
|
|
||||||
|
/** Create / open file and write the provided data to it **/
|
||||||
|
bool FileSetData(const char* path, const u8* data, size_t size, size_t foffset, bool create);
|
||||||
|
|
||||||
|
/** Read data from file@offset **/
|
||||||
|
size_t FileGetData(const char* path, u8* data, size_t size, size_t foffset);
|
||||||
|
|
||||||
|
/** Get size of file **/
|
||||||
|
size_t FileGetSize(const char* path);
|
||||||
|
|
||||||
|
/** Get SHA-256 of file **/
|
||||||
|
bool FileGetSha256(const char* path, u8* sha256);
|
||||||
|
|
||||||
|
/** Find data in file **/
|
||||||
|
u32 FileFindData(const char* path, u8* data, u32 size, u32 offset);
|
||||||
|
|
||||||
|
/** Inject file into file @offset **/
|
||||||
|
bool FileInjectFile(const char* dest, const char* orig, u32 offset);
|
||||||
|
|
||||||
|
/** Recursively copy a file or directory **/
|
||||||
|
bool PathCopy(const char* destdir, const char* orig, u32* flags);
|
||||||
|
|
||||||
|
/** Recursively move a file or directory **/
|
||||||
|
bool PathMove(const char* destdir, const char* orig, u32* flags);
|
||||||
|
|
||||||
|
/** Recursively delete a file or directory **/
|
||||||
|
bool PathDelete(const char* path);
|
||||||
|
|
||||||
|
/** Rename file / folder in path to new name **/
|
||||||
|
bool PathRename(const char* path, const char* newname);
|
||||||
|
|
||||||
|
/** Create a new directory in cpath **/
|
||||||
|
bool DirCreate(const char* cpath, const char* dirname);
|
||||||
|
|
||||||
|
/** Create a screenshot of the current framebuffer **/
|
||||||
|
void CreateScreenshot();
|
@ -1,7 +1,10 @@
|
|||||||
#include "godmode.h"
|
#include "godmode.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
#include "fs.h"
|
#include "fsinit.h"
|
||||||
|
#include "fsdrive.h"
|
||||||
|
#include "fsutil.h"
|
||||||
|
#include "fsperm.h"
|
||||||
#include "gameio.h"
|
#include "gameio.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "nand.h"
|
#include "nand.h"
|
||||||
@ -99,7 +102,7 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
|
|||||||
}
|
}
|
||||||
DrawStringF(TOP_SCREEN, 4, info_start + 12 + 10, color_current, COLOR_STD_BG, tempstr);
|
DrawStringF(TOP_SCREEN, 4, info_start + 12 + 10, color_current, COLOR_STD_BG, tempstr);
|
||||||
// path of file (if in search results)
|
// path of file (if in search results)
|
||||||
if (IsSearchDrive(curr_path) && strrchr(curr_entry->path, '/')) {
|
if ((DriveType(curr_path) & DRV_SEARCH) && strrchr(curr_entry->path, '/')) {
|
||||||
char dirstr[256];
|
char dirstr[256];
|
||||||
strncpy(dirstr, curr_entry->path, 256);
|
strncpy(dirstr, curr_entry->path, 256);
|
||||||
*(strrchr(dirstr, '/')+1) = '\0';
|
*(strrchr(dirstr, '/')+1) = '\0';
|
||||||
@ -625,7 +628,7 @@ u32 GodMode() {
|
|||||||
|
|
||||||
// basic navigation commands
|
// basic navigation commands
|
||||||
if ((pad_state & BUTTON_A) && (curr_entry->type != T_FILE) && (curr_entry->type != T_DOTDOT)) { // for dirs
|
if ((pad_state & BUTTON_A) && (curr_entry->type != T_FILE) && (curr_entry->type != T_DOTDOT)) { // for dirs
|
||||||
if (switched && !IsSearchDrive(curr_entry->path)) { // search directory
|
if (switched && !(DriveType(curr_entry->path) & DRV_SEARCH)) { // search directory
|
||||||
char searchstr[256];
|
char searchstr[256];
|
||||||
char namestr[20+1];
|
char namestr[20+1];
|
||||||
snprintf(searchstr, 256, "*");
|
snprintf(searchstr, 256, "*");
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "godmode.h"
|
#include "godmode.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "fs.h"
|
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
|
||||||
void Reboot()
|
void Reboot()
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#include "fs.h"
|
#include "nand.h"
|
||||||
|
#include "fsdrive.h"
|
||||||
|
#include "fsutil.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
#include "sha.h"
|
#include "sha.h"
|
||||||
#include "sdmmc.h"
|
#include "sdmmc.h"
|
||||||
#include "nand.h"
|
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
|
||||||
#define NAND_MIN_SECTORS ((GetUnitPlatform() == PLATFORM_N3DS) ? 0x26C000 : 0x1D7800)
|
#define NAND_MIN_SECTORS ((GetUnitPlatform() == PLATFORM_N3DS) ? 0x26C000 : 0x1D7800)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "dir.h"
|
#include "fsdir.h"
|
||||||
#include "nand.h"
|
#include "nand.h"
|
||||||
|
|
||||||
#define VRT_SYSNAND NAND_SYSNAND
|
#define VRT_SYSNAND NAND_SYSNAND
|
||||||
|
Loading…
x
Reference in New Issue
Block a user