*Fixed booting games from FAT/NTFS (thx r-win)

*Fixed Toy Story 3 boot bug
*Changed IOS limits. Now allowing all IOSs from 200-255 to support more Waninkoko cIOS slots. You will get a warning if you don't have an IOS installed and try to choose it.
This commit is contained in:
dimok321 2010-11-07 12:16:34 +00:00
parent 33ce3e48ab
commit 64744ce20d
19 changed files with 585 additions and 603 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
#include "menu/menus.h" #include "menu/menus.h"
#include "mload/mload.h" #include "mload/mload.h"
#include "mload/mload_modules.h" #include "mload/mload_modules.h"
#include "system/IosLoader.h"
#include "usbloader/disc.h" #include "usbloader/disc.h"
#include "usbloader/apploader.h" #include "usbloader/apploader.h"
#include "usbloader/wdvd.h" #include "usbloader/wdvd.h"
@ -137,7 +138,7 @@ int BootGame(const char * gameID)
if(iosChoice != IOS_GetVersion()) if(iosChoice != IOS_GetVersion())
{ {
gprintf("Reloading into cIOS: %i\n", iosChoice); gprintf("Reloading into game cIOS: %i...\n", iosChoice);
IosLoader::LoadGameCios(iosChoice); IosLoader::LoadGameCios(iosChoice);
if(MountGamePartition(false) < 0) if(MountGamePartition(false) < 0)
return -1; return -1;
@ -149,10 +150,6 @@ int BootGame(const char * gameID)
ret = get_frag_list(header->id); ret = get_frag_list(header->id);
gprintf("%d\n", ret); gprintf("%d\n", ret);
gprintf("Setting fragment list...");
ret = set_frag_list(header->id);
gprintf("%d\n", ret);
ret = Disc_SetUSB(header->id); ret = Disc_SetUSB(header->id);
if (ret < 0) Sys_BackToLoader(); if (ret < 0) Sys_BackToLoader();
gprintf("\tUSB set to game\n"); gprintf("\tUSB set to game\n");
@ -162,9 +159,12 @@ int BootGame(const char * gameID)
gprintf("\tUSB not set, loading DVD\n"); gprintf("\tUSB not set, loading DVD\n");
} }
gprintf("Disc_Open()...");
ret = Disc_Open(); ret = Disc_Open();
gprintf("%d\n", ret);
if (ret < 0) Sys_BackToLoader(); if (ret < 0)
Sys_BackToLoader();
if (dvdheader) delete dvdheader; if (dvdheader) delete dvdheader;
@ -172,7 +172,7 @@ int BootGame(const char * gameID)
ret = do_bca_code(header->id); ret = do_bca_code(header->id);
gprintf("%d\n", ret); gprintf("%d\n", ret);
if (reloadblock == ON && Sys_IsHermes()) if (reloadblock == ON && IosLoader::IsHermesIOS())
{ {
enable_ES_ioctlv_vector(); enable_ES_ioctlv_vector();
if (load_from_fs == PART_FS_WBFS) if (load_from_fs == PART_FS_WBFS)

View File

@ -123,7 +123,6 @@ const u8 *LoadBannerSound(const u8 *discid, u32 *size)
{ {
if (!discid) return NULL; if (!discid) return NULL;
Disc_SetUSB(NULL);
wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) discid); wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) discid);
if (!disc) if (!disc)
{ {

View File

@ -44,7 +44,6 @@ int DiscBrowse(struct discHdr * header, char * alternatedname, int alternatednam
HaltGui(); HaltGui();
Disc_SetUSB(NULL);
wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) header->id); wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) header->id);
if (!disc) if (!disc)
{ {

View File

@ -64,18 +64,6 @@ static const char *opts_partitions[3] = { trNOOP( "Game partition" ), trNOOP( "A
static const char *opts_installdir[INSTALL_TO_MAX] = { trNOOP( "None" ), trNOOP( "GAMEID_Gamename" ), static const char *opts_installdir[INSTALL_TO_MAX] = { trNOOP( "None" ), trNOOP( "GAMEID_Gamename" ),
trNOOP( "Gamename [GAMEID]" ) }; trNOOP( "Gamename [GAMEID]" ) };
bool IsValidPartition(int fs_type, int cios)
{
if (cios == 249 || cios == 250)
{
return fs_type == FS_TYPE_WBFS;
}
else
{
return fs_type == FS_TYPE_WBFS || fs_type == FS_TYPE_FAT32 || fs_type == FS_TYPE_NTFS;
}
}
/**************************************************************************** /****************************************************************************
* MenuSettings * MenuSettings
***************************************************************************/ ***************************************************************************/
@ -1008,26 +996,22 @@ int MenuSettings()
if (firstRun) options2.SetName(Idx, "%s", tr( "Boot/Standard" )); if (firstRun) options2.SetName(Idx, "%s", tr( "Boot/Standard" ));
if (ret == Idx && Settings.godmode == 1) if (ret == Idx && Settings.godmode == 1)
{ {
switch (Settings.cios) char entered[4];
snprintf(entered, sizeof(entered), "%i", Settings.cios);
if(OnScreenKeyboard(entered, sizeof(entered), 0))
{ {
case 222: Settings.cios = atoi(entered);
Settings.cios = 223; if(Settings.cios < 200) Settings.cios = 200;
break; else if(Settings.cios > 255) Settings.cios = 255;
case 223:
Settings.cios = 224; if(NandTitles.IndexOf(TITLE_ID(1, Settings.cios)) < 0)
break; {
case 224: WindowPrompt(tr("Warning:"), tr("This IOS was not found on the titles list. If you are sure you have it installed than ignore this warning."), tr("OK"));
Settings.cios = 249; }
break; else if(Settings.cios == 254)
case 249: {
Settings.cios = 250; WindowPrompt(tr("Warning:"), tr("This IOS is the BootMii ios. If you are sure it is not BootMii and you have something else installed there than ignore this warning."), tr("OK"));
break; }
case 250:
Settings.cios = 222;
break;
default:
Settings.cios = 222;
break;
} }
} }
if (Settings.godmode == 1) if (Settings.godmode == 1)
@ -1041,12 +1025,12 @@ int MenuSettings()
if (ret == Idx) if (ret == Idx)
{ {
// Select the next valid partition, even if that's the same one // Select the next valid partition, even if that's the same one
int fs_type = partitions.pinfo[Settings.partition].fs_type;
do do
{ {
Settings.partition = Settings.partition + 1 == partitions.num ? 0 Settings.partition = (Settings.partition + 1) % partitions.num;
: Settings.partition + 1; fs_type = partitions.pinfo[Settings.partition].fs_type;
} while (!IsValidPartition(partitions.pinfo[Settings.partition].fs_type, } while (!(fs_type == FS_TYPE_WBFS || fs_type == FS_TYPE_FAT32 || fs_type == FS_TYPE_NTFS));
Settings.cios));
} }
PartInfo pInfo = partitions.pinfo[Settings.partition]; PartInfo pInfo = partitions.pinfo[Settings.partition];
@ -2622,26 +2606,22 @@ int MenuGameSettings(struct discHdr * header)
if (firstRun) options2.SetName(Idx, "IOS"); if (firstRun) options2.SetName(Idx, "IOS");
if (ret == Idx) if (ret == Idx)
{ {
switch (game_cfg.ios) char entered[4];
snprintf(entered, sizeof(entered), "%i", Settings.cios);
if(OnScreenKeyboard(entered, sizeof(entered), 0))
{ {
case 222: Settings.cios = atoi(entered);
game_cfg.ios = 223; if(Settings.cios < 200) Settings.cios = 200;
break; else if(Settings.cios > 255) Settings.cios = 255;
case 223:
game_cfg.ios = 224; if(NandTitles.IndexOf(TITLE_ID(1, Settings.cios)) < 0)
break; {
case 224: WindowPrompt(tr("Warning:"), tr("This IOS was not found on the titles list. If you are sure you have it installed than ignore this warning."), tr("OK"));
game_cfg.ios = 249; }
break; else if(Settings.cios == 254)
case 249: {
game_cfg.ios = 250; WindowPrompt(tr("Warning:"), tr("This IOS is the BootMii ios. If you are sure it is not BootMii and you have something else installed there than ignore this warning."), tr("OK"));
break; }
case 250:
game_cfg.ios = 222;
break;
default:
game_cfg.ios = 222;
break;
} }
} }
options2.SetValue(Idx, "IOS %i", game_cfg.ios); options2.SetValue(Idx, "IOS %i", game_cfg.ios);

View File

@ -162,13 +162,6 @@ void Sys_BackToLoader(void)
Sys_LoadMenu(); Sys_LoadMenu();
} }
bool Sys_IsHermes()
{
int ios = IOS_GetVersion();
return ios == 222 || ios == 223 || ios == 224;
}
void ScreenShot() void ScreenShot()
{ {
time_t rawtime; time_t rawtime;

View File

@ -13,7 +13,6 @@ void Sys_ShutdownToIdel(void);
void Sys_ShutdownToStandby(void); void Sys_ShutdownToStandby(void);
void Sys_LoadMenu(void); void Sys_LoadMenu(void);
void Sys_BackToLoader(void); void Sys_BackToLoader(void);
bool Sys_IsHermes();
void ScreenShot(); void ScreenShot();
#endif #endif

View File

@ -17,11 +17,31 @@
#include "mload/modules/ehcmodule_5.h" #include "mload/modules/ehcmodule_5.h"
#include "mload/modules/dip_plugin_249.h" #include "mload/modules/dip_plugin_249.h"
#include "mload/modules/odip_frag.h" #include "mload/modules/odip_frag.h"
#include "gecko.h"
/****************************************************************************** /******************************************************************************
* Public Methods: * Public Methods:
******************************************************************************/ ******************************************************************************/
/*
* Check if the ios passed is a Hermes ios.
*/
bool IosLoader::IsHermesIOS(s32 ios)
{
return (ios == 222 || ios == 223 || ios == 224 || ios == 202);
}
/*
* Check if the ios passed is a Waninkoko ios.
*/
bool IosLoader::IsWaninkokoIOS(s32 ios)
{
if(ios < 200 || ios > 255)
return false;
return !IsHermesIOS(ios);
}
/* /*
* Loads CIOS (If possible the one from the settings file). * 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. * @return 0 if a cios has been successfully loaded. Else a value below 0 is returned.
@ -102,34 +122,21 @@ s32 IosLoader::LoadGameCios(s32 ios)
*/ */
s32 IosLoader::ReloadIosSafe(s32 ios) s32 IosLoader::ReloadIosSafe(s32 ios)
{ {
switch (ios) if(IsHermesIOS(ios))
{ {
case 222: s32 iosRev = NandTitles.VersionOf(TITLE_ID(1, ios));
{ if((iosRev < 2 || iosRev > 5) && iosRev != 65535)
s32 ios222rev = NandTitles.VersionOf(0x1000000deULL); return -11;
if (ios222rev == 4 || ios222rev == 5 || ios222rev == 65535) break; }
return -2; else if(IsWaninkokoIOS(ios))
} {
case 223: s32 iosRev = NandTitles.VersionOf(TITLE_ID(1, ios));
{ if(iosRev < 9 || iosRev > 30) //let's see if Waninkoko actually gets to 30
s32 ios223rev = NandTitles.VersionOf(0x1000000dfULL); return -22;
if (ios223rev == 4 || ios223rev == 5 || ios223rev == 65535) break; }
return -2; else
} {
case 249: return -33;
{
s32 ios249rev = NandTitles.VersionOf(0x1000000f9ULL);
if (ios249rev < 9 || ios249rev == 65280) return -2;
break;
}
case 250:
{
s32 ios250rev = NandTitles.VersionOf(0x1000000faULL);
if (ios250rev < 9 || ios250rev == 65280) return -2;
break;
}
default:
return -3;
} }
s32 r = IOS_ReloadIOS(ios); s32 r = IOS_ReloadIOS(ios);
@ -146,7 +153,7 @@ s32 IosLoader::ReloadIosSafe(s32 ios)
void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev) void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
{ {
//! Hermes IOS //! Hermes IOS
if(ios == 222 || ios == 223 || ios == 224) if(IsHermesIOS(ios))
{ {
const u8 * ech_module = NULL; const u8 * ech_module = NULL;
int ehc_module_size = 0; int ehc_module_size = 0;
@ -160,18 +167,21 @@ void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
ehc_module_size = ehcmodule_2_size; ehc_module_size = ehcmodule_2_size;
dip_plugin = dip_plugin_2; dip_plugin = dip_plugin_2;
dip_plugin_size = dip_plugin_2_size; dip_plugin_size = dip_plugin_2_size;
gprintf("Loading ehc and dip module v2\n");
break; break;
case 3: case 3:
ech_module = ehcmodule_3; ech_module = ehcmodule_3;
ehc_module_size = ehcmodule_3_size; ehc_module_size = ehcmodule_3_size;
dip_plugin = dip_plugin_3; dip_plugin = dip_plugin_3;
dip_plugin_size = dip_plugin_3_size; dip_plugin_size = dip_plugin_3_size;
gprintf("Loading ehc and dip module v3\n");
break; break;
default: default:
ech_module = ehcmodule_5; ech_module = ehcmodule_5;
ehc_module_size = ehcmodule_5_size; ehc_module_size = ehcmodule_5_size;
dip_plugin = odip_frag; dip_plugin = odip_frag;
dip_plugin_size = odip_frag_size; dip_plugin_size = odip_frag_size;
gprintf("Loading ehc v5 and opendip module\n");
break; break;
} }
@ -180,18 +190,20 @@ void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
{ {
ehc_cfg += 12; ehc_cfg += 12;
ehc_cfg[0] = 0; // USB Port 0 ehc_cfg[0] = 0; // USB Port 0
gprintf("Patched ehc module to use usb port 0.\n");
} }
load_modules(ech_module, ehc_module_size, dip_plugin, dip_plugin_size); load_modules(ech_module, ehc_module_size, dip_plugin, dip_plugin_size);
} }
//! Waninkoko IOS //! Waninkoko IOS
else if(ios == 249 || ios == 250) else if(IsWaninkokoIOS(ios))
{ {
if(ios_rev >= 18) if(ios_rev >= 18)
{ {
if(mload_init() < 0) if(mload_init() < 0)
return; return;
gprintf("Loading dip module for Waninkoko's cios\n");
mload_module((u8 *) dip_plugin_249, dip_plugin_249_size); mload_module((u8 *) dip_plugin_249, dip_plugin_249_size);
mload_close(); mload_close();
} }

View File

@ -1,7 +1,7 @@
#ifndef _IOSLOADER_H_ #ifndef _IOSLOADER_H_
#define _IOSLOADER_H_ #define _IOSLOADER_H_
#include <gctypes.h> #include <gccore.h>
class IosLoader class IosLoader
{ {
@ -9,6 +9,8 @@ class IosLoader
static s32 LoadAppCios(); static s32 LoadAppCios();
static s32 LoadGameCios(s32 ios); static s32 LoadGameCios(s32 ios);
static s32 ReloadIosSafe(s32 ios); static s32 ReloadIosSafe(s32 ios);
static bool IsHermesIOS(s32 ios = IOS_GetVersion());
static bool IsWaninkokoIOS(s32 ios = IOS_GetVersion());
private: private:
static void LoadIOSModules(s32 ios, s32 ios_rev); static void LoadIOSModules(s32 ios, s32 ios_rev);
}; };

View File

@ -12,6 +12,7 @@
#include "disc.h" #include "disc.h"
#include "video.h" #include "video.h"
#include "wdvd.h" #include "wdvd.h"
#include "frag.h"
#include "alternatedol.h" #include "alternatedol.h"
#include "memory/memory.h" #include "memory/memory.h"
#include "wbfs.h" #include "wbfs.h"
@ -241,15 +242,10 @@ s32 Disc_Wait(void)
s32 Disc_SetUSB(const u8 *id) s32 Disc_SetUSB(const u8 *id)
{ {
u32 part = 0; if (wbfs_part_fs)
if (wbfs_part_fs) return set_frag_list((u8 *) id);
{
part = wbfs_part_lba; u32 part = wbfs_part_idx ? wbfs_part_idx - 1 : 0;
}
else
{
part = wbfs_part_idx ? wbfs_part_idx - 1 : 0;
}
/* Set USB mode */ /* Set USB mode */
return WDVD_SetUSBMode((u8 *) id, part); return WDVD_SetUSBMode((u8 *) id, part);
@ -293,11 +289,10 @@ s32 Disc_JumpToEntrypoint(u8 videoselected, bool enablecheat)
gprintf("USB Loader GX is done.\n"); gprintf("USB Loader GX is done.\n");
/* Shutdown IOS subsystems */ /* Shutdown IOS subsystems */
// fix for PeppaPig (from WiiFlow) extern void __exception_closeall();
u8 temp_data[4]; u32 level = IRQ_Disable();
memcpy(temp_data, (u8 *) 0x800000F4, 4); __IOS_ShutdownSubsystems();
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0); __exception_closeall();
memcpy((u8 *) 0x800000F4, temp_data, 4);
if (enablecheat) if (enablecheat)
{ {
@ -323,6 +318,8 @@ s32 Disc_JumpToEntrypoint(u8 videoselected, bool enablecheat)
); );
} }
IRQ_Restore(level);
return 0; return 0;
} }

View File

@ -1,180 +1,280 @@
#include <ogcsys.h> #include <ogcsys.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "fatmounter.h" #include "libs/libntfs/ntfs.h"
#include "libs/libntfs/ntfs.h" #include "libs/libwbfs/libwbfs.h"
#include "libs/libwbfs/libwbfs.h"
#include "wbfs.h" #include "usbloader/wbfs.h"
#include "usbstorage2.h" #include "usbloader/wdvd.h"
#include "frag.h" #include "usbloader/usbstorage2.h"
#include "utils.h" #include "frag.h"
#include "sys.h"
FragList *frag_list = NULL; #include "gecko.h"
void frag_init(FragList *ff, int maxnum) #define SAFE_FREE(x) if(x) { free(x); x = NULL; }
{
memset(ff, 0, sizeof(Fragment) * (maxnum + 1)); extern sec_t fs_ntfs_sec;
ff->maxnum = maxnum;
} int _FAT_get_fragments (const char *path, _frag_append_t append_fragment, void *callback_data);
int frag_append(FragList *ff, u32 offset, u32 sector, u32 count) static FragList *frag_list = NULL;
{
int n; void frag_init(FragList *ff, int maxnum)
if (count) {
{ memset(ff, 0, sizeof(Fragment) * (maxnum+1));
n = ff->num - 1; ff->maxnum = maxnum;
if (ff->num > 0 && ff->frag[n].offset + ff->frag[n].count == offset && ff->frag[n].sector + ff->frag[n].count }
== sector)
{ void frag_dump(FragList *ff)
// merge {
ff->frag[n].count += count; int i;
} gprintf("frag list: %d %d 0x%x\n", ff->num, ff->size, ff->size);
else for (i=0; i<ff->num; i++) {
{ if (i>10) {
// add gprintf("...\n");
if (ff->num >= ff->maxnum) break;
{ }
// too many fragments gprintf(" %d : %8x %8x %8x\n", i,
return -500; ff->frag[i].offset,
} ff->frag[i].count,
n = ff->num; ff->frag[i].sector);
ff->frag[n].offset = offset; }
ff->frag[n].sector = sector; }
ff->frag[n].count = count;
ff->num++; int frag_append(FragList *ff, u32 offset, u32 sector, u32 count)
} {
} int n;
ff->size = offset + count; if (count) {
return 0; n = ff->num - 1;
} if (ff->num > 0
&& ff->frag[n].offset + ff->frag[n].count == offset
int _frag_append(void *ff, u32 offset, u32 sector, u32 count) && ff->frag[n].sector + ff->frag[n].count == sector)
{ {
return frag_append(ff, offset, sector, count); // merge
} ff->frag[n].count += count;
}
int frag_concat(FragList *ff, FragList *src) else
{ {
int i, ret; // add
u32 size = ff->size; if (ff->num >= ff->maxnum) {
//printf("concat: %d %d <- %d %d\n", ff->num, ff->size, src->num, src->size); // too many fragments
for (i = 0; i < src->num; i++) return -500;
{ }
ret = frag_append(ff, size + src->frag[i].offset, src->frag[i].sector, src->frag[i].count); n = ff->num;
if (ret) return ret; ff->frag[n].offset = offset;
} ff->frag[n].sector = sector;
ff->size = size + src->size; ff->frag[n].count = count;
//printf("concat: -> %d %d\n", ff->num, ff->size); ff->num++;
return 0; }
} }
ff->size = offset + count;
// in case a sparse block is requested, return 0;
// the returned poffset might not be equal to requested offset }
// the difference should be filled with 0
int frag_get(FragList *ff, u32 offset, u32 count, u32 *poffset, u32 *psector, u32 *pcount) int _frag_append(void *ff, u32 offset, u32 sector, u32 count)
{ {
int i; return frag_append(ff, offset, sector, count);
u32 delta; }
//printf("frag_get(%u %u)\n", offset, count);
for (i = 0; i < ff->num; i++) int frag_concat(FragList *ff, FragList *src)
{ {
if (ff->frag[i].offset <= offset && ff->frag[i].offset + ff->frag[i].count > offset) int i, ret;
{ u32 size = ff->size;
delta = offset - ff->frag[i].offset; //printf("concat: %d %d <- %d %d\n", ff->num, ff->size, src->num, src->size);
*poffset = offset; for (i=0; i<src->num; i++) {
*psector = ff->frag[i].sector + delta; ret = frag_append(ff, size + src->frag[i].offset,
*pcount = ff->frag[i].count - delta; src->frag[i].sector, src->frag[i].count);
if (*pcount > count) *pcount = count; if (ret) return ret;
goto out; }
} ff->size = size + src->size;
if (ff->frag[i].offset > offset && ff->frag[i].offset < offset + count) //printf("concat: -> %d %d\n", ff->num, ff->size);
{ return 0;
delta = ff->frag[i].offset - offset; }
*poffset = ff->frag[i].offset;
*psector = ff->frag[i].sector; // in case a sparse block is requested,
*pcount = ff->frag[i].count; // the returned poffset might not be equal to requested offset
count -= delta; // the difference should be filled with 0
if (*pcount > count) *pcount = count; int frag_get(FragList *ff, u32 offset, u32 count,
goto out; u32 *poffset, u32 *psector, u32 *pcount)
} {
} int i;
// not found u32 delta;
if (offset + count > ff->size) //printf("frag_get(%u %u)\n", offset, count);
{ for (i=0; i<ff->num; i++) {
// error: out of range! if (ff->frag[i].offset <= offset
return -1; && ff->frag[i].offset + ff->frag[i].count > offset)
} {
// if inside range, then it must be just sparse, zero filled delta = offset - ff->frag[i].offset;
// return empty block at the end of requested *poffset = offset;
*poffset = offset + count; *psector = ff->frag[i].sector + delta;
*psector = 0; *pcount = ff->frag[i].count - delta;
*pcount = 0; if (*pcount > count) *pcount = count;
out: goto out;
//printf("=>(%u %u %u)\n", *poffset, *psector, *pcount); }
return 0; if (ff->frag[i].offset > offset
} && ff->frag[i].offset < offset + count)
{
int frag_remap(FragList *ff, FragList *log, FragList *phy) delta = ff->frag[i].offset - offset;
{ *poffset = ff->frag[i].offset;
int i; *psector = ff->frag[i].sector;
int ret; *pcount = ff->frag[i].count;
u32 offset; count -= delta;
u32 sector; if (*pcount > count) *pcount = count;
u32 count; goto out;
u32 delta; }
for (i = 0; i < log->num; i++) }
{ // not found
delta = 0; if (offset + count > ff->size) {
count = 0; // error: out of range!
do return -1;
{ }
ret = frag_get(phy, log->frag[i].sector + delta + count, log->frag[i].count - delta - count, &offset, // if inside range, then it must be just sparse, zero filled
&sector, &count); // return empty block at the end of requested
if (ret) return ret; // error *poffset = offset + count;
delta = offset - log->frag[i].sector; *psector = 0;
ret = frag_append(ff, log->frag[i].offset + delta, sector, count); *pcount = 0;
if (ret) return ret; // error out:
} while (count + delta < log->frag[i].count); //printf("=>(%u %u %u)\n", *poffset, *psector, *pcount);
} return 0;
return 0; }
}
int frag_remap(FragList *ff, FragList *log, FragList *phy)
int get_frag_list(u8 *id) {
{ int i;
return WBFS_GetFragList(id); int ret;
} u32 offset;
u32 sector;
int set_frag_list(u8 *id) u32 count;
{ u32 delta;
if (wbfs_part_fs == PART_FS_WBFS) return 0; for (i=0; i<log->num; i++) {
if (frag_list == NULL) delta = 0;
{ count = 0;
if (wbfs_part_fs == PART_FS_FAT) do {
{ ret = frag_get(phy,
// fall back to old fat method log->frag[i].sector + delta + count,
// printf("FAT: fallback to old method\n"); log->frag[i].count - delta - count,
return 0; &offset, &sector, &count);
} if (ret) return ret; // error
// ntfs has no fallback, return error delta = offset - log->frag[i].sector;
return -1; ret = frag_append(ff, log->frag[i].offset + delta, sector, count);
} if (ret) return ret; // error
} while (count + delta < log->frag[i].count);
// (+1 for header which is same size as fragment) }
int size = sizeof(Fragment) * (frag_list->num + 1); return 0;
int ret = USBStorage_WBFS_SetFragList(frag_list, size); }
if (ret)
{ int get_frag_list_for_file(char *fname, u8 *id)
// printf("set_frag: %d\n", ret); {
return ret; char fname1[1024];
} struct stat st;
FragList *fs = NULL;
// verify id matches FragList *fa = NULL;
char discid[8]; FragList *fw = NULL;
memset(discid, 0, sizeof(discid)); int ret;
ret = USBStorage_WBFS_Read(0, 6, discid); int i, j;
return 0; int is_wbfs = 0;
} int ret_val = -1;
if (strcasecmp(strrchr(fname,'.'), ".wbfs") == 0) {
is_wbfs = 1;
}
fs = malloc(sizeof(FragList));
fa = malloc(sizeof(FragList));
fw = malloc(sizeof(FragList));
frag_init(fa, MAX_FRAG);
for (i=0; i<10; i++) {
frag_init(fs, MAX_FRAG);
if (i > 0) {
fname[strlen(fname)-1] = '0' + i;
if (stat(fname, &st) == -1) break;
}
strcpy(fname1, fname);
if (wbfs_part_fs == PART_FS_FAT) {
ret = _FAT_get_fragments(fname, &_frag_append, fs);
if (ret) {
// don't return failure, let it fallback to old method
//ret_val = ret;
ret_val = 0;
goto out;
}
} else if (wbfs_part_fs == PART_FS_NTFS) {
ret = _NTFS_get_fragments(fname, &_frag_append, fs);
if (ret) {
ret_val = ret;
goto out;
}
// offset to start of partition
for (j=0; j<fs->num; j++) {
fs->frag[j].sector += fs_ntfs_sec;
}
}
frag_concat(fa, fs);
}
frag_list = malloc(sizeof(FragList));
frag_init(frag_list, MAX_FRAG);
if (is_wbfs) {
// if wbfs file format, remap.
wbfs_disc_t *d = WBFS_OpenDisc(id);
if (!d) { ret_val = -4; goto out; }
frag_init(fw, MAX_FRAG);
ret = wbfs_get_fragments(d, &_frag_append, fw);
if (ret) { ret_val = -5; goto out; }
WBFS_CloseDisc(d);
// DEBUG: frag_list->num = MAX_FRAG-10; // stress test
ret = frag_remap(frag_list, fw, fa);
if (ret) { ret_val = -6; goto out; }
} else {
// .iso does not need remap just copy
memcpy(frag_list, fa, sizeof(FragList));
}
ret_val = 0;
out:
if (ret_val) {
// error
SAFE_FREE(frag_list);
}
SAFE_FREE(fs);
SAFE_FREE(fa);
SAFE_FREE(fw);
return ret_val;
}
int get_frag_list(u8 *id)
{
return WBFS_GetFragList(id);
}
int set_frag_list(u8 *id)
{
if (wbfs_part_fs == PART_FS_WBFS) return 1;
if (frag_list == NULL) {
return -2;
}
// (+1 for header which is same size as fragment)
int size = sizeof(Fragment) * (frag_list->num + 1);
int ret;
DCFlushRange(frag_list, size);
gprintf("Calling WDVD_SetFragList, frag list size %d\n", size);
ret = WDVD_SetFragList(wbfsDev, frag_list, size);
if (ret) {
return ret;
}
// verify id matches
char discid[8];
memset(discid, 0, sizeof(discid));
ret = WDVD_UnencryptedRead(discid, 8, 0);
gprintf("Reading ID after setting fraglist: %s (expected: %s)\n", discid, id);
return (strncasecmp((char *) id, discid, 6) != 0) ? -3 : 0;
}

View File

@ -1,50 +1,53 @@
// worst case wbfs fragmentation scenario:
// 9GB (dual layer) / 2mb (wbfs sector size) = 4608 // worst case wbfs fragmentation scenario:
#define MAX_FRAG 20000 // 9GB (dual layer) / 2mb (wbfs sector size) = 4608
// max that ehcmodule_frag will allow at the moment is about: #define MAX_FRAG 20000
// 40000/4/3-1 = 21844 // max that ehcmodule_frag will allow at the moment is about:
// 40000/4/3-1 = 21844
#ifdef __cplusplus
extern "C" #ifdef __cplusplus
{ extern "C" {
#endif #endif
#include "libs/libwbfs/libwbfs.h" #include "libs/libwbfs/libwbfs.h"
typedef struct typedef struct
{ {
u32 offset; // file offset, in sectors unit u32 offset; // file offset, in sectors unit
u32 sector; u32 sector;
u32 count; u32 count;
} Fragment; } Fragment;
typedef struct typedef struct
{ {
u32 size; // num sectors u32 size; // num sectors
u32 num; // num fragments u32 num; // num fragments
u32 maxnum; u32 maxnum;
Fragment frag[MAX_FRAG]; Fragment frag[MAX_FRAG];
} FragList; } FragList;
typedef int (*frag_append_t)(void *ff, u32 offset, u32 sector, u32 count); typedef int (*frag_append_t)(void *ff, u32 offset, u32 sector, u32 count);
int _FAT_get_fragments(const char *path, _frag_append_t append_fragment, void *callback_data); int _FAT_get_fragments (const char *path, _frag_append_t append_fragment, void *callback_data);
void frag_init(FragList *ff, int maxnum); void frag_init(FragList *ff, int maxnum);
int frag_append(FragList *ff, u32 offset, u32 sector, u32 count); void frag_dump(FragList *ff);
int _frag_append(void *ff, u32 offset, u32 sector, u32 count); int frag_append(FragList *ff, u32 offset, u32 sector, u32 count);
int frag_concat(FragList *ff, FragList *src); int _frag_append(void *ff, u32 offset, u32 sector, u32 count);
int frag_concat(FragList *ff, FragList *src);
// in case a sparse block is requested,
// the returned poffset might not be equal to requested offset // in case a sparse block is requested,
// the difference should be filled with 0 // the returned poffset might not be equal to requested offset
int frag_get(FragList *ff, u32 offset, u32 count, u32 *poffset, u32 *psector, u32 *pcount); // the difference should be filled with 0
int frag_get(FragList *ff, u32 offset, u32 count,
int frag_remap(FragList *ff, FragList *log, FragList *phy); u32 *poffset, u32 *psector, u32 *pcount);
int get_frag_list(u8 *id); int frag_remap(FragList *ff, FragList *log, FragList *phy);
int set_frag_list(u8 *id);
int get_frag_list_for_file(char *fname, u8 *id);
#ifdef __cplusplus int get_frag_list(u8 *id);
} int set_frag_list(u8 *id);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -137,15 +137,6 @@ bool Wbfs::Mounted()
return hdd == NULL; return hdd == NULL;
} }
int Wbfs::GetFragList(u8 *id)
{
return 0;
}
int Wbfs::GetFragList(char *filename, _frag_append_t append_fragment, FragList *)
{
return 0;
}
bool Wbfs::ShowFreeSpace(void) bool Wbfs::ShowFreeSpace(void)
{ {

View File

@ -1,54 +1,53 @@
#ifndef _H #ifndef _H
#define _H #define _H
#include "libs/libwbfs/libwbfs.h" #include "libs/libwbfs/libwbfs.h"
#include "usbloader/utils.h" #include "usbloader/utils.h"
#include "usbloader/frag.h" #include "usbloader/frag.h"
class Wbfs class Wbfs
{ {
public: public:
Wbfs(u32, u32, u32); Wbfs(u32, u32, u32);
void GetProgressValue(s32 * d, s32 * m); void GetProgressValue(s32 * d, s32 * m);
static s32 Init(u32); static s32 Init(u32);
void Close(); void Close();
s32 CheckGame(u8 *); s32 CheckGame(u8 *);
s32 GameSize(u8 *, f32 *); s32 GameSize(u8 *, f32 *);
wbfs_t *GetHddInfo(void); wbfs_t *GetHddInfo(void);
bool Mounted(); bool Mounted();
virtual int GetFragList(u8 *id); virtual int GetFragList(u8 *id) { return 0; };
virtual int GetFragList(char *filename, _frag_append_t append_fragment, FragList *); virtual bool ShowFreeSpace(void);
virtual bool ShowFreeSpace(void);
virtual s32 Open() = 0;
virtual s32 Open() = 0; virtual wbfs_disc_t* OpenDisc(u8 *discid) = 0;
virtual wbfs_disc_t* OpenDisc(u8 *discid) = 0; virtual void CloseDisc(wbfs_disc_t *disc) = 0;
virtual void CloseDisc(wbfs_disc_t *disc) = 0; virtual s32 Format();
virtual s32 Format(); virtual s32 GetCount(u32 *) = 0;
virtual s32 GetCount(u32 *) = 0; virtual s32 GetHeaders(struct discHdr *, u32, u32) = 0;
virtual s32 GetHeaders(struct discHdr *, u32, u32) = 0; virtual s32 AddGame(void) = 0;
virtual s32 AddGame(void) = 0; virtual s32 RemoveGame(u8 *) = 0;
virtual s32 RemoveGame(u8 *) = 0; virtual s32 DiskSpace(f32 *, f32 *) = 0;
virtual s32 DiskSpace(f32 *, f32 *) = 0; virtual s32 RenameGame(u8 *, const void *) = 0;
virtual s32 RenameGame(u8 *, const void *) = 0; virtual s32 ReIDGame(u8 *discid, const void *newID) = 0;
virtual s32 ReIDGame(u8 *discid, const void *newID) = 0; virtual f32 EstimateGameSize(void) = 0;
virtual f32 EstimateGameSize(void) = 0;
/*
/* static s32 OpenPart(u32 part_fat, u32 part_idx, u32 part_lba, u32 part_size, char *partition);
static s32 OpenPart(u32 part_fat, u32 part_idx, u32 part_lba, u32 part_size, char *partition); static s32 OpenNamed(char *partition);
static s32 OpenNamed(char *partition); static s32 OpenLBA(u32 lba, u32 size);
static s32 OpenLBA(u32 lba, u32 size); */
*/ protected:
protected: static u32 nb_sectors;
static u32 nb_sectors;
/* WBFS HDD */
/* WBFS HDD */ wbfs_t *hdd;
wbfs_t *hdd;
u32 device, lba, size;
u32 device, lba, size; private:
private:
static s32 total, done;
static s32 total, done; };
};
#endif //_H
#endif //_H

View File

@ -817,86 +817,11 @@ bool Wbfs_Fat::is_gameid(char *id)
int Wbfs_Fat::GetFragList(u8 *id) int Wbfs_Fat::GetFragList(u8 *id)
{ {
char fname[1024]; char fname[1024];
char fname1[1024];
struct stat st;
FragList *fs = NULL;
FragList *fa = NULL;
FragList *fw = NULL;
int ret;
int i;
int is_wbfs = 0;
int ret_val = -1;
ret = FindFilename(id, fname, sizeof(fname)); int ret = FindFilename(id, fname, sizeof(fname));
if (!ret) return -1; if (!ret) return -1;
if (strcasecmp(strrchr(fname, '.'), ".wbfs") == 0) return get_frag_list_for_file(fname, id);
{
is_wbfs = 1;
}
fs = (FragList *) malloc(sizeof(FragList));
fa = (FragList *) malloc(sizeof(FragList));
fw = (FragList *) malloc(sizeof(FragList));
frag_init(fa, MAX_FRAG);
for (i = 0; i < 10; i++)
{
frag_init(fs, MAX_FRAG);
if (i > 0)
{
fname[strlen(fname) - 1] = '0' + i;
if (stat(fname, &st) == -1) break;
}
strcpy(fname1, fname);
if ((ret = GetFragList((char *) &fname, &_frag_append, fs)))
{
ret_val = ret;
goto out;
}
frag_concat(fa, fs);
}
frag_list = (FragList *) malloc(sizeof(FragList));
frag_init(frag_list, MAX_FRAG);
if (is_wbfs)
{
// if wbfs file format, remap.
//printf("=====\n");
wbfs_disc_t *d = OpenDisc(id);
if (!d) goto out;
frag_init(fw, MAX_FRAG);
ret = wbfs_get_fragments(d, &_frag_append, fw);
if (ret) goto out;
CloseDisc(d);
// DEBUG:
//frag_list->num = MAX_FRAG-10; // stress test
ret = frag_remap(frag_list, fw, fa);
if (ret) goto out;
}
else
{
// .iso does not need remap just copy
//printf("fa:\n");
memcpy(frag_list, fa, sizeof(FragList));
}
ret_val = 0;
out: if (ret_val)
{
// error
SAFE_FREE( frag_list );
}
SAFE_FREE( fs );
SAFE_FREE( fa );
SAFE_FREE( fw );
return ret_val;
}
int Wbfs_Fat::GetFragList(char *filename, _frag_append_t append_fragment, FragList *fs)
{
return _FAT_get_fragments(filename, append_fragment, fs);
} }
bool Wbfs_Fat::ShowFreeSpace(void) bool Wbfs_Fat::ShowFreeSpace(void)

View File

@ -1,67 +1,66 @@
#ifndef _WBFS_FAT_H #ifndef _WBFS_FAT_H
#define _WBFS_FAT_H #define _WBFS_FAT_H
#include <ogcsys.h> #include <ogcsys.h>
#include "usbloader/splits.h" #include "usbloader/splits.h"
#include "wbfs_base.h" #include "wbfs_base.h"
class Wbfs_Fat: public Wbfs class Wbfs_Fat: public Wbfs
{ {
public: public:
Wbfs_Fat(u32 device, u32 lba, u32 size); Wbfs_Fat(u32 device, u32 lba, u32 size);
~Wbfs_Fat(); ~Wbfs_Fat();
virtual s32 Open(); virtual s32 Open();
wbfs_disc_t* OpenDisc(u8 *); wbfs_disc_t* OpenDisc(u8 *);
void CloseDisc(wbfs_disc_t *); void CloseDisc(wbfs_disc_t *);
s32 GetCount(u32 *); s32 GetCount(u32 *);
s32 GetHeaders(struct discHdr *, u32, u32); s32 GetHeaders(struct discHdr *, u32, u32);
s32 AddGame(); s32 AddGame();
s32 RemoveGame(u8 *); s32 RemoveGame(u8 *);
s32 DiskSpace(f32 *, f32 *); s32 DiskSpace(f32 *, f32 *);
s32 RenameGame(u8 *, const void *); s32 RenameGame(u8 *, const void *);
s32 ReIDGame(u8 *, const void *); s32 ReIDGame(u8 *, const void *);
f32 EstimateGameSize(); f32 EstimateGameSize();
int GetFragList(u8 *); int GetFragList(u8 *);
virtual int GetFragList(char *, _frag_append_t, FragList *); virtual bool ShowFreeSpace(void);
virtual bool ShowFreeSpace(void);
protected:
protected: static char wbfs_fs_drive[16];
static char wbfs_fs_drive[16]; private:
private: split_info_t split;
split_info_t split;
static u32 fat_sector_size;
static u32 fat_sector_size; static char wbfs_fat_dir[16];
static char wbfs_fat_dir[16]; static char invalid_path[];
static char invalid_path[]; static struct discHdr *fat_hdr_list;
static struct discHdr *fat_hdr_list; static u32 fat_hdr_count;
static u32 fat_hdr_count;
wbfs_t* OpenPart(char *fname);
wbfs_t* OpenPart(char *fname); void ClosePart(wbfs_t* part);
void ClosePart(wbfs_t* part); wbfs_t* CreatePart(u8 *id, char *path);
wbfs_t* CreatePart(u8 *id, char *path); int FindFilename(u8 *id, char *fname, int len);
int FindFilename(u8 *id, char *fname, int len); void Filename(u8 *id, char *fname, int len, char *path);
void Filename(u8 *id, char *fname, int len, char *path); bool CheckLayoutB(char *fname, int len, u8* id, char *fname_title);
bool CheckLayoutB(char *fname, int len, u8* id, char *fname_title); s32 GetHeadersCount();
s32 GetHeadersCount(); void GetDir(struct discHdr *header, char *path);
void GetDir(struct discHdr *header, char *path);
void mk_title_txt(struct discHdr *header, char *path);
void mk_title_txt(struct discHdr *header, char *path); void mk_gameid_title(struct discHdr *header, char *name, int re_space, int layout);
void mk_gameid_title(struct discHdr *header, char *name, int re_space, int layout); void title_filename(char *title);
void title_filename(char *title); bool is_gameid(char *id);
bool is_gameid(char *id);
static int nop_rw_sector(void *_fp, u32 lba, u32 count, void* buf)
static int nop_rw_sector(void *_fp, u32 lba, u32 count, void* buf) {
{ return 0;
return 0; }
} };
};
#endif //_WBFS_FAT_H
#endif //_WBFS_FAT_H

View File

@ -1,30 +1,14 @@
#include "wbfs_ntfs.h" #include "wbfs_ntfs.h"
#include "fatmounter.h" #include "fatmounter.h"
#include "libs/libntfs/ntfs.h" #include "libs/libntfs/ntfs.h"
s32 Wbfs_Ntfs::Open() s32 Wbfs_Ntfs::Open()
{ {
strcpy(wbfs_fs_drive, "NTFS:"); strcpy(wbfs_fs_drive, "NTFS:");
return MountNTFS(lba); return MountNTFS(lba);
} }
int Wbfs_Ntfs::GetFragList(char *filename, _frag_append_t append_fragment, FragList *fs) bool Wbfs_Ntfs::ShowFreeSpace(void)
{ {
int ret = _NTFS_get_fragments(filename, append_fragment, fs); return true;
if (ret) }
{
return ret;
}
// offset to start of partition
for (unsigned int j = 0; j < fs->num; j++)
{
fs->frag[j].sector += fs_ntfs_sec;
}
return ret;
}
bool Wbfs_Ntfs::ShowFreeSpace(void)
{
return true;
}

View File

@ -1,20 +1,19 @@
#ifndef _WBFS_NTFS_H #ifndef _WBFS_NTFS_H
#define _WBFS_NTFS_H #define _WBFS_NTFS_H
#include "wbfs_fat.h" #include "wbfs_fat.h"
class Wbfs_Ntfs: public Wbfs_Fat class Wbfs_Ntfs: public Wbfs_Fat
{ {
public: public:
Wbfs_Ntfs(u32 device, u32 lba, u32 size) : Wbfs_Ntfs(u32 device, u32 lba, u32 size) :
Wbfs_Fat(device, lba, size) Wbfs_Fat(device, lba, size)
{ {
} }
virtual s32 Open(); virtual s32 Open();
int GetFragList(char *filename, _frag_append_t append_fragment, FragList *fs); bool ShowFreeSpace(void);
bool ShowFreeSpace(void); };
};
#endif //_WBFS_NTFS_H
#endif //_WBFS_NTFS_H

View File

@ -79,6 +79,7 @@ s32 WDVD_Reset(void)
inbuf[0] = IOCTL_DI_RESET << 24; inbuf[0] = IOCTL_DI_RESET << 24;
inbuf[1] = 1; inbuf[1] = 1;
ret = IOS_Ioctl(di_fd, IOCTL_DI_RESET, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf)); ret = IOS_Ioctl(di_fd, IOCTL_DI_RESET, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf));
if (ret < 0) if (ret < 0)
return ret; return ret;