Files
Project_CTR/makerom/titleid.c
T
applestash efd71def1c fixes
2014-06-25 12:31:01 +10:00

231 lines
7.4 KiB
C

#include "lib.h"
#include "ncch.h"
#include "titleid.h"
void SetPIDType(u16 *type);
int SetPIDCategoryFromName(u16 *cat, char *CategoryStr);
int SetPIDCategoryFromFlags(u16 *cat, char **CategoryFlags, u32 FlagNum);
int SetPIDCategoryFromFlag(u16 *cat, u16 flag, char *flagName);
u32 SetPIDUniqueId(char *UniqueIdStr);
int SetTitleVariation(u8 *var, u16 cat, rsf_settings *rsf);
u64 ConvertTwlIdToCtrId(u64 pgid)
{
return 0x0004800000000000 | (pgid & 0x00007FFFFFFFFFFF);
}
int GetProgramID(u64 *dest, rsf_settings *rsf, bool IsForExheader)
{
int ret;
u32 uniqueId;
u16 type,category;
u8 variation;
if(rsf->TitleInfo.Category && rsf->TitleInfo.CategoryFlags){
fprintf(stderr,"[ID ERROR] Can not set \"Cateory\" and \"CategoryFlags\" at the same time.\n");
return PID_BAD_RSF_SET;
}
// Getting Type
SetPIDType(&type);
// Getting Category
if(rsf->TitleInfo.Category)
ret = SetPIDCategoryFromName(&category,rsf->TitleInfo.Category);
else if(rsf->TitleInfo.CategoryFlags)
ret = SetPIDCategoryFromFlags(&category,rsf->TitleInfo.CategoryFlags,rsf->TitleInfo.CategoryFlagsNum);
if(IsForExheader && rsf->TitleInfo.TargetCategory)
ret = SetPIDCategoryFromName(&category,rsf->TitleInfo.TargetCategory);
if(ret == PID_INVALID_CATEGORY) // Error occured
return PID_BAD_RSF_SET;
// Getting UniqueId
if(rsf->TitleInfo.UniqueId)
GetUniqueID(&uniqueId,rsf);
else{
fprintf(stderr,"[ID ERROR] ParameterNotFound: \"TitleInfo/UniqueId\"\n");
return PID_BAD_RSF_SET;
}
// Getting Variation
if(SetTitleVariation(&variation,category,rsf) == PID_INVALID_VARIATION)
return PID_BAD_RSF_SET;
u64 programId = 0;
programId |= (u64)variation<<0;
programId |= (u64)uniqueId<<8;
programId |= (u64)category<<32;
programId |= (u64)type<<48;
*dest = programId;
return 0;
}
void SetPIDType(u16 *type)
{
*type = 0x0004;
}
int GetUniqueID(u32 *uid, rsf_settings *rsf)
{
if(rsf->TitleInfo.UniqueId) *uid = 0xffffff & SetPIDUniqueId(rsf->TitleInfo.UniqueId);
else{
fprintf(stderr,"[ID ERROR] ParameterNotFound: \"TitleInfo/UniqueId\"\n");
return PID_BAD_RSF_SET;
}
return 0;
}
int SetPIDCategoryFromName(u16 *cat, char *CategoryStr)
{
if(strcmp(CategoryStr,"Application") == 0) *cat = PROGRAM_ID_CATEGORY_APPLICATION;
else if(strcmp(CategoryStr,"SystemApplication") == 0) *cat = PROGRAM_ID_CATEGORY_SYSTEM_APPLICATION;
else if(strcmp(CategoryStr,"Applet") == 0) *cat = PROGRAM_ID_CATEGORY_APPLET;
else if(strcmp(CategoryStr,"Firmware") == 0) *cat = PROGRAM_ID_CATEGORY_FIRMWARE;
else if(strcmp(CategoryStr,"Base") == 0) *cat = PROGRAM_ID_CATEGORY_BASE;
else if(strcmp(CategoryStr,"DlpChild") == 0) *cat = PROGRAM_ID_CATEGORY_DLP_CHILD;
else if(strcmp(CategoryStr,"Demo") == 0) *cat = PROGRAM_ID_CATEGORY_DEMO;
else if(strcmp(CategoryStr,"Contents") == 0) *cat = PROGRAM_ID_CATEGORY_CONTENTS;
else if(strcmp(CategoryStr,"SystemContents") == 0) *cat = PROGRAM_ID_CATEGORY_SYSTEM_CONTENT;
else if(strcmp(CategoryStr,"SharedContents") == 0) *cat = PROGRAM_ID_CATEGORY_SHARED_CONTENT;
else if(strcmp(CategoryStr,"AddOnContents") == 0) *cat = PROGRAM_ID_CATEGORY_ADD_ON_CONTENTS;
else if(strcmp(CategoryStr,"Patch") == 0) *cat = PROGRAM_ID_CATEGORY_PATCH;
else if(strcmp(CategoryStr,"AutoUpdateContents") == 0) *cat = PROGRAM_ID_CATEGORY_AUTO_UPDATE_CONTENT;
else {
fprintf(stderr,"[ID ERROR] Invalid Category: \"%s\"\n",CategoryStr);
return PID_INVALID_CATEGORY;
}
return 0;
}
int SetPIDCategoryFromFlags(u16 *cat, char **CategoryFlags, u32 FlagNum)
{
int ret = 0;
for(u32 i = 0; i < FlagNum; i++){
if(strcmp(CategoryFlags[i],"Normal") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_NORMAL,"Normal");
else if(strcmp(CategoryFlags[i],"DlpChild") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_DLP_CHILD,"DlpChild");
else if(strcmp(CategoryFlags[i],"Demo") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_DEMO,"Demo");
else if(strcmp(CategoryFlags[i],"Contents") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_CONTENTS,"Contents");
else if(strcmp(CategoryFlags[i],"AddOnContents") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_ADD_ON_CONTENTS,"AddOnContents");
else if(strcmp(CategoryFlags[i],"Patch") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_PATCH,"Patch");
else if(strcmp(CategoryFlags[i],"CannotExecution") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_CANNOT_EXECUTION,"CannotExecution");
else if(strcmp(CategoryFlags[i],"System") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_SYSTEM,"System");
else if(strcmp(CategoryFlags[i],"RequireBatchUpdate") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_REQUIRE_BATCH_UPDATE,"RequireBatchUpdate");
else if(strcmp(CategoryFlags[i],"NotRequireUserApproval") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_USER_APPROVAL,"NotRequireUserApproval");
else if(strcmp(CategoryFlags[i],"NotRequireRightForMount") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_NOT_REQUIRE_RIGHT_FOR_MOUNT,"NotRequireRightForMount");
else if(strcmp(CategoryFlags[i],"CanSkipConvertJumpId") == 0)
ret = SetPIDCategoryFromFlag(cat,PROGRAM_ID_CATEGORY_FLAG_CAN_SKIP_CONVERT_JUMP_ID,"CanSkipConvertJumpId");
if(ret == PID_INVALID_CATEGORY) break;
else {
fprintf(stderr,"[ID ERROR] Invalid CategoryFlag: \"%s\"\n",CategoryFlags[i]);
return PID_INVALID_CATEGORY;
}
}
return ret;
}
int SetPIDCategoryFromFlag(u16 *cat, u16 flag, char *flagName)
{
if(!flag) return 0;
if((*cat & flag) == flag){
fprintf(stderr,"[ID ERROR] Failed to set \"%s\" for category. CategoryFlag was already set.\n",flagName);
return PID_INVALID_CATEGORY;
}
*cat |= flag;
return 0;
}
u32 SetPIDUniqueId(char *UniqueIdStr)
{
return 0xffffff & strtoull(UniqueIdStr,NULL,0);
}
int SetTitleVariation(u8 *var, u16 cat, rsf_settings *rsf)
{
if(IsDemo(cat)){
if(rsf->TitleInfo.DemoIndex){
u8 DemoIndex = 0xff & strtol(rsf->TitleInfo.DemoIndex,NULL,10);
if(DemoIndex == 0){
fprintf(stderr,"[ID ERROR] Invalid demo index \"%d\"\n",DemoIndex);
return PID_INVALID_VARIATION;
}
*var = DemoIndex;
}
else{
fprintf(stderr,"[ID ERROR] ParameterNotFound: \"TitleInfo/DemoIndex\"\n");
return PID_INVALID_VARIATION;
}
}
else if(IsDlpChild(cat)){
if(rsf->TitleInfo.ChildIndex)
*var = 0xff & strtol(rsf->TitleInfo.ChildIndex,NULL,10);
else
*var = 0;
}
else if(IsAddOnContent(cat)){
if(rsf->TitleInfo.Variation) // Might Rename to DataTitleIndex
*var = 0xff & strtol(rsf->TitleInfo.Variation,NULL,10);
else
*var = 0;
}
else if(IsContents(cat)){
if(rsf->TitleInfo.ContentsIndex)
*var = 0xff & strtol(rsf->TitleInfo.ContentsIndex,NULL,10);
else
*var = 0;
}
else{
if(rsf->TitleInfo.Version)
*var = 0xff & strtol(rsf->TitleInfo.Version,NULL,10);
else
*var = 0;
}
return 0;
}
bool IsDemo(u16 Category)
{
return Category == PROGRAM_ID_CATEGORY_DEMO;
}
bool IsSystem(u16 Category)
{
return (Category & PROGRAM_ID_CATEGORY_FLAG_SYSTEM) == PROGRAM_ID_CATEGORY_FLAG_SYSTEM;
}
bool IsDlpChild(u16 Category)
{
return Category == PROGRAM_ID_CATEGORY_DLP_CHILD;
}
bool IsPatch(u16 Category)
{
return Category == PROGRAM_ID_CATEGORY_PATCH;
}
bool IsContents(u16 Category)
{
return (Category & PROGRAM_ID_CATEGORY_FLAG_CONTENTS) == PROGRAM_ID_CATEGORY_FLAG_CONTENTS;
}
bool IsAddOnContent(u16 Category)
{
return Category == PROGRAM_ID_CATEGORY_ADD_ON_CONTENTS;
}