mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 05:32:47 +00:00
Added ability to extract uncompressed .code
This commit is contained in:
parent
f12dcfda4c
commit
a6a15eb70d
@ -701,6 +701,7 @@ bool ShowProgress(u64 current, u64 total, const char* opstr)
|
|||||||
DrawRectangle(MAIN_SCREEN, bar_pos_x + 1, bar_pos_y + 1, bar_width - 2, bar_height - 2, COLOR_STD_BG);
|
DrawRectangle(MAIN_SCREEN, bar_pos_x + 1, bar_pos_y + 1, bar_width - 2, bar_height - 2, COLOR_STD_BG);
|
||||||
}
|
}
|
||||||
DrawRectangle(MAIN_SCREEN, bar_pos_x + 2, bar_pos_y + 2, prog_width, bar_height - 4, COLOR_STD_FONT);
|
DrawRectangle(MAIN_SCREEN, bar_pos_x + 2, bar_pos_y + 2, prog_width, bar_height - 4, COLOR_STD_FONT);
|
||||||
|
DrawRectangle(MAIN_SCREEN, bar_pos_x + 2 + prog_width, bar_pos_y + 2, (bar_width-4) - prog_width, bar_height - 4, COLOR_STD_BG);
|
||||||
|
|
||||||
TruncateString(progstr, opstr, (bar_width / FONT_WIDTH_EXT) - 7, 8);
|
TruncateString(progstr, opstr, (bar_width / FONT_WIDTH_EXT) - 7, 8);
|
||||||
snprintf(tempstr, 64, "%s (%lu%%)", progstr, prog_percent);
|
snprintf(tempstr, 64, "%s (%lu%%)", progstr, prog_percent);
|
||||||
|
@ -86,11 +86,11 @@ u32 IdentifyFileType(const char* path) {
|
|||||||
strncpy(ext_cetk, "cetk", 5);
|
strncpy(ext_cetk, "cetk", 5);
|
||||||
if (FileGetSize(path_cetk) > 0)
|
if (FileGetSize(path_cetk) > 0)
|
||||||
return GAME_NUSCDN; // NUS/CDN type 2
|
return GAME_NUSCDN; // NUS/CDN type 2
|
||||||
} else if (strncasecmp(fname, TIKDB_NAME_ENC, sizeof(TIKDB_NAME_ENC)) == 0) {
|
} else if (strncasecmp(fname, TIKDB_NAME_ENC, sizeof(TIKDB_NAME_ENC)+1) == 0) {
|
||||||
return BIN_TIKDB | FLAG_ENC; // titlekey database / encrypted
|
return BIN_TIKDB | FLAG_ENC; // titlekey database / encrypted
|
||||||
} else if (strncasecmp(fname, TIKDB_NAME_DEC, sizeof(TIKDB_NAME_DEC)) == 0) {
|
} else if (strncasecmp(fname, TIKDB_NAME_DEC, sizeof(TIKDB_NAME_DEC)+1) == 0) {
|
||||||
return BIN_TIKDB; // titlekey database / decrypted
|
return BIN_TIKDB; // titlekey database / decrypted
|
||||||
} else if (strncasecmp(fname, KEYDB_NAME, sizeof(KEYDB_NAME)) == 0) {
|
} else if (strncasecmp(fname, KEYDB_NAME, sizeof(KEYDB_NAME)+1) == 0) {
|
||||||
return BIN_KEYDB; // key database
|
return BIN_KEYDB; // key database
|
||||||
} else if ((sscanf(fname, "slot%02lXKey", &id) == 1) && (strncasecmp(ext, "bin", 4) == 0) && (fsize = 16) && (id < 0x40)) {
|
} else if ((sscanf(fname, "slot%02lXKey", &id) == 1) && (strncasecmp(ext, "bin", 4) == 0) && (fsize = 16) && (id < 0x40)) {
|
||||||
return BIN_LEGKEY; // legacy key file
|
return BIN_LEGKEY; // legacy key file
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#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))
|
||||||
#define FTYPE_RENAMABLE(tp) (tp&(GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_NDS))
|
#define FTYPE_RENAMABLE(tp) (tp&(GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_NDS))
|
||||||
#define FTYPE_TRANSFERABLE(tp) ((u32) (tp&(IMG_FAT|FLAG_CTR)) == (u32) (IMG_FAT|FLAG_CTR))
|
#define FTYPE_TRANSFERABLE(tp) ((u32) (tp&(IMG_FAT|FLAG_CTR)) == (u32) (IMG_FAT|FLAG_CTR))
|
||||||
#define FTYPE_HSINJECTABLE(tp) ((u32) (tp&(GAME_NCCH|FLAG_CXI)) == (u32) (GAME_NCCH|FLAG_CXI))
|
#define FTYPE_HASCODE(tp) ((u32) (tp&(GAME_NCCH|FLAG_CXI)) == (u32) (GAME_NCCH|FLAG_CXI))
|
||||||
#define FTYPE_RESTORABLE(tp) (tp&(IMG_NAND))
|
#define FTYPE_RESTORABLE(tp) (tp&(IMG_NAND))
|
||||||
#define FTYPE_EBACKUP(tp) (tp&(IMG_NAND))
|
#define FTYPE_EBACKUP(tp) (tp&(IMG_NAND))
|
||||||
#define FTYPE_XORPAD(tp) (tp&(BIN_NCCHNFO))
|
#define FTYPE_XORPAD(tp) (tp&(BIN_NCCHNFO))
|
||||||
|
82
source/game/codelzss.c
Normal file
82
source/game/codelzss.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include "codelzss.h"
|
||||||
|
|
||||||
|
#define CODE_COMP_SIZE(f) ((f)->off_size_comp & 0xFFFFFF)
|
||||||
|
#define CODE_COMP_END(f) ((int) CODE_COMP_SIZE(f) - (int) (((f)->off_size_comp >> 24) % 0xFF))
|
||||||
|
#define CODE_DEC_SIZE(f) (CODE_COMP_SIZE(f) + (f)->addsize_dec)
|
||||||
|
|
||||||
|
#define CODE_SEG_OFFSET(s) (((s) & 0x0FFF) + 2)
|
||||||
|
#define CODE_SEG_SIZE(s) ((((s) >> 12) & 0xF) + 3)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 off_size_comp; // 0xOOSSSSSS, where O == reverse offset and S == size
|
||||||
|
u32 addsize_dec; // decompressed size - compressed size
|
||||||
|
} __attribute__((packed)) CodeLzssFooter;
|
||||||
|
|
||||||
|
// see: https://github.com/zoogie/DSP1/blob/master/source/main.c#L44
|
||||||
|
u32 DecompressCodeLzss(u8* data_start, u32* code_size, u32 max_size) {
|
||||||
|
u8* comp_start = data_start;
|
||||||
|
|
||||||
|
// get footer, fix comp_start offset
|
||||||
|
if ((*code_size < sizeof(CodeLzssFooter)) || (*code_size > max_size)) return 1;
|
||||||
|
CodeLzssFooter* footer = (CodeLzssFooter*) (void*) (data_start + *code_size - sizeof(CodeLzssFooter));
|
||||||
|
if (CODE_COMP_SIZE(footer) <= *code_size) comp_start += *code_size - CODE_COMP_SIZE(footer);
|
||||||
|
else return 1;
|
||||||
|
|
||||||
|
// more sanity checks
|
||||||
|
if ((CODE_COMP_END(footer) < 0) || (CODE_DEC_SIZE(footer) > max_size))
|
||||||
|
return 1; // not reverse LZSS compressed code or too big uncompressed
|
||||||
|
|
||||||
|
// set pointers
|
||||||
|
u8* data_end = (u8*) comp_start + CODE_DEC_SIZE(footer);
|
||||||
|
u8* ptr_in = (u8*) comp_start + CODE_COMP_END(footer);
|
||||||
|
u8* ptr_out = data_end;
|
||||||
|
|
||||||
|
// main decompression loop
|
||||||
|
while ((ptr_in > comp_start) && (ptr_out > comp_start)) {
|
||||||
|
// sanity check
|
||||||
|
if (ptr_out < ptr_in) return 1;
|
||||||
|
|
||||||
|
// read and process control byte
|
||||||
|
u8 ctrlbyte = *(--ptr_in);
|
||||||
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
// end conditions met?
|
||||||
|
if ((ptr_in <= comp_start) || (ptr_out <= comp_start))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// process control byte
|
||||||
|
if ((ctrlbyte >> i) & 0x1) {
|
||||||
|
// control bit set, read segment code
|
||||||
|
ptr_in -= 2;
|
||||||
|
u16 seg_code = getle16(ptr_in);
|
||||||
|
if (ptr_in < comp_start) return 1; // corrupted code
|
||||||
|
u32 seg_off = CODE_SEG_OFFSET(seg_code);
|
||||||
|
u32 seg_len = CODE_SEG_SIZE(seg_code);
|
||||||
|
|
||||||
|
// sanity check for output pointer
|
||||||
|
if ((ptr_out - seg_len < comp_start) || (ptr_out + seg_off >= data_end))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// copy data to the correct place
|
||||||
|
for (u32 c = 0; c < seg_len; c++) {
|
||||||
|
u8 byte = *(ptr_out + seg_off);
|
||||||
|
*(--ptr_out) = byte;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// sanity check for both pointers
|
||||||
|
if ((ptr_out == comp_start) || (ptr_in == comp_start))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// control bit not set, copy byte verbatim
|
||||||
|
*(--ptr_out) = *(--ptr_in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check pointers
|
||||||
|
if ((ptr_in != comp_start) || (ptr_out != comp_start))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// all fine if arriving here - return the result
|
||||||
|
*code_size = data_end - data_start;
|
||||||
|
return 0;
|
||||||
|
}
|
7
source/game/codelzss.h
Normal file
7
source/game/codelzss.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#define EXEFS_CODE_NAME ".code"
|
||||||
|
|
||||||
|
u32 DecompressCodeLzss(u8* data_start, u32* code_size, u32 max_size);
|
@ -8,5 +8,6 @@
|
|||||||
#include "firm.h"
|
#include "firm.h"
|
||||||
#include "boss.h"
|
#include "boss.h"
|
||||||
#include "smdh.h"
|
#include "smdh.h"
|
||||||
|
#include "codelzss.h"
|
||||||
#include "nds.h"
|
#include "nds.h"
|
||||||
#include "ncchinfo.h"
|
#include "ncchinfo.h"
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char name[8];
|
char name[8];
|
||||||
u8 reserved[0x5];
|
u8 reserved[0x5];
|
||||||
u8 flag; // bit 1 for SD
|
u8 flag; // bit 1 for SD, bit 0 for compressed .code
|
||||||
u16 remaster_version;
|
u16 remaster_version;
|
||||||
u8 sci_data[0x30];
|
u8 sci_data[0x30];
|
||||||
u8 dependencies[0x180];
|
u8 dependencies[0x180];
|
||||||
|
@ -706,7 +706,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
bool titleinfo = (FTYPE_TITLEINFO(filetype));
|
bool titleinfo = (FTYPE_TITLEINFO(filetype));
|
||||||
bool renamable = (FTYPE_RENAMABLE(filetype));
|
bool renamable = (FTYPE_RENAMABLE(filetype));
|
||||||
bool transferable = (FTYPE_TRANSFERABLE(filetype) && IS_A9LH && (drvtype & DRV_FAT));
|
bool transferable = (FTYPE_TRANSFERABLE(filetype) && IS_A9LH && (drvtype & DRV_FAT));
|
||||||
bool hsinjectable = (FTYPE_HSINJECTABLE(filetype));
|
bool hsinjectable = (FTYPE_HASCODE(filetype));
|
||||||
|
bool extrcodeable = (FTYPE_HASCODE(filetype));
|
||||||
bool restorable = (FTYPE_RESTORABLE(filetype) && IS_A9LH && !(drvtype & DRV_SYSNAND));
|
bool restorable = (FTYPE_RESTORABLE(filetype) && IS_A9LH && !(drvtype & DRV_SYSNAND));
|
||||||
bool ebackupable = (FTYPE_EBACKUP(filetype));
|
bool ebackupable = (FTYPE_EBACKUP(filetype));
|
||||||
bool xorpadable = (FTYPE_XORPAD(filetype));
|
bool xorpadable = (FTYPE_XORPAD(filetype));
|
||||||
@ -714,7 +715,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
bool scriptable = (FTYPE_SCRIPT(filetype));
|
bool scriptable = (FTYPE_SCRIPT(filetype));
|
||||||
bool bootable = (FTYPE_BOOTABLE(filetype) && !(drvtype & DRV_VIRTUAL));
|
bool bootable = (FTYPE_BOOTABLE(filetype) && !(drvtype & DRV_VIRTUAL));
|
||||||
bool installable = (FTYPE_INSTALLABLE(filetype) && !(drvtype & DRV_VIRTUAL));
|
bool installable = (FTYPE_INSTALLABLE(filetype) && !(drvtype & DRV_VIRTUAL));
|
||||||
bool special_opt = mountable || verificable || decryptable || encryptable || cia_buildable || cia_buildable_legit || cxi_dumpable || tik_buildable || key_buildable || titleinfo || renamable || transferable || hsinjectable || restorable || xorpadable || ebackupable || keyinitable || bootable || scriptable || installable;
|
bool special_opt = mountable || verificable || decryptable || encryptable || cia_buildable || cia_buildable_legit || cxi_dumpable || tik_buildable || key_buildable || titleinfo || renamable || transferable || hsinjectable || restorable || xorpadable || ebackupable || extrcodeable || keyinitable || bootable || scriptable || installable;
|
||||||
|
|
||||||
char pathstr[32+1];
|
char pathstr[32+1];
|
||||||
TruncateString(pathstr, curr_entry->path, 32, 8);
|
TruncateString(pathstr, curr_entry->path, 32, 8);
|
||||||
@ -866,6 +867,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
int verify = (verificable) ? ++n_opt : -1;
|
int verify = (verificable) ? ++n_opt : -1;
|
||||||
int ctrtransfer = (transferable) ? ++n_opt : -1;
|
int ctrtransfer = (transferable) ? ++n_opt : -1;
|
||||||
int hsinject = (hsinjectable) ? ++n_opt : -1;
|
int hsinject = (hsinjectable) ? ++n_opt : -1;
|
||||||
|
int extrcode = (extrcodeable) ? ++n_opt : -1;
|
||||||
int rename = (renamable) ? ++n_opt : -1;
|
int rename = (renamable) ? ++n_opt : -1;
|
||||||
int xorpad = (xorpadable) ? ++n_opt : -1;
|
int xorpad = (xorpadable) ? ++n_opt : -1;
|
||||||
int xorpad_inplace = (xorpadable) ? ++n_opt : -1;
|
int xorpad_inplace = (xorpadable) ? ++n_opt : -1;
|
||||||
@ -891,6 +893,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
if (rename > 0) optionstr[rename-1] = "Rename file";
|
if (rename > 0) optionstr[rename-1] = "Rename file";
|
||||||
if (xorpad > 0) optionstr[xorpad-1] = "Build XORpads (SD output)";
|
if (xorpad > 0) optionstr[xorpad-1] = "Build XORpads (SD output)";
|
||||||
if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = "Build XORpads (inplace)";
|
if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = "Build XORpads (inplace)";
|
||||||
|
if (extrcode > 0) optionstr[extrcode-1] = "Extract " EXEFS_CODE_NAME;
|
||||||
if (keyinit > 0) optionstr[keyinit-1] = "Init " KEYDB_NAME;
|
if (keyinit > 0) optionstr[keyinit-1] = "Init " KEYDB_NAME;
|
||||||
if (install > 0) optionstr[install-1] = "Install FIRM";
|
if (install > 0) optionstr[install-1] = "Install FIRM";
|
||||||
if (boot > 0) optionstr[boot-1] = "Boot FIRM";
|
if (boot > 0) optionstr[boot-1] = "Boot FIRM";
|
||||||
@ -1181,6 +1184,12 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
(InjectHealthAndSafety(curr_entry->path, destdrv[user_select-1]) == 0) ? "success" : "failed");
|
(InjectHealthAndSafety(curr_entry->path, destdrv[user_select-1]) == 0) ? "success" : "failed");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (user_select == extrcode) { // -> Extract code
|
||||||
|
ShowString("%s\nExtracting .code,\nplease wait...", pathstr);
|
||||||
|
if (ExtractCodeFromCxiFile(curr_entry->path) == 0) {
|
||||||
|
ShowPrompt(false, "%s\n.code extracted to " OUTPUT_PATH, pathstr);
|
||||||
|
} else ShowPrompt(false, "%s\n.code extract failed", pathstr);
|
||||||
|
return 0;
|
||||||
} else if (user_select == ctrtransfer) { // -> transfer CTRNAND image to SysNAND
|
} else if (user_select == ctrtransfer) { // -> transfer CTRNAND image to SysNAND
|
||||||
char* destdrv[2] = { NULL };
|
char* destdrv[2] = { NULL };
|
||||||
n_opt = 0;
|
n_opt = 0;
|
||||||
|
@ -121,7 +121,7 @@ u32 LoadCiaStub(CiaStub* stub, const char* path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 LoadExeFsFile(void* data, const char* path, u32 offset, const char* name, u32 size_max) {
|
u32 LoadExeFsFile(void* data, const char* path, u32 offset, const char* name, u32 size_max, u32* bytes_read) {
|
||||||
NcchHeader ncch;
|
NcchHeader ncch;
|
||||||
ExeFsHeader exefs;
|
ExeFsHeader exefs;
|
||||||
FIL file;
|
FIL file;
|
||||||
@ -161,6 +161,7 @@ u32 LoadExeFsFile(void* data, const char* path, u32 offset, const char* name, u3
|
|||||||
}
|
}
|
||||||
} else ret = 1;
|
} else ret = 1;
|
||||||
|
|
||||||
|
if (bytes_read) *bytes_read = btr;
|
||||||
fvx_close(&file);
|
fvx_close(&file);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -172,7 +173,7 @@ u32 LoadNcchMeta(CiaMeta* meta, const char* path, u64 offset) {
|
|||||||
// get dependencies from exthdr, icon from exeFS
|
// get dependencies from exthdr, icon from exeFS
|
||||||
if ((LoadNcchHeaders(&ncch, &exthdr, NULL, path, offset) != 0) ||
|
if ((LoadNcchHeaders(&ncch, &exthdr, NULL, path, offset) != 0) ||
|
||||||
(BuildCiaMeta(meta, &exthdr, NULL) != 0) ||
|
(BuildCiaMeta(meta, &exthdr, NULL) != 0) ||
|
||||||
(LoadExeFsFile(meta->smdh, path, offset, "icon", sizeof(meta->smdh))))
|
(LoadExeFsFile(meta->smdh, path, offset, "icon", sizeof(meta->smdh), NULL)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1256,7 +1257,7 @@ u32 BuildCiaFromNcchFile(const char* path_ncch, const char* path_cia) {
|
|||||||
// optional stuff (proper titlekey / meta data)
|
// optional stuff (proper titlekey / meta data)
|
||||||
FindTitleKey((&cia->ticket), title_id);
|
FindTitleKey((&cia->ticket), title_id);
|
||||||
if (exthdr && (BuildCiaMeta(meta, exthdr, NULL) == 0) &&
|
if (exthdr && (BuildCiaMeta(meta, exthdr, NULL) == 0) &&
|
||||||
(LoadExeFsFile(meta->smdh, path_ncch, 0, "icon", sizeof(meta->smdh)) == 0) &&
|
(LoadExeFsFile(meta->smdh, path_ncch, 0, "icon", sizeof(meta->smdh), NULL) == 0) &&
|
||||||
(InsertCiaMeta(path_cia, meta) == 0))
|
(InsertCiaMeta(path_cia, meta) == 0))
|
||||||
cia->header.size_meta = CIA_META_SIZE;
|
cia->header.size_meta = CIA_META_SIZE;
|
||||||
|
|
||||||
@ -1321,7 +1322,7 @@ u32 BuildCiaFromNcsdFile(const char* path_ncsd, const char* path_cia) {
|
|||||||
// optional stuff (proper titlekey / meta data)
|
// optional stuff (proper titlekey / meta data)
|
||||||
FindTitleKey(&(cia->ticket), title_id);
|
FindTitleKey(&(cia->ticket), title_id);
|
||||||
if ((BuildCiaMeta(meta, exthdr, NULL) == 0) &&
|
if ((BuildCiaMeta(meta, exthdr, NULL) == 0) &&
|
||||||
(LoadExeFsFile(meta->smdh, path_ncsd, NCSD_CNT0_OFFSET, "icon", sizeof(meta->smdh)) == 0) &&
|
(LoadExeFsFile(meta->smdh, path_ncsd, NCSD_CNT0_OFFSET, "icon", sizeof(meta->smdh), NULL) == 0) &&
|
||||||
(InsertCiaMeta(path_cia, meta) == 0))
|
(InsertCiaMeta(path_cia, meta) == 0))
|
||||||
cia->header.size_meta = CIA_META_SIZE;
|
cia->header.size_meta = CIA_META_SIZE;
|
||||||
|
|
||||||
@ -1401,6 +1402,37 @@ u32 DumpCxiSrlFromTmdFile(const char* path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 ExtractCodeFromCxiFile(const char* path) {
|
||||||
|
u8* code = (u8*) TEMP_BUFFER;
|
||||||
|
u32 code_max_size = TEMP_BUFFER_SIZE;
|
||||||
|
|
||||||
|
NcchHeader ncch;
|
||||||
|
NcchExtHeader exthdr;
|
||||||
|
|
||||||
|
// load ncch, exthdr, .code
|
||||||
|
u32 code_size;
|
||||||
|
if ((LoadNcchHeaders(&ncch, &exthdr, NULL, path, 0) != 0) ||
|
||||||
|
(LoadExeFsFile(code, path, 0, EXEFS_CODE_NAME, code_max_size, &code_size)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// decompress code (only if required)
|
||||||
|
if ((exthdr.flag & 0x1) && (DecompressCodeLzss(code, &code_size, code_max_size) != 0))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// build output path
|
||||||
|
char dest[256];
|
||||||
|
snprintf(dest, 256, OUTPUT_PATH "/%016llX%s%s", ncch.programId, (exthdr.flag & 0x1) ? ".dec" : "", EXEFS_CODE_NAME);
|
||||||
|
|
||||||
|
// write output file
|
||||||
|
fvx_unlink(dest);
|
||||||
|
if (fvx_qwrite(dest, code, 0, code_size, NULL) != FR_OK) {
|
||||||
|
fvx_unlink(dest);
|
||||||
|
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);
|
||||||
|
|
||||||
@ -1408,9 +1440,9 @@ u32 LoadSmdhFromGameFile(const char* path, Smdh* smdh) {
|
|||||||
UINT btr;
|
UINT btr;
|
||||||
if ((fvx_qread(path, smdh, 0, sizeof(Smdh), &btr) == FR_OK) || (btr == sizeof(Smdh))) return 0;
|
if ((fvx_qread(path, smdh, 0, sizeof(Smdh), &btr) == FR_OK) || (btr == sizeof(Smdh))) return 0;
|
||||||
} else if (filetype & GAME_NCCH) { // NCCH file
|
} else if (filetype & GAME_NCCH) { // NCCH file
|
||||||
if (LoadExeFsFile(smdh, path, 0, "icon", sizeof(Smdh)) == 0) return 0;
|
if (LoadExeFsFile(smdh, path, 0, "icon", sizeof(Smdh), NULL) == 0) return 0;
|
||||||
} else if (filetype & GAME_NCSD) { // NCSD file
|
} else if (filetype & GAME_NCSD) { // NCSD file
|
||||||
if (LoadExeFsFile(smdh, path, NCSD_CNT0_OFFSET, "icon", sizeof(Smdh)) == 0) return 0;
|
if (LoadExeFsFile(smdh, path, NCSD_CNT0_OFFSET, "icon", sizeof(Smdh), NULL) == 0) return 0;
|
||||||
} else if (filetype & GAME_CIA) { // CIA file
|
} else if (filetype & GAME_CIA) { // CIA file
|
||||||
CiaInfo info;
|
CiaInfo info;
|
||||||
UINT btr;
|
UINT btr;
|
||||||
@ -1419,7 +1451,7 @@ u32 LoadSmdhFromGameFile(const char* path, Smdh* smdh) {
|
|||||||
(GetCiaInfo(&info, (CiaHeader*) &info) != 0)) return 1;
|
(GetCiaInfo(&info, (CiaHeader*) &info) != 0)) return 1;
|
||||||
if ((info.offset_meta) && (fvx_qread(path, smdh, info.offset_meta + 0x400, sizeof(Smdh), &btr) == FR_OK) &&
|
if ((info.offset_meta) && (fvx_qread(path, smdh, info.offset_meta + 0x400, sizeof(Smdh), &btr) == FR_OK) &&
|
||||||
(btr == sizeof(Smdh))) return 0;
|
(btr == sizeof(Smdh))) return 0;
|
||||||
else if (LoadExeFsFile(smdh, path, info.offset_content, "icon", sizeof(Smdh)) == 0) return 0;
|
else if (LoadExeFsFile(smdh, path, info.offset_content, "icon", sizeof(Smdh), NULL) == 0) return 0;
|
||||||
} else if (filetype & GAME_TMD) {
|
} else if (filetype & GAME_TMD) {
|
||||||
char path_content[256];
|
char path_content[256];
|
||||||
if (GetTmdContentPath(path_content, path) != 0) return 1;
|
if (GetTmdContentPath(path_content, path) != 0) return 1;
|
||||||
|
@ -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 DumpCxiSrlFromTmdFile(const char* path);
|
u32 DumpCxiSrlFromTmdFile(const char* path);
|
||||||
|
u32 ExtractCodeFromCxiFile(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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user