forked from Mirror/GodMode9
Allow dumping CXIs from TMDs
This commit is contained in:
parent
0e3433385f
commit
a6fa7042d5
@ -49,7 +49,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// GodMode9 version
|
// GodMode9 version
|
||||||
#define VERSION "1.1.5"
|
#define VERSION "1.1.6"
|
||||||
|
|
||||||
// Maximum payload size (arbitrary value!)
|
// Maximum payload size (arbitrary value!)
|
||||||
#define SELF_MAX_SIZE (320 * 1024) // 320kB
|
#define SELF_MAX_SIZE (320 * 1024) // 320kB
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#define FYTPE_ENCRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS|BIN_KEYDB))
|
#define FYTPE_ENCRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS|BIN_KEYDB))
|
||||||
#define FTYPE_CIABUILD(tp) (tp&(GAME_NCSD|GAME_NCCH|GAME_TMD))
|
#define FTYPE_CIABUILD(tp) (tp&(GAME_NCSD|GAME_NCCH|GAME_TMD))
|
||||||
#define FTYPE_CIABUILD_L(tp) (FTYPE_CIABUILD(tp) && (tp&(GAME_TMD)))
|
#define FTYPE_CIABUILD_L(tp) (FTYPE_CIABUILD(tp) && (tp&(GAME_TMD)))
|
||||||
|
#define FTYPE_CXIDUMP(tp) (tp&(GAME_TMD))
|
||||||
#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_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD|GAME_NDS))
|
#define FTYPE_TITLEINFO(tp) (tp&(GAME_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD|GAME_NDS))
|
||||||
|
@ -755,7 +755,7 @@ u32 CryptNcchNcsdBossFirmFile(const char* orig, const char* dest, u32 mode, u16
|
|||||||
|
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
if (!ShowProgress(offset, fsize, dest)) ret = 1;
|
if (!ShowProgress(offset, fsize, dest)) ret = 1;
|
||||||
if (mode & (GAME_NCCH|GAME_NCSD|GAME_BOSS|SYS_FIRM)) { // for NCCH / NCSD / BOSS / FIRM files
|
if (mode & (GAME_NCCH|GAME_NCSD|GAME_BOSS|SYS_FIRM|GAME_NDS)) { // for NCCH / NCSD / BOSS / FIRM files
|
||||||
for (u64 i = 0; (i < size) && (ret == 0); i += MAIN_BUFFER_SIZE) {
|
for (u64 i = 0; (i < size) && (ret == 0); i += MAIN_BUFFER_SIZE) {
|
||||||
u32 read_bytes = min(MAIN_BUFFER_SIZE, (size - i));
|
u32 read_bytes = min(MAIN_BUFFER_SIZE, (size - i));
|
||||||
UINT bytes_read, bytes_written;
|
UINT bytes_read, bytes_written;
|
||||||
@ -1375,6 +1375,27 @@ u32 BuildCiaFromGameFile(const char* path, bool force_legit) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this has very limited uses right now
|
||||||
|
u32 DumpCxiSrlFromTmdFile(const char* path) {
|
||||||
|
u32 filetype = 0;
|
||||||
|
char path_cxi[256];
|
||||||
|
char dest[256];
|
||||||
|
|
||||||
|
// prepare output name
|
||||||
|
snprintf(dest, 256, OUTPUT_PATH "/");
|
||||||
|
char* dname = dest + strnlen(dest, 256);
|
||||||
|
|
||||||
|
// get path to CXI/SRL and decrypt (if encrypted)
|
||||||
|
if ((strncmp(path + 1, ":/title/", 8) != 0) ||
|
||||||
|
(GetTmdContentPath(path_cxi, path) != 0) ||
|
||||||
|
(!((filetype = IdentifyFileType(path_cxi)) & (GAME_NCCH|GAME_NDS))) ||
|
||||||
|
(GetGoodName(dname, path_cxi, false) != 0) ||
|
||||||
|
(CryptNcchNcsdBossFirmFile(path_cxi, dest, filetype, CRYPTO_DECRYPT, 0, 0, NULL, NULL) != 0))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
u32 LoadSmdhFromGameFile(const char* path, Smdh* smdh) {
|
u32 LoadSmdhFromGameFile(const char* path, Smdh* smdh) {
|
||||||
u32 filetype = IdentifyFileType(path);
|
u32 filetype = IdentifyFileType(path);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ u32 VerifyGameFile(const char* path);
|
|||||||
u32 CheckEncryptedGameFile(const char* path);
|
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 DumpCxiSrlFromTmdFile(const char* path);
|
||||||
u32 ShowGameFileTitleInfo(const char* path);
|
u32 ShowGameFileTitleInfo(const char* path);
|
||||||
u32 BuildNcchInfoXorpads(const char* destdir, const char* path);
|
u32 BuildNcchInfoXorpads(const char* destdir, const char* path);
|
||||||
u32 CheckHealthAndSafetyInject(const char* hsdrv);
|
u32 CheckHealthAndSafetyInject(const char* hsdrv);
|
||||||
|
@ -668,6 +668,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
bool cryptable_inplace = ((encryptable||decryptable) && !in_output_path && (drvtype & DRV_FAT));
|
bool cryptable_inplace = ((encryptable||decryptable) && !in_output_path && (drvtype & DRV_FAT));
|
||||||
bool cia_buildable = (FTYPE_CIABUILD(filetype));
|
bool cia_buildable = (FTYPE_CIABUILD(filetype));
|
||||||
bool cia_buildable_legit = (FTYPE_CIABUILD_L(filetype));
|
bool cia_buildable_legit = (FTYPE_CIABUILD_L(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;
|
||||||
bool key_buildable = (FTYPE_KEYBUILD(filetype)) && !in_output_path;
|
bool key_buildable = (FTYPE_KEYBUILD(filetype)) && !in_output_path;
|
||||||
bool titleinfo = (FTYPE_TITLEINFO(filetype));
|
bool titleinfo = (FTYPE_TITLEINFO(filetype));
|
||||||
@ -818,6 +819,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
int encrypt = (encryptable) ? ++n_opt : -1;
|
int encrypt = (encryptable) ? ++n_opt : -1;
|
||||||
int cia_build = (cia_buildable) ? ++n_opt : -1;
|
int cia_build = (cia_buildable) ? ++n_opt : -1;
|
||||||
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 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;
|
||||||
int key_build = (key_buildable) ? ++n_opt : -1;
|
int key_build = (key_buildable) ? ++n_opt : -1;
|
||||||
@ -835,6 +837,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
if (encrypt > 0) optionstr[encrypt-1] = (cryptable_inplace) ? "Encrypt file (...)" : "Encrypt file (" OUTPUT_PATH ")";
|
if (encrypt > 0) optionstr[encrypt-1] = (cryptable_inplace) ? "Encrypt file (...)" : "Encrypt file (" OUTPUT_PATH ")";
|
||||||
if (cia_build > 0) optionstr[cia_build-1] = (cia_build_legit < 0) ? "Build CIA from file" : "Build CIA (standard)";
|
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 (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 (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;
|
||||||
if (key_build > 0) optionstr[key_build-1] = "Build " KEYDB_NAME;
|
if (key_build > 0) optionstr[key_build-1] = "Build " KEYDB_NAME;
|
||||||
@ -966,7 +969,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
else ShowPrompt(false, "%s\nEncrypted to %s", pathstr, OUTPUT_PATH);
|
else ShowPrompt(false, "%s\nEncrypted to %s", pathstr, OUTPUT_PATH);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if ((user_select == cia_build) || (user_select == cia_build_legit)) { // -> build CIA
|
} else if ((user_select == cia_build) || (user_select == cia_build_legit) || (user_select == cxi_dump)) { // -> build CIA / dump CXI
|
||||||
|
char* type = (user_select == cxi_dump) ? "CXI" : "CIA";
|
||||||
bool force_legit = (user_select == cia_build_legit);
|
bool force_legit = (user_select == cia_build_legit);
|
||||||
if ((n_marked > 1) && ShowPrompt(true, "Try to process all %lu selected files?", n_marked)) {
|
if ((n_marked > 1) && ShowPrompt(true, "Try to process all %lu selected files?", n_marked)) {
|
||||||
u32 n_success = 0;
|
u32 n_success = 0;
|
||||||
@ -980,24 +984,26 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
current_dir->entry[i].marked = false;
|
current_dir->entry[i].marked = false;
|
||||||
if (BuildCiaFromGameFile(path, force_legit) == 0) n_success++;
|
if (((user_select != cxi_dump) && (BuildCiaFromGameFile(path, force_legit) == 0)) ||
|
||||||
|
((user_select == cxi_dump) && (DumpCxiSrlFromTmdFile(path) == 0))) n_success++;
|
||||||
else { // on failure: set *cursor on failed title, break;
|
else { // on failure: set *cursor on failed title, break;
|
||||||
TruncateString(pathstr, path, 32, 8);
|
TruncateString(pathstr, path, 32, 8);
|
||||||
ShowPrompt(false, "%s\nBuild CIA failed", pathstr);
|
ShowPrompt(false, "%s\nBuild %s failed", pathstr, type);
|
||||||
*cursor = i;
|
*cursor = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n_other) ShowPrompt(false, "%lu/%lu CIAs built ok\n%lu/%lu not of same type",
|
if (n_other) ShowPrompt(false, "%lu/%lu %ss built ok\n%lu/%lu not of same type",
|
||||||
n_success, n_marked, n_other, n_marked);
|
n_success, n_marked, type, n_other, n_marked);
|
||||||
else ShowPrompt(false, "%lu/%lu CIAs built ok", n_success, n_marked);
|
else ShowPrompt(false, "%lu/%lu %ss built ok", n_success, n_marked, type);
|
||||||
if (n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH);
|
if (n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH);
|
||||||
if (n_success && in_output_path) GetDirContents(current_dir, current_path);
|
if (n_success && in_output_path) GetDirContents(current_dir, current_path);
|
||||||
} else {
|
} else {
|
||||||
if (BuildCiaFromGameFile(curr_entry->path, force_legit) == 0) {
|
if (((user_select != cxi_dump) && (BuildCiaFromGameFile(curr_entry->path, force_legit) == 0)) ||
|
||||||
ShowPrompt(false, "%s\nCIA built to %s", pathstr, OUTPUT_PATH);
|
((user_select == cxi_dump) && (DumpCxiSrlFromTmdFile(curr_entry->path) == 0))) {
|
||||||
|
ShowPrompt(false, "%s\n%s built to %s", pathstr, type, OUTPUT_PATH);
|
||||||
if (in_output_path) GetDirContents(current_dir, current_path);
|
if (in_output_path) GetDirContents(current_dir, current_path);
|
||||||
} else ShowPrompt(false, "%s\nCIA build failed", pathstr);
|
} else ShowPrompt(false, "%s\n%s build failed", pathstr, type);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if (user_select == verify) { // -> verify game / nand file
|
} else if (user_select == verify) { // -> verify game / nand file
|
||||||
|
Loading…
x
Reference in New Issue
Block a user