mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-18 01:09:16 +01:00
*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:
parent
33ce3e48ab
commit
64744ce20d
File diff suppressed because one or more lines are too long
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
§or, &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, §or, &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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user