//--------------------------------------------------------------------------------- s32 install(const signed_blob *s_tmd, const signed_blob *s_certs, u32 certs_len){ //--------------------------------------------------------------------------------- u32 ret, i; tmd *p_tmd = SIGNATURE_PAYLOAD(s_tmd); ret = ES_AddTitleStart(s_tmd, SIGNED_TMD_SIZE(s_tmd), s_certs, certs_len, NULL, 0); if(ret < 0) { ES_AddTitleCancel(); return ret; } for(i=0; i<p_tmd->num_contents; i++) { currentfile = i+1; filecount = p_tmd->num_contents; installios_thread_state = 1; ret = install_nus_object((tmd *)SIGNATURE_PAYLOAD(s_tmd), i); if (ret) return ret; } ret = ES_AddTitleFinish(); if(ret < 0) { ES_AddTitleCancel(); return ret; } return 0; }
s32 Wad_Install(FILE *fp) { //////start the gui shit GuiWindow promptWindow(472,320); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); // GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); char imgPath[100]; snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path); GuiImageData btnOutline(imgPath, button_dialogue_box_png); snprintf(imgPath, sizeof(imgPath), "%sdialogue_box.png", CFG.theme_path); GuiImageData dialogBox(imgPath, dialogue_box_png); GuiTrigger trigA; trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); GuiImage dialogBoxImg(&dialogBox); if (Settings.wsprompt == yes){ dialogBoxImg.SetWidescreen(CFG.widescreen);} GuiText btn1Txt(tr("OK"), 22, THEME.prompttext); GuiImage btn1Img(&btnOutline); if (Settings.wsprompt == yes){ btn1Txt.SetWidescreen(CFG.widescreen); btn1Img.SetWidescreen(CFG.widescreen);} GuiButton btn1(&btn1Img,&btn1Img, 2, 4, 0, -35, &trigA, &btnSoundOver, btnClick2,1); btn1.SetLabel(&btn1Txt); btn1.SetState(STATE_SELECTED); snprintf(imgPath, sizeof(imgPath), "%sprogressbar_outline.png", CFG.theme_path); GuiImageData progressbarOutline(imgPath, progressbar_outline_png); GuiImage progressbarOutlineImg(&progressbarOutline); if (Settings.wsprompt == yes){ progressbarOutlineImg.SetWidescreen(CFG.widescreen);} progressbarOutlineImg.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); progressbarOutlineImg.SetPosition(25, 50); snprintf(imgPath, sizeof(imgPath), "%sprogressbar_empty.png", CFG.theme_path); GuiImageData progressbarEmpty(imgPath, progressbar_empty_png); GuiImage progressbarEmptyImg(&progressbarEmpty); progressbarEmptyImg.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); progressbarEmptyImg.SetPosition(25, 50); progressbarEmptyImg.SetTile(100); snprintf(imgPath, sizeof(imgPath), "%sprogressbar.png", CFG.theme_path); GuiImageData progressbar(imgPath, progressbar_png); GuiImage progressbarImg(&progressbar); progressbarImg.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); progressbarImg.SetPosition(25, 50); char title[50]; sprintf(title, "%s", tr("Installing wad")); GuiText titleTxt(title, 26, THEME.prompttext); titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); titleTxt.SetPosition(0,40); char msg[50]; sprintf(msg, " "); // sprintf(msg, "%s", tr("Initializing Network")); GuiText msg1Txt(NULL, 20, THEME.prompttext); msg1Txt.SetAlignment(ALIGN_LEFT, ALIGN_TOP); msg1Txt.SetPosition(50,75); // char msg2[50] = " "; GuiText msg2Txt(NULL, 20, THEME.prompttext); msg2Txt.SetAlignment(ALIGN_LEFT, ALIGN_TOP); msg2Txt.SetPosition(50, 98); GuiText msg3Txt(NULL, 20, THEME.prompttext); msg3Txt.SetAlignment(ALIGN_LEFT, ALIGN_TOP); msg3Txt.SetPosition(50, 121); GuiText msg4Txt(NULL, 20, THEME.prompttext); msg4Txt.SetAlignment(ALIGN_LEFT, ALIGN_TOP); msg4Txt.SetPosition(50, 144); GuiText msg5Txt(NULL, 20, THEME.prompttext); msg5Txt.SetAlignment(ALIGN_LEFT, ALIGN_TOP); msg5Txt.SetPosition(50, 167); GuiText prTxt(NULL, 26, THEME.prompttext); prTxt.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); prTxt.SetPosition(0, 50); if ((Settings.wsprompt == yes) && (CFG.widescreen)){/////////////adjust for widescreen progressbarOutlineImg.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); progressbarOutlineImg.SetPosition(0, 50); progressbarEmptyImg.SetPosition(80,50); progressbarEmptyImg.SetTile(78); progressbarImg.SetPosition(80, 50); msg1Txt.SetPosition(90,75); msg2Txt.SetPosition(90, 98); msg3Txt.SetPosition(90, 121); msg4Txt.SetPosition(90, 144); msg5Txt.SetPosition(90, 167); } promptWindow.Append(&dialogBoxImg); promptWindow.Append(&titleTxt); promptWindow.Append(&msg5Txt); promptWindow.Append(&msg4Txt); promptWindow.Append(&msg3Txt); promptWindow.Append(&msg1Txt); promptWindow.Append(&msg2Txt); //promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50); HaltGui(); mainWindow->SetState(STATE_DISABLED); mainWindow->Append(&promptWindow); mainWindow->ChangeFocus(&promptWindow); //sleep(1); ///start the wad shit bool fail = false; wadHeader *header = NULL; void *pvoid; signed_blob *p_certs = NULL, *p_crl = NULL, *p_tik = NULL, *p_tmd = NULL; tmd *tmd_data = NULL; u32 cnt, offset = 0; s32 ret = 666; ResumeGui(); msg1Txt.SetText(tr(">> Reading WAD data...")); HaltGui(); #define SetPointer(a, p) a=(typeof(a))p // WAD header //ret = __Wad_ReadAlloc(fp, (void *)header, offset, sizeof(wadHeader)); ret = __Wad_ReadAlloc(fp, &pvoid, offset, sizeof(wadHeader)); if (ret < 0) goto err; SetPointer(header, pvoid); offset += round_up(header->header_len, 64); // WAD certificates //ret = __Wad_ReadAlloc(fp, (void *)&p_certs, offset, header->certs_len); ret = __Wad_ReadAlloc(fp, &pvoid, offset, header->certs_len); if (ret < 0) goto err; SetPointer(p_certs, pvoid); offset += round_up(header->certs_len, 64); // WAD crl if (header->crl_len) { //ret = __Wad_ReadAlloc(fp, (void *)&p_crl, offset, header->crl_len); ret = __Wad_ReadAlloc(fp, &pvoid, offset, header->crl_len); if (ret < 0) goto err; SetPointer(p_crl, pvoid); offset += round_up(header->crl_len, 64); } // WAD ticket //ret = __Wad_ReadAlloc(fp, (void *)&p_tik, offset, header->tik_len); ret = __Wad_ReadAlloc(fp, &pvoid, offset, header->tik_len); if (ret < 0) goto err; SetPointer(p_tik, pvoid); offset += round_up(header->tik_len, 64); // WAD TMD //ret = __Wad_ReadAlloc(fp, (void *)&p_tmd, offset, header->tmd_len); ret = __Wad_ReadAlloc(fp, &pvoid, offset, header->tmd_len); if (ret < 0) goto err; SetPointer(p_tmd, pvoid); offset += round_up(header->tmd_len, 64); ResumeGui(); msg1Txt.SetText(tr("Reading WAD data... Ok!")); msg2Txt.SetText(tr(">> Installing ticket...")); HaltGui(); // Install ticket ret = ES_AddTicket(p_tik, header->tik_len, p_certs, header->certs_len, p_crl, header->crl_len); if (ret < 0) goto err; ResumeGui(); msg2Txt.SetText(tr("Installing ticket... Ok!")); msg3Txt.SetText(tr(">> Installing title...")); //WindowPrompt(">> Installing title...",0,0,0,0,0,200); HaltGui(); // Install title ret = ES_AddTitleStart(p_tmd, header->tmd_len, p_certs, header->certs_len, p_crl, header->crl_len); if (ret < 0) goto err; // Get TMD info tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd); // Install contents //ResumeGui(); //HaltGui(); promptWindow.Append(&progressbarEmptyImg); promptWindow.Append(&progressbarImg); promptWindow.Append(&progressbarOutlineImg); promptWindow.Append(&prTxt); ResumeGui(); msg3Txt.SetText(tr("Installing title... Ok!")); for (cnt = 0; cnt < tmd_data->num_contents; cnt++) { tmd_content *content = &tmd_data->contents[cnt]; u32 idx = 0, len; s32 cfd; ResumeGui(); //printf("\r\t\t>> Installing content #%02d...", content->cid); // Encrypted content size len = round_up(content->size, 64); // Install content cfd = ES_AddContentStart(tmd_data->title_id, content->cid); if (cfd < 0) { ret = cfd; goto err; } snprintf(imgPath, sizeof(imgPath), "%s%d...",tr(">> Installing content #"),content->cid); msg4Txt.SetText(imgPath); // Install content data while (idx < len) { //VIDEO_WaitVSync (); u32 size; // Data length size = (len - idx); if (size > BLOCK_SIZE) size = BLOCK_SIZE; // Read data ret = __Wad_ReadFile(fp, &wadBuffer, offset, size); if (ret < 0) goto err; // Install data ret = ES_AddContentData(cfd, wadBuffer, size); if (ret < 0) goto err; // Increase variables idx += size; offset += size; //snprintf(imgPath, sizeof(imgPath), "%s%d (%d)...",tr(">> Installing content #"),content->cid,idx); //msg4Txt.SetText(imgPath); prTxt.SetTextf("%i%%", 100*(cnt*len+idx)/(tmd_data->num_contents*len)); if ((Settings.wsprompt == yes) && (CFG.widescreen)) { progressbarImg.SetTile(78*(cnt*len+idx)/(tmd_data->num_contents*len)); } else { progressbarImg.SetTile(100*(cnt*len+idx)/(tmd_data->num_contents*len)); } } // Finish content installation ret = ES_AddContentFinish(cfd); if (ret < 0) goto err; } msg4Txt.SetText(tr("Installing content... Ok!")); msg5Txt.SetText(tr(">> Finishing installation...")); // Finish title install ret = ES_AddTitleFinish(); if (ret >= 0) { // printf(" OK!\n"); goto out; } err: //char titties[100]; ResumeGui(); prTxt.SetTextf("%s%d", tr("Error..."),ret); promptWindow.Append(&prTxt); fail = true; //snprintf(titties, sizeof(titties), "%d", ret); //printf(" ERROR! (ret = %d)\n", ret); //WindowPrompt("ERROR!",titties,"Back",0,0); // Cancel install ES_AddTitleCancel(); goto exit; //return ret; out: // Free memory if (header) free(header); if (p_certs) free(p_certs); if (p_crl) free(p_crl); if (p_tik) free(p_tik); if (p_tmd) free(p_tmd); goto exit; exit: if (!fail)msg5Txt.SetText(tr("Finishing installation... Ok!")); promptWindow.Append(&btn1); while(btn1.GetState() != STATE_CLICKED){ } HaltGui(); mainWindow->Remove(&promptWindow); mainWindow->SetState(STATE_DEFAULT); ResumeGui(); return ret; }
bool NandSave::CheckSave() { /* 10 million variables */ u32 u8_bin_size = 0; u8 *u8_bin = NULL; u32 certSize = 0; signed_blob *certBuffer = NULL; u32 tmd_bin_size = 0; const signed_blob *tmd_bin = NULL; u32 tik_bin_size = 0; const signed_blob *tik_bin = NULL; u32 banner_bin_size = 0; const u8 *banner_bin = NULL; u32 entries = 0; /* May our banner already exist */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, BANNER_PATH); fd = ISFS_Open(ISFS_Path, ISFS_OPEN_READ); if(fd >= 0) { ISFS_Close(fd); gprintf("Found WiiFlow Save\n"); goto done; } /* extract our archive */ u8_bin = DecompressCopy(save_bin, save_bin_size, &u8_bin_size); if(u8_bin == NULL || u8_bin_size == 0) goto error; /* grab cert.sys */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/sys/cert.sys"); certBuffer = (signed_blob*)ISFS_GetFile(ISFS_Path, &certSize, -1); if(certBuffer == NULL || certSize == 0) goto error; /* Install tik and tmd */ tik_bin = (const signed_blob*)u8_get_file(u8_bin, "tik.bin", &tik_bin_size); if(tik_bin == NULL || tik_bin_size == 0) goto error; ret = ES_AddTicket(tik_bin, tik_bin_size, certBuffer, certSize, NULL, 0); if(ret < 0) goto error; tmd_bin = (const signed_blob*)u8_get_file(u8_bin, "tmd.bin", &tmd_bin_size); if(tmd_bin == NULL || tmd_bin_size == 0) goto error; ret = ES_AddTitleStart(tmd_bin, tmd_bin_size, certBuffer, certSize, NULL, 0); if(ret < 0) goto error; ret = ES_AddTitleFinish(); if(ret < 0) goto error; /* WARNING dirty, delete tik again */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/ticket/00010000/57465346.tik"); ret = ISFS_Delete(ISFS_Path); if(ret < 0) goto error; /* Delete the unused ticket folder */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/ticket/00010000"); ret = ISFS_ReadDir(ISFS_Path, NULL, &entries); if(ret < 0) goto error; if(entries == 0) { ret = ISFS_Delete(ISFS_Path); if(ret < 0) goto error; } banner_bin = u8_get_file(u8_bin, "banner.bin", &banner_bin_size); if(banner_bin == NULL || banner_bin_size == 0) goto error; memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, BANNER_PATH); /* Write our banner */ ISFS_CreateFile(ISFS_Path, 0, 3, 3, 3); fd = ISFS_Open(ISFS_Path, ISFS_OPEN_WRITE); if(fd < 0) goto error; ret = ISFS_Write(fd, banner_bin, banner_bin_size); ISFS_Close(fd); if(ret < 0) { ISFS_Delete(ISFS_Path); goto error; } free(certBuffer); if(u8_bin != save_bin) free(u8_bin); gprintf("Created WiiFlow Save\n"); done: loaded = true; return loaded; error: gprintf("Error while creating WiiFlow Save\n"); loaded = false; ES_AddTitleCancel(); if(certBuffer != NULL) free(certBuffer); certBuffer = NULL; if(u8_bin != NULL) free(u8_bin); u8_bin = NULL; tik_bin = NULL; tmd_bin = NULL; banner_bin = NULL; return loaded; }
s32 install_IOS(IOS *ios, bool skipticket) { int ret; int cfd; if (!skipticket) { ((u8*)(ios->ticket))[0x1F1] = 0x00; /* -1029 fix */ ret = ES_AddTicket(ios->ticket, ios->ticket_size, ios->certs, ios->certs_size, ios->crl, ios->crl_size); if (ret < 0) { printf("ES_AddTicket returned: %d\n", ret); ES_AddTitleCancel(); return ret; } } printf("."); ret = ES_AddTitleStart(ios->tmd, ios->tmd_size, ios->certs, ios->certs_size, ios->crl, ios->crl_size); if (ret < 0) { printf("\nES_AddTitleStart returned: %d\n", ret); ES_AddTitleCancel(); return ret; } printf("."); tmd *tmd_data = (tmd *)SIGNATURE_PAYLOAD(ios->tmd); int i; for (i = 0; i < ios->content_count; i++) { tmd_content *content = &tmd_data->contents[i]; cfd = ES_AddContentStart(tmd_data->title_id, content->cid); if (cfd < 0) { printf("\nES_AddContentStart for content #%u cid %u returned: %d\n", i, content->cid, cfd); ES_AddTitleCancel(); return cfd; } ret = ES_AddContentData(cfd, ios->encrypted_buffer[i], ios->buffer_size[i]); if (ret < 0) { printf("\nES_AddContentData for content #%u cid %u returned: %d\n", i, content->cid, ret); ES_AddTitleCancel(); return ret; } ret = ES_AddContentFinish(cfd); if (ret < 0) { printf("\nES_AddContentFinish for content #%u cid %u returned: %d\n", i, content->cid, ret); ES_AddTitleCancel(); return ret; } printf("."); } ret = ES_AddTitleFinish(); if (ret < 0) { printf("\nES_AddTitleFinish returned: %d\n", ret); ES_AddTitleCancel(); return ret; } printf(".\n"); return 0; }
s32 Downgrade_IOS(u32 iosversion, u32 highrevision, u32 lowrevision, bool free) { printf("Preparing downgrade of IOS%u from revison: %u to: %u\n", iosversion, highrevision, lowrevision); int ret; IOS *highios; IOS *lowios; printf("Getting IOS%u revision %u...\n", iosversion, highrevision); ret = get_IOS(&highios, iosversion, highrevision); if (ret < 0) { printf("Error reading IOS into memory\n"); return ret; } printf("Getting IOS%u revision %u...\n", iosversion, lowrevision); ret = get_IOS(&lowios, iosversion, lowrevision); if (ret < 0) { printf("Error reading IOS into memory\n"); free_IOS(&highios); return ret; } printf("\n"); printf("Downgrading involves two steps:\n"); printf("Step 1: Set the revison to 0\n"); printf("Step 2: Install IOS with low revision\n"); printf("Preparations complete, step 1...\n"); u32 pressed; u32 pressedGC; waitforbuttonpress(&pressed, &pressedGC); if (pressed != WPAD_BUTTON_A && pressedGC != PAD_BUTTON_A) { printf("Other button pressed\n"); free_IOS(&highios); free_IOS(&lowios); return -1; } printf("Installing ticket...\n"); ret = ES_AddTicket(highios->ticket, highios->ticket_size, highios->certs, highios->certs_size, highios->crl, highios->crl_size); if (ret < 0) { printf("ES_AddTicket returned: %d\n", ret); free_IOS(&highios); free_IOS(&lowios); ES_AddTitleCancel(); return ret; } ret = Downgrade_TMD_Revision(highios->tmd, highios->tmd_size, highios->certs, highios->certs_size); if (ret < 0) { printf("Error: Could not set the revision to 0\n"); free_IOS(&highios); free_IOS(&lowios); return ret; } printf("Revision set to 0, step 1 of downgrade complete.\n"); printf("\n"); printf("step 2 of downgrade...\n"); waitforbuttonpress(&pressed, &pressedGC); if (pressed != WPAD_BUTTON_A && pressedGC != PAD_BUTTON_A) { printf("Other button pressed\n"); free_IOS(&highios); free_IOS(&lowios); return -1; } printf("Installing IOS%u Rev %u...\n", iosversion, lowrevision); ret = install_IOS(lowios, true); if (ret < 0) { printf("Error: Could not install IOS%u Rev %u\n", iosversion, lowrevision); free_IOS(&highios); free_IOS(&lowios); return ret; } printf("IOS%u downgrade to revision: %u complete.\n", iosversion, lowrevision); if (free) { free_IOS(&highios); free_IOS(&lowios); } return 0; }
s32 Downgrade_TMD_Revision(void *ptmd, u32 tmd_size, void *certs, u32 certs_size) { // The revison of the tmd used as paramter here has to be >= the revision of the installed tmd s32 ret; printf("Setting the revision to 0...\n"); ret = ES_AddTitleStart(ptmd, tmd_size, certs, certs_size, NULL, 0); if (ret < 0) { if (ret == -1035) { printf("Error: ES_AddTitleStart returned %d, maybe you need an updated Downgrader\n", ret); } else { printf("Error: ES_AddTitleStart returned %d\n", ret); } ES_AddTitleCancel(); return ret; } s32 file; char *tmd_path = "/tmp/title.tmd"; ret = ISFS_Delete(tmd_path); if (ret < 0) { printf("Error: ISFS_Delete returned %d\n", ret); ES_AddTitleCancel(); ISFS_Deinitialize(); return ret; } ret = ISFS_CreateFile(tmd_path, 0, 3, 3, 3); if (ret < 0) { printf("Error: ISFS_CreateFile returned %d\n", ret); ES_AddTitleCancel(); ISFS_Deinitialize(); return ret; } file = ISFS_Open(tmd_path, ISFS_OPEN_RW); if (file < 0) { printf("Error: ISFS_Open returned %d\n", file); ES_AddTitleCancel(); ISFS_Deinitialize(); return file; } u8 *tmd = (u8 *)ptmd; tmd[0x1dc] = 0; tmd[0x1dd] = 0; ret = ISFS_Write(file, (u8 *)ptmd, tmd_size); if (ret < 0) { printf("Error: ISFS_Write returned %d\n", ret); ISFS_Close(file); ES_AddTitleCancel(); ISFS_Deinitialize(); return ret; } ISFS_Close(file); ISFS_Deinitialize(); ret = ES_AddTitleFinish(); if (ret < 0) { printf("Error: ES_AddTitleFinish returned %d\n", ret); return ret; } return 1; }