diff --git a/include/fs.h b/include/fs.h index d1ac6bf..d925d3c 100644 --- a/include/fs.h +++ b/include/fs.h @@ -55,6 +55,7 @@ s32 fMount(FsDrive drive); s32 fUnmount(FsDrive drive); +s32 fGetFree(FsDrive drive, u64 *size); s32 fOpen(const char *const path, FsOpenMode mode); s32 fRead(s32 handle, void *const buf, u32 size); s32 fWrite(s32 handle, const void *const buf, u32 size); @@ -63,8 +64,8 @@ u32 fTell(s32 handle); u32 fSize(s32 handle); s32 fClose(s32 handle); -s32 fStat(const char *const path, FsFileInfo *fi); s32 fExpand(s32 handle, u32 size); +s32 fStat(const char *const path, FsFileInfo *fi); s32 fOpenDir(const char *const path); s32 fReadDir(s32 handle, FsFileInfo *fi, u32 num); s32 fCloseDir(s32 handle); diff --git a/include/ipc_handler.h b/include/ipc_handler.h index 2de4a0b..b213d7b 100644 --- a/include/ipc_handler.h +++ b/include/ipc_handler.h @@ -37,23 +37,23 @@ { IPC_CMD9_FMOUNT = CMD_ID(0) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), IPC_CMD9_FUNMOUNT = CMD_ID(1) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FOPEN = CMD_ID(2) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FREAD = CMD_ID(3) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(1), - IPC_CMD9_FWRITE = CMD_ID(4) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FSYNC = CMD_ID(5) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FLSEEK = CMD_ID(6) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(2), - IPC_CMD9_FTELL = CMD_ID(7) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FSIZE = CMD_ID(8) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FCLOSE = CMD_ID(9) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FSTAT = CMD_ID(10) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(1) | CMD_PARAMS(0), + IPC_CMD9_FGETFREE = CMD_ID(2) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(1), + IPC_CMD9_FOPEN = CMD_ID(3) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FREAD = CMD_ID(4) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(1), + IPC_CMD9_FWRITE = CMD_ID(5) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FSYNC = CMD_ID(6) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FLSEEK = CMD_ID(7) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(2), + IPC_CMD9_FTELL = CMD_ID(8) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FSIZE = CMD_ID(9) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FCLOSE = CMD_ID(10) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), IPC_CMD9_FEXPAND = CMD_ID(11) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(2), - IPC_CMD9_FOPEN_DIR = CMD_ID(12) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), // Invalid on purpose. Will be decided later. - IPC_CMD9_FREAD_DIR = CMD_ID(13) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(2), - IPC_CMD9_FCLOSE_DIR = CMD_ID(14) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), - IPC_CMD9_FMKDIR = CMD_ID(15) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_FRENAME = CMD_ID(16) | CMD_IN_BUFS(2) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_FUNLINK = CMD_ID(17) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), - IPC_CMD9_FGETFREE = CMD_ID(18) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(15), + IPC_CMD9_FSTAT = CMD_ID(12) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(1) | CMD_PARAMS(0), + IPC_CMD9_FOPEN_DIR = CMD_ID(13) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), // Invalid on purpose. Will be decided later. + IPC_CMD9_FREAD_DIR = CMD_ID(14) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(1) | CMD_PARAMS(2), + IPC_CMD9_FCLOSE_DIR = CMD_ID(15) | CMD_IN_BUFS(0) | CMD_OUT_BUFS(0) | CMD_PARAMS(1), + IPC_CMD9_FMKDIR = CMD_ID(16) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), + IPC_CMD9_FRENAME = CMD_ID(17) | CMD_IN_BUFS(2) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), + IPC_CMD9_FUNLINK = CMD_ID(18) | CMD_IN_BUFS(1) | CMD_OUT_BUFS(0) | CMD_PARAMS(0), IPC_CMD9_READ_SECTORS = CMD_ID(19) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(15), IPC_CMD9_WRITE_SECTORS = CMD_ID(20) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(15), IPC_CMD9_MALLOC = CMD_ID(21) | CMD_IN_BUFS(15) | CMD_OUT_BUFS(15) | CMD_PARAMS(15), diff --git a/source/arm11/fs.c b/source/arm11/fs.c index 4602e8d..2e27832 100644 --- a/source/arm11/fs.c +++ b/source/arm11/fs.c @@ -36,6 +36,16 @@ return PXI_sendCmd(IPC_CMD9_FUNMOUNT, &cmdBuf, 1); } +s32 fGetFree(FsDrive drive, u64 *size) +{ + u32 cmdBuf[3]; + cmdBuf[0] = (u32)size; + cmdBuf[1] = 8; + cmdBuf[2] = drive; + + return PXI_sendCmd(IPC_CMD9_FGETFREE, cmdBuf, 3); +} + s32 fOpen(const char *const path, FsOpenMode mode) { u32 cmdBuf[3]; @@ -99,6 +109,15 @@ return PXI_sendCmd(IPC_CMD9_FCLOSE, &cmdBuf, 1); } +s32 fExpand(s32 handle, u32 size) +{ + u32 cmdBuf[2]; + cmdBuf[0] = handle; + cmdBuf[1] = size; + + return PXI_sendCmd(IPC_CMD9_FEXPAND, cmdBuf, 2); +} + s32 fStat(const char *const path, FsFileInfo *fi) { u32 cmdBuf[4]; @@ -110,15 +129,6 @@ return PXI_sendCmd(IPC_CMD9_FSTAT, cmdBuf, 4); } -s32 fExpand(s32 handle, u32 size) -{ - u32 cmdBuf[2]; - cmdBuf[0] = handle; - cmdBuf[1] = size; - - return PXI_sendCmd(IPC_CMD9_FEXPAND, cmdBuf, 2); -} - s32 fOpenDir(const char *const path) { u32 cmdBuf[2]; diff --git a/source/arm9/fs.c b/source/arm9/fs.c index 68bac39..fb57749 100644 --- a/source/arm9/fs.c +++ b/source/arm9/fs.c @@ -63,6 +63,22 @@ else return -res; } +s32 fGetFree(FsDrive drive, u64 *size) +{ + if((u32)drive >= FS_MAX_DRIVES) return -30; + if(!fsStatTable[drive]) return -31; + + DWORD freeClusters; + FATFS *fs; + FRESULT res = f_getfree(fsPathTable[drive], &freeClusters, &fs); + if(res == FR_OK) + { + if(size) *size = ((u64)(freeClusters * fs->csize)) * 512; + return FR_OK; + } + else return -res; +} + static s32 findUnusedFileSlot(void) { if(fHandles >= FS_MAX_FILES) return -1; @@ -167,13 +183,6 @@ else return -res; } -s32 fStat(const char *const path, FsFileInfo *fi) -{ - FRESULT res = f_stat(path, fi); - if(res == FR_OK) return res; - else return -res; -} - s32 fExpand(s32 handle, u32 size) { if(!isFileHandleValid(handle)) return -30; @@ -183,6 +192,13 @@ else return -res; } +s32 fStat(const char *const path, FsFileInfo *fi) +{ + FRESULT res = f_stat(path, fi); + if(res == FR_OK) return res; + else return -res; +} + static s32 findUnusedDirSlot(void) { if(dHandles >= FS_MAX_DIRS) return -1; diff --git a/source/arm9/ipc_handler.c b/source/arm9/ipc_handler.c index f7dec85..b3ca286 100644 --- a/source/arm9/ipc_handler.c +++ b/source/arm9/ipc_handler.c @@ -42,6 +42,9 @@ case IPC_CMD_ID_MASK(IPC_CMD9_FUNMOUNT): result = fUnmount(buf[0]); break; + case IPC_CMD_ID_MASK(IPC_CMD9_FGETFREE): + result = fGetFree(buf[2], (u64*)buf[0]); + break; case IPC_CMD_ID_MASK(IPC_CMD9_FOPEN): result = fOpen((const char *const)buf[0], buf[2]); break; @@ -66,12 +69,12 @@ case IPC_CMD_ID_MASK(IPC_CMD9_FCLOSE): result = fClose(buf[0]); break; - case IPC_CMD_ID_MASK(IPC_CMD9_FSTAT): - result = fStat((const char *const)buf[0], (FsFileInfo*)buf[2]); - break; case IPC_CMD_ID_MASK(IPC_CMD9_FEXPAND): result = fExpand(buf[0], buf[1]); break; + case IPC_CMD_ID_MASK(IPC_CMD9_FSTAT): + result = fStat((const char *const)buf[0], (FsFileInfo*)buf[2]); + break; case IPC_CMD_ID_MASK(IPC_CMD9_FOPEN_DIR): result = fOpenDir((const char *const)buf[0]); break; @@ -90,8 +93,6 @@ case IPC_CMD_ID_MASK(IPC_CMD9_FUNLINK): result = fUnlink((const char *const)buf[0]); break; - case IPC_CMD_ID_MASK(IPC_CMD9_FGETFREE): - break; case IPC_CMD_ID_MASK(IPC_CMD9_READ_SECTORS): break; case IPC_CMD_ID_MASK(IPC_CMD9_WRITE_SECTORS):