mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Basic uninstaller support for title.db entries
This commit is contained in:
parent
6eb546dfab
commit
f0ad45dd60
@ -53,6 +53,7 @@
|
||||
#define FTYPE_CIABUILD_L(tp) (FTYPE_CIABUILD(tp) && (tp&(GAME_TMD)))
|
||||
#define FTYPE_CIAINSTALL(tp) ((tp&(GAME_NCSD|GAME_NCCH|GAME_CIA)) || ((tp&GAME_NDS)&&(tp&(FLAG_DSIW))) || (tp&(GAME_TMD)&&(tp&(FLAG_NUSCDN))))
|
||||
#define FTYPE_CXIDUMP(tp) (tp&(GAME_TMD))
|
||||
#define FTYPE_UNINSTALL(tp) (tp&(GAME_TIE))
|
||||
#define FTYPE_TIKBUILD(tp) (tp&(GAME_TICKET|SYS_TICKDB|BIN_TIKDB))
|
||||
#define FTYPE_KEYBUILD(tp) (tp&(BIN_KEYDB|BIN_LEGKEY))
|
||||
#define FTYPE_TITLEINFO(tp) (tp&(GAME_TIE|GAME_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD|GAME_NDS|GAME_GBA|GAME_TAD|GAME_3DSX))
|
||||
|
@ -1094,6 +1094,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
||||
bool cia_buildable_legit = (FTYPE_CIABUILD_L(filetype));
|
||||
bool cia_installable = (FTYPE_CIAINSTALL(filetype)) && !(drvtype & DRV_CTRNAND) &&
|
||||
!(drvtype & DRV_TWLNAND) && !(drvtype & DRV_ALIAS);
|
||||
bool uninstallable = (FTYPE_UNINSTALL(filetype));
|
||||
bool cxi_dumpable = (FTYPE_CXIDUMP(filetype));
|
||||
bool tik_buildable = (FTYPE_TIKBUILD(filetype)) && !in_output_path;
|
||||
bool key_buildable = (FTYPE_KEYBUILD(filetype)) && !in_output_path &&
|
||||
@ -1165,7 +1166,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
||||
(filetype & GAME_EXEFS) ? "Mount as EXEFS image" :
|
||||
(filetype & GAME_ROMFS) ? "Mount as ROMFS image" :
|
||||
(filetype & GAME_TMD ) ? "TMD file options..." :
|
||||
(filetype & GAME_TIE ) ? "Show title info" :
|
||||
(filetype & GAME_TIE ) ? "Manage Title..." :
|
||||
(filetype & GAME_BOSS ) ? "BOSS file options..." :
|
||||
(filetype & GAME_NUSCDN)? "Decrypt NUS/CDN file" :
|
||||
(filetype & GAME_SMDH) ? "Show SMDH title info" :
|
||||
@ -1315,6 +1316,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
||||
int cia_build_legit = (cia_buildable_legit) ? ++n_opt : -1;
|
||||
int cxi_dump = (cxi_dumpable) ? ++n_opt : -1;
|
||||
int cia_install = (cia_installable) ? ++n_opt : -1;
|
||||
int uninstall = (uninstallable) ? ++n_opt : -1;
|
||||
int tik_build_enc = (tik_buildable) ? ++n_opt : -1;
|
||||
int tik_build_dec = (tik_buildable) ? ++n_opt : -1;
|
||||
int key_build = (key_buildable) ? ++n_opt : -1;
|
||||
@ -1347,7 +1349,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
||||
if (cia_build > 0) optionstr[cia_build-1] = (cia_build_legit < 0) ? "Build CIA from file" : "Build CIA (standard)";
|
||||
if (cia_build_legit > 0) optionstr[cia_build_legit-1] = "Build CIA (legit)";
|
||||
if (cxi_dump > 0) optionstr[cxi_dump-1] = "Dump CXI/NDS file";
|
||||
if (cia_install > 0) optionstr[cia_install-1] = "Install game file";
|
||||
if (cia_install > 0) optionstr[cia_install-1] = "Install game image";
|
||||
if (uninstall > 0) optionstr[uninstall-1] = "Uninstall title";
|
||||
if (tik_build_enc > 0) optionstr[tik_build_enc-1] = "Build " TIKDB_NAME_ENC;
|
||||
if (tik_build_dec > 0) optionstr[tik_build_dec-1] = "Build " TIKDB_NAME_DEC;
|
||||
if (key_build > 0) optionstr[key_build-1] = "Build " KEYDB_NAME;
|
||||
@ -1601,6 +1604,43 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (user_select == uninstall) { // -> uninstall title
|
||||
bool full_uninstall = false;
|
||||
|
||||
// safety confirmation
|
||||
optionstr[0] = "Keep ticket & savegame";
|
||||
optionstr[1] = "Uninstall everything";
|
||||
optionstr[2] = "Abort uninstall";
|
||||
user_select = (int) (n_marked > 1) ?
|
||||
ShowSelectPrompt(3, optionstr, "Uninstall %lu selected titles?", n_marked) :
|
||||
ShowSelectPrompt(3, optionstr, "%s\nUninstall selected title?", pathstr);
|
||||
full_uninstall = (user_select == 2);
|
||||
if (!user_select || (user_select == 3))
|
||||
return 0;
|
||||
|
||||
// batch uninstall
|
||||
if (n_marked > 1) {
|
||||
u32 n_success = 0;
|
||||
u32 num = 0;
|
||||
ShowProgress(0, 0, "batch uninstall");
|
||||
for (u32 i = 0; i < current_dir->n_entries; i++) {
|
||||
const char* path = current_dir->entry[i].path;
|
||||
if (!current_dir->entry[i].marked) continue;
|
||||
if (!(IdentifyFileType(path) & filetype & TYPE_BASE)) continue;
|
||||
if (!ShowProgress(++num, n_marked, path)) break;
|
||||
if (UninstallGameDataTie(path, true, full_uninstall, full_uninstall) == 0)
|
||||
n_success++;
|
||||
}
|
||||
ShowPrompt(false, "%lu/%lu titles uninstalled", n_success, n_marked);
|
||||
} else {
|
||||
ShowString("%s\nUninstalling, please wait...", pathstr);
|
||||
if (UninstallGameDataTie(file_path, true, full_uninstall, full_uninstall) != 0)
|
||||
ShowPrompt(false, "%s\nUninstall failed!", pathstr);
|
||||
}
|
||||
|
||||
GetDirContents(current_dir, current_path);
|
||||
return 0;
|
||||
}
|
||||
else if (user_select == verify) { // -> verify game / nand file
|
||||
if ((n_marked > 1) && ShowPrompt(true, "Try to verify all %lu selected files?", n_marked)) {
|
||||
u32 n_success = 0;
|
||||
|
@ -1353,6 +1353,83 @@ u32 GetInstallSavePath(char* path, const char* drv, u64 tid64) {
|
||||
}
|
||||
}
|
||||
|
||||
u32 UninstallGameData(u64 tid64, bool remove_tie, bool remove_ticket, bool remove_save, bool from_emunand) {
|
||||
char drv[3];
|
||||
|
||||
// check permissions for SysNAND (this includes everything we need)
|
||||
if (!CheckWritePermissions(from_emunand ? "4:" : "1:")) return 1;
|
||||
|
||||
// determine the drive
|
||||
if (GetInstallDataDrive(drv, tid64, from_emunand) != 0) return 1;
|
||||
|
||||
// remove data path
|
||||
char path_data[256];
|
||||
if (GetInstallPath(path_data, drv, tid64, NULL, remove_save ? NULL : "content") != 0) return 1;
|
||||
fvx_runlink(path_data);
|
||||
|
||||
// clear leftovers
|
||||
if (GetInstallPath(path_data, drv, tid64, NULL, NULL) != 0)
|
||||
fvx_unlink(path_data);
|
||||
// system save is *not* cleared in any case (!!!)
|
||||
|
||||
// remove titledb entry / ticket
|
||||
u32 ret = 0;
|
||||
if (remove_tie || remove_ticket) {
|
||||
// ensure remounting the old mount path
|
||||
char path_store[256] = { 0 };
|
||||
char* path_bak = NULL;
|
||||
strncpy(path_store, GetMountPath(), 256);
|
||||
if (*path_store) path_bak = path_store;
|
||||
|
||||
// we need the big endian title ID
|
||||
u8 title_id[8];
|
||||
for (u32 i = 0; i < 8; i++)
|
||||
title_id[i] = (tid64 >> ((7-i)*8)) & 0xFF;
|
||||
|
||||
// ticket database
|
||||
if (remove_ticket) {
|
||||
char path_ticketdb[256];
|
||||
if ((GetInstallDbsPath(path_ticketdb, drv, "ticket.db") != 0) || !InitImgFS(path_ticketdb) ||
|
||||
((RemoveTicketFromDB("D:/partitionA.bin", title_id)) != 0)) ret = 1;
|
||||
}
|
||||
|
||||
// title database
|
||||
if (remove_tie) {
|
||||
char path_titledb[256];
|
||||
if ((GetInstallDbsPath(path_titledb, drv, "title.db") != 0) || !InitImgFS(path_titledb) ||
|
||||
((RemoveTitleInfoEntryFromDB("D:/partitionA.bin", title_id)) != 0)) ret = 1;
|
||||
}
|
||||
|
||||
// restore old mount path
|
||||
InitImgFS(path_bak);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 UninstallGameDataTie(const char* path, bool remove_tie, bool remove_ticket, bool remove_save) {
|
||||
// requirements for this to work:
|
||||
// * title.db from standard path mounted to T:/
|
||||
// * entry filename starts with title id
|
||||
// * these two conditions need to be fulfilled for all ties
|
||||
bool from_emunand = false;
|
||||
u64 tid64;
|
||||
|
||||
const char* mntpath = GetMountPath();
|
||||
if (!mntpath) return 1;
|
||||
|
||||
// title.db from emunand?
|
||||
if ((strncasecmp(mntpath, "B:/dbs/title.db", 16) == 0) ||
|
||||
(strncasecmp(mntpath, "4:/dbs/title.db", 16) == 0))
|
||||
from_emunand = true;
|
||||
|
||||
// get title ID
|
||||
if (sscanf(path, "T:/%016llx", &tid64) != 1)
|
||||
return 1;
|
||||
|
||||
return UninstallGameData(tid64, remove_tie, remove_ticket, remove_save, from_emunand);
|
||||
}
|
||||
|
||||
u32 InstallCiaContent(const char* drv, const char* path_content, u32 offset, u32 size,
|
||||
TmdContentChunk* chunk, const u8* title_id, const u8* titlekey, bool cxi_fix) {
|
||||
char dest[256];
|
||||
|
@ -15,6 +15,7 @@ u32 TrimGameFile(const char* path);
|
||||
u32 ShowGameFileTitleInfoF(const char* path, u16* screen, bool clear);
|
||||
u32 ShowGameFileTitleInfo(const char* path);
|
||||
u32 ShowCiaCheckerInfo(const char* path);
|
||||
u32 UninstallGameDataTie(const char* path, bool remove_tie, bool remove_ticket, bool remove_save);
|
||||
u32 GetTmdContentPath(char* path_content, const char* path_tmd);
|
||||
u32 BuildNcchInfoXorpads(const char* destdir, const char* path);
|
||||
u32 CheckHealthAndSafetyInject(const char* hsdrv);
|
||||
|
Loading…
x
Reference in New Issue
Block a user