mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Install, verify, info handling for tickets
This commit is contained in:
parent
48347c947a
commit
667a1bf2c0
@ -46,17 +46,18 @@
|
|||||||
#define FLAG_CXI (1ULL<<63)
|
#define FLAG_CXI (1ULL<<63)
|
||||||
|
|
||||||
#define FTYPE_MOUNTABLE(tp) (tp&(IMG_FAT|IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_EXEFS|GAME_ROMFS|GAME_NDS|GAME_TAD|SYS_FIRM|SYS_DIFF|SYS_DISA|SYS_TICKDB|BIN_KEYDB))
|
#define FTYPE_MOUNTABLE(tp) (tp&(IMG_FAT|IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_EXEFS|GAME_ROMFS|GAME_NDS|GAME_TAD|SYS_FIRM|SYS_DIFF|SYS_DISA|SYS_TICKDB|BIN_KEYDB))
|
||||||
#define FTYPE_VERIFICABLE(tp) (tp&(IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_TMD|GAME_TIE|GAME_BOSS|SYS_FIRM))
|
#define FTYPE_VERIFICABLE(tp) (tp&(IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_TMD|GAME_TIE|GAME_TICKET|GAME_BOSS|SYS_FIRM))
|
||||||
#define FTYPE_DECRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS|GAME_NUSCDN|SYS_FIRM|BIN_KEYDB))
|
#define FTYPE_DECRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS|GAME_NUSCDN|SYS_FIRM|BIN_KEYDB))
|
||||||
#define FTYPE_ENCRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS|BIN_KEYDB))
|
#define FTYPE_ENCRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS|BIN_KEYDB))
|
||||||
#define FTYPE_CIABUILD(tp) ((tp&(GAME_NCSD|GAME_NCCH|GAME_TMD|GAME_TIE)) || ((tp&GAME_NDS)&&(tp&(FLAG_DSIW))))
|
#define FTYPE_CIABUILD(tp) ((tp&(GAME_NCSD|GAME_NCCH|GAME_TMD|GAME_TIE)) || ((tp&GAME_NDS)&&(tp&(FLAG_DSIW))))
|
||||||
#define FTYPE_CIABUILD_L(tp) (FTYPE_CIABUILD(tp) && (tp&(GAME_TMD|GAME_TIE)))
|
#define FTYPE_CIABUILD_L(tp) (FTYPE_CIABUILD(tp) && (tp&(GAME_TMD|GAME_TIE)))
|
||||||
#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_CIAINSTALL(tp) ((tp&(GAME_NCSD|GAME_NCCH|GAME_CIA)) || ((tp&GAME_NDS)&&(tp&(FLAG_DSIW))) || (tp&(GAME_TMD)&&(tp&(FLAG_NUSCDN))))
|
||||||
|
#define FTYPE_TIKINSTALL(tp) (tp&(GAME_TICKET))
|
||||||
#define FTYPE_CXIDUMP(tp) (tp&(GAME_TMD))
|
#define FTYPE_CXIDUMP(tp) (tp&(GAME_TMD))
|
||||||
#define FTYPE_UNINSTALL(tp) (tp&(GAME_TIE))
|
#define FTYPE_UNINSTALL(tp) (tp&(GAME_TIE))
|
||||||
#define FTYPE_TIKBUILD(tp) (tp&(GAME_TICKET|SYS_TICKDB|BIN_TIKDB))
|
#define FTYPE_TIKBUILD(tp) (tp&(GAME_TICKET|SYS_TICKDB|BIN_TIKDB))
|
||||||
#define FTYPE_KEYBUILD(tp) (tp&(BIN_KEYDB|BIN_LEGKEY))
|
#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))
|
#define FTYPE_TITLEINFO(tp) (tp&(GAME_TIE|GAME_TICKET|GAME_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD|GAME_NDS|GAME_GBA|GAME_TAD|GAME_3DSX))
|
||||||
#define FTYPE_CIACHECK(tp) (tp&GAME_CIA)
|
#define FTYPE_CIACHECK(tp) (tp&GAME_CIA)
|
||||||
#define FTYPE_RENAMABLE(tp) (tp&(GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_NDS|GAME_GBA))
|
#define FTYPE_RENAMABLE(tp) (tp&(GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_NDS|GAME_GBA))
|
||||||
#define FTYPE_TRIMABLE(tp) (tp&(IMG_NAND|GAME_NCCH|GAME_NCSD|GAME_NDS|SYS_FIRM))
|
#define FTYPE_TRIMABLE(tp) (tp&(IMG_NAND|GAME_NCCH|GAME_NCSD|GAME_NDS|SYS_FIRM))
|
||||||
|
@ -1095,6 +1095,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
|||||||
bool cia_buildable_legit = (FTYPE_CIABUILD_L(filetype));
|
bool cia_buildable_legit = (FTYPE_CIABUILD_L(filetype));
|
||||||
bool cia_installable = (FTYPE_CIAINSTALL(filetype)) && !(drvtype & DRV_CTRNAND) &&
|
bool cia_installable = (FTYPE_CIAINSTALL(filetype)) && !(drvtype & DRV_CTRNAND) &&
|
||||||
!(drvtype & DRV_TWLNAND) && !(drvtype & DRV_ALIAS) && !(drvtype & DRV_IMAGE);
|
!(drvtype & DRV_TWLNAND) && !(drvtype & DRV_ALIAS) && !(drvtype & DRV_IMAGE);
|
||||||
|
bool tik_installable = (FTYPE_TIKINSTALL(filetype));
|
||||||
bool uninstallable = (FTYPE_UNINSTALL(filetype));
|
bool uninstallable = (FTYPE_UNINSTALL(filetype));
|
||||||
bool cxi_dumpable = (FTYPE_CXIDUMP(filetype));
|
bool cxi_dumpable = (FTYPE_CXIDUMP(filetype));
|
||||||
bool tik_buildable = (FTYPE_TIKBUILD(filetype)) && !in_output_path;
|
bool tik_buildable = (FTYPE_TIKBUILD(filetype)) && !in_output_path;
|
||||||
@ -1330,6 +1331,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
|||||||
int cia_build_legit = (cia_buildable_legit) ? ++n_opt : -1;
|
int cia_build_legit = (cia_buildable_legit) ? ++n_opt : -1;
|
||||||
int cxi_dump = (cxi_dumpable) ? ++n_opt : -1;
|
int cxi_dump = (cxi_dumpable) ? ++n_opt : -1;
|
||||||
int cia_install = (cia_installable) ? ++n_opt : -1;
|
int cia_install = (cia_installable) ? ++n_opt : -1;
|
||||||
|
int tik_install = (tik_installable) ? ++n_opt : -1;
|
||||||
int uninstall = (uninstallable) ? ++n_opt : -1;
|
int uninstall = (uninstallable) ? ++n_opt : -1;
|
||||||
int tik_build_enc = (tik_buildable) ? ++n_opt : -1;
|
int tik_build_enc = (tik_buildable) ? ++n_opt : -1;
|
||||||
int tik_build_dec = (tik_buildable) ? ++n_opt : -1;
|
int tik_build_dec = (tik_buildable) ? ++n_opt : -1;
|
||||||
@ -1364,6 +1366,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
|||||||
if (cia_build_legit > 0) optionstr[cia_build_legit-1] = "Build CIA (legit)";
|
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 (cxi_dump > 0) optionstr[cxi_dump-1] = "Dump CXI/NDS file";
|
||||||
if (cia_install > 0) optionstr[cia_install-1] = "Install game image";
|
if (cia_install > 0) optionstr[cia_install-1] = "Install game image";
|
||||||
|
if (tik_install > 0) optionstr[tik_install-1] = "Install ticket";
|
||||||
if (uninstall > 0) optionstr[uninstall-1] = "Uninstall title";
|
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_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 (tik_build_dec > 0) optionstr[tik_build_dec-1] = "Build " TIKDB_NAME_DEC;
|
||||||
@ -1572,7 +1575,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (user_select == cia_install) { // -> install game file
|
else if ((user_select == cia_install) || (user_select == tik_install)) { // -> install game/ticket file
|
||||||
|
bool install_tik = (user_select == tik_install);
|
||||||
bool to_emunand = false;
|
bool to_emunand = false;
|
||||||
if (CheckVirtualDrive("E:")) {
|
if (CheckVirtualDrive("E:")) {
|
||||||
optionstr[0] = "Install to SysNAND";
|
optionstr[0] = "Install to SysNAND";
|
||||||
@ -1595,7 +1599,9 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DrawDirContents(current_dir, (*cursor = i), scroll);
|
DrawDirContents(current_dir, (*cursor = i), scroll);
|
||||||
if (InstallGameFile(path, to_emunand) == 0) n_success++;
|
if ((!install_tik && (InstallGameFile(path, to_emunand) == 0)) ||
|
||||||
|
(install_tik && (InstallTicketFile(path, to_emunand) == 0)))
|
||||||
|
n_success++;
|
||||||
else { // on failure: show error, continue
|
else { // on failure: show error, continue
|
||||||
char lpathstr[32+1];
|
char lpathstr[32+1];
|
||||||
TruncateString(lpathstr, path, 32, 8);
|
TruncateString(lpathstr, path, 32, 8);
|
||||||
@ -1609,7 +1615,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan
|
|||||||
n_success, n_marked, n_other, n_marked);
|
n_success, n_marked, n_other, n_marked);
|
||||||
} else ShowPrompt(false, "%lu/%lu files installed ok", n_success, n_marked);
|
} else ShowPrompt(false, "%lu/%lu files installed ok", n_success, n_marked);
|
||||||
} else {
|
} else {
|
||||||
u32 ret = InstallGameFile(file_path, to_emunand);
|
u32 ret = install_tik ? InstallTicketFile(file_path, to_emunand) :
|
||||||
|
InstallGameFile(file_path, to_emunand);
|
||||||
ShowPrompt(false, "%s\nInstall %s", pathstr, (ret == 0) ? "success" : "failed");
|
ShowPrompt(false, "%s\nInstall %s", pathstr, (ret == 0) ? "success" : "failed");
|
||||||
if ((ret != 0) && (filetype & (GAME_NCCH|GAME_NCSD)) &&
|
if ((ret != 0) && (filetype & (GAME_NCCH|GAME_NCSD)) &&
|
||||||
ShowPrompt(true, "%s\nfile failed install.\n \nVerify now?", pathstr)) {
|
ShowPrompt(true, "%s\nfile failed install.\n \nVerify now?", pathstr)) {
|
||||||
|
@ -205,8 +205,30 @@ u32 LoadTmdFile(TitleMetaData* tmd, const char* path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 LoadCdnTicketFile(Ticket** ticket, const char* path_cnt) {
|
u32 LoadTicketFile(Ticket** ticket, const char* path_tik) {
|
||||||
if(!ticket) return 1;
|
if(!ticket) return 1;
|
||||||
|
|
||||||
|
// load and check ticket
|
||||||
|
TicketMinimum tmp;
|
||||||
|
UINT br;
|
||||||
|
if ((fvx_qread(path_tik, &tmp, 0, TICKET_MINIMUM_SIZE, &br) != FR_OK) || (br != TICKET_MINIMUM_SIZE) ||
|
||||||
|
ValidateTicket((Ticket*)&tmp) != 0) return 1;
|
||||||
|
|
||||||
|
u32 tik_size = GetTicketSize((Ticket*)&tmp);
|
||||||
|
|
||||||
|
Ticket* tik = (Ticket*)malloc(tik_size);
|
||||||
|
if (!tik) return 1;
|
||||||
|
|
||||||
|
if ((fvx_qread(path_tik, tik, 0, tik_size, &br) != FR_OK) || (br != tik_size)) {
|
||||||
|
free(tik);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ticket = tik;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 LoadCdnTicketFile(Ticket** ticket, const char* path_cnt) {
|
||||||
// path points to CDN content file
|
// path points to CDN content file
|
||||||
char path_cetk[256];
|
char path_cetk[256];
|
||||||
strncpy(path_cetk, path_cnt, 256);
|
strncpy(path_cetk, path_cnt, 256);
|
||||||
@ -216,25 +238,8 @@ u32 LoadCdnTicketFile(Ticket** ticket, const char* path_cnt) {
|
|||||||
char* ext_cetk = strrchr(++name_cetk, '.');
|
char* ext_cetk = strrchr(++name_cetk, '.');
|
||||||
ext_cetk = (ext_cetk) ? ext_cetk + 1 : name_cetk;
|
ext_cetk = (ext_cetk) ? ext_cetk + 1 : name_cetk;
|
||||||
snprintf(ext_cetk, 256 - (ext_cetk - path_cetk), "cetk");
|
snprintf(ext_cetk, 256 - (ext_cetk - path_cetk), "cetk");
|
||||||
|
// ticket is loaded and vaildated here
|
||||||
// load and check ticket
|
return LoadTicketFile(ticket, path_cetk);
|
||||||
TicketMinimum tmp;
|
|
||||||
UINT br;
|
|
||||||
if ((fvx_qread(path_cetk, &tmp, 0, TICKET_MINIMUM_SIZE, &br) != FR_OK) || (br != TICKET_MINIMUM_SIZE) ||
|
|
||||||
ValidateTicket((Ticket*)&tmp) != 0) return 1;
|
|
||||||
|
|
||||||
u32 tik_size = GetTicketSize((Ticket*)&tmp);
|
|
||||||
|
|
||||||
Ticket* tik = (Ticket*)malloc(tik_size);
|
|
||||||
if (!tik) return 1;
|
|
||||||
|
|
||||||
if ((fvx_qread(path_cetk, tik, 0, tik_size, &br) != FR_OK) || (br != tik_size)) {
|
|
||||||
free(tik);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ticket = tik;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetTmdContentPath(char* path_content, const char* path_tmd) {
|
u32 GetTmdContentPath(char* path_content, const char* path_tmd) {
|
||||||
@ -316,6 +321,52 @@ u32 GetTieContentPath(char* path_content, const char* path_tie) {
|
|||||||
return GetTmdContentPath(path_content, path_tmd);
|
return GetTmdContentPath(path_content, path_tmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetTitleIdTmdPath(char* path_tmd, const u64 title_id, bool from_emunand) {
|
||||||
|
u32 tid_high = (u32) ((title_id >> 32) & 0xFFFFFFFF);
|
||||||
|
u32 tid_low = (u32) (title_id & 0xFFFFFFFF);
|
||||||
|
char* drv = from_emunand ?
|
||||||
|
((tid_high & 0x8000) ? "5:" : ((tid_high & 0x10) ? "4:" : "B:")) :
|
||||||
|
((tid_high & 0x8000) ? "2:" : ((tid_high & 0x10) ? "1:" : "A:"));
|
||||||
|
if (tid_high & 0x8000) tid_high = 0x00030000 | (tid_high&0xFF);
|
||||||
|
|
||||||
|
char path_pat[64];
|
||||||
|
snprintf(path_pat, 64, "%2.2s/title/%08lX/%08lX/content/*.tmd",
|
||||||
|
drv, tid_high, tid_low);
|
||||||
|
|
||||||
|
if (fvx_findpath(path_tmd, path_pat, FN_HIGHEST) != FR_OK)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// done
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetTicketContentPath(char* path_content, const char* path_tik) {
|
||||||
|
char path_tmd[256];
|
||||||
|
bool from_emunand = false;
|
||||||
|
u64 tid64 = 0;
|
||||||
|
|
||||||
|
// available for all tickets, but will fail for titles not installed
|
||||||
|
|
||||||
|
// from mounted ticket.db?
|
||||||
|
if (*path_tik == 'T') {
|
||||||
|
const char* mntpath = GetMountPath();
|
||||||
|
from_emunand = (mntpath && (*mntpath == '4'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// load ticket, get title id
|
||||||
|
Ticket ticket;
|
||||||
|
if (fvx_qread(path_tik, &ticket, 0, sizeof(Ticket), NULL) != FR_OK)
|
||||||
|
return 1;
|
||||||
|
tid64 = getbe64(ticket.title_id);
|
||||||
|
|
||||||
|
// get the TMD path
|
||||||
|
if (GetTitleIdTmdPath(path_tmd, tid64, from_emunand) != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// let the TMD content path function take over
|
||||||
|
return GetTmdContentPath(path_content, path_tmd);
|
||||||
|
}
|
||||||
|
|
||||||
u32 WriteCiaStub(CiaStub* stub, const char* path) {
|
u32 WriteCiaStub(CiaStub* stub, const char* path) {
|
||||||
FIL file;
|
FIL file;
|
||||||
UINT btw;
|
UINT btw;
|
||||||
@ -846,6 +897,18 @@ u32 VerifyBossFile(const char* path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 VerifyTicketFile(const char* path) {
|
||||||
|
// load ticket
|
||||||
|
Ticket* ticket;
|
||||||
|
if (LoadTicketFile(&ticket, path) != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// ticket verification is strict, fake-signed tickets are discarded
|
||||||
|
u32 res = ValidateTicketSignature(ticket);
|
||||||
|
free(ticket);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
u32 VerifyGameFile(const char* path) {
|
u32 VerifyGameFile(const char* path) {
|
||||||
u64 filetype = IdentifyFileType(path);
|
u64 filetype = IdentifyFileType(path);
|
||||||
if (filetype & GAME_CIA)
|
if (filetype & GAME_CIA)
|
||||||
@ -862,6 +925,8 @@ u32 VerifyGameFile(const char* path) {
|
|||||||
return VerifyBossFile(path);
|
return VerifyBossFile(path);
|
||||||
else if (filetype & SYS_FIRM)
|
else if (filetype & SYS_FIRM)
|
||||||
return VerifyFirmFile(path);
|
return VerifyFirmFile(path);
|
||||||
|
else if (filetype & GAME_TICKET)
|
||||||
|
return VerifyTicketFile(path);
|
||||||
else return 1;
|
else return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2416,6 +2481,71 @@ u32 InstallGameFile(const char* path, bool to_emunand) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 InstallTicketFile(const char* path, bool to_emunand) {
|
||||||
|
// sanity check
|
||||||
|
if (!(IdentifyFileType(path) & GAME_TICKET))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// path string
|
||||||
|
char pathstr[32 + 1];
|
||||||
|
TruncateString(pathstr, path, 32, 8);
|
||||||
|
|
||||||
|
// check ticket db
|
||||||
|
char path_ticketdb[32];
|
||||||
|
if ((GetInstallDbsPath(path_ticketdb, to_emunand ? "4:" : "1:", "ticket.db") != 0) || !fvx_qsize(path_ticketdb)) {
|
||||||
|
ShowPrompt(false, "Install error:\nThis system is missing the\nticket.db file.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load & verify ticket
|
||||||
|
Ticket* ticket;
|
||||||
|
if (LoadTicketFile(&ticket, path) != 0)
|
||||||
|
return 1;
|
||||||
|
if (ValidateTicketSignature(ticket) != 0) {
|
||||||
|
ShowPrompt(false, "%s\nError: Fake-signed ticket\n \nOnly valid signed tickets can\nbe installed to the system.", pathstr);
|
||||||
|
free(ticket);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check ticket console id
|
||||||
|
u32 cid = getbe32(ticket->console_id);
|
||||||
|
if (cid && (cid != (&ARM9_ITCM->otp)->deviceId)) {
|
||||||
|
ShowPrompt(false, "%s\nError: Unknown cid %08lX\n \nThis ticket does not belong to\nthis 3DS console.", pathstr, cid);
|
||||||
|
free(ticket);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check permissions for SysNAND
|
||||||
|
if (!CheckWritePermissions(to_emunand ? "4:" : "1:")) {
|
||||||
|
free(ticket);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// let the user know we're working
|
||||||
|
ShowString("%s\nInstalling ticket...\n", pathstr);
|
||||||
|
|
||||||
|
// write ticket database
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// ticket database
|
||||||
|
if (!InitImgFS(path_ticketdb) ||
|
||||||
|
((AddTicketToDB(PART_PATH, ticket->title_id, (Ticket*) ticket, true)) != 0)) {
|
||||||
|
InitImgFS(path_bak);
|
||||||
|
free(ticket);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore old mount path
|
||||||
|
InitImgFS(path_bak);
|
||||||
|
|
||||||
|
free(ticket);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// this has very limited uses right now
|
// this has very limited uses right now
|
||||||
u32 DumpCxiSrlFromTmdFile(const char* path) {
|
u32 DumpCxiSrlFromTmdFile(const char* path) {
|
||||||
u64 filetype = 0;
|
u64 filetype = 0;
|
||||||
@ -2648,6 +2778,10 @@ u32 LoadSmdhFromGameFile(const char* path, Smdh* smdh) {
|
|||||||
char path_content[256];
|
char path_content[256];
|
||||||
if (GetTieContentPath(path_content, path) != 0) return 1;
|
if (GetTieContentPath(path_content, path) != 0) return 1;
|
||||||
return LoadSmdhFromGameFile(path_content, smdh);
|
return LoadSmdhFromGameFile(path_content, smdh);
|
||||||
|
} else if (filetype & GAME_TICKET) {
|
||||||
|
char path_content[256];
|
||||||
|
if (GetTicketContentPath(path_content, path) != 0) return 1;
|
||||||
|
return LoadSmdhFromGameFile(path_content, smdh);
|
||||||
} else if (filetype & GAME_3DSX) {
|
} else if (filetype & GAME_3DSX) {
|
||||||
ThreedsxHeader threedsx;
|
ThreedsxHeader threedsx;
|
||||||
if ((fvx_qread(path, &threedsx, 0, sizeof(ThreedsxHeader), NULL) != FR_OK) ||
|
if ((fvx_qread(path, &threedsx, 0, sizeof(ThreedsxHeader), NULL) != FR_OK) ||
|
||||||
@ -2709,6 +2843,9 @@ u32 ShowGameFileTitleInfoF(const char* path, u16* screen, bool clear) {
|
|||||||
} else if (itype & GAME_TIE) {
|
} else if (itype & GAME_TIE) {
|
||||||
if (GetTieContentPath(path_content, path) != 0) return 1;
|
if (GetTieContentPath(path_content, path) != 0) return 1;
|
||||||
path = path_content;
|
path = path_content;
|
||||||
|
} else if (itype & GAME_TICKET) {
|
||||||
|
if (GetTicketContentPath(path_content, path) != 0) return 1;
|
||||||
|
path = path_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* buffer = (void*) malloc(max(sizeof(Smdh), sizeof(TwlIconData)));
|
void* buffer = (void*) malloc(max(sizeof(Smdh), sizeof(TwlIconData)));
|
||||||
|
@ -7,6 +7,7 @@ u32 CheckEncryptedGameFile(const char* path);
|
|||||||
u32 CryptGameFile(const char* path, bool inplace, bool encrypt);
|
u32 CryptGameFile(const char* path, bool inplace, bool encrypt);
|
||||||
u32 BuildCiaFromGameFile(const char* path, bool force_legit);
|
u32 BuildCiaFromGameFile(const char* path, bool force_legit);
|
||||||
u32 InstallGameFile(const char* path, bool to_emunand);
|
u32 InstallGameFile(const char* path, bool to_emunand);
|
||||||
|
u32 InstallTicketFile(const char* path, bool to_emunand);
|
||||||
u32 DumpCxiSrlFromTmdFile(const char* path);
|
u32 DumpCxiSrlFromTmdFile(const char* path);
|
||||||
u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr);
|
u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr);
|
||||||
u32 CompressCode(const char* path, const char* path_out);
|
u32 CompressCode(const char* path, const char* path_out);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user