From e744be504b1fc1fe7c0ace329bb111e7c71050f0 Mon Sep 17 00:00:00 2001 From: aspargas2 Date: Fri, 31 Jul 2020 02:18:44 -0400 Subject: [PATCH] perform DISA/DIFF cmac fixing automatically upon unmounting --- arm9/source/filesys/fsinit.c | 2 +- arm9/source/filesys/image.c | 6 ++++++ arm9/source/godmode.c | 6 +++--- arm9/source/utils/ctrtransfer.c | 2 +- arm9/source/utils/gameutil.c | 4 +--- arm9/source/utils/nandcmac.c | 18 +++++++++--------- arm9/source/utils/nandcmac.h | 14 +++++++------- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/arm9/source/filesys/fsinit.c b/arm9/source/filesys/fsinit.c index ea8bd29..f9f553b 100644 --- a/arm9/source/filesys/fsinit.c +++ b/arm9/source/filesys/fsinit.c @@ -65,9 +65,9 @@ bool InitImgFS(const char* path) { } void DeinitExtFS() { + InitImgFS(NULL); SetupNandSdDrive(NULL, NULL, NULL, 0); SetupNandSdDrive(NULL, NULL, NULL, 1); - InitImgFS(NULL); for (u32 i = NORM_FS - 1; i > 0; i--) { if (fs_mounted[i]) { char fsname[8]; diff --git a/arm9/source/filesys/image.c b/arm9/source/filesys/image.c index 09a4279..507f9f5 100644 --- a/arm9/source/filesys/image.c +++ b/arm9/source/filesys/image.c @@ -1,11 +1,14 @@ #include "image.h" #include "vff.h" +#include "nandcmac.h" static FIL mount_file; static u64 mount_state = 0; static char mount_path[256] = { 0 }; +static bool fix_cmac = false; + int ReadImageBytes(void* buffer, u64 offset, u64 count) { UINT bytes_read; @@ -28,6 +31,7 @@ int WriteImageBytes(const void* buffer, u64 offset, u64 count) { if (fvx_tell(&mount_file) != offset) fvx_lseek(&mount_file, offset); ret = fvx_write(&mount_file, buffer, count, &bytes_written); + if (ret == 0) fix_cmac = true; return (ret != 0) ? (int) ret : (bytes_written != count) ? -1 : 0; } @@ -59,6 +63,8 @@ u64 MountImage(const char* path) { u64 type = (path) ? IdentifyFileType(path) : 0; if (mount_state) { fvx_close(&mount_file); + if (fix_cmac) FixFileCmac(mount_path, false); + fix_cmac = false; mount_state = 0; *mount_path = 0; } diff --git a/arm9/source/godmode.c b/arm9/source/godmode.c index 9bf46fa..1cf20aa 100644 --- a/arm9/source/godmode.c +++ b/arm9/source/godmode.c @@ -892,7 +892,7 @@ u32 CmacCalculator(const char* path) { pathstr, getbe64(cmac + 0), getbe64(cmac + 8), "CMAC verification: ", (identical) ? "passed!" : "failed!", (!identical) ? "\n \nFix CMAC in file?" : "") && - !identical && (WriteFileCmac(path, cmac) != 0)) { + !identical && (WriteFileCmac(path, cmac, true) != 0)) { ShowPrompt(false, "Fixing CMAC: failed!"); } } @@ -901,7 +901,7 @@ u32 CmacCalculator(const char* path) { if (ShowPrompt(!correct, "%s\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n%s%s%s", pathstr, "CMAC verification: ", (correct) ? "passed!" : "failed!", (!correct) ? "\n \nFix CMAC in file?" : "") && - !correct && (FixCmdCmac(path) != 0)) { + !correct && (FixCmdCmac(path, true) != 0)) { ShowPrompt(false, "Fixing CMAC: failed!"); } } @@ -1233,7 +1233,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, PaneData** pan continue; } if (CheckFileCmac(path) == 0) n_success++; - else if (fix && (FixFileCmac(path) == 0)) n_fixed++; + else if (fix && (FixFileCmac(path, true) == 0)) n_fixed++; else { // on failure: set cursor on failed file *cursor = i; continue; diff --git a/arm9/source/utils/ctrtransfer.c b/arm9/source/utils/ctrtransfer.c index 8ee054e..7ac1c91 100644 --- a/arm9/source/utils/ctrtransfer.c +++ b/arm9/source/utils/ctrtransfer.c @@ -108,7 +108,7 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) { snprintf(path_from, 32, "7:/dbs/%s", dbnames[i]); PathDelete(path_to); PathCopy(path_dbs, path_from, &flags); - FixFileCmac(path_to); + FixFileCmac(path_to, true); } ShowString("Cleaning up titles, please wait..."); snprintf(path_to, 32, "%s/title", drv); diff --git a/arm9/source/utils/gameutil.c b/arm9/source/utils/gameutil.c index 2f5f713..51a8420 100644 --- a/arm9/source/utils/gameutil.c +++ b/arm9/source/utils/gameutil.c @@ -1489,9 +1489,7 @@ u32 InstallCiaSystemData(CiaStub* cia, const char* drv) { InitImgFS(path_bak); // fix CMACs where required - if (!syscmd) FixFileCmac(path_cmd); - FixFileCmac(path_ticketdb); - FixFileCmac(path_titledb); + if (!syscmd) FixFileCmac(path_cmd, true); return 0; } diff --git a/arm9/source/utils/nandcmac.c b/arm9/source/utils/nandcmac.c index a0aedf8..d1f1ac5 100644 --- a/arm9/source/utils/nandcmac.c +++ b/arm9/source/utils/nandcmac.c @@ -130,7 +130,7 @@ u32 CheckCmacPath(const char* path) { return (CalculateFileCmac(path, NULL)) ? 0 : 1; } -u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write) { +u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write, bool check_perms) { u32 cmac_type = CalculateFileCmac(path, NULL); u32 offset = 0; @@ -141,7 +141,7 @@ u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write) { else if ((cmac_type == CMAC_CMD_SD) || (cmac_type == CMAC_CMD_TWLN)) return 1; // can't do that here else offset = 0x000; - if (do_write && !CheckWritePermissions(path)) return 1; + if (do_write && check_perms && !CheckWritePermissions(path)) return 1; if (!do_write) return (fvx_qread(path, cmac, offset, 0x10, NULL) != FR_OK) ? 1 : 0; else return (fvx_qwrite(path, cmac, offset, 0x10, NULL) != FR_OK) ? 1 : 0; } @@ -298,13 +298,13 @@ u32 CheckFileCmac(const char* path) { } else return 1; } -u32 FixFileCmac(const char* path) { +u32 FixFileCmac(const char* path, bool check_perms) { u32 cmac_type = CalculateFileCmac(path, NULL); if ((cmac_type == CMAC_CMD_SD) || (cmac_type == CMAC_CMD_TWLN)) { - return FixCmdCmac(path); + return FixCmdCmac(path, check_perms); } else if (cmac_type) { u8 ccmac[16]; - return ((CalculateFileCmac(path, ccmac) == 0) && (WriteFileCmac(path, ccmac) == 0)) ? 0 : 1; + return ((CalculateFileCmac(path, ccmac) == 0) && (WriteFileCmac(path, ccmac, check_perms) == 0)) ? 0 : 1; } else return 1; } @@ -344,7 +344,7 @@ u32 FixAgbSaveCmac(void* data, u8* cmac, const char* sddrv) { return 0; } -u32 CheckFixCmdCmac(const char* path, bool fix) { +u32 CheckFixCmdCmac(const char* path, bool fix, bool check_perms) { u8 cmac[16] __attribute__((aligned(4))); u32 keyslot = ((*path == 'A') || (*path == 'B')) ? 0x30 : 0x0B; bool fixed = false; @@ -440,7 +440,7 @@ u32 CheckFixCmdCmac(const char* path, bool fix) { } // if fixing is enabled, write back cmd file - if (fix && fixed && CheckWritePermissions(path) && + if (fix && fixed && (!check_perms || CheckWritePermissions(path)) && (fvx_qwrite(path, cmd_data, 0, cmd_size, NULL) != FR_OK)) { free(cmd_data); return 1; @@ -472,14 +472,14 @@ u32 RecursiveFixFileCmacWorker(char* path) { } else if (fno.fattrib & AM_DIR) { // directory, recurse through it if (RecursiveFixFileCmacWorker(path) != 0) err = 1; } else if (CheckCmacPath(path) == 0) { // file, try to fix the CMAC - if (FixFileCmac(path) != 0) err = 1; + if (FixFileCmac(path, true) != 0) err = 1; ShowString("%s\nFixing CMACs, please wait...", pathstr); } } f_closedir(&pdir); *(--fname) = '\0'; } else if (CheckCmacPath(path) == 0) // fix single file CMAC - return FixFileCmac(path); + return FixFileCmac(path, true); return err; } diff --git a/arm9/source/utils/nandcmac.h b/arm9/source/utils/nandcmac.h index 741c9a1..6d5c5e6 100644 --- a/arm9/source/utils/nandcmac.h +++ b/arm9/source/utils/nandcmac.h @@ -2,16 +2,16 @@ #include "common.h" -#define ReadFileCmac(path, cmac) ReadWriteFileCmac(path, cmac, false) -#define WriteFileCmac(path, cmac) ReadWriteFileCmac(path, cmac, true) -#define CheckCmdCmac(path) CheckFixCmdCmac(path, false) -#define FixCmdCmac(path) CheckFixCmdCmac(path, true) +#define ReadFileCmac(path, cmac) ReadWriteFileCmac(path, cmac, false, true) +#define WriteFileCmac(path, cmac, check_perms) ReadWriteFileCmac(path, cmac, true, check_perms) +#define CheckCmdCmac(path) CheckFixCmdCmac(path, false, true) +#define FixCmdCmac(path, check_perms) CheckFixCmdCmac(path, true, check_perms) u32 CheckCmacPath(const char* path); -u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write); +u32 ReadWriteFileCmac(const char* path, u8* cmac, bool do_write, bool check_perms); u32 CalculateFileCmac(const char* path, u8* cmac); u32 CheckFileCmac(const char* path); -u32 FixFileCmac(const char* path); +u32 FixFileCmac(const char* path, bool check_perms); u32 FixAgbSaveCmac(void* data, u8* cmac, const char* sddrv); -u32 CheckFixCmdCmac(const char* path, bool fix); +u32 CheckFixCmdCmac(const char* path, bool fix, bool check_perms); u32 RecursiveFixFileCmac(const char* path);