From 0c32d1b0c12541b396eb27e5d7159a7baf796be1 Mon Sep 17 00:00:00 2001 From: "fix94.1" Date: Sun, 20 May 2012 12:34:48 +0000 Subject: [PATCH] -fixed BASIC(!) channel launching, currently only booting channels from real nand works here, also return to wiiflow seems to be broken, but its a start --- source/channel/channel_launcher.c | 87 +++++++++++++++++-------------- source/channel/channel_launcher.h | 2 +- source/channel/channels.cpp | 18 ++++--- source/channel/channels.h | 5 +- source/channel/nand.cpp | 23 ++++++-- source/menu/menu_game.cpp | 21 ++++---- 6 files changed, 92 insertions(+), 64 deletions(-) diff --git a/source/channel/channel_launcher.c b/source/channel/channel_launcher.c index 914a37cc..7b0ca395 100644 --- a/source/channel/channel_launcher.c +++ b/source/channel/channel_launcher.c @@ -20,6 +20,7 @@ void __Disc_SetLowMem(void); void __Disc_SetVMode(void); void __Disc_SetTime(void); void _unstub_start(); +u32 entryPoint; extern void __exception_closeall(); @@ -35,15 +36,10 @@ typedef struct _dolheader{ u32 padding[7]; } __attribute__((packed)) dolheader; -u32 entryPoint; - -s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio) +s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio) { - u32 ios; - Identify(chantitle, &ios); - - entryPoint = LoadChannel(data); - MEM2_free(data); + gprintf("Loading Channel...\n"); + entryPoint = entry; /* Select an appropriate video mode */ GXRModeObj * vmode = __Disc_SelectVMode(vidMode, chantitle); @@ -61,11 +57,6 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS entrypoint appJump = (entrypoint)entryPoint; - if (disableIOSreload) - IOSReloadBlock(IOS_GetVersion(), false); - else - IOSReloadBlock(IOS_GetVersion(), true); - /* Set an appropriate video mode */ __Disc_SetVMode(); @@ -79,15 +70,20 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS memset((void *)0x80000000, 0, 6); *(vu32 *)0x80000000 = TITLE_LOWER(chantitle); DCFlushRange((void *)0x80000000, 6); - - /* Shutdown IOS subsystems */ - SYS_ResetSystem(SYS_SHUTDOWN, 0, 0); gprintf("Jumping to entrypoint %08x\n", entryPoint); - + + /* Shutdown IOS subsystems */ + u32 level = IRQ_Disable(); + __IOS_ShutdownSubsystems(); + __exception_closeall(); + + /* Originally from tueidj - taken from NeoGamma (thx) */ + *(vu32*)0xCC003024 = 1; + if (entryPoint != 0x3400) { - if (hooktype != 0) + if(hooktype != 0) { __asm__( "lis %r3, entryPoint@h\n" @@ -101,9 +97,10 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS "bctr\n" ); } - else appJump(); + else + appJump(); } - else if (hooktype != 0) + else if(hooktype != 0) { __asm__( "lis %r3, returnpoint@h\n" @@ -126,7 +123,10 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS "rfi\n" ); } - else _unstub_start(); + else + _unstub_start(); + + IRQ_Restore(level); return 0; } @@ -140,30 +140,30 @@ u32 LoadChannel(u8 *buffer) dolchunkcount = 0; dolheader *dolfile = (dolheader *)buffer; - if(dolfile->bss_start) - { - if(!(dolfile->bss_start & 0x80000000)) - dolfile->bss_start |= 0x80000000; + if(dolfile->bss_start) + { + if(!(dolfile->bss_start & 0x80000000)) + dolfile->bss_start |= 0x80000000; - ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size); - memset((void *)dolfile->bss_start, 0, dolfile->bss_size); - DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size); - } - - int i; + 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_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], dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]); - ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); - memmove (dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]); + memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]); DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); + ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); dolchunkcount++; } @@ -216,38 +216,45 @@ bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen) bool Identify(u64 titleid, u32 *ios) { char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); - + + gprintf("Reading TMD..."); sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid)); u32 tmdSize; u8 *tmdBuffer = ISFS_GetFile((u8 *) &filepath, &tmdSize, -1); if (tmdBuffer == NULL || tmdSize == 0) { - gprintf("Reading TMD...Failed!\n"); + gprintf("Failed!\n"); return false; } + gprintf("Success!\n"); *ios = (u32)(tmdBuffer[0x18b]); u32 tikSize; signed_blob *tikBuffer = NULL; + gprintf("Generating fake ticket..."); if(!Identify_GenerateTik(&tikBuffer,&tikSize)) { - gprintf("Generating fake ticket...Failed!\n"); + gprintf("Failed!\n"); return false; } + gprintf("Success!\n"); + gprintf("Reading certs..."); sprintf(filepath, "/sys/cert.sys"); u32 certSize; u8 *certBuffer = ISFS_GetFile((u8 *) &filepath, &certSize, -1); if (certBuffer == NULL || certSize == 0) { - gprintf("Reading certs...Failed!\n"); + gprintf("Failed!\n"); MEM2_free(tmdBuffer); MEM2_free(tikBuffer); return false; } - + gprintf("Success!\n"); + + gprintf("ES_Identify\n"); s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL); if (ret < 0) { diff --git a/source/channel/channel_launcher.h b/source/channel/channel_launcher.h index b8279b8b..a83dc965 100644 --- a/source/channel/channel_launcher.h +++ b/source/channel/channel_launcher.h @@ -8,7 +8,7 @@ extern "C" { #include #include -s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio); +s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio); u32 LoadChannel(u8 *buffer); void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio); diff --git a/source/channel/channels.cpp b/source/channel/channels.cpp index 5d79d6fd..53bc3fc5 100644 --- a/source/channel/channels.cpp +++ b/source/channel/channels.cpp @@ -73,15 +73,22 @@ Channels::~Channels() { } -u8 * Channels::Load(u64 title) +u32 Channels::Load(u64 title, u32 *ios) { char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); u32 bootcontent; + u32 entry = 0; if(!GetAppNameFromTmd(title, app, true, &bootcontent)) - return NULL; + return entry; - return GetDol(title, bootcontent); + u8* data = GetDol(title, bootcontent); + + Identify(title, ios); + entry = LoadChannel(data); + free(data); + + return entry; } u8 Channels::GetRequestedIOS(u64 title) @@ -104,11 +111,6 @@ u8 Channels::GetRequestedIOS(u64 title) return IOS; } -bool Channels::Launch(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio) -{ - return BootChannel(data, chantitle, vidMode, vipatch, countryString, patchVidMode, disableIOSreload, aspectRatio); -} - u64* Channels::GetChannelList(u32* count) { u32 countall; diff --git a/source/channel/channels.h b/source/channel/channels.h index 761eae93..fc1e936a 100644 --- a/source/channel/channels.h +++ b/source/channel/channels.h @@ -54,10 +54,9 @@ class Channels void Init(u32 channelType, string lang, bool reload = false); - u8 * Load(u64 title); + u32 Load(u64 title, u32 *ios); u8 GetRequestedIOS(u64 title); - bool Launch(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio); - + int Count(); wchar_t *GetName(int index); char *GetId(int index); diff --git a/source/channel/nand.cpp b/source/channel/nand.cpp index 7b443aa6..82344501 100644 --- a/source/channel/nand.cpp +++ b/source/channel/nand.cpp @@ -81,8 +81,14 @@ void Nand::Init(string path, u32 partition, bool disable) s32 Nand::Nand_Mount(NandDevice *Device) { + gprintf("Device: %s\n", Device->Name); + s32 fd = IOS_Open("fat", 0); - if (fd < 0) return fd; + if(fd < 0) + { + gprintf("Mount Fail 1\n"); + return fd; + } static ioctlv vector[1] ATTRIBUTE_ALIGN(32); @@ -145,17 +151,28 @@ s32 Nand::Nand_Disable(void) s32 Nand::Enable_Emu() { if(MountedDevice == EmuDevice || Disabled) + { + gprintf("Fail 1\n"); return 0; + } Disable_Emu(); NandDevice *Device = &NandDeviceList[EmuDevice]; s32 ret = Nand_Mount(Device); - if (ret < 0) return ret; + if(ret < 0) + { + gprintf("Fail 2\n"); + return ret; + } ret = Nand_Enable(Device); - if (ret < 0) return ret; + if(ret < 0) + { + gprintf("Fail 3\n"); + return ret; + } MountedDevice = EmuDevice; diff --git a/source/menu/menu_game.cpp b/source/menu/menu_game.cpp index 14a3f3f9..cf8eb591 100644 --- a/source/menu/menu_game.cpp +++ b/source/menu/menu_game.cpp @@ -872,8 +872,10 @@ static const char systems[11] = { 'C', 'E', 'F', 'J', 'L', 'M', 'N', 'P', 'Q', ' void CMenu::_launchChannel(dir_discHdr *hdr) { Channels channel; - u8 *data = NULL; - + u32 ios = 0; + u32 entry = 0; + MEM1_wrap(0); + string id = string((const char *) hdr->hdr.id); bool forwarder = true; @@ -887,14 +889,10 @@ void CMenu::_launchChannel(dir_discHdr *hdr) } forwarder = m_gcfg2.getBool(id, "custom", forwarder) || strncmp(id.c_str(), "WIMC", 4) == 0; - if(!forwarder) - data = channel.Load(hdr->hdr.chantitle); - + entry = channel.Load(hdr->hdr.chantitle, &ios); Nand::Instance()->Disable_Emu(); - if(!forwarder && data == NULL) return; - bool vipatch = m_gcfg2.testOptBool(id, "vipatch", m_cfg.getBool("GENERAL", "vipatch", false)); bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool("NAND", "cheat", false)); bool countryPatch = m_gcfg2.testOptBool(id, "country_patch", m_cfg.getBool("GENERAL", "country_patch", false)); @@ -986,7 +984,12 @@ void CMenu::_launchChannel(dir_discHdr *hdr) gprintf("Return to channel %s. Using new d2x way\n", IOS_Ioctlv(ESHandle, 0xA1, 1, 0, vector) != -101 ? "Succeeded" : "Failed!" ); IOS_Close(ESHandle); } - + + if (disableIOSreload) + IOSReloadBlock(IOS_GetVersion(), false); + else + IOSReloadBlock(IOS_GetVersion(), true); + CheckGameSoundThread(); cleanup(); Close_Inputs(); @@ -1000,7 +1003,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr) if (WII_LaunchTitle(hdr->hdr.chantitle) < 0) Sys_LoadMenu(); } - else if(!channel.Launch(data, hdr->hdr.chantitle, videoMode, vipatch, countryPatch, patchVidMode, disableIOSreload, aspectRatio)) + else if(!BootChannel(entry, hdr->hdr.chantitle, ios, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio)) Sys_LoadMenu(); }