* Added Hermes rev5 support! (issue 1438)

* Updated to Hermes usb storage code
* Fixed some bugs in ntfs while writing timestamps, resulting in different hashes (dimok)
* Fixed codedump when switching partitions (issue 1454)
* Fixed graphical glitch on 4:3 screens, where the prefetch cover was visible in the coverwall
* Fixed a bug with installing games, due to the switch to C++ (dimok)
This commit is contained in:
e.bovendeur 2010-02-22 21:29:47 +00:00
parent 275aee0dab
commit ce5930f297
44 changed files with 770 additions and 3473 deletions

View File

@ -2,8 +2,8 @@
<app version="1">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>1.0 r913</version>
<release_date>201002162013</release_date>
<version>1.0 r914</version>
<release_date>201002222228</release_date>
<short_description>Loads games from USB-devices</short_description>
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times.
The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller.

Binary file not shown.

BIN
data/fatffs_module.bin Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,7 @@
#include <locale.h>
#include "usbloader/sdhc.h"
#include "usbloader/usbstorage.h"
#include "usbloader/usbstorage2.h"
#include "usbloader/wbfs.h"
#include "libfat/fat.h"
#include "libntfs/ntfs.h"
@ -53,15 +53,15 @@ int USBDevice_Init() {
//right now mounts first FAT-partition
//try first mount with cIOS
if (!fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) {
//try now mount with libogc
if (!fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) {
// if (!fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) {
// //try now mount with libogc
if (!fatMount("USB", &__io_usbstorage2, 0, CACHE, SECTORS)) {
#ifdef DEBUG_FAT
gprintf(":-1");
#endif
return -1;
}
}
// }
fat_usb_mount = 1;
fat_usb_sec = _FAT_startSector;
@ -88,12 +88,12 @@ int WBFSDevice_Init(u32 sector) {
//right now mounts first FAT-partition
//try first mount with cIOS
if (!fatMount("WBFS", &__io_wiiums, 0, CACHE, SECTORS)) {
// if (!fatMount("WBFS", &__io_wiiums, 0, CACHE, SECTORS)) {
//try now mount with libogc
if (!fatMount("WBFS", &__io_usbstorage, 0, CACHE, SECTORS)) {
if (!fatMount("WBFS", &__io_usbstorage2, 0, CACHE, SECTORS)) {
return -1;
}
}
// }
fat_wbfs_mount = 1;
fat_wbfs_sec = _FAT_startSector;
@ -180,19 +180,19 @@ s32 MountNTFS(u32 sector)
if (wbfsDev == WBFS_DEVICE_USB) {
/* Initialize WBFS interface */
if (!__io_wiiums.startup()) {
ret = __io_usbstorage.startup();
// if (!__io_wiiums.startup()) {
ret = __io_usbstorage2.startup();
if (!ret) {
return -1;
}
}
// }
/* Mount device */
if (!ntfsMount("NTFS", &__io_wiiums, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER)) {
ret = ntfsMount("NTFS", &__io_usbstorage, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);
// if (!ntfsMount("NTFS", &__io_wiiums, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER)) {
ret = ntfsMount("NTFS", &__io_usbstorage2, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);
if (!ret) {
return -2;
}
}
// }
} else if (wbfsDev == WBFS_DEVICE_SDHC) {
if (sdhc_mode_sd == 0) {
ret = ntfsMount("NTFS", &__io_sdhc, 0, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER);

View File

@ -40,14 +40,14 @@ The list is terminated by a NULL/NULL entry.
/* ====================== Wii ====================== */
#include <sdcard/wiisd_io.h>
#include <ogc/usbstorage.h>
#include "usbloader/usbstorage2.h"
#include <sdcard/gcsd.h>
static const DISC_INTERFACE* get_io_wiisd (void) {
return &__io_wiisd;
}
static const DISC_INTERFACE* get_io_usbstorage (void) {
return &__io_usbstorage;
return &__io_usbstorage2;
}
static const DISC_INTERFACE* get_io_gcsda (void) {

View File

@ -1129,6 +1129,8 @@ put_err_out:
*/
void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
{
return;
time_t now;
if (!ni) {

View File

@ -41,11 +41,12 @@
#if defined(__wii__)
#include <sdcard/wiisd_io.h>
#include <sdcard/gcsd.h>
#include <ogc/usbstorage.h>
#include "usbloader/usbstorage2.h"
const INTERFACE_ID ntfs_disc_interfaces[] = {
{ "sd", &__io_wiisd },
{ "usb", &__io_usbstorage },
{ "usb", &__io_usbstorage2 },
{ "carda", &__io_gcsda },
{ "cardb", &__io_gcsdb },
{ NULL, NULL }

View File

@ -536,6 +536,7 @@ u32 wbfs_add_disc(wbfs_t*p, read_wiidisc_callback_t read_src_wii_disc,
}
if (ret) break;
info->wlba_table[i] = wbfs_htons(bl);
wbfs_sync(p);
}
// write disc info
int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s;

View File

@ -67,7 +67,7 @@ typedef struct wbfs_disc_info
// callback definition. Return 1 on fatal error (callback is supposed to make retries until no hopes..)
typedef int (*rw_sector_callback_t)(void*fp,u32 lba,u32 count,void*iobuf);
typedef void (*progress_callback_t)(int status,int total);
typedef void (*progress_callback_t)(u32 status, u32 total);
typedef struct wbfs_s

View File

@ -232,9 +232,9 @@ static int Pos3[45][2][2] = {
{{591,153}, {633,153}},
{{591,250}, {633,250}},
{{645,58}, {633,58}},
{{645,153}, {633,153}},
{{645,250}, {633,250}}
{{660,58}, {660,58}},
{{660,153}, {660,153}},
{{660,250}, {660,250}}
};
#define VALUE4ROWS(rows, val1, val2, val3) (rows==3 ? val3 : (rows==2 ? val2 : val1))

View File

@ -48,7 +48,7 @@ extern "C"
#include "svnrev.h"
#include "wad/title.h"
#include "usbloader/partition_usbloader.h"
#include "usbloader/usbstorage.h"
#include "usbloader/usbstorage2.h"
#include "memory/mem2.h"
#include "lstub.h"
@ -413,7 +413,7 @@ main(int argc, char *argv[])
printf("\n\tReloading IOS to config setting (%d)...", Settings.cios == ios222 ? 222 : 223);
SDCard_deInit(); // unmount SD for reloading IOS
USBDevice_deInit(); // unmount USB for reloading IOS
USBStorage_Deinit();
USBStorage2_Deinit();
ret = IOS_ReloadIOSsafe(Settings.cios == ios222 ? 222 : 223);
printf("%d", ret);
SDCard_Init();
@ -436,7 +436,7 @@ main(int argc, char *argv[])
printf("\n\tReloading IOS to config setting (%d)...", ios249 ? 249 : 250);
SDCard_deInit(); // unmount SD for reloading IOS
USBDevice_deInit(); // unmount USB for reloading IOS
USBStorage_Deinit();
USBStorage2_Deinit();
ret = IOS_ReloadIOSsafe(ios249 ? 249 : 250);
printf("%d", ret);
if (ret < 0)

View File

@ -2,7 +2,7 @@
#include "menus.h"
#include "fatmounter.h"
#include "usbloader/usbstorage.h"
#include "usbloader/usbstorage2.h"
#include "usbloader/utils.h"
#include "usbloader/wbfs.h"
#include "libwiigui/gui_customoptionbrowser.h"
@ -18,7 +18,7 @@ int MenuFormat() {
USBDevice_deInit();
sleep(1);
USBStorage_Init();
USBStorage2_Init();
int menu = MENU_NONE;
char imgPath[100];

View File

@ -1,5 +1,5 @@
#include "menus.h"
#include "usbloader/usbstorage.h"
#include "usbloader/usbstorage2.h"
#include "usbloader/wbfs.h"
#include "usbloader/disc.h"
#include "usbloader/utils.h"
@ -104,11 +104,11 @@ int MenuInstall() {
menu = MENU_DISCLIST;
break;
} else {
USBStorage_Watchdog(0);
USBStorage2_Watchdog(0);
SetupGameInstallProgress(gametxt, name);
ret = WBFS_AddGame();
ProgressStop();
USBStorage_Watchdog(1);
USBStorage2_Watchdog(1);
wiilight(0);
if (ret != 0) {
WindowPrompt(tr("Install Error!"),0,tr("Back"));

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
#define size_fatffs_module 58440
extern unsigned char fatffs_module[58440];

View File

@ -5,6 +5,8 @@
#define ALIGNED(x) __attribute__((aligned(x)))
#define DEBUG_MLOAD
/* Used for Hermes NAND emulation */
int global_mount;
int sd_ok=0;
@ -287,7 +289,7 @@ int load_fatffs_module(u8 *discid)
if(mload_init()<0) return -1;
mload_elf((void *) fatffs_module, &my_data_elf);
mload_elf((void *) fatffs_module_bin, &my_data_elf);
my_thread_id= mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio);
if(my_thread_id<0) return -1;

View File

@ -3,7 +3,7 @@
#include "dip_plugin.h"
#include "mload.h"
#include "fatffs_module.h"
#include "fatffs_module_bin.h"
#ifdef __cplusplus
extern "C" {

View File

@ -17,6 +17,7 @@
#include "prompts/ProgressWindow.h"
#include "usbloader/wbfs.h"
#include "usbloader/utils.h"
#include "usbloader/spinner.h"
/*** Variables used only in this file ***/
static lwp_t progressthread = LWP_THREAD_NULL;
@ -32,8 +33,8 @@ static f32 progressDone = 0.0;
static bool showTime = false;
static bool showSize = false;
static bool changed = true;
static s32 gameinstalldone = 0;
static s32 gameinstalltotal = -1;
static u32 gameinstalldone = 0;
static u32 gameinstalltotal = 0;
static time_t start;
/*** Extern variables ***/
@ -51,10 +52,10 @@ extern void HaltGui();
***************************************************************************/
static void GameInstallProgress() {
if (gameinstalltotal <= 0)
if (gameinstalltotal == 0)
return;
int oldinstalldone = gameinstalldone;
u32 oldinstalldone = gameinstalldone;
GetProgressValue(&gameinstalldone, &gameinstalltotal);
@ -312,7 +313,7 @@ static void * ProgressThread (void *arg) {
***************************************************************************/
void ProgressStop() {
showProgress = 0;
gameinstalltotal = -1;
gameinstalltotal = 0;
// wait for thread to finish
while (!LWP_ThreadIsSuspended(progressthread))

View File

@ -10,7 +10,7 @@
#include "usbloader/wbfs.h"
#include "usbloader/wdvd.h"
#include "usbloader/partition_usbloader.h"
#include "usbloader/usbstorage.h"
#include "usbloader/usbstorage2.h"
#include "usbloader/getentries.h"
#include "language/gettext.h"
#include "libwiigui/gui.h"

View File

@ -2201,6 +2201,7 @@ int MenuSettings()
if (Settings.partition != settingspartitionold) {
reloaddatabasefile = true;
CloseXMLDatabase();
CFG_Cleanup();
}
OpenXMLDatabase(Settings.titlestxt_path, Settings.db_language, Settings.db_JPtoEN, reloaddatabasefile, Settings.titlesOverride==1?true:false, true); // open file, reload titles, keep in memory
}

View File

@ -1882,12 +1882,12 @@ void CFG_LoadGlobal(void) {
void CFG_Cleanup(void)
{
int i = 0;
for(i = 0; i < num_title; i++)
{
if(cfg_title[i].title)
free(cfg_title[i].title);
cfg_title[i].title = NULL;
}
for(i = 0; i < num_title; i++)
{
if(cfg_title[i].title)
free(cfg_title[i].title);
cfg_title[i].title = NULL;
}
if (cfg_title) {
free(cfg_title);
cfg_title = NULL;

View File

@ -3,7 +3,7 @@
#include <unistd.h>
#include "usbloader/wdvd.h"
#include "usbloader/usbstorage.h"
#include "usbloader/usbstorage2.h"
#include "usbloader/disc.h"
#include "usbloader/wbfs.h"
#include "usbloader/partition_usbloader.h"
@ -78,7 +78,7 @@ int Sys_ChangeIos(int ios) {
WDVD_Close();
USBStorage_Deinit();
USBStorage2_Deinit();
s32 ret = IOS_ReloadIOSsafe(ios);
if (ret < 0) {
@ -122,7 +122,7 @@ int Sys_IosReload(int IOS) {
WDVD_Close();
USBStorage_Deinit();
USBStorage2_Deinit();
if (IOS == 249 || IOS == 222 || IOS == 223) {
for (int i = 0; i < 10; i++) {
@ -132,7 +132,7 @@ int Sys_IosReload(int IOS) {
ret = WBFS_Init(WBFS_DEVICE_USB);
if (!(ret < 0)) break;
sleep(1);
USBStorage_Deinit();
USBStorage2_Deinit();
}
if (ret>=0) {
ret = Disc_Init();

View File

@ -19,7 +19,8 @@ extern "C" {
u8 bufsize;
/* Padding */
u8 unused1[14];
u8 is_ciso;
u8 unused1[13];
/* Magic word */
u32 magic;

View File

@ -8,7 +8,7 @@
#include "libntfs/ntfs.h"
#include "libwbfs/libwbfs.h"
#include "wbfs.h"
#include "usbstorage.h"
#include "usbstorage2.h"
#include "frag.h"
#include "utils.h"

View File

@ -7,7 +7,7 @@
#include "partition_usbloader.h"
#include "sdhc.h"
#include "usbstorage.h"
#include "usbstorage2.h"
#include "utils.h"
#include "wbfs.h"
#include "libwbfs/libwbfs.h"
@ -33,12 +33,12 @@ s32 Partition_GetEntries(u32 device, partitionEntry *outbuf, u32 *outval)
switch (device) {
case WBFS_DEVICE_USB: {
/* Get sector size */
ret = USBStorage_GetCapacity(&sector_size);
ret = USBStorage2_GetCapacity(&sector_size);
if (ret == 0)
return -1;
/* Read partition table */
ret = USBStorage_ReadSectors(0, 1, &table);
ret = USBStorage2_ReadSectors(0, 1, &table);
if (ret < 0)
return ret;
@ -86,7 +86,7 @@ bool Device_ReadSectors(u32 device, u32 sector, u32 count, void *buffer)
/* Read from specified device */
switch (device) {
case WBFS_DEVICE_USB:
ret = USBStorage_ReadSectors(sector, count, buffer);
ret = USBStorage2_ReadSectors(sector, count, buffer);
if (ret < 0)
return false;
return true;
@ -105,7 +105,7 @@ bool Device_WriteSectors(u32 device, u32 sector, u32 count, void *buffer)
/* Read from specified device */
switch (device) {
case WBFS_DEVICE_USB:
ret = USBStorage_WriteSectors(sector, count, buffer);
ret = USBStorage2_WriteSectors(sector, count, buffer);
if (ret < 0)
return false;
return true;
@ -129,7 +129,7 @@ s32 Partition_GetEntriesEx(u32 device, partitionEntry *outbuf, u32 *psect_size,
// Get sector size
switch (device) {
case WBFS_DEVICE_USB:
ret = USBStorage_GetCapacity(&sector_size);
ret = USBStorage2_GetCapacity(&sector_size);
if (ret == 0) return -1;
break;
case WBFS_DEVICE_SDHC:

View File

@ -0,0 +1,17 @@
#include <gccore.h>
#include "libwbfs/libwbfs.h"
static u32 done = 0;
static u32 total = 0;
void WBFS_Spinner(u32 d, u32 t)
{
done = d;
total = t;
}
void GetProgressValue(u32 * d, u32 * t)
{
*d = done;
*t = total;
}

View File

@ -0,0 +1,15 @@
#ifndef SPINNER_H_
#define SPINNER_H_
#ifdef __cplusplus
extern "C" {
#endif
void WBFS_Spinner(u32 d, u32 t);
void GetProgressValue(u32 * d, u32 * t);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,382 +0,0 @@
/*-------------------------------------------------------------
usbstorage_starlet.c -- USB mass storage support, inside starlet
Copyright (C) 2009 Kwiirk
If this driver is linked before libogc, this will replace the original
usbstorage driver by svpe from libogc
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
-------------------------------------------------------------*/
#include <gccore.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
/* IOCTL commands */
#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
#define USB_IOCTL_UMS_UNMOUNT (UMS_BASE+0x10)
#define USB_IOCTL_UMS_WATCHDOG (UMS_BASE+0x80)
#define WBFS_BASE (('W'<<24)|('F'<<16)|('S'<<8))
#define USB_IOCTL_WBFS_OPEN_DISC (WBFS_BASE+0x1)
#define USB_IOCTL_WBFS_READ_DISC (WBFS_BASE+0x2)
#define USB_IOCTL_WBFS_READ_DIRECT_DISC (WBFS_BASE+0x3)
#define USB_IOCTL_WBFS_STS_DISC (WBFS_BASE+0x4)
#define USB_IOCTL_WBFS_SET_DEVICE (WBFS_BASE+0x50)
#define USB_IOCTL_WBFS_SET_FRAGLIST (WBFS_BASE+0x51)
#define UMS_HEAPSIZE 0x1000
/* Variables */
static char fs[] ATTRIBUTE_ALIGN(32) = "/dev/usb2";
static char fs2[] ATTRIBUTE_ALIGN(32) = "/dev/usb/ehc";
static s32 hid = -1, fd = -1;
static u32 sector_size;
s32 USBStorage_GetCapacity(u32 *_sector_size) {
if (fd > 0) {
s32 ret;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", &sector_size);
if (ret && _sector_size)
*_sector_size = sector_size;
return ret;
}
return IPC_ENOENT;
}
s32 USBStorage_Init(void) {
s32 ret;
/* Already open */
if (fd > 0)
return 0;
/* Create heap */
if (hid < 0) {
hid = iosCreateHeap(UMS_HEAPSIZE);
if (hid < 0)
return IPC_ENOMEM;
}
/* Open USB device */
fd = IOS_Open(fs, 0);
if (fd < 0)
fd = IOS_Open(fs2, 0);
if (fd < 0)
return fd;
/* Initialize USB storage */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_INIT, ":");
if (ret<0) goto err;
/* Get device capacity */
ret = USBStorage_GetCapacity(NULL);
if (!ret)
goto err;
return 0;
err:
/* Close USB device */
if (fd > 0) {
IOS_Close(fd);
fd = -1;
}
return -1;
}
/** Hermes **/
s32 USBStorage_Watchdog(u32 on_off) {
if (fd >= 0) {
s32 ret;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WATCHDOG, "i:", on_off);
return ret;
}
return IPC_ENOENT;
}
s32 USBStorage_Umount(void) {
if (fd >= 0) {
s32 ret;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_UNMOUNT, ":");
return ret;
}
return IPC_ENOENT;
}
void USBStorage_Deinit(void) {
/* Close USB device */
if (fd > 0) {
IOS_Close(fd);
fd = -1;
}
}
s32 USBStorage_ReadSectors(u32 sector, u32 numSectors, void *buffer) {
// void *buf = (void *)buffer;
u32 len = (sector_size * numSectors);
s32 ret;
/* Device not opened */
if (fd < 0)
return fd;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, numSectors, buffer, len);
return ret;
}
s32 USBStorage_WriteSectors(u32 sector, u32 numSectors, const void *buffer) {
u32 len = (sector_size * numSectors);
s32 ret;
/* Device not opened */
if (fd < 0)
return fd;
/* Write data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, numSectors, buffer, len);
return ret;
}
static bool __io_usb_Startup(void)
{
return USBStorage_Init() >= 0;
}
static bool __io_usb_IsInserted(void)
{
s32 ret;
if (fd < 0) return false;
ret = USBStorage_GetCapacity(NULL);
if (ret == 0) return false;
return true;
}
bool __io_usb_ReadSectors(u32 sector, u32 count, void *buffer)
{
s32 ret = USBStorage_ReadSectors(sector, count, buffer);
return ret > 0;
}
bool __io_usb_WriteSectors(u32 sector, u32 count, void *buffer)
{
s32 ret = USBStorage_WriteSectors(sector, count, buffer);
return ret > 0;
}
static bool __io_usb_ClearStatus(void)
{
return true;
}
static bool __io_usb_Shutdown(void)
{
// do nothing
return true;
}
static bool __io_usb_NOP(void)
{
// do nothing
return true;
}
const DISC_INTERFACE __io_usbstorage_ro = {
DEVICE_TYPE_WII_USB,
FEATURE_MEDIUM_CANREAD | FEATURE_WII_USB,
(FN_MEDIUM_STARTUP) &__io_usb_Startup,
(FN_MEDIUM_ISINSERTED) &__io_usb_IsInserted,
(FN_MEDIUM_READSECTORS) &__io_usb_ReadSectors,
(FN_MEDIUM_WRITESECTORS) &__io_usb_NOP, //&__io_usb_WriteSectors,
(FN_MEDIUM_CLEARSTATUS) &__io_usb_ClearStatus,
(FN_MEDIUM_SHUTDOWN) &__io_usb_Shutdown
};
s32 USBStorage_WBFS_Open(char *buffer)
{
u32 len = 8;
s32 ret;
/* Device not opened */
if (fd < 0)
return fd;
extern u32 wbfs_part_lba;
u32 part = wbfs_part_lba;
/* Read data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_OPEN_DISC, "dd:", buffer, len, &part, 4);
return ret;
}
// woffset is in 32bit words, len is in bytes
s32 USBStorage_WBFS_Read(u32 woffset, u32 len, void *buffer)
{
s32 ret;
USBStorage_Init();
/* Device not opened */
if (fd < 0)
return fd;
/* Read data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_READ_DISC, "ii:d", woffset, len, buffer, len);
return ret;
}
s32 USBStorage_WBFS_SetDevice(int dev)
{
s32 ret;
static s32 retval = 0;
retval = 0;
USBStorage_Init();
// Device not opened
if (fd < 0) return fd;
// ioctl
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_SET_DEVICE, "i:i", dev, &retval);
if (retval) return retval;
return ret;
}
s32 USBStorage_WBFS_SetFragList(void *p, int size)
{
s32 ret;
USBStorage_Init();
// Device not opened
if (fd < 0) return fd;
// ioctl
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_SET_FRAGLIST, "d:", p, size);
return ret;
}
#define DEVICE_TYPE_WII_UMS (('W'<<24)|('U'<<16)|('M'<<8)|'S')
bool umsio_Startup() {
return USBStorage_Init() == 0;
}
bool umsio_IsInserted() {
return true; // allways true
}
bool umsio_ReadSectors(sec_t sector, sec_t numSectors, u8 *buffer) {
u32 cnt = 0;
s32 ret;
/* Do reads */
while (cnt < numSectors) {
u32 sectors = (numSectors - cnt);
/* Read sectors is too big */
if (sectors > 32)
sectors = 32;
/* USB read */
ret = USBStorage_ReadSectors(sector + cnt, sectors, &buffer[cnt*512]);
if (ret < 0)
return false;
/* Increment counter */
cnt += sectors;
}
return true;
}
bool umsio_WriteSectors(sec_t sector, sec_t numSectors, const u8* buffer) {
u32 cnt = 0;
s32 ret;
/* Do writes */
while (cnt < numSectors) {
u32 sectors = (numSectors - cnt);
/* Write sectors is too big */
if (sectors > 32)
sectors = 32;
/* USB write */
ret = USBStorage_WriteSectors(sector + cnt, sectors, &buffer[cnt * 512]);
if (ret < 0)
return false;
/* Increment counter */
cnt += sectors;
}
return true;
}
bool umsio_ClearStatus(void) {
return true;
}
bool umsio_Shutdown() {
USBStorage_Deinit();
return true;
}
const DISC_INTERFACE __io_wiiums = {
DEVICE_TYPE_WII_UMS,
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
(FN_MEDIUM_STARTUP) &umsio_Startup,
(FN_MEDIUM_ISINSERTED) &umsio_IsInserted,
(FN_MEDIUM_READSECTORS) &umsio_ReadSectors,
(FN_MEDIUM_WRITESECTORS) &umsio_WriteSectors,
(FN_MEDIUM_CLEARSTATUS) &umsio_ClearStatus,
(FN_MEDIUM_SHUTDOWN) &umsio_Shutdown
};
const DISC_INTERFACE __io_wiiums_ro = {
DEVICE_TYPE_WII_UMS,
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
(FN_MEDIUM_STARTUP) &umsio_Startup,
(FN_MEDIUM_ISINSERTED) &umsio_IsInserted,
(FN_MEDIUM_READSECTORS) &umsio_ReadSectors,
(FN_MEDIUM_WRITESECTORS) &__io_usb_NOP,
(FN_MEDIUM_CLEARSTATUS) &umsio_ClearStatus,
(FN_MEDIUM_SHUTDOWN) &umsio_Shutdown
};

View File

@ -1,26 +0,0 @@
#ifndef _USBSTORAGE_H_
#define _USBSTORAGE_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Prototypes */
s32 USBStorage_GetCapacity(u32 *);
s32 USBStorage_Init(void);
void USBStorage_Deinit(void);
s32 USBStorage_Watchdog(u32 on_off);
s32 USBStorage_ReadSectors(u32, u32, void *);
s32 USBStorage_WriteSectors(u32, u32, const void *);
s32 USBStorage_WBFS_Open(char *buf_id);
s32 USBStorage_WBFS_Read(u32 woffset, u32 len, void *buffer);
s32 USBStorage_WBFS_SetDevice(int dev);
s32 USBStorage_WBFS_SetFragList(void *p, int size);
extern const DISC_INTERFACE __io_wiiums;
extern const DISC_INTERFACE __io_wiiums_ro;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,456 @@
/*-------------------------------------------------------------
usbstorage_starlet.c -- USB mass storage support, inside starlet
Copyright (C) 2009 Kwiirk
If this driver is linked before libogc, this will replace the original
usbstorage driver by svpe from libogc
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
-------------------------------------------------------------*/
#include <gccore.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include "usbstorage2.h"
/* IOCTL commands */
#define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
#define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
#define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
#define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
#define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
#define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
#define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
#define USB_IOCTL_UMS_UMOUNT (UMS_BASE+0x10)
#define USB_IOCTL_UMS_WATCHDOG (UMS_BASE+0x80)
#define USB_IOCTL_UMS_TESTMODE (UMS_BASE+0x81)
#define WBFS_BASE (('W'<<24)|('F'<<16)|('S'<<8))
#define USB_IOCTL_WBFS_OPEN_DISC (WBFS_BASE+0x1)
#define USB_IOCTL_WBFS_READ_DISC (WBFS_BASE+0x2)
#define USB_IOCTL_WBFS_READ_DIRECT_DISC (WBFS_BASE+0x3)
#define USB_IOCTL_WBFS_STS_DISC (WBFS_BASE+0x4)
#define USB_IOCTL_WBFS_SET_DEVICE (WBFS_BASE+0x50)
#define USB_IOCTL_WBFS_SET_FRAGLIST (WBFS_BASE+0x51)
#define UMS_HEAPSIZE 0x1000 //0x10000
/* Variables */
static char fs[] ATTRIBUTE_ALIGN(32) = "/dev/usb2";
static char fs2[] ATTRIBUTE_ALIGN(32) = "/dev/usb/ehc";
static char fsoff[] ATTRIBUTE_ALIGN(32) = "/dev/usb2/OFF";
static s32 hid = -1, fd = -1;
static u32 sector_size;
static int mounted=0;
s32 USBStorage2_Umount(void)
{
if (fd >= 0 && mounted) {
s32 ret;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_UMOUNT, ":");
return ret;
}
return IPC_ENOENT;
}
s32 USBStorage2_Watchdog(u32 on_off)
{
if (fd >= 0) {
s32 ret;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WATCHDOG, "i:", on_off);
return ret;
}
return IPC_ENOENT;
}
s32 USBStorage2_TestMode(u32 on_off)
{
if (fd >= 0) {
s32 ret;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_TESTMODE, "i:", on_off);
return ret;
}
return IPC_ENOENT;
}
inline s32 __USBStorage2_isMEM2Buffer(const void *buffer)
{
u32 high_addr = ((u32)buffer) >> 24;
return (high_addr == 0x90) || (high_addr == 0xD0);
}
s32 USBStorage2_GetCapacity(u32 *_sector_size)
{
if (fd >= 0) {
s32 ret;
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", &sector_size);
if (ret && _sector_size)
*_sector_size = sector_size;
return ret;
}
return IPC_ENOENT;
}
s32 USBStorage2_EHC_Off(void)
{
USBStorage2_Deinit();
fd=IOS_Open(fsoff, 0);
USBStorage2_Deinit();
return 0;
}
s32 USBStorage2_Init(void)
{
s32 ret,ret2;
static u32 sector_size=0;
/* Already open */
if (fd >= 0)
return 0;
/* Create heap */
if (hid < 0) {
hid = iosCreateHeap(UMS_HEAPSIZE);
if (hid < 0)
return IPC_ENOMEM;
}
/* Open USB device */
fd = IOS_Open(fs, 0);
if (fd < 0) fd = IOS_Open(fs2, 0);
if (fd < 0)
return fd;
/* Initialize USB storage */
ret=IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_INIT, ":");
if(ret<0) goto err;
if(ret>1) ret=0;
ret2=ret;
/* Get device capacity */
ret = USBStorage2_GetCapacity(&sector_size);
if (!ret)
{
ret=-1;
goto err;
}
if(ret2==0 && sector_size!=512) // check for HD sector size 512 bytes
{
ret=-20001;
goto err;
}
if(ret2==1 && sector_size!=2048) // check for DVD sector size 2048 bytes
{
ret=-20002;
goto err;
}
mounted=1;
return ret2; // 0->HDD, 1->DVD
err:
/* Close USB device */
if (fd >= 0) {
IOS_Close(fd);
fd = -1;
}
return ret;
}
void USBStorage2_Deinit(void)
{
mounted = 0;
/* Close USB device */
if (fd >= 0) {
IOS_Close(fd);
fd = -1;
}
}
extern void* SYS_AllocArena2MemLo(u32 size,u32 align);
static void *mem2_ptr=NULL;
s32 USBStorage2_ReadSectors(u32 sector, u32 numSectors, void *buffer)
{
void *buf = (void *)buffer;
u32 len = (sector_size * numSectors);
s32 ret;
/* Device not opened */
if (fd < 0)
return fd;
if(!mem2_ptr) mem2_ptr=SYS_AllocArena2MemLo(2048*256,32);
/* MEM1 buffer */
if (!__USBStorage2_isMEM2Buffer(buffer)) {
/* Allocate memory */
buf = mem2_ptr; //iosAlloc(hid, len);
if (!buf)
return IPC_ENOMEM;
}
/* Read data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, numSectors, buf, len);
/* Copy data */
if (buf != buffer) {
memcpy(buffer, buf, len);
//iosFree(hid, buf);
}
return ret;
}
s32 USBStorage2_WriteSectors(u32 sector, u32 numSectors, const void *buffer)
{
void *buf = (void *)buffer;
u32 len = (sector_size * numSectors);
s32 ret;
/* Device not opened */
if (fd < 0)
return fd;
if(!mem2_ptr) mem2_ptr=SYS_AllocArena2MemLo(2048*256,32);
/* MEM1 buffer */
if (!__USBStorage2_isMEM2Buffer(buffer)) {
/* Allocate memory */
buf = mem2_ptr; //buf = iosAlloc(hid, len);
if (!buf)
return IPC_ENOMEM;
/* Copy data */
memcpy(buf, buffer, len);
}
/* Write data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, numSectors, buf, len);
/* Free memory */
if (buf != buffer)
iosFree(hid, buf);
return ret;
}
static bool __usbstorage_Startup(void)
{
return USBStorage2_Init()==0;
}
static bool __usbstorage_IsInserted(void)
{
return ( USBStorage2_GetCapacity(NULL)>=0);
}
static bool __usbstorage_ReadSectors(u32 sector, u32 numSectors, void *buffer)
{
s32 retval;
retval = USBStorage2_ReadSectors( sector, numSectors, buffer);
if(retval < 0)
return false;
return true;
}
static bool __usbstorage_WriteSectors(u32 sector, u32 numSectors, const void *buffer)
{
s32 retval;
retval = USBStorage2_WriteSectors( sector, numSectors, buffer);
if(retval < 0)
return false;
return true;
}
static bool __usbstorage_ClearStatus(void)
{
return true;
}
static bool __usbstorage_Shutdown(void)
{
//if(mounted) USBStorage2_Umount();
USBStorage2_Deinit();
mounted = 0;
return true;
}
const DISC_INTERFACE __io_usbstorage2 = {
DEVICE_TYPE_WII_UMS,
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
(FN_MEDIUM_STARTUP)&__usbstorage_Startup,
(FN_MEDIUM_ISINSERTED)&__usbstorage_IsInserted,
(FN_MEDIUM_READSECTORS)&__usbstorage_ReadSectors,
(FN_MEDIUM_WRITESECTORS)&__usbstorage_WriteSectors,
(FN_MEDIUM_CLEARSTATUS)&__usbstorage_ClearStatus,
(FN_MEDIUM_SHUTDOWN)&__usbstorage_Shutdown
};
static bool __io_usb_Startup(void)
{
return USBStorage2_Init() >= 0;
}
static bool __io_usb_IsInserted(void)
{
s32 ret;
if (fd < 0) return false;
ret = USBStorage2_GetCapacity(NULL);
if (ret == 0) return false;
return true;
}
bool __io_usb_ReadSectors(u32 sector, u32 count, void *buffer)
{
s32 ret = USBStorage2_ReadSectors(sector, count, buffer);
return ret > 0;
}
bool __io_usb_WriteSectors(u32 sector, u32 count, void *buffer)
{
s32 ret = USBStorage2_WriteSectors(sector, count, buffer);
return ret > 0;
}
static bool __io_usb_ClearStatus(void)
{
return true;
}
static bool __io_usb_Shutdown(void)
{
// do nothing
return true;
}
static bool __io_usb_NOP(void)
{
// do nothing
return true;
}
const DISC_INTERFACE __io_usbstorage2_ro = {
DEVICE_TYPE_WII_UMS,
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
(FN_MEDIUM_STARTUP)&__usbstorage_Startup,
(FN_MEDIUM_ISINSERTED)&__usbstorage_IsInserted,
(FN_MEDIUM_READSECTORS)&__usbstorage_ReadSectors,
(FN_MEDIUM_WRITESECTORS)&__io_usb_NOP,
(FN_MEDIUM_CLEARSTATUS)&__usbstorage_ClearStatus,
(FN_MEDIUM_SHUTDOWN)&__usbstorage_Shutdown
};
s32 USBStorage_WBFS_Open(char *buffer)
{
u32 len = 8;
s32 ret;
/* Device not opened */
if (fd < 0)
return fd;
extern u32 wbfs_part_lba;
u32 part = wbfs_part_lba;
/* Read data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_OPEN_DISC, "dd:", buffer, len, &part, 4);
return ret;
}
// woffset is in 32bit words, len is in bytes
s32 USBStorage_WBFS_Read(u32 woffset, u32 len, void *buffer)
{
s32 ret;
USBStorage2_Init();
/* Device not opened */
if (fd < 0)
return fd;
/* Read data */
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_READ_DISC, "ii:d", woffset, len, buffer, len);
return ret;
}
s32 USBStorage_WBFS_SetDevice(int dev)
{
s32 ret;
static s32 retval = 0;
retval = 0;
USBStorage2_Init();
// Device not opened
if (fd < 0) return fd;
// ioctl
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_SET_DEVICE, "i:i", dev, &retval);
if (retval) return retval;
return ret;
}
s32 USBStorage_WBFS_SetFragList(void *p, int size)
{
s32 ret;
USBStorage2_Init();
// Device not opened
if (fd < 0) return fd;
// ioctl
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_SET_FRAGLIST, "d:", p, size);
return ret;
}

View File

@ -0,0 +1,33 @@
#ifndef _USBSTORAGE2_H_
#define _USBSTORAGE2_H_
#include "ogc/disc_io.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Prototypes */
s32 USBStorage2_GetCapacity(u32 *);
s32 USBStorage2_Init(void);
void USBStorage2_Deinit(void);
s32 USBStorage2_Umount(void);
s32 USBStorage2_ReadSectors(u32, u32, void *);
s32 USBStorage2_WriteSectors(u32, u32, const void *);
s32 USBStorage2_Watchdog(u32 on_off);
s32 USBStorage2_TestMode(u32 on_off);
s32 USBStorage2_EHC_Off(void);
#define DEVICE_TYPE_WII_UMS (('W'<<24)|('U'<<16)|('M'<<8)|'S')
extern const DISC_INTERFACE __io_usbstorage2;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -30,10 +30,6 @@ void WBFS_CloseDisc(wbfs_disc_t *disc) {
current->CloseDisc(disc);
}
void GetProgressValue(s32 * d, s32 * m) {
current->GetProgressValue(d, m);
}
wbfs_t *GetHddInfo(void) {
return current->GetHddInfo();
}

View File

@ -23,7 +23,6 @@ extern "C" {
extern char wbfs_fs_drive[16];
/* Prototypes */
void GetProgressValue(s32 * d, s32 * m);
s32 WBFS_Init(u32);
s32 WBFS_Open(void);
s32 WBFS_Format(u32, u32);

View File

@ -5,17 +5,15 @@
#include <errno.h>
#include "usbloader/sdhc.h"
#include "usbloader/usbstorage.h"
#include "usbloader/usbstorage2.h"
#include "fatmounter.h"
#include "wbfs_rw.h"
#include "wbfs_base.h"
rw_sector_callback_t Wbfs::readCallback = NULL;
rw_sector_callback_t Wbfs::writeCallback = NULL;
s32 Wbfs::done = -1;
s32 Wbfs::total = -1;
u32 Wbfs::nb_sectors;
u32 Wbfs::sector_size;
Wbfs::Wbfs(u32 device, u32 lba, u32 size) : hdd(NULL)
{
@ -36,14 +34,14 @@ s32 Wbfs::Init(u32 device)
switch (device) {
case WBFS_DEVICE_USB:
/* Initialize USB storage */
ret = USBStorage_Init();
ret = USBStorage2_Init();
if (ret >= 0) {
/* Setup callbacks */
readCallback = __ReadUSB;
writeCallback = __WriteUSB;
/* Device info */
/* Get USB capacity */
nb_sectors = USBStorage_GetCapacity(&sector_size);
nb_sectors = USBStorage2_GetCapacity(&sector_size);
if (!nb_sectors)
return -1;
} else
@ -124,12 +122,6 @@ s32 Wbfs::GameSize(u8 *discid, f32 *size)
return 0;
}
void Wbfs::Spinner(s32 x, s32 max)
{
done = x;
total = max;
}
wbfs_t *Wbfs::GetHddInfo()
{
return hdd;

View File

@ -40,23 +40,13 @@ public:
static s32 OpenLBA(u32 lba, u32 size);
*/
protected:
static rw_sector_callback_t readCallback;
static rw_sector_callback_t writeCallback;
static s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf);
static void Spinner(s32 x, s32 max);
static u32 nb_sectors;
static u32 sector_size;
/* WBFS HDD */
wbfs_t *hdd;
u32 device, lba, size;
private:
static s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf);
static s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf);
static s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf);
static s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf);
static s32 total, done;
};

View File

@ -15,6 +15,8 @@
#include "usbloader/disc.h"
#include "fatmounter.h"
#include "wbfs_fat.h"
#include "../spinner.h"
#include "wbfs_rw.h"
#include "gecko.h"
@ -170,7 +172,7 @@ s32 Wbfs_Fat::AddGame(void)
}
wbfs_t *old_hdd = hdd;
hdd = part; // used by spinner
ret = wbfs_add_disc(part, __ReadDVD, NULL, Spinner, part_sel, copy_1_1);
ret = wbfs_add_disc(part, __ReadDVD, NULL, WBFS_Spinner, part_sel, copy_1_1);
hdd = old_hdd;
wbfs_trim(part);
ClosePart(part);
@ -408,14 +410,18 @@ s32 Wbfs_Fat::GetHeadersCount()
strcpy(strrchr(fpath, '.'), ".iso"); // replace .wbfs with .iso
if (stat(fpath, &st) == -1) {
//printf("missing: %s\n", fpath);
if (lay_a && lay_b == 1) {
// mark lay_b so that the stat check is still done,
// but lay_b is not re-tried again
lay_b = 2;
// retry with layout b
goto try_lay_b;
// try .ciso
strcpy(strrchr(fpath, '.'), ".ciso"); // replace .iso with .ciso
if (stat(fpath, &st) == -1 ) {
if (lay_a && lay_b == 1) {
// mark lay_b so that the stat check is still done,
// but lay_b is not re-tried again
lay_b = 2;
// retry with layout b
goto try_lay_b;
}
continue;
}
continue;
}
}
} else {
@ -424,10 +430,12 @@ s32 Wbfs_Fat::GetHeadersCount()
} else {
// usb:/wbfs/GAMEID.wbfs
// or usb:/wbfs/GAMEID.iso
// or usb:/wbfs/GAMEID.ciso
p = strrchr(fname, '.');
if (!p) continue;
if ( (strcasecmp(p, ".wbfs") != 0)
&& (strcasecmp(p, ".iso") != 0) ) continue;
&& (strcasecmp(p, ".iso") != 0)
&& (strcasecmp(p, ".ciso") != 0) ) continue;
int n = p - fname; // length withouth .wbfs
if (n != 6) {
// TITLE [GAMEID].wbfs
@ -461,6 +469,7 @@ s32 Wbfs_Fat::GetHeadersCount()
fseek(fp, 512, SEEK_SET);
fread(&tmpHdr, sizeof(struct discHdr), 1, fp);
fclose(fp);
tmpHdr.is_ciso = 0;
if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) {
goto add_hdr;
}
@ -486,6 +495,19 @@ s32 Wbfs_Fat::GetHeadersCount()
fseek(fp, 0, SEEK_SET);
fread(&tmpHdr, sizeof(struct discHdr), 1, fp);
fclose(fp);
tmpHdr.is_ciso = 0;
if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) {
goto add_hdr;
}
}
} else if (strcasecmp(strrchr(fpath,'.'), ".ciso") == 0) {
// ciso file
FILE *fp = fopen(fpath, "rb");
if (fp != NULL) {
fseek(fp, 0x8000, SEEK_SET);
fread(&tmpHdr, sizeof(struct discHdr), 1, fp);
fclose(fp);
tmpHdr.is_ciso = 1;
if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) {
goto add_hdr;
}
@ -517,6 +539,9 @@ int Wbfs_Fat::FindFilename(u8 *id, char *fname, int len)
// look for direct .iso file
strcpy(strrchr(fname, '.'), ".iso"); // replace .wbfs with .iso
if (stat(fname, &st) == 0) return 1;
// look for direct .ciso file
strcpy(strrchr(fname, '.'), ".ciso"); // replace .iso with .ciso
if (stat(fname, &st) == 0) return 1;
// direct file not found, check subdirs
*fname = 0;
DIR_ITER *dir_iter;
@ -549,6 +574,9 @@ int Wbfs_Fat::FindFilename(u8 *id, char *fname, int len)
if (stat(fname, &st) == 0) break;
// look for .iso file
snprintf(fname, len, "%s/%s/%.6s.iso", path, name, id);
if (stat(fname, &st) == 0) break;
// look for .ciso file
snprintf(fname, len, "%s/%s/%.6s.ciso", path, name, id);
} else {
// TITLE [GAMEID].wbfs
char fn_title[TITLE_LEN];
@ -556,7 +584,8 @@ int Wbfs_Fat::FindFilename(u8 *id, char *fname, int len)
char *p = strrchr(name, '.');
if (!p) continue;
if ( (strcasecmp(p, ".wbfs") != 0)
&& (strcasecmp(p, ".iso") != 0) ) continue;
&& (strcasecmp(p, ".iso") != 0)
&& (strcasecmp(p, ".ciso") != 0) ) continue;
int n = p - name; // length withouth .wbfs
if (!CheckLayoutB(name, n, fn_id, fn_title)) continue;
if (strncmp((char*)fn_id, (char*)id, 6) != 0) continue;
@ -784,7 +813,8 @@ int Wbfs_Fat::GetFragList(u8 *id)
ret = wbfs_get_fragments(d, &_frag_append, fw);
if (ret) goto out;
CloseDisc(d);
// DEBUG: frag_list->num = MAX_FRAG-10; // stress test
// DEBUG:
frag_list->num = MAX_FRAG-10; // stress test
ret = frag_remap(frag_list, fw, fa);
if (ret) goto out;
} else {

View File

@ -1,15 +1,25 @@
#include <ogcsys.h>
#include <malloc.h>
#include <string.h>
#include "usbloader/sdhc.h"
#include "usbloader/usbstorage.h"
#include "usbloader/usbstorage2.h"
#include "usbloader/wdvd.h"
#include "wbfs_base.h"
#include "wbfs_rw.h"
/* Constants */
#define MAX_NB_SECTORS 32
s32 Wbfs::__ReadDVD(void *fp, u32 lba, u32 len, void *iobuf) {
u32 sector_size = 512;
rw_sector_callback_t readCallback = NULL;
rw_sector_callback_t writeCallback = NULL;
void SetSectorSize(u32 size)
{
sector_size = size;
}
s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf) {
void *buffer = NULL;
u64 offset;
@ -58,7 +68,7 @@ out:
return ret;
}
s32 Wbfs::__ReadUSB(void *fp, u32 lba, u32 count, void *iobuf) {
s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf) {
u32 cnt = 0;
s32 ret;
@ -72,7 +82,7 @@ s32 Wbfs::__ReadUSB(void *fp, u32 lba, u32 count, void *iobuf) {
sectors = MAX_NB_SECTORS;
/* USB read */
ret = USBStorage_ReadSectors(lba + cnt, sectors, ptr);
ret = USBStorage2_ReadSectors(lba + cnt, sectors, ptr);
if (ret < 0)
return ret;
@ -83,7 +93,7 @@ s32 Wbfs::__ReadUSB(void *fp, u32 lba, u32 count, void *iobuf) {
return 0;
}
s32 Wbfs::__WriteUSB(void *fp, u32 lba, u32 count, void *iobuf) {
s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf) {
u32 cnt = 0;
s32 ret;
@ -97,7 +107,7 @@ s32 Wbfs::__WriteUSB(void *fp, u32 lba, u32 count, void *iobuf) {
sectors = MAX_NB_SECTORS;
/* USB write */
ret = USBStorage_WriteSectors(lba + cnt, sectors, ptr);
ret = USBStorage2_WriteSectors(lba + cnt, sectors, ptr);
if (ret < 0)
return ret;
@ -108,7 +118,7 @@ s32 Wbfs::__WriteUSB(void *fp, u32 lba, u32 count, void *iobuf) {
return 0;
}
s32 Wbfs::__ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf) {
s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf) {
u32 cnt = 0;
s32 ret;
@ -133,7 +143,7 @@ s32 Wbfs::__ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf) {
return 0;
}
s32 Wbfs::__WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf) {
s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf) {
u32 cnt = 0;
s32 ret;

View File

@ -0,0 +1,25 @@
#ifndef _WBFS_RW_H
#define _WBFS_RW_H
#ifdef __cplusplus
extern "C" {
#endif
#include "libwbfs/libwbfs.h"
extern u32 sector_size;
extern rw_sector_callback_t readCallback;
extern rw_sector_callback_t writeCallback;
s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf);
s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf);
s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf);
s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf);
s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf);
#ifdef __cplusplus
}
#endif
#endif //_WBFS_RW_H

View File

@ -1,5 +1,7 @@
#include "wbfs_wbfs.h"
#include "../spinner.h"
#include "settings/cfg.h"
#include "wbfs_rw.h"
extern u32 sector_size;
@ -108,7 +110,7 @@ s32 Wbfs_Wbfs::AddGame()
part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS;
}
ret = wbfs_add_disc(hdd, __ReadDVD, NULL, Spinner, part_sel, copy_1_1);
ret = wbfs_add_disc(hdd, __ReadDVD, NULL, WBFS_Spinner, part_sel, copy_1_1);
if (ret < 0)
return ret;

View File

@ -1,739 +0,0 @@
// WBFS FAT by oggzee
// WBFS FAT by oggzee
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <ogcsys.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/statvfs.h>
#include <ctype.h>
#include "libwbfs/libwbfs.h"
#include "usbloader/disc.h"
#include "usbloader/sdhc.h"
#include "usbloader/usbstorage.h"
#include "usbloader/utils.h"
#include "usbloader/wbfs.h"
#include "usbloader/wdvd.h"
#include "usbloader/splits.h"
#include "usbloader/wbfs_fat.h"
#include "usbloader/partition_usbloader.h"
#include "libfat/fat.h"
#include "settings/cfg.h"
// max fat fname = 256
#define MAX_FAT_PATH 1024
char wbfs_fs_drive[16];
char wbfs_fat_dir[16] = "/wbfs";
char invalid_path[] = "/\\:|<>?*\"'";
split_info_t split;
static u32 fat_sector_size = 512;
static struct discHdr *fat_hdr_list = NULL;
static int fat_hdr_count = 0;
void WBFS_Spinner(s32 x, s32 max);
s32 __WBFS_ReadDVD(void *fp, u32 lba, u32 len, void *iobuf);
bool is_gameid(char *id)
{
int i;
for (i=0; i<6; i++) {
if (!isalnum((u32) id[i])) return false;
}
return true;
}
s32 _WBFS_FAT_GetHeadersCount()
{
DIR_ITER *dir_iter;
char path[MAX_FAT_PATH];
char fname[MAX_FAT_PATH];
char fpath[MAX_FAT_PATH];
struct discHdr tmpHdr;
struct stat st;
wbfs_t *part = NULL;
u8 id[8];
int ret;
char *p;
u32 size;
int is_dir;
int len;
char dir_title[65];
char *title;
//dbg_time1();
SAFE_FREE(fat_hdr_list);
fat_hdr_count = 0;
strcpy(path, wbfs_fs_drive);
strcat(path, wbfs_fat_dir);
dir_iter = diropen(path);
if (!dir_iter) return 0;
while (dirnext(dir_iter, fname, &st) == 0) {
//printf("found: %s\n", fname); Wpad_WaitButtonsCommon();
if ((char)fname[0] == '.') continue;
len = strlen(fname);
if (len < 8) continue; // "GAMEID_x"
memcpy(id, fname, 6);
id[6] = 0;
is_dir = S_ISDIR(st.st_mode);
//printf("mode: %d %d %x\n", is_dir, st.st_mode, st.st_mode);
if (is_dir) {
int lay_a = 0;
int lay_b = 0;
if (fname[6] == '_' && is_gameid((char*)id)) {
// usb:/wbfs/GAMEID_TITLE/GAMEID.wbfs
lay_a = 1;
}
if (fname[len-8] == '[' && fname[len-1] == ']' && is_gameid(&fname[len-7])) {
// usb:/wbfs/TITLE[GAMEID]/GAMEID.wbfs
lay_b = 1;
}
if (!lay_a && !lay_b) continue;
if (lay_a) {
strncpy(dir_title, &fname[7], sizeof(dir_title));
} else {
try_lay_b:
memcpy(id, &fname[len-7], 6);
id[6] = 0;
strncpy(dir_title, fname, sizeof(dir_title));
dir_title[len-8] = 0; // cut at '['
int n = strlen(dir_title);
if (n == 0) continue;
// cut trailing _ or ' '
if (dir_title[n - 1] == ' ' || dir_title[n - 1] == '_' ) {
dir_title[n - 1] = 0;
}
if (strlen(dir_title) == 0) continue;
}
snprintf(fpath, sizeof(fpath), "%s/%s/%s.wbfs", path, fname, id);
//printf("path2: %s\n", fpath);
// if more than 50 games, skip second stat to improve speed
// but if ambiguous layout check anyway
if (fat_hdr_count < 50 || (lay_a && lay_b)) {
if (stat(fpath, &st) == -1) {
//printf("missing: %s\n", fpath);
// try .iso
strcpy(strrchr(fpath, '.'), ".iso"); // replace .wbfs with .iso
if (stat(fpath, &st) == -1) {
//printf("missing: %s\n", fpath);
if (lay_a && lay_b == 1) {
// mark lay_b so that the stat check is still done,
// but lay_b is not re-tried again
lay_b = 2;
// retry with layout b
goto try_lay_b;
}
continue;
}
}
} else {
st.st_size = 1024*1024;
}
} else {
// usb:/wbfs/GAMEID.wbfs
// or usb:/wbfs/GAMEID.iso
p = strrchr(fname, '.');
if (!p) continue;
if ( (strcasecmp(p, ".wbfs") != 0)
&& (strcasecmp(p, ".iso") != 0) ) continue;
if (p - fname != 6) continue; // GAMEID.
snprintf(fpath, sizeof(fpath), "%s/%s", path, fname);
}
//printf("found: %s %d MB\n", fpath, (int)(st.st_size/1024/1024));
// size must be at least 1MB to be considered a valid wbfs file
if (st.st_size < 1024*1024) continue;
// if we have titles.txt entry use that
title = cfg_get_title(id);
// if directory, and no titles.txt get title from dir name
if (!title && is_dir) {
title = dir_title;
}
if (title) {
memset(&tmpHdr, 0, sizeof(tmpHdr));
memcpy(tmpHdr.id, id, 6);
strncpy(tmpHdr.title, title, sizeof(tmpHdr.title)-1);
tmpHdr.magic = 0x5D1C9EA3;
goto add_hdr;
}
// else read it from file directly
if (strcasecmp(strrchr(fpath,'.'), ".wbfs") == 0) {
// wbfs file directly
FILE *fp = fopen(fpath, "rb");
if (fp != NULL) {
fseek(fp, 512, SEEK_SET);
fread(&tmpHdr, sizeof(struct discHdr), 1, fp);
fclose(fp);
if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) {
goto add_hdr;
}
}
// no title found, read it from wbfs file
// but this is a little bit slower
// open 'partition' file
part = WBFS_FAT_OpenPart(fpath);
if (!part) {
printf("bad wbfs file: %s\n", fpath);
sleep(2);
continue;
}
/* Get header */
ret = wbfs_get_disc_info(part, 0, (u8*)&tmpHdr,
sizeof(struct discHdr), &size);
WBFS_FAT_ClosePart(part);
if (ret == 0) {
goto add_hdr;
}
} else if (strcasecmp(strrchr(fpath,'.'), ".iso") == 0) {
// iso file
FILE *fp = fopen(fpath, "rb");
if (fp != NULL) {
fseek(fp, 0, SEEK_SET);
fread(&tmpHdr, sizeof(struct discHdr), 1, fp);
fclose(fp);
if ((tmpHdr.magic == 0x5D1C9EA3) && (memcmp(tmpHdr.id, id, 6) == 0)) {
goto add_hdr;
}
}
}
// fail:
continue;
// succes: add tmpHdr to list:
add_hdr:
memset(&st, 0, sizeof(st));
//printf("added: %.6s %.20s\n", tmpHdr.id, tmpHdr.title); Wpad_WaitButtons();
fat_hdr_count++;
fat_hdr_list = realloc(fat_hdr_list, fat_hdr_count * sizeof(struct discHdr));
memcpy(&fat_hdr_list[fat_hdr_count-1], &tmpHdr, sizeof(struct discHdr));
}
dirclose(dir_iter);
//dbg_time2("\nFAT_GetCount"); Wpad_WaitButtonsCommon();
return 0;
}
s32 WBFS_FAT_GetCount(u32 *count)
{
*count = 0;
_WBFS_FAT_GetHeadersCount();
if (fat_hdr_count && fat_hdr_list) {
// for compacter mem - move up as it will be freed later
int size = fat_hdr_count * sizeof(struct discHdr);
struct discHdr *buf = malloc(size);
if (buf) {
memcpy(buf, fat_hdr_list, size);
SAFE_FREE(fat_hdr_list);
fat_hdr_list = buf;
}
}
*count = fat_hdr_count;
return 0;
}
s32 WBFS_FAT_GetHeaders(void *outbuf, u32 cnt, u32 len)
{
int i;
int slen = len;
if (slen > sizeof(struct discHdr)) {
slen = sizeof(struct discHdr);
}
for (i=0; i<cnt && i<fat_hdr_count; i++) {
memcpy(outbuf + i * len, &fat_hdr_list[i], slen);
}
SAFE_FREE(fat_hdr_list);
fat_hdr_count = 0;
return 0;
}
wbfs_disc_t* WBFS_FAT_OpenDisc(u8 *discid)
{
char fname[MAX_FAT_PATH];
// wbfs 'partition' file
if ( !WBFS_FAT_find_fname(discid, fname, sizeof(fname)) ) return NULL;
if (strcasecmp(strrchr(fname,'.'), ".iso") == 0) {
// .iso file
// create a fake wbfs_disc
int fd;
fd = open(fname, O_RDONLY);
if (fd == -1) return NULL;
wbfs_disc_t *iso_file = calloc(sizeof(wbfs_disc_t),1);
if (iso_file == NULL) return NULL;
// mark with a special wbfs_part
wbfs_iso_file.wbfs_sec_sz = 512;
iso_file->p = &wbfs_iso_file;
iso_file->header = (void*)fd;
return iso_file;
}
wbfs_t *part = WBFS_FAT_OpenPart(fname);
if (!part) return NULL;
return wbfs_open_disc(part, discid);
}
void WBFS_FAT_CloseDisc(wbfs_disc_t* disc)
{
if (!disc) return;
wbfs_t *part = disc->p;
// is this really a .iso file?
if (part == &wbfs_iso_file) {
close((int)disc->header);
free(disc);
return;
}
wbfs_close_disc(disc);
WBFS_FAT_ClosePart(part);
return;
}
s32 WBFS_FAT_DiskSpace(f32 *used, f32 *free)
{
f32 size;
int ret;
struct statvfs wbfs_fat_vfs;
*used = 0;
*free = 0;
ret = statvfs(wbfs_fs_drive, &wbfs_fat_vfs);
if (ret) return -1;
/* FS size in GB */
size = (f32)wbfs_fat_vfs.f_frsize * (f32)wbfs_fat_vfs.f_blocks / GB_SIZE;
*free = (f32)wbfs_fat_vfs.f_frsize * (f32)wbfs_fat_vfs.f_bfree / GB_SIZE;
*used = size - *free;
return 0;
}
static int nop_read_sector(void *_fp,u32 lba,u32 count,void*buf)
{
//printf("read %d %d\n", lba, count); //Wpad_WaitButtons();
return 0;
}
static int nop_write_sector(void *_fp,u32 lba,u32 count,void*buf)
{
//printf("write %d %d\n", lba, count); //Wpad_WaitButtons();
return 0;
}
void WBFS_FAT_fname(u8 *id, char *fname, int len, char *path)
{
if (path == NULL) {
snprintf(fname, len, "%s%s/%.6s.wbfs", wbfs_fs_drive, wbfs_fat_dir, id);
} else {
snprintf(fname, len, "%s/%.6s.wbfs", path, id);
}
}
// format title so that it is usable in a filename
void title_filename(char *title)
{
int i, len;
// trim leading space
len = strlen(title);
while (*title == ' ') {
memmove(title, title+1, len);
len--;
}
// trim trailing space - not allowed on windows directories
while (len && title[len-1] == ' ') {
title[len-1] = 0;
len--;
}
// replace silly chars with '_'
for (i=0; i<len; i++) {
if(strchr(invalid_path, title[i]) || iscntrl((int) title[i])) {
title[i] = '_';
}
}
}
void mk_gameid_title(struct discHdr *header, char *name, int re_space, int layout)
{
int i, len;
char title[65];
char id[8];
memcpy(name, header->id, 6);
name[6] = 0;
strncpy(title, get_title(header), sizeof(title));
title_filename(title);
if (layout == 0) {
sprintf(name, "%s_%s", id, title);
} else {
sprintf(name, "%s [%s]", title, id);
}
// replace space with '_'
if (re_space) {
len = strlen(name);
for (i = 0; i < len; i++) {
if(name[i]==' ') name[i] = '_';
}
}
}
void WBFS_FAT_get_dir(struct discHdr *header, char *path)
{
strcpy(path, wbfs_fs_drive);
strcat(path, wbfs_fat_dir);
if (Settings.FatInstallToDir) {
strcat(path, "/");
int layout = 0;
if (Settings.FatInstallToDir == 2) layout = 1;
mk_gameid_title(header, path + strlen(path), 0, layout);
}
}
void mk_title_txt(struct discHdr *header, char *path)
{
char fname[MAX_FAT_PATH];
FILE *f;
strcpy(fname, path);
strcat(fname, "/");
mk_gameid_title(header, fname+strlen(fname), 1, 0);
strcat(fname, ".txt");
f = fopen(fname, "wb");
if (!f) return;
fprintf(f, "%.6s = %.64s\n", header->id, get_title(header));
fclose(f);
printf("Info file: %s\n", fname);
}
int WBFS_FAT_find_fname(u8 *id, char *fname, int len)
{
struct stat st;
// look for direct .wbfs file
WBFS_FAT_fname(id, fname, len, NULL);
if (stat(fname, &st) == 0) return 1;
// look for direct .iso file
strcpy(strrchr(fname, '.'), ".iso"); // replace .wbfs with .iso
if (stat(fname, &st) == 0) return 1;
// direct file not found, check subdirs
*fname = 0;
DIR_ITER *dir_iter;
char path[MAX_FAT_PATH];
char name[MAX_FAT_PATH];
strcpy(path, wbfs_fs_drive);
strcat(path, wbfs_fat_dir);
dir_iter = diropen(path);
//printf("dir: %s %p\n", path, dir); Wpad_WaitButtons();
if (!dir_iter) {
return 0;
}
while (dirnext(dir_iter, name, &st) == 0) {
if (name[0] == '.') continue;
int n = strlen(name);
if (n < 8) continue;
if (name[6] == '_') {
// GAMEID_TITLE
if (strncmp(name, (char*)id, 6) != 0) goto try_alter;
} else {
try_alter:
// TITLE [GAMEID]
if (name[n-8] != '[' || name[n-1] != ']') continue;
if (strncmp(&name[n-7], (char*)id, 6) != 0) continue;
}
// look for .wbfs file
snprintf(fname, len, "%s/%s/%.6s.wbfs", path, name, id);
if (stat(fname, &st) == 0) {
break;
}
// look for .iso file
snprintf(fname, len, "%s/%s/%.6s.iso", path, name, id);
if (stat(fname, &st) == 0) {
break;
}
*fname = 0;
}
dirclose(dir_iter);
if (*fname) {
// found
//printf("found:%s\n", fname);
return 2;
}
// not found
return 0;
}
wbfs_t* WBFS_FAT_OpenPart(char *fname)
{
wbfs_t *part = NULL;
int ret;
// wbfs 'partition' file
ret = split_open(&split, fname);
if (ret) return NULL;
part = wbfs_open_partition(
split_read_sector,
nop_write_sector, //readonly //split_write_sector,
&split, fat_sector_size, split.total_sec, 0, 0);
if (!part) {
split_close(&split);
}
return part;
}
wbfs_t* WBFS_FAT_CreatePart(u8 *id, char *path)
{
char fname[MAX_FAT_PATH];
wbfs_t *part = NULL;
u64 size = (u64)143432*2*0x8000ULL;
u32 n_sector = size / 512;
int ret;
//printf("CREATE PART %s %lld %d\n", id, size, n_sector);
snprintf(fname, sizeof(fname), "%s%s", wbfs_fs_drive, wbfs_fat_dir);
mkdir(fname, 0777); // base usb:/wbfs
mkdir(path, 0777); // game subdir
WBFS_FAT_fname(id, fname, sizeof(fname), path);
printf("Writing to %s\n", fname);
ret = split_create(&split, fname, OPT_split_size, size, true);
if (ret) return NULL;
// force create first file
u32 scnt = 0;
int fd = split_get_file(&split, 0, &scnt, 0);
if (fd<0) {
printf("ERROR creating file\n");
sleep(2);
split_close(&split);
return NULL;
}
part = wbfs_open_partition(
split_read_sector,
split_write_sector,
&split, fat_sector_size, n_sector, 0, 1);
if (!part) {
split_close(&split);
}
return part;
}
void WBFS_FAT_ClosePart(wbfs_t* part)
{
if (!part) return;
split_info_t *s = (split_info_t*)part->callback_data;
wbfs_close(part);
if (s) split_close(s);
}
s32 WBFS_FAT_RemoveGame(u8 *discid)
{
char fname[MAX_FAT_PATH];
int loc;
// wbfs 'partition' file
loc = WBFS_FAT_find_fname(discid, fname, sizeof(fname));
if ( !loc ) return -1;
split_create(&split, fname, 0, 0, true);
split_close(&split);
if (loc == 1) return 0;
// game is in subdir
// remove optional .txt file
DIR_ITER *dir_iter;
struct stat st;
char path[MAX_FAT_PATH];
char name[MAX_FAT_PATH];
strncpy(path, fname, sizeof(path));
char *p = strrchr(path, '/');
if (p) *p = 0;
dir_iter = diropen(path);
if (!dir_iter) return 0;
while (dirnext(dir_iter, name, &st) == 0) {
if (name[0] == '.') continue;
if (name[6] != '_') continue;
if (strncmp(name, (char*)discid, 6) != 0) continue;
p = strrchr(name, '.');
if (!p) continue;
if (strcasecmp(p, ".txt") != 0) continue;
snprintf(fname, sizeof(fname), "%s/%s", path, name);
remove(fname);
break;
}
dirclose(dir_iter);
// remove game subdir
unlink(path);
return 0;
}
s32 WBFS_FAT_AddGame(void)
{
static struct discHdr header ATTRIBUTE_ALIGN(32);
char path[MAX_FAT_PATH];
wbfs_t *part = NULL;
s32 ret;
// read ID from DVD
Disc_ReadHeader(&header);
// path
WBFS_FAT_get_dir(&header, path);
// create wbfs 'partition' file
part = WBFS_FAT_CreatePart(header.id, path);
if (!part) return -1;
/* Add game to device */
partition_selector_t part_sel = ALL_PARTITIONS;
int copy_1_1 = Settings.fullcopy;
switch (Settings.partitions_to_install) {
case install_game_only:
part_sel = ONLY_GAME_PARTITION;
break;
case install_all:
part_sel = ALL_PARTITIONS;
break;
case install_all_but_update:
part_sel = REMOVE_UPDATE_PARTITION;
break;
}
if (copy_1_1) {
part_sel = ALL_PARTITIONS;
}
extern wbfs_t *hdd;
wbfs_t *old_hdd = hdd;
hdd = part; // used by spinner
ret = wbfs_add_disc(part, __WBFS_ReadDVD, NULL, WBFS_Spinner, part_sel, copy_1_1);
hdd = old_hdd;
wbfs_trim(part);
WBFS_FAT_ClosePart(part);
if (ret < 0) return ret;
mk_title_txt(&header, path);
return 0;
}
s32 WBFS_FAT_DVD_Size(u64 *comp_size, u64 *real_size)
{
s32 ret;
u32 comp_sec = 0, last_sec = 0;
wbfs_t *part = NULL;
u64 size = (u64)143432*2*0x8000ULL;
u32 n_sector = size / fat_sector_size;
u32 wii_sec_sz;
// init a temporary dummy part
// as a placeholder for wbfs_size_disc
part = wbfs_open_partition(
nop_read_sector, nop_write_sector,
NULL, fat_sector_size, n_sector, 0, 1);
if (!part) return -1;
wii_sec_sz = part->wii_sec_sz;
/* Add game to device */
partition_selector_t part_sel;
if (Settings.partitions_to_install) {
part_sel = ALL_PARTITIONS;
} else {
part_sel = ONLY_GAME_PARTITION;
}
ret = wbfs_size_disc(part, __WBFS_ReadDVD, NULL, part_sel, &comp_sec, &last_sec);
wbfs_close(part);
if (ret < 0)
return ret;
*comp_size = (u64)wii_sec_sz * comp_sec;
*real_size = (u64)wii_sec_sz * last_sec;
return 0;
}
s32 WBFS_FAT_RenameGame(u8 *discid, const void *newname)
{
wbfs_t *part = WBFS_FAT_OpenPart((char *) discid);
if (!part)
return -1;
s32 ret = wbfs_ren_disc(part, discid,(u8*)newname);
WBFS_FAT_ClosePart(part);
return ret;
}
s32 WBFS_FAT_ReIDGame(u8 *discid, const void *newID)
{
wbfs_t *part = WBFS_FAT_OpenPart((char *) discid);
if (!part)
return -1;
s32 ret = wbfs_rID_disc(part, discid,(u8*)newID);
WBFS_FAT_ClosePart(part);
if(ret == 0)
{
char fname[100];
char fnamenew[100];
s32 cnt = 0x31;
WBFS_FAT_fname(discid, fname, sizeof(fname), NULL);
WBFS_FAT_fname((u8*) newID, fnamenew, sizeof(fnamenew), NULL);
int stringlength = strlen(fname);
while(rename(fname, fnamenew) == 0)
{
fname[stringlength] = cnt;
fname[stringlength+1] = 0;
fnamenew[stringlength] = cnt;
fnamenew[stringlength+1] = 0;
cnt++;
}
}
return ret;
}
s32 WBFS_FAT_EstimateGameSize(void) {
wbfs_t *part = NULL;
u64 size = (u64)143432*2*0x8000ULL;
u32 n_sector = size / fat_sector_size;
u32 wii_sec_sz;
// init a temporary dummy part
// as a placeholder for wbfs_size_disc
part = wbfs_open_partition(
nop_read_sector, nop_write_sector,
NULL, fat_sector_size, n_sector, 0, 1);
if (!part) return -1;
wii_sec_sz = part->wii_sec_sz;
partition_selector_t part_sel;
if (Settings.fullcopy) {
part_sel = ALL_PARTITIONS;
} else {
part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS;
}
return wbfs_estimate_disc(part, __WBFS_ReadDVD, NULL, part_sel);
}