From cbea40e42e13f94b059b96906b649528a49bed0f Mon Sep 17 00:00:00 2001 From: J-D-K Date: Fri, 8 May 2020 02:30:41 -0400 Subject: [PATCH] Add back RomFS opening to extras, add free space checks --- Makefile | 2 +- README.MD | 2 +- inc/file.h | 4 ++++ inc/ui.h | 2 +- src/ex.c | 35 +------------------------------ src/file.cpp | 52 +++++++++++++++++++++++++++++++--------------- src/main.cpp | 9 +++++++- src/ui.cpp | 4 ++-- src/ui/advmode.cpp | 4 ++-- src/ui/fldrsel.cpp | 2 +- src/ui/ttlsel.cpp | 2 +- src/ui/txtui.cpp | 4 ++-- 12 files changed, 59 insertions(+), 63 deletions(-) diff --git a/Makefile b/Makefile index a9c8e68..39f911f 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ INCLUDES := inc EXEFS_SRC := exefs_src APP_TITLE := JKSV APP_AUTHOR := JK -APP_VERSION := 04.30.2020 +APP_VERSION := 05.08.2020 ROMFS := romfs #--------------------------------------------------------------------------------- diff --git a/README.MD b/README.MD index c8dae15..0f330b1 100644 --- a/README.MD +++ b/README.MD @@ -17,7 +17,7 @@ JKSV on Switch started as a small project/port to test some things and get famil * Ability to remove downloaded firmware updates from NAND. * Terminating processes by [ID](https://switchbrew.org/wiki/Title_list#System_Modules). Allowing you to dump normally unopenable system archives. * Mount by System Save [ID](https://switchbrew.org/wiki/Flash_Filesystem#System_Savegames). Normally used when the terminated process makes JKSV unable to rescan titles without the Switch crashing. - * Mount and open RomFS of process the homebrew menu takes over (if launched as NRO) (To be re-added later) + * Mount and open RomFS of process the homebrew menu takes over (if launched as NRO). * Hold R while opening a game or applet with Atmosphere so the homebrew menu loads. Open JKSV and press minus and select **Mount Process RomFS**. The romfs of the app should appear in the browser along with your SD on the right. ## Quick Guide diff --git a/inc/file.h b/inc/file.h index 1f995c7..d9de04c 100644 --- a/inc/file.h +++ b/inc/file.h @@ -39,6 +39,10 @@ namespace fs void getDirProps(const std::string& _path, uint32_t& dirCount, uint32_t& fileCount, uint64_t& totalSize); bool fileExists(const std::string& _path); + //Returns file size + size_t fsize(const std::string& _f); + //Returns if device in path has space needed. Device is gotten from file path. + bool hasFreeSpace(const std::string& _f, int needed); bool isDir(const std::string& _path); std::string getWorkDir(); diff --git a/inc/ui.h b/inc/ui.h index d70836d..16058f3 100644 --- a/inc/ui.h +++ b/inc/ui.h @@ -66,7 +66,7 @@ namespace ui void initTheme(); //Loads graphics and stuff - void init(); + void init(void *a); void exit(); //Prepares ui diff --git a/src/ex.c b/src/ex.c index 4aa2148..3920146 100644 --- a/src/ex.c +++ b/src/ex.c @@ -4,38 +4,5 @@ Result fsOpenDataFileSystemByCurrentProcess(FsFileSystem *out) { - /* - Result ret = 0; - - IpcCommand c; - ipcInitialize(&c); - struct - { - uint64_t mag; - uint64_t cmd; - } *raw = serviceIpcPrepareHeader(fsGetServiceSession(), &c, sizeof(*raw)); - raw->mag = SFCI_MAGIC; - raw->cmd = 2; - - ret = serviceIpcDispatch(fsGetServiceSession()); - if(R_SUCCEEDED(ret)) - { - IpcParsedCommand p; - struct - { - uint64_t mag; - uint64_t res; - } *resp; - - serviceIpcParse(fsGetServiceSession(), &p, sizeof(*resp)); - resp = p.Raw; - - ret = resp->res; - if(R_SUCCEEDED(ret)) - serviceCreateSubservice(&out->s, fsGetServiceSession(), &p, 0); - } - - return ret;*/ - - return 1; + return serviceDispatch(fsGetServiceSession(), 2, 0, .out_num_objects = 1, .out_objects = &out->s); } diff --git a/src/file.cpp b/src/file.cpp index 57a459a..4a03620 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -114,20 +114,6 @@ static void copyfileCommit_t(void *a) args->fin = true; } -static inline size_t fsize(const std::string& _f) -{ - size_t ret = 0; - FILE *get = fopen(_f.c_str(), "rb"); - if(get != NULL) - { - fseek(get, 0, SEEK_END); - ret = ftell(get); - fseek(get, 0, SEEK_SET); - } - fclose(get); - return ret; -} - static void mkdirRec(const std::string& _p) { //skip first slash @@ -177,7 +163,7 @@ namespace fs switch(open.getType()) { case FsSaveDataType_System: - svOpen = fsOpen_SystemSaveData(&sv, FsSaveDataSpaceId_System, open.getID(), (AccountUid){0}); + svOpen = fsOpen_SystemSaveData(&sv, FsSaveDataSpaceId_System, open.getID(), (AccountUid) {0}); break; case FsSaveDataType_Account: @@ -373,7 +359,10 @@ namespace fs std::string fullFrom = from + list.getItem(i); std::string fullTo = to + list.getItem(i); - copyFile(fullFrom, fullTo); + if(hasFreeSpace(fullTo, fsize(fullFrom))) + copyFile(fullFrom, fullTo); + else + ui::showMessage("*Error*", "Not enough free space to copy #%s#!", fullFrom.c_str()); } } } @@ -398,7 +387,10 @@ namespace fs std::string fullFrom = from + list.getItem(i); std::string fullTo = to + list.getItem(i); - copyFileCommit(fullFrom, fullTo, dev); + if(hasFreeSpace(fullTo, fsize(fullFrom))) + copyFileCommit(fullFrom, fullTo, dev); + else + ui::showMessage("*Error*", "Not enough free space to copy #%s#!", fullFrom.c_str()); } } } @@ -517,6 +509,32 @@ namespace fs return false; } + size_t fsize(const std::string& _f) + { + size_t ret = 0; + FILE *get = fopen(_f.c_str(), "rb"); + if(get != NULL) + { + fseek(get, 0, SEEK_END); + ret = ftell(get); + fseek(get, 0, SEEK_SET); + } + fclose(get); + return ret; + } + + bool hasFreeSpace(const std::string& _f, int needed) + { + s64 free = 0; + //grab device from _f + size_t endDevPos = _f.find(':', 0); + std::string dev; + dev.assign(_f.begin(), _f.begin() + endDevPos); + fsFsGetFreeSpace(fsdevGetDeviceFileSystem(dev.c_str()), "/", &free); + + return free > needed; + } + std::string getWorkDir() { return wd; } bool isDir(const std::string& _path) diff --git a/src/main.cpp b/src/main.cpp index 0728806..c04a672 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,8 +40,15 @@ int main(int argc, const char *argv[]) graphicsInit(1280, 720); //Needed for icon gen ui::initTheme(); + + /*Not completely stable yet + Thread uiInitThrd; + threadCreate(&uiInitThrd, ui::init, NULL, NULL, 0x80000, 0x2B, -2); + threadStart(&uiInitThrd);*/ data::init(); - ui::init(); + ui::init(NULL); + /*threadWaitForExit(&uiInitThrd); + threadClose(&uiInitThrd);*/ while(appletMainLoop()) { diff --git a/src/ui.cpp b/src/ui.cpp index 78f6bf0..2333f2d 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -10,7 +10,7 @@ #include "util.h" #include "file.h" -#define VER_STRING "v. 04.30.2020" +#define VER_STRING "v. 05.08.2020" //Nav buttons std::vector usrNav, ttlNav, fldNav; @@ -123,7 +123,7 @@ namespace ui } } - void init() + void init(void *a) { mnuTopLeft = texLoadPNGFile("romfs:/img/fb/menuTopLeft.png"); mnuTopRight = texLoadPNGFile("romfs:/img/fb/menuTopRight.png"); diff --git a/src/ui/advmode.cpp b/src/ui/advmode.cpp index 46e15c3..22c9f16 100644 --- a/src/ui/advmode.cpp +++ b/src/ui/advmode.cpp @@ -65,7 +65,7 @@ void performCopyMenuOps() //just copy file std::string fromPath = savePath + saveList.getItem(saveSel); std::string toPath = sdPath + saveList.getItem(saveSel); - if(ui::confirmTransfer(fromPath, toPath)) + if(ui::confirmTransfer(fromPath, toPath) && fs::hasFreeSpace(toPath, fs::fsize(fromPath))) fs::copyFile(fromPath, toPath); } } @@ -99,7 +99,7 @@ void performCopyMenuOps() { std::string fromPath = sdPath + sdList.getItem(sdSel); std::string toPath = savePath + sdList.getItem(sdSel); - if(ui::confirmTransfer(fromPath, toPath)) + if(ui::confirmTransfer(fromPath, toPath) && fs::hasFreeSpace(toPath, fs::fsize(fromPath))) commit ? fs::copyFileCommit(fromPath, toPath, dev) : fs::copyFile(fromPath, toPath); } } diff --git a/src/ui/fldrsel.cpp b/src/ui/fldrsel.cpp index 6b034b7..5481862 100644 --- a/src/ui/fldrsel.cpp +++ b/src/ui/fldrsel.cpp @@ -151,7 +151,7 @@ namespace ui advModePrep("sv:/", true); mstate = ADV_MDE; } - else if(down & KEY_ZR && confirm(true, ui::confEraseFolder.c_str(), data::curData.getTitle().c_str())) + else if(down & KEY_ZR && data::curData.getType() != FsSaveDataType_System && confirm(true, ui::confEraseFolder.c_str(), data::curData.getTitle().c_str())) { fs::delDir("sv:/"); fsdevCommitDevice("sv"); diff --git a/src/ui/ttlsel.cpp b/src/ui/ttlsel.cpp index 8171304..62c0490 100644 --- a/src/ui/ttlsel.cpp +++ b/src/ui/ttlsel.cpp @@ -225,7 +225,7 @@ namespace ui { data::titledata tempData = data::curUser.titles[data::selData]; if(tempData.getType() == FsSaveDataType_System) - ui::showMessage("Deleting system save archives is disabled.", "*NO*"); + ui::showMessage("*NO*", "Deleting system save archives is disabled."); else if(confirm(true, ui::confEraseNand.c_str(), tempData.getTitle().c_str())) { fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tempData.getSaveID()); diff --git a/src/ui/txtui.cpp b/src/ui/txtui.cpp index 028ef81..4094a52 100644 --- a/src/ui/txtui.cpp +++ b/src/ui/txtui.cpp @@ -179,7 +179,7 @@ namespace ui { data::titledata tempData = data::curUser.titles[titleMenu.getSelected()]; if(tempData.getType() == FsSaveDataType_System) - ui::showMessage("Deleting system save archives is disabled.", "*NO*"); + ui::showMessage("*NO*", "Deleting system save archives is disabled."); else if(confirm(true, ui::confEraseNand.c_str(), tempData.getTitle().c_str())) { fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tempData.getSaveID()); @@ -310,7 +310,7 @@ namespace ui advModePrep("sv:/", true); mstate = ADV_MDE; } - else if(down & KEY_ZR && confirm(true, ui::confEraseFolder.c_str(), data::curData.getTitle().c_str())) + else if(down & KEY_ZR && data::curData.getType() != FsSaveDataType_System && confirm(true, ui::confEraseFolder.c_str(), data::curData.getTitle().c_str())) { fs::delDir("sv:/"); fsdevCommitDevice("sv");