From 4c965b8c9237855e98520be1c854b54f131edef1 Mon Sep 17 00:00:00 2001 From: jakcron Date: Thu, 22 Oct 2015 01:45:08 +0800 Subject: [PATCH] [makerom] Simplified CIA version logic. --- makerom/cia.c | 26 ++++---------------------- makerom/cia_build.h | 4 ++-- makerom/user_settings.c | 38 +++++++++++++++++++++++++++++++++----- makerom/user_settings.h | 2 ++ 4 files changed, 41 insertions(+), 29 deletions(-) diff --git a/makerom/cia.c b/makerom/cia.c index 8c496bc..719c91b 100644 --- a/makerom/cia.c +++ b/makerom/cia.c @@ -170,6 +170,7 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset) ciaset->cert.caCrlVersion = 0; ciaset->cert.signerCrlVersion = 0; + ciaset->common.useCxiRemasterVersion = !usrset->cia.useFullTitleVer; for(int i = 0; i < 3; i++){ ciaset->common.titleVersion[i] = usrset->cia.titleVersion[i]; } @@ -239,6 +240,7 @@ int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset) int result = VerifyNcch(ncch0, ciaset->keys, false, ciaset->verbose == false); if(result == UNABLE_TO_LOAD_NCCH_KEY){ ciaset->content.keyFound = false; + ciaset->common.useCxiRemasterVersion = false; if(!ciaset->content.IsCfa){ fprintf(stderr,"[CIA WARNING] CXI AES Key could not be loaded\n"); fprintf(stderr," Meta Region, SaveDataSize, Remaster Version cannot be obtained\n"); @@ -306,35 +308,15 @@ int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 * ciaset->tmd.savedataSize = 0; // Process title version - // If this is a CFA, the -major must be set, since CFAs don't have an exheader - if(ciaset->content.IsCfa){ - if(ciaset->common.titleVersion[VER_MAJOR] == MAX_U16){ // '-major' wasn't set - fprintf(stderr,"[CIA ERROR] Invalid major version. Use \"-major\" option.\n"); - result = CIA_BAD_VERSION; - goto cleanup; - } - } - // Otherwise this is a CXI, if it can be decrypted, -major cannot be set and must be read from exheader - else if(ciaset->content.keyFound){ - if(ciaset->common.titleVersion[VER_MAJOR] != MAX_U16){ // '-major' was set - fprintf(stderr,"[CIA ERROR] Option \"-major\" cannot be applied for cxi.\n"); - result = CIA_BAD_VERSION; - goto cleanup; - } + // If this is a CXI, and we have to pull version major from exheader... + if(!ciaset->content.IsCfa && ciaset->common.useCxiRemasterVersion){ // Setting remaster ver ciaset->common.titleVersion[VER_MAJOR] = GetRemasterVersion_frm_exhdr(exhdr); } - - // CXI which cannot be decrypted - else{ - if(ciaset->common.titleVersion[VER_MAJOR] == MAX_U16) // '-major' wasn't set - ciaset->common.titleVersion[VER_MAJOR] = 0; - } // Calculate u16 title version ciaset->tmd.version = ciaset->tik.version = SetupVersion(ciaset->common.titleVersion[VER_MAJOR],ciaset->common.titleVersion[VER_MINOR],ciaset->common.titleVersion[VER_MICRO]); -cleanup: free(exhdr); return result; } diff --git a/makerom/cia_build.h b/makerom/cia_build.h index 0c24277..f25f156 100644 --- a/makerom/cia_build.h +++ b/makerom/cia_build.h @@ -7,7 +7,6 @@ typedef enum CIA_NO_NCCH0 = -1, CIA_INVALID_NCCH0 = -2, CIA_CONFILCTING_CONTENT_IDS = -3, - CIA_BAD_VERSION = -4, } cia_errors; typedef struct @@ -23,8 +22,9 @@ typedef struct bool verbose; struct{ + bool useCxiRemasterVersion; u64 titleId; - u16 titleVersion[4]; + u16 titleVersion[3]; u8 titleKey[16]; } common; diff --git a/makerom/user_settings.c b/makerom/user_settings.c index 7477b82..aa5bc46 100644 --- a/makerom/user_settings.c +++ b/makerom/user_settings.c @@ -118,7 +118,7 @@ void SetDefaults(user_settings *set) set->cia.deviceId = 0; set->cia.eshopAccId = 0; set->cia.useDataTitleVer = false; - set->cia.titleVersion[VER_MAJOR] = MAX_U16; // invalid so changes can be detected + set->cia.useFullTitleVer = false; set->cia.randomTitleKey = false; set->common.keys.aes.currentCommonKey = MAX_U8 + 1; // invalid so changes can be detected for (int i = 0; i < CIA_MAX_CONTENT; i++) @@ -450,13 +450,29 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set) } // Cia Options + else if (strcmp(argv[i], "-ver") == 0) { + if (ParamNum != 1) { + PrintArgReqParam(argv[i], 1); + return USR_ARG_REQ_PARAM; + } + set->cia.useFullTitleVer = true; + u32 ver = strtoul(argv[i + 1], NULL, 0); + if (ver > VER_MAX) { + fprintf(stderr, "[SETTING ERROR] Version: '%d' is too large, max: '%d'\n", ver, VER_MAX); + return USR_BAD_ARG; + } + set->cia.titleVersion[VER_MAJOR] = (ver >> 10) & VER_MAJOR_MAX; + set->cia.titleVersion[VER_MINOR] = (ver >> 4) & VER_MINOR_MAX; + set->cia.titleVersion[VER_MICRO] = ver & VER_MICRO_MAX; + return 2; + } else if (strcmp(argv[i], "-major") == 0) { if (ParamNum != 1) { PrintArgReqParam(argv[i], 1); return USR_ARG_REQ_PARAM; } set->cia.useNormTitleVer = true; - u32 ver = strtoul(argv[i + 1], NULL, 10); + u32 ver = strtoul(argv[i + 1], NULL, 0); if (ver > VER_MAJOR_MAX) { fprintf(stderr, "[SETTING ERROR] Major version: '%d' is too large, max: '%d'\n", ver, VER_MAJOR_MAX); return USR_BAD_ARG; @@ -470,7 +486,7 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set) return USR_ARG_REQ_PARAM; } set->cia.useNormTitleVer = true; - u32 ver = strtoul(argv[i + 1], NULL, 10); + u32 ver = strtoul(argv[i + 1], NULL, 0); if (ver > VER_MINOR_MAX) { fprintf(stderr, "[SETTING ERROR] Minor version: '%d' is too large, max: '%d'\n", ver, VER_MINOR_MAX); return USR_BAD_ARG; @@ -483,7 +499,7 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set) PrintArgReqParam(argv[i], 1); return USR_ARG_REQ_PARAM; } - u32 ver = strtoul(argv[i + 1], NULL, 10); + u32 ver = strtoul(argv[i + 1], NULL, 0); if (ver > VER_MICRO_MAX) { fprintf(stderr, "[SETTING ERROR] Micro version: '%d' is too large, max: '%d'\n", ver, VER_MICRO_MAX); return USR_BAD_ARG; @@ -497,7 +513,7 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set) return USR_ARG_REQ_PARAM; } set->cia.useDataTitleVer = true; - u32 ver = strtoul(argv[i + 1], NULL, 10); + u32 ver = strtoul(argv[i + 1], NULL, 0); if (ver > VER_DVER_MAX) { fprintf(stderr, "[SETTING ERROR] Data version: '%d' is too large, max: '%d'\n", ver, VER_DVER_MAX); return USR_BAD_ARG; @@ -732,6 +748,16 @@ int CheckArgumentCombination(user_settings *set) return USR_BAD_ARG; } + if (set->cia.useDataTitleVer && set->cia.useFullTitleVer) { + fprintf(stderr, "[SETTING ERROR] Arguments \"-dver\" and \"-ver\" cannot be used together\n"); + return USR_BAD_ARG; + } + + if (set->cia.useNormTitleVer && set->cia.useFullTitleVer) { + fprintf(stderr, "[SETTING ERROR] Arguments \"-ver\" and \"-major\"/\"-minor\" cannot be used together\n"); + return USR_BAD_ARG; + } + if (set->ncch.elfPath && set->ncch.codePath) { fprintf(stderr, "[SETTING ERROR] Arguments \"-elf\" and \"-code\" cannot be used together\n"); return USR_BAD_ARG; @@ -878,6 +904,7 @@ void DisplayHelp(char *app_name) printf(" -romfs RomFS binary\n"); printf("CIA/CCI OPTIONS:\n"); printf(" -content : Specify content files\n"); + printf(" -ver Title Version\n"); } void DisplayExtendedHelp(char *app_name) @@ -923,6 +950,7 @@ void DisplayExtendedHelp(char *app_name) printf("CIA OPTIONS:\n"); printf(" -content :: Specify content files\n"); printf(" -ver Title Version\n"); + printf(" -major Major version\n"); printf(" -minor Minor version\n"); printf(" -micro Micro version\n"); printf(" -dver Data-title version\n"); diff --git a/makerom/user_settings.h b/makerom/user_settings.h index 6e18c98..f06f95f 100644 --- a/makerom/user_settings.h +++ b/makerom/user_settings.h @@ -15,6 +15,7 @@ typedef enum typedef enum { + VER_MAX = 65535, VER_MAJOR_MAX = 63, VER_MINOR_MAX = 63, VER_MICRO_MAX = 15, @@ -291,6 +292,7 @@ typedef struct bool useNormTitleVer; bool useDataTitleVer; + bool useFullTitleVer; u16 titleVersion[3]; u32 deviceId;