forked from Mirror/SafeB9SInstaller
100 lines
2.4 KiB
C
100 lines
2.4 KiB
C
|
#include "qff.h"
|
||
|
|
||
|
#define NUM_FS 4
|
||
|
|
||
|
// don't use this area for anything else!
|
||
|
static FATFS* fs = (FATFS*) 0x20316000;
|
||
|
|
||
|
// currently open file systems
|
||
|
static FRESULT fs_mounted[NUM_FS] = { FR_NOT_READY };
|
||
|
|
||
|
FRESULT f_qread (const TCHAR* path, void* buff, FSIZE_t ofs, UINT btr, UINT* br) {
|
||
|
FIL fp;
|
||
|
FRESULT res;
|
||
|
UINT brl;
|
||
|
if (!br) br = &brl;
|
||
|
|
||
|
res = f_open(&fp, path, FA_READ | FA_OPEN_EXISTING);
|
||
|
if (res != FR_OK) return res;
|
||
|
|
||
|
res = f_lseek(&fp, ofs);
|
||
|
if (res != FR_OK) {
|
||
|
f_close(&fp);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
res = f_read(&fp, buff, btr, br);
|
||
|
f_close(&fp);
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
FRESULT f_qwrite (const TCHAR* path, const void* buff, FSIZE_t ofs, UINT btw, UINT* bw) {
|
||
|
FIL fp;
|
||
|
FRESULT res;
|
||
|
UINT bwl;
|
||
|
if (!bw) bw = &bwl;
|
||
|
|
||
|
res = f_open(&fp, path, FA_WRITE | FA_OPEN_ALWAYS);
|
||
|
if (res != FR_OK) return res;
|
||
|
|
||
|
res = f_lseek(&fp, ofs);
|
||
|
if (res != FR_OK) {
|
||
|
f_close(&fp);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
res = f_write(&fp, buff, btw, bw);
|
||
|
f_close(&fp);
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
FATFS* fs_getobj(const TCHAR* path) {
|
||
|
UINT fsnum = (path[1] == ':') ? *path - '0' : -1;
|
||
|
return ((fsnum < NUM_FS) && (fs_mounted[fsnum] == FR_OK)) ? &fs[fsnum] : (FATFS*) 0;
|
||
|
}
|
||
|
|
||
|
FRESULT f_getfreebyte (const TCHAR* path, QWORD* bt) {
|
||
|
DWORD free_clusters;
|
||
|
FATFS* fsptr;
|
||
|
FRESULT res;
|
||
|
|
||
|
res = f_getfree(path, &free_clusters, &fsptr);
|
||
|
if (res != FR_OK) return res;
|
||
|
|
||
|
FATFS* fsobj = fs_getobj(path);
|
||
|
if (!fsobj) return FR_NOT_READY;
|
||
|
*bt = (QWORD) free_clusters * fsobj->csize * _MAX_SS;
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
FRESULT f_gettotalbyte (const TCHAR* path, QWORD* bt) {
|
||
|
FATFS* fsobj = fs_getobj(path);
|
||
|
*bt = (fsobj) ? ((QWORD) (fsobj->n_fatent - 2) * fsobj->csize * _MAX_SS) : 0;
|
||
|
return *bt ? FR_OK : FR_NOT_READY;
|
||
|
}
|
||
|
|
||
|
FRESULT fs_init(void) {
|
||
|
for (UINT i = 0; i < NUM_FS; i++) {
|
||
|
TCHAR* fsname = "X:";
|
||
|
*fsname = (TCHAR) ('0' + i);
|
||
|
if (fs_mounted[i] == FR_OK) continue;
|
||
|
fs_mounted[i] = f_mount(fs + i, fsname, 1);
|
||
|
if ((fs_mounted[i] != FR_OK) && (i == 0)) return fs_mounted[i]; // SD can't fail
|
||
|
}
|
||
|
return FR_OK;
|
||
|
}
|
||
|
|
||
|
FRESULT fs_deinit(void) {
|
||
|
for (UINT i = 0; i < NUM_FS; i++) {
|
||
|
TCHAR* fsname = "X:";
|
||
|
*fsname = (TCHAR) ('0' + i);
|
||
|
if (fs_mounted[i] != FR_OK) continue;
|
||
|
f_mount(0, fsname, 1);
|
||
|
fs_mounted[i] = FR_NOT_READY;
|
||
|
}
|
||
|
return FR_OK;
|
||
|
}
|