2016-02-13 17:29:56 +01:00
|
|
|
#include "draw.h"
|
2016-02-25 16:57:01 +01:00
|
|
|
#include "fs.h"
|
2016-02-13 17:29:56 +01:00
|
|
|
#include "fatfs/ff.h"
|
2016-02-25 16:57:01 +01:00
|
|
|
#include "fatfs/nandio.h"
|
2016-02-13 17:29:56 +01:00
|
|
|
|
2016-02-25 16:57:01 +01:00
|
|
|
// don't use this area for anything else!
|
2016-02-26 17:03:25 +01:00
|
|
|
static FATFS* fs = (FATFS*)0x20316000;
|
2016-02-25 16:57:01 +01:00
|
|
|
// reserve one MB for this, just to be safe
|
|
|
|
static DirStruct* curdir_contents = (DirStruct*)0x21000000;
|
|
|
|
// this is the main buffer
|
|
|
|
// static u8* main_buffer = (u8*)0x21100000;
|
|
|
|
// number of currently open file systems
|
|
|
|
static u32 numfs = 0;
|
2016-02-13 17:29:56 +01:00
|
|
|
|
|
|
|
bool InitFS()
|
|
|
|
{
|
2016-02-25 16:57:01 +01:00
|
|
|
#ifndef EXEC_GATEWAY
|
2016-02-13 17:29:56 +01:00
|
|
|
// TODO: Magic?
|
|
|
|
*(u32*)0x10000020 = 0;
|
|
|
|
*(u32*)0x10000020 = 0x340;
|
|
|
|
#endif
|
2016-02-25 16:57:01 +01:00
|
|
|
for (numfs = 0; numfs < 16; numfs++) {
|
|
|
|
char fsname[8];
|
2016-02-26 17:03:25 +01:00
|
|
|
snprintf(fsname, 8, "%lu:", numfs);
|
|
|
|
int res = f_mount(fs + numfs, fsname, 1);
|
|
|
|
if (res != FR_OK) {
|
|
|
|
if (numfs >= 4) break;
|
|
|
|
ShowError("Initialising failed! (%lu/%s/%i)", numfs, fsname, res);
|
2016-02-25 16:57:01 +01:00
|
|
|
DeinitFS();
|
|
|
|
return false;
|
2016-02-13 17:29:56 +01:00
|
|
|
}
|
|
|
|
}
|
2016-02-26 17:03:25 +01:00
|
|
|
ShowError("Mounted: %i partitions", numfs);
|
2016-02-13 17:29:56 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-02-25 16:57:01 +01:00
|
|
|
void DeinitFS()
|
2016-02-13 17:29:56 +01:00
|
|
|
{
|
2016-02-25 16:57:01 +01:00
|
|
|
for (u32 i = 0; i < numfs; i++) {
|
|
|
|
char fsname[8];
|
|
|
|
snprintf(fsname, 7, "%lu:", numfs);
|
|
|
|
f_mount(NULL, fsname, 1);
|
2016-02-13 17:29:56 +01:00
|
|
|
}
|
2016-02-25 16:57:01 +01:00
|
|
|
numfs = 0;
|
2016-02-13 17:29:56 +01:00
|
|
|
}
|
|
|
|
|
2016-02-25 16:57:01 +01:00
|
|
|
bool GetRootDirContentsWorker(DirStruct* contents)
|
2016-02-13 17:29:56 +01:00
|
|
|
{
|
2016-02-25 16:57:01 +01:00
|
|
|
static const char* drvname[16] = {
|
2016-02-26 17:03:25 +01:00
|
|
|
"SDCARD",
|
|
|
|
"SYSCTRN", "SYSTWLN", "SYSTWLP",
|
|
|
|
"EMU0CTRN", "EMU0TWLN", "EMU0TWLP",
|
|
|
|
"EMU1CTRN", "EMU1TWLN", "EMU1TWLP",
|
|
|
|
"EMU2CTRN", "EMU2TWLN", "EMU2TWLP",
|
|
|
|
"EMU3CTRN", "EMU3TWLN", "EMU3TWLP"
|
2016-02-25 16:57:01 +01:00
|
|
|
};
|
2016-02-13 17:29:56 +01:00
|
|
|
|
2016-02-25 16:57:01 +01:00
|
|
|
for (u32 pdrv = 0; (pdrv < numfs) && (pdrv < MAX_ENTRIES); pdrv++) {
|
|
|
|
memset(contents->entry[pdrv].path, 0x00, 16);
|
2016-02-26 17:03:25 +01:00
|
|
|
snprintf(contents->entry[pdrv].path + 0, 4, "%lu:", pdrv);
|
2016-02-26 18:52:30 +01:00
|
|
|
snprintf(contents->entry[pdrv].path + 4, 16, "[%lu:] %s", pdrv, drvname[pdrv]);
|
2016-02-25 16:57:01 +01:00
|
|
|
contents->entry[pdrv].name = contents->entry[pdrv].path + 4;
|
|
|
|
contents->entry[pdrv].size = 0;
|
2016-02-26 18:52:30 +01:00
|
|
|
contents->entry[pdrv].type = T_FAT_DIR;
|
2016-02-13 17:29:56 +01:00
|
|
|
}
|
2016-02-26 17:03:25 +01:00
|
|
|
contents->n_entries = numfs;
|
2016-02-13 17:29:56 +01:00
|
|
|
|
2016-02-25 16:57:01 +01:00
|
|
|
return contents->n_entries;
|
2016-02-13 17:29:56 +01:00
|
|
|
}
|
|
|
|
|
2016-02-25 16:57:01 +01:00
|
|
|
bool GetDirContentsWorker(DirStruct* contents, char* fpath, int fsize, bool recursive)
|
2016-02-13 17:29:56 +01:00
|
|
|
{
|
|
|
|
DIR pdir;
|
|
|
|
FILINFO fno;
|
|
|
|
char* fname = fpath + strnlen(fpath, fsize - 1);
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
if (f_opendir(&pdir, fpath) != FR_OK)
|
|
|
|
return false;
|
|
|
|
(fname++)[0] = '/';
|
|
|
|
fno.lfname = fname;
|
|
|
|
fno.lfsize = fsize - (fname - fpath);
|
|
|
|
|
|
|
|
while (f_readdir(&pdir, &fno) == FR_OK) {
|
|
|
|
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
|
|
|
|
continue; // filter out virtual entries
|
|
|
|
if (fname[0] == 0)
|
|
|
|
strncpy(fname, fno.fname, (fsize - 1) - (fname - fpath));
|
|
|
|
if (fno.fname[0] == 0) {
|
|
|
|
ret = true;
|
|
|
|
break;
|
2016-02-25 16:57:01 +01:00
|
|
|
} else {
|
|
|
|
DirEntry* entry = &(contents->entry[contents->n_entries]);
|
2016-02-26 18:52:30 +01:00
|
|
|
strncpy(entry->path, fpath, 256);
|
|
|
|
entry->name = entry->path + (fname - fpath);
|
2016-02-25 16:57:01 +01:00
|
|
|
if (fno.fattrib & AM_DIR) {
|
|
|
|
entry->type = T_FAT_DIR;
|
|
|
|
entry->size = 0;
|
|
|
|
} else {
|
|
|
|
entry->type = T_FAT_FILE;
|
|
|
|
entry->size = fno.fsize;
|
|
|
|
}
|
|
|
|
contents->n_entries++;
|
|
|
|
if (contents->n_entries >= MAX_ENTRIES)
|
|
|
|
break;
|
2016-02-13 17:29:56 +01:00
|
|
|
}
|
|
|
|
if (recursive && (fno.fattrib & AM_DIR)) {
|
2016-02-25 16:57:01 +01:00
|
|
|
if (!GetDirContentsWorker(contents, fpath, fsize, recursive))
|
2016-02-13 17:29:56 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f_closedir(&pdir);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-02-25 16:57:01 +01:00
|
|
|
DirStruct* GetDirContents(const char* path)
|
2016-02-13 17:29:56 +01:00
|
|
|
{
|
2016-02-25 16:57:01 +01:00
|
|
|
curdir_contents->n_entries = 0;
|
|
|
|
if (strncmp(path, "", 256) == 0) { // root directory
|
|
|
|
if (!GetRootDirContentsWorker(curdir_contents))
|
|
|
|
curdir_contents->n_entries = 0; // not required, but so what?
|
|
|
|
} else {
|
|
|
|
char fpath[256]; // 256 is the maximum length of a full path
|
|
|
|
strncpy(fpath, path, 256);
|
|
|
|
if (!GetDirContentsWorker(curdir_contents, fpath, 256, false))
|
|
|
|
curdir_contents->n_entries = 0;
|
2016-02-13 17:29:56 +01:00
|
|
|
}
|
|
|
|
|
2016-02-25 16:57:01 +01:00
|
|
|
return curdir_contents;
|
2016-02-13 17:29:56 +01:00
|
|
|
}
|
|
|
|
|
2016-02-25 16:57:01 +01:00
|
|
|
/*static uint64_t ClustersToBytes(FATFS* fs, DWORD clusters)
|
2016-02-13 17:29:56 +01:00
|
|
|
{
|
|
|
|
uint64_t sectors = clusters * fs->csize;
|
|
|
|
#if _MAX_SS != _MIN_SS
|
|
|
|
return sectors * fs->ssize;
|
|
|
|
#else
|
|
|
|
return sectors * _MAX_SS;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t RemainingStorageSpace()
|
|
|
|
{
|
|
|
|
DWORD free_clusters;
|
|
|
|
FATFS *fs2;
|
|
|
|
FRESULT res = f_getfree("0:", &free_clusters, &fs2);
|
|
|
|
if (res)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return ClustersToBytes(&fs, free_clusters);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t TotalStorageSpace()
|
|
|
|
{
|
|
|
|
return ClustersToBytes(&fs, fs.n_fatent - 2);
|
2016-02-25 16:57:01 +01:00
|
|
|
}*/
|