diff --git a/data/wii_game_booter.dol b/data/wii_game_booter.dol index 4818a0aa..6f471727 100644 Binary files a/data/wii_game_booter.dol and b/data/wii_game_booter.dol differ diff --git a/resources/wiiflow_game_booter/source/ChannelHandler.cpp b/resources/wiiflow_game_booter/source/ChannelHandler.cpp new file mode 100644 index 00000000..662afd77 --- /dev/null +++ b/resources/wiiflow_game_booter/source/ChannelHandler.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** + * 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 + +#include "Config.hpp" +#include "ChannelHandler.hpp" + +#include "patchcode.h" +#include "cios.h" +#include "fs.h" +#include "fst.h" +#include "lz77.h" +#include "utils.h" +#include "videopatch.h" + +using namespace std; + +void *dolchunkoffset[18]; +u32 dolchunksize[18]; +u32 dolchunkcount; +u32 bootcontent; + +char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); + +static u8 *GetDol(u32 bootcontent) +{ + memset(filepath, 0, ISFS_MAXPATH); + sprintf(filepath, "/title/%08x/%08x/content/%08x.app", TITLE_UPPER(conf->title), TITLE_LOWER(conf->title), bootcontent); + + u32 contentSize = 0; + + u8 *data = ISFS_GetFile((u8 *) &filepath, &contentSize, -1); + if(data != NULL && contentSize != 0) + { + if(isLZ77compressed(data)) + { + u8 *decompressed; + u32 size = 0; + if(decompressLZ77content(data, contentSize, &decompressed, &size) < 0) + { + free(data); + return NULL; + } + free(data); + data = decompressed; + } + return data; + } + return NULL; +} + +static bool GetAppNameFromTmd(bool dol, u32 *bootcontent) +{ + bool ret = false; + + memset(filepath, 0, ISFS_MAXPATH); + sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(conf->title), TITLE_LOWER(conf->title)); + + u32 size; + u8 *data = ISFS_GetFile((u8 *) &filepath, &size, -1); + if(data == NULL || size < 0x208) + return ret; + + _tmd *tmd_file = (_tmd *)SIGNATURE_PAYLOAD((u32 *)data); + for(u16 i = 0; i < tmd_file->num_contents; ++i) + { + if(tmd_file->contents[i].index == (dol ? tmd_file->boot_index : 0)) + { + *bootcontent = tmd_file->contents[i].cid; + ret = true; + break; + } + } + + free(data); + + return ret; +} + +static u32 MoveDol(u8 *buffer) +{ + dolchunkcount = 0; + dolheader *dolfile = (dolheader *)buffer; + + if(dolfile->bss_start) + { + if(!(dolfile->bss_start & 0x80000000)) + dolfile->bss_start |= 0x80000000; + + memset((void *)dolfile->bss_start, 0, dolfile->bss_size); + DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size); + ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size); + } + + for(u8 i = 0; i < 18; i++) + { + if(!dolfile->section_size[i]) + continue; + if(dolfile->section_pos[i] < sizeof(dolheader)) + continue; + if(!(dolfile->section_start[i] & 0x80000000)) + dolfile->section_start[i] |= 0x80000000; + + dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i]; + dolchunksize[dolchunkcount] = dolfile->section_size[i]; + + memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]); + DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); + ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); + + dolchunkcount++; + } + return dolfile->entry_point; +} + +u32 LoadChannel() +{ + u32 entry = 0; + + /* Re-Init ISFS */ + ISFS_Initialize(); + + GetAppNameFromTmd(true, &bootcontent); + u8 *data = GetDol(bootcontent); + entry = MoveDol(data); + free(data); + + /* De-Init ISFS */ + ISFS_Deinitialize(); + + return entry; +} + +void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio) +{ + bool hook = false; + for(u32 i = 0; i < dolchunkcount; i++) + { + patchVideoModes(dolchunkoffset[i], dolchunksize[i], vidMode, vmode, patchVidModes); + if(vipatch) vidolpatcher(dolchunkoffset[i], dolchunksize[i]); + if(configbytes[0] != 0xCD) langpatcher(dolchunkoffset[i], dolchunksize[i]); + if(countryString) PatchCountryStrings(dolchunkoffset[i], dolchunksize[i]); + if(aspectRatio != -1) PatchAspectRatio(dolchunkoffset[i], dolchunksize[i], aspectRatio); + if(hooktype != 0 && dogamehooks(dolchunkoffset[i], dolchunksize[i], true)) + hook = true; + } + if(hook) + ocarina_do_code(conf->title); +} diff --git a/resources/wiiflow_game_booter/source/ChannelHandler.hpp b/resources/wiiflow_game_booter/source/ChannelHandler.hpp new file mode 100644 index 00000000..bcd5f13a --- /dev/null +++ b/resources/wiiflow_game_booter/source/ChannelHandler.hpp @@ -0,0 +1,19 @@ + +#ifndef __CHANHANDLE_HPP_ +#define __CHANHANDLE_HPP_ + +typedef struct _dolheader +{ + u32 section_pos[18]; + u32 section_start[18]; + u32 section_size[18]; + u32 bss_start; + u32 bss_size; + u32 entry_point; + u32 padding[7]; +} __attribute__((packed)) dolheader; + +void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio); +u32 LoadChannel(); + +#endif /* __CHANHANDLE_HPP_ */ diff --git a/resources/wiiflow_game_booter/source/Config.hpp b/resources/wiiflow_game_booter/source/Config.hpp new file mode 100644 index 00000000..158be93b --- /dev/null +++ b/resources/wiiflow_game_booter/source/Config.hpp @@ -0,0 +1,31 @@ + +#ifndef _CFG_HPP_ +#define _CFG_HPP_ + +#include "cios.h" + +typedef struct _the_CFG { + u8 vidMode; + bool vipatch; + bool countryString; + u8 patchVidMode; + int aspectRatio; + u32 returnTo; + u8 configbytes[2]; + IOS_Info IOS; + void *codelist; + u8 *codelistend; + u8 *cheats; + u32 cheatSize; + u32 hooktype; + u8 debugger; + u32 *gameconf; + u32 gameconfsize; + u8 BootType; + /* needed for channels */ + u64 title; +} the_CFG; + +static the_CFG *conf = (the_CFG*)0x90000000; + +#endif /* _CFG_HPP_ */ diff --git a/resources/wiiflow_game_booter/source/main.cpp b/resources/wiiflow_game_booter/source/main.cpp index cdd5ed82..ab635a35 100644 --- a/resources/wiiflow_game_booter/source/main.cpp +++ b/resources/wiiflow_game_booter/source/main.cpp @@ -21,44 +21,18 @@ #include #include +#include "Config.hpp" +#include "ChannelHandler.hpp" + #include "apploader.h" -#include "wdvd.h" #include "patchcode.h" -#include "cios.h" #include "disc.h" -#include "fs.h" #include "fst.h" -#include "lz77.h" -#include "utils.h" -#include "videopatch.h" +#include "wdvd.h" using namespace std; IOS_Info CurrentIOS; -typedef struct _the_CFG { - u8 vidMode; - bool vipatch; - bool countryString; - u8 patchVidMode; - int aspectRatio; - u32 returnTo; - u8 configbytes[2]; - IOS_Info IOS; - void *codelist; - u8 *codelistend; - u8 *cheats; - u32 cheatSize; - u32 hooktype; - u8 debugger; - u32 *gameconf; - u32 gameconfsize; - u8 BootType; - /* needed for channels */ - u64 title; -} the_CFG; - -static the_CFG *conf = (the_CFG*)0x90000000; - /* Boot Variables */ u32 vmode_reg = 0; entry_point p_entry; @@ -68,146 +42,6 @@ u32 AppEntrypoint; extern "C" { extern void __exception_closeall(); } -typedef struct _dolheader -{ - u32 section_pos[18]; - u32 section_start[18]; - u32 section_size[18]; - u32 bss_start; - u32 bss_size; - u32 entry_point; - u32 padding[7]; -} __attribute__((packed)) dolheader; - -void *dolchunkoffset[18]; -u32 dolchunksize[18]; -u32 dolchunkcount; - -void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio) -{ - for(u32 i = 0; i < dolchunkcount; i++) - { - patchVideoModes(dolchunkoffset[i], dolchunksize[i], vidMode, vmode, patchVidModes); - if(vipatch) vidolpatcher(dolchunkoffset[i], dolchunksize[i]); - if(configbytes[0] != 0xCD) langpatcher(dolchunkoffset[i], dolchunksize[i]); - if(countryString) PatchCountryStrings(dolchunkoffset[i], dolchunksize[i]); - if(aspectRatio != -1) PatchAspectRatio(dolchunkoffset[i], dolchunksize[i], aspectRatio); - - if(hooktype != 0) - dogamehooks(dolchunkoffset[i], dolchunksize[i], true); - } -} - -static u8 *GetDol(u32 bootcontent) -{ - char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); - sprintf(filepath, "/title/%08x/%08x/content/%08x.app", TITLE_UPPER(conf->title), TITLE_LOWER(conf->title), bootcontent); - - u32 contentSize = 0; - - u8 *data = ISFS_GetFile((u8 *) &filepath, &contentSize, -1); - if(data != NULL && contentSize != 0) - { - if(isLZ77compressed(data)) - { - u8 *decompressed; - u32 size = 0; - if(decompressLZ77content(data, contentSize, &decompressed, &size) < 0) - { - free(data); - return NULL; - } - free(data); - data = decompressed; - } - return data; - } - return NULL; -} - -static bool GetAppNameFromTmd(char *app, bool dol, u32 *bootcontent) -{ - bool ret = false; - - char tmd[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); - sprintf(tmd, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(conf->title), TITLE_LOWER(conf->title)); - - u32 size; - u8 *data = ISFS_GetFile((u8 *) &tmd, &size, -1); - if (data == NULL || size < 0x208) - return ret; - - _tmd *tmd_file = (_tmd *)SIGNATURE_PAYLOAD((u32 *)data); - u16 i; - for(i = 0; i < tmd_file->num_contents; ++i) - { - if(tmd_file->contents[i].index == (dol ? tmd_file->boot_index : 0)) - { - *bootcontent = tmd_file->contents[i].cid; - sprintf(app, "/title/%08x/%08x/content/%08x.app", TITLE_UPPER(conf->title), TITLE_LOWER(conf->title), *bootcontent); - ret = true; - break; - } - } - - free(data); - - return ret; -} - -static u32 MoveDol(u8 *buffer) -{ - dolchunkcount = 0; - dolheader *dolfile = (dolheader *)buffer; - - if(dolfile->bss_start) - { - if(!(dolfile->bss_start & 0x80000000)) - dolfile->bss_start |= 0x80000000; - - memset((void *)dolfile->bss_start, 0, dolfile->bss_size); - DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size); - ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size); - } - - int i; - for(i = 0; i < 18; i++) - { - if(!dolfile->section_size[i]) - continue; - if(dolfile->section_pos[i] < sizeof(dolheader)) - continue; - if(!(dolfile->section_start[i] & 0x80000000)) - dolfile->section_start[i] |= 0x80000000; - - dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i]; - dolchunksize[dolchunkcount] = dolfile->section_size[i]; - - //gprintf("Moving section %u from offset %08x to %08x-%08x...\n", i, dolfile->section_pos[i], dolchunkoffset[dolchunkcount], (u32)dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]); - memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]); - DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); - ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); - - dolchunkcount++; - } - return dolfile->entry_point; -} - -u32 LoadChannel() -{ - char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); - u32 bootcontent; - u32 entry = 0; - - if(!GetAppNameFromTmd(app, true, &bootcontent)) - return entry; - - u8 *data = GetDol(bootcontent); - entry = MoveDol(data); - free(data); - return entry; -} - int main() { VIDEO_Init(); @@ -227,6 +61,7 @@ int main() if(conf->BootType == TYPE_WII_GAME) { + /* Re-Init DI */ WDVD_Init(); /* Find Partition */ @@ -240,16 +75,15 @@ int main() Apploader_Run(&p_entry, conf->vidMode, vmode, conf->vipatch, conf->countryString, conf->patchVidMode, conf->aspectRatio, conf->returnTo); AppEntrypoint = (u32)p_entry; + + /* De-Init DI */ + WDVD_Close(); } else if(conf->BootType == TYPE_CHANNEL) { - ISFS_Initialize(); AppEntrypoint = LoadChannel(); PatchChannel(conf->vidMode, vmode, conf->vipatch, conf->countryString, conf->patchVidMode, conf->aspectRatio); - if(hooktype != 0) - ocarina_do_code(conf->title); - ISFS_Deinitialize(); } /* Set time */ diff --git a/resources/wiiflow_game_booter/source/patchcode.c b/resources/wiiflow_game_booter/source/patchcode.c index c6951a3c..2ab92e3d 100644 --- a/resources/wiiflow_game_booter/source/patchcode.c +++ b/resources/wiiflow_game_booter/source/patchcode.c @@ -27,6 +27,9 @@ #include "apploader.h" #include "patchcode.h" +u32 hooktype; +u8 configbytes[2]; + extern void patchhook(u32 address, u32 len); extern void patchhook2(u32 address, u32 len); extern void patchhook3(u32 address, u32 len); @@ -381,33 +384,6 @@ bool PatchReturnTo( void *Address, int Size, u32 id ) return returnToPatched; } -s32 IOSReloadBlock(u8 reqios, bool enable) -{ - s32 ESHandle = IOS_Open("/dev/es", 0); - - if (ESHandle < 0) - return ESHandle; - - static ioctlv vector[2] ATTRIBUTE_ALIGN(32); - static u32 mode ATTRIBUTE_ALIGN(32); - static u32 ios ATTRIBUTE_ALIGN(32); - - mode = enable ? 2 : 0; - vector[0].data = &mode; - vector[0].len = sizeof(u32); - - if (enable) { - ios = reqios; - vector[1].data = &ios; - vector[1].len = sizeof(u32); - } - - s32 r = IOS_Ioctlv(ESHandle, 0xA0, 2, 0, vector); - IOS_Close(ESHandle); - - return r; -} - void PatchAspectRatio(void *addr, u32 len, u8 aspect) { if(aspect > 1) diff --git a/resources/wiiflow_game_booter/source/patchcode.h b/resources/wiiflow_game_booter/source/patchcode.h index 30039846..41c13dc1 100644 --- a/resources/wiiflow_game_booter/source/patchcode.h +++ b/resources/wiiflow_game_booter/source/patchcode.h @@ -26,8 +26,8 @@ extern "C" { #endif // Globals -u32 hooktype; -u8 configbytes[2]; +extern u32 hooktype; +extern u8 configbytes[2]; // Function prototypes bool dogamehooks(void *addr, u32 len, bool channel); diff --git a/resources/wiiflow_game_booter/source/types.h b/resources/wiiflow_game_booter/source/types.h index 8f5c8bab..f6b7189c 100644 --- a/resources/wiiflow_game_booter/source/types.h +++ b/resources/wiiflow_game_booter/source/types.h @@ -25,6 +25,7 @@ enum IOS_TYPE_WANIN, IOS_TYPE_HERMES, IOS_TYPE_KWIIRK, + IOS_TYPE_NEEK2O, IOS_TYPE_NORMAL_IOS, IOS_TYPE_STUB, };