/**************************************************************************** * Copyright (C) 2012 FIX94 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ #include #include #include #include #include #include "external_booter.hpp" #include "Config.h" #include "channel/nand.hpp" #include "devicemounter/DeviceHandler.hpp" #include "fileOps/fileOps.h" #include "gecko/wifi_gecko.hpp" #include "gui/text.hpp" #include "loader/fst.h" #include "loader/mload.h" #include "loader/wdvd.h" #include "loader/sys.h" #include "homebrew/homebrew.h" #include "memory/mem2.hpp" #include "network/FTP_Dir.hpp" #include "network/http.h" #include "plugin/crc32.h" /* External WiiFlow Game Booter */ static the_CFG *BooterConfig = (the_CFG*)0x93100000; #define EXT_ADDR ((u8*)0x80B00000) #define EXT_ENTRY ((entry)EXT_ADDR) #define BOOTER_ADDR ((u8*)0x93100000) /* temporary location */ extern "C" { u8 configbytes[2]; u32 hooktype; }; extern u8 *code_buf; extern u32 code_size; extern void *codelist; extern u8 *codelistend; extern u32 gameconfsize; extern u32 *gameconf; size_t booter_size = 0; the_CFG normalCFG; void WiiFlow_ExternalBooter(u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio, u32 returnTo, u8 BootType, bool use_led) { normalCFG.vidMode = vidMode; normalCFG.vipatch = vipatch; normalCFG.countryString = countryString; normalCFG.patchVidMode = patchVidMode; normalCFG.aspectRatio = aspectRatio; normalCFG.returnTo = returnTo; normalCFG.configbytes[0] = configbytes[0]; normalCFG.configbytes[1] = configbytes[1]; normalCFG.IOS = CurrentIOS; normalCFG.codelist = codelist; normalCFG.codelistend = codelistend; normalCFG.cheats = code_buf; normalCFG.cheatSize = code_size; normalCFG.hooktype = hooktype; normalCFG.debugger = debuggerselect; normalCFG.gameconf = gameconf; normalCFG.gameconfsize = gameconfsize; normalCFG.BootType = BootType; normalCFG.use_led = use_led; normalCFG.wip_list = get_wip_list(); normalCFG.wip_count = get_wip_count(); /* Unmount devices etc */ ShutdownBeforeExit(); /* Copy in booter */ memcpy(EXT_ADDR, BOOTER_ADDR, booter_size); DCFlushRange(EXT_ADDR, booter_size); /* Copy CFG into new memory region */ memcpy(BooterConfig, &normalCFG, sizeof(the_CFG)); DCFlushRange(BooterConfig, sizeof(the_CFG)); /* Wii Games will need it */ net_wc24cleanup(); /* Set proper time */ settime(secs_to_ticks(time(NULL) - 946684800)); /* Boot it */ JumpToEntry(EXT_ENTRY); } bool ExternalBooter_LoadBooter(const char *booter_path) { fsop_GetFileSizeBytes(booter_path, &booter_size); if(booter_size > 0) { fsop_ReadFileLoc(booter_path, booter_size, BOOTER_ADDR); return true; } return false; } extern FragList *frag_list; extern s32 wbfsDev; extern u32 wbfs_part_idx; void ExternalBooter_WiiGameSetup(bool wbfs, bool dvd, const char *ID) { memset(&normalCFG, 0, sizeof(the_CFG)); normalCFG.GameBootType = dvd ? TYPE_WII_DISC : (wbfs ? TYPE_WII_WBFS : TYPE_WII_WBFS_EXT); strncpy(normalCFG.gameID, ID, 6); normalCFG.fragments = frag_list; normalCFG.wbfsDevice = wbfsDev; normalCFG.wbfsPart = wbfs_part_idx; } void ExternalBooter_ChannelSetup(u64 title, bool dol) { memset(&normalCFG, 0, sizeof(the_CFG)); memcpy(&normalCFG.title, &title, sizeof(u64)); normalCFG.use_dol = dol; } void ShutdownBeforeExit(void) { DeviceHandle.UnMountAll(); NandHandle.DeInit_ISFS(); WDVD_Close(); Close_Inputs(); /* Deinit network */ if(networkInit == true) { while(net_get_status() == -EBUSY) usleep(50); WiFiDebugger.Close(); ftp_endTread(); net_deinit(); networkInit = false; } }