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"> <app version="1">
<name> USB Loader GX</name> <name> USB Loader GX</name>
<coder>USB Loader GX Team</coder> <coder>USB Loader GX Team</coder>
<version>1.0 r867</version> <version>1.0 r869</version>
<release_date>200912161915</release_date> <release_date>200912191425</release_date>
<short_description>Loads games from USB-devices</short_description> <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. <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. 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")); WindowPrompt(tr("Could not open Disc"), 0, tr("OK"));
return NULL; return NULL;
} }
u32 opening_bnr_size = 0; u8 * opening_bnr = wd_extract_file(wdisc, ALL_PARTITIONS, (char *) "opening.bnr");
u8 * opening_bnr = wd_extract_file(wdisc, &opening_bnr_size, ALL_PARTITIONS, (char *) "opening.bnr");
if(!opening_bnr) if(!opening_bnr)
{ {
//WindowPrompt(tr("ERROR"), tr("Failed to extract opening.bnr"), tr("OK")); //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; s64 br, to_read, ofs, total, total2, max_read, max_init;
ntfs_volume *vol; ntfs_volume *vol;
runlist_element *rl; runlist_element *rl;
u16 efs_padding_length; // u16 efs_padding_length;
/* Sanity checking arguments is done in ntfs_attr_pread(). */ /* 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 // Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
// Modified by oggzee
#include "libwbfs.h" #include "libwbfs.h"
@ -14,10 +16,12 @@
wbfs_t wbfs_iso_file; wbfs_t wbfs_iso_file;
static int force_mode=0; static int force_mode=0;
void wbfs_set_force_mode(int force) void wbfs_set_force_mode(int force)
{ {
force_mode = force; force_mode = force;
} }
static u8 size_to_shift(u32 size) static u8 size_to_shift(u32 size)
{ {
u8 ret = 0; u8 ret = 0;
@ -53,14 +57,13 @@ wbfs_t*wbfs_open_hd(rw_sector_callback_t read_hdsector,
// verify there is the magic. // verify there is the magic.
if (head->magic == wbfs_htonl(WBFS_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, wbfs_t*p = wbfs_open_partition(read_hdsector,write_hdsector,
callback_data,hd_sector_size,0,part_lba,reset); callback_data,hd_sector_size,0,part_lba,reset);
wbfs_iofree(tmp_buffer);
return p; return p;
} }
} }
wbfs_iofree(tmp_buffer);
if(reset)// XXX make a empty hd partition.. 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); 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) void wbfs_close(wbfs_t*p)
{ {
wbfs_sync(p); wbfs_sync(p);
@ -296,6 +300,7 @@ u32 wbfs_count_discs(wbfs_t*p)
return count; return count;
} }
u32 wbfs_sector_used(wbfs_t *p,wbfs_disc_info_t *di) u32 wbfs_sector_used(wbfs_t *p,wbfs_disc_info_t *di)
{ {
u32 tot_blk=0,j; u32 tot_blk=0,j;
@ -303,17 +308,30 @@ u32 wbfs_sector_used(wbfs_t *p,wbfs_disc_info_t *di)
if(wbfs_ntohs(di->wlba_table[j])) if(wbfs_ntohs(di->wlba_table[j]))
tot_blk++; tot_blk++;
return 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 wbfs_get_disc_info(wbfs_t*p, u32 index,u8 *header,int header_size,u32 *size)//size in 32 bit
{ {
u32 i,count=0; u32 i,count=0;
if (!p) return 1;
int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s; int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s;
for(i=0;i<p->max_disc;i++) for(i=0;i<p->max_disc;i++)
if (p->head->disc_table[i]){ if (p->head->disc_table[i]){
if(count++==index) if(count++==index)
{ {
p->read_hdsector(p->callback_data, p->read_hdsector(p->callback_data,
p->part_lba+1+i*disc_info_sz_lba,1,p->tmp_buffer); p->part_lba+1+i*disc_info_sz_lba,1,p->tmp_buffer);
if(header_size > (int)p->hd_sec_sz) if(header_size > (int)p->hd_sec_sz)
header_size = p->hd_sec_sz; header_size = p->hd_sec_sz;
@ -368,7 +386,8 @@ u32 wbfs_count_usedblocks(wbfs_t*p)
// write access // 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; u32 k;
i*=wblk_sz; i*=wblk_sz;
@ -403,119 +422,162 @@ static void free_block(wbfs_t *p,int bl)
u32 v = wbfs_ntohl(p->freeblks[i]); u32 v = wbfs_ntohl(p->freeblks[i]);
p->freeblks[i] = wbfs_htonl(v | 1<<j); 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) 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)
{ {
int i,discn; int i,discn;
u32 tot,cur; u32 tot,cur;
u32 wii_sec_per_wbfs_sect = 1<<(p->wbfs_sec_sz_s-p->wii_sec_sz_s); u32 wii_sec_per_wbfs_sect = 1<<(p->wbfs_sec_sz_s-p->wii_sec_sz_s);
wiidisc_t *d = 0; wiidisc_t *d = 0;
u8 *used = 0; u8 *used = 0;
wbfs_disc_info_t *info = 0; wbfs_disc_info_t *info = 0;
u8* copy_buffer = 0; u8* copy_buffer = 0;
used = wbfs_malloc(p->n_wii_sec_per_disc); int retval = -1;
if(!used) int num_wbfs_sect_to_copy;
ERROR("unable to alloc memory"); u32 last_used;
if(!copy_1_1) used = wbfs_malloc(p->n_wii_sec_per_disc);
{
d = wd_open_disc(read_src_wii_disc,callback_data);
if(!d)
ERROR("unable to open wii disc");
wd_build_disc_usage(d,sel,used);
wd_close_disc(d);
d = 0;
}
if(!used)
ERROR("unable to alloc memory");
// 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)
ERROR("unable to open wii disc");
wd_build_disc_usage(d,sel,used);
wd_close_disc(d);
d = 0;
}
for(i=0;i<p->max_disc;i++)// find a free slot. for(i=0;i<p->max_disc;i++)// find a free slot.
if(p->head->disc_table[i]==0) if(p->head->disc_table[i]==0)
break; break;
if(i==p->max_disc) if(i==p->max_disc)
ERROR("no space left on device (table full)"); ERROR("no space left on device (table full)");
p->head->disc_table[i] = 1; p->head->disc_table[i] = 1;
discn = i; discn = i;
load_freeblocks(p); load_freeblocks(p);
// build disc info // build disc info
info = wbfs_ioalloc(p->disc_info_sz); info = wbfs_ioalloc(p->disc_info_sz);
read_src_wii_disc(callback_data,0,0x100,info->disc_header_copy); read_src_wii_disc(callback_data,0,0x100,info->disc_header_copy);
copy_buffer = wbfs_ioalloc(p->wii_sec_sz); copy_buffer = wbfs_ioalloc(p->wii_sec_sz);
if(!copy_buffer) if(!copy_buffer)
ERROR("alloc memory"); ERROR("alloc memory");
tot=0; tot=0;
cur=0; cur=0;
if(spinner){ num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc;
// count total number to write for spinner // count total number of sectors to write
for(i=0; i<p->n_wbfs_sec_per_disc;i++) last_used = 0;
if(copy_1_1 || block_used(used,i,wii_sec_per_wbfs_sect)) tot += wii_sec_per_wbfs_sect; for(i=0; i<num_wbfs_sect_to_copy; i++) {
spinner(0,tot); if(block_used(used,i,wii_sec_per_wbfs_sect)) {
} tot += wii_sec_per_wbfs_sect;
for(i=0; i<p->n_wbfs_sec_per_disc;i++){ last_used = i;
u16 bl = 0; }
if(copy_1_1 || block_used(used,i,wii_sec_per_wbfs_sect)) { }
u16 j; 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;
bl = alloc_block(p); bl = alloc_block(p);
if (bl==0xffff) if (bl==0xffff)
ERROR("no space left on device (disc full)"); ERROR("no space left on device (disc full)");
for(j=0; j<wii_sec_per_wbfs_sect;j++) { for(j=0; j<wii_sec_per_wbfs_sect;j++) {
u32 offset = (i*(p->wbfs_sec_sz>>2)) + (j*(p->wii_sec_sz>>2)); 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 //fix the partition table
if(offset == (0x40000>>2)) if(offset == (0x40000>>2))
wd_fix_partition_table(d, sel, copy_buffer); 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->wii_sec_sz/p->hd_sec_sz,copy_buffer); p->part_lba+bl*(p->wbfs_sec_sz/p->hd_sec_sz) + j*(p->wii_sec_sz/p->hd_sec_sz),
cur++; p->wii_sec_sz/p->hd_sec_sz, copy_buffer);
if(spinner) cur++;
spinner(cur,tot); if(spinner)
} spinner(cur,tot);
} }
info->wlba_table[i] = wbfs_htons(bl); }
} if (ret) break;
// write disc info info->wlba_table[i] = wbfs_htons(bl);
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); // write disc info
wbfs_sync(p); 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: error:
if(d) if(d)
wd_close_disc(d); wd_close_disc(d);
if(used) if(used)
wbfs_free(used); wbfs_free(used);
if(info) if(info)
wbfs_iofree(info); wbfs_iofree(info);
if(copy_buffer) if(copy_buffer)
wbfs_iofree(copy_buffer); wbfs_iofree(copy_buffer);
// init with all free blocks // init with all free blocks
return 0; return retval;
} }
u32 wbfs_rm_disc(wbfs_t*p, u8* discid) u32 wbfs_rm_disc(wbfs_t*p, u8* discid)
{ {
wbfs_disc_t *d = wbfs_open_disc(p,discid); wbfs_disc_t *d = wbfs_open_disc(p,discid);
int i; int i;
int discn = 0; int discn = 0;
int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s; int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s;
if(!d) if(!d)
return 1; return 1;
load_freeblocks(p); load_freeblocks(p);
discn = d->i; discn = d->i;
for( i=0; i< p->n_wbfs_sec_per_disc; i++) for( i=0; i< p->n_wbfs_sec_per_disc; i++)
{ {
u32 iwlba = wbfs_ntohs(d->header->wlba_table[i]); u32 iwlba = wbfs_ntohs(d->header->wlba_table[i]);
if (iwlba) if (iwlba)
free_block(p,iwlba); free_block(p,iwlba);
} }
memset(d->header,0,p->disc_info_sz); memset(d->header,0,p->disc_info_sz);
p->write_hdsector(p->callback_data,p->part_lba+1+discn*disc_info_sz_lba,disc_info_sz_lba,d->header); p->write_hdsector(p->callback_data,p->part_lba+1+discn*disc_info_sz_lba,disc_info_sz_lba,d->header);
p->head->disc_table[discn] = 0; p->head->disc_table[discn] = 0;
wbfs_close_disc(d); wbfs_close_disc(d);
wbfs_sync(p); wbfs_sync(p);
return 0; return 0;
} }
u32 wbfs_ren_disc(wbfs_t*p, u8* discid, u8* newname) u32 wbfs_ren_disc(wbfs_t*p, u8* discid, u8* newname)
@ -551,7 +613,19 @@ u32 wbfs_rID_disc(wbfs_t*p, u8* discid, u8* newID)
} }
// trim the file-system to its minimum size // 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 // 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) 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: error:
return 1; return 1;
} }
u32 wbfs_extract_file(wbfs_disc_t*d, char *path);
float wbfs_estimate_disc float wbfs_estimate_disc
( (
@ -643,7 +716,6 @@ error:
return tot * (((p->wbfs_sec_sz*1.0) / p->hd_sec_sz) * 512); 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, u32 wbfs_size_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
void *callback_data,partition_selector_t sel, void *callback_data,partition_selector_t sel,
u32 *comp_size, u32 *real_size) u32 *comp_size, u32 *real_size)
@ -683,19 +755,38 @@ error:
return 0; return 0;
} }
// trim the file-system to its minimum size // offset is pointing 32bit words to address the whole dvd, although len is in bytes
u32 wbfs_trim(wbfs_t*p) //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; return wbfs_disc_read((wbfs_disc_t*)fp, offset, count, iobuf);
load_freeblocks(p); }
maxbl = alloc_block(p);
p->n_hd_sec = maxbl<<(p->wbfs_sec_sz_s-p->hd_sec_sz_s); int wbfs_extract_file(wbfs_disc_t*d, char *path, void **data)
p->head->n_hd_sec = wbfs_htonl(p->n_hd_sec); {
// make all block full wiidisc_t *wd = 0;
memset(p->freeblks,0,p->n_wbfs_sec/8); int ret = 0;
wbfs_sync(p);
// os layer will truncate the file. wd = wd_open_disc(read_wiidisc_wbfsdisc, d);
return maxbl; 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) 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) return st.st_blocks; // in 512 units (can be sparse)
} }
u32 last_blk; u32 last_blk = 0;
u32 ret; u32 ret;
ret = wbfs_sector_used2(d->p, d->header, &last_blk); ret = wbfs_sector_used2(d->p, d->header, &last_blk);
if (num_blk) { if (num_blk) {
@ -764,3 +855,5 @@ u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk)
} }
return ret; return ret;
} }

View File

@ -1,3 +1,6 @@
// Modified by oggzee
#ifndef LIBWBFS_H #ifndef LIBWBFS_H
#define 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); void wbfs_close_disc(wbfs_disc_t*d);
u32 wbfs_sector_used(wbfs_t *p,wbfs_disc_info_t *di); 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 /*! @brief accessor to the wii disc
@param d: a pointer to already open 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 // 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); 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); 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 /*! 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 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*/ /* change ID of a game*/
u32 wbfs_rID_disc(wbfs_t*p, u8* discid, u8* newID); u32 wbfs_rID_disc(wbfs_t*p, u8* discid, u8* newID);
/*! trim the file-system to its minimum size /*! trim the file-system to its minimum size
This allows to use wbfs as a wiidisc container 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. /*! 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 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 // remove some sanity checks
void wbfs_set_force_mode(int force); 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, wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc,
void *callback_data, void *callback_data,
partition_selector_t sel); partition_selector_t sel);
// compressed and real size // compressed and real size
u32 wbfs_size_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc, u32 wbfs_size_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc,
void *callback_data,partition_selector_t sel, 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); 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); 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 #ifdef __cplusplus
} }

View File

@ -122,12 +122,11 @@ static u32 do_fst(wiidisc_t *d,u8 *fst, const char *names, u32 i)
return size; return size;
} else { } else {
offset = _be32(fst + 12*i + 4); 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_buffer = wbfs_ioalloc(size);
d->extracted_size = size;
partition_read(d,offset, d->extracted_buffer, size,0); partition_read(d,offset, d->extracted_buffer, size,0);
if(d->extracted_buffer != 0)
d->extracted_buffer_size = size;
}else }else
partition_read(d,offset, 0, size,1); partition_read(d,offset, 0, size,1);
return i + 1; return i + 1;
@ -165,11 +164,21 @@ static void do_files(wiidisc_t*d)
partition_read(d,fst_offset, fst, fst_size,0); partition_read(d,fst_offset, fst, fst_size,0);
n_files = _be32(fst + 8); 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) if (n_files > 1)
do_fst(d,fst, (char *)fst + 12*n_files, 0); do_fst(d,fst, (char *)fst + 12*n_files, 0);
wbfs_iofree(b); wbfs_iofree(b);
wbfs_iofree(apl_header); wbfs_iofree(apl_header);
wbfs_iofree(fst); if (fst != d->extracted_buffer)
wbfs_iofree(fst);
} }
static void do_partition(wiidisc_t*d) static void do_partition(wiidisc_t*d)
@ -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 // 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. // XXX pathname not implemented. files are extracted by their name.
// first file found with that name is returned. // 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; u8 *retval = 0;
d->extract_pathname = pathname; 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->extract_pathname = 0;
d->part_sel = ALL_PARTITIONS; d->part_sel = ALL_PARTITIONS;
retval = d->extracted_buffer; retval = d->extracted_buffer;
if (size != 0)
*size = d->extracted_buffer_size;
d->extracted_buffer = 0; d->extracted_buffer = 0;
d->extracted_buffer_size = 0;
return retval; return retval;
} }

View File

@ -45,13 +45,13 @@ typedef struct wiidisc_s
char *extract_pathname; char *extract_pathname;
u8 *extracted_buffer; u8 *extracted_buffer;
u32 extracted_buffer_size; int extracted_size;
}wiidisc_t; }wiidisc_t;
wiidisc_t *wd_open_disc(read_wiidisc_callback_t read,void*fp); wiidisc_t *wd_open_disc(read_wiidisc_callback_t read,void*fp);
void wd_close_disc(wiidisc_t *); void wd_close_disc(wiidisc_t *);
// returns a buffer allocated with wbfs_ioalloc() or NULL if not found of alloc error // 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); 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); // DEBUG_Init(GDBSTUB_DEVICE_USB, 1);
//_break(); //_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("\n\n------------------");
gprintf("\nUSB Loader GX rev%s",GetRev()); gprintf("\nUSB Loader GX rev%s",GetRev());