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..
{ {
} }
@ -72,7 +75,7 @@ wbfs_t*wbfs_open_partition(rw_sector_callback_t read_hdsector,
int hd_sector_size, int num_hd_sector, u32 part_lba, int reset) int hd_sector_size, int num_hd_sector, u32 part_lba, int reset)
{ {
wbfs_t *p = wbfs_malloc(sizeof(wbfs_t)); wbfs_t *p = wbfs_malloc(sizeof(wbfs_t));
wbfs_head_t *head = wbfs_ioalloc(hd_sector_size?hd_sector_size:512); wbfs_head_t *head = wbfs_ioalloc(hd_sector_size?hd_sector_size:512);
//constants, but put here for consistancy //constants, but put here for consistancy
@ -111,7 +114,7 @@ wbfs_t*wbfs_open_partition(rw_sector_callback_t read_hdsector,
p->n_hd_sec = wbfs_ntohl(head->n_hd_sec); p->n_hd_sec = wbfs_ntohl(head->n_hd_sec);
p->n_wii_sec = (p->n_hd_sec/p->wii_sec_sz)*(p->hd_sec_sz); p->n_wii_sec = (p->n_hd_sec/p->wii_sec_sz)*(p->hd_sec_sz);
p->wbfs_sec_sz_s = head->wbfs_sec_sz_s; p->wbfs_sec_sz_s = head->wbfs_sec_sz_s;
p->wbfs_sec_sz = 1<<p->wbfs_sec_sz_s; p->wbfs_sec_sz = 1<<p->wbfs_sec_sz_s;
p->n_wbfs_sec = p->n_wii_sec >> (p->wbfs_sec_sz_s - p->wii_sec_sz_s); p->n_wbfs_sec = p->n_wii_sec >> (p->wbfs_sec_sz_s - p->wii_sec_sz_s);
@ -124,7 +127,7 @@ wbfs_t*wbfs_open_partition(rw_sector_callback_t read_hdsector,
p->callback_data = callback_data; p->callback_data = callback_data;
p->freeblks_lba = (p->wbfs_sec_sz - p->n_wbfs_sec/8)>>p->hd_sec_sz_s; p->freeblks_lba = (p->wbfs_sec_sz - p->n_wbfs_sec/8)>>p->hd_sec_sz_s;
if(!reset) if(!reset)
p->freeblks = 0; // will alloc and read only if needed p->freeblks = 0; // will alloc and read only if needed
else else
@ -144,7 +147,7 @@ error:
wbfs_free(p); wbfs_free(p);
wbfs_iofree(head); wbfs_iofree(head);
return 0; return 0;
} }
void wbfs_sync(wbfs_t*p) void wbfs_sync(wbfs_t*p)
@ -152,11 +155,12 @@ void wbfs_sync(wbfs_t*p)
// copy back descriptors // copy back descriptors
if(p->write_hdsector){ if(p->write_hdsector){
p->write_hdsector(p->callback_data,p->part_lba+0,1, p->head); p->write_hdsector(p->callback_data,p->part_lba+0,1, p->head);
if(p->freeblks) if(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); 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);
@ -168,9 +172,9 @@ void wbfs_close(wbfs_t*p)
wbfs_iofree(p->tmp_buffer); wbfs_iofree(p->tmp_buffer);
if(p->freeblks) if(p->freeblks)
wbfs_iofree(p->freeblks); wbfs_iofree(p->freeblks);
wbfs_free(p); wbfs_free(p);
error: error:
return; return;
} }
@ -209,7 +213,7 @@ error:
if(d) if(d)
wbfs_iofree(d); wbfs_iofree(d);
return 0; return 0;
} }
void wbfs_close_disc(wbfs_disc_t*d) void wbfs_close_disc(wbfs_disc_t*d)
{ {
@ -223,7 +227,7 @@ int wbfs_disc_read(wbfs_disc_t*d,u32 offset, u32 len, u8 *data)
if (d->p == &wbfs_iso_file) { if (d->p == &wbfs_iso_file) {
return wbfs_iso_file_read(d, offset, data, len); return wbfs_iso_file_read(d, offset, data, len);
} }
wbfs_t *p = d->p; wbfs_t *p = d->p;
u16 wlba = offset>>(p->wbfs_sec_sz_s-2); u16 wlba = offset>>(p->wbfs_sec_sz_s-2);
u32 iwlba_shift = p->wbfs_sec_sz_s - p->hd_sec_sz_s; u32 iwlba_shift = p->wbfs_sec_sz_s - p->hd_sec_sz_s;
@ -259,7 +263,7 @@ int wbfs_disc_read(wbfs_disc_t*d,u32 offset, u32 len, u8 *data)
while(likely(len>=p->hd_sec_sz)) while(likely(len>=p->hd_sec_sz))
{ {
u32 nlb = len>>(p->hd_sec_sz_s); u32 nlb = len>>(p->hd_sec_sz_s);
if(unlikely(lba + nlb > p->wbfs_sec_sz)) // dont cross wbfs sectors.. if(unlikely(lba + nlb > p->wbfs_sec_sz)) // dont cross wbfs sectors..
nlb = p->wbfs_sec_sz-lba; nlb = p->wbfs_sec_sz-lba;
err = p->read_hdsector(p->callback_data, err = p->read_hdsector(p->callback_data,
@ -282,7 +286,7 @@ int wbfs_disc_read(wbfs_disc_t*d,u32 offset, u32 len, u8 *data)
if(err) if(err)
return err; return err;
wbfs_memcpy(ptr, p->tmp_buffer, len); wbfs_memcpy(ptr, p->tmp_buffer, len);
} }
return 0; return 0;
} }
@ -294,8 +298,9 @@ u32 wbfs_count_discs(wbfs_t*p)
if (p->head->disc_table[i]) if (p->head->disc_table[i])
count++; count++;
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;
@ -345,7 +363,7 @@ static void load_freeblocks(wbfs_t*p)
// XXX should handle malloc error.. // XXX should handle malloc error..
p->freeblks = wbfs_ioalloc(ALIGN_LBA(p->n_wbfs_sec/8)); p->freeblks = wbfs_ioalloc(ALIGN_LBA(p->n_wbfs_sec/8));
p->read_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->read_hdsector(p->callback_data,p->part_lba+p->freeblks_lba,ALIGN_LBA(p->n_wbfs_sec/8)>>p->hd_sec_sz_s, p->freeblks);
} }
u32 wbfs_count_usedblocks(wbfs_t*p) u32 wbfs_count_usedblocks(wbfs_t*p)
{ {
@ -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)
@ -570,7 +644,7 @@ u32 wbfs_extract_disc(wbfs_disc_t*d, rw_sector_callback_t write_dst_wii_sector,v
u32 iwlba = wbfs_ntohs(d->header->wlba_table[i]); u32 iwlba = wbfs_ntohs(d->header->wlba_table[i]);
if (iwlba) if (iwlba)
{ {
if(spinner) if(spinner)
spinner(i,p->n_wbfs_sec_per_disc); spinner(i,p->n_wbfs_sec_per_disc);
p->read_hdsector(p->callback_data, p->part_lba + iwlba*src_wbs_nlb, src_wbs_nlb, copy_buffer); p->read_hdsector(p->callback_data, p->part_lba + iwlba*src_wbs_nlb, src_wbs_nlb, copy_buffer);
@ -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
@ -12,7 +15,7 @@ typedef u32 be32_t;
typedef u16 be16_t; typedef u16 be16_t;
typedef struct wbfs_head typedef struct wbfs_head
{ {
be32_t magic; be32_t magic;
@ -72,14 +75,14 @@ typedef struct wbfs_s
u32 n_hd_sec; // the number of hd sector in the wbfs partition u32 n_hd_sec; // the number of hd sector in the wbfs partition
/* standard wii sector (0x8000 bytes) */ /* standard wii sector (0x8000 bytes) */
u32 wii_sec_sz; u32 wii_sec_sz;
u8 wii_sec_sz_s; u8 wii_sec_sz_s;
u32 n_wii_sec; u32 n_wii_sec;
u32 n_wii_sec_per_disc; u32 n_wii_sec_per_disc;
/* The size of a wbfs sector */ /* The size of a wbfs sector */
u32 wbfs_sec_sz; u32 wbfs_sec_sz;
u32 wbfs_sec_sz_s; u32 wbfs_sec_sz_s;
u16 n_wbfs_sec; // this must fit in 16 bit! u16 n_wbfs_sec; // this must fit in 16 bit!
u16 n_wbfs_sec_per_disc; // size of the lookup table u16 n_wbfs_sec_per_disc; // size of the lookup table
@ -95,9 +98,9 @@ typedef struct wbfs_s
u16 disc_info_sz; u16 disc_info_sz;
u8 *tmp_buffer; // pre-allocated buffer for unaligned read u8 *tmp_buffer; // pre-allocated buffer for unaligned read
u32 n_disc_open; u32 n_disc_open;
}wbfs_t; }wbfs_t;
typedef struct wbfs_disc_s typedef struct wbfs_disc_s
@ -110,7 +113,7 @@ typedef struct wbfs_disc_s
#define WBFS_MAGIC (('W'<<24)|('B'<<16)|('F'<<8)|('S')) #define WBFS_MAGIC (('W'<<24)|('B'<<16)|('F'<<8)|('S'))
/*! @brief open a MSDOS partitionned harddrive. This tries to find a wbfs partition into the harddrive /*! @brief open a MSDOS partitionned harddrive. This tries to find a wbfs partition into the harddrive
@param read_hdsector,write_hdsector: accessors to a harddrive @param read_hdsector,write_hdsector: accessors to a harddrive
@hd_sector_size: size of the hd sector. Can be set to zero if the partition in already initialized @hd_sector_size: size of the hd sector. Can be set to zero if the partition in already initialized
@num_hd_sector: number of sectors in this disc. Can be set to zero if the partition in already initialized @num_hd_sector: number of sectors in this disc. Can be set to zero if the partition in already initialized
@ -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
@ -167,7 +171,7 @@ u32 wbfs_count_discs(wbfs_t*p);
@param header: pointer to 0x100 bytes to write the header @param header: pointer to 0x100 bytes to write the header
@size: optional pointer to a 32bit word that will get the size in 32bit words of the DVD taken on the partition. @size: optional pointer to a 32bit word that will get the size in 32bit words of the DVD taken on the partition.
*/ */
u32 wbfs_get_disc_info(wbfs_t*p, u32 i,u8 *header,int header_size,u32 *size); u32 wbfs_get_disc_info(wbfs_t*p, u32 i,u8 *header,int header_size,u32 *size);
/*! get the number of used block of the partition. /*! get the number of used block of the partition.
to be multiplied by p->wbfs_sec_sz (use 64bit multiplication) to have the number in bytes to be multiplied by p->wbfs_sec_sz (use 64bit multiplication) to have the number in bytes
@ -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
*/ */
@ -206,10 +209,10 @@ Even if the filesize is 4.7GB, the disc usage will be less.
*/ */
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);
/*! 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;
@ -157,7 +156,7 @@ static void do_files(wiidisc_t*d)
// fake read dol and partition // fake read dol and partition
partition_read(d,apl_offset, 0, apl_size,1); partition_read(d,apl_offset, 0, apl_size,1);
partition_read(d,dol_offset, 0, (fst_offset - dol_offset)<<2,1); partition_read(d,dol_offset, 0, (fst_offset - dol_offset)<<2,1);
fst = wbfs_ioalloc(fst_size); fst = wbfs_ioalloc(fst_size);
if (fst == 0) if (fst == 0)
@ -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)
@ -230,7 +239,7 @@ static int test_parition_skip(u32 partition_type,partition_selector_t part_sel)
default: default:
return (partition_type!=part_sel); return (partition_type!=part_sel);
} }
} }
static void do_disc(wiidisc_t*d) static void do_disc(wiidisc_t*d)
{ {
u8 *b = wbfs_ioalloc(0x100); u8 *b = wbfs_ioalloc(0x100);
@ -281,9 +290,9 @@ void wd_close_disc(wiidisc_t *d)
wbfs_free(d); wbfs_free(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;
} }
@ -313,8 +319,8 @@ void wd_build_disc_usage(wiidisc_t *d, partition_selector_t selector, u8* usage_
void wd_fix_partition_table(wiidisc_t *d, partition_selector_t selector, u8* partition_table) void wd_fix_partition_table(wiidisc_t *d, partition_selector_t selector, u8* partition_table)
{ {
u8 *b = partition_table; u8 *b = partition_table;
u32 partition_offset; u32 partition_offset;
u32 partition_type; u32 partition_type;
u32 n_partitions,i,j; u32 n_partitions,i,j;
u32 *b32; u32 *b32;
if(selector == ALL_PARTITIONS) if(selector == ALL_PARTITIONS)
@ -322,7 +328,7 @@ void wd_fix_partition_table(wiidisc_t *d, partition_selector_t selector, u8* par
n_partitions = _be32(b); n_partitions = _be32(b);
if(_be32(b + 4)-(0x40000>>2) >0x50) if(_be32(b + 4)-(0x40000>>2) >0x50)
wbfs_fatal("cannot modify this partition table. Please report the bug."); wbfs_fatal("cannot modify this partition table. Please report the bug.");
b += (_be32(b + 4)-(0x40000>>2))*4; b += (_be32(b + 4)-(0x40000>>2))*4;
j=0; j=0;
for (i = 0; i < n_partitions; i++){ for (i = 0; i < n_partitions; i++){

View File

@ -35,7 +35,7 @@ typedef struct wiidisc_s
u32 partition_data_offset; u32 partition_data_offset;
u32 partition_data_size; u32 partition_data_size;
u32 partition_block; u32 partition_block;
u8 *tmp_buffer; u8 *tmp_buffer;
u8 *tmp_buffer2; u8 *tmp_buffer2;
u8 disc_key[16]; u8 disc_key[16];
@ -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());