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

View File

@ -44,7 +44,6 @@ int DiscBrowse(struct discHdr * header, char * alternatedname, int alternatednam
HaltGui();
Disc_SetUSB(NULL);
wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) header->id);
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" ),
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
***************************************************************************/
@ -1008,26 +996,22 @@ int MenuSettings()
if (firstRun) options2.SetName(Idx, "%s", tr( "Boot/Standard" ));
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 = 223;
break;
case 223:
Settings.cios = 224;
break;
case 224:
Settings.cios = 249;
break;
case 249:
Settings.cios = 250;
break;
case 250:
Settings.cios = 222;
break;
default:
Settings.cios = 222;
break;
Settings.cios = atoi(entered);
if(Settings.cios < 200) Settings.cios = 200;
else if(Settings.cios > 255) Settings.cios = 255;
if(NandTitles.IndexOf(TITLE_ID(1, Settings.cios)) < 0)
{
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"));
}
else if(Settings.cios == 254)
{
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"));
}
}
}
if (Settings.godmode == 1)
@ -1041,12 +1025,12 @@ int MenuSettings()
if (ret == Idx)
{
// Select the next valid partition, even if that's the same one
int fs_type = partitions.pinfo[Settings.partition].fs_type;
do
{
Settings.partition = Settings.partition + 1 == partitions.num ? 0
: Settings.partition + 1;
} while (!IsValidPartition(partitions.pinfo[Settings.partition].fs_type,
Settings.cios));
Settings.partition = (Settings.partition + 1) % partitions.num;
fs_type = partitions.pinfo[Settings.partition].fs_type;
} while (!(fs_type == FS_TYPE_WBFS || fs_type == FS_TYPE_FAT32 || fs_type == FS_TYPE_NTFS));
}
PartInfo pInfo = partitions.pinfo[Settings.partition];
@ -2622,26 +2606,22 @@ int MenuGameSettings(struct discHdr * header)
if (firstRun) options2.SetName(Idx, "IOS");
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:
game_cfg.ios = 223;
break;
case 223:
game_cfg.ios = 224;
break;
case 224:
game_cfg.ios = 249;
break;
case 249:
game_cfg.ios = 250;
break;
case 250:
game_cfg.ios = 222;
break;
default:
game_cfg.ios = 222;
break;
Settings.cios = atoi(entered);
if(Settings.cios < 200) Settings.cios = 200;
else if(Settings.cios > 255) Settings.cios = 255;
if(NandTitles.IndexOf(TITLE_ID(1, Settings.cios)) < 0)
{
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"));
}
else if(Settings.cios == 254)
{
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"));
}
}
}
options2.SetValue(Idx, "IOS %i", game_cfg.ios);

View File

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

View File

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

View File

@ -17,11 +17,31 @@
#include "mload/modules/ehcmodule_5.h"
#include "mload/modules/dip_plugin_249.h"
#include "mload/modules/odip_frag.h"
#include "gecko.h"
/******************************************************************************
* 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).
* @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)
{
switch (ios)
if(IsHermesIOS(ios))
{
case 222:
{
s32 ios222rev = NandTitles.VersionOf(0x1000000deULL);
if (ios222rev == 4 || ios222rev == 5 || ios222rev == 65535) break;
return -2;
}
case 223:
{
s32 ios223rev = NandTitles.VersionOf(0x1000000dfULL);
if (ios223rev == 4 || ios223rev == 5 || ios223rev == 65535) break;
return -2;
}
case 249:
{
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 iosRev = NandTitles.VersionOf(TITLE_ID(1, ios));
if((iosRev < 2 || iosRev > 5) && iosRev != 65535)
return -11;
}
else if(IsWaninkokoIOS(ios))
{
s32 iosRev = NandTitles.VersionOf(TITLE_ID(1, ios));
if(iosRev < 9 || iosRev > 30) //let's see if Waninkoko actually gets to 30
return -22;
}
else
{
return -33;
}
s32 r = IOS_ReloadIOS(ios);
@ -146,7 +153,7 @@ s32 IosLoader::ReloadIosSafe(s32 ios)
void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
{
//! Hermes IOS
if(ios == 222 || ios == 223 || ios == 224)
if(IsHermesIOS(ios))
{
const u8 * ech_module = NULL;
int ehc_module_size = 0;
@ -160,18 +167,21 @@ void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
ehc_module_size = ehcmodule_2_size;
dip_plugin = dip_plugin_2;
dip_plugin_size = dip_plugin_2_size;
gprintf("Loading ehc and dip module v2\n");
break;
case 3:
ech_module = ehcmodule_3;
ehc_module_size = ehcmodule_3_size;
dip_plugin = dip_plugin_3;
dip_plugin_size = dip_plugin_3_size;
gprintf("Loading ehc and dip module v3\n");
break;
default:
ech_module = ehcmodule_5;
ehc_module_size = ehcmodule_5_size;
dip_plugin = odip_frag;
dip_plugin_size = odip_frag_size;
gprintf("Loading ehc v5 and opendip module\n");
break;
}
@ -180,18 +190,20 @@ void IosLoader::LoadIOSModules(s32 ios, s32 ios_rev)
{
ehc_cfg += 12;
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);
}
//! Waninkoko IOS
else if(ios == 249 || ios == 250)
else if(IsWaninkokoIOS(ios))
{
if(ios_rev >= 18)
{
if(mload_init() < 0)
return;
gprintf("Loading dip module for Waninkoko's cios\n");
mload_module((u8 *) dip_plugin_249, dip_plugin_249_size);
mload_close();
}

View File

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

View File

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

View File

@ -4,177 +4,277 @@
#include <unistd.h>
#include <sys/stat.h>
#include "fatmounter.h"
#include "libs/libntfs/ntfs.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)
{
memset(ff, 0, sizeof(Fragment) * (maxnum + 1));
ff->maxnum = maxnum;
memset(ff, 0, sizeof(Fragment) * (maxnum+1));
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 n;
if (count)
{
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
== sector)
{
// merge
ff->frag[n].count += count;
}
else
{
// add
if (ff->num >= ff->maxnum)
{
// too many fragments
return -500;
}
n = ff->num;
ff->frag[n].offset = offset;
ff->frag[n].sector = sector;
ff->frag[n].count = count;
ff->num++;
}
}
ff->size = offset + count;
return 0;
int n;
if (count) {
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 == sector)
{
// merge
ff->frag[n].count += count;
}
else
{
// add
if (ff->num >= ff->maxnum) {
// too many fragments
return -500;
}
n = ff->num;
ff->frag[n].offset = offset;
ff->frag[n].sector = sector;
ff->frag[n].count = count;
ff->num++;
}
}
ff->size = offset + count;
return 0;
}
int _frag_append(void *ff, u32 offset, u32 sector, u32 count)
{
return frag_append(ff, offset, sector, count);
return frag_append(ff, offset, sector, count);
}
int frag_concat(FragList *ff, FragList *src)
{
int i, ret;
u32 size = ff->size;
//printf("concat: %d %d <- %d %d\n", ff->num, ff->size, src->num, src->size);
for (i = 0; i < src->num; i++)
{
ret = frag_append(ff, size + src->frag[i].offset, src->frag[i].sector, src->frag[i].count);
if (ret) return ret;
}
ff->size = size + src->size;
//printf("concat: -> %d %d\n", ff->num, ff->size);
return 0;
int i, ret;
u32 size = ff->size;
//printf("concat: %d %d <- %d %d\n", ff->num, ff->size, src->num, src->size);
for (i=0; i<src->num; i++) {
ret = frag_append(ff, size + src->frag[i].offset,
src->frag[i].sector, src->frag[i].count);
if (ret) return ret;
}
ff->size = size + src->size;
//printf("concat: -> %d %d\n", ff->num, ff->size);
return 0;
}
// in case a sparse block is requested,
// 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_get(FragList *ff, u32 offset, u32 count,
u32 *poffset, u32 *psector, u32 *pcount)
{
int i;
u32 delta;
//printf("frag_get(%u %u)\n", offset, count);
for (i = 0; i < ff->num; i++)
{
if (ff->frag[i].offset <= offset && ff->frag[i].offset + ff->frag[i].count > offset)
{
delta = offset - ff->frag[i].offset;
*poffset = offset;
*psector = ff->frag[i].sector + delta;
*pcount = ff->frag[i].count - delta;
if (*pcount > count) *pcount = count;
goto out;
}
if (ff->frag[i].offset > offset && ff->frag[i].offset < offset + count)
{
delta = ff->frag[i].offset - offset;
*poffset = ff->frag[i].offset;
*psector = ff->frag[i].sector;
*pcount = ff->frag[i].count;
count -= delta;
if (*pcount > count) *pcount = count;
goto out;
}
}
// not found
if (offset + count > ff->size)
{
// error: out of range!
return -1;
}
// if inside range, then it must be just sparse, zero filled
// return empty block at the end of requested
*poffset = offset + count;
*psector = 0;
*pcount = 0;
out:
//printf("=>(%u %u %u)\n", *poffset, *psector, *pcount);
return 0;
int i;
u32 delta;
//printf("frag_get(%u %u)\n", offset, count);
for (i=0; i<ff->num; i++) {
if (ff->frag[i].offset <= offset
&& ff->frag[i].offset + ff->frag[i].count > offset)
{
delta = offset - ff->frag[i].offset;
*poffset = offset;
*psector = ff->frag[i].sector + delta;
*pcount = ff->frag[i].count - delta;
if (*pcount > count) *pcount = count;
goto out;
}
if (ff->frag[i].offset > offset
&& ff->frag[i].offset < offset + count)
{
delta = ff->frag[i].offset - offset;
*poffset = ff->frag[i].offset;
*psector = ff->frag[i].sector;
*pcount = ff->frag[i].count;
count -= delta;
if (*pcount > count) *pcount = count;
goto out;
}
}
// not found
if (offset + count > ff->size) {
// error: out of range!
return -1;
}
// if inside range, then it must be just sparse, zero filled
// return empty block at the end of requested
*poffset = offset + count;
*psector = 0;
*pcount = 0;
out:
//printf("=>(%u %u %u)\n", *poffset, *psector, *pcount);
return 0;
}
int frag_remap(FragList *ff, FragList *log, FragList *phy)
{
int i;
int ret;
u32 offset;
u32 sector;
u32 count;
u32 delta;
for (i = 0; i < log->num; i++)
{
delta = 0;
count = 0;
do
{
ret = frag_get(phy, log->frag[i].sector + delta + count, log->frag[i].count - delta - count, &offset,
&sector, &count);
if (ret) return ret; // error
delta = offset - log->frag[i].sector;
ret = frag_append(ff, log->frag[i].offset + delta, sector, count);
if (ret) return ret; // error
} while (count + delta < log->frag[i].count);
}
return 0;
int i;
int ret;
u32 offset;
u32 sector;
u32 count;
u32 delta;
for (i=0; i<log->num; i++) {
delta = 0;
count = 0;
do {
ret = frag_get(phy,
log->frag[i].sector + delta + count,
log->frag[i].count - delta - count,
&offset, &sector, &count);
if (ret) return ret; // error
delta = offset - log->frag[i].sector;
ret = frag_append(ff, log->frag[i].offset + delta, sector, count);
if (ret) return ret; // error
} while (count + delta < log->frag[i].count);
}
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)
{
return WBFS_GetFragList(id);
return WBFS_GetFragList(id);
}
int set_frag_list(u8 *id)
{
if (wbfs_part_fs == PART_FS_WBFS) return 0;
if (frag_list == NULL)
{
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;
}
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 = USBStorage_WBFS_SetFragList(frag_list, size);
if (ret)
{
// printf("set_frag: %d\n", ret);
return ret;
}
// (+1 for header which is same size as fragment)
int size = sizeof(Fragment) * (frag_list->num + 1);
int ret;
DCFlushRange(frag_list, size);
// verify id matches
char discid[8];
memset(discid, 0, sizeof(discid));
ret = USBStorage_WBFS_Read(0, 6, discid);
return 0;
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,3 +1,4 @@
// worst case wbfs fragmentation scenario:
// 9GB (dual layer) / 2mb (wbfs sector size) = 4608
#define MAX_FRAG 20000
@ -5,45 +6,47 @@
// 40000/4/3-1 = 21844
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include "libs/libwbfs/libwbfs.h"
typedef struct
{
u32 offset; // file offset, in sectors unit
u32 sector;
u32 count;
} Fragment;
typedef struct
{
u32 offset; // file offset, in sectors unit
u32 sector;
u32 count;
} Fragment;
typedef struct
{
u32 size; // num sectors
u32 num; // num fragments
u32 maxnum;
Fragment frag[MAX_FRAG];
} FragList;
typedef struct
{
u32 size; // num sectors
u32 num; // num fragments
u32 maxnum;
Fragment frag[MAX_FRAG];
} 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);
int frag_append(FragList *ff, u32 offset, u32 sector, u32 count);
int _frag_append(void *ff, u32 offset, u32 sector, u32 count);
int frag_concat(FragList *ff, FragList *src);
void frag_init(FragList *ff, int maxnum);
void frag_dump(FragList *ff);
int frag_append(FragList *ff, u32 offset, u32 sector, u32 count);
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
// the difference should be filled with 0
int frag_get(FragList *ff, u32 offset, u32 count, u32 *poffset, u32 *psector, u32 *pcount);
// in case a sparse block is requested,
// 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_remap(FragList *ff, FragList *log, FragList *phy);
int frag_remap(FragList *ff, FragList *log, FragList *phy);
int get_frag_list(u8 *id);
int set_frag_list(u8 *id);
int get_frag_list_for_file(char *fname, u8 *id);
int get_frag_list(u8 *id);
int set_frag_list(u8 *id);
#ifdef __cplusplus
}

View File

@ -137,15 +137,6 @@ bool Wbfs::Mounted()
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)
{

View File

@ -17,8 +17,7 @@ class Wbfs
s32 GameSize(u8 *, f32 *);
wbfs_t *GetHddInfo(void);
bool Mounted();
virtual int GetFragList(u8 *id);
virtual int GetFragList(char *filename, _frag_append_t append_fragment, FragList *);
virtual int GetFragList(u8 *id) { return 0; };
virtual bool ShowFreeSpace(void);
virtual s32 Open() = 0;

View File

@ -817,86 +817,11 @@ bool Wbfs_Fat::is_gameid(char *id)
int Wbfs_Fat::GetFragList(u8 *id)
{
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 (strcasecmp(strrchr(fname, '.'), ".wbfs") == 0)
{
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);
return get_frag_list_for_file(fname, id);
}
bool Wbfs_Fat::ShowFreeSpace(void)

View File

@ -30,7 +30,6 @@ class Wbfs_Fat: public Wbfs
f32 EstimateGameSize();
int GetFragList(u8 *);
virtual int GetFragList(char *, _frag_append_t, FragList *);
virtual bool ShowFreeSpace(void);
protected:

View File

@ -8,22 +8,6 @@ s32 Wbfs_Ntfs::Open()
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)
{
return true;

View File

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

View File

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