From 1618b4b1e0be41d6ad1f55386832a7a5248706b1 Mon Sep 17 00:00:00 2001 From: dimok321 <15055714+dimok789@users.noreply.github.com> Date: Wed, 29 Jun 2011 20:45:40 +0000 Subject: [PATCH] USB Loader GX Release V2.2 New: - Added game categories and filter games list by categories (Can be imported from WiiTDB). - Wiinertag support. - Supporting arguments from meta.xml on boot (--ios=xxx and --usbport=x) (Requires Homebrew Channel 1.0.7+ or UNEO Forwarder v3.0). - New ehci modules by Rodries with better drive compatibility. - Added two new video modes to force progressive video mode, 'FORCE PAL480p' and 'FORCE NTSC480p'. - Added Sneek Video Patch mode. - Added new 'Inherit' setting for game settings named "Use global". If that option is set then the main loader setting is used. - Full d2x cIOS support with it's new features (Block IOS Reload, Return To, Sector Sizes > 512). - Support for sector sizes > 512B with FAT32/NTFS (Requires d2x v6+) - Real support for simultanious use of both USB ports without switching the 2nd drive temporary off. (Requires Hermes cIOS or Rodries MOD of the Hermes cIOS (recommended)) - Added two new settings menus - Added saving of game browser position when returning to USB Loader GX Changes: - Improved several GUI controls/navigations - Changed settings menu layout and sorted the items to their correct place (HDD menu, features menu) - Set games settings to use the global setting by default, set to "use global" to use the main loader settings. - Use TinyXML instead of MXML (better XML support) - Updated to new libs (libogc, libfat, libext2fs, libntfs) Fix: - "Return to" option now work for all games, even problematic games like Prince of Persia. (Requires d2x v4+) - Xflip setting fixed. - Fix the parental lock of Individual game settings (Thanks to NJ7) - Fix Theme downloader - Fixed reset of the loader when loading game with IOS reload and disabled WiiTDB titles - Fixed timeout timer on startup to count correctly. - Fixed reversed disc image download when Custom/Original option is selected - Fixed reload of game list after a game rename - Fixed horizontal text scrolling - Fixed booting games by arguments (headless id feature) - Fixed We Dare game boot (thx oggzee) R1099 Change Log: *Added IOS225 from Rodries cIOS Installer MOD to Hermes IOS types New Forwarder V3.0 Changes: *added support for ext partitions *added support for arguments from xml *clean up of source --- Makefile | 4 +- source/background_image.c | 1 - source/cfg.c | 97 +++++++++++++++++++-------------------- source/cfg.h | 33 ++++++------- source/devicemounter.c | 6 +++ source/main.c | 94 +++++++++++++++++++++++++++++++++---- 6 files changed, 153 insertions(+), 82 deletions(-) diff --git a/Makefile b/Makefile index 374e9e4e..ff83fc62 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lfat -lntfs -lpng -lz -lbte -logc -lm +LIBS := -lfat -lntfs -lext2fs -lpng -lz -lbte -logc -lm #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -107,7 +107,7 @@ export OUTPUT := $(CURDIR)/$(TARGET) #--------------------------------------------------------------------------------- $(BUILD): @[ -d $@ ] || mkdir -p $@ - @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile #--------------------------------------------------------------------------------- clean: diff --git a/source/background_image.c b/source/background_image.c index efe6ce78..080c85ad 100644 --- a/source/background_image.c +++ b/source/background_image.c @@ -18,7 +18,6 @@ u8 * GetImageData() else ctx = PNGU_SelectImageFromBuffer(background_png); - if (!ctx) return NULL; diff --git a/source/cfg.c b/source/cfg.c index 68fa241e..774ba1a8 100644 --- a/source/cfg.c +++ b/source/cfg.c @@ -6,72 +6,67 @@ #include #include -#include "cfg.h" - -char update_path[150]; - -static char *cfg_name, *cfg_val; - -char* strcopy(char *dest, char *src, int size) +static char *trimcopy(char *src, char *dest, int size) { - strncpy(dest,src,size); - dest[size-1] = 0; - return dest; -} - -char* trimcopy(char *dest, char *src, int size) -{ - int len; + int i = 0; while (*src == ' ') src++; - len = strlen(src); - // trim trailing " \r\n" - while (len > 0 && strchr(" \r\n", src[len-1])) len--; - if (len >= size) len = size-1; - strncpy(dest, src, len); - dest[len] = 0; + + while (*src != 0 && *src != '\n' && *src != '\r' && i < size-1) + { + dest[i] = *src; + i++; + src++; + } + dest[i] = 0; + i--; + + while(i > 0 && dest[i] == ' ') + { + dest[i] = 0; + i--; + } + return dest; } -void cfg_parseline(char *line, void (*set_func)(char*, char*)) +static char *cfg_parseline(char *line) { - // split name = value - char tmp[200], name[100], val[100]; - strcopy(tmp, line, sizeof(tmp)); + char tmp[300], name[200]; + snprintf(tmp, sizeof(tmp), line); char *eq = strchr(tmp, '='); - if (!eq) return; + if (!eq) + return NULL; + *eq = 0; - trimcopy(name, tmp, sizeof(name)); - trimcopy(val, eq+1, sizeof(val)); - //printf("CFG: %s = %s\n", name, val); - set_func(name, val); + + trimcopy(tmp, name, sizeof(name)); + + if(strcmp(name, "update_path") == 0) + return eq+1; + + return NULL; } - -bool cfg_parsefile(char *fname, void (*set_func)(char*, char*)) +bool cfg_parsefile(char *fname, int size) { - FILE *f; - char line[200]; - - //printf("opening(%s)\n", fname); - f = fopen(fname, "r"); - if (!f) { - //printf("error opening(%s)\n", fname); + FILE *f = fopen(fname, "r"); + if (!f) return false; - } - while (fgets(line, sizeof(line), f)) { - // lines starting with # are comments + + char line[300]; + + while (fgets(line, sizeof(line), f)) + { if (line[0] == '#') continue; - cfg_parseline(line, set_func); + + char * value = cfg_parseline(line); + if(value) + { + trimcopy(value, fname, size); + break; + } } fclose(f); return true; } -void cfg_set(char *name, char *val) -{ - cfg_name = name; - cfg_val = val; - if (strcmp(name, "update_path") == 0) { - strcopy(update_path, val, sizeof(update_path)); - } -} diff --git a/source/cfg.h b/source/cfg.h index 261a25a5..93d3a2cd 100644 --- a/source/cfg.h +++ b/source/cfg.h @@ -1,18 +1,15 @@ -#ifndef _CFG_H_ -#define _CFG_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern char update_path[150]; - -void cfg_set(char *name, char *val); -bool cfg_parsefile(char * fname, void (*set_func)(char*, char*)); - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef _CFG_H_ +#define _CFG_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +bool cfg_parsefile(char * fname, int maxsize); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/devicemounter.c b/source/devicemounter.c index fa3ecb7d..b9c21b83 100644 --- a/source/devicemounter.c +++ b/source/devicemounter.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ typedef struct _MASTER_BOOT_RECORD { } __attribute__((__packed__)) MASTER_BOOT_RECORD; +#define PARTITION_TYPE_LINUX 0x83 #define le32(i) (((((u32) i) & 0xFF) << 24) | ((((u32) i) & 0xFF00) << 8) | \ ((((u32) i) & 0xFF0000) >> 8) | ((((u32) i) & 0xFF000000) >> 24)) @@ -76,6 +78,10 @@ int USBDevice_Init() ntfsMount(DeviceName[USB1+i], &__io_usbstorage, le32(mbr.partitions[i].lba_start), CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER | NTFS_IGNORE_CASE); } } + else if(mbr.partitions[i].type == PARTITION_TYPE_LINUX) + { + ext2Mount(DeviceName[USB1+i], &__io_usbstorage, le32(mbr.partitions[i].lba_start), CACHE, SECTORS, EXT2_FLAG_DEFAULT); + } } return -1; diff --git a/source/main.c b/source/main.c index f87f3131..1daff025 100644 --- a/source/main.c +++ b/source/main.c @@ -39,6 +39,78 @@ void __exception_setreload(int t); +static int GetXMLArguments(const char *path, struct __argv *args) +{ + char xmlpath[200]; + snprintf(xmlpath, sizeof(xmlpath), "%s", path); + + char *ptr = strrchr(xmlpath, '/'); + if(ptr) + ptr[1] = '\0'; + else + return -1; // only take full path + + strncat(xmlpath, "meta.xml", sizeof(xmlpath)); + + FILE *fp = fopen(xmlpath, "rb"); + if(!fp) + return -1; + + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + rewind(fp); + + char *fileBuf = (char *) malloc(size+1); + if(!fileBuf) + { + fclose(fp); + return -1; + } + + fread(fileBuf, 1, size, fp); + fclose(fp); + + fileBuf[size] = '\0'; + + const int max_len = 1024; + char *entry = (char *) malloc(max_len); + ptr = fileBuf; + + while(ptr) + { + char *comment = strstr(ptr, ""); + continue; + } + + ptr += strlen(""); + int len; + for(len = 0; *ptr != '\0' && !(ptr[0] == '<' && ptr[1] == '/') && len < max_len-1; ptr++, len++) + entry[len] = *ptr; + + entry[len] = '\0'; + + char *tmp = (char *) realloc(args->commandLine, args->length + len + 1); + if(!tmp) + break; //out of memory, take what we got until now + + args->commandLine = tmp; + strcpy(args->commandLine + args->length - 1, entry); + args->length += len + 1; + } + + free(entry); + free(fileBuf); + + return 0; +} + static FILE * open_file(const char * dev, char * filepath) { sprintf(filepath, "%s:/apps/usbloader_gx/boot.dol", dev); @@ -58,21 +130,21 @@ static FILE * open_file(const char * dev, char * filepath) return exeFile; } -static bool FindConfigPath(const char * device, char *cfgpath) +static bool FindConfigPath(const char * device, char *cfgpath, int maxsize) { bool result = false; - sprintf(cfgpath, "%s:/config/GXGlobal.cfg", device); - result = cfg_parsefile(cfgpath, &cfg_set); + snprintf(cfgpath, maxsize, "%s:/config/GXGlobal.cfg", device); + result = cfg_parsefile(cfgpath, maxsize); if(!result) { - sprintf(cfgpath, "%s:/apps/usbloader_gx/GXGlobal.cfg", device); - result = cfg_parsefile(cfgpath, &cfg_set); + snprintf(cfgpath, maxsize, "%s:/apps/usbloader_gx/GXGlobal.cfg", device); + result = cfg_parsefile(cfgpath, maxsize); } if(!result) { - sprintf(cfgpath, "%s:/apps/usbloadergx/GXGlobal.cfg", device); - result = cfg_parsefile(cfgpath, &cfg_set); + snprintf(cfgpath, maxsize, "%s:/apps/usbloadergx/GXGlobal.cfg", device); + result = cfg_parsefile(cfgpath, maxsize); } return result; @@ -99,7 +171,7 @@ int main(int argc, char **argv) // try SD Card First SDCard_Init(); - if(FindConfigPath(DeviceName[SD], filepath)) + if(FindConfigPath(DeviceName[SD], filepath, sizeof(filepath))) { strcat(filepath, "boot.dol"); exeFile = fopen(filepath, "rb"); @@ -113,7 +185,7 @@ int main(int argc, char **argv) int dev; for(dev = USB1; dev < MAXDEVICES; ++dev) { - if(FindConfigPath(DeviceName[dev], filepath)) + if(FindConfigPath(DeviceName[dev], filepath, sizeof(filepath))) { strcat(filepath, "boot.dol"); exeFile = fopen(filepath, "rb"); @@ -159,6 +231,7 @@ int main(int argc, char **argv) args.commandLine = (char*)malloc(args.length); if (!args.commandLine) SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); strcpy(args.commandLine, filepath); + GetXMLArguments(filepath, &args); args.commandLine[args.length - 1] = '\0'; args.argc = 1; args.argv = &args.commandLine; @@ -188,8 +261,9 @@ int main(int argc, char **argv) StopGX(); free(imgdata); - //! Reset HBC stub so we can leave correct from usb loader + //! Reset HBC stub so we can leave correct from USB Loader to System Menu memset((char *) 0x80001804, 0, 8); + DCFlushRange((char *) 0x80001804, 8); if (exeEntryPointAddress == 0) SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);