From 785142ae1ed3c0417764cf2f95d676cb0d05bfdf Mon Sep 17 00:00:00 2001 From: Christopher Roy Bratusek Date: Thu, 3 Jan 2013 22:30:48 +0100 Subject: [PATCH] import fix94 forwarder v12.7 --- forwarder/Makefile | 47 +++-- forwarder/data/app_booter.bin | Bin 0 -> 872 bytes forwarder/source/devicemounter.c | 126 ++++++++++++ forwarder/source/devicemounter.h | 37 ++++ forwarder/source/main.c | 331 ++++++++++++++++++++++++++++++- 5 files changed, 522 insertions(+), 19 deletions(-) create mode 100644 forwarder/data/app_booter.bin create mode 100644 forwarder/source/devicemounter.c create mode 100644 forwarder/source/devicemounter.h diff --git a/forwarder/Makefile b/forwarder/Makefile index 20aa0b4..e0af651 100644 --- a/forwarder/Makefile +++ b/forwarder/Makefile @@ -15,10 +15,9 @@ include $(DEVKITPPC)/wii_rules # SOURCES is a list of directories containing source code # INCLUDES is a list of directories containing extra header files #--------------------------------------------------------------------------------- -TARGET := forwarder +TARGET := boot BUILD := build -SOURCES := source \ - ../svnrev +SOURCES := source DATA := data INCLUDES := @@ -26,21 +25,26 @@ INCLUDES := # options for code generation #--------------------------------------------------------------------------------- -CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) +CFLAGS = -Os -Wall $(MACHDEP) $(INCLUDE) CXXFLAGS = $(CFLAGS) -LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map +#--------------------------------------------------------------------------------- +# move loader to another location - THANKS CREDIAR - 0x81330000 for HBC +#--------------------------------------------------------------------------------- +#LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--section-start,.init=0x81000000 +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map +#LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--section-start,.init=0x80003f00 #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lwiiuse -lbte -logc -lm +LIBS := -lfat -lntfs -lext2fs -lz -lbte -logc -lm -lwiiuse -lbte #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS := +LIBDIRS := $(PORTLIBS) #--------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional @@ -64,7 +68,8 @@ CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) -WADFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.wad*))) +DOLFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.dol))) +ELFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.elf))) #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -75,9 +80,10 @@ else export LD := $(CXX) endif -export OFILES := $(addsuffix .o,$(BINFILES)) \ - $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ - $(sFILES:.s=.o) $(SFILES:.S=.o) +export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) \ + $(addsuffix .o,$(DOLFILES)) \ + $(addsuffix .o,$(ELFFILES)) $(addsuffix .o,$(BINFILES)) #--------------------------------------------------------------------------------- # build a list of include paths @@ -99,7 +105,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: @@ -111,6 +117,11 @@ run: wiiload $(TARGET).dol +#--------------------------------------------------------------------------------- +pack: + zip -9 loadMii.zip $(TARGET).dol ../icon.png ../meta.xml ../README + + #--------------------------------------------------------------------------------- else @@ -123,9 +134,17 @@ $(OUTPUT).dol: $(OUTPUT).elf $(OUTPUT).elf: $(OFILES) #--------------------------------------------------------------------------------- -# This rule links in binary data with extension +# This rule links in binary data with the .jpg extension #--------------------------------------------------------------------------------- -%.wad.o : %.wad +%.dol.o : %.dol + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +%.elf.o : %.elf + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +%.bin.o : %.bin @echo $(notdir $<) @bin2s -a 32 $< | $(AS) -o $(@) diff --git a/forwarder/data/app_booter.bin b/forwarder/data/app_booter.bin new file mode 100644 index 0000000000000000000000000000000000000000..08d1806350e35c2d4e633b9527bf93dd770a0820 GIT binary patch literal 872 zcmZuwL2DC17=7DBNhLy*6>1xriOHeW!d`ONuqke&O0ZQbq~J+c(qa#K5f3X&I}_6$ z3JSsW;Gsz)wE-a%JgPMD;E(Vi5~&`f9u)*>$8WY+L_93K@6CK~zV|+sduSC);Tv9w zfqO=J3dUHD)eJjXkv4!;L%q#;HQ1%lye)xTlkjF}o^Omy7tr^TzW8cV^?0PO)h#2& z7ls~G4Ww-k$Uj6+F5rC*W#K{XXH!av6}b62GL=1i7-wb46N9FZ1=p=3B6bSX`VH~r zmruGgx>tM-@MF>0^+k8rcj#PpQMHyyzkv}cP&ikCa<>te>j1BxF{wAJd8(^~uUTt2 z>L`SrH5hI~y>oh`(LwuAV-d558V$q`G>jjTc-cUkG>%*AIOcpL4RxSFv-KqTd_$h? zBp8o`T301lIYk*kT=Xz?iM%4q0Jnp5GlZBW(dRZ`5}0k|&{L2b~x6O>hqYO{PE zQR@h0y9{?`6rH)0L{%V4yO_wo4zdgLhRzOqlwFjvBW#=^zpOcoF;NGcZ5a7A^;`~P zpa^tkLlSg9qIVr+K{NlI#UC#@?+LUY?PXH!f3hmjv&A$&sniM5h#ug*S9At0hJ5nk zjdIlIKpj?MB6Tb Qi3)Qmr*E3m|C8?f4Pki$ivR!s literal 0 HcmV?d00001 diff --git a/forwarder/source/devicemounter.c b/forwarder/source/devicemounter.c new file mode 100644 index 0000000..14e3e7d --- /dev/null +++ b/forwarder/source/devicemounter.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "devicemounter.h" + +#define MAX_SECTOR_SIZE 4096 + +//these are the only stable and speed is good +#define CACHE 8 +#define SECTORS 64 + +typedef struct _PARTITION_RECORD { + u8 status; /* Partition status; see above */ + u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */ + u8 type; /* Partition type; see above */ + u8 chs_end[3]; /* Cylinder-head-sector address to last block of partition */ + u32 lba_start; /* Local block address to first sector of partition */ + u32 block_count; /* Number of blocks in partition */ +} __attribute__((__packed__)) PARTITION_RECORD; + + +typedef struct _MASTER_BOOT_RECORD { + u8 code_area[446]; /* Code area; normally empty */ + PARTITION_RECORD partitions[4]; /* 4 primary partitions */ + u16 signature; /* MBR signature; 0xAA55 */ +} __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)) + +int USBDevice_Init() +{ + time_t start = time(0); + + while(time(0) - start < 10) // 10 sec + { + if(__io_usbstorage.startup() && __io_usbstorage.isInserted()) + break; + + usleep(200000); // 1/5 sec + } + + if(!__io_usbstorage.startup() || !__io_usbstorage.isInserted()) + return -1; + + int i; + MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD *) malloc(MAX_SECTOR_SIZE); + char *BootSector = (char *) malloc(MAX_SECTOR_SIZE); + if(!mbr || !BootSector) + return -1; + + __io_usbstorage.readSectors(0, 1, mbr); + + for(i = 0; i < 4; ++i) + { + if(mbr->partitions[i].type == 0) + continue; + + __io_usbstorage.readSectors(le32(mbr->partitions[i].lba_start), 1, BootSector); + + if(*((u16 *) (BootSector + 0x1FE)) == 0x55AA) + { + //! Partition typ can be missleading the correct partition format. Stupid lazy ass Partition Editors. + if(memcmp(BootSector + 0x36, "FAT", 3) == 0 || memcmp(BootSector + 0x52, "FAT", 3) == 0) + fatMount(DeviceName[USB1+i], &__io_usbstorage, le32(mbr->partitions[i].lba_start), CACHE, SECTORS); + else if (memcmp(BootSector + 0x03, "NTFS", 4) == 0) + 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); + } + free(mbr); + free(BootSector); + + return -1; +} + +void USBDevice_deInit() +{ + int dev; + char Name[20]; + + for(dev = USB1; dev <= USB4; ++dev) + { + sprintf(Name, "%s:/", DeviceName[dev]); + fatUnmount(Name); + ntfsUnmount(Name, true); + ext2Unmount(Name); + } + //Let's not shutdown so it stays awake for the application + __io_usbstorage.shutdown(); + USB_Deinitialize(); +} + +int SDCard_Init() +{ + if(!__io_wiisd.startup() || !__io_wiisd.isInserted()) + return -1; + + if(fatMount(DeviceName[SD], &__io_wiisd, 0, CACHE, SECTORS)) + return 1; + + return -1; +} + +void SDCard_deInit() +{ + char Name[20]; + sprintf(Name, "%s:/", DeviceName[SD]); + //closing all open Files write back the cache and then shutdown em! + fatUnmount(Name); + //Let's not shutdown so it stays awake for the application + __io_wiisd.shutdown(); +} diff --git a/forwarder/source/devicemounter.h b/forwarder/source/devicemounter.h new file mode 100644 index 0000000..7b1c0fb --- /dev/null +++ b/forwarder/source/devicemounter.h @@ -0,0 +1,37 @@ +#ifndef _FATMOUNTER_H_ +#define _FATMOUNTER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum +{ + SD = 0, + USB1, + USB2, + USB3, + USB4, + MAXDEVICES +}; + +static const char DeviceName[MAXDEVICES][6] = +{ + "sd", + "usb1", + "usb2", + "usb3", + "usb4" +}; + +int USBDevice_Init(); +void USBDevice_deInit(); +int SDCard_Init(); +void SDCard_deInit(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/forwarder/source/main.c b/forwarder/source/main.c index eb78a10..e7c96ee 100644 --- a/forwarder/source/main.c +++ b/forwarder/source/main.c @@ -1,11 +1,332 @@ - + /**************************************************************************** + * Copyright 2009 The Lemon Man and thanks to luccax, Wiipower, Aurelio and crediar + * Copyright 2010 Dimok + * Copyright 2011 FIX94, oggzee + * + * Original forwarder source by + * + * 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 +#include +#include +#include +#include +#include +#include -int main(int argc, char **argv) +#include +#include +#include + +#include "devicemounter.h" + +#define EXECUTE_ADDR ((u8 *) 0x92000000) +#define BOOTER_ADDR ((u8 *) 0x93000000) +#define ARGS_ADDR ((u8 *) 0x93200000) + +#define MAX_CMDLINE 4096 +#define MAX_ARGV 1000 +struct __argv args; +char *a_argv[MAX_ARGV]; +char *meta_buf = NULL; + +typedef void (*entrypoint) (void); +extern void __exception_setreload(int t); +extern void __exception_closeall(); +extern const u8 app_booter_bin[]; +extern const u32 app_booter_bin_size; + +static FILE *open_file(const char *dev, char *filepath) { - VIDEO_Init(); + sprintf(filepath, "%s:/apps/usbloader/boot.dol", dev); + FILE *exeFile = fopen(filepath ,"rb"); - WII_LaunchTitle(0x0001000154484246); + if (exeFile == NULL) + { + sprintf(filepath, "%s:/apps/usbloader_cfg/boot.dol", dev); + exeFile = fopen(filepath ,"rb"); + } + if (exeFile == NULL) + { + sprintf(filepath, "%s:/apps/usbloader/boot.elf", dev); + exeFile = fopen(filepath ,"rb"); + } + if (exeFile == NULL) + { + sprintf(filepath, "%s:/apps/usbloader_cfg/boot.elf", dev); + exeFile = fopen(filepath ,"rb"); + } + return exeFile; +} + +void SystemMenu() +{ + *(vu32*)0x8132FFFB = 0x50756e65; + DCFlushRange((void *)(0x8132FFFB), 4); + ICInvalidateRange((void *)(0x8132FFFB), 4); + SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); +} + +bool IsDollZ(u8 *buff) +{ + int ret; + + u8 dollz_stamp[] = {0x3C}; + int dollz_offs = 0x100; + + ret = memcmp(&buff[dollz_offs], dollz_stamp, sizeof(dollz_stamp)); + if (ret == 0) + return true; + + return false; +} + +void arg_init() +{ + memset(&args, 0, sizeof(args)); + memset(a_argv, 0, sizeof(a_argv)); + args.argvMagic = ARGV_MAGIC; + args.length = 1; // double \0\0 + args.argc = 0; + //! Put the argument into mem2 too, to avoid overwriting it + args.commandLine = (char *) ARGS_ADDR + sizeof(args); + args.argv = a_argv; + args.endARGV = a_argv; +} + +char* strcopy(char *dest, const char *src, int size) +{ + strncpy(dest,src,size); + dest[size-1] = 0; + return dest; +} + +int arg_addl(char *arg, int len) +{ + if (args.argc >= MAX_ARGV) + return -1; + if (args.length + len + 1 > MAX_CMDLINE) + return -1; + strcopy(args.commandLine + args.length - 1, arg, len+1); + args.length += len + 1; // 0 term. + args.commandLine[args.length - 1] = 0; // double \0\0 + args.argc++; + args.endARGV = args.argv + args.argc; return 0; -} \ No newline at end of file +} + +int arg_add(char *arg) +{ + return arg_addl(arg, strlen(arg)); +} + +int load_file(char *name, void *buf, int size) +{ + int fd; + int ret; + fd = open(name, O_RDONLY); + if (fd < 0) + return -1; + ret = read(fd, buf, size); + close(fd); + if (ret != size) + return -2; + return 0; +} + +void load_meta(const char *exe_path) +{ + char meta_path[200]; + const char *p; + struct stat st; + + p = strrchr(exe_path, '/'); + snprintf(meta_path, sizeof(meta_path), "%.*smeta.xml", p ? p-exe_path+1 : 0, exe_path); + + if (stat(meta_path, &st) != 0) + return; + if (st.st_size > 64*1024) + return; + + // +1 so that the buf is 0 terminated + meta_buf = calloc(st.st_size + 1, 1); + if (!meta_buf) + return; + + load_file(meta_path, meta_buf, st.st_size); +} + +void strip_comments(char *buf) +{ + char *p = buf; // start of comment + char *e; // end of comment + int len; + while (p && *p) + { + p = strstr(p, ""); + if (!e) + { + *p = 0; // terminate + break; + } + e += 3; + len = strlen(e); + memmove(p, e, len + 1); // +1 for 0 termination + } +} + +void parse_meta() +{ + char *p; + char *e, *end; + if (meta_buf == NULL) + return; + strip_comments(meta_buf); + if (!strstr(meta_buf, "")) + return; + + p = strstr(meta_buf, ""); + if (!p) + return; + + end = strstr(meta_buf, ""); + if (!end) + return; + + do + { + p = strstr(p, ""); + if (!p) + return; + p += 5; //strlen(""); + e = strstr(p, ""); + if (!e) + return; + arg_addl(p, e-p); + p = e + 6; + } + while (p < end); + + if (meta_buf) + { + free(meta_buf); + meta_buf = NULL; + } +} + +int main(int argc, char *argv[]) +{ + u32 cookie; + FILE *exeFile = NULL; + void *exeBuffer = (void *)EXECUTE_ADDR; + u32 exeSize = 0; + entrypoint exeEntryPoint; + __exception_setreload(0); + + // initial video + void *xfb = NULL; + GXRModeObj *rmode = NULL; + + VIDEO_Init(); + rmode = VIDEO_GetPreferredMode(NULL); + xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + VIDEO_Configure(rmode); + VIDEO_SetNextFramebuffer(xfb); + VIDEO_SetBlack(TRUE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + if(rmode->viTVMode&VI_NON_INTERLACE) + VIDEO_WaitVSync(); + + char filepath[200]; + + //init wiimote + WPAD_Init(); + + // try SD Card First + SDCard_Init(); + exeFile = open_file(DeviceName[SD], filepath); + // if app not found on SD Card try USB + if (exeFile == NULL) + { + USBDevice_Init(); + int dev; + for(dev = USB1; dev < MAXDEVICES; ++dev) + { + if(!exeFile) + exeFile = open_file(DeviceName[dev], filepath); + } + } + + // if nothing found exiting + if (exeFile == NULL) + { + fclose(exeFile); + SDCard_deInit(); + USBDevice_deInit(); + SystemMenu(); + } + + fseek(exeFile, 0, SEEK_END); + exeSize = ftell(exeFile); + rewind(exeFile); + + if(fread(exeBuffer, 1, exeSize, exeFile) != exeSize) + { + fclose(exeFile); + SDCard_deInit(); + USBDevice_deInit(); + SystemMenu(); + } + fclose(exeFile); + + if (IsDollZ(exeBuffer) == false) + { + arg_init(); + arg_add(filepath); // argv[0] = filepath + // load meta.xml + load_meta(filepath); + // parse in meta.xml + parse_meta(); + } + + memcpy(BOOTER_ADDR, app_booter_bin, app_booter_bin_size); + DCFlushRange(BOOTER_ADDR, app_booter_bin_size); + + memcpy(ARGS_ADDR, &args, sizeof(args)); + DCFlushRange(ARGS_ADDR, sizeof(args) + args.length); + + SDCard_deInit(); + USBDevice_deInit(); + + exeEntryPoint = (entrypoint)BOOTER_ADDR; + /* cleaning up and load dol */ + SYS_ResetSystem(SYS_SHUTDOWN, 0, 0); + _CPU_ISR_Disable(cookie); + __exception_closeall(); + exeEntryPoint(); + _CPU_ISR_Restore(cookie); + return 0; +}