s32 NandTitle::Get() { s32 ret; u64 *list = NULL; u32 numTitles = 0; titleIds.clear(); ret = ES_GetNumTitles(&numTitles); if (ret < 0) return WII_EINTERNAL; list = (u64*) memalign(32, numTitles * sizeof(u64)); if (!list) { return -1; } ret = ES_GetTitles(list, numTitles); if (ret < 0) { free(list); return WII_EINTERNAL; } for (u32 i = 0; i < numTitles; i++) { titleIds.push_back(list[i]); } free(list); return 1; }
s32 WII_OpenURL(const char *url) { u32 tmdsize; u64 tid = 0; u64 *list; u32 titlecount; s32 ret; int i; if(!__initialized) return WII_ENOTINIT; ret = ES_GetNumTitles(&titlecount); if(ret < 0) return WII_EINTERNAL; list = memalign(32, titlecount * sizeof(u64) + 32); ret = ES_GetTitles(list, titlecount); if(ret < 0) { free(list); return WII_EINTERNAL; } for(i=0; i<titlecount; i++) { if((list[i] & ~0xFF) == 0x1000148414400LL) { tid = list[i]; break; } } free(list); if(!tid) return WII_EINSTALL; if(ES_GetStoredTMDSize(tid, &tmdsize) < 0) return WII_EINSTALL; return WII_LaunchTitleWithArgs(tid, 0, url, NULL); }
//boot HBC in either HAXX or JODI locations //this function expects WII_Initialize() be called before it is called s32 WII_BootHBC() { u32 tmdsize; u64 tid = 0; u64 *list; u32 titlecount; s32 ret; u32 i; ret = ES_GetNumTitles(&titlecount); if(ret < 0) return WII_EINTERNAL; list = CFMemAlign(32, titlecount * sizeof(u64) + 32); ret = ES_GetTitles(list, titlecount); if(ret < 0) { CFFree(list); return WII_EINTERNAL; } for(i=0; i<titlecount; i++) { if (list[i]==TITLE_ID(0x00010001,0x4A4F4449) || list[i]==TITLE_ID(0x00010001,0x48415858) || list[i]==TITLE_ID(0x00010001,0xaf1bf516)) { tid = list[i]; break; } } CFFree(list); if(!tid) return WII_EINSTALL; if(ES_GetStoredTMDSize(tid, &tmdsize) < 0) return WII_EINSTALL; return WII_LaunchTitle(tid); }
s32 Title_GetList(u64 **outbuf, u32 *outlen) { u64 *titles = NULL; u32 len, nb_titles; s32 ret; /* Get number of titles */ ret = ES_GetNumTitles(&nb_titles); if (ret < 0) return ret; /* Calculate buffer lenght */ len = round_up(sizeof(u64) * nb_titles, 32); /* Allocate memory */ titles = memalign(32, len); if (!titles) return -1; /* Get titles */ ret = ES_GetTitles(titles, nb_titles); if (ret < 0) goto err; /* Set values */ *outbuf = titles; *outlen = nb_titles; return 0; err: /* Free memory */ if (titles) free(titles); return ret; }
s32 *get_ioslist(u32 *cnt) { u64 *buf = 0; s32 res; u32 i, k = 0, tcnt = 0, icnt = 0; s32 *ioses = NULL; bool skip_title; /* Get stored IOS versions */ res = ES_GetNumTitles(&tcnt); if (res < 0) { printf("\t- ES_GetNumTitles: Error! (result = %ld).\n", res); return 0; } buf = memalign(32, sizeof(u64) * tcnt); if (!buf) { printf("\t- Error allocating titlelist memory buffer!\n"); return 0; } res = ES_GetTitles(buf, tcnt); if (res < 0) { printf("\t- ES_GetTitles: Error! (result = %ld).\n", res); free(buf); return 0; } for (i = 0; i < tcnt; i++) { /* Skip BC, MIOS, System Menu, BootMii IOS, BC-NAND, BC-WFS and stub IOSses */ if ((TITLE_UPPER(buf[i - k]) == 1) && (TITLE_LOWER(buf[i - k]) > 2) && (TITLE_LOWER(buf[i - k]) < 0xFE)) { u32 tmdSize = 0; tmd *iosTMD = NULL; signed_blob *iosTMDBuffer = NULL; /* Get stored TMD size */ res = ES_GetStoredTMDSize(buf[i - k], &tmdSize); if (res < 0) { printf("\t- ES_GetStoredTMDSize: Error! (result = %ld / IOS%lu).\n", res, ((u32)buf[i - k])); break; } iosTMDBuffer = (signed_blob*)memalign(32, (tmdSize+31)&(~31)); if (!iosTMDBuffer) { res = -1; printf("\t- Error allocating IOS%lu TMD buffer (size = %lu bytes).\n", ((u32)buf[i - k]), tmdSize); break; } memset(iosTMDBuffer, 0, tmdSize); /* Get stored TMD */ res = ES_GetStoredTMD(buf[i - k], iosTMDBuffer, tmdSize); if (res < 0) { printf("\t- ES_GetStoredTMD: Error! (result = %ld / IOS%lu).\n", res, ((u32)buf[i - k])); free(iosTMDBuffer); break; } iosTMD = (tmd*)SIGNATURE_PAYLOAD(iosTMDBuffer); /* Calculate title size */ u16 j; u32 titleSize = 0; for (j = 0; j < iosTMD->num_contents; j++) { tmd_content *content = &iosTMD->contents[j]; /* Add content size */ titleSize += content->size; } /* Check if this IOS is a stub */ skip_title = (titleSize < 0x100000); free(iosTMDBuffer); } else { skip_title = true; } if (!skip_title) { icnt++; } else { /* Move around memory blocks */ if ((tcnt - 1) > i) { memmove(&(buf[i - k]), &(buf[i - k + 1]), (sizeof(u64) * (tcnt - i - 1))); k++; } } } if (res < 0) { free(buf); return 0; } if (realloc(buf, sizeof(u64) * icnt) == NULL) { printf("\t- Error reallocating titlelist memory block!\n"); free(buf); return 0; } ioses = (s32 *)malloc(sizeof(s32) * icnt); if (!ioses) { printf("\t- Error allocating IOS memory buffer!\n"); free(buf); return 0; } for (i = 0; i < icnt; i++) ioses[i] = (s32)buf[i]; free(buf); qsort(ioses, icnt, sizeof(s32), __s32Cmp); *cnt = icnt; return ioses; }
s32 IOS_GetPreferredVersion() { int ver = IOS_EBADVERSION; s32 res; u32 count; u64 *titles; u32 tmd_size; u32 i; u32 a,b; res = __IOS_InitHeap(); if(res<0) return res; res = ES_GetNumTitles(&count); if(res < 0) { #ifdef DEBUG_IOS printf(" GetNumTitles failed: %d\n",res); #endif return res; } #ifdef DEBUG_IOS printf(" %d titles on card:\n",count); #endif titles = iosAlloc(__ios_hid, sizeof(u64)*count); if(!titles) { printf(" iosAlloc titles failed\n"); return -1; } res = ES_GetTitles(titles, count); if(res < 0) { #ifdef DEBUG_IOS printf(" GetTitles failed: %d\n",res); #endif iosFree(__ios_hid, titles); return res; } u32 *tmdbuffer = memalign(32, MAX_SIGNED_TMD_SIZE); if(!tmdbuffer) { iosFree(__ios_hid, titles); return -1; } for(i=0; i<count; i++) { a = titles[i]>>32; b = titles[i]&0xFFFFFFFF; if(a != 1) continue; if(b < IOS_MIN_VERSION) continue; if(b > IOS_MAX_VERSION) continue; if (ES_GetStoredTMDSize(titles[i], &tmd_size) < 0) continue; if (tmd_size < 0 || tmd_size > 4096) continue; if(ES_GetStoredTMD(titles[i], (signed_blob *)tmdbuffer, tmd_size) < 0) continue; if (!tmdbuffer[1] && !tmdbuffer[2]) continue; if((((s32)b) > ((s32)ver) && ver != 58) || b == 58) ver = b; } #ifdef DEBUG_IOS printf(" Preferred verson: %d\n",ver); #endif iosFree(__ios_hid, titles); free(tmdbuffer); return ver; }