usbloadergx/source/usbloader/wbfs.c
dimok321 587fdbbae2 *Reverting some stuff to the OLD way before new IOS222
Now if you use 249 there is no change to R492 before 222.    
  So if you still get blackscreens it wasnt caused by that.
2009-06-13 23:39:42 +00:00

539 lines
8.6 KiB
C

#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <ogcsys.h>
#include <errno.h>
#include "sdhc.h"
#include "usbstorage.h"
#include "utils.h"
#include "video.h"
#include "wdvd.h"
#include "wbfs.h"
#include "libwbfs/libwbfs.h"
/* Constants */
#define MAX_NB_SECTORS 32
/* WBFS HDD */
static wbfs_t *hdd = NULL;
/* WBFS callbacks */
static rw_sector_callback_t readCallback = NULL;
static rw_sector_callback_t writeCallback = NULL;
/* Variables */
static u32 nb_sectors, sector_size;
void __WBFS_Spinner(s32 x, s32 max)
{
static time_t start;
static u32 expected;
f32 percent, size;
u32 d, h, m, s;
/* First time */
if (!x) {
start = time(0);
expected = 300;
}
/* Elapsed time */
d = time(0) - start;
if (x != max) {
/* Expected time */
if (d)
expected = (expected * 3 + d * max / x) / 4;
/* Remaining time */
d = (expected > d) ? (expected - d) : 0;
}
/* Calculate time values */
h = d / 3600;
m = (d / 60) % 60;
s = d % 60;
/* Calculate percentage/size */
percent = (x * 100.0) / max;
size = (hdd->wii_sec_sz / GB_SIZE) * max;
//Con_ClearLine();
/* Show progress */
if (x != max) {
printf(" %.2f%% of %.2fGB (%c) ETA: %d:%02d:%02d\r", percent, size, "/|\\-"[(x / 10) % 4], h, m, s);
fflush(stdout);
} else
printf(" %.2fGB copied in %d:%02d:%02d\n", size, h, m, s);
}
wbfs_t *GetHddInfo(void)
{
return hdd;
}
s32 __WBFS_ReadDVD(void *fp, u32 lba, u32 len, void *iobuf)
{
void *buffer = NULL;
u64 offset;
u32 mod, size;
s32 ret;
/* Calculate offset */
offset = ((u64)lba) << 2;
/* Calcualte sizes */
mod = len % 32;
size = len - mod;
/* Read aligned data */
if (size) {
ret = WDVD_UnencryptedRead(iobuf, size, offset);
if (ret < 0)
goto out;
}
/* Read non-aligned data */
if (mod) {
/* Allocate memory */
buffer = memalign(32, 0x20);
if (!buffer)
return -1;
/* Read data */
ret = WDVD_UnencryptedRead(buffer, 0x20, offset + size);
if (ret < 0)
goto out;
/* Copy data */
memcpy(iobuf + size, buffer, mod);
}
/* Success */
ret = 0;
out:
/* Free memory */
if (buffer)
free(buffer);
return ret;
}
s32 __WBFS_ReadUSB(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do reads */
while (cnt < count) {
void *ptr = ((u8 *)iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Read sectors is too big */
if (sectors > MAX_NB_SECTORS)
sectors = MAX_NB_SECTORS;
/* USB read */
ret = USBStorage_ReadSectors(lba + cnt, sectors, ptr);
if (ret < 0)
return ret;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 __WBFS_WriteUSB(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do writes */
while (cnt < count) {
void *ptr = ((u8 *)iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Write sectors is too big */
if (sectors > MAX_NB_SECTORS)
sectors = MAX_NB_SECTORS;
/* USB write */
ret = USBStorage_WriteSectors(lba + cnt, sectors, ptr);
if (ret < 0)
return ret;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 __WBFS_ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do reads */
while (cnt < count) {
void *ptr = ((u8 *)iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Read sectors is too big */
if (sectors > MAX_NB_SECTORS)
sectors = MAX_NB_SECTORS;
/* SDHC read */
ret = SDHC_ReadSectors(lba + cnt, sectors, ptr);
if (!ret)
return -1;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 __WBFS_WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf)
{
u32 cnt = 0;
s32 ret;
/* Do writes */
while (cnt < count) {
void *ptr = ((u8 *)iobuf) + (cnt * sector_size);
u32 sectors = (count - cnt);
/* Write sectors is too big */
if (sectors > MAX_NB_SECTORS)
sectors = MAX_NB_SECTORS;
/* SDHC write */
ret = SDHC_WriteSectors(lba + cnt, sectors, ptr);
if (!ret)
return -1;
/* Increment counter */
cnt += sectors;
}
return 0;
}
s32 WBFS_Init(u32 device)
{
s32 ret;
switch (device) {
case WBFS_DEVICE_USB:
/* Initialize USB storage */
ret = USBStorage_Init();
if (ret >= 0) {
/* Setup callbacks */
readCallback = __WBFS_ReadUSB;
writeCallback = __WBFS_WriteUSB;
/* Device info */
/* Get USB capacity */
nb_sectors = USBStorage_GetCapacity(&sector_size);
if (!nb_sectors)
return -1;
}
else
return ret;
break;
case WBFS_DEVICE_SDHC:
/* Initialize SDHC */
ret = SDHC_Init();
if (ret) {
/* Setup callbacks */
readCallback = __WBFS_ReadSDHC;
writeCallback = __WBFS_WriteSDHC;
/* Device info */
nb_sectors = 0;
sector_size = SDHC_SECTOR_SIZE;
}
else
return -1;
break;
}
return 0;
}
//s32 WBFS_Init(void)
//{
// s32 ret;
//
// /* Initialize USB storage */
// ret = USBStorage_Init();
// if (ret < 0)
// return ret;
//
// /* Get USB capacity */
// nb_sectors = USBStorage_GetCapacity(&sector_size);
// if (!nb_sectors)
// return -1;
//
// return 0;
//}
/*
s32 WBFS_Init(u32 device, u32 timeout)
{
u32 cnt;
s32 ret;
// Wrong timeout
if (!timeout)
return -1;
// Try to mount device
for (cnt = 0; cnt < timeout; cnt++) {
switch (device) {
case WBFS_DEVICE_USB: {
// Initialize USB storage
ret = USBStorage_Init();
if (ret >= 0) {
// Setup callbacks
readCallback = __WBFS_ReadUSB;
writeCallback = __WBFS_WriteUSB;
// Device info
nb_sectors = USBStorage_GetCapacity(&sector_size);
goto out;
}
}
case WBFS_DEVICE_SDHC: {
// Initialize SDHC
ret = SDHC_Init();
if (ret) {
// Setup callbacks
readCallback = __WBFS_ReadSDHC;
writeCallback = __WBFS_WriteSDHC;
// Device info
nb_sectors = 0;
sector_size = SDHC_SECTOR_SIZE;
goto out;
} else
ret = -1;
}
default:
return -1;
}
// Sleep 1 second
sleep(1);
}
out:
return ret;
}
*/
s32 WBFS_Open(void)
{
/* Close hard disk */
if (hdd)
wbfs_close(hdd);
/* Open hard disk */
hdd = wbfs_open_hd(readCallback, writeCallback, NULL, sector_size, nb_sectors, 0);
if (!hdd)
return -1;
return 0;
}
s32 WBFS_Close(void)
{
/* Close hard disk */
if (hdd)
wbfs_close(hdd);
return 0;
}
s32 WBFS_Format(u32 lba, u32 size)
{
wbfs_t *partition = NULL;
/* Reset partition */
partition = wbfs_open_partition(readCallback, writeCallback, NULL, sector_size, size, lba, 1);
if (!partition)
return -1;
/* Free memory */
wbfs_close(partition);
return 0;
}
s32 WBFS_GetCount(u32 *count)
{
/* No device open */
if (!hdd)
return -1;
/* Get list length */
*count = wbfs_count_discs(hdd);
return 0;
}
s32 WBFS_GetHeaders(void *outbuf, u32 cnt, u32 len)
{
u32 idx, size;
s32 ret;
/* No device open */
if (!hdd)
return -1;
for (idx = 0; idx < cnt; idx++) {
u8 *ptr = ((u8 *)outbuf) + (idx * len);
/* Get header */
ret = wbfs_get_disc_info(hdd, idx, ptr, len, &size);
if (ret < 0)
return ret;
}
return 0;
}
s32 WBFS_CheckGame(u8 *discid)
{
wbfs_disc_t *disc = NULL;
/* Try to open game disc */
disc = wbfs_open_disc(hdd, discid);
if (disc) {
/* Close disc */
wbfs_close_disc(disc);
return 1;
}
return 0;
}
s32 WBFS_AddGame(void)
{
s32 ret;
/* No device open */
if (!hdd)
return -1;
/* Add game to device */
ret = wbfs_add_disc(hdd, __WBFS_ReadDVD, NULL, __WBFS_Spinner, ALL_PARTITIONS, 0);
if (ret < 0)
return ret;
return 0;
}
s32 WBFS_RemoveGame(u8 *discid)
{
s32 ret;
/* No device open */
if (!hdd)
return -1;
/* Remove game from USB device */
ret = wbfs_rm_disc(hdd, discid);
if (ret < 0)
return ret;
return 0;
}
s32 WBFS_GameSize(u8 *discid, f32 *size)
{
wbfs_disc_t *disc = NULL;
u32 sectors;
/* No device open */
if (!hdd)
return -1;
/* Open disc */
disc = wbfs_open_disc(hdd, discid);
if (!disc)
return -2;
/* Get game size in sectors */
sectors = wbfs_sector_used(hdd, disc->header);
/* Close disc */
wbfs_close_disc(disc);
/* Copy value */
*size = (hdd->wbfs_sec_sz / GB_SIZE) * sectors;
return 0;
}
s32 WBFS_DiskSpace(f32 *used, f32 *free)
{
f32 ssize;
u32 cnt;
/* No device open */
if (!hdd)
return -1;
/* Count used blocks */
cnt = wbfs_count_usedblocks(hdd);
/* Sector size in GB */
ssize = hdd->wbfs_sec_sz / GB_SIZE;
/* Copy values */
*free = ssize * cnt;
*used = ssize * (hdd->n_wbfs_sec - cnt);
return 0;
}
s32 WBFS_RenameGame(u8 *discid, const void *newname)
{
s32 ret;
/* No USB device open */
if (!hdd)
return -1;
ret = wbfs_ren_disc(hdd, discid,(u8*)newname);
if (ret < 0)
return ret;
return 0;
}
f32 WBFS_EstimeGameSize(void)
{
return wbfs_estimate_disc(hdd, __WBFS_ReadDVD, NULL, ONLY_GAME_PARTITION);
}