-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 // Modified by oggzee
#include <unistd.h>
#include <sys/stat.h>
#include "libwbfs.h" #include "libwbfs.h"
#include "gecko/gecko.h"
#define likely(x) __builtin_expect(!!(x), 1) #define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0) #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 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))) #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; 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) 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; int i=num_hd_sector,ret;
u8 *ptr,*tmp_buffer = wbfs_ioalloc(hd_sector_size); u8 *ptr,*tmp_buffer = wbfs_ioalloc(hd_sector_size);
u8 part_table[16*4]; u8 part_table[16*4];
ret = read_hdsector(callback_data,0,1,tmp_buffer); ret = read_hdsector(callback_data,0,1,tmp_buffer);
if(ret) return 0; if(ret)
return 0;
//find wbfs partition //find wbfs partition
wbfs_memcpy(part_table, tmp_buffer + 0x1be, 16 * 4); wbfs_memcpy(part_table, tmp_buffer + 0x1be, 16 * 4);
ptr = part_table; 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); wbfs_iofree(tmp_buffer);
if(reset)// XXX make a empty hd partition.. if(reset)// XXX make a empty hd partition..
{ {
} }
return 0; 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_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
p->wii_sec_sz = 0x8000; p->wii_sec_sz = 0x8000;
p->wii_sec_sz_s = size_to_shift(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 = (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->head = head;
p->part_lba = part_lba; p->part_lba = part_lba;
// init the partition // init the partition
@ -89,14 +96,19 @@ wbfs_t *wbfs_open_partition(rw_sector_callback_t read_hdsector, rw_sector_callba
for(sz_s = 6; sz_s < 11; sz_s++) for(sz_s = 6; sz_s < 11; sz_s++)
{ {
// ensure that wbfs_sec_sz is big enough to address every blocks using 16 bits // 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; if(p->n_wii_sec < ((1U << 16) * (1 << sz_s)))
break;
} }
head->wbfs_sec_sz_s = sz_s + p->wii_sec_sz_s; head->wbfs_sec_sz_s = sz_s + p->wii_sec_sz_s;
} }
else read_hdsector(callback_data, p->part_lba, 1, head); else
if (head->magic != wbfs_htonl(WBFS_MAGIC)) ERROR("bad magic"); read_hdsector(callback_data, p->part_lba, 1, head);
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 (head->magic != wbfs_htonl( WBFS_MAGIC ))
if(!force_mode && num_hd_sector && head->n_hd_sec != wbfs_htonl(num_hd_sector)) ERROR("hd num sector doesn't match"); 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 = 1 << head->hd_sec_sz_s;
p->hd_sec_sz_s = 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_hd_sec = wbfs_ntohl(head->n_hd_sec);
@ -109,26 +121,29 @@ wbfs_t *wbfs_open_partition(rw_sector_callback_t read_hdsector, rw_sector_callba
p->n_wbfs_sec_per_disc = p->n_wii_sec_per_disc >> (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); 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->read_hdsector = read_hdsector;
p->write_hdsector = write_hdsector; p->write_hdsector = write_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) p->freeblks = 0; // will alloc and read only if needed if (!reset)
p->freeblks = 0; // will alloc and read only if needed
else else
{ {
// init with all free blocks // init with all free blocks
p->freeblks = wbfs_ioalloc(ALIGN_LBA(p->n_wbfs_sec/8)); p->freeblks = wbfs_ioalloc(ALIGN_LBA( p->n_wbfs_sec / 8));
wbfs_memset(p->freeblks,0xff,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); 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->tmp_buffer = wbfs_ioalloc(p->hd_sec_sz);
p->n_disc_open = 0; p->n_disc_open = 0;
return p; return p;
error: error:
wbfs_free(p); wbfs_free(p);
wbfs_iofree(head); wbfs_iofree(head);
@ -142,7 +157,8 @@ void wbfs_sync(wbfs_t *p)
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) 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); 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->head);
wbfs_iofree(p->tmp_buffer); wbfs_iofree(p->tmp_buffer);
if(p->freeblks) wbfs_iofree(p->freeblks); if(p->freeblks)
wbfs_iofree(p->freeblks);
wbfs_free(p); wbfs_free(p);
@ -175,7 +193,8 @@ wbfs_disc_t *wbfs_open_disc(wbfs_t* p, const u8 *discid)
if(wbfs_memcmp(discid,p->tmp_buffer,6)==0) if(wbfs_memcmp(discid,p->tmp_buffer,6)==0)
{ {
d = wbfs_malloc(sizeof(*d)); d = wbfs_malloc(sizeof(*d));
if(!d) ERROR("allocating memory"); if(!d)
ERROR("allocating memory");
d->p = p; d->p = p;
d->i = i; d->i = i;
d->header = wbfs_ioalloc(p->disc_info_sz); d->header = wbfs_ioalloc(p->disc_info_sz);
@ -183,17 +202,17 @@ wbfs_disc_t *wbfs_open_disc(wbfs_t* p, const u8 *discid)
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->read_hdsector(p->callback_data, p->part_lba + 1 + i * disc_info_sz_lba, disc_info_sz_lba, d->header);
p->n_disc_open ++; p->n_disc_open ++;
// for(i = 0; i < p->n_wbfs_sec_per_disc; i++) //for(i = 0; i < p->n_wbfs_sec_per_disc; i++)
// printf("%d,", wbfs_ntohs(d->header->wlba_table[i])); //printf("%d,", wbfs_ntohs(d->header->wlba_table[i]));
return d; return d;
} }
} }
} }
return 0; return 0;
error: error:
if(d) wbfs_iofree(d); if(d) wbfs_iofree(d);
return 0; return 0;
} }
void wbfs_close_disc(wbfs_disc_t*d) 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 // 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)
{ {
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; wbfs_t *p = d->p;
u16 wlba = offset>>(p->wbfs_sec_sz_s-2); 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; u32 len_copied;
int err = 0; int err = 0;
u8 *ptr = data; u8 *ptr = data;
if(unlikely(iwlba==0)) return 1; if(unlikely(iwlba==0))
return 1;
if(unlikely(off)) if(unlikely(off))
{ {
off *= 4; off *= 4;
err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba<<iwlba_shift) + lba, 1, p->tmp_buffer); 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; 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); wbfs_memcpy(ptr, p->tmp_buffer + off, len_copied);
len -= len_copied; len -= len_copied;
ptr += 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; lba=0;
iwlba = wbfs_ntohs(d->header->wlba_table[++wlba]); 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)) 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, p->part_lba + (iwlba<<iwlba_shift) + lba, nlb, ptr); 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; len -= nlb << p->hd_sec_sz_s;
ptr += nlb << p->hd_sec_sz_s; ptr += nlb << p->hd_sec_sz_s;
lba += nlb; lba += nlb;
@ -250,13 +274,15 @@ int wbfs_disc_read(wbfs_disc_t *d, u32 offset, u32 len, u8 *data)
{ {
lba = 0; lba = 0;
iwlba = wbfs_ntohs(d->header->wlba_table[++wlba]); iwlba = wbfs_ntohs(d->header->wlba_table[++wlba]);
if(unlikely(iwlba==0)) return 1; if(unlikely(iwlba==0))
return 1;
} }
} }
if(unlikely(len)) if(unlikely(len))
{ {
err = p->read_hdsector(p->callback_data, p->part_lba + (iwlba << iwlba_shift) + lba, 1, p->tmp_buffer); 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); wbfs_memcpy(ptr, p->tmp_buffer, len);
} }
return 0; return 0;
@ -267,16 +293,21 @@ u32 wbfs_count_discs(wbfs_t *p)
{ {
u32 i,count=0; u32 i,count=0;
for(i = 0; i < p->max_disc; i++) for(i = 0; i < p->max_disc; i++)
if (p->head->disc_table[i]) count++; {
if (p->head->disc_table[i])
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;
for(j = 0; j < p->n_wbfs_sec_per_disc; 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; return tot_blk;
} }
@ -284,21 +315,26 @@ u32 wbfs_sector_used2(wbfs_t *p, wbfs_disc_info_t *di, u32 *last_blk)
{ {
u32 tot_blk = 0, j; u32 tot_blk = 0, j;
for(j = 0; j < p->n_wbfs_sec_per_disc; j++) for(j = 0; j < p->n_wbfs_sec_per_disc; j++)
{
if(wbfs_ntohs(di->wlba_table[j])) if(wbfs_ntohs(di->wlba_table[j]))
{ {
if (last_blk) *last_blk = j; if (last_blk)
*last_blk = j;
tot_blk++; tot_blk++;
} }
}
return 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; 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)
@ -323,12 +359,14 @@ u32 wbfs_get_disc_info(wbfs_t *p, u32 index,u8 *header,int header_size,u32 *size
return 0; return 0;
} }
} }
}
return 1; return 1;
} }
static void load_freeblocks(wbfs_t *p) static void load_freeblocks(wbfs_t *p)
{ {
if(p->freeblks) return; if(p->freeblks)
return;
// 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);
@ -344,10 +382,14 @@ u32 wbfs_count_usedblocks(wbfs_t *p)
if(v == ~0U) if(v == ~0U)
count += 32; count += 32;
else if(v != 0) else if(v != 0)
{
for(j = 0; j < 32; j++) for(j = 0; j < 32; j++)
{
if (v & (1 << j)) if (v & (1 << j))
count++; count++;
} }
}
}
return count; return count;
} }
@ -358,7 +400,10 @@ int block_used(u8 *used, u32 i, u32 wblk_sz)
u32 k; u32 k;
i *= wblk_sz; i *= wblk_sz;
for(k = 0; k < wblk_sz; k++) 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; return 0;
} }
@ -371,6 +416,7 @@ static u32 alloc_block(wbfs_t *p)
if(v != 0) if(v != 0)
{ {
for(j = 0; j < 32; j++) for(j = 0; j < 32; j++)
{
if (v & (1 << j)) if (v & (1 << j))
{ {
p->freeblks[i] = wbfs_htonl(v & ~(1<<j)); p->freeblks[i] = wbfs_htonl(v & ~(1<<j));
@ -378,6 +424,7 @@ static u32 alloc_block(wbfs_t *p)
} }
} }
} }
}
return ~0; return ~0;
} }
static void free_block(wbfs_t *p,int bl) static void free_block(wbfs_t *p,int bl)
@ -388,7 +435,8 @@ static void free_block(wbfs_t *p,int bl)
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,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; int i,discn;
u32 tot,cur; 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; u32 last_used;
used = wbfs_malloc(p->n_wii_sec_per_disc); 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 // copy_1_1 needs disk usage for layers detection
//if(!copy_1_1) //if(!copy_1_1)
{ {
d = wd_open_disc(read_src_wii_disc, callback_data); 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_build_disc_usage(d, sel, used);
wd_close_disc(d); 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. 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; p->head->disc_table[i] = 1;
discn = i; discn = i;
load_freeblocks(p); 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); 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) ERROR("alloc memory"); if(!copy_buffer)
ERROR("alloc memory");
tot = 0; tot = 0;
cur = 0; cur = 0;
num_wbfs_sect_to_copy = p->n_wbfs_sec_per_disc; 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) if (copy_1_1)
{ {
// detect single or dual layer // 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; 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; 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) if (copy_1_1 && i > p->n_wbfs_sec_per_disc / 2)
{ {
// end of dual layer data // 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); spinner(tot,tot,spinner_data);
break; 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 //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->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); * (p->wii_sec_sz / p->hd_sec_sz), p->wii_sec_sz / p->hd_sec_sz, copy_buffer);
cur++; 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); info->wlba_table[i] = wbfs_htons(bl);
} }
// write disc info // 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); p->write_hdsector(p->callback_data,p->part_lba+1+discn*disc_info_sz_lba,disc_info_sz_lba,info);
wbfs_sync(p); wbfs_sync(p);
retval = 0; 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; return retval;
} }
@ -519,13 +583,15 @@ u32 wbfs_rm_disc(wbfs_t *p, u8* 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) return 1; if(!d)
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) free_block(p,iwlba); if(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);
@ -550,7 +616,8 @@ u32 wbfs_trim(wbfs_t *p)
} }
// 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)
{ {
wbfs_t *p = d->p; wbfs_t *p = d->p;
u8* copy_buffer = 0; 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 src_wbs_nlb = p->wbfs_sec_sz / p->hd_sec_sz;
int dst_wbs_nlb = p->wbfs_sec_sz / p->wii_sec_sz; int dst_wbs_nlb = p->wbfs_sec_sz / p->wii_sec_sz;
copy_buffer = wbfs_ioalloc(p->wbfs_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++) 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)
{ {
if(spinner)
if(spinner) spinner(i, p->n_wbfs_sec_per_disc, NULL); 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); 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); write_dst_wii_sector(callback_data, i * dst_wbs_nlb, dst_wbs_nlb, copy_buffer);
} }
@ -577,18 +645,21 @@ error:
return 1; 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; int i;
u32 tot = 0, last = 0; u32 tot = 0, last = 0;
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 =wbfs_malloc(p->n_wii_sec_per_disc); u8 *used = wbfs_malloc(p->n_wii_sec_per_disc);
if(!used) ERROR("unable to alloc memory"); if(!used)
ERROR("unable to alloc memory");
d = wd_open_disc(read_src_wii_disc,callback_data); 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_build_disc_usage(d, sel, used);
wd_close_disc(d); 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: error:
if(d) wd_close_disc(d); if(d)
if(used) wbfs_free(used); wd_close_disc(d);
if(used)
wbfs_free(used);
*comp_size = tot; *comp_size = tot;
*real_size = last; *real_size = last;
@ -648,9 +721,11 @@ u32 wbfs_extract_file(wbfs_disc_t *d, char *path, void **data)
return ret; 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; wbfs_t *p = d->p;
int src_wbs_nlb = p->wbfs_sec_sz / hdd_sector_size; 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; 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; last = p->n_wbfs_sec_per_disc / 2;
u32 size = last * src_wbs_nlb; 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 // 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 // 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) 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 = (int)d->header; //HMM?
//int fd = d->i; //int fd = d->i;
off_t off = ((u64)offset) << 2; off_t off = ((u64)offset) << 2;
off_t ret_off; off_t ret_off;
int ret; int ret;
ret_off = lseek(fd, off, SEEK_SET); ret_off = lseek(fd, off, SEEK_SET);
if (ret_off != off) return -1; if (ret_off != off)
return -1;
ret = read(fd, data, len); ret = read(fd, data, len);
if (ret != len) return -2; if (ret != len)
return -2;
return 0; return 0;
} }
u32 wbfs_disc_sector_used(wbfs_disc_t *d, u32 *num_blk) 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) if (d->p == &wbfs_iso_file)
{ {
int fd = (int)d->header; //HMM? int fd = (int)d->header; //HMM?
//int fd = d->i; //int fd = d->i;
struct stat st; struct stat st;
if (fstat(fd, &st) == -1) return 0; if (fstat(fd, &st) == -1)
if (num_blk) *num_blk = (st.st_size >> 9); // in 512 units return 0;
if (num_blk)
*num_blk = (st.st_size >> 9); // in 512 units
return st.st_blocks; // in 512 units (can be sparse) return st.st_blocks; // in 512 units (can be sparse)
} }
u32 last_blk = 0; 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) *num_blk = last_blk + 1; if (num_blk)
*num_blk = last_blk + 1;
return ret; return ret;
} }

View File

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

View File

@ -1,10 +1,10 @@
#define MAX_SPLIT 10
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define MAX_SPLIT 10
typedef struct split_info typedef struct split_info
{ {
char fname[1024]; 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) 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 */ /* No device open */
if (!hdd) return NULL; if (!hdd)
return NULL;
/* Open disc */ /* Open disc */
return wbfs_open_disc(hdd, discid); 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; if (fd == -1) return NULL;
wbfs_disc_t *iso_file = calloc(sizeof(wbfs_disc_t),1); 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 // 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->p = &wbfs_iso_file;
iso_file->header = (void*)fd; iso_file->header = (void*)fd;
return iso_file; return iso_file;
} }
wbfs_t *part = WBFS_Ext_OpenPart(fname); wbfs_t *part = WBFS_Ext_OpenPart(fname);
if (!part)return NULL; if(!part)
return NULL;
return wbfs_open_disc(part, discid); return wbfs_open_disc(part, discid);
} }
@ -129,11 +131,13 @@ wbfs_t* WBFS_Ext_OpenPart(char *fname)
if(split_open(&split, fname) < 0) if(split_open(&split, fname) < 0)
return NULL; return NULL;
wbfs_t *part = wbfs_open_partition( wbfs_set_force_mode(1);
split_read_sector, nop_write_sector, //readonly //split_write_sector, wbfs_t *part = wbfs_open_partition(split_read_sector, nop_write_sector, //readonly //split_write_sector,
&split, sector_size, split.total_sec, 0, 0); &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; 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>