svn wrong file addition format...

update meta.xml version too.
This commit is contained in:
cyan06 2015-07-05 14:47:47 +00:00
parent 422d14cb5b
commit f49b732a3b
4 changed files with 573 additions and 573 deletions

View File

@ -2,7 +2,7 @@
<app version="1"> <app version="1">
<name> USB Loader GX</name> <name> USB Loader GX</name>
<coder>USB Loader GX Team</coder> <coder>USB Loader GX Team</coder>
<version>3.0 r1248</version> <version>3.0 r1250</version>
<release_date>20150705141019</release_date> <release_date>20150705141019</release_date>
<!-- // remove this line to enable arguments <!-- // remove this line to enable arguments
<arguments> <arguments>

View File

@ -1,5 +1,5 @@
# USB Loader GX language source file. # USB Loader GX language source file.
# French.lang - r1244 # French.lang - r1248
# don't delete/change this line (é). # don't delete/change this line (é).
msgid "" msgid ""
msgstr "" msgstr ""

View File

@ -1,483 +1,483 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2015 Cyan * Copyright (C) 2015 Cyan
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <malloc.h> #include <malloc.h>
#include <gccore.h> #include <gccore.h>
#include <ogc/machine/processor.h> #include <ogc/machine/processor.h>
#include "neek.hpp" #include "neek.hpp"
#include "memory/mem2.h" #include "memory/mem2.h"
#include "Controls/DeviceHandler.hpp" #include "Controls/DeviceHandler.hpp"
#include "FileOperations/fileops.h" #include "FileOperations/fileops.h"
#include "settings/CSettings.h" #include "settings/CSettings.h"
#include "sys.h" #include "sys.h"
#include "gecko.h" #include "gecko.h"
typedef struct { typedef struct {
u32 hdrsize; u32 hdrsize;
u32 loadersize; u32 loadersize;
u32 elfsize; u32 elfsize;
u32 argument; u32 argument;
} ioshdr; } ioshdr;
#define MEM_REG_BASE 0xd8b4000 #define MEM_REG_BASE 0xd8b4000
#define MEM_PROT (MEM_REG_BASE + 0x20a) #define MEM_PROT (MEM_REG_BASE + 0x20a)
#define TITLE_ID(x,y) (((u64)(x) << 32) | (y)) #define TITLE_ID(x,y) (((u64)(x) << 32) | (y))
static u32 *kernel = NULL; static u32 *kernel = NULL;
static inline void disable_memory_protection(void) { static inline void disable_memory_protection(void) {
write32(MEM_PROT, read32(MEM_PROT) & 0x0000FFFF); write32(MEM_PROT, read32(MEM_PROT) & 0x0000FFFF);
} }
bool neekLoadKernel (const char* nandpath) bool neekLoadKernel (const char* nandpath)
{ {
gprintf( "NEEK: Loading Kernel.bin... "); gprintf( "NEEK: Loading Kernel.bin... ");
char kernelPath[30]; char kernelPath[30];
if(isWiiU()) if(isWiiU())
snprintf(kernelPath, sizeof(kernelPath), "%s:/sneek/vwiikernel.bin", DeviceHandler::GetDevicePrefix(nandpath)); snprintf(kernelPath, sizeof(kernelPath), "%s:/sneek/vwiikernel.bin", DeviceHandler::GetDevicePrefix(nandpath));
if(!isWiiU() || !CheckFile(kernelPath)) if(!isWiiU() || !CheckFile(kernelPath))
snprintf(kernelPath, sizeof(kernelPath), "%s:/sneek/kernel.bin", DeviceHandler::GetDevicePrefix(nandpath)); snprintf(kernelPath, sizeof(kernelPath), "%s:/sneek/kernel.bin", DeviceHandler::GetDevicePrefix(nandpath));
if(!CheckFile(kernelPath)) if(!CheckFile(kernelPath))
{ {
gprintf("File not found.\n"); gprintf("File not found.\n");
return false; return false;
} }
FILE *f = NULL; FILE *f = NULL;
f = fopen(kernelPath, "rb"); f = fopen(kernelPath, "rb");
if(!f) if(!f)
{ {
gprintf("Failed loading file %s.\n", kernelPath); gprintf("Failed loading file %s.\n", kernelPath);
return false; return false;
} }
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
long fsize = ftell(f); long fsize = ftell(f);
rewind(f); rewind(f);
// Allocate kernel to mem2 // Allocate kernel to mem2
kernel = (u32 *) MEM2_alloc(fsize); kernel = (u32 *) MEM2_alloc(fsize);
if(!kernel) if(!kernel)
{ {
return false; return false;
} }
fread(kernel, 1, fsize, f); fread(kernel, 1, fsize, f);
//((ioshdr*)kernel)->argument = 0x42; // set argument size //((ioshdr*)kernel)->argument = 0x42; // set argument size
DCFlushRange(kernel, fsize); DCFlushRange(kernel, fsize);
gprintf("Loaded to 0x%08x, size: %d\n", kernel, fsize); gprintf("Loaded to 0x%08x, size: %d\n", kernel, fsize);
gprintf("NEEK: offset memory address: %08x\n", (u32)kernel - 0x80000000); // offset gprintf("NEEK: offset memory address: %08x\n", (u32)kernel - 0x80000000); // offset
fclose(f); fclose(f);
return true; return true;
} }
/* /*
static void neekClearKernel(void) static void neekClearKernel(void)
{ {
if(kernel) if(kernel)
MEM2_free(kernel); MEM2_free(kernel);
kernel = NULL; kernel = NULL;
} }
*/ */
int neekBoot(void) int neekBoot(void)
{ {
gprintf("Booting S/Uneek !!\n"); gprintf("Booting S/Uneek !!\n");
if(kernel == NULL) if(kernel == NULL)
{ {
gprintf("Kernel not loaded !! Exiting...\n"); gprintf("Kernel not loaded !! Exiting...\n");
return -1; return -1;
} }
/** boot mini without BootMii IOS code by Crediar. **/ /** boot mini without BootMii IOS code by Crediar. **/
disable_memory_protection(); disable_memory_protection();
unsigned int i = 0x939F02F0; unsigned int i = 0x939F02F0;
unsigned char ES_ImportBoot2[16] = unsigned char ES_ImportBoot2[16] =
{ 0x68, 0x4B, 0x2B, 0x06, 0xD1, 0x0C, 0x68, 0x8B, 0x2B, 0x00, 0xD1, 0x09, 0x68, 0xC8, 0x68, 0x42 }; { 0x68, 0x4B, 0x2B, 0x06, 0xD1, 0x0C, 0x68, 0x8B, 0x2B, 0x00, 0xD1, 0x09, 0x68, 0xC8, 0x68, 0x42 };
if( memcmp( (void*)(i), ES_ImportBoot2, sizeof(ES_ImportBoot2) ) != 0 ) if( memcmp( (void*)(i), ES_ImportBoot2, sizeof(ES_ImportBoot2) ) != 0 )
for( i = 0x939F0000; i < 0x939FE000; i+=4 ) for( i = 0x939F0000; i < 0x939FE000; i+=4 )
if( memcmp( (void*)(i), ES_ImportBoot2, sizeof(ES_ImportBoot2) ) == 0 ) if( memcmp( (void*)(i), ES_ImportBoot2, sizeof(ES_ImportBoot2) ) == 0 )
break; break;
if(i >= 0x939FE000) if(i >= 0x939FE000)
{ {
gprintf("ES_ImportBoot2 not patched !! Exiting...\n"); gprintf("ES_ImportBoot2 not patched !! Exiting...\n");
//SYS_ResetSystem( SYS_RETURNTOMENU, 0, 0 ); //SYS_ResetSystem( SYS_RETURNTOMENU, 0, 0 );
return -1; return -1;
} }
DCInvalidateRange( (void*)i, 0x20 ); DCInvalidateRange( (void*)i, 0x20 );
*(vu32*)(i+0x00) = 0x48034904; // LDR R0, 0x10, LDR R1, 0x14 *(vu32*)(i+0x00) = 0x48034904; // LDR R0, 0x10, LDR R1, 0x14
*(vu32*)(i+0x04) = 0x477846C0; // BX PC, NOP *(vu32*)(i+0x04) = 0x477846C0; // BX PC, NOP
*(vu32*)(i+0x08) = 0xE6000870; // SYSCALL *(vu32*)(i+0x08) = 0xE6000870; // SYSCALL
*(vu32*)(i+0x0C) = 0xE12FFF1E; // BLR *(vu32*)(i+0x0C) = 0xE12FFF1E; // BLR
//*(vu32*)(i+0x10) = 0x11000000; // kernel offset from 0x80000000. Kernel loaded to (void *)0x91000000 //*(vu32*)(i+0x10) = 0x11000000; // kernel offset from 0x80000000. Kernel loaded to (void *)0x91000000
*(vu32*)(i+0x10) = (u32)kernel - 0x80000000; // kernel offset *(vu32*)(i+0x10) = (u32)kernel - 0x80000000; // kernel offset
*(vu32*)(i+0x14) = 0x0000FF01; // version *(vu32*)(i+0x14) = 0x0000FF01; // version
DCFlushRange( (void*)i, 0x20 ); DCFlushRange( (void*)i, 0x20 );
__IOS_ShutdownSubsystems(); __IOS_ShutdownSubsystems();
s32 fd = IOS_Open( "/dev/es", 0 ); s32 fd = IOS_Open( "/dev/es", 0 );
u8 *buffer = (u8*)memalign( 32, 0x100 ); u8 *buffer = (u8*)memalign( 32, 0x100 );
memset( buffer, 0, 0x100 ); memset( buffer, 0, 0x100 );
IOS_IoctlvAsync( fd, 0x1F, 0, 0, (ioctlv*)buffer, NULL, NULL ); IOS_IoctlvAsync( fd, 0x1F, 0, 0, (ioctlv*)buffer, NULL, NULL );
return 0; return 0;
} }
/**************************************************************************** /****************************************************************************
* neekIsNeek2o * neekIsNeek2o
* *
* Detects Kernel.bin format * Detects Kernel.bin format
* *
* @return values : * @return values :
* -1 : kernel.bin not found * -1 : kernel.bin not found
* 0 : sneek or uneek kernel.bin * 0 : sneek or uneek kernel.bin
* 1 : sneek2o or uneek2o kernel.bin * 1 : sneek2o or uneek2o kernel.bin
***************************************************************************/ ***************************************************************************/
int neekIsNeek2o(const char* nandpath) int neekIsNeek2o(const char* nandpath)
{ {
int found = 0; int found = 0;
char tempPath[100]; char tempPath[100];
if(isWiiU()) if(isWiiU())
snprintf(tempPath, sizeof(tempPath), "%s:/sneek/vwiikernel.bin", DeviceHandler::GetDevicePrefix(nandpath)); snprintf(tempPath, sizeof(tempPath), "%s:/sneek/vwiikernel.bin", DeviceHandler::GetDevicePrefix(nandpath));
if(!isWiiU() || !CheckFile(tempPath)) if(!isWiiU() || !CheckFile(tempPath))
snprintf(tempPath, sizeof(tempPath), "%s:/sneek/kernel.bin", DeviceHandler::GetDevicePrefix(nandpath)); snprintf(tempPath, sizeof(tempPath), "%s:/sneek/kernel.bin", DeviceHandler::GetDevicePrefix(nandpath));
if(!CheckFile(tempPath)) if(!CheckFile(tempPath))
return -1; return -1;
u8 *buffer = NULL; u8 *buffer = NULL;
u32 filesize = 0; u32 filesize = 0;
const char* str = "NEEK2O"; const char* str = "NEEK2O";
if(LoadFileToMem(tempPath, &buffer, &filesize)) if(LoadFileToMem(tempPath, &buffer, &filesize))
{ {
for(u32 i = filesize-strlen(str); i > 0; i--) for(u32 i = filesize-strlen(str); i > 0; i--)
{ {
if( memcmp(buffer+i, str, strlen(str)) == 0) if( memcmp(buffer+i, str, strlen(str)) == 0)
{ {
found = 1; found = 1;
break; break;
} }
} }
} }
else else
return -1; return -1;
if(buffer) if(buffer)
free(buffer); free(buffer);
return found; return found;
} }
/**************************************************************************** /****************************************************************************
* neekPathFormat * neekPathFormat
* *
* Convert and trim full path to path format used by neek * Convert and trim full path to path format used by neek
***************************************************************************/ ***************************************************************************/
int neekPathFormat(char* nandpath_out, const char* nandpath_in, u32 len) int neekPathFormat(char* nandpath_out, const char* nandpath_in, u32 len)
{ {
const char* neekNandPathTemp = strchr(nandpath_in, '/'); const char* neekNandPathTemp = strchr(nandpath_in, '/');
if(!neekNandPathTemp) if(!neekNandPathTemp)
return -1; return -1;
snprintf(nandpath_out, len, "%s", neekNandPathTemp); snprintf(nandpath_out, len, "%s", neekNandPathTemp);
if(nandpath_out[strlen(nandpath_out)-1] == '/') if(nandpath_out[strlen(nandpath_out)-1] == '/')
*(strrchr(nandpath_out, '/')) = '\0'; // remove trailing slash *(strrchr(nandpath_out, '/')) = '\0'; // remove trailing slash
return 1; return 1;
} }
/**************************************************************************** /****************************************************************************
* neek2oSetBootSettings * neek2oSetBootSettings
* *
* Generate the neek2o autoboot settings * Generate the neek2o autoboot settings
* *
* neek_config: Pointer to cfg * neek_config: Pointer to cfg
* TitleID : Full path to Channel (00010001 + ABCD) or ID4 for Wii/GC games (00000000 + ID) * TitleID : Full path to Channel (00010001 + ABCD) or ID4 for Wii/GC games (00000000 + ID)
* Magic : 0x0 for channel, 0x5d1c9ea3 for Wii game, 0xC2339F3D for gamecube and quadforce games * Magic : 0x0 for channel, 0x5d1c9ea3 for Wii game, 0xC2339F3D for gamecube and quadforce games
* returnTo : true/false to return to another neek channel instead of system menu * returnTo : true/false to return to another neek channel instead of system menu
* nandpath : Set a different temporary Nand Path to use (full path to nand) * nandpath : Set a different temporary Nand Path to use (full path to nand)
* *
***************************************************************************/ ***************************************************************************/
bool neek2oSetBootSettings(NEEK_CFG* neek_config, u64 TitleID, u32 Magic, u64 returnto, const char* nandpath ) bool neek2oSetBootSettings(NEEK_CFG* neek_config, u64 TitleID, u32 Magic, u64 returnto, const char* nandpath )
{ {
if(!neek_config) if(!neek_config)
return false; return false;
char tmpPath[100]; char tmpPath[100];
memset(neek_config, 0, sizeof(NEEK_CFG)); memset(neek_config, 0, sizeof(NEEK_CFG));
// Magic and version for DML // Magic and version for DML
neek_config->magic = NEEK_MAGIC; neek_config->magic = NEEK_MAGIC;
// GameID // GameID
if(!Magic) if(!Magic)
neek_config->titleid = TitleID; // Set channel ID neek_config->titleid = TitleID; // Set channel ID
else else
{ {
neek_config->gameid = (u32)TitleID; // Wii or Gamecube title ID4 to autoboot neek_config->gameid = (u32)TitleID; // Wii or Gamecube title ID4 to autoboot
neek_config->gamemagic = Magic; // set to 0x5d1c9ea3 for Wii game, 0xC2339F3D for gamecube and quadforce games neek_config->gamemagic = Magic; // set to 0x5d1c9ea3 for Wii game, 0xC2339F3D for gamecube and quadforce games
neek_config->config |= NCON_EXT_BOOT_GAME ; // set Disc booting neek_config->config |= NCON_EXT_BOOT_GAME ; // set Disc booting
} }
// Return to // Return to
if(returnto) if(returnto)
{ {
// check if NK2O is installed // check if NK2O is installed
snprintf(tmpPath, sizeof(tmpPath), "%s/title/00010001/4e4b324f/content/title.tmd", nandpath != NULL ? nandpath : Settings.NandEmuChanPath); snprintf(tmpPath, sizeof(tmpPath), "%s/title/00010001/4e4b324f/content/title.tmd", nandpath != NULL ? nandpath : Settings.NandEmuChanPath);
if(CheckFile(tmpPath)) if(CheckFile(tmpPath))
{ {
neek_config->returnto = TITLE_ID(0x00010001, 'NK2O'); // Currently forced to NK2O user channel neek_config->returnto = TITLE_ID(0x00010001, 'NK2O'); // Currently forced to NK2O user channel
neek_config->config |= NCON_EXT_RETURN_TO; // enable "return to" patch neek_config->config |= NCON_EXT_RETURN_TO; // enable "return to" patch
} }
if(isWiiU()) if(isWiiU())
{ {
neek_config->returnto = TITLE_ID(0x00010002, 'HCVA');// Currently forced to "Return to WiiU" system channel neek_config->returnto = TITLE_ID(0x00010002, 'HCVA');// Currently forced to "Return to WiiU" system channel
neek_config->config |= NCON_EXT_RETURN_TO; // enable "return to" patch neek_config->config |= NCON_EXT_RETURN_TO; // enable "return to" patch
} }
} }
if(!(neek_config->config & NCON_EXT_RETURN_TO)) if(!(neek_config->config & NCON_EXT_RETURN_TO))
{ {
// delete residual "return to" file if last shutdown was unclean. // delete residual "return to" file if last shutdown was unclean.
snprintf(tmpPath, sizeof(tmpPath), "%s:/sneek/reload.sys", DeviceHandler::GetDevicePrefix(nandpath)); snprintf(tmpPath, sizeof(tmpPath), "%s:/sneek/reload.sys", DeviceHandler::GetDevicePrefix(nandpath));
if(CheckFile(tmpPath)) if(CheckFile(tmpPath))
RemoveFile(tmpPath); RemoveFile(tmpPath);
} }
if(nandpath && strlen(nandpath) > 0) if(nandpath && strlen(nandpath) > 0)
{ {
// ensure path is correct format // ensure path is correct format
char neekNandPath[256] = ""; char neekNandPath[256] = "";
if(neekPathFormat(neekNandPath, nandpath, sizeof(neekNandPath))) if(neekPathFormat(neekNandPath, nandpath, sizeof(neekNandPath)))
{ {
snprintf(neek_config->nandpath, sizeof(neek_config->nandpath), "%s", neekNandPath); snprintf(neek_config->nandpath, sizeof(neek_config->nandpath), "%s", neekNandPath);
neek_config->config |= NCON_EXT_NAND_PATH ; // Use custom nand path neek_config->config |= NCON_EXT_NAND_PATH ; // Use custom nand path
// neek_config->config |= NCON_HIDE_EXT_PATH; // Set custom nand path as temporary // neek_config->config |= NCON_HIDE_EXT_PATH; // Set custom nand path as temporary
} }
} }
//set a custom di folder //set a custom di folder
//snprintf(neek_config->dipath, sizeof(neek_config->dipath), "/sneek/vwii"); // Set path for di.bin and diconfig.bin //snprintf(neek_config->dipath, sizeof(neek_config->dipath), "/sneek/vwii"); // Set path for di.bin and diconfig.bin
//neek_config->config |= NCON_EXT_DI_PATH; // Use custom di path //neek_config->config |= NCON_EXT_DI_PATH; // Use custom di path
DCFlushRange(neek_config, sizeof(NEEK_CFG)); DCFlushRange(neek_config, sizeof(NEEK_CFG));
//hexdump(neek_config, sizeof(NEEK_CFG)); //hexdump(neek_config, sizeof(NEEK_CFG));
return true; return true;
} }
/**************************************************************************** /****************************************************************************
* neek2oSetNAND * neek2oSetNAND
* *
* Generates nandcfg.bin if missing and adds missing EmuNAND path * Generates nandcfg.bin if missing and adds missing EmuNAND path
* Sets default EmuNAND path for neek2o * Sets default EmuNAND path for neek2o
* *
* @return values : * @return values :
* -1 : error * -1 : error
* x : Default path set to EmuNAND number x * x : Default path set to EmuNAND number x
***************************************************************************/ ***************************************************************************/
int neek2oSetNAND(const char* nandpath) int neek2oSetNAND(const char* nandpath)
{ {
// format path string for neek // format path string for neek
char neekNandPath[256] = ""; char neekNandPath[256] = "";
if(neekPathFormat(neekNandPath, nandpath, sizeof(neekNandPath)) < 0) if(neekPathFormat(neekNandPath, nandpath, sizeof(neekNandPath)) < 0)
return -1; return -1;
FILE *f = NULL; FILE *f = NULL;
u32 ret = -1; u32 ret = -1;
bool found = false; bool found = false;
u32 i = 0; u32 i = 0;
char nandconfigPath[100]; char nandconfigPath[100];
snprintf(nandconfigPath, sizeof(nandconfigPath), "%s:/sneek/nandcfg.bin", DeviceHandler::GetDevicePrefix(nandpath)); snprintf(nandconfigPath, sizeof(nandconfigPath), "%s:/sneek/nandcfg.bin", DeviceHandler::GetDevicePrefix(nandpath));
// vWii neek2o - different filename but not the same format? // vWii neek2o - different filename but not the same format?
//if(isWiiU()) //if(isWiiU())
// snprintf(nandconfigPath, sizeof(nandconfigPath), "%s:/sneek/vwiincfg.bin", DeviceHandler::GetDevicePrefix(nandpath)); // snprintf(nandconfigPath, sizeof(nandconfigPath), "%s:/sneek/vwiincfg.bin", DeviceHandler::GetDevicePrefix(nandpath));
#ifdef DEBUG #ifdef DEBUG
gprintf("nandconfigPath : %s\n", nandconfigPath); gprintf("nandconfigPath : %s\n", nandconfigPath);
#endif #endif
// create the file if it doesn't exist // create the file if it doesn't exist
if(!CheckFile(nandconfigPath) || FileSize(nandconfigPath) < NANDCONFIG_HEADER_SIZE+1) if(!CheckFile(nandconfigPath) || FileSize(nandconfigPath) < NANDCONFIG_HEADER_SIZE+1)
{ {
u8* nandConfigHeader[NANDCONFIG_HEADER_SIZE]; u8* nandConfigHeader[NANDCONFIG_HEADER_SIZE];
memset(nandConfigHeader, 0, NANDCONFIG_HEADER_SIZE); memset(nandConfigHeader, 0, NANDCONFIG_HEADER_SIZE);
f = fopen(nandconfigPath, "wb"); f = fopen(nandconfigPath, "wb");
if(!f) if(!f)
{ {
gprintf("Failed creating file %s.\n", nandconfigPath); gprintf("Failed creating file %s.\n", nandconfigPath);
return -1; return -1;
} }
// create an empty header with 0 NAND // create an empty header with 0 NAND
fwrite(nandConfigHeader, 1, NANDCONFIG_HEADER_SIZE, f); fwrite(nandConfigHeader, 1, NANDCONFIG_HEADER_SIZE, f);
fclose(f); fclose(f);
} }
f = fopen(nandconfigPath, "rb"); f = fopen(nandconfigPath, "rb");
if(!f) if(!f)
{ {
gprintf("Failed loading file %s.\n", nandconfigPath); gprintf("Failed loading file %s.\n", nandconfigPath);
return -1; return -1;
} }
fseek(f , 0 , SEEK_END); fseek(f , 0 , SEEK_END);
u32 filesize = ftell(f); u32 filesize = ftell(f);
rewind(f); rewind(f);
/* Allocate memory */ /* Allocate memory */
NandConfig *nandCfg = (NandConfig *) MEM2_alloc(filesize); NandConfig *nandCfg = (NandConfig *) MEM2_alloc(filesize);
if (!nandCfg) if (!nandCfg)
{ {
fclose (f); fclose (f);
return -1; return -1;
} }
// Read the file // Read the file
ret = fread (nandCfg, 1, filesize, f); ret = fread (nandCfg, 1, filesize, f);
if(ret != filesize) if(ret != filesize)
{ {
gprintf("Failed loading file %s to Mem.\n", nandconfigPath); gprintf("Failed loading file %s to Mem.\n", nandconfigPath);
fclose (f); fclose (f);
MEM2_free(nandCfg); MEM2_free(nandCfg);
return -1; return -1;
} }
#ifdef DEBUG #ifdef DEBUG
hexdump(nandCfg, NANDCONFIG_HEADER_SIZE); hexdump(nandCfg, NANDCONFIG_HEADER_SIZE);
#endif #endif
// don't parse if wrong file // don't parse if wrong file
if(nandCfg->NandCnt > NANDCONFIG_MAXNAND || nandCfg->NandSel > nandCfg->NandCnt) // wrong header, delete file. if(nandCfg->NandCnt > NANDCONFIG_MAXNAND || nandCfg->NandSel > nandCfg->NandCnt) // wrong header, delete file.
{ {
fclose(f); fclose(f);
MEM2_free(nandCfg); MEM2_free(nandCfg);
RemoveFile(nandconfigPath); // delete corrupted file. RemoveFile(nandconfigPath); // delete corrupted file.
return -1; return -1;
} }
#ifdef DEBUG #ifdef DEBUG
// List found nands from the file // List found nands from the file
gprintf("NandCnt = %d\n", nandCfg->NandCnt); gprintf("NandCnt = %d\n", nandCfg->NandCnt);
gprintf("NandSel = %d\n", nandCfg->NandSel); gprintf("NandSel = %d\n", nandCfg->NandSel);
for( i = 0 ; i < nandCfg->NandCnt ; i++) for( i = 0 ; i < nandCfg->NandCnt ; i++)
{ {
gprintf("Path %d = %s %s\n", i, &nandCfg->Nands[i], strcmp((const char *)&nandCfg->Nands[i], neekNandPath) == 0 ? "found" : ""); gprintf("Path %d = %s %s\n", i, &nandCfg->Nands[i], strcmp((const char *)&nandCfg->Nands[i], neekNandPath) == 0 ? "found" : "");
} }
#endif #endif
for( i = 0 ; i < nandCfg->NandCnt ; i++) for( i = 0 ; i < nandCfg->NandCnt ; i++)
{ {
if(strcmp((const char *)&nandCfg->Nands[i], neekNandPath) == 0) if(strcmp((const char *)&nandCfg->Nands[i], neekNandPath) == 0)
{ {
found = true; found = true;
break; break;
} }
} }
if(found) // NAND path already present in nandcfg.bin if(found) // NAND path already present in nandcfg.bin
{ {
// set selected nand in header if different // set selected nand in header if different
if(nandCfg->NandSel != i) if(nandCfg->NandSel != i)
{ {
nandCfg->NandSel = i; nandCfg->NandSel = i;
nandCfg->Padding1 = i; // same value? nandCfg->Padding1 = i; // same value?
DCFlushRange(nandCfg, NANDCONFIG_HEADER_SIZE); DCFlushRange(nandCfg, NANDCONFIG_HEADER_SIZE);
#ifdef DEBUG #ifdef DEBUG
gprintf("new nandCfg->sel = %d", nandCfg->NandSel); gprintf("new nandCfg->sel = %d", nandCfg->NandSel);
hexdump(nandCfg, NANDCONFIG_HEADER_SIZE); hexdump(nandCfg, NANDCONFIG_HEADER_SIZE);
#endif #endif
freopen(nandconfigPath, "wb", f); freopen(nandconfigPath, "wb", f);
ret = fwrite(nandCfg, sizeof(char), filesize, f); // Write full file ret = fwrite(nandCfg, sizeof(char), filesize, f); // Write full file
} }
} }
else // new NAND path to nandcfg.bin else // new NAND path to nandcfg.bin
{ {
NandInfo * newNand = (NandInfo *) MEM2_alloc(sizeof(NandInfo)); NandInfo * newNand = (NandInfo *) MEM2_alloc(sizeof(NandInfo));
if(newNand) if(newNand)
{ {
memset(newNand, 0, sizeof(NandInfo)); memset(newNand, 0, sizeof(NandInfo));
snprintf(newNand->Path, sizeof(newNand->Path), neekNandPath); snprintf(newNand->Path, sizeof(newNand->Path), neekNandPath);
snprintf(newNand->Name, sizeof(newNand->Name), strlen(neekNandPath) == 0 ? "root" : strrchr(neekNandPath, '/')+1); snprintf(newNand->Name, sizeof(newNand->Name), strlen(neekNandPath) == 0 ? "root" : strrchr(neekNandPath, '/')+1);
snprintf(newNand->DiPath, sizeof(newNand->DiPath), "/sneek"); snprintf(newNand->DiPath, sizeof(newNand->DiPath), "/sneek");
DCFlushRange(newNand, sizeof(NandInfo)); DCFlushRange(newNand, sizeof(NandInfo));
#ifdef DEBUG #ifdef DEBUG
gprintf("new nandCfg"); gprintf("new nandCfg");
hexdump(newNand, sizeof(NandInfo)); hexdump(newNand, sizeof(NandInfo));
#endif #endif
nandCfg->NandCnt++; nandCfg->NandCnt++;
nandCfg->NandSel = ++i; nandCfg->NandSel = ++i;
// prevent NAND selection bigger than number of NANDs. // prevent NAND selection bigger than number of NANDs.
if(nandCfg->NandSel >= nandCfg->NandCnt) if(nandCfg->NandSel >= nandCfg->NandCnt)
{ {
nandCfg->NandSel = nandCfg->NandCnt -1; nandCfg->NandSel = nandCfg->NandCnt -1;
i--; i--;
} }
freopen(nandconfigPath, "wb", f); freopen(nandconfigPath, "wb", f);
ret = fwrite(nandCfg, sizeof(char), filesize, f); // Write full file ret = fwrite(nandCfg, sizeof(char), filesize, f); // Write full file
ret = fwrite(newNand,1,sizeof(NandInfo),f); // append new NANDInfo ret = fwrite(newNand,1,sizeof(NandInfo),f); // append new NANDInfo
if(ret != sizeof(NandInfo)) if(ret != sizeof(NandInfo))
gprintf("Writing new NAND info failed\n"); gprintf("Writing new NAND info failed\n");
MEM2_free(newNand); MEM2_free(newNand);
} }
} }
// verify the header is correctly written // verify the header is correctly written
freopen(nandconfigPath, "rb", f); freopen(nandconfigPath, "rb", f);
ret = fread (nandCfg, 1, NANDCONFIG_HEADER_SIZE, f); ret = fread (nandCfg, 1, NANDCONFIG_HEADER_SIZE, f);
if(ret != NANDCONFIG_HEADER_SIZE) if(ret != NANDCONFIG_HEADER_SIZE)
{ {
gprintf("Failed loading file %s to Mem.\n", nandconfigPath); gprintf("Failed loading file %s to Mem.\n", nandconfigPath);
fclose (f); fclose (f);
MEM2_free(nandCfg); MEM2_free(nandCfg);
return -1; return -1;
} }
ret = nandCfg->NandSel; ret = nandCfg->NandSel;
fclose (f); fclose (f);
MEM2_free(nandCfg); MEM2_free(nandCfg);
#ifdef DEBUG #ifdef DEBUG
gprintf("verify header:\n"); gprintf("verify header:\n");
hexdump(nandCfg, NANDCONFIG_HEADER_SIZE); hexdump(nandCfg, NANDCONFIG_HEADER_SIZE);
#endif #endif
if(ret == i) if(ret == i)
return ret ; return ret ;
return -1; return -1;
} }

View File

@ -1,88 +1,88 @@
/**************************************************************************** /****************************************************************************
* Copyright (C) 2015 Cyan * Copyright (C) 2015 Cyan
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#ifndef NEEK_CONFIG_H_ #ifndef NEEK_CONFIG_H_
#define NEEK_CONFIG_H_ #define NEEK_CONFIG_H_
#include <gctypes.h> #include <gctypes.h>
#define NEEK_MAGIC 0x666c6f77 // 'FLOW'. 0x47414d45 'GAME' autoboot disc? #define NEEK_MAGIC 0x666c6f77 // 'FLOW'. 0x47414d45 'GAME' autoboot disc?
#define NEEK_CONFIG_ADDRESS 0x81200000 #define NEEK_CONFIG_ADDRESS 0x81200000
typedef struct _NEEK_CFG typedef struct _NEEK_CFG
{ {
u32 magic; // always has to be 0x666c6f77 u32 magic; // always has to be 0x666c6f77
u64 titleid; // the full path of the NAND title to boot (both folder names) u64 titleid; // the full path of the NAND title to boot (both folder names)
u32 config; // see below u32 config; // see below
u64 returnto; // same as titleid above u64 returnto; // same as titleid above
u32 gameid; // game for DI to autoboot use 4-digit game id u32 gameid; // game for DI to autoboot use 4-digit game id
u32 gamemagic; // set to 0x5d1c9ea3 for Wii game, 0xC2339F3D for gamecube games u32 gamemagic; // set to 0x5d1c9ea3 for Wii game, 0xC2339F3D for gamecube games
char dipath[256]; // string specifying path DI should use to find games (/wbfs/ or usb1/wbfs?) char dipath[256]; // string specifying path DI should use to find games (/wbfs/ or usb1/wbfs?)
char nandpath[256]; // string specifying where the emuNAND is stored if it's not in the normal place. (/nands/ or usb1/nands/ ?) char nandpath[256]; // string specifying where the emuNAND is stored if it's not in the normal place. (/nands/ or usb1/nands/ ?)
} NEEK_CFG; } NEEK_CFG;
enum neekconfig enum neekconfig
{ {
NCON_EXT_DI_PATH = (1<<0), // 1 if you're using/specifying dipath NCON_EXT_DI_PATH = (1<<0), // 1 if you're using/specifying dipath
NCON_EXT_NAND_PATH = (1<<1), // 1 if you're using/specifying nandpath NCON_EXT_NAND_PATH = (1<<1), // 1 if you're using/specifying nandpath
NCON_HIDE_EXT_PATH = (1<<2), // 1 to have it not SAVE the last used custom path? NCON_HIDE_EXT_PATH = (1<<2), // 1 to have it not SAVE the last used custom path?
NCON_EXT_RETURN_TO = (1<<3), // 1 if you're using returnto NCON_EXT_RETURN_TO = (1<<3), // 1 if you're using returnto
NCON_EXT_BOOT_GAME = (1<<4), // 1 if you're using gameid NCON_EXT_BOOT_GAME = (1<<4), // 1 if you're using gameid
}; };
#define NANDCONFIG_MAXNAND 8 #define NANDCONFIG_MAXNAND 8
#define NANDCONFIG_HEADER_SIZE 0x10 #define NANDCONFIG_HEADER_SIZE 0x10
#define NANDCONFIG_NANDINFO_SIZE 0x100 #define NANDCONFIG_NANDINFO_SIZE 0x100
typedef struct typedef struct
{ {
char Path[128]; char Path[128];
char Name[64]; char Name[64];
char DiPath[64]; char DiPath[64];
} NandInfo; } NandInfo;
typedef struct _NandConfig typedef struct _NandConfig
{ {
u32 NandCnt; u32 NandCnt;
u32 NandSel; u32 NandSel;
u32 Padding1; u32 Padding1;
u32 Padding2; u32 Padding2;
NandInfo Nands[]; NandInfo Nands[];
} NandConfig; } NandConfig;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
#endif #endif
bool neekLoadKernel(const char* nandpath); bool neekLoadKernel(const char* nandpath);
int neekBoot(void); int neekBoot(void);
int neekIsNeek2o(const char* nandpath); int neekIsNeek2o(const char* nandpath);
int neekPathFormat(char* nandpath_out, const char* nandpath_in, u32 len); int neekPathFormat(char* nandpath_out, const char* nandpath_in, u32 len);
bool neek2oSetBootSettings(NEEK_CFG* neek_config, u64 TitleID, u32 Magic, u64 returnto, const char* nandpath ); bool neek2oSetBootSettings(NEEK_CFG* neek_config, u64 TitleID, u32 Magic, u64 returnto, const char* nandpath );
int neek2oSetNAND(const char* nandpath); int neek2oSetNAND(const char* nandpath);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif