s8 GetTitleName(u64 id, u32 app, char* name,u8* _dst_uncode_name) { s32 r; int lang = 1; //CONF_GetLanguage(); /* languages: enum { CONF_LANG_JAPANESE = 0, CONF_LANG_ENGLISH, CONF_LANG_GERMAN, CONF_LANG_FRENCH, CONF_LANG_SPANISH, CONF_LANG_ITALIAN, CONF_LANG_DUTCH, CONF_LANG_SIMP_CHINESE, CONF_LANG_TRAD_CHINESE, CONF_LANG_KOREAN }; cause we dont support unicode stuff in font.cpp we will force to use english then(1) */ u8 return_unicode_name = 0; if(_dst_uncode_name == NULL) { return_unicode_name = 0; } else { return_unicode_name = 1; } char file[256] ATTRIBUTE_ALIGN(32); memset(file,0,256); sprintf(file, "/title/%08x/%08x/content/%08x.app", (u32)(id >> 32), (u32)(id & 0xFFFFFFFF), app); gdprintf("GetTitleName : %s\n",file); u32 cnt ATTRIBUTE_ALIGN(32); cnt = 0; IMET *data = (IMET *)mem_align(32, ALIGN32( sizeof(IMET) ) ); if(data == NULL) { gprintf("GetTitleName : IMET header align failure\n"); return -1; } memset(data,0,sizeof(IMET) ); r = ES_GetNumTicketViews(id, &cnt); if(r < 0) { gprintf("GetTitleName : GetNumTicketViews error %d!\n",r); mem_free(data); return -1; } tikview *views = (tikview *)mem_align( 32, sizeof(tikview)*cnt ); if(views == NULL) { mem_free(data); return -2; } r = ES_GetTicketViews(id, views, cnt); if (r < 0) { gprintf("GetTitleName : GetTicketViews error %d \n",r); mem_free(data); mem_free(views); return -3; } //lets get this party started with the right way to call ES_OpenTitleContent. and not like how libogc < 1.8.3 does it. patch was passed on , and is done correctly in 1.8.3 //the right way is ES_OpenTitleContent(u64 TitleID,tikview* views,u16 Index); note the views >_> s32 fh = ES_OpenTitleContent(id, views, 0); if (fh == -106) { CheckTitleOnSD(id); mem_free(data); mem_free(views); return -106; } else if(fh < 0) { //ES method failed. remove tikviews from memory and fall back on ISFS method gprintf("GetTitleName : ES_OpenTitleContent error %d\n",fh); mem_free(views); fh = ISFS_Open(file, ISFS_OPEN_READ); // f**k failed. lets check SD & GTFO if (fh == -106) { CheckTitleOnSD(id); return -106; } else if (fh < 0) { mem_free(data); gprintf("open %s error %d\n",file,fh); return -5; } // read the completed IMET header r = ISFS_Read(fh, data, sizeof(IMET)); if (r < 0) { gprintf("IMET read error %d\n",r); ISFS_Close(fh); mem_free(data); return -6; } ISFS_Close(fh); } else { //ES method r = ES_ReadContent(fh,(u8*)data,sizeof(IMET)); if (r < 0) { gprintf("GetTitleName : ES_ReadContent error %d\n",r); ES_CloseContent(fh); mem_free(data); mem_free(views); return -8; } //free data and let it point to IMET_data so everything else can work just fine ES_CloseContent(fh); mem_free(views); } char str[10][84]; char str_unprocessed[10][84]; //clear any memory that is in the place of the array cause we dont want any confusion here memset(str,0,10*84); if(return_unicode_name) memset(str_unprocessed,0,10*84); if(data->imet == 0x494d4554) // check if its a valid imet header { for(u8 y =0;y <= 9;y++) { u8 p = 0; u8 up = 0; for(u8 j=0;j<83;j++) { if(data->names[y][j] < 0x20) if(return_unicode_name && data->names[y][j] == 0x00) str_unprocessed[y][up++] = data->names[y][j]; else continue; else if(data->names[y][j] > 0x7E) continue; else { str[y][p++] = data->names[y][j]; str_unprocessed[y][up++] = data->names[y][j]; } } str[y][83] = '\0'; } mem_free(data); } else { gprintf("invalid IMET header for 0x%08x/0x%08x\n", (u32)(id >> 32), (u32)(id & 0xFFFFFFFF)); return -9; } if(str[lang][0] != '\0') { gdprintf("GetTitleName : title %s\n",str[lang]); snprintf(name,255, "%s", str[lang]); if (return_unicode_name && str_unprocessed[lang][1] != '\0') { memcpy(_dst_uncode_name,&str_unprocessed[lang][0],83); } else if(return_unicode_name) gprintf("WARNING : empty unprocessed string\n"); } else gprintf("GetTitleName: no name found\n"); memset(str,0,10*84); memset(str_unprocessed,0,10*84); return 1; }
return ERR_NONE; } void changeChannelName(u64 titleID) { printf("Identifying as 00000001-00000000 (SU)!... "); CheckESRetval(ES_Identify(SU_IDENTIFY)); // if(ES_SetUID(titleID)<0) // return; u32 tmd_size ATTRIBUTE_ALIGN(32); if(CheckESRetval(ES_GetStoredTMDSize(titleID, &tmd_size))!=0) return; signed_blob *TMD = (signed_blob *)memalign( 32, tmd_size ); memset(TMD, 0, tmd_size); if(CheckESRetval(ES_GetStoredTMD(titleID, TMD, tmd_size))!=0) { free(TMD); return; } u32 cnt ATTRIBUTE_ALIGN(32); if(CheckESRetval(ES_GetNumTicketViews(titleID, &cnt))!=0) { free(TMD); return; } if( cnt <= 0 ) { free(TMD); return; } tikview *views = (tikview *)memalign( 32, sizeof(tikview)*cnt ); if(CheckESRetval(ES_GetTicketViews(titleID, views, cnt))!=0) { free(views); free(TMD); return; } char *name=calloc((0x54/2),1); int z; for(z=0; z < 1; ++z) { tmd_content *TMDc = TMD_CONTENTS(((tmd*)(SIGNATURE_PAYLOAD(TMD)))); // OH GOD CREDIAR, WTF WAS THAT MESS!!! //printf("%d,",TMDc->index); s32 cfd = ES_OpenTitleContent( titleID, TMDc->index); free(views); if(CheckESRetval(cfd)!=0) { ; //printf("ES_OpenContent(%d) failed\n", cfd); //sleep(10); //exit(0); } else { u64 sz ATTRIBUTE_ALIGN(32) = 0x140; u8 *data = (u8*)memalign(32, sz); if( TMDc->size < sz ) sz = TMDc->size; if( data != NULL ) { if(ES_ReadContent(cfd, data, sz)<0) { free(data); return; } int y; int chan_name_offset=(language_setting*0x54); // Set to WiiMU's language for(y=0;y<(0x54/2);y++) name[y]=data[(0x9C+chan_name_offset)+(y*2)+1]; } if(CheckESRetval(ES_CloseContent(cfd))!=0) { ; //printf("ES_CloseContent failed\n"); //sleep(10); //exit(0); } free(data); } } int wiistring_size; reenter: wiistring_size=type_string_wiimote(name, 0x54/2); if(wiistring_size<=0) { printf("\n\nPlease enter a name!\n"); sleep(3); goto reenter; } name[wiistring_size+1]=0; /* Get Content */ char nameDirectory[80]; tmd_content *TMDc = TMD_CONTENTS(((tmd*)(SIGNATURE_PAYLOAD(TMD)))); sprintf(nameDirectory,"/title/%08x/%08x/content/%08x.app",TITLE_UPPER(titleID),TITLE_LOWER(titleID),TMDc->cid); s32 contentFd=ISFS_Open(nameDirectory,ISFS_OPEN_RW); CheckISFSRetval(contentFd); ClearScreen(); printf("\n\nOpened content!\n"); u8 *data=calloc(TMDc->size,1); int isUnaligned = ((int)data)%32 | TMDc->size%32; int alignedLen = (TMDc->size+31)&0xffffffe0; u8* alignedBuf; if(isUnaligned) alignedBuf = memalign(32, alignedLen); else alignedBuf = data; CheckISFSRetval(ISFS_Seek(contentFd,0,0)); CheckISFSRetval(ISFS_Read(contentFd, alignedBuf, alignedLen)); printf("Read content!\n"); int y; int chan_name_offset=(SYSCONF_GetArea()*0x54); // Edits the one for the Wii's system Menu char* nameOut=calloc(96,1); for(y=0;y<(0x54/2);y++) nameOut[(y*2)+1]=name[y]; printf("Wrote new name! %s\n", name); CheckISFSRetval(ISFS_Seek(contentFd,(0x9C+chan_name_offset),0)); printf("Seeked to location!\n"); if(nameOut==NULL) { printf("FAILED! (Name Out is NULL!)\n"); sleep(5); Finish(1); } if(((u32)nameOut%32)!=0) { isUnaligned = ((int)nameOut)%32 | 0x54%32; alignedLen = (0x54+31)&0xffffffe0; if(isUnaligned){ alignedBuf = memalign(32, alignedLen); memcpy(alignedBuf, nameOut, 0x54); } else alignedBuf = (u8*)nameOut; } CheckISFSRetval(ISFS_Write(contentFd, alignedBuf, 0x54)); printf("Wrote content name!\nReading new Header Chunk!\n"); CheckISFSRetval(ISFS_Seek(contentFd,0,0)); CheckISFSRetval(ISFS_Read(contentFd, alignedBuf, alignedLen)); printf("Read content!\n"); u8* header_chunk=calloc(0x640, 1); int i; for(i=0;i<0x630;i++) header_chunk[i]=alignedBuf[i]; for(i=0x630;i<0x640;i++) header_chunk[i]=0; u8* hash=calloc(0x10,1); md5(header_chunk, 0x640, hash); CheckISFSRetval(ISFS_Seek(contentFd,0x630,0)); printf("Seeked to location!\n"); if(hash==NULL) { printf("FAILED! (Hash is NULL!)\n"); sleep(5); Finish(1); } if(((u32)hash%32)!=0) { isUnaligned = ((int)hash)%32 | 0x10%32; alignedLen = (0x10+31)&0xffffffe0; if(isUnaligned){ alignedBuf = memalign(32, alignedLen); memcpy(alignedBuf, hash, 0x10); } else alignedBuf = hash;