diff --git a/source/game/gameutil.c b/source/game/gameutil.c index 7a3af30..bd221a5 100644 --- a/source/game/gameutil.c +++ b/source/game/gameutil.c @@ -1545,20 +1545,9 @@ u32 BuildNcchInfoXorpads(const char* destdir, const char* path) { return ret; } -u32 CheckHealthAndSafetyInject(const char* hsdrv) { - char path_mrk[32] = { 0 }; - snprintf(path_mrk, 32, "%s/%s", hsdrv, HSINJECT_MARKFILE); - return (f_stat(path_mrk, NULL) == FR_OK) ? 0 : 1; -} - -u32 InjectHealthAndSafety(const char* path, const char* destdrv) { +u32 GetHealthAndSafetyPaths(const char* drv, char* path_cxi, char* path_bak) { const u32 tidlow_hs_o3ds[] = { 0x00020300, 0x00021300, 0x00022300, 0, 0x00026300, 0x00027300, 0x00028300 }; const u32 tidlow_hs_n3ds[] = { 0x20020300, 0x20021300, 0x20022300, 0, 0, 0x20027300, 0 }; - NcchHeader ncch; - - // write permissions - if (!CheckWritePermissions(destdrv)) - return 1; // get H&S title id low u32 tidlow_hs = 0; @@ -1567,7 +1556,7 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) { u8 secinfo[0x111]; u32 region = 0xFF; UINT br; - snprintf(path_secinfo, 32, "%s/rw/sys/SecureInfo_%c", destdrv, secchar); + snprintf(path_secinfo, 32, "%s/rw/sys/SecureInfo_%c", drv, secchar); if ((fvx_qread(path_secinfo, secinfo, 0, 0x111, &br) != FR_OK) || (br != 0x111)) continue; @@ -1580,26 +1569,48 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) { if (!tidlow_hs) return 1; // build paths - char path_cxi[64] = { 0 }; - char path_bak[64] = { 0 }; - char path_mrk[32] = { 0 }; - snprintf(path_mrk, 32, "%s/%s", destdrv, HSINJECT_MARKFILE); + if (path_cxi) *path_cxi = '\0'; + if (path_bak) *path_bak = '\0'; for (u32 i = 0; i < 8; i++) { // 8 is an arbitrary number TitleMetaData* tmd = (TitleMetaData*) TEMP_BUFFER; TmdContentChunk* chunk = (TmdContentChunk*) (tmd + 1); char path_tmd[64]; - snprintf(path_tmd, 64, "%s/title/00040010/%08lx/content/%08lx.tmd", destdrv, tidlow_hs, i); + snprintf(path_tmd, 64, "%s/title/00040010/%08lx/content/%08lx.tmd", drv, tidlow_hs, i); if (LoadTmdFile(tmd, path_tmd) != 0) continue; if (!getbe16(tmd->content_count)) return 1; - snprintf(path_cxi, 64, "%s/title/00040010/%08lx/content/%08lx.app", destdrv, tidlow_hs, getbe32(chunk->id)); - snprintf(path_bak, 64, "%s/title/00040010/%08lx/content/%08lx.bak", destdrv, tidlow_hs, getbe32(chunk->id)); + if (path_cxi) snprintf(path_cxi, 64, "%s/title/00040010/%08lx/content/%08lx.app", drv, tidlow_hs, getbe32(chunk->id)); + if (path_bak) snprintf(path_bak, 64, "%s/title/00040010/%08lx/content/%08lx.bak", drv, tidlow_hs, getbe32(chunk->id)); break; } - if (!(*path_cxi)) return 1; + + return ((path_cxi && !*path_cxi) || (path_bak && !*path_bak)) ? 1 : 0; +} + +u32 CheckHealthAndSafetyInject(const char* hsdrv) { + char path_bak[64] = { 0 }; + return ((GetHealthAndSafetyPaths(hsdrv, NULL, path_bak) == 0) && + (f_stat(path_bak, NULL) == FR_OK)) ? 0 : 1; +} + +u32 InjectHealthAndSafety(const char* path, const char* destdrv) { + NcchHeader ncch; + + // write permissions + if (!CheckWritePermissions(destdrv)) + return 1; + + // legacy stuff - remove mark file + char path_mrk[32] = { 0 }; + snprintf(path_mrk, 32, "%s/%s", destdrv, "__gm9_hsbak.pth"); + f_unlink(path_mrk); + + // get H&S paths + char path_cxi[64] = { 0 }; + char path_bak[64] = { 0 }; + if (GetHealthAndSafetyPaths(destdrv, path_cxi, path_bak) != 0) return 1; if (!path) { // if path == NULL -> restore H&S from backup if (f_stat(path_bak, NULL) != FR_OK) return 1; - f_unlink(path_mrk); f_unlink(path_cxi); f_rename(path_bak, path_cxi); return 0; @@ -1611,15 +1622,13 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) { return 1; // check crypto, get sig - u64 tid_hs = ((u64) 0x00040010 << 32) | tidlow_hs; - u16 crypto = NCCH_NOCRYPTO; - u8 sig[0x100]; if ((LoadNcchHeaders(&ncch, NULL, NULL, path_cxi, 0) != 0) || - (SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) || !(NCCH_IS_CXI(&ncch)) || - (ncch.programId != tid_hs) || (ncch.partitionId != tid_hs)) + (SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) || !(NCCH_IS_CXI(&ncch))) return 1; - crypto = NCCH_GET_CRYPTO(&ncch); + u8 sig[0x100]; memcpy(sig, ncch.signature, 0x100); + u16 crypto = NCCH_GET_CRYPTO(&ncch); + u64 tid_hs = ncch.programId; // make a backup copy if there is not already one (point of no return) if (f_stat(path_bak, NULL) != FR_OK) { @@ -1649,9 +1658,6 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) { if (ret != 0) { // in case of failure: try recover f_unlink(path_cxi); f_rename(path_bak, path_cxi); - } else { // in case of success: mark this ctrnand as H&S injected - UINT bw; - fvx_qwrite(path_mrk, path_bak, 0, strnlen(path_bak, 63) + 1, &bw); } return ret; diff --git a/source/game/gameutil.h b/source/game/gameutil.h index 176c27b..100f334 100644 --- a/source/game/gameutil.h +++ b/source/game/gameutil.h @@ -2,8 +2,6 @@ #include "common.h" -#define HSINJECT_MARKFILE "__gm9_hsbak.pth" - u32 VerifyGameFile(const char* path); u32 CheckEncryptedGameFile(const char* path); u32 CryptGameFile(const char* path, bool inplace, bool encrypt); diff --git a/source/game/nds.c b/source/game/nds.c index 0a55b19..036eac1 100644 --- a/source/game/nds.c +++ b/source/game/nds.c @@ -55,7 +55,7 @@ u32 GetTwlTitle(char* desc, const TwlIconData* twl_icon) { u32 GetTwlIcon(u8* icon, const TwlIconData* twl_icon) { const u32 h = TWLICON_DIM_ICON; // fixed size const u32 w = TWLICON_DIM_ICON; // fixed size - u16* palette = twl_icon->palette; + const u16* palette = twl_icon->palette; u8* pix4 = (u8*) twl_icon->icon; for (u32 y = 0; y < h; y += 8) { for (u32 x = 0; x < w; x += 8) { diff --git a/source/nand/ctrtransfer.c b/source/nand/ctrtransfer.c index 9b4708c..99e5239 100644 --- a/source/nand/ctrtransfer.c +++ b/source/nand/ctrtransfer.c @@ -62,8 +62,6 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) { PathCopy(path_dbs, path_from, &flags); FixFileCmac(path_to); } - snprintf(path_to, 32, "%s/" HSINJECT_MARKFILE, drv); - PathDelete(path_to); ShowString("Cleaning up titles, please wait..."); snprintf(path_to, 32, "%s/title", drv); snprintf(path_from, 32, "7:/title");