-FINALLY added wii game launching support for 3TB HDDs

This commit is contained in:
fix94.1 2012-04-27 22:55:17 +00:00
parent 2d6a737bc6
commit eaf62500a9
7 changed files with 231 additions and 141 deletions

View File

@ -4,11 +4,17 @@
// Modified by oggzee
#include <unistd.h>
#include <sys/stat.h>
#include "libwbfs.h"
#include "gecko/gecko.h"
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define read_le32_unaligned(x) ((x)[0]|((x)[1]<<8)|((x)[2]<<16)|((x)[3]<<24))
#define ERROR(x) do {wbfs_error(x);goto error;}while(0)
#define ALIGN_LBA(x) (((x)+p->hd_sec_sz-1)&(~(p->hd_sec_sz-1)))
@ -32,15 +38,14 @@ static u8 size_to_shift(u32 size)
return ret - 1;
}
#define read_le32_unaligned(x) ((x)[0]|((x)[1]<<8)|((x)[2]<<16)|((x)[3]<<24))
wbfs_t *wbfs_open_hd(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, void *callback_data, int hd_sector_size, int num_hd_sector __attribute((unused)), int reset)
{
int i=num_hd_sector,ret;
u8 *ptr,*tmp_buffer = wbfs_ioalloc(hd_sector_size);
u8 part_table[16*4];
ret = read_hdsector(callback_data,0,1,tmp_buffer);
if(ret) return 0;
if(ret)
return 0;
//find wbfs partition
wbfs_memcpy(part_table, tmp_buffer + 0x1be, 16 * 4);
ptr = part_table;
@ -60,21 +65,23 @@ wbfs_t *wbfs_open_hd(rw_sector_callback_t read_hdsector, rw_sector_callback_t wr
wbfs_iofree(tmp_buffer);
if(reset)// XXX make a empty hd partition..
{
}
return 0;
}
wbfs_t *wbfs_open_partition(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, void *callback_data, int hd_sector_size, int num_hd_sector, u32 part_lba, int reset)
wbfs_t *wbfs_open_partition(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector,
void *callback_data, 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);
wbfs_head_t *head = wbfs_ioalloc( hd_sector_size ? hd_sector_size : 512 );
//constants, but put here for consistancy
p->wii_sec_sz = 0x8000;
p->wii_sec_sz_s = size_to_shift(0x8000);
p->n_wii_sec = (num_hd_sector / 0x8000) * hd_sector_size;
p->n_wii_sec_per_disc = 143432 * 2;//support for double layers discs..
p->n_wii_sec_per_disc = 143432 * 2; //support for double layers discs..
p->head = head;
p->part_lba = part_lba;
// init the partition
@ -88,47 +95,55 @@ wbfs_t *wbfs_open_partition(rw_sector_callback_t read_hdsector, rw_sector_callba
// choose minimum wblk_sz that fits this partition size
for(sz_s = 6; sz_s < 11; sz_s++)
{
// ensure that wbfs_sec_sz is big enough to address every blocks using 16 bits
if(p->n_wii_sec < ((1U << 16) * (1 << sz_s))) break;
// ensure that wbfs_sec_sz is big enough to address every blocks using 16 bits
if(p->n_wii_sec < ((1U << 16) * (1 << sz_s)))
break;
}
head->wbfs_sec_sz_s = sz_s + p->wii_sec_sz_s;
}
else read_hdsector(callback_data, p->part_lba, 1, head);
if (head->magic != wbfs_htonl(WBFS_MAGIC)) ERROR("bad magic");
if(!force_mode && hd_sector_size && head->hd_sec_sz_s !=size_to_shift(hd_sector_size)) ERROR("hd sector size doesn't match");
if(!force_mode && num_hd_sector && head->n_hd_sec != wbfs_htonl(num_hd_sector)) ERROR("hd num sector doesn't match");
else
read_hdsector(callback_data, p->part_lba, 1, head);
if (head->magic != wbfs_htonl( WBFS_MAGIC ))
ERROR( "bad magic" );
if (!force_mode && hd_sector_size && head->hd_sec_sz_s != size_to_shift(hd_sector_size))
ERROR( "hd sector size doesn't match" );
if (!force_mode && num_hd_sector && head->n_hd_sec != (u32) wbfs_htonl( num_hd_sector ))
ERROR( "hd num sector doesn't match" );
p->hd_sec_sz = 1 << head->hd_sec_sz_s;
p->hd_sec_sz_s = head->hd_sec_sz_s;
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);
p->n_wbfs_sec_per_disc = p->n_wii_sec_per_disc >> (p->wbfs_sec_sz_s - p->wii_sec_sz_s);
p->disc_info_sz = ALIGN_LBA(sizeof(wbfs_disc_info_t) + p->n_wbfs_sec_per_disc * 2);
//printf("hd_sector_size %X wii_sector size %X wbfs sector_size %X\n",p->hd_sec_sz,p->wii_sec_sz,p->wbfs_sec_sz);
//gprintf("hd_sector_size %X wii_sector size %X wbfs sector_size %X\n", p->hd_sec_sz, p->wii_sec_sz, p->wbfs_sec_sz);
p->read_hdsector = read_hdsector;
p->write_hdsector = write_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
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
{
// init with all free blocks
p->freeblks = wbfs_ioalloc(ALIGN_LBA(p->n_wbfs_sec/8));
wbfs_memset(p->freeblks,0xff,p->n_wbfs_sec/8);
// init with all free blocks
p->freeblks = wbfs_ioalloc(ALIGN_LBA( p->n_wbfs_sec / 8));
wbfs_memset(p->freeblks, 0xff, p->n_wbfs_sec / 8);
}
p->max_disc = (p->freeblks_lba - 1) / (p->disc_info_sz >> p->hd_sec_sz_s);
if(p->max_disc > p->hd_sec_sz - sizeof(wbfs_head_t)) p->max_disc = p->hd_sec_sz - sizeof(wbfs_head_t);
if(p->max_disc > p->hd_sec_sz - sizeof(wbfs_head_t))
p->max_disc = p->hd_sec_sz - sizeof(wbfs_head_t);
p->tmp_buffer = wbfs_ioalloc(p->hd_sec_sz);
p->n_disc_open = 0;
return p;
error:
wbfs_free(p);
wbfs_iofree(head);
@ -142,7 +157,8 @@ void wbfs_sync(wbfs_t *p)
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);
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);
}
}
@ -150,11 +166,13 @@ void wbfs_close(wbfs_t *p)
{
wbfs_sync(p);
if(p->n_disc_open) ERROR("trying to close wbfs while discs still open");
if(p->n_disc_open)
ERROR("trying to close wbfs while discs still open");
wbfs_iofree(p->head);
wbfs_iofree(p->tmp_buffer);
if(p->freeblks) wbfs_iofree(p->freeblks);
if(p->freeblks)
wbfs_iofree(p->freeblks);
wbfs_free(p);
@ -175,25 +193,26 @@ wbfs_disc_t *wbfs_open_disc(wbfs_t* p, const u8 *discid)
if(wbfs_memcmp(discid,p->tmp_buffer,6)==0)
{
d = wbfs_malloc(sizeof(*d));
if(!d) ERROR("allocating memory");
if(!d)
ERROR("allocating memory");
d->p = p;
d->i = i;
d->header = wbfs_ioalloc(p->disc_info_sz);
if(!d->header)
ERROR("allocating memory");
ERROR("allocating memory");
p->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, disc_info_sz_lba, d->header);
p->n_disc_open ++;
// for(i = 0; i < p->n_wbfs_sec_per_disc; i++)
// printf("%d,", wbfs_ntohs(d->header->wlba_table[i]));
//for(i = 0; i < p->n_wbfs_sec_per_disc; i++)
//printf("%d,", wbfs_ntohs(d->header->wlba_table[i]));
return d;
}
}
}
return 0;
error:
if(d) wbfs_iofree(d);
return 0;
}
void wbfs_close_disc(wbfs_disc_t*d)
{
@ -204,7 +223,8 @@ void wbfs_close_disc(wbfs_disc_t*d)
// 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)
{
if (d->p == &wbfs_iso_file) return wbfs_iso_file_read(d, offset, data, len);
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);
@ -216,14 +236,17 @@ int wbfs_disc_read(wbfs_disc_t *d, u32 offset, u32 len, u8 *data)
u32 len_copied;
int err = 0;
u8 *ptr = data;
if(unlikely(iwlba==0)) return 1;
if(unlikely(iwlba==0))
return 1;
if(unlikely(off))
{
off *= 4;
err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba<<iwlba_shift) + lba, 1, p->tmp_buffer);
if(err) return err;
if(err)
return err;
len_copied = p->hd_sec_sz - off;
if(likely(len < len_copied)) len_copied = len;
if(likely(len < len_copied))
len_copied = len;
wbfs_memcpy(ptr, p->tmp_buffer + off, len_copied);
len -= len_copied;
ptr += len_copied;
@ -232,17 +255,18 @@ int wbfs_disc_read(wbfs_disc_t *d, u32 offset, u32 len, u8 *data)
{
lba=0;
iwlba = wbfs_ntohs(d->header->wlba_table[++wlba]);
if(unlikely(iwlba==0)) return 1;
if(unlikely(iwlba==0))
return 1;
}
}
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;
nlb = p->wbfs_sec_sz-lba;
err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba<<iwlba_shift) + lba, nlb, ptr);
if(err) return err;
if(err)
return err;
len -= nlb << p->hd_sec_sz_s;
ptr += nlb << p->hd_sec_sz_s;
lba += nlb;
@ -250,13 +274,15 @@ int wbfs_disc_read(wbfs_disc_t *d, u32 offset, u32 len, u8 *data)
{
lba = 0;
iwlba = wbfs_ntohs(d->header->wlba_table[++wlba]);
if(unlikely(iwlba==0)) return 1;
if(unlikely(iwlba==0))
return 1;
}
}
if(unlikely(len))
{
err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba << iwlba_shift) + lba, 1, p->tmp_buffer);
if(err) return err;
if(err)
return err;
wbfs_memcpy(ptr, p->tmp_buffer, len);
}
return 0;
@ -267,16 +293,21 @@ u32 wbfs_count_discs(wbfs_t *p)
{
u32 i,count=0;
for(i = 0; i < p->max_disc; i++)
if (p->head->disc_table[i]) count++;
{
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;
for(j = 0; j < p->n_wbfs_sec_per_disc; j++)
if(wbfs_ntohs(di->wlba_table[j])) tot_blk++;
{
if(wbfs_ntohs(di->wlba_table[j]))
tot_blk++;
}
return tot_blk;
}
@ -284,26 +315,31 @@ 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;
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;
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->part_lba + 1 + i * disc_info_sz_lba, 1, p->tmp_buffer);
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;
u32 magic = wbfs_ntohl(*(u32*)(p->tmp_buffer + 24));
if(magic != 0x5D1C9EA3)
@ -323,12 +359,14 @@ u32 wbfs_get_disc_info(wbfs_t *p, u32 index,u8 *header,int header_size,u32 *size
return 0;
}
}
}
return 1;
}
static void load_freeblocks(wbfs_t *p)
{
if(p->freeblks) return;
if(p->freeblks)
return;
// 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);
@ -340,13 +378,17 @@ u32 wbfs_count_usedblocks(wbfs_t *p)
load_freeblocks(p);
for(i = 0; i < p->n_wbfs_sec / (8 * 4); i++)
{
u32 v = wbfs_ntohl(p->freeblks[i]);
if(v == ~0U)
count += 32;
else if(v != 0)
for(j = 0; j < 32; j++)
if (v & (1 << j))
count++;
u32 v = wbfs_ntohl(p->freeblks[i]);
if(v == ~0U)
count += 32;
else if(v != 0)
{
for(j = 0; j < 32; j++)
{
if (v & (1 << j))
count++;
}
}
}
return count;
}
@ -358,7 +400,10 @@ int block_used(u8 *used, u32 i, u32 wblk_sz)
u32 k;
i *= wblk_sz;
for(k = 0; k < wblk_sz; k++)
if(i + k < 143432 * 2 && used[i + k]) return 1;
{
if(i + k < 143432 * 2 && used[i + k])
return 1;
}
return 0;
}
@ -371,11 +416,13 @@ static u32 alloc_block(wbfs_t *p)
if(v != 0)
{
for(j = 0; j < 32; j++)
{
if (v & (1 << j))
{
p->freeblks[i] = wbfs_htonl(v & ~(1<<j));
return (i * 32) + j + 1;
}
}
}
}
return ~0;
@ -388,7 +435,8 @@ static void free_block(wbfs_t *p,int bl)
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,void *spinner_data,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,void *spinner_data,partition_selector_t sel,int copy_1_1)
{
int i,discn;
u32 tot,cur;
@ -402,12 +450,14 @@ u32 wbfs_add_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *ca
u32 last_used;
used = wbfs_malloc(p->n_wii_sec_per_disc);
if(!used) ERROR("unable to alloc memory");
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");
if(!d)
ERROR("unable to open wii disc");
wd_build_disc_usage(d, sel, used);
wd_close_disc(d);
@ -415,9 +465,13 @@ u32 wbfs_add_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *ca
}
for(i = 0; i < p->max_disc; i++)// find a free slot.
if(p->head->disc_table[i]==0) break;
{
if(p->head->disc_table[i]==0)
break;
}
if(i == p->max_disc) ERROR("no space left on device (table full)");
if(i == p->max_disc)
ERROR("no space left on device (table full)");
p->head->disc_table[i] = 1;
discn = i;
load_freeblocks(p);
@ -427,7 +481,8 @@ u32 wbfs_add_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *ca
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");
if(!copy_buffer)
ERROR("alloc memory");
tot = 0;
cur = 0;
num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc;
@ -444,10 +499,10 @@ u32 wbfs_add_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *ca
if (copy_1_1)
{
// detect single or dual layer
if ( (last_used + 1) > (p->n_wbfs_sec_per_disc / 2) )
if((last_used + 1) > (p->n_wbfs_sec_per_disc / 2))
num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc;
else num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc / 2;
else
num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc / 2;
tot = num_wbfs_sect_to_copy * wii_sec_per_wbfs_sect;
}
/*
@ -479,7 +534,8 @@ u32 wbfs_add_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *ca
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);
if(j > 0)
info->wlba_table[i] = wbfs_htons(bl);
spinner(tot,tot,spinner_data);
break;
}
@ -488,14 +544,17 @@ u32 wbfs_add_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *ca
}
//fix the partition table
if(offset == (0x40000>>2)) wd_fix_partition_table(d, sel, copy_buffer);
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,spinner_data);
if(spinner)
spinner(cur,tot,spinner_data);
}
}
if (ret) break;
if(ret)
break;
info->wlba_table[i] = wbfs_htons(bl);
}
// write disc info
@ -503,13 +562,18 @@ u32 wbfs_add_disc(wbfs_t *p, read_wiidisc_callback_t read_src_wii_disc, void *ca
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
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
return retval;
}
@ -519,13 +583,15 @@ u32 wbfs_rm_disc(wbfs_t *p, u8* discid)
int i;
int discn = 0;
int disc_info_sz_lba = p->disc_info_sz>>p->hd_sec_sz_s;
if(!d) return 1;
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);
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);
@ -550,7 +616,8 @@ u32 wbfs_trim(wbfs_t *p)
}
// 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)
{
wbfs_t *p = d->p;
u8* copy_buffer = 0;
@ -558,15 +625,16 @@ u32 wbfs_extract_disc(wbfs_disc_t*d, rw_sector_callback_t write_dst_wii_sector,v
int src_wbs_nlb = p->wbfs_sec_sz / p->hd_sec_sz;
int dst_wbs_nlb = p->wbfs_sec_sz / p->wii_sec_sz;
copy_buffer = wbfs_ioalloc(p->wbfs_sec_sz);
if (!copy_buffer) ERROR("alloc memory");
if (!copy_buffer)
ERROR("alloc memory");
for(i = 0; i < p->n_wbfs_sec_per_disc; i++)
{
u32 iwlba = wbfs_ntohs(d->header->wlba_table[i]);
if (iwlba)
{
if(spinner) spinner(i, p->n_wbfs_sec_per_disc, NULL);
if(spinner)
spinner(i, p->n_wbfs_sec_per_disc, NULL);
p->read_hdsector(p->callback_data, p->part_lba + iwlba * src_wbs_nlb, src_wbs_nlb, copy_buffer);
write_dst_wii_sector(callback_data, i * dst_wbs_nlb, dst_wbs_nlb, copy_buffer);
}
@ -577,18 +645,21 @@ error:
return 1;
}
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)
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)
{
int i;
u32 tot = 0, last = 0;
u32 wii_sec_per_wbfs_sect = 1 << (p->wbfs_sec_sz_s - p->wii_sec_sz_s);
wiidisc_t *d = 0;
u8 *used =wbfs_malloc(p->n_wii_sec_per_disc);
if(!used) ERROR("unable to alloc memory");
u8 *used = wbfs_malloc(p->n_wii_sec_per_disc);
if(!used)
ERROR("unable to alloc memory");
d = wd_open_disc(read_src_wii_disc,callback_data);
if(!d) ERROR("unable to open wii disc");
if(!d)
ERROR("unable to open wii disc");
wd_build_disc_usage(d, sel, used);
wd_close_disc(d);
@ -605,8 +676,10 @@ u32 wbfs_size_disc(wbfs_t *p,read_wiidisc_callback_t read_src_wii_disc, void *ca
}
error:
if(d) wd_close_disc(d);
if(used) wbfs_free(used);
if(d)
wd_close_disc(d);
if(used)
wbfs_free(used);
*comp_size = tot;
*real_size = last;
@ -648,9 +721,11 @@ u32 wbfs_extract_file(wbfs_disc_t *d, char *path, void **data)
return ret;
}
int wbfs_get_fragments(wbfs_disc_t *d, _frag_append_t append_fragment, void *callback_data, u32 hdd_sector_size)
int wbfs_get_fragments(wbfs_disc_t *d, _frag_append_t append_fragment,
void *callback_data, u32 hdd_sector_size)
{
if (!d) return -1;
if (!d)
return -1;
wbfs_t *p = d->p;
int src_wbs_nlb = p->wbfs_sec_sz / hdd_sector_size;
@ -668,7 +743,7 @@ int wbfs_get_fragments(wbfs_disc_t *d, _frag_append_t append_fragment, void *cal
last = i;
}
}
if (last < p->n_wbfs_sec_per_disc / 2)
if(last < p->n_wbfs_sec_per_disc / 2)
last = p->n_wbfs_sec_per_disc / 2;
u32 size = last * src_wbs_nlb;
@ -678,42 +753,46 @@ int wbfs_get_fragments(wbfs_disc_t *d, _frag_append_t append_fragment, void *cal
// wrapper for reading .iso files using wbfs apis
#include <unistd.h>
#include <sys/stat.h>
// offset is pointing 32bit words to address the whole dvd, although len is in bytes
int wbfs_iso_file_read(wbfs_disc_t*d,u32 offset, u8 *data, u32 len)
{
if (!d || d->p != &wbfs_iso_file) return -1;
if (!d || d->p != &wbfs_iso_file)
return -1;
int fd = (int)d->header; //HMM?
//int fd = d->i;
off_t off = ((u64)offset) << 2;
off_t ret_off;
int ret;
ret_off = lseek(fd, off, SEEK_SET);
if (ret_off != off) return -1;
if (ret_off != off)
return -1;
ret = read(fd, data, len);
if (ret != len) return -2;
if (ret != len)
return -2;
return 0;
}
u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk)
{
if(!d) return 0;
if(!d)
return 0;
if (d->p == &wbfs_iso_file)
{
int fd = (int)d->header; //HMM?
//int fd = d->i;
struct stat st;
if (fstat(fd, &st) == -1) return 0;
if (num_blk) *num_blk = (st.st_size >> 9); // in 512 units
if (fstat(fd, &st) == -1)
return 0;
if (num_blk)
*num_blk = (st.st_size >> 9); // in 512 units
return st.st_blocks; // in 512 units (can be sparse)
}
u32 last_blk = 0;
u32 ret;
ret = wbfs_sector_used2(d->p, d->header, &last_blk);
if (num_blk) *num_blk = last_blk + 1;
if (num_blk)
*num_blk = last_blk + 1;
return ret;
}

View File

@ -12,7 +12,7 @@
#include <ctype.h>
#include "splits.h"
#include "gecko.h"
#include "gecko/gecko.h"
#define off64_t off_t
#define FMT_llu "%llu"
@ -21,7 +21,7 @@
#define split_error(x) do { printf("\nsplit error: %s\n\n",x); } while(0)
// 1 cluster less than 4gb
u64 OPT_split_size = (u64)4LL * 1024 * 1024 * 1024 - 32 * 1024;
u64 OPT_split_size = (u64) 4LL * 1024 * 1024 * 1024 - 32 * 1024;
// 1 cluster less than 2gb
//u64 OPT_split_size = (u64)2LL * 1024 * 1024 * 1024 - 32 * 1024;
@ -30,9 +30,12 @@ u64 OPT_split_size = (u64)4LL * 1024 * 1024 * 1024 - 32 * 1024;
void split_get_fname(split_info_t *s, int idx, char *fname)
{
strcpy(fname, s->fname);
if (idx == 0 && s->create_mode) {
// strcat(fname, ".tmp");
} else if (idx > 0) {
if (idx == 0 && s->create_mode)
{
strcat(fname, ".tmp");
}
else if (idx > 0)
{
char *c = fname + strlen(fname) - 1;
*c = '0' + idx;
}
@ -41,19 +44,18 @@ void split_get_fname(split_info_t *s, int idx, char *fname)
int split_open_file(split_info_t *s, int idx)
{
int fd = s->fd[idx];
if (fd>=0) return fd;
if (fd >= 0) return fd;
char fname[1024];
split_get_fname(s, idx, fname);
//char *mode = s->create_mode ? "wb+" : "rb+";
int mode = s->create_mode ? (O_CREAT | O_RDWR) : O_RDWR ;
int mode = s->create_mode ? (O_CREAT | O_RDWR) : O_RDWR;
//gprintf("SPLIT OPEN %s %s %d\n", fname, mode, idx); //Wpad_WaitButtons();
//f = fopen(fname, mode);
fd = open(fname, mode);
if (fd<0) return -1;
if (idx > 0 && s->create_mode) {
// gprintf("%s Split: %d %s \n",
// s->create_mode ? "Create" : "Read",
// idx, fname);
if (fd < 0) return -1;
if (idx > 0 && s->create_mode)
{
//gprintf("%s Split: %d %s \n", s->create_mode ? "Create" : "Read", idx, fname);
}
s->fd[idx] = fd;
return fd;
@ -206,15 +208,17 @@ void split_init(split_info_t *s, char *fname)
{
int i;
char *p;
//fprintf(stderr, "SPLIT_INIT %s\n", fname);
//gprintf("SPLIT_INIT %s\n", fname);
memset(s, 0, sizeof(*s));
for (i=0; i<MAX_SPLIT; i++) {
for (i = 0; i < MAX_SPLIT; i++)
{
s->fd[i] = -1;
}
strcpy(s->fname, fname);
s->max_split = 1;
p = strrchr(fname, '.');
if (p && (strcasecmp(p, ".wbfs") == 0)) {
if (p && (strcasecmp(p, ".wbfs") == 0))
{
s->max_split = MAX_SPLIT;
}
}
@ -284,36 +288,37 @@ int split_open(split_info_t *s, char *fname)
u64 split_size = 0;
int fd;
split_init(s, fname);
for (i=0; i<s->max_split; i++) {
for (i = 0; i < s->max_split; i++)
{
fd = split_open_file(s, i);
if (fd<0) {
if (i==0) goto err;
if (fd < 0)
{
if (i == 0)
goto error;
break;
}
// check previous size - all splits except last must be same size
if (i > 0 && size != split_size) {
fprintf(stderr, "split %d: invalid size "FMT_lld"", i, size);
goto err;
if (i > 0 && size != split_size)
{
gprintf("split %i: invalid size %ld\n", i, size);
goto error;
}
// get size
//fseeko(f, 0, SEEK_END);
//size = ftello(f);
size = lseek(fd, 0, SEEK_END);
// check sector alignment
if (size % 512) {
fprintf(stderr, "split %d: size ("FMT_lld") not sector (512) aligned!",
i, size);
}
if (size % 512)
gprintf("split %i: size (%ld) not sector (512) aligned!", i, size);
// first sets split size
if (i==0) {
if (i == 0)
split_size = size;
}
total_size += size;
}
split_set_size(s, split_size, total_size);
return 0;
err:
error:
split_close(s);
return -1;
}

View File

@ -1,10 +1,10 @@
#define MAX_SPLIT 10
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_SPLIT 10
typedef struct split_info
{
char fname[1024];

View File

@ -348,10 +348,12 @@ s32 WBFS_DiskSpace(f32 *used, f32 *free)
wbfs_disc_t* WBFS_OpenDisc(u8 *discid, char *path)
{
if (wbfs_part_fs) return WBFS_Ext_OpenDisc(discid, path);
if (wbfs_part_fs)
return WBFS_Ext_OpenDisc(discid, path);
/* No device open */
if (!hdd) return NULL;
if (!hdd)
return NULL;
/* Open disc */
return wbfs_open_disc(hdd, discid);

View File

@ -56,17 +56,19 @@ wbfs_disc_t* WBFS_Ext_OpenDisc(u8 *discid, char *fname)
if (fd == -1) return NULL;
wbfs_disc_t *iso_file = calloc(sizeof(wbfs_disc_t),1);
if (iso_file == NULL) return NULL;
if (iso_file == NULL)
return NULL;
// mark with a special wbfs_part
wbfs_iso_file.wbfs_sec_sz = 512;
wbfs_iso_file.wbfs_sec_sz = sector_size;
iso_file->p = &wbfs_iso_file;
iso_file->header = (void*)fd;
return iso_file;
}
wbfs_t *part = WBFS_Ext_OpenPart(fname);
if (!part)return NULL;
if(!part)
return NULL;
return wbfs_open_disc(part, discid);
}
@ -129,11 +131,13 @@ wbfs_t* WBFS_Ext_OpenPart(char *fname)
if(split_open(&split, fname) < 0)
return NULL;
wbfs_t *part = wbfs_open_partition(
split_read_sector, nop_write_sector, //readonly //split_write_sector,
&split, sector_size, split.total_sec, 0, 0);
wbfs_set_force_mode(1);
wbfs_t *part = wbfs_open_partition(split_read_sector, nop_write_sector, //readonly //split_write_sector,
&split, sector_size, split.total_sec, 0, 0);
wbfs_set_force_mode(0);
if (!part) split_close(&split);
if (!part)
split_close(&split);
return part;
}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<pd><ViewState><e p="Wiiflow" x="true"></e><e p="Wiiflow\resources" x="false"></e><e p="Wiiflow\source\devicemounter\libwbfs" x="false"></e><e p="Wiiflow\data" x="false"></e><e p="Wiiflow\scripts" x="false"></e><e p="Wiiflow\source" x="true"></e><e p="Wiiflow\source\network" x="false"></e><e p="Wiiflow\source\channel" x="true"></e><e p="Wiiflow\source\menu" x="true"></e><e p="Wiiflow\docs" x="false"></e><e p="Wiiflow\source\cheats" x="true"></e><e p="Wiiflow\portlibs" x="false"></e><e p="Wiiflow\source\config" x="true"></e><e p="Wiiflow\source\devicemounter" x="true"></e><e p="Wiiflow\source\gc" x="true"></e><e p="Wiiflow\source\gecko" x="false"></e><e p="Wiiflow\source\gui" x="true"></e><e p="Wiiflow\source\homebrew" x="true"></e><e p="Wiiflow\source\list" x="true"></e><e p="Wiiflow\source\loader" x="true"></e><e p="Wiiflow\source\memory" x="false"></e><e p="Wiiflow\source\music" x="false"></e><e p="Wiiflow\source\unzip" x="false"></e><e p="Wiiflow\source\wstringEx" x="false"></e><e p="Wiiflow\wii" x="false"></e></ViewState></pd>
<pd><ViewState><e p="Wiiflow" x="true"></e><e p="Wiiflow\resources" x="false"></e><e p="Wiiflow\source\devicemounter\libwbfs" x="false"></e><e p="Wiiflow\data" x="false"></e><e p="Wiiflow\scripts" x="false"></e><e p="Wiiflow\source" x="true"></e><e p="Wiiflow\source\network" x="false"></e><e p="Wiiflow\source\channel" x="true"></e><e p="Wiiflow\source\menu" x="true"></e><e p="Wiiflow\docs" x="false"></e><e p="Wiiflow\source\cheats" x="true"></e><e p="Wiiflow\portlibs" x="false"></e><e p="Wiiflow\source\config" x="true"></e><e p="Wiiflow\source\devicemounter" x="true"></e><e p="Wiiflow\source\gc" x="true"></e><e p="Wiiflow\source\gecko" x="true"></e><e p="Wiiflow\source\gui" x="true"></e><e p="Wiiflow\source\homebrew" x="true"></e><e p="Wiiflow\source\list" x="true"></e><e p="Wiiflow\source\loader" x="true"></e><e p="Wiiflow\source\memory" x="false"></e><e p="Wiiflow\source\music" x="false"></e><e p="Wiiflow\source\plugin" x="false"></e><e p="Wiiflow\source\unzip" x="false"></e><e p="Wiiflow\source\wstringEx" x="false"></e><e p="Wiiflow\wii" x="false"></e></ViewState></pd>