From 64f448bc7fe425fd078e99bdeb092fa9a19637b5 Mon Sep 17 00:00:00 2001 From: Cyan Date: Sun, 4 May 2014 14:42:52 +0000 Subject: [PATCH] * Fixed an issue where setting files were created on SD if boot.dol was on USB (Thanks Badablek) * Added Auto-edition of meta.xml arguments based on internal user settings. * Added support for meta.xml arguments when rebooting the loader. Nintendont : * Added support for v1.20+ * Fixed launching Gamecube in FST format with nintendont (Thank VashTS) --- HBC/META.XML | 5 +- source/StartUpProcess.cpp | 19 ++-- source/homebrewboot/HomebrewXML.cpp | 70 ++++++++++++++ source/homebrewboot/HomebrewXML.h | 3 + source/prompts/PromptWindows.cpp | 4 +- source/settings/menus/HardDriveSM.cpp | 18 +++- source/settings/menus/HardDriveSM.hpp | 5 +- source/settings/menus/LoaderSettings.cpp | 10 +- source/settings/menus/LoaderSettings.hpp | 1 + source/settings/meta.cpp | 118 +++++++++++++++++++++++ source/settings/meta.h | 30 ++++++ source/sys.cpp | 29 +++++- source/usbloader/GameBooter.cpp | 11 +-- svnrev.sh | 1 + 14 files changed, 297 insertions(+), 27 deletions(-) create mode 100644 source/settings/meta.cpp create mode 100644 source/settings/meta.h diff --git a/HBC/META.XML b/HBC/META.XML index df8e840d..d247ec2a 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,12 +2,13 @@ USB Loader GX USB Loader GX Team - 3.0 r1221 - 20140429130640 + 3.0 r1223 + 20140504141623 diff --git a/source/StartUpProcess.cpp b/source/StartUpProcess.cpp index 9a5e6475..c45c00da 100644 --- a/source/StartUpProcess.cpp +++ b/source/StartUpProcess.cpp @@ -96,6 +96,12 @@ int StartUpProcess::ParseArguments(int argc, char *argv[]) Settings.USBPort = LIMIT(atoi(ptr+strlen("-usbport=")), 0, 2); } + ptr = strcasestr(argv[i], "-mountusb="); + if(ptr) + { + Settings.USBAutoMount = LIMIT(atoi(ptr+strlen("-mountusb=")), 0, 1); + } + if(strlen(argv[i]) == 6 && strchr(argv[i], '=') == 0 && strchr(argv[i], '-') == 0) quickBoot = i; } @@ -244,21 +250,16 @@ int StartUpProcess::Execute() SetTextf("Initialize sd card\n"); DeviceHandler::Instance()->MountSD(); - SetTextf("Loading config files\n"); - - // Ugly, but let's load SD card first to allow users to disable USB Auto mounting. - gprintf("\tLoading config from SD..."); - bool settingsLoaded = Settings.Load(); - gprintf("%s\n", settingsLoaded ? "done" : "failed"); - if(Settings.USBAutoMount == ON) { SetTextf("Initialize usb device\n"); USBSpinUp(); DeviceHandler::Instance()->MountAllUSB(false); } - - if(!settingsLoaded) gprintf("\tLoading config from USB...%s\n", Settings.Load() ? "done" : "failed"); + + SetTextf("Loading config files\n"); + + gprintf("\tLoading config...%s\n", Settings.Load() ? "done" : "failed"); gprintf("\tLoading language...%s\n", Settings.LoadLanguage(Settings.language_path, CONSOLE_DEFAULT) ? "done" : "failed"); gprintf("\tLoading game settings...%s\n", GameSettings.Load(Settings.ConfigPath) ? "done" : "failed"); gprintf("\tLoading game statistics...%s\n", GameStatistics.Load(Settings.ConfigPath) ? "done" : "failed"); diff --git a/source/homebrewboot/HomebrewXML.cpp b/source/homebrewboot/HomebrewXML.cpp index c94fa39d..da80b63c 100644 --- a/source/homebrewboot/HomebrewXML.cpp +++ b/source/homebrewboot/HomebrewXML.cpp @@ -88,6 +88,70 @@ int HomebrewXML::LoadHomebrewXMLData(const char* filename) return 1; } +int HomebrewXML::SaveHomebrewXMLData(const char* filename) +{ + const int max_line_size = 4096; + char *line = new char[max_line_size]; + + FILE *fp = fopen(filename, "wb"); + if(!fp) + { + delete [] line; + return 0; + } + + snprintf(line, max_line_size,"\n"); fputs(line, fp); + snprintf(line, max_line_size,"\n"); fputs(line, fp); + snprintf(line, max_line_size," %s\n", GetName()); fputs(line, fp); + snprintf(line, max_line_size," %s\n", GetCoder()); fputs(line, fp); + snprintf(line, max_line_size," %s\n", GetVersion()); fputs(line, fp); + snprintf(line, max_line_size," %s\n", GetReleasedate()); fputs(line, fp); + if (Arguments.size() > 0) + { + snprintf(line, max_line_size," \n"); fputs(line, fp); + for(u8 i = 0; i < Arguments.size(); i++) + { + snprintf(line, max_line_size," %s\n", Arguments[i].c_str()); fputs(line, fp); + } + snprintf(line, max_line_size," \n"); fputs(line, fp); + } + snprintf(line, max_line_size," \n"); fputs(line, fp); + snprintf(line, max_line_size," %s\n", GetShortDescription()); fputs(line, fp); + snprintf(line, max_line_size," %s\n", GetLongDescription()); fputs(line, fp); + snprintf(line, max_line_size,"\n"); fputs(line, fp); + + fclose(fp); + delete [] line; + return 1; +} + +/* Set argument */ +void HomebrewXML::SetArgument(const char* argument) +{ + // Crop value from argument, if present + char argName[strlen(argument)+1]; + strcpy(argName, argument); + char *ptr = strrchr(argName, '='); + if(ptr) *(ptr+1) = 0; + + // Check if argument already exists and edit it + bool found = false; + for(u8 i=0; i < Arguments.size(); i++) + { + size_t pos = Arguments[i].find(argName); + if(pos != std::string::npos) + { + Arguments[i] = argument; + found = true; + break; + } + } + + // if it doesn't exist, add the new argument. + if(!found) + Arguments.push_back(argument); +} + /* Get name */ const char * HomebrewXML::GetName() const { @@ -112,6 +176,12 @@ const char * HomebrewXML::GetVersion() const return Version.c_str(); } +/* Set version */ +void HomebrewXML::SetVersion(const char * newVer) +{ + Version = newVer; +} + /* Get releasedate */ const char * HomebrewXML::GetReleasedate() const { diff --git a/source/homebrewboot/HomebrewXML.h b/source/homebrewboot/HomebrewXML.h index 5251b2e7..b284ca0e 100644 --- a/source/homebrewboot/HomebrewXML.h +++ b/source/homebrewboot/HomebrewXML.h @@ -15,15 +15,18 @@ class HomebrewXML HomebrewXML(const char* filename) { LoadHomebrewXMLData(filename); }; int LoadHomebrewXMLData(const char* filename); + int SaveHomebrewXMLData(const char* filename); const char * GetName() const; void SetName(char * newName); const char * GetCoder() const; const char * GetVersion() const; + void SetVersion(const char * newVer); const char * GetReleasedate() const; const char * GetShortDescription() const; const char * GetLongDescription() const; const std::vector & GetArguments() const { return Arguments; }; + void SetArgument(const char* argument); protected: std::string Name; diff --git a/source/prompts/PromptWindows.cpp b/source/prompts/PromptWindows.cpp index 357a3106..e4e9d561 100644 --- a/source/prompts/PromptWindows.cpp +++ b/source/prompts/PromptWindows.cpp @@ -343,8 +343,10 @@ void WindowCredits() // Nintendont Loader..Built : %s %s..Sep 20 2013.15:27:01 // alpha0.1 if((*(u32*)(buffer+i+2)) == 'nten' && (*(u32*)(buffer+i+6)) == 'dont' && (*(u32*)(buffer+i+11)) == 'Load') { + u8 offset = *(u32*)(buffer+i+17) == ' USB' ? 40 : 36; // r39 only + if(buffer[i+17] == '\r') offset += 2; //v1.20+ for(int j = 0 ; j < 20 ; j++) - NINversion[j] = *(u8*)(buffer+i+36+j); + NINversion[j] = *(u8*)(buffer+i+offset+j); NINversion[11] = ' '; // replace \0 between year and time with a space. NINversion[20] = 0; snprintf(GCInfo2, sizeof(GCInfo2), "Nintendont Built %.20s", NINversion ); diff --git a/source/settings/menus/HardDriveSM.cpp b/source/settings/menus/HardDriveSM.cpp index cae2c4d1..ccea76ad 100644 --- a/source/settings/menus/HardDriveSM.cpp +++ b/source/settings/menus/HardDriveSM.cpp @@ -1,6 +1,6 @@ /**************************************************************************** - * Copyright (C) 2011 - * by Dimok + * Copyright (C) 2014 Cyan + * Copyright (C) 2011 Dimok * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any @@ -26,6 +26,7 @@ #include "HardDriveSM.hpp" #include "Controls/DeviceHandler.hpp" #include "settings/CSettings.h" +#include "settings/meta.h" #include "prompts/PromptWindows.h" #include "language/gettext.h" #include "usbloader/GameList.h" @@ -86,6 +87,7 @@ HardDriveSM::HardDriveSM() OldSettingsPartition = Settings.partition; OldSettingsMultiplePartitions = Settings.MultiplePartitions; NewSettingsUSBPort = Settings.USBPort; + oldSettingsUSBAutoMount = Settings.USBAutoMount; SetOptionValues(); } @@ -95,7 +97,8 @@ HardDriveSM::~HardDriveSM() //! if partition has changed, Reinitialize it if (Settings.partition != OldSettingsPartition || Settings.MultiplePartitions != OldSettingsMultiplePartitions || - Settings.USBPort != NewSettingsUSBPort) + Settings.USBPort != NewSettingsUSBPort || + Settings.USBAutoMount != oldSettingsUSBAutoMount) { WBFS_CloseAll(); @@ -107,6 +110,9 @@ HardDriveSM::~HardDriveSM() if(Settings.partition >= DeviceHandler::GetUSBPartitionCount()) Settings.partition = 0; + + // set -1 to edit meta.xml arguments + NewSettingsUSBPort = -1; } WBFS_Init(WBFS_DEVICE_USB); @@ -119,6 +125,12 @@ HardDriveSM::~HardDriveSM() gameList.ReadGameList(); gameList.LoadUnfiltered(); GameTitles.LoadTitlesFromGameTDB(Settings.titlestxt_path, false); + + if(oldSettingsUSBAutoMount != Settings.USBAutoMount || NewSettingsUSBPort == -1) + { + // edit meta.xml arguments + editMetaArguments(); + } } } diff --git a/source/settings/menus/HardDriveSM.hpp b/source/settings/menus/HardDriveSM.hpp index de1b2f81..ad97f903 100644 --- a/source/settings/menus/HardDriveSM.hpp +++ b/source/settings/menus/HardDriveSM.hpp @@ -1,6 +1,6 @@ /**************************************************************************** - * Copyright (C) 2011 - * by Dimok + * Copyright (C) 2014 Cyan + * Copyright (C) 2011 Dimok * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any @@ -37,6 +37,7 @@ class HardDriveSM : public SettingsMenu int OldSettingsPartition; int OldSettingsMultiplePartitions; + int oldSettingsUSBAutoMount; int NewSettingsUSBPort; OptionList GuiOptions; diff --git a/source/settings/menus/LoaderSettings.cpp b/source/settings/menus/LoaderSettings.cpp index d83e982a..0d6bf068 100644 --- a/source/settings/menus/LoaderSettings.cpp +++ b/source/settings/menus/LoaderSettings.cpp @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2012-2013 by Cyan + * Copyright (C) 2012-2014 Cyan * Copyright (C) 2010 by Dimok * * This software is provided 'as-is', without any express or implied @@ -26,6 +26,7 @@ #include "usbloader/usbstorage2.h" #include "settings/CSettings.h" #include "settings/GameTitles.h" +#include "settings/meta.h" #include "prompts/PromptWindows.h" #include "language/gettext.h" #include "wad/nandtitle.h" @@ -218,6 +219,7 @@ LoaderSettings::LoaderSettings() oldLoaderMode = Settings.LoaderMode; oldGameCubeSource = Settings.GameCubeSource; + oldLoaderIOS = Settings.LoaderIOS; } LoaderSettings::~LoaderSettings() @@ -238,6 +240,12 @@ LoaderSettings::~LoaderSettings() { GCGames::Instance()->LoadAllGames(); } + + if(oldLoaderIOS != Settings.LoaderIOS) + { + // edit meta.xml arguments + editMetaArguments(); + } } void LoaderSettings::SetOptionValues() diff --git a/source/settings/menus/LoaderSettings.hpp b/source/settings/menus/LoaderSettings.hpp index 2d6024e5..389bda86 100644 --- a/source/settings/menus/LoaderSettings.hpp +++ b/source/settings/menus/LoaderSettings.hpp @@ -37,6 +37,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 new file mode 100644 index 00000000..f4de4f51 --- /dev/null +++ b/source/settings/meta.cpp @@ -0,0 +1,118 @@ +/* +Copyright (c) 2014 - Cyan + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ +#include "homebrewboot\HomebrewXML.h" +#include "FileOperations\fileops.h" +#include "settings\CSettings.h" +#include "svnrev.h" + +int updateMetaXML (void) +{ + HomebrewXML MetaXML; + char filepath[255]; + snprintf(filepath, sizeof(filepath), "%s/meta.xml", Settings.update_path); + if(!MetaXML.LoadHomebrewXMLData(filepath)) + return 0; + + char line[50]; + snprintf(line, sizeof(line), "--ios=%d", Settings.LoaderIOS); + MetaXML.SetArgument(line); + snprintf(line, sizeof(line), "--usbport=%d", Settings.USBPort); + MetaXML.SetArgument(line); + snprintf(line, sizeof(line), "--mountusb=%d", Settings.USBAutoMount); + MetaXML.SetArgument(line); + snprintf(line, sizeof(line), "3.0 r%s", GetRev()); + MetaXML.SetVersion(line); + + int ret = MetaXML.SaveHomebrewXMLData(filepath); + return ret; +} + +int editMetaArguments (void) +{ + char metapath[255] = ""; + char metatmppath[255] = ""; + + snprintf(metapath, sizeof(metapath), "%s/meta.xml", Settings.update_path); + snprintf(metatmppath, sizeof(metatmppath), "%s/meta.tmp", Settings.update_path); + + FILE *source = fopen(metapath, "rb"); + if(!source) + { + return 0; + } + + FILE *destination = fopen(metatmppath, "wb"); + if(!destination) + { + fclose(source); + return 0; + } + + const int max_line_size = 255; + char *line = new char[max_line_size]; + while (fgets(line, max_line_size, source) != NULL) + { + // delete commented lines + if( strstr(line, "") != NULL) + { + strcpy(line, " \n"); + } + + // 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, " --usbport=%d\n", Settings.USBPort); + fputs(line, destination); + snprintf(line, max_line_size, " --mountusb=%d\n", Settings.USBAutoMount); + fputs(line, destination); + + while(strstr(line, "") == NULL) + { + fgets(line, max_line_size, source); // advance one line + if(feof(source)) + { + fclose(source); + fclose(destination); + delete [] line; + return 0; + } + } + } + fputs(line, destination); + } + + fclose(source); + fclose(destination); + delete [] line; + + if(CopyFile(metatmppath, metapath) <0) + return 0; + + RemoveFile(metatmppath); + + return 1; +} diff --git a/source/settings/meta.h b/source/settings/meta.h new file mode 100644 index 00000000..55fbaeca --- /dev/null +++ b/source/settings/meta.h @@ -0,0 +1,30 @@ +/**************************************************************************** + * Copyright (C) 2014 + * by cyan + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#ifndef _META_H_ +#define _META_H_ + +int updateMetaXML(void); +int editMetaArguments(void); + +#endif diff --git a/source/sys.cpp b/source/sys.cpp index 4fe17bdc..54ace09f 100644 --- a/source/sys.cpp +++ b/source/sys.cpp @@ -10,6 +10,7 @@ #include "settings/CSettings.h" #include "settings/GameTitles.h" #include "settings/newtitles.h" +#include "settings/meta.h" #include "language/gettext.h" #include "network/networkops.h" #include "utils/ResourceManager.h" @@ -222,14 +223,40 @@ void Sys_LoadHBC(void) bool RebootApp(void) { + // be sure to use current settings as arguments + editMetaArguments(); + #ifdef FULLCHANNEL ExitApp(); WII_Initialize(); return !(WII_LaunchTitle(TITLE_ID(0x00010001, 0x554c4e52)) < 0); #else + + // Load meta.xml arguments char filepath[255]; + HomebrewXML MetaXML; + snprintf(filepath, sizeof(filepath), "%s/meta.xml", Settings.update_path); + MetaXML.LoadHomebrewXMLData(filepath); + + u8 *buffer = NULL; + u32 filesize = 0; snprintf(filepath, sizeof(filepath), "%s/boot.dol", Settings.update_path); - return !(BootHomebrew(filepath) < 0); + LoadFileToMem(filepath, &buffer, &filesize); + if(!buffer) + { + return false; + } + FreeHomebrewBuffer(); + CopyHomebrewMemory(buffer, 0, filesize); + + AddBootArgument(filepath); + + for(u32 i = 0; i < MetaXML.GetArguments().size(); ++i) + { + AddBootArgument(MetaXML.GetArguments().at(i).c_str()); + } + + return !(BootHomebrewFromMem() <0); #endif } diff --git a/source/usbloader/GameBooter.cpp b/source/usbloader/GameBooter.cpp index 31c1d573..649ad0f5 100644 --- a/source/usbloader/GameBooter.cpp +++ b/source/usbloader/GameBooter.cpp @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2012-2013 Cyan + * Copyright (C) 2012-2014 Cyan * Copyright (C) 2011 Dimok * * This program is free software: you can redistribute it and/or modify @@ -969,12 +969,6 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr) return 0; } - if(gameHdr->type == TYPE_GAME_GC_EXTRACTED) - { - if(WindowPrompt(tr("Warning:"), fmt(tr("%s only accepts GameCube backups in ISO format."),LoaderName), tr("Continue"), tr("Cancel")) == 0) - return 0; - } - if(!CheckAHBPROT()) { WindowPrompt(tr("Error:"), fmt(tr("%s requires AHB access! Please launch USBLoaderGX from HBC or from an updated channel or forwarder."),LoaderName), tr("OK")); @@ -1047,7 +1041,8 @@ int GameBooter::BootNintendont(struct discHdr *gameHdr) { // Get Nintendont version char NINversion[21]; - u8 offset = *(u32*)(buffer+i+17) == ' USB' ? 40 : 36; + u8 offset = *(u32*)(buffer+i+17) == ' USB' ? 40 : 36; // r39 only + if(buffer[i+17] == '\r') offset += 2; //v1.20+ for(int j = 0 ; j < 20 ; j++) NINversion[j] = *(u8*)(buffer+i+offset+j); NINversion[11] = ' '; // replace \0 between year and time with a space. diff --git a/svnrev.sh b/svnrev.sh index d61d40e3..0bbd4de0 100644 --- a/svnrev.sh +++ b/svnrev.sh @@ -51,6 +51,7 @@ cat < ./HBC/META.XML --ios=250 --usbport=0 + --mountusb=1 // remove this line to enable arguments -->