mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-04 18:45:05 +01:00
Added changed libwbfs by oggzee.
This commit is contained in:
parent
f3ce461dc6
commit
27024a9ad1
@ -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.
|
||||
|
@ -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"));
|
||||
|
@ -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(). */
|
||||
|
||||
|
@ -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..
|
||||
{
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
wbfs_t *p = wbfs_malloc(sizeof(wbfs_t));
|
||||
|
||||
|
||||
wbfs_head_t *head = wbfs_ioalloc(hd_sector_size?hd_sector_size:512);
|
||||
|
||||
//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_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 = 1<<p->wbfs_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->freeblks_lba = (p->wbfs_sec_sz - p->n_wbfs_sec/8)>>p->hd_sec_sz_s;
|
||||
|
||||
|
||||
if(!reset)
|
||||
p->freeblks = 0; // will alloc and read only if needed
|
||||
else
|
||||
@ -144,7 +147,7 @@ error:
|
||||
wbfs_free(p);
|
||||
wbfs_iofree(head);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void wbfs_sync(wbfs_t*p)
|
||||
@ -152,11 +155,12 @@ void wbfs_sync(wbfs_t*p)
|
||||
// copy back descriptors
|
||||
if(p->write_hdsector){
|
||||
p->write_hdsector(p->callback_data,p->part_lba+0,1, p->head);
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void wbfs_close(wbfs_t*p)
|
||||
{
|
||||
wbfs_sync(p);
|
||||
@ -168,9 +172,9 @@ void wbfs_close(wbfs_t*p)
|
||||
wbfs_iofree(p->tmp_buffer);
|
||||
if(p->freeblks)
|
||||
wbfs_iofree(p->freeblks);
|
||||
|
||||
|
||||
wbfs_free(p);
|
||||
|
||||
|
||||
error:
|
||||
return;
|
||||
}
|
||||
@ -209,7 +213,7 @@ error:
|
||||
if(d)
|
||||
wbfs_iofree(d);
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
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) {
|
||||
return wbfs_iso_file_read(d, offset, data, len);
|
||||
}
|
||||
|
||||
|
||||
wbfs_t *p = d->p;
|
||||
u16 wlba = offset>>(p->wbfs_sec_sz_s-2);
|
||||
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))
|
||||
{
|
||||
u32 nlb = len>>(p->hd_sec_sz_s);
|
||||
|
||||
|
||||
if(unlikely(lba + nlb > p->wbfs_sec_sz)) // dont cross wbfs sectors..
|
||||
nlb = p->wbfs_sec_sz-lba;
|
||||
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)
|
||||
return err;
|
||||
wbfs_memcpy(ptr, p->tmp_buffer, len);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -294,8 +298,9 @@ u32 wbfs_count_discs(wbfs_t*p)
|
||||
if (p->head->disc_table[i])
|
||||
count++;
|
||||
return count;
|
||||
|
||||
|
||||
}
|
||||
|
||||
u32 wbfs_sector_used(wbfs_t *p,wbfs_disc_info_t *di)
|
||||
{
|
||||
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]))
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if(header_size > (int)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..
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
u32 wbfs_count_usedblocks(wbfs_t*p)
|
||||
{
|
||||
@ -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,119 +422,162 @@ 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)
|
||||
|
||||
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;
|
||||
u32 tot,cur;
|
||||
u32 wii_sec_per_wbfs_sect = 1<<(p->wbfs_sec_sz_s-p->wii_sec_sz_s);
|
||||
wiidisc_t *d = 0;
|
||||
u8 *used = 0;
|
||||
wbfs_disc_info_t *info = 0;
|
||||
u8* copy_buffer = 0;
|
||||
used = wbfs_malloc(p->n_wii_sec_per_disc);
|
||||
if(!used)
|
||||
ERROR("unable to alloc memory");
|
||||
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;
|
||||
}
|
||||
int i,discn;
|
||||
u32 tot,cur;
|
||||
u32 wii_sec_per_wbfs_sect = 1<<(p->wbfs_sec_sz_s-p->wii_sec_sz_s);
|
||||
wiidisc_t *d = 0;
|
||||
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");
|
||||
// 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.
|
||||
if(p->head->disc_table[i]==0)
|
||||
break;
|
||||
if(i==p->max_disc)
|
||||
ERROR("no space left on device (table full)");
|
||||
p->head->disc_table[i] = 1;
|
||||
discn = i;
|
||||
load_freeblocks(p);
|
||||
for(i=0;i<p->max_disc;i++)// find a free slot.
|
||||
if(p->head->disc_table[i]==0)
|
||||
break;
|
||||
if(i==p->max_disc)
|
||||
ERROR("no space left on device (table full)");
|
||||
p->head->disc_table[i] = 1;
|
||||
discn = i;
|
||||
load_freeblocks(p);
|
||||
|
||||
// build disc info
|
||||
info = wbfs_ioalloc(p->disc_info_sz);
|
||||
read_src_wii_disc(callback_data,0,0x100,info->disc_header_copy);
|
||||
// build disc info
|
||||
info = wbfs_ioalloc(p->disc_info_sz);
|
||||
read_src_wii_disc(callback_data,0,0x100,info->disc_header_copy);
|
||||
|
||||
copy_buffer = wbfs_ioalloc(p->wii_sec_sz);
|
||||
if(!copy_buffer)
|
||||
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);
|
||||
}
|
||||
for(i=0; i<p->n_wbfs_sec_per_disc;i++){
|
||||
u16 bl = 0;
|
||||
if(copy_1_1 || block_used(used,i,wii_sec_per_wbfs_sect)) {
|
||||
u16 j;
|
||||
copy_buffer = wbfs_ioalloc(p->wii_sec_sz);
|
||||
if(!copy_buffer)
|
||||
ERROR("alloc memory");
|
||||
tot=0;
|
||||
cur=0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
if (bl==0xffff)
|
||||
ERROR("no space left on device (disc full)");
|
||||
for(j=0; j<wii_sec_per_wbfs_sect;j++) {
|
||||
u32 offset = (i*(p->wbfs_sec_sz>>2)) + (j*(p->wii_sec_sz>>2));
|
||||
bl = alloc_block(p);
|
||||
if (bl==0xffff)
|
||||
ERROR("no space left on device (disc full)");
|
||||
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->wii_sec_sz/p->hd_sec_sz,copy_buffer);
|
||||
cur++;
|
||||
if(spinner)
|
||||
spinner(cur,tot);
|
||||
}
|
||||
}
|
||||
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);
|
||||
//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->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);
|
||||
if(used)
|
||||
wbfs_free(used);
|
||||
if(info)
|
||||
wbfs_iofree(info);
|
||||
if(copy_buffer)
|
||||
wbfs_iofree(copy_buffer);
|
||||
// init with all free blocks
|
||||
if(d)
|
||||
wd_close_disc(d);
|
||||
if(used)
|
||||
wbfs_free(used);
|
||||
if(info)
|
||||
wbfs_iofree(info);
|
||||
if(copy_buffer)
|
||||
wbfs_iofree(copy_buffer);
|
||||
// init with all free blocks
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
u32 wbfs_rm_disc(wbfs_t*p, u8* discid)
|
||||
{
|
||||
wbfs_disc_t *d = wbfs_open_disc(p,discid);
|
||||
int i;
|
||||
int discn = 0;
|
||||
int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s;
|
||||
if(!d)
|
||||
return 1;
|
||||
load_freeblocks(p);
|
||||
discn = d->i;
|
||||
for( i=0; i< p->n_wbfs_sec_per_disc; i++)
|
||||
{
|
||||
u32 iwlba = wbfs_ntohs(d->header->wlba_table[i]);
|
||||
if (iwlba)
|
||||
free_block(p,iwlba);
|
||||
}
|
||||
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->head->disc_table[discn] = 0;
|
||||
wbfs_close_disc(d);
|
||||
wbfs_sync(p);
|
||||
return 0;
|
||||
wbfs_disc_t *d = wbfs_open_disc(p,discid);
|
||||
int i;
|
||||
int discn = 0;
|
||||
int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s;
|
||||
if(!d)
|
||||
return 1;
|
||||
load_freeblocks(p);
|
||||
discn = d->i;
|
||||
for( i=0; i< p->n_wbfs_sec_per_disc; i++)
|
||||
{
|
||||
u32 iwlba = wbfs_ntohs(d->header->wlba_table[i]);
|
||||
if (iwlba)
|
||||
free_block(p,iwlba);
|
||||
}
|
||||
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->head->disc_table[discn] = 0;
|
||||
wbfs_close_disc(d);
|
||||
wbfs_sync(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
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)
|
||||
@ -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]);
|
||||
if (iwlba)
|
||||
{
|
||||
|
||||
|
||||
if(spinner)
|
||||
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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
|
||||
// Modified by oggzee
|
||||
|
||||
#ifndef LIBWBFS_H
|
||||
#define LIBWBFS_H
|
||||
|
||||
@ -12,7 +15,7 @@ typedef u32 be32_t;
|
||||
typedef u16 be16_t;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct wbfs_head
|
||||
{
|
||||
be32_t magic;
|
||||
@ -72,14 +75,14 @@ typedef struct wbfs_s
|
||||
u32 n_hd_sec; // the number of hd sector in the wbfs partition
|
||||
|
||||
/* standard wii sector (0x8000 bytes) */
|
||||
u32 wii_sec_sz;
|
||||
u32 wii_sec_sz;
|
||||
u8 wii_sec_sz_s;
|
||||
u32 n_wii_sec;
|
||||
u32 n_wii_sec_per_disc;
|
||||
|
||||
|
||||
/* The size of a wbfs sector */
|
||||
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_per_disc; // size of the lookup table
|
||||
|
||||
@ -95,9 +98,9 @@ typedef struct wbfs_s
|
||||
u16 disc_info_sz;
|
||||
|
||||
u8 *tmp_buffer; // pre-allocated buffer for unaligned read
|
||||
|
||||
|
||||
u32 n_disc_open;
|
||||
|
||||
|
||||
}wbfs_t;
|
||||
|
||||
typedef struct wbfs_disc_s
|
||||
@ -110,7 +113,7 @@ typedef struct wbfs_disc_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
|
||||
@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
|
||||
@ -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
|
||||
@ -167,7 +171,7 @@ u32 wbfs_count_discs(wbfs_t*p);
|
||||
@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.
|
||||
*/
|
||||
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.
|
||||
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*/
|
||||
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
|
||||
*/
|
||||
@ -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);
|
||||
|
||||
/*! 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
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
@ -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;
|
||||
@ -157,7 +156,7 @@ static void do_files(wiidisc_t*d)
|
||||
// fake read dol and partition
|
||||
partition_read(d,apl_offset, 0, apl_size,1);
|
||||
partition_read(d,dol_offset, 0, (fst_offset - dol_offset)<<2,1);
|
||||
|
||||
|
||||
|
||||
fst = wbfs_ioalloc(fst_size);
|
||||
if (fst == 0)
|
||||
@ -165,11 +164,21 @@ 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);
|
||||
wbfs_iofree(fst);
|
||||
wbfs_iofree(b);
|
||||
wbfs_iofree(apl_header);
|
||||
if (fst != d->extracted_buffer)
|
||||
wbfs_iofree(fst);
|
||||
}
|
||||
|
||||
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:
|
||||
return (partition_type!=part_sel);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void do_disc(wiidisc_t*d)
|
||||
{
|
||||
u8 *b = wbfs_ioalloc(0x100);
|
||||
@ -281,9 +290,9 @@ void wd_close_disc(wiidisc_t *d)
|
||||
wbfs_free(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.
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
u8 *b = partition_table;
|
||||
u32 partition_offset;
|
||||
u32 partition_type;
|
||||
u32 partition_offset;
|
||||
u32 partition_type;
|
||||
u32 n_partitions,i,j;
|
||||
u32 *b32;
|
||||
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);
|
||||
if(_be32(b + 4)-(0x40000>>2) >0x50)
|
||||
wbfs_fatal("cannot modify this partition table. Please report the bug.");
|
||||
|
||||
|
||||
b += (_be32(b + 4)-(0x40000>>2))*4;
|
||||
j=0;
|
||||
for (i = 0; i < n_partitions; i++){
|
||||
|
@ -35,7 +35,7 @@ typedef struct wiidisc_s
|
||||
u32 partition_data_offset;
|
||||
u32 partition_data_size;
|
||||
u32 partition_block;
|
||||
|
||||
|
||||
u8 *tmp_buffer;
|
||||
u8 *tmp_buffer2;
|
||||
u8 disc_key[16];
|
||||
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user