Added changed libwbfs by oggzee.

This commit is contained in:
e.bovendeur 2009-12-19 15:47:12 +00:00
parent f3ce461dc6
commit 27024a9ad1
8 changed files with 273 additions and 178 deletions

View File

@ -2,8 +2,8 @@
<app version="1">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>1.0 r867</version>
<release_date>200912161915</release_date>
<version>1.0 r869</version>
<release_date>200912191425</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.

View File

@ -141,8 +141,7 @@ const u8 *LoadBannerSound(const u8 *discid, u32 *size)
WindowPrompt(tr("Could not open Disc"), 0, tr("OK"));
return NULL;
}
u32 opening_bnr_size = 0;
u8 * opening_bnr = wd_extract_file(wdisc, &opening_bnr_size, ALL_PARTITIONS, (char *) "opening.bnr");
u8 * opening_bnr = wd_extract_file(wdisc, ALL_PARTITIONS, (char *) "opening.bnr");
if(!opening_bnr)
{
//WindowPrompt(tr("ERROR"), tr("Failed to extract opening.bnr"), tr("OK"));

View File

@ -818,7 +818,7 @@ static s64 ntfs_attr_getfragments_i(ntfs_attr *na, const s64 pos, s64 count, u64
s64 br, to_read, ofs, total, total2, max_read, max_init;
ntfs_volume *vol;
runlist_element *rl;
u16 efs_padding_length;
// u16 efs_padding_length;
/* Sanity checking arguments is done in ntfs_attr_pread(). */

View File

@ -2,6 +2,8 @@
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
// Modified by oggzee
#include "libwbfs.h"
@ -14,10 +16,12 @@
wbfs_t wbfs_iso_file;
static int force_mode=0;
void wbfs_set_force_mode(int force)
{
force_mode = force;
}
static u8 size_to_shift(u32 size)
{
u8 ret = 0;
@ -53,14 +57,13 @@ wbfs_t*wbfs_open_hd(rw_sector_callback_t read_hdsector,
// verify there is the magic.
if (head->magic == wbfs_htonl(WBFS_MAGIC))
{
// Override the sector size by the sector size in the wbfs header...
hd_sector_size = 1 << head->hd_sec_sz_s;
wbfs_t*p = wbfs_open_partition(read_hdsector,write_hdsector,
callback_data,hd_sector_size,0,part_lba,reset);
wbfs_iofree(tmp_buffer);
return p;
}
}
wbfs_iofree(tmp_buffer);
if(reset)// XXX make a empty hd partition..
{
}
@ -157,6 +160,7 @@ void wbfs_sync(wbfs_t*p)
p->write_hdsector(p->callback_data,p->part_lba+p->freeblks_lba,ALIGN_LBA(p->n_wbfs_sec/8)>>p->hd_sec_sz_s, p->freeblks);
}
}
void wbfs_close(wbfs_t*p)
{
wbfs_sync(p);
@ -296,6 +300,7 @@ u32 wbfs_count_discs(wbfs_t*p)
return count;
}
u32 wbfs_sector_used(wbfs_t *p,wbfs_disc_info_t *di)
{
u32 tot_blk=0,j;
@ -303,12 +308,25 @@ u32 wbfs_sector_used(wbfs_t *p,wbfs_disc_info_t *di)
if(wbfs_ntohs(di->wlba_table[j]))
tot_blk++;
return tot_blk;
}
u32 wbfs_sector_used2(wbfs_t *p, wbfs_disc_info_t *di, u32 *last_blk)
{
u32 tot_blk=0,j;
for(j=0;j<p->n_wbfs_sec_per_disc;j++)
if(wbfs_ntohs(di->wlba_table[j])) {
if (last_blk) *last_blk = j;
tot_blk++;
}
return tot_blk;
}
u32 wbfs_get_disc_info(wbfs_t*p, u32 index,u8 *header,int header_size,u32 *size)//size in 32 bit
{
u32 i,count=0;
if (!p) return 1;
int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s;
for(i=0;i<p->max_disc;i++)
if (p->head->disc_table[i]){
if(count++==index)
@ -368,7 +386,8 @@ u32 wbfs_count_usedblocks(wbfs_t*p)
// write access
static int block_used(u8 *used,u32 i,u32 wblk_sz)
//static
int block_used(u8 *used,u32 i,u32 wblk_sz)
{
u32 k;
i*=wblk_sz;
@ -403,6 +422,7 @@ static void free_block(wbfs_t *p,int bl)
u32 v = wbfs_ntohl(p->freeblks[i]);
p->freeblks[i] = wbfs_htonl(v | 1<<j);
}
u32 wbfs_add_disc(wbfs_t*p, read_wiidisc_callback_t read_src_wii_disc,
void *callback_data,progress_callback_t spinner,partition_selector_t sel,int copy_1_1)
{
@ -413,10 +433,15 @@ u32 wbfs_add_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
u8 *used = 0;
wbfs_disc_info_t *info = 0;
u8* copy_buffer = 0;
int retval = -1;
int num_wbfs_sect_to_copy;
u32 last_used;
used = wbfs_malloc(p->n_wii_sec_per_disc);
if(!used)
ERROR("unable to alloc memory");
if(!copy_1_1)
// copy_1_1 needs disk usage for layers detection
//if(!copy_1_1)
{
d = wd_open_disc(read_src_wii_disc,callback_data);
if(!d)
@ -426,7 +451,6 @@ u32 wbfs_add_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
d = 0;
}
for(i=0;i<p->max_disc;i++)// find a free slot.
if(p->head->disc_table[i]==0)
break;
@ -445,13 +469,36 @@ u32 wbfs_add_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
ERROR("alloc memory");
tot=0;
cur=0;
if(spinner){
// count total number to write for spinner
for(i=0; i<p->n_wbfs_sec_per_disc;i++)
if(copy_1_1 || block_used(used,i,wii_sec_per_wbfs_sect)) tot += wii_sec_per_wbfs_sect;
spinner(0,tot);
num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc;
// count total number of sectors to write
last_used = 0;
for(i=0; i<num_wbfs_sect_to_copy; i++) {
if(block_used(used,i,wii_sec_per_wbfs_sect)) {
tot += wii_sec_per_wbfs_sect;
last_used = i;
}
for(i=0; i<p->n_wbfs_sec_per_disc;i++){
}
if (copy_1_1) {
// detect single or dual layer
if ( (last_used + 1) > (p->n_wbfs_sec_per_disc / 2) ) {
// dual layer
num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc;
} else {
// single layer
num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc / 2;
}
tot = num_wbfs_sect_to_copy * wii_sec_per_wbfs_sect;
}
/*
// num of hd sectors to copy could be specified directly
if (copy_1_1 > 1) {
u32 hd_sec_per_wii_sec = p->wii_sec_sz / p->hd_sec_sz;
num_wbfs_sect_to_copy = copy_1_1 / hd_sec_per_wii_sec / wii_sec_per_wbfs_sect;
tot = num_wbfs_sect_to_copy * wii_sec_per_wbfs_sect;
}*/
int ret = 0;
if(spinner) spinner(0,tot);
for(i=0; i<num_wbfs_sect_to_copy; i++){
u16 bl = 0;
if(copy_1_1 || block_used(used,i,wii_sec_per_wbfs_sect)) {
u16 j;
@ -462,24 +509,39 @@ u32 wbfs_add_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
for(j=0; j<wii_sec_per_wbfs_sect;j++) {
u32 offset = (i*(p->wbfs_sec_sz>>2)) + (j*(p->wii_sec_sz>>2));
read_src_wii_disc(callback_data,offset,p->wii_sec_sz,copy_buffer);
ret = read_src_wii_disc(callback_data,offset,p->wii_sec_sz,copy_buffer);
if (ret) {
if (copy_1_1 && i > p->n_wbfs_sec_per_disc / 2) {
// end of dual layer data
if (j > 0) {
info->wlba_table[i] = wbfs_htons(bl);
}
spinner(tot,tot);
break;
}
//ERROR("read error");
printf("\rWARNING: read (%u) error (%d)\n", offset, ret);
}
//fix the partition table
if(offset == (0x40000>>2))
wd_fix_partition_table(d, sel, copy_buffer);
p->write_hdsector(p->callback_data,p->part_lba+bl*(p->wbfs_sec_sz/p->hd_sec_sz)+j*(p->wii_sec_sz/p->hd_sec_sz),
p->write_hdsector(p->callback_data,
p->part_lba+bl*(p->wbfs_sec_sz/p->hd_sec_sz) + j*(p->wii_sec_sz/p->hd_sec_sz),
p->wii_sec_sz/p->hd_sec_sz, copy_buffer);
cur++;
if(spinner)
spinner(cur,tot);
}
}
if (ret) break;
info->wlba_table[i] = wbfs_htons(bl);
}
// write disc info
int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s;
p->write_hdsector(p->callback_data,p->part_lba+1+discn*disc_info_sz_lba,disc_info_sz_lba,info);
wbfs_sync(p);
retval = 0;
error:
if(d)
wd_close_disc(d);
@ -491,7 +553,7 @@ error:
wbfs_iofree(copy_buffer);
// init with all free blocks
return 0;
return retval;
}
u32 wbfs_rm_disc(wbfs_t*p, u8* discid)
@ -551,7 +613,19 @@ u32 wbfs_rID_disc(wbfs_t*p, u8* discid, u8* newID)
}
// trim the file-system to its minimum size
u32 wbfs_trim(wbfs_t*p);
u32 wbfs_trim(wbfs_t*p)
{
u32 maxbl;
load_freeblocks(p);
maxbl = alloc_block(p);
p->n_hd_sec = maxbl<<(p->wbfs_sec_sz_s-p->hd_sec_sz_s);
p->head->n_hd_sec = wbfs_htonl(p->n_hd_sec);
// make all block full
memset(p->freeblks,0,p->n_wbfs_sec/8);
wbfs_sync(p);
// os layer will truncate the file.
return maxbl;
}
// data extraction
u32 wbfs_extract_disc(wbfs_disc_t*d, rw_sector_callback_t write_dst_wii_sector,void *callback_data,progress_callback_t spinner)
@ -582,7 +656,6 @@ u32 wbfs_extract_disc(wbfs_disc_t*d, rw_sector_callback_t write_dst_wii_sector,v
error:
return 1;
}
u32 wbfs_extract_file(wbfs_disc_t*d, char *path);
float wbfs_estimate_disc
(
@ -643,7 +716,6 @@ error:
return tot * (((p->wbfs_sec_sz*1.0) / p->hd_sec_sz) * 512);
}
u32 wbfs_size_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
void *callback_data,partition_selector_t sel,
u32 *comp_size, u32 *real_size)
@ -683,19 +755,38 @@ error:
return 0;
}
// trim the file-system to its minimum size
u32 wbfs_trim(wbfs_t*p)
// offset is pointing 32bit words to address the whole dvd, although len is in bytes
//int wbfs_disc_read(wbfs_disc_t*d,u32 offset, u8 *data, u32 len)
// offset points 32bit words, count counts bytes
//int (*read_wiidisc_callback_t)(void*fp,u32 offset,u32 count,void*iobuf);
// connect wiidisc to wbfs_disc
int read_wiidisc_wbfsdisc(void*fp,u32 offset,u32 count,void*iobuf)
{
u32 maxbl;
load_freeblocks(p);
maxbl = alloc_block(p);
p->n_hd_sec = maxbl<<(p->wbfs_sec_sz_s-p->hd_sec_sz_s);
p->head->n_hd_sec = wbfs_htonl(p->n_hd_sec);
// make all block full
memset(p->freeblks,0,p->n_wbfs_sec/8);
wbfs_sync(p);
// os layer will truncate the file.
return maxbl;
return wbfs_disc_read((wbfs_disc_t*)fp, offset, count, iobuf);
}
int wbfs_extract_file(wbfs_disc_t*d, char *path, void **data)
{
wiidisc_t *wd = 0;
int ret = 0;
wd = wd_open_disc(read_wiidisc_wbfsdisc, d);
if (!wd) {
ERROR("opening wbfs disc");
return -1;
}
wd->extracted_size = 0;
*data = wd_extract_file(wd, ONLY_GAME_PARTITION, path);
ret = wd->extracted_size;
if (!*data) {
//ERROR("file not found");
ret = -1;
}
wd_close_disc(wd);
error:
return ret;
}
int wbfs_get_fragments(wbfs_disc_t *d, _frag_append_t append_fragment, void *callback_data)
@ -756,7 +847,7 @@ u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk)
}
return st.st_blocks; // in 512 units (can be sparse)
}
u32 last_blk;
u32 last_blk = 0;
u32 ret;
ret = wbfs_sector_used2(d->p, d->header, &last_blk);
if (num_blk) {
@ -764,3 +855,5 @@ u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk)
}
return ret;
}

View File

@ -1,3 +1,6 @@
// Modified by oggzee
#ifndef LIBWBFS_H
#define LIBWBFS_H
@ -150,6 +153,7 @@ wbfs_disc_t *wbfs_open_disc(wbfs_t* p, u8 *diskid);
void wbfs_close_disc(wbfs_disc_t*d);
u32 wbfs_sector_used(wbfs_t *p,wbfs_disc_info_t *di);
u32 wbfs_sector_used2(wbfs_t *p,wbfs_disc_info_t *di, u32 *last_blk);
/*! @brief accessor to the wii disc
@param d: a pointer to already open disc
@ -159,7 +163,7 @@ u32 wbfs_sector_used(wbfs_t *p,wbfs_disc_info_t *di);
// offset is pointing 32bit words to address the whole dvd, although len is in bytes
int wbfs_disc_read(wbfs_disc_t*d,u32 offset, u32 len, u8 *data);
/*! @return the number of discs inside the paritition */
/*! @return the number of discs inside the partition */
u32 wbfs_count_discs(wbfs_t*p);
/*! get the disc info of ith disc inside the partition. It correspond to the first 0x100 bytes of the wiidvd
http://www.wiibrew.org/wiki/Wiidisc#Header
@ -195,7 +199,6 @@ u32 wbfs_ren_disc(wbfs_t*p, u8* discid, u8* newname);
/* change ID of a game*/
u32 wbfs_rID_disc(wbfs_t*p, u8* discid, u8* newID);
/*! trim the file-system to its minimum size
This allows to use wbfs as a wiidisc container
*/
@ -209,7 +212,7 @@ u32 wbfs_extract_disc(wbfs_disc_t*d, rw_sector_callback_t write_dst_wii_sector,v
/*! extract a file from the wii disc filesystem.
E.G. Allows to extract the opening.bnr to install a game as a system menu channel
*/
u32 wbfs_extract_file(wbfs_disc_t*d, char *path);
int wbfs_extract_file(wbfs_disc_t*d, char *path, void **data);
// remove some sanity checks
void wbfs_set_force_mode(int force);
@ -218,7 +221,6 @@ float wbfs_estimate_disc(
wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc,
void *callback_data,
partition_selector_t sel);
// compressed and real size
u32 wbfs_size_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
void *callback_data,partition_selector_t sel,
@ -231,10 +233,6 @@ extern wbfs_t wbfs_iso_file;
u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk);
int wbfs_iso_file_read(wbfs_disc_t*d,u32 offset, u8 *data, u32 len);
/*! trim the file-system to its minimum size
This allows to use wbfs as a wiidisc container
*/
u32 wbfs_trim(wbfs_t*p);
#ifdef __cplusplus
}

View File

@ -122,12 +122,11 @@ static u32 do_fst(wiidisc_t *d,u8 *fst, const char *names, u32 i)
return size;
} else {
offset = _be32(fst + 12*i + 4);
if(d->extract_pathname && stricmp(name, d->extract_pathname)==0)
if(d->extract_pathname && strcasecmp(name, d->extract_pathname)==0)
{
d->extracted_buffer = wbfs_ioalloc(size);
d->extracted_size = size;
partition_read(d,offset, d->extracted_buffer, size,0);
if(d->extracted_buffer != 0)
d->extracted_buffer_size = size;
}else
partition_read(d,offset, 0, size,1);
return i + 1;
@ -165,10 +164,20 @@ static void do_files(wiidisc_t*d)
partition_read(d,fst_offset, fst, fst_size,0);
n_files = _be32(fst + 8);
if (d->extract_pathname && *d->extract_pathname == 0) {
// if empty pathname requested return fst
d->extracted_buffer = fst;
d->extracted_size = fst_size;
d->extract_pathname = NULL;
// skip do_fst if only fst requested
n_files = 0;
}
if (n_files > 1)
do_fst(d,fst, (char *)fst + 12*n_files, 0);
wbfs_iofree(b);
wbfs_iofree(apl_header);
if (fst != d->extracted_buffer)
wbfs_iofree(fst);
}
@ -283,7 +292,7 @@ void wd_close_disc(wiidisc_t *d)
// returns a buffer allocated with wbfs_ioalloc() or NULL if not found of alloc error
// XXX pathname not implemented. files are extracted by their name.
// first file found with that name is returned.
u8 * wd_extract_file(wiidisc_t *d, u32 *size, partition_selector_t partition_type, char *pathname)
u8 * wd_extract_file(wiidisc_t *d, partition_selector_t partition_type, char *pathname)
{
u8 *retval = 0;
d->extract_pathname = pathname;
@ -293,10 +302,7 @@ u8 * wd_extract_file(wiidisc_t *d, u32 *size, partition_selector_t partition_typ
d->extract_pathname = 0;
d->part_sel = ALL_PARTITIONS;
retval = d->extracted_buffer;
if (size != 0)
*size = d->extracted_buffer_size;
d->extracted_buffer = 0;
d->extracted_buffer_size = 0;
return retval;
}

View File

@ -45,13 +45,13 @@ typedef struct wiidisc_s
char *extract_pathname;
u8 *extracted_buffer;
u32 extracted_buffer_size;
int extracted_size;
}wiidisc_t;
wiidisc_t *wd_open_disc(read_wiidisc_callback_t read,void*fp);
void wd_close_disc(wiidisc_t *);
// returns a buffer allocated with wbfs_ioalloc() or NULL if not found of alloc error
u8 * wd_extract_file(wiidisc_t *d, u32 *size, partition_selector_t partition_type, char *pathname);
u8 * wd_extract_file(wiidisc_t *d, partition_selector_t partition_type, char *pathname);
void wd_build_disc_usage(wiidisc_t *d, partition_selector_t selector, u8* usage_table);

View File

@ -185,8 +185,7 @@ main(int argc, char *argv[]) {
// DEBUG_Init(GDBSTUB_DEVICE_USB, 1);
//_break();
__exception_setreload(5);//auto reset code dump nobody gives us codedump info anyways.
// __exception_setreload(5);//auto reset code dump nobody gives us codedump info anyways.
gprintf("\n\n------------------");
gprintf("\nUSB Loader GX rev%s",GetRev());