mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-25 20:56:53 +01:00
* 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:
parent
275aee0dab
commit
ce5930f297
@ -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
BIN
data/fatffs_module.bin
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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 }
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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];
|
||||
|
@ -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
@ -1,3 +0,0 @@
|
||||
#define size_fatffs_module 58440
|
||||
|
||||
extern unsigned char fatffs_module[58440];
|
@ -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;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "dip_plugin.h"
|
||||
#include "mload.h"
|
||||
#include "fatffs_module.h"
|
||||
#include "fatffs_module_bin.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -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))
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -19,7 +19,8 @@ extern "C" {
|
||||
u8 bufsize;
|
||||
|
||||
/* Padding */
|
||||
u8 unused1[14];
|
||||
u8 is_ciso;
|
||||
u8 unused1[13];
|
||||
|
||||
/* Magic word */
|
||||
u32 magic;
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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(§or_size);
|
||||
ret = USBStorage2_GetCapacity(§or_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(§or_size);
|
||||
ret = USBStorage2_GetCapacity(§or_size);
|
||||
if (ret == 0) return -1;
|
||||
break;
|
||||
case WBFS_DEVICE_SDHC:
|
||||
|
17
source/usbloader/spinner.c
Normal file
17
source/usbloader/spinner.c
Normal 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;
|
||||
}
|
15
source/usbloader/spinner.h
Normal file
15
source/usbloader/spinner.h
Normal 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
|
@ -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", §or_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
|
||||
};
|
@ -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
|
456
source/usbloader/usbstorage2.c
Normal file
456
source/usbloader/usbstorage2.c
Normal 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", §or_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(§or_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;
|
||||
}
|
33
source/usbloader/usbstorage2.h
Normal file
33
source/usbloader/usbstorage2.h
Normal 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
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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(§or_size);
|
||||
nb_sectors = USBStorage2_GetCapacity(§or_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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
25
source/usbloader/wbfs/wbfs_rw.h
Normal file
25
source/usbloader/wbfs/wbfs_rw.h
Normal 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
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user