diff --git a/Languages/czech.lang b/Languages/czech.lang index 547322c7..8f242671 100644 --- a/Languages/czech.lang +++ b/Languages/czech.lang @@ -555,6 +555,12 @@ msgstr "Vlastní adresa" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Vlastní cesty" diff --git a/Languages/danish.lang b/Languages/danish.lang index b01f5521..06006847 100644 --- a/Languages/danish.lang +++ b/Languages/danish.lang @@ -555,6 +555,12 @@ msgstr "Brugerdefineret adresse" msgid "Custom Banners" msgstr "Brugerdefineret bannere" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Sti-indstillinger" diff --git a/Languages/dutch.lang b/Languages/dutch.lang index 78db7bba..9499c990 100644 --- a/Languages/dutch.lang +++ b/Languages/dutch.lang @@ -555,6 +555,12 @@ msgstr "Aangepaste Adres" msgid "Custom Banners" msgstr "Aangepaste Banners" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Aangepaste Locaties" diff --git a/Languages/english.lang b/Languages/english.lang index 5f2d00fb..909d3226 100644 --- a/Languages/english.lang +++ b/Languages/english.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "" diff --git a/Languages/finnish.lang b/Languages/finnish.lang index 62379195..f9975d39 100644 --- a/Languages/finnish.lang +++ b/Languages/finnish.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Omat polut" diff --git a/Languages/french.lang b/Languages/french.lang index bdf83374..f63bfb52 100644 --- a/Languages/french.lang +++ b/Languages/french.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "Bannières persos" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Personnalisation des dossiers" diff --git a/Languages/german.lang b/Languages/german.lang index 44682741..6ead166c 100644 --- a/Languages/german.lang +++ b/Languages/german.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "Community Banner" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Community Pfade" diff --git a/Languages/greek.lang b/Languages/greek.lang index 16343d0b..1930a488 100644 --- a/Languages/greek.lang +++ b/Languages/greek.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "Τροποποιημένες ταμπέλες-εικονίδια" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Τροποποιημένες διευθύνσεις/μονοπάτια αρχείων" diff --git a/Languages/hungarian.lang b/Languages/hungarian.lang index ee903767..565edfac 100644 --- a/Languages/hungarian.lang +++ b/Languages/hungarian.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Egyéni útvonalak" diff --git a/Languages/italian.lang b/Languages/italian.lang index f18c09af..89c6832e 100644 --- a/Languages/italian.lang +++ b/Languages/italian.lang @@ -555,6 +555,12 @@ msgstr "Indirizzo personalizzati" msgid "Custom Banners" msgstr "Banner personalizzati" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Percorsi personalizzati" diff --git a/Languages/japanese.lang b/Languages/japanese.lang index 8e84a9be..8e3be54a 100644 --- a/Languages/japanese.lang +++ b/Languages/japanese.lang @@ -555,6 +555,12 @@ msgstr "カスタム アドレス" msgid "Custom Banners" msgstr "カスタムバナー" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "パスを変更" diff --git a/Languages/korean.lang b/Languages/korean.lang index 96df2bf5..a908aa9e 100644 --- a/Languages/korean.lang +++ b/Languages/korean.lang @@ -555,6 +555,12 @@ msgstr "커스텀 주소" msgid "Custom Banners" msgstr "커스텀 배너" +msgid "Custom Game IOS" +msgstr "커스텀 게임 IOS" + +msgid "Custom Games IOS" +msgstr "커스텀 게임 IOS" + msgid "Custom Paths" msgstr "커스텀 경로" diff --git a/Languages/norwegian.lang b/Languages/norwegian.lang index fc10a205..b08ca2bc 100644 --- a/Languages/norwegian.lang +++ b/Languages/norwegian.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Egendefinerte stier" diff --git a/Languages/polish.lang b/Languages/polish.lang index 22cdee91..86eeac94 100644 --- a/Languages/polish.lang +++ b/Languages/polish.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Sciezki" diff --git a/Languages/portuguese_br.lang b/Languages/portuguese_br.lang index edc09914..03262560 100644 --- a/Languages/portuguese_br.lang +++ b/Languages/portuguese_br.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "Banners Modificados" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Caminhos" diff --git a/Languages/portuguese_pt.lang b/Languages/portuguese_pt.lang index 310e2837..e7c828ac 100644 --- a/Languages/portuguese_pt.lang +++ b/Languages/portuguese_pt.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Caminhos Personalizados" diff --git a/Languages/russian.lang b/Languages/russian.lang index 975de12d..acfd1d81 100644 --- a/Languages/russian.lang +++ b/Languages/russian.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Изменение путей" diff --git a/Languages/schinese.lang b/Languages/schinese.lang index 5d2964d4..d75f55eb 100644 --- a/Languages/schinese.lang +++ b/Languages/schinese.lang @@ -555,6 +555,12 @@ msgstr "自定义地址" msgid "Custom Banners" msgstr "自定义频道动画" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "自定义路径" diff --git a/Languages/spanish.lang b/Languages/spanish.lang index 2c6dee3c..116ec77d 100644 --- a/Languages/spanish.lang +++ b/Languages/spanish.lang @@ -555,6 +555,12 @@ msgstr "Dirección custom" msgid "Custom Banners" msgstr "Banners personalizados" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Rutas personalizadas" diff --git a/Languages/swedish.lang b/Languages/swedish.lang index 59d6d98f..904018ac 100644 --- a/Languages/swedish.lang +++ b/Languages/swedish.lang @@ -555,6 +555,12 @@ msgstr "Anpassad adress" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Anpassade sökvägar" diff --git a/Languages/tchinese.lang b/Languages/tchinese.lang index 3217fe23..77eb1818 100644 --- a/Languages/tchinese.lang +++ b/Languages/tchinese.lang @@ -555,6 +555,12 @@ msgstr "自訂地址" msgid "Custom Banners" msgstr "自製頻道動畫" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "自訂路徑" diff --git a/Languages/thai.lang b/Languages/thai.lang index 09f3540e..990da475 100644 --- a/Languages/thai.lang +++ b/Languages/thai.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "กำหนด ที่เก็บ" diff --git a/Languages/turkish.lang b/Languages/turkish.lang index 34b5c7a8..815eab3e 100644 --- a/Languages/turkish.lang +++ b/Languages/turkish.lang @@ -555,6 +555,12 @@ msgstr "" msgid "Custom Banners" msgstr "" +msgid "Custom Game IOS" +msgstr "" + +msgid "Custom Games IOS" +msgstr "" + msgid "Custom Paths" msgstr "Kişisel Yollar" diff --git a/Makefile b/Makefile index 73e3ac6b..6d589a3d 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ SOURCES := source \ source/Controls \ source/system \ source/libs/libwbfs \ + source/libs/libruntimeiospatch \ source/language \ source/mload \ source/mload/modules \ @@ -73,7 +74,7 @@ endif #--------------------------------------------------------------------------------- LIBS := -lwolfssl -lcustomfat -lcustomntfs -lcustomext2fs -lvorbisidec -logg \ -lmad -lfreetype -lgd -ljpeg -lpng -lm -lz -lwiiuse -lwiidrc \ - -lbte -lasnd -logc -lruntimeiospatch + -lbte -lasnd -logc #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing # include and lib @@ -140,7 +141,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ #--------------------------------------------------------------------------------- export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -L$(CURDIR)/source/libs/libdrc/ \ -L$(CURDIR)/source/libs/libext2fs -L$(CURDIR)/source/libs/libfat \ - -L$(CURDIR)/source/libs/libntfs -L$(CURDIR)/source/libs/libruntimeiospatch \ + -L$(CURDIR)/source/libs/libntfs \ -L$(CURDIR)/source/libs/libwolfssl -L$(LIBOGC_LIB) export OUTPUT := $(CURDIR)/$(TARGET) diff --git a/source/Channels/channels.cpp b/source/Channels/channels.cpp index 08ef9203..e1c8d4ee 100755 --- a/source/Channels/channels.cpp +++ b/source/Channels/channels.cpp @@ -264,12 +264,12 @@ u8 *Channels::GetDol(const u64 &title, u8 *tmdBuffer, bool &isForwarder) return outBuf; } -u8 Channels::GetRequestedIOS(const u64 &title) +u8 Channels::GetRequestedIOS(const u64 &title, const char *prefix) { u8 IOS = 0; u32 tmdSize = 0; - u8 *titleTMD = GetTMD(title, &tmdSize, ""); + u8 *titleTMD = GetTMD(title, &tmdSize, prefix); if (!titleTMD) return 0; diff --git a/source/Channels/channels.h b/source/Channels/channels.h index 0ddc538b..67b0ab56 100755 --- a/source/Channels/channels.h +++ b/source/Channels/channels.h @@ -37,7 +37,7 @@ public: static void DestroyInstance(void) { if(instance) delete instance; instance = NULL; } static u32 LoadChannel(const u64 &chantitle); - static u8 GetRequestedIOS(const u64 &title); + static u8 GetRequestedIOS(const u64 &title, const char *prefix); static u8 *GetTMD(const u64 &tid, u32 *size, const char *prefix); static u8 *GetDol(const u64 &title, u8 *tmdBuffer, bool &isForwarder); static u8 *GetOpeningBnr(const u64 &title, u32 *outsize, const char *pathPrefix); diff --git a/source/StartUpProcess.cpp b/source/StartUpProcess.cpp index 88fb4b2b..678abe4b 100644 --- a/source/StartUpProcess.cpp +++ b/source/StartUpProcess.cpp @@ -51,7 +51,7 @@ StartUpProcess::StartUpProcess() versionTxt = new GuiText(" ", 18, (GXColor){255, 255, 255, 255}); versionTxt->SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM); - versionTxt->SetPosition(20, screenheight - 20); + versionTxt->SetPosition(23, screenheight - 20); #ifdef FULLCHANNEL versionTxt->SetTextf("v3.0c Rev. %s (%s)", GetRev(), commitID()); @@ -101,15 +101,22 @@ int StartUpProcess::ParseArguments(int argc, char *argv[]) gprintf("Boot argument %i: %s\n", i + 1, argv[i]); - char *ptr = strcasestr(argv[i], "-bootios="); + char *ptr = strcasestr(argv[i], "-ios="); + if(ptr) + { + if(atoi(ptr+strlen("-ios=")) == 58) + Settings.LoaderIOS = 58; + else + Settings.LoaderIOS = LIMIT(atoi(ptr+strlen("-ios=")), 200, 255); + } + + ptr = strcasestr(argv[i], "-bootios="); if (ptr) { if (atoi(ptr + strlen("-bootios=")) == 58) - Settings.LoaderIOS = 58; + Settings.BootIOS = 58; else - Settings.LoaderIOS = LIMIT(atoi(ptr + strlen("-bootios=")), 200, 255); - Settings.UseArgumentIOS = ON; - Settings.BootIOS = Settings.LoaderIOS; + Settings.BootIOS = LIMIT(atoi(ptr + strlen("-bootios=")), 200, 255); } ptr = strcasestr(argv[i], "-usbport="); @@ -245,38 +252,54 @@ int StartUpProcess::Run(int argc, char *argv[]) return ret; } +void StartUpProcess::LoadIOS(u8 ios, bool boot) +{ + SetTextf("Reloading to IOS%d%s\n", ios, boot ? " requested in meta.xml" : ""); + if (IosLoader::LoadAppCios(ios) < 0) + { + SetTextf("Failed to load an IOS. USB Loader GX requires a cIOS or IOS58 with AHB access. Exiting...\n"); + sleep(5); + Sys_BackToLoader(); + } + SetTextf("Reloaded to IOS%d r%d\n", Settings.LoaderIOS, IOS_GetRevision()); +} + int StartUpProcess::Execute(bool quickGameBoot) { Settings.EntryIOS = IOS_GetVersion(); // Disable AHBPROT - IosLoader::PatchAHB(); - gprintf("Current IOS: %d - have AHB access: %s\n", Settings.EntryIOS, AHBPROT_DISABLED ? "yes" : "no"); - // Reload to a cIOS if required (old forwarder?) or requested - if (!AHBPROT_DISABLED || (Settings.EntryIOS != Settings.BootIOS)) - { - SetTextf("Reloading to cIOS %d%s\n", Settings.LoaderIOS, Settings.UseArgumentIOS ? "requested in meta.xml" : ""); - if (IosLoader::LoadAppCios(Settings.LoaderIOS) < 0) - { - SetTextf("Failed to load an IOS. USB Loader GX requires a cIOS or IOS58 with AHB access. Exiting...\n"); - sleep(5); - Sys_BackToLoader(); - } - SetTextf("Reloaded to cIOS %d\n", Settings.LoaderIOS); - gprintf("Current IOS: %d - have AHB access: %s\n", IOS_GetVersion(), AHBPROT_DISABLED ? "yes" : "no"); - } + IosPatch_AHBPROT(false); + // Store dx2 cIOS info + IosLoader::GetD2XInfo(); + + gprintf("Current IOS: %d - have AHB access: %s\n", Settings.EntryIOS, AHBPROT_DISABLED ? "yes" : "no"); + // Reload to a cIOS if we're using both USB ports + if (Settings.USBPort == 2) + LoadIOS(Settings.LoaderIOS, false); + + // Reload to a cIOS if required (old forwarder?) or requested + else if (!AHBPROT_DISABLED || (Settings.EntryIOS != Settings.BootIOS)) + LoadIOS(Settings.BootIOS, true); + + // Setup the pads SetupPads(); + // Mount the SD card SetTextf("Initializing SD card\n"); DeviceHandler::Instance()->MountSD(); // Do not mount USB if not needed. USB is not available with WiiU WiiVC injected channel + bool USBSuccess = false; if (Settings.USBAutoMount == ON && !isWiiVC) { SetTextf("Initializing USB devices\n"); - USBSpinUp(); - DeviceHandler::Instance()->MountAllUSB(false); - gprintf("Completed initialization of USB devices\n"); + if (USBSpinUp()) + { + DeviceHandler::Instance()->MountAllUSB(false); + USBSuccess = true; + gprintf("Completed initialization of USB devices\n"); + } } SetTextf("Loading config files\n"); @@ -311,7 +334,7 @@ int StartUpProcess::Execute(bool quickGameBoot) // Now load the cIOS that was set in the settings menu if (IosLoader::LoadAppCios(Settings.LoaderIOS) > -1) { - SetTextf("Reloaded to %s%d r%d\n", IOS_GetVersion() >= 200 ? "cIOS " : "IOS", Settings.LoaderIOS, IOS_GetRevision()); + SetTextf("Reloaded to IOS%d r%d\n", Settings.LoaderIOS, IOS_GetRevision()); // Re-Mount devices SetTextf("Reinitializing devices\n"); } @@ -321,10 +344,10 @@ int StartUpProcess::Execute(bool quickGameBoot) SetupPads(); DeviceHandler::Instance()->MountSD(); - if (Settings.USBAutoMount == ON) + if (Settings.USBAutoMount == ON && USBSuccess) { - USBSpinUp(); - DeviceHandler::Instance()->MountAllUSB(false); + if (USBSpinUp()) + DeviceHandler::Instance()->MountAllUSB(false); } } @@ -353,9 +376,9 @@ int StartUpProcess::Execute(bool quickGameBoot) // Enable isfs permission if using Hermes v4 without AHB, or WiiU WiiVC (IOS255 fw.img) if (IOS_GetVersion() < 200 || (IosLoader::IsHermesIOS() && IOS_GetRevision() == 4) || isWiiVC) { - SetTextf("Patching %s%d\n", IOS_GetVersion() >= 200 ? "cIOS " : "IOS", IOS_GetVersion()); + SetTextf("Patching IOS%d\n", IOS_GetVersion()); if (IosPatch_RUNTIME(!isWiiVC, false, false, isWiiVC, false) == ERROR_PATCH) - gprintf("Patching %sIOS%d failed!\n", IOS_GetVersion() >= 200 ? "c" : "", IOS_GetVersion()); + gprintf("Patching IOS%d failed!\n", IOS_GetVersion()); else NandTitles.Get(); // get NAND channel's titles diff --git a/source/StartUpProcess.h b/source/StartUpProcess.h index 4ca8a48d..ea962e3f 100644 --- a/source/StartUpProcess.h +++ b/source/StartUpProcess.h @@ -11,6 +11,7 @@ public: private: StartUpProcess(); ~StartUpProcess(); + void LoadIOS(u8 ios, bool boot); int Execute(bool quickGameBoot); bool USBSpinUp(); void TextFade(int direction); diff --git a/source/libs/libruntimeiospatch/libruntimeiospatch.a b/source/libs/libruntimeiospatch/libruntimeiospatch.a deleted file mode 100644 index 10ea9cd1..00000000 Binary files a/source/libs/libruntimeiospatch/libruntimeiospatch.a and /dev/null differ diff --git a/source/libs/libruntimeiospatch/runtimeiospatch.c b/source/libs/libruntimeiospatch/runtimeiospatch.c new file mode 100644 index 00000000..06ccbfc8 --- /dev/null +++ b/source/libs/libruntimeiospatch/runtimeiospatch.c @@ -0,0 +1,237 @@ +// 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, version 2.0. + +// 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 2.0 for more details. + +// Copyright (C) 2010 Joseph Jordan +// Copyright (C) 2012-2013 damysteryman +// Copyright (C) 2012-2015 Christopher Bratusek +// Copyright (C) 2013 DarkMatterCore +// Copyright (C) 2014 megazig +// Copyright (C) 2015-2017 FIX94 + +#include +#include +#include +#include + +#include "../../gecko.h" +#include "runtimeiospatch.h" + +#define MEM_REG_BASE 0xd8b4000 +#define MEM_PROT (MEM_REG_BASE + 0x20a) + + +static inline void disable_memory_protection(void) { + write32(MEM_PROT, read32(MEM_PROT) & 0x0000FFFF); +} + +static const u8 di_readlimit_old[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 +}; +static const u8 di_readlimit_patch[] = { 0x7e, 0xd4 }; + +static const u8 isfs_permissions_old[] = { 0x42, 0x8B, 0xD0, 0x01, 0x25, 0x66 }; +static const u8 isfs_permissions_patch[] = { 0x42, 0x8B, 0xE0, 0x01, 0x25, 0x66 }; +#if 1 +static const u8 setuid_old[] = { 0xD1, 0x2A, 0x1C, 0x39 }; +static const u8 setuid_patch[] = { 0x46, 0xC0 }; +#endif +static const u8 es_identify_old[] = { 0x28, 0x03, 0xD1, 0x23 }; +static const u8 es_identify_patch[] = { 0x00, 0x00 }; +static const u8 hash_old[] = { 0x20, 0x07, 0x23, 0xA2 }; +static const u8 hash_patch[] = { 0x00 }; +static const u8 new_hash_old[] = { 0x20, 0x07, 0x4B, 0x0B }; +#if 0 +static const u8 addticket_vers_check[] = { 0xD2, 0x01, 0x4E, 0x56 }; +static const u8 addticket_patch[] = { 0xE0 }; +#endif +static const u8 es_set_ahbprot_old[] = { 0x68, 0x5B, 0x22, 0xEC, 0x00, 0x52, 0x18, 0x9B, 0x68, 0x1B, 0x46, 0x98, 0x07, 0xDB }; +static const u8 es_set_ahbprot_patch[] = { 0x01 }; + +/* SSL patches made by FIX94 for Nintendont. Ported to libruntimeiospatch by DarkMatterCore */ +static const u8 ssl_patch1_old[] = { 0xFE, 0x0E, 0xE3, 0x50, 0x00, 0x00, 0x05, 0x9F }; +static const u8 ssl_patch1_new[] = { 0xFE, 0x0E, 0xE3, 0x28, 0xF1, 0x02, 0x05, 0x9F }; // Fixes SSL error -9 (wrong host) +static const u8 ssl_patch2_old[] = { 0x00, 0x00, 0x0A, 0x00, 0x00, 0x09, 0xEA, 0x00 }; +static const u8 ssl_patch2_new[] = { 0x00, 0x00, 0xEA, 0x00, 0x00, 0x09, 0xEA, 0x00 }; // Fixes SSL error -10 (part 1) (wrong root cert) +static const u8 ssl_patch3_old[] = { 0x00, 0x00, 0x1A, 0x00, 0x00, 0x08, 0xE3, 0xE0 }; +static const u8 ssl_patch3_new[] = { 0x00, 0x00, 0xEA, 0x00, 0x00, 0x08, 0xE3, 0xE0 }; // Fixes SSL error -10 (part 2) (wrong root cert) +static const u8 ssl_patch4_old[] = { 0x00, 0x00, 0xDA, 0x00, 0x00, 0x16, 0xE7, 0x96 }; +static const u8 ssl_patch4_new[] = { 0x00, 0x00, 0xEA, 0x00, 0x00, 0x16, 0xE7, 0x96 }; // Fixes SSL error -11 (wrong client cert) + +//Following patches added to iospatch.c by damysteryman, taken from sciifii v5 +static const u8 MEM2_prot_old[] = { 0xB5, 0x00, 0x4B, 0x09, 0x22, 0x01, 0x80, 0x1A, 0x22, 0xF0 }; +static const u8 MEM2_prot_patch[] = { 0xB5, 0x00, 0x4B, 0x09, 0x22, 0x00, 0x80, 0x1A, 0x22, 0xF0 }; +static const u8 ES_OpenTitleContent1_old[] = { 0x9D, 0x05, 0x42, 0x9D, 0xD0, 0x03 }; +static const u8 ES_OpenTitleContent1_patch[] = { 0x9D, 0x05, 0x42, 0x9D, 0xE0, 0x03 }; +static const u8 ES_OpenTitleContent2_old[] = { 0xD4, 0x01, 0x4C, 0x36, 0xE0, 0x3B }; +static const u8 ES_OpenTitleContent2_patch[] = { 0xE0, 0x01, 0x4C, 0x36, 0xE0, 0x3B }; +static const u8 ES_ReadContent_old[] = { 0xFC, 0x0F, 0xB5, 0x30, 0x1C, 0x14, 0x1C, 0x1D, 0x4B, + 0x0E, 0x68, 0x9B, 0x2B, 0x00, 0xD0, 0x03, 0x29, 0x00, 0xDB, 0x01, + 0x29, 0x0F, 0xDD, 0x01 }; +static const u8 ES_ReadContent_patch[] = { 0xFC, 0x0F, 0xB5, 0x30, 0x1C, 0x14, 0x1C, 0x1D, 0x4B, + 0x0E, 0x68, 0x9B, 0x2B, 0x00, 0x46, 0xC0, 0x29, 0x00, 0x46, 0xC0, + 0x29, 0x0F, 0xE0, 0x01 }; +static const u8 ES_CloseContent_old[] = { 0xB5, 0x10, 0x4B, 0x10, 0x68, 0x9B, 0x2B, 0x00, 0xD0, + 0x03, 0x29, 0x00, 0xDB, 0x01, 0x29, 0x0F, 0xDD, 0x01 }; +static const u8 ES_CloseContent_patch[] = { 0xB5, 0x10, 0x4B, 0x10, 0x68, 0x9B, 0x2B, 0x00, 0x46, + 0xC0, 0x29, 0x00, 0x46, 0xC0, 0x29, 0x0F, 0xE0, 0x01 }; +static const u8 ES_TitleVersionCheck_old[] = { 0xD2, 0x01, 0x4E, 0x56 }; +static const u8 ES_TitleVersionCheck_patch[] = { 0xE0, 0x01, 0x4E, 0x56 }; +static const u8 ES_TitleDeleteCheck_old[] = { 0xD8, 0x00, 0x4A, 0x04 }; +static const u8 ES_TitleDeleteCheck_patch[] = { 0xE0, 0x00, 0x4A, 0x04 }; + +//Following set of patches made by damysteryman for use with Wii U's vWii +static const u8 Kill_AntiSysTitleInstallv3_pt1_old[] = { 0x68, 0x1A, 0x2A, 0x01, 0xD0, 0x05 }; // Make sure that the pt1 +static const u8 Kill_AntiSysTitleInstallv3_pt1_patch[] = { 0x68, 0x1A, 0x2A, 0x01, 0x46, 0xC0 }; // patch is applied twice. -dmm +static const u8 Kill_AntiSysTitleInstallv3_pt2_old[] = { 0xD0, 0x02, 0x33, 0x06, 0x42, 0x9A, 0xD1, 0x01 }; // Make sure that the pt2 patch +static const u8 Kill_AntiSysTitleInstallv3_pt2_patch[] = { 0x46, 0xC0, 0x33, 0x06, 0x42, 0x9A, 0xE0, 0x01 }; // is also applied twice. -dmm +static const u8 Kill_AntiSysTitleInstallv3_pt3_old[] = { 0x68, 0xFB, 0x2B, 0x00, 0xDB, 0x01 }; +static const u8 Kill_AntiSysTitleInstallv3_pt3_patch[] = { 0x68, 0xFB, 0x2B, 0x00, 0xDB, 0x10 }; + +/* ISFS_SetAttr patches made by megazig */ +#if 0 +static const u8 isfs_setattr_pt1_old[] = { 0x42, 0xAB, 0xD0, 0x02, 0x20, 0x66 }; +static const u8 isfs_setattr_pt1_patch[] = { 0x42, 0xAB, 0xE0, 0x02, 0x20, 0x66 }; +static const u8 isfs_setattr_pt2_old[] = { 0x2D, 0x00, 0xD0, 0x02, 0x20, 0x66 }; +static const u8 isfs_setattr_pt2_patch[] = { 0x2D, 0x00, 0xE0, 0x02, 0x20, 0x66 }; +#endif + +/* ISFS_permission for WiiU WiiVC patches made by fix94 */ +static const u8 isfs_perm_wiivc_old[] = { 0x42, 0x9F, 0xD1, 0x03, 0x20, 0x00, 0xBD, 0xF0, 0x09, 0x8B, 0xE7, 0xF8, 0x20, 0x66 }; +static const u8 isfs_perm_wiivc_patch[] = { 0x42, 0x9F, 0x46, 0xC0, 0x20, 0x00, 0xBD, 0xF0, 0x09, 0x8B, 0xE7, 0xF8, 0x20, 0x66 }; + + +static u8 apply_patch(const char *name, const u8 *old, u32 old_size, const u8 *patch, size_t patch_size, u32 patch_offset, bool verbose) { + u8 *ptr_start = (u8*)*((u32*)0x80003134), *ptr_end = (u8*)0x94000000; + u8 found = 0; + if(verbose) + gprintf(" Patching %-30s", name); + u8 *location = NULL; + while (ptr_start < (ptr_end - patch_size)) { + if (!memcmp(ptr_start, old, old_size)) { + found++; + location = ptr_start + patch_offset; + u8 *start = location; + u32 i; + for (i = 0; i < patch_size; i++) { + *location++ = patch[i]; + } + DCFlushRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64); + ICInvalidateRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64); + } + ptr_start++; + } + if(verbose){ + if (found) + gprintf(" patched\n"); + else + gprintf(" not patched\n"); + } + return found; +} + +s32 IosPatch_AHBPROT(bool verbose) { + if (AHBPROT_DISABLED) { + disable_memory_protection(); + s32 ret = apply_patch("es_set_ahbprot", es_set_ahbprot_old, sizeof(es_set_ahbprot_old), es_set_ahbprot_patch, sizeof(es_set_ahbprot_patch), 25, verbose); + if (ret) + return ret; + else + return ERROR_PATCH; + } + return ERROR_AHBPROT; +} + +s32 IosPatch_RUNTIME(bool wii, bool sciifii, bool vwii, bool wiivc, bool verbose) { + s32 count = 0; + + if (AHBPROT_DISABLED) { + disable_memory_protection(); + if(wii) + { + if(verbose) gprintf(">> Applying standard Wii patches:\n"); + count += apply_patch("di_readlimit", di_readlimit_old, sizeof(di_readlimit_old), di_readlimit_patch, sizeof(di_readlimit_patch), 12, verbose); + count += apply_patch("isfs_permissions", isfs_permissions_old, sizeof(isfs_permissions_old), isfs_permissions_patch, sizeof(isfs_permissions_patch), 0, verbose); + //count += apply_patch("es_setuid", setuid_old, sizeof(setuid_old), setuid_patch, sizeof(setuid_patch), 0, verbose); + count += apply_patch("es_identify", es_identify_old, sizeof(es_identify_old), es_identify_patch, sizeof(es_identify_patch), 2, verbose); + count += apply_patch("hash_check", hash_old, sizeof(hash_old), hash_patch, sizeof(hash_patch), 1, verbose); + count += apply_patch("new_hash_check", new_hash_old, sizeof(new_hash_old), hash_patch, sizeof(hash_patch), 1, verbose); + //count += apply_patch("isfs_setattr_pt1", isfs_setattr_pt1_old, sizeof(isfs_setattr_pt1_old), isfs_setattr_pt1_patch, sizeof(isfs_setattr_pt1_patch), 0, verbose); + //count += apply_patch("isfs_setattr_pt2", isfs_setattr_pt2_old, sizeof(isfs_setattr_pt2_old), isfs_setattr_pt2_patch, sizeof(isfs_setattr_pt2_patch), 0, verbose); + //count += apply_patch("ssl_patch1", ssl_patch1_old, sizeof(ssl_patch1_old), ssl_patch1_new, sizeof(ssl_patch1_new), 0, verbose); + //count += apply_patch("ssl_patch2", ssl_patch2_old, sizeof(ssl_patch2_old), ssl_patch2_new, sizeof(ssl_patch2_new), 0, verbose); + //count += apply_patch("ssl_patch3", ssl_patch3_old, sizeof(ssl_patch3_old), ssl_patch3_new, sizeof(ssl_patch3_new), 0, verbose); + //count += apply_patch("ssl_patch4", ssl_patch4_old, sizeof(ssl_patch4_old), ssl_patch4_new, sizeof(ssl_patch4_new), 0, verbose); + } + if(sciifii) + { + if(verbose) gprintf(">> Applying Sciifii patches:\n"); + count += apply_patch("MEM2_prot", MEM2_prot_old, sizeof(MEM2_prot_old), MEM2_prot_patch, sizeof(MEM2_prot_patch), 0, verbose); + count += apply_patch("ES_OpenTitleContent1", ES_OpenTitleContent1_old, sizeof(ES_OpenTitleContent1_old), ES_OpenTitleContent1_patch, sizeof(ES_OpenTitleContent1_patch), 0, verbose); + count += apply_patch("ES_OpenTitleContent2", ES_OpenTitleContent2_old, sizeof(ES_OpenTitleContent2_old), ES_OpenTitleContent2_patch, sizeof(ES_OpenTitleContent2_patch), 0, verbose); + count += apply_patch("ES_ReadContent_prot", ES_ReadContent_old, sizeof(ES_ReadContent_old), ES_ReadContent_patch, sizeof(ES_ReadContent_patch), 0, verbose); + count += apply_patch("ES_CloseContent", ES_CloseContent_old, sizeof(ES_CloseContent_old), ES_CloseContent_patch, sizeof(ES_CloseContent_patch), 0, verbose); + count += apply_patch("ES_TitleVersionCheck", ES_TitleVersionCheck_old, sizeof(ES_TitleVersionCheck_old), ES_TitleVersionCheck_patch, sizeof(ES_TitleVersionCheck_patch), 0, verbose); + count += apply_patch("ES_TitleDeleteCheck", ES_TitleDeleteCheck_old, sizeof(ES_TitleDeleteCheck_old), ES_TitleDeleteCheck_patch, sizeof(ES_TitleDeleteCheck_patch), 0, verbose); + } + if(vwii) + { + if(verbose) gprintf(">> Applying vWii patches:\n"); + count += apply_patch("Kill_AntiSysTitleInstallv3_pt1", Kill_AntiSysTitleInstallv3_pt1_old, sizeof(Kill_AntiSysTitleInstallv3_pt1_old), Kill_AntiSysTitleInstallv3_pt1_patch, sizeof(Kill_AntiSysTitleInstallv3_pt1_patch), 0, verbose); + count += apply_patch("Kill_AntiSysTitleInstallv3_pt2", Kill_AntiSysTitleInstallv3_pt2_old, sizeof(Kill_AntiSysTitleInstallv3_pt2_old), Kill_AntiSysTitleInstallv3_pt2_patch, sizeof(Kill_AntiSysTitleInstallv3_pt2_patch), 0, verbose); + count += apply_patch("Kill_AntiSysTitleInstallv3_pt3", Kill_AntiSysTitleInstallv3_pt3_old, sizeof(Kill_AntiSysTitleInstallv3_pt3_old), Kill_AntiSysTitleInstallv3_pt3_patch, sizeof(Kill_AntiSysTitleInstallv3_pt3_patch), 0, verbose); + } + if(wiivc) + { + if(verbose) gprintf(">> Applying WiiVC patches:\n"); + count += apply_patch("isfs_permissions", isfs_perm_wiivc_old, sizeof(isfs_perm_wiivc_old), isfs_perm_wiivc_patch, sizeof(isfs_perm_wiivc_patch), 0, verbose); + count += apply_patch("es_setuid", setuid_old, sizeof(setuid_old), setuid_patch, sizeof(setuid_patch), 0, verbose); + count += apply_patch("es_identify", es_identify_old, sizeof(es_identify_old), es_identify_patch, sizeof(es_identify_patch), 2, verbose); + } + return count; + } + return ERROR_AHBPROT; +} + +s32 IosPatch_FULL(bool wii, bool sciifii, bool vwii, bool wiivc, bool verbose, int IOS) { + s32 ret = 0; + s32 xret = 0; + + if (AHBPROT_DISABLED) + ret = IosPatch_AHBPROT(verbose); + else + return ERROR_AHBPROT; + + if (ret) { + IOS_ReloadIOS(IOS); + xret = IosPatch_RUNTIME(wii, sciifii, vwii, wiivc, verbose); + } else { + xret = ERROR_PATCH; + } + + return xret; + +} + +s32 IosPatch_SSL(bool verbose) { + s32 count = 0; + + if (AHBPROT_DISABLED) { + disable_memory_protection(); + if(verbose) gprintf(">> Applying SSL patches:\n"); + count += apply_patch("ssl_patch1", ssl_patch1_old, sizeof(ssl_patch1_old), ssl_patch1_new, sizeof(ssl_patch1_new), 0, verbose); + count += apply_patch("ssl_patch2", ssl_patch2_old, sizeof(ssl_patch2_old), ssl_patch2_new, sizeof(ssl_patch2_new), 0, verbose); + count += apply_patch("ssl_patch3", ssl_patch3_old, sizeof(ssl_patch3_old), ssl_patch3_new, sizeof(ssl_patch3_new), 0, verbose); + count += apply_patch("ssl_patch4", ssl_patch4_old, sizeof(ssl_patch4_old), ssl_patch4_new, sizeof(ssl_patch4_new), 0, verbose); + return count; + } + return ERROR_AHBPROT; +} diff --git a/source/prompts/GameWindow.cpp b/source/prompts/GameWindow.cpp index fdccb24e..f01b0442 100644 --- a/source/prompts/GameWindow.cpp +++ b/source/prompts/GameWindow.cpp @@ -745,8 +745,9 @@ void GameWindow::BootGame(struct discHdr *header) snprintf(IDfull, sizeof(IDfull), "%s", (char *) header->id); int gameIOS = game_cfg->ios == INHERIT ? Settings.cios : game_cfg->ios; + int autoIOS = game_cfg->autoios == INHERIT ? Settings.AutoIOS : game_cfg->autoios; int gameNandEmuMode = game_cfg->NandEmuMode == INHERIT ? Settings.NandEmuMode : game_cfg->NandEmuMode; - if(header->type == TYPE_GAME_EMUNANDCHAN) + if (header->type == TYPE_GAME_EMUNANDCHAN) gameNandEmuMode = game_cfg->NandEmuMode == INHERIT ? Settings.NandEmuChanMode : game_cfg->NandEmuMode; if (game_cfg->loadalternatedol == 2) @@ -760,14 +761,14 @@ void GameWindow::BootGame(struct discHdr *header) return; } } - else if(game_cfg->loadalternatedol == 3 && WDMMenu::Show(header) == 0) + else if (game_cfg->loadalternatedol == 3 && WDMMenu::Show(header) == 0) { // Canceled return; } - else if(game_cfg->loadalternatedol == 4) + else if (game_cfg->loadalternatedol == 4) { - if(!IosLoader::IsD2X(gameIOS)) + if(autoIOS == GAME_IOS_CUSTOM && !IosLoader::IsD2X(gameIOS)) defaultDolPrompt((char *) header->id); } @@ -778,35 +779,38 @@ void GameWindow::BootGame(struct discHdr *header) if (CheckFile(filepath) == false) { snprintf(filepath + n, sizeof(filepath) - n, " %s", tr( "does not exist! Loading game without cheats." )); - if(!WindowPrompt(tr( "Error" ), filepath, tr( "Continue" ), tr( "Cancel"))) + if (!WindowPrompt(tr( "Error" ), filepath, tr( "Continue" ), tr( "Cancel"))) return; } } - if(header->type == TYPE_GAME_EMUNANDCHAN) + if (autoIOS == GAME_IOS_CUSTOM) { - if(gameNandEmuMode != EMUNAND_NEEK) + if (header->type == TYPE_GAME_EMUNANDCHAN) { - // If NandEmuPath is on root of the first FAT32 partition, allow Waninkoko's rev17-21 cIOS for EmuNAND Channels - bool NandEmu_compatible = false; - const char *NandEmuChanPath = game_cfg->NandEmuPath.size() == 0 ? Settings.NandEmuChanPath : game_cfg->NandEmuPath.c_str(); - NandEmu_compatible = IosLoader::is_NandEmu_compatible(NandEmuChanPath, gameIOS); - - if(!IosLoader::IsD2X(gameIOS) && !NandEmu_compatible) + if (gameNandEmuMode != EMUNAND_NEEK) { - ShowError(tr("Launching emulated NAND channels only works on d2x cIOS! Change game IOS to a d2x cIOS first.")); - return; + // If NandEmuPath is on root of the first FAT32 partition, allow Waninkoko's rev17-21 cIOS for EmuNAND Channels + bool NandEmu_compatible = false; + const char *NandEmuChanPath = game_cfg->NandEmuPath.size() == 0 ? Settings.NandEmuChanPath : game_cfg->NandEmuPath.c_str(); + NandEmu_compatible = IosLoader::is_NandEmu_compatible(NandEmuChanPath, gameIOS); + + if (!IosLoader::IsD2X(gameIOS) && !NandEmu_compatible) + { + ShowError(tr("Launching emulated NAND channels only works on d2x cIOS! Change game IOS to a d2x cIOS first.")); + return; + } } } - } - // Restrict EmuNAND with Wii games only with d2x - if(header->type == TYPE_GAME_WII_IMG || header->type == TYPE_GAME_WII_DISC) - { - if(gameNandEmuMode && !IosLoader::IsD2X(gameIOS)) + // Restrict EmuNAND with Wii games only with d2x + if (header->type == TYPE_GAME_WII_IMG || header->type == TYPE_GAME_WII_DISC) { - ShowError(tr("Launching Wii games with emulated NAND only works on d2x cIOS! Change game IOS to a d2x cIOS first.")); - return; + if (gameNandEmuMode && !IosLoader::IsD2X(gameIOS)) + { + ShowError(tr("Launching Wii games with emulated NAND only works on d2x cIOS! Change game IOS to a d2x cIOS first.")); + return; + } } } diff --git a/source/prompts/PromptWindows.cpp b/source/prompts/PromptWindows.cpp index a08d5244..36c450ac 100644 --- a/source/prompts/PromptWindows.cpp +++ b/source/prompts/PromptWindows.cpp @@ -295,10 +295,12 @@ void WindowCredits() #endif char IosInfo[80] = ""; - iosinfo_t * info = IosLoader::GetIOSInfo(IOS_GetVersion()); + iosinfo_t *info = IosLoader::GetIOSInfo(IOS_GetVersion()); if(info) + { snprintf(IosInfo, sizeof(IosInfo), "(%s v%i%s base%i)", info->name, (int)info->version, info->versionstring, (int)info->baseios); - + free(info); + } // Check if DIOS MIOS (Lite) is available char GCInfo[80] = ""; int currentMIOS = IosLoader::GetMIOSInfo(); diff --git a/source/settings/CGameSettings.cpp b/source/settings/CGameSettings.cpp index 1a0fc6f0..a836dd07 100644 --- a/source/settings/CGameSettings.cpp +++ b/source/settings/CGameSettings.cpp @@ -194,6 +194,7 @@ bool CGameSettings::Save() fprintf(f, "ocarina:%d; ", GameList[i].ocarina); fprintf(f, "vipatch:%d; ", GameList[i].vipatch); fprintf(f, "ios:%d; ", GameList[i].ios); + fprintf(f, "autoios:%d; ", GameList[i].autoios); fprintf(f, "parentalcontrol:%d; ", GameList[i].parentalcontrol); fprintf(f, "iosreloadblock:%d; ", GameList[i].iosreloadblock); fprintf(f, "patchcountrystrings:%d; ", GameList[i].patchcountrystrings); @@ -307,6 +308,11 @@ bool CGameSettings::SetSetting(GameCFG & game, const char *name, const char *val game.ios = atoi(value); return true; } + else if(strcmp(name, "autoios") == 0) + { + game.autoios = atoi(value); + return true; + } else if(strcmp(name, "parentalcontrol") == 0) { game.parentalcontrol = atoi(value); @@ -689,6 +695,7 @@ void CGameSettings::SetDefault(GameCFG &game) game.ocarina = INHERIT; game.vipatch = INHERIT; game.ios = INHERIT; + game.autoios = INHERIT; game.parentalcontrol = PARENTAL_LVL_EVERYONE; game.patchcountrystrings = INHERIT; game.loadalternatedol = ALT_DOL_DEFAULT; diff --git a/source/settings/CGameSettings.h b/source/settings/CGameSettings.h index 464caec5..f1ec67f1 100644 --- a/source/settings/CGameSettings.h +++ b/source/settings/CGameSettings.h @@ -19,6 +19,7 @@ typedef struct _GameCFG short ocarina; short vipatch; short ios; + short autoios; short parentalcontrol; short iosreloadblock; short loadalternatedol; @@ -87,6 +88,7 @@ typedef struct _GameCFG this->ocarina = game.ocarina; this->vipatch = game.vipatch; this->ios = game.ios; + this->autoios = game.autoios; this->parentalcontrol = game.parentalcontrol; this->iosreloadblock = game.iosreloadblock; this->loadalternatedol = game.loadalternatedol; diff --git a/source/settings/CSettings.cpp b/source/settings/CSettings.cpp index 6ddff8bf..24adb124 100644 --- a/source/settings/CSettings.cpp +++ b/source/settings/CSettings.cpp @@ -124,6 +124,7 @@ void CSettings::SetDefault() BootIOS = 58; LoaderIOS = 249; cios = 249; + AutoIOS = GAME_IOS_AUTO; gridRows = 3; partition = 0; discart = DISCARTS_ORIGINALS_CUSTOMS; @@ -345,6 +346,7 @@ bool CSettings::Save() fprintf(file, "GameSort = %d\n", GameSort); fprintf(file, "LoaderIOS = %d\n", LoaderIOS); fprintf(file, "cios = %d\n", cios); + fprintf(file, "autoios = %d\n", AutoIOS); fprintf(file, "keyset = %d\n", keyset); fprintf(file, "xflip = %d\n", xflip); fprintf(file, "gridRows = %d\n", gridRows); @@ -666,6 +668,11 @@ bool CSettings::SetSetting(char *name, char *value) cios = atoi(value); return true; } + else if (strcmp(name, "autoios") == 0) + { + AutoIOS = atoi(value); + return true; + } else if (strcmp(name, "keyset") == 0) { keyset = atoi(value); diff --git a/source/settings/CSettings.h b/source/settings/CSettings.h index de73b33c..52293449 100644 --- a/source/settings/CSettings.h +++ b/source/settings/CSettings.h @@ -124,6 +124,7 @@ class CSettings u8 BootIOS; u8 LoaderIOS; u8 cios; + short AutoIOS; short quickboot; short wsprompt; short keyset; @@ -171,7 +172,6 @@ class CSettings std::vector RequiredCategories; std::vector ForbiddenCategories; u8 EntryIOS; - short UseArgumentIOS; short NandEmuMode; short NandEmuChanMode; short UseSystemFont; diff --git a/source/settings/SettingsEnums.h b/source/settings/SettingsEnums.h index af460ec1..0fb3c135 100644 --- a/source/settings/SettingsEnums.h +++ b/source/settings/SettingsEnums.h @@ -409,4 +409,11 @@ enum TITLETYPE TITLETYPE_MANUAL_OVERRIDE = 7 }; +enum +{ + GAME_IOS_AUTO, + GAME_IOS_CUSTOM, + GAME_IOS_MAX +}; + #endif diff --git a/source/settings/menus/GameLoadSM.cpp b/source/settings/menus/GameLoadSM.cpp index 04f58d6b..04e66c15 100644 --- a/source/settings/menus/GameLoadSM.cpp +++ b/source/settings/menus/GameLoadSM.cpp @@ -42,6 +42,12 @@ static const char * OnOffText[] = trNOOP( "Auto" ) }; +static const char * GamesIOSText[] = +{ + trNOOP( "Auto" ), + trNOOP( "Custom" ) +}; + static const char * VideoModeText[] = { trNOOP( "System Default" ), @@ -226,6 +232,10 @@ void GameLoadSM::SetOptionNames() Options->SetName(Idx++, "%s", tr( "Hooktype" )); Options->SetName(Idx++, "%s", tr( "Wiird Debugger" )); Options->SetName(Idx++, "%s", tr( "Game IOS" )); + if(GameConfig.autoios == GAME_IOS_CUSTOM) + { + Options->SetName(Idx++, "%s", tr( "Custom Game IOS" )); + } Options->SetName(Idx++, "%s", tr( "Return To" )); Options->SetName(Idx++, "%s", tr( "Block IOS Reload" )); @@ -356,10 +366,19 @@ void GameLoadSM::SetOptionValues() Options->SetValue(Idx++, "%s", tr( OnOffText[GameConfig.WiirdDebugger] )); //! Settings: Game IOS - if(GameConfig.ios == INHERIT) + if(GameConfig.autoios == INHERIT) Options->SetValue(Idx++, tr("Use global")); else - Options->SetValue(Idx++, "%i", GameConfig.ios); + Options->SetValue(Idx++, "%s", tr( GamesIOSText[GameConfig.autoios] )); + + //! Settings: Custom Game IOS + if(GameConfig.autoios == GAME_IOS_CUSTOM) + { + if(GameConfig.ios == INHERIT) + Options->SetValue(Idx++, tr("Use global")); + else + Options->SetValue(Idx++, "%i", GameConfig.ios); + } //! Settings: Return To if(Header->type == TYPE_GAME_EMUNANDCHAN && EMUNAND_NEEK == (GameConfig.NandEmuMode == INHERIT ? Settings.NandEmuChanMode : GameConfig.NandEmuMode)) @@ -570,6 +589,15 @@ int GameLoadSM::GetMenuInternal() //! Settings: Game IOS else if (ret == ++Idx) + { + if (++GameConfig.autoios >= GAME_IOS_MAX) GameConfig.autoios = INHERIT; + Options->ClearList(); + SetOptionNames(); + SetOptionValues(); + } + + //! Settings: Custom Game IOS + else if (GameConfig.autoios == GAME_IOS_CUSTOM && ret == ++Idx) { char entered[8]; snprintf(entered, sizeof(entered), "%i", GameConfig.ios); @@ -630,14 +658,15 @@ int GameLoadSM::GetMenuInternal() //! Settings: EmuNAND Save/Channel Path else if (ret == ++Idx) { + int autoIOS = GameConfig.autoios == INHERIT ? Settings.AutoIOS : GameConfig.autoios; // If NandEmuPath is on root of the first FAT32 partition, allow rev17-21 cIOS for EmuNAND Channels bool NandEmu_compatible = false; - if(Header->type == TYPE_GAME_EMUNANDCHAN) + if(!autoIOS && Header->type == TYPE_GAME_EMUNANDCHAN) { NandEmu_compatible = IosLoader::is_NandEmu_compatible(NULL, GameConfig.ios == INHERIT ? Settings.cios : GameConfig.ios); } - if(!IosLoader::IsD2X(GameConfig.ios == INHERIT ? Settings.cios : GameConfig.ios) && !NandEmu_compatible) + if(autoIOS == GAME_IOS_CUSTOM && !IosLoader::IsD2X(GameConfig.ios == INHERIT ? Settings.cios : GameConfig.ios) && !NandEmu_compatible) WindowPrompt(tr("Error:"), tr("NAND emulation is only available on D2X cIOS!"), tr("OK")); else { diff --git a/source/settings/menus/LoaderSettings.cpp b/source/settings/menus/LoaderSettings.cpp index cac578b9..5f3702ab 100644 --- a/source/settings/menus/LoaderSettings.cpp +++ b/source/settings/menus/LoaderSettings.cpp @@ -45,6 +45,12 @@ static const char * OnOffText[] = trNOOP( "Auto" ) }; +static const char * GamesIOSText[] = +{ + trNOOP( "Auto" ), + trNOOP( "Custom" ) +}; + static const char * AspectText[] = { trNOOP( "Force 4:3" ), @@ -219,6 +225,7 @@ LoaderSettings::LoaderSettings() oldLoaderMode = Settings.LoaderMode; oldGameCubeSource = Settings.GameCubeSource; + oldLoaderIOS = Settings.LoaderIOS; } LoaderSettings::~LoaderSettings() @@ -238,6 +245,11 @@ LoaderSettings::~LoaderSettings() { GCGames::Instance()->LoadAllGames(); } + + if(oldLoaderIOS != Settings.LoaderIOS) + { + editMetaArguments(); + } } void LoaderSettings::SetOptionNames() @@ -262,6 +274,10 @@ void LoaderSettings::SetOptionNames() } Options->SetName(Idx++, "%s", tr( "Loaders IOS" )); Options->SetName(Idx++, "%s", tr( "Games IOS" )); + if(Settings.AutoIOS == GAME_IOS_CUSTOM) + { + Options->SetName(Idx++, "%s", tr( "Custom Games IOS" )); + } Options->SetName(Idx++, "%s", tr( "Quick Boot" )); Options->SetName(Idx++, "%s", tr( "Block IOS Reload" )); Options->SetName(Idx++, "%s", tr( "Return To" )); @@ -371,16 +387,25 @@ void LoaderSettings::SetOptionValues() //! Settings: Loaders IOS if (Settings.godmode) - Options->SetValue(Idx++, "IOS %i", Settings.LoaderIOS); + Options->SetValue(Idx++, "%i", Settings.LoaderIOS); else Options->SetValue(Idx++, "********"); //! Settings: Games IOS if (Settings.godmode) - Options->SetValue(Idx++, "IOS %i", Settings.cios); + Options->SetValue(Idx++, "%s", tr( GamesIOSText[Settings.AutoIOS] )); else Options->SetValue(Idx++, "********"); + //! Settings: Custom Games IOS + if(Settings.AutoIOS == GAME_IOS_CUSTOM) + { + if (Settings.godmode) + Options->SetValue(Idx++, "%i", Settings.cios); + else + Options->SetValue(Idx++, "********"); + } + //! Settings: Quick Boot Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.quickboot] )); @@ -693,6 +718,17 @@ int LoaderSettings::GetMenuInternal() //! Settings: Games IOS else if (ret == ++Idx) + { + if(!Settings.godmode) + return MENU_NONE; + if (++Settings.AutoIOS >= GAME_IOS_MAX) Settings.AutoIOS = GAME_IOS_AUTO; + Options->ClearList(); + SetOptionNames(); + SetOptionValues(); + } + + //! Settings: Custom Games IOS + else if (Settings.AutoIOS == GAME_IOS_CUSTOM && ret == ++Idx) { if(!Settings.godmode) return MENU_NONE; @@ -738,8 +774,11 @@ int LoaderSettings::GetMenuInternal() //! Settings: EmuNAND Save Mode else if (ret == ++Idx ) { - if(!IosLoader::IsD2X(Settings.cios)) - WindowPrompt(tr("Error:"), tr("NAND Emulation is only available on D2X cIOS!"), tr("OK")); + if (Settings.AutoIOS == GAME_IOS_CUSTOM && !IosLoader::IsD2X(Settings.cios)) + { + WindowPrompt(tr("Error:"), tr("NAND emulation is only available on D2X cIOS!"), tr("OK")); + Settings.NandEmuMode = EMUNAND_OFF; + } else if (++Settings.NandEmuMode >= EMUNAND_NEEK) Settings.NandEmuMode = EMUNAND_OFF; } diff --git a/source/settings/menus/LoaderSettings.hpp b/source/settings/menus/LoaderSettings.hpp index db194aea..b087ad8c 100644 --- a/source/settings/menus/LoaderSettings.hpp +++ b/source/settings/menus/LoaderSettings.hpp @@ -38,6 +38,7 @@ class LoaderSettings : public SettingsMenu short oldLoaderMode; short oldGameCubeSource; + short oldLoaderIOS; OptionList GuiOptions; }; diff --git a/source/settings/meta.cpp b/source/settings/meta.cpp index 56e96afe..27cac0ee 100644 --- a/source/settings/meta.cpp +++ b/source/settings/meta.cpp @@ -34,6 +34,8 @@ int updateMetaXML() return 0; char line[50]; + snprintf(line, sizeof(line), "--ios=%d", Settings.LoaderIOS); + MetaXML.SetArgument(line); snprintf(line, sizeof(line), "--bootios=%d", Settings.BootIOS); MetaXML.SetArgument(line); snprintf(line, sizeof(line), "--usbport=%d", Settings.USBPort); @@ -85,6 +87,8 @@ int editMetaArguments() // generate argurments if (strstr(line, "") != NULL) { + fputs(line, destination); + snprintf(line, max_line_size, " --ios=%d\n", Settings.LoaderIOS); fputs(line, destination); snprintf(line, max_line_size, " --bootios=%d\n", Settings.BootIOS); fputs(line, destination); @@ -111,11 +115,9 @@ int editMetaArguments() fclose(source); fclose(destination); delete[] line; - - if(CopyFile(metatmppath, metapath) <0) - return 0; - - RemoveFile(metatmppath); - + + if (RemoveFile(metapath)) + RenameFile(metatmppath, metapath); + return 1; } diff --git a/source/system/IosLoader.cpp b/source/system/IosLoader.cpp index d4331e3e..11a2f851 100644 --- a/source/system/IosLoader.cpp +++ b/source/system/IosLoader.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "IosLoader.h" #include "sys.h" @@ -18,27 +19,23 @@ #include "mload/modules/odip_frag.h" #include "utils/tools.h" #include "gecko.h" - -#define MEM2_PROT 0x0D8B420A -#define ES_MODULE_START ((u16 *)0x939F0000) -#define ES_MODULE_END (ES_MODULE_START + 0x4000) -#define ES_HACK_OFFSET 4 +#include "libs/libruntimeiospatch/runtimeiospatch.h" extern u32 hdd_sector_size[2]; /* * Buffer variables for the IOS info to avoid loading it several times */ -static int currentIOS = -1; -static iosinfo_t *currentIOSInfo = NULL; static int currentMIOS = -1; static int currentDMLVersion = -1; +std::vector d2x_list; + /****************************************************************************** * Public Methods: ******************************************************************************/ /* - * Check if the ios passed is a Hermes ios. + * Check if the IOS passed is a Hermes IOS. */ bool IosLoader::IsHermesIOS(s32 ios) { @@ -46,7 +43,7 @@ bool IosLoader::IsHermesIOS(s32 ios) } /* - * Check if the ios passed is a Waninkoko ios. + * Check if the IOS passed is a Waninkoko IOS. */ bool IosLoader::IsWaninkokoIOS(s32 ios) { @@ -57,22 +54,77 @@ bool IosLoader::IsWaninkokoIOS(s32 ios) } /* - * Check if the ios passed is a d2x ios. + * Check if the IOS passed is a d2x IOS. */ bool IosLoader::IsD2X(s32 ios) { - iosinfo_t *info = GetIOSInfo(ios); - if(!info) - return false; - - bool res = (strncasecmp(info->name, "d2x", 3) == 0); - - return res; + for (auto cios = d2x_list.begin(); cios != d2x_list.end(); ++cios) + { + if (cios->slot == ios) + return true; + } + return false; } /* - * Loads CIOS (If possible the one from the settings file). - * @return 0 if a cios has been successfully loaded. Else a value below 0 is returned. + * Check if the IOS is a d2x cIOS and return the base IOS. + */ +bool IosLoader::IsD2XBase(s32 ios, s32 *base) +{ + iosinfo_t *info = GetIOSInfo(ios); + if(!info) + { + *base = 0; + return 0; + } + + *base = (u8)info->baseios; + + bool result = (strncasecmp(info->name, "d2x", 3) == 0); + free(info); + return result; +} + +/* + * Get the cIOS slot from a given base IOS. + */ +s32 IosLoader::GetD2XIOS(s32 base) +{ + for (auto cios = d2x_list.begin(); cios != d2x_list.end(); ++cios) + { + if (cios->base == base) + return cios->slot; + } + return 0; +} + +/* + * Check if slots 255-200 contain a d2x cIOS and store info about them. + */ +void IosLoader::GetD2XInfo() +{ + s32 base = 0; + ISFS_Initialize(); + for (s32 i = 255; i >= 200; i--) // Prefer higher slots e.g. 251, 250 & 249 + { + if (IsD2XBase(i, &base)) + { + struct d2x cios = {}; + cios.slot = i; + cios.base = base; + cios.duplicate = GetD2XIOS(base) ? 1 : 0; + d2x_list.push_back(cios); + gprintf("Found d2x cIOS %d (base %d)\n", i, base); + } + } + ISFS_Deinitialize(); + std::sort(d2x_list.begin(), d2x_list.end(), [](const d2x &a, const d2x &b) + { return a.base < b.base; }); +} + +/* + * Loads cIOS (If possible the one from the settings file). + * @return 0 if a cIOS has been successfully loaded. Else a value below 0 is returned. */ s32 IosLoader::LoadAppCios(u8 ios) { @@ -98,7 +150,7 @@ s32 IosLoader::LoadAppCios(u8 ios) if ((ret = ReloadIosSafe(cios)) > -1) { - // Remember working cios + // Remember working cIOS Settings.LoaderIOS = cios; break; } @@ -108,8 +160,8 @@ s32 IosLoader::LoadAppCios(u8 ios) } /* - * Loads a CIOS before a game start. - * @return 0 if a cios has been successfully loaded. Else a value below 0 is returned. + * Loads a cIOS before a game start. + * @return 0 if a cIOS has been successfully loaded. Else a value below 0 is returned. */ s32 IosLoader::LoadGameCios(s32 ios) { @@ -136,7 +188,7 @@ s32 IosLoader::LoadGameCios(s32 ios) /* * Reloads a certain IOS under the condition, that an appropriate version of the IOS is installed. - * @return a negative value if a safe reload of the ios was not possible. + * @return a negative value if a safe reload of the IOS was not possible. */ s32 IosLoader::ReloadIosSafe(s32 ios) { @@ -176,45 +228,11 @@ s32 IosLoader::ReloadIosSafe(s32 ios) */ s32 IosLoader::ReloadIosKeepingRights(s32 ios) { - PatchAHB(); + IosPatch_AHBPROT(false); // Reload IOS. MEM2 protection is implicitly re-enabled return IOS_ReloadIOS(ios); } -void IosLoader::PatchAHB() -{ - if (CheckAHBPROT()) - { - static const u16 ticket_check[] = { - 0x685B, // ldr r3, [r3, #4] ; Get TMD pointer - 0x22EC, 0x0052, // movs r2, 0x1D8 ; Set offset of access rights field in TMD - 0x189B, // adds r3, r3, r2 ; Add offset to TMD pointer - 0x681B, // ldr r3, [r3] ; Load access rights. We'll hack it with full access rights!!! - 0x4698, // mov r8, r3 ; Store it for the DVD video bitcheck later - 0x07DB // lsls r3, r3, 0x1F ; check AHBPROT bit - }; - // Disable memory protection - write16(MEM2_PROT, 0); - - for (u16 *patchme = ES_MODULE_START; patchme < ES_MODULE_END; patchme++) - { - if (!memcmp(patchme, ticket_check, sizeof(ticket_check))) - { - gprintf("PatchAHB: Found TMD access rights check at %p\n", patchme); - - /* Apply patch */ - patchme[ES_HACK_OFFSET] = 0x23FF; // li r3, 0xFF ; Set full access rights - - /* Flush cache */ - DCFlushRange(patchme+ES_HACK_OFFSET, 2); - break; - } - } - // Enable memory protection - write16(MEM2_PROT, 1); - } -} - /* * Check if MIOS is DIOS MIOS, DIOS MIOS Lite or official MIOS. */ @@ -565,70 +583,51 @@ void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev) mload_close(); } } + if (info) + free(info); ISFS_Deinitialize(); } } /* - * Reads the ios info struct from the .app file. + * Reads the IOS info struct from the .app file. * @return pointer to iosinfo_t on success else NULL. The user is responsible for freeing the buffer. */ iosinfo_t *IosLoader::GetIOSInfo(s32 ios) { - if(currentIOS == ios && currentIOSInfo) - return currentIOSInfo; - - if(currentIOSInfo) - { - free(currentIOSInfo); - currentIOSInfo = NULL; - } - - currentIOS = ios; - char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(0x20); + char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); u64 TicketID = ((((u64) 1) << 32) | ios); u32 TMD_Length; - s32 ret = ES_GetStoredTMDSize(TicketID, &TMD_Length); - if (ret < 0) + if (ES_GetStoredTMDSize(TicketID, &TMD_Length) < 0) return NULL; signed_blob *TMD = (signed_blob*) memalign(32, ALIGN32(TMD_Length)); if (!TMD) return NULL; - ret = ES_GetStoredTMD(TicketID, TMD, TMD_Length); - if (ret < 0) + if (ES_GetStoredTMD(TicketID, TMD, TMD_Length) < 0) { free(TMD); return NULL; } - snprintf(filepath, sizeof(filepath), "/title/%08x/%08x/content/%08x.app", 0x00000001, (unsigned int)ios, (unsigned int)(*(u8 *)((u32)TMD+0x1E7))); - + snprintf(filepath, sizeof(filepath), "/title/00000001/%08x/content/%08x.app", (u8)ios, *(u8 *)((u32)TMD+0x1E7)); free(TMD); - u8 *buffer = NULL; u32 filesize = 0; + iosinfo_t *buffer = NULL; - NandTitle::LoadFileFromNand(filepath, &buffer, &filesize); + NandTitle::LoadFileFromNand(filepath, (u8**)&buffer, &filesize); - if(!buffer) + if (!buffer || filesize == 0) return NULL; - iosinfo_t *iosinfo = (iosinfo_t *) buffer; - - if(iosinfo->magicword != 0x1ee7c105 || iosinfo->magicversion != 1) + if (buffer->magicword != 0x1ee7c105 || buffer->magicversion != 1) { free(buffer); return NULL; } - iosinfo = (iosinfo_t *) realloc(buffer, sizeof(iosinfo_t)); - if(!iosinfo) - iosinfo = (iosinfo_t *) buffer; - - currentIOSInfo = iosinfo; - - return iosinfo; + return buffer; } diff --git a/source/system/IosLoader.h b/source/system/IosLoader.h index 6f74f543..4debaa7d 100644 --- a/source/system/IosLoader.h +++ b/source/system/IosLoader.h @@ -81,6 +81,13 @@ typedef struct _iosinfo_t char versionstring[0x10]; // Example: beta2 } __attribute__((packed)) iosinfo_t; +typedef struct d2x +{ + s32 slot; + s32 base; + s32 duplicate; +} d2x; + class IosLoader { public: @@ -88,10 +95,12 @@ class IosLoader static s32 LoadGameCios(s32 ios); static s32 ReloadIosSafe(s32 ios); static s32 ReloadIosKeepingRights(s32 ios); - static void PatchAHB(); static bool IsHermesIOS(s32 ios = IOS_GetVersion()); static bool IsWaninkokoIOS(s32 ios = IOS_GetVersion()); static bool IsD2X(s32 ios = IOS_GetVersion()); + static bool IsD2XBase(s32 ios, s32 *base); + static s32 GetD2XIOS(s32 base); + static void GetD2XInfo(); static iosinfo_t *GetIOSInfo(s32 ios); static u8 GetMIOSInfo(); static u8 GetDMLVersion(char* releaseDate = NULL); diff --git a/source/usbloader/GameBooter.cpp b/source/usbloader/GameBooter.cpp index fbadfec8..f7acb544 100644 --- a/source/usbloader/GameBooter.cpp +++ b/source/usbloader/GameBooter.cpp @@ -15,6 +15,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ +#include + #include "menu/menus.h" #include "menu/WDMMenu.hpp" #include "mload/mload.h" @@ -57,6 +59,7 @@ #include "neek.hpp" #include "lstub.h" #include "xml/GameTDB.hpp" +#include "wad/nandtitle.h" /* GCC 11 false positives */ #if __GNUC__ > 10 @@ -69,6 +72,7 @@ u32 AppEntrypoint = 0; extern bool isWiiVC; // in sys.cpp extern u32 hdd_sector_size[2]; +extern std::vector d2x_list; extern "C" { syssram *__SYS_LockSram(); @@ -143,7 +147,8 @@ u32 GameBooter::BootPartition(char *dolpath, u8 videoselected, u8 alternatedol, return 0; /* Open specified partition */ - ret = WDVD_OpenPartition(offset); + u32 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32); + ret = WDVD_OpenPartition(offset, Tmd_Buffer); if (ret < 0) return 0; @@ -307,6 +312,7 @@ int GameBooter::BootGame(struct discHdr *gameHdr) u8 deflicker = game_cfg->deflicker == INHERIT ? Settings.deflicker : game_cfg->deflicker; u8 sneekChoice = game_cfg->sneekVideoPatch == INHERIT ? Settings.sneekVideoPatch : game_cfg->sneekVideoPatch; s32 iosChoice = game_cfg->ios == INHERIT ? Settings.cios : game_cfg->ios; + u8 autoIOS = game_cfg->autoios == INHERIT ? Settings.AutoIOS : game_cfg->autoios; u8 countrystrings = game_cfg->patchcountrystrings == INHERIT ? Settings.patchcountrystrings : game_cfg->patchcountrystrings; u8 alternatedol = game_cfg->loadalternatedol; u32 alternatedoloffset = game_cfg->alternatedolstart; @@ -363,6 +369,104 @@ int GameBooter::BootGame(struct discHdr *gameHdr) } } + if (autoIOS == GAME_IOS_AUTO && d2x_list.size()) + { + s32 requestedIOS = 0; + if (gameHeader.type == TYPE_GAME_NANDCHAN) + requestedIOS = Channels::GetRequestedIOS(gameHeader.tid, NULL); + else if (gameHeader.type == TYPE_GAME_EMUNANDCHAN) + requestedIOS = Channels::GetRequestedIOS(gameHeader.tid, NandEmuPath); + else if (gameHeader.type == TYPE_GAME_WII_IMG) + { + wbfs_disc_t *d = WBFS_OpenDisc(gameHeader.id); + if (d) + { + void *titleTMD = NULL; + int tmd_size = wbfs_extract_file(d, (char *)"TMD", &titleTMD); + if (titleTMD != NULL) + { + if (tmd_size > 0x18B) + requestedIOS = *((u8 *)titleTMD + 0x18B); + free(titleTMD); + } + WBFS_CloseDisc(d); + } + } + else if (gameHeader.type == TYPE_GAME_WII_DISC) + { + u64 offset; + if (Disc_FindPartition(&offset) >= 0) + { + u32 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32); + if (WDVD_OpenPartition(offset, Tmd_Buffer) >= 0) + { + tmd *tmd_dvd = (tmd *)SIGNATURE_PAYLOAD(Tmd_Buffer); + requestedIOS = tmd_dvd->sys_version; + WDVD_ClosePartition(); + } + } + } + + if (requestedIOS) + { + // Remove cIOS duplicates + // This is done here so that IsD2X() always has the complete list + for (auto cios = d2x_list.begin(); cios != d2x_list.end();) + { + if (cios->duplicate) + { + gprintf("Duplicate IOS: %d in slot %d removed\n", cios->base, cios->slot); + cios = d2x_list.erase(cios); + } + else + ++cios; + } + + gprintf("Requested IOS: %d\n", requestedIOS); + // Workaround for SpongeBobs Boating Bash + if (memcmp(gameHeader.id, "SBV", 3) == 0) + { + // Check if we don't have a cIOS with base IOS 53 + if (!IosLoader::GetD2XIOS(requestedIOS)) + { + if (isWiiU()) + requestedIOS = 58; + else + requestedIOS = IosLoader::GetD2XIOS(58) ? 58 : 38; + gprintf("Applied SpongeBob workaround\n"); + } + } + + // Check if there's any cIOS options remaining + if (d2x_list.size()) + { + // Check for a D2X cIOS with the requested base IOS + int slot = IosLoader::GetD2XIOS(requestedIOS); + if (slot) + iosChoice = slot; + else + { + // Nothing found, so try the closest match + // e.g. if we've got 55, 57 & 58 and a game requests 56 we'll use 57 + auto cios = std::lower_bound(d2x_list.begin(), d2x_list.end(), requestedIOS, [](const d2x &x, const int &y) + { return x.base < y; }); + // Check if the requested IOS is greater than what's available + if (cios == d2x_list.end()) + { + requestedIOS = d2x_list.back().base; + iosChoice = d2x_list.back().slot; + } + else + { + requestedIOS = cios->base; + iosChoice = cios->slot; + } + gprintf("Next best IOS: %d\n", requestedIOS); + } + gprintf("Boot with IOS: %d base %d\n", iosChoice, requestedIOS); + } + } + } AppCleanUp(); gprintf("\tSettings.partition: %d\n", Settings.partition); diff --git a/source/usbloader/wdvd.c b/source/usbloader/wdvd.c index 574fd1d8..7b327d0b 100644 --- a/source/usbloader/wdvd.c +++ b/source/usbloader/wdvd.c @@ -193,12 +193,11 @@ s32 WDVD_StopMotor(void) return (ret == 1) ? 0 : -ret; } -s32 WDVD_OpenPartition(u64 offset) +s32 WDVD_OpenPartition(u64 offset, u32 *tmdbuf) { if (_di_fd < 0) return _di_fd; - static u8 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32); static ioctlv Vectors[5] ATTRIBUTE_ALIGN(32); s32 ret; @@ -214,7 +213,7 @@ s32 WDVD_OpenPartition(u64 offset) Vectors[1].len = 0; Vectors[2].data = 0; Vectors[2].len = 0; - Vectors[3].data = Tmd_Buffer; + Vectors[3].data = tmdbuf; Vectors[3].len = 0x49e4; Vectors[4].data = outbuf; Vectors[4].len = 0x20; diff --git a/source/usbloader/wdvd.h b/source/usbloader/wdvd.h index 295a9975..0bdede22 100644 --- a/source/usbloader/wdvd.h +++ b/source/usbloader/wdvd.h @@ -15,7 +15,7 @@ s32 WDVD_Seek(u64); s32 WDVD_Offset(u64); s32 WDVD_StopLaser(void); s32 WDVD_StopMotor(void); -s32 WDVD_OpenPartition(u64 offset); +s32 WDVD_OpenPartition(u64 offset, u32 *tmdbuf); s32 WDVD_ClosePartition(void); s32 WDVD_UnencryptedRead(void *, u32, u64); s32 WDVD_Read(void *, u32, u64); diff --git a/svnrev.sh b/svnrev.sh index d3d559af..cac2f98b 100644 --- a/svnrev.sh +++ b/svnrev.sh @@ -49,6 +49,7 @@ cat < ./HBC/meta.xml $rev_date