*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;
} }
case 223: else if(IsWaninkokoIOS(ios))
{ {
s32 ios223rev = NandTitles.VersionOf(0x1000000dfULL); s32 iosRev = NandTitles.VersionOf(TITLE_ID(1, ios));
if (ios223rev == 4 || ios223rev == 5 || ios223rev == 65535) break; if(iosRev < 9 || iosRev > 30) //let's see if Waninkoko actually gets to 30
return -2; return -22;
} }
case 249: else
{ {
s32 ios249rev = NandTitles.VersionOf(0x1000000f9ULL); return -33;
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

@ -4,30 +4,54 @@
#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 "usbstorage2.h"
#include "frag.h"
#include "utils.h"
FragList *frag_list = NULL; #include "usbloader/wbfs.h"
#include "usbloader/wdvd.h"
#include "usbloader/usbstorage2.h"
#include "frag.h"
#include "sys.h"
#include "gecko.h"
#define SAFE_FREE(x) if(x) { free(x); x = NULL; }
extern sec_t fs_ntfs_sec;
int _FAT_get_fragments (const char *path, _frag_append_t append_fragment, void *callback_data);
static FragList *frag_list = NULL;
void frag_init(FragList *ff, int maxnum) void frag_init(FragList *ff, int maxnum)
{ {
memset(ff, 0, sizeof(Fragment) * (maxnum + 1)); memset(ff, 0, sizeof(Fragment) * (maxnum+1));
ff->maxnum = maxnum; ff->maxnum = maxnum;
} }
void frag_dump(FragList *ff)
{
int i;
gprintf("frag list: %d %d 0x%x\n", ff->num, ff->size, ff->size);
for (i=0; i<ff->num; i++) {
if (i>10) {
gprintf("...\n");
break;
}
gprintf(" %d : %8x %8x %8x\n", i,
ff->frag[i].offset,
ff->frag[i].count,
ff->frag[i].sector);
}
}
int frag_append(FragList *ff, u32 offset, u32 sector, u32 count) int frag_append(FragList *ff, u32 offset, u32 sector, u32 count)
{ {
int n; int n;
if (count) if (count) {
{
n = ff->num - 1; n = ff->num - 1;
if (ff->num > 0 && ff->frag[n].offset + ff->frag[n].count == offset && ff->frag[n].sector + ff->frag[n].count if (ff->num > 0
== sector) && ff->frag[n].offset + ff->frag[n].count == offset
&& ff->frag[n].sector + ff->frag[n].count == sector)
{ {
// merge // merge
ff->frag[n].count += count; ff->frag[n].count += count;
@ -35,8 +59,7 @@ int frag_append(FragList *ff, u32 offset, u32 sector, u32 count)
else else
{ {
// add // add
if (ff->num >= ff->maxnum) if (ff->num >= ff->maxnum) {
{
// too many fragments // too many fragments
return -500; return -500;
} }
@ -61,9 +84,9 @@ int frag_concat(FragList *ff, FragList *src)
int i, ret; int i, ret;
u32 size = ff->size; u32 size = ff->size;
//printf("concat: %d %d <- %d %d\n", ff->num, ff->size, src->num, src->size); //printf("concat: %d %d <- %d %d\n", ff->num, ff->size, src->num, src->size);
for (i = 0; i < src->num; i++) for (i=0; i<src->num; i++) {
{ ret = frag_append(ff, size + src->frag[i].offset,
ret = frag_append(ff, size + src->frag[i].offset, src->frag[i].sector, src->frag[i].count); src->frag[i].sector, src->frag[i].count);
if (ret) return ret; if (ret) return ret;
} }
ff->size = size + src->size; ff->size = size + src->size;
@ -74,14 +97,15 @@ int frag_concat(FragList *ff, FragList *src)
// in case a sparse block is requested, // in case a sparse block is requested,
// the returned poffset might not be equal to requested offset // the returned poffset might not be equal to requested offset
// the difference should be filled with 0 // the difference should be filled with 0
int frag_get(FragList *ff, u32 offset, u32 count, u32 *poffset, u32 *psector, u32 *pcount) int frag_get(FragList *ff, u32 offset, u32 count,
u32 *poffset, u32 *psector, u32 *pcount)
{ {
int i; int i;
u32 delta; u32 delta;
//printf("frag_get(%u %u)\n", offset, count); //printf("frag_get(%u %u)\n", offset, count);
for (i = 0; i < ff->num; i++) for (i=0; i<ff->num; i++) {
{ if (ff->frag[i].offset <= offset
if (ff->frag[i].offset <= offset && ff->frag[i].offset + ff->frag[i].count > offset) && ff->frag[i].offset + ff->frag[i].count > offset)
{ {
delta = offset - ff->frag[i].offset; delta = offset - ff->frag[i].offset;
*poffset = offset; *poffset = offset;
@ -90,7 +114,8 @@ int frag_get(FragList *ff, u32 offset, u32 count, u32 *poffset, u32 *psector, u3
if (*pcount > count) *pcount = count; if (*pcount > count) *pcount = count;
goto out; goto out;
} }
if (ff->frag[i].offset > offset && ff->frag[i].offset < offset + count) if (ff->frag[i].offset > offset
&& ff->frag[i].offset < offset + count)
{ {
delta = ff->frag[i].offset - offset; delta = ff->frag[i].offset - offset;
*poffset = ff->frag[i].offset; *poffset = ff->frag[i].offset;
@ -102,8 +127,7 @@ int frag_get(FragList *ff, u32 offset, u32 count, u32 *poffset, u32 *psector, u3
} }
} }
// not found // not found
if (offset + count > ff->size) if (offset + count > ff->size) {
{
// error: out of range! // error: out of range!
return -1; return -1;
} }
@ -125,14 +149,14 @@ int frag_remap(FragList *ff, FragList *log, FragList *phy)
u32 sector; u32 sector;
u32 count; u32 count;
u32 delta; u32 delta;
for (i = 0; i < log->num; i++) for (i=0; i<log->num; i++) {
{
delta = 0; delta = 0;
count = 0; count = 0;
do do {
{ ret = frag_get(phy,
ret = frag_get(phy, log->frag[i].sector + delta + count, log->frag[i].count - delta - count, &offset, log->frag[i].sector + delta + count,
&sector, &count); log->frag[i].count - delta - count,
&offset, &sector, &count);
if (ret) return ret; // error if (ret) return ret; // error
delta = offset - log->frag[i].sector; delta = offset - log->frag[i].sector;
ret = frag_append(ff, log->frag[i].offset + delta, sector, count); ret = frag_append(ff, log->frag[i].offset + delta, sector, count);
@ -142,6 +166,88 @@ int frag_remap(FragList *ff, FragList *log, FragList *phy)
return 0; return 0;
} }
int get_frag_list_for_file(char *fname, u8 *id)
{
char fname1[1024];
struct stat st;
FragList *fs = NULL;
FragList *fa = NULL;
FragList *fw = NULL;
int ret;
int i, j;
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) int get_frag_list(u8 *id)
{ {
return WBFS_GetFragList(id); return WBFS_GetFragList(id);
@ -149,32 +255,26 @@ int get_frag_list(u8 *id)
int set_frag_list(u8 *id) int set_frag_list(u8 *id)
{ {
if (wbfs_part_fs == PART_FS_WBFS) return 0; if (wbfs_part_fs == PART_FS_WBFS) return 1;
if (frag_list == NULL) if (frag_list == NULL) {
{ return -2;
if (wbfs_part_fs == PART_FS_FAT)
{
// fall back to old fat method
// printf("FAT: fallback to old method\n");
return 0;
}
// ntfs has no fallback, return error
return -1;
} }
// (+1 for header which is same size as fragment) // (+1 for header which is same size as fragment)
int size = sizeof(Fragment) * (frag_list->num + 1); int size = sizeof(Fragment) * (frag_list->num + 1);
int ret = USBStorage_WBFS_SetFragList(frag_list, size); int ret;
if (ret) DCFlushRange(frag_list, size);
{
// printf("set_frag: %d\n", ret); gprintf("Calling WDVD_SetFragList, frag list size %d\n", size);
ret = WDVD_SetFragList(wbfsDev, frag_list, size);
if (ret) {
return ret; return ret;
} }
// verify id matches // verify id matches
char discid[8]; char discid[8];
memset(discid, 0, sizeof(discid)); memset(discid, 0, sizeof(discid));
ret = USBStorage_WBFS_Read(0, 6, discid); ret = WDVD_UnencryptedRead(discid, 8, 0);
return 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,3 +1,4 @@
// worst case wbfs fragmentation scenario: // worst case wbfs fragmentation scenario:
// 9GB (dual layer) / 2mb (wbfs sector size) = 4608 // 9GB (dual layer) / 2mb (wbfs sector size) = 4608
#define MAX_FRAG 20000 #define MAX_FRAG 20000
@ -5,45 +6,47 @@
// 40000/4/3-1 = 21844 // 40000/4/3-1 = 21844
#ifdef __cplusplus #ifdef __cplusplus
extern "C" 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, // in case a sparse block is requested,
// the returned poffset might not be equal to requested offset // the returned poffset might not be equal to requested offset
// the difference should be filled with 0 // the difference should be filled with 0
int frag_get(FragList *ff, u32 offset, u32 count, u32 *poffset, u32 *psector, u32 *pcount); int frag_get(FragList *ff, u32 offset, u32 count,
u32 *poffset, u32 *psector, u32 *pcount);
int frag_remap(FragList *ff, FragList *log, FragList *phy); int frag_remap(FragList *ff, FragList *log, FragList *phy);
int get_frag_list(u8 *id); int get_frag_list_for_file(char *fname, u8 *id);
int set_frag_list(u8 *id); int get_frag_list(u8 *id);
int set_frag_list(u8 *id);
#ifdef __cplusplus #ifdef __cplusplus
} }

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

@ -17,8 +17,7 @@ class Wbfs
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;

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

@ -30,7 +30,6 @@ class Wbfs_Fat: public Wbfs
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:

View File

@ -8,22 +8,6 @@ s32 Wbfs_Ntfs::Open()
return MountNTFS(lba); return MountNTFS(lba);
} }
int Wbfs_Ntfs::GetFragList(char *filename, _frag_append_t append_fragment, FragList *fs)
{
int ret = _NTFS_get_fragments(filename, append_fragment, fs);
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) bool Wbfs_Ntfs::ShowFreeSpace(void)
{ {
return true; return true;

View File

@ -13,7 +13,6 @@ class Wbfs_Ntfs: public Wbfs_Fat
virtual s32 Open(); virtual s32 Open();
int GetFragList(char *filename, _frag_append_t append_fragment, FragList *fs);
bool ShowFreeSpace(void); bool ShowFreeSpace(void);
}; };

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;