From 27024a9ad150fb55bd92c609acd3f3654f13be25 Mon Sep 17 00:00:00 2001 From: "e.bovendeur" Date: Sat, 19 Dec 2009 15:47:12 +0000 Subject: [PATCH] Added changed libwbfs by oggzee. --- HBC/META.XML | 4 +- source/bannersound.cpp | 3 +- source/libntfs/attrib_frag.c | 2 +- source/libwbfs/libwbfs.c | 363 ++++++++++++++++++++++------------- source/libwbfs/libwbfs.h | 32 ++- source/libwbfs/wiidisc.c | 38 ++-- source/libwbfs/wiidisc.h | 6 +- source/main.cpp | 3 +- 8 files changed, 273 insertions(+), 178 deletions(-) diff --git a/HBC/META.XML b/HBC/META.XML index b0fd85c5..97d1b45f 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,8 +2,8 @@ USB Loader GX USB Loader GX Team - 1.0 r867 - 200912161915 + 1.0 r869 + 200912191425 Loads games from USB-devices 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. diff --git a/source/bannersound.cpp b/source/bannersound.cpp index fe300992..baa94f30 100644 --- a/source/bannersound.cpp +++ b/source/bannersound.cpp @@ -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")); diff --git a/source/libntfs/attrib_frag.c b/source/libntfs/attrib_frag.c index f1e1aaf0..7f5a659e 100644 --- a/source/libntfs/attrib_frag.c +++ b/source/libntfs/attrib_frag.c @@ -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(). */ diff --git a/source/libwbfs/libwbfs.c b/source/libwbfs/libwbfs.c index db5b4614..02886357 100644 --- a/source/libwbfs/libwbfs.c +++ b/source/libwbfs/libwbfs.c @@ -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<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;jn_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;imax_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<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;imax_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;imax_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; in_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; in_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 (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; iwbfs_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; jwbfs_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; } + + diff --git a/source/libwbfs/libwbfs.h b/source/libwbfs/libwbfs.h index 31e73567..9c8508f7 100644 --- a/source/libwbfs/libwbfs.h +++ b/source/libwbfs/libwbfs.h @@ -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 } diff --git a/source/libwbfs/wiidisc.c b/source/libwbfs/wiidisc.c index 43e7c95c..6857935c 100644 --- a/source/libwbfs/wiidisc.c +++ b/source/libwbfs/wiidisc.c @@ -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++){ diff --git a/source/libwbfs/wiidisc.h b/source/libwbfs/wiidisc.h index b8e59e0f..ba285208 100644 --- a/source/libwbfs/wiidisc.h +++ b/source/libwbfs/wiidisc.h @@ -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); diff --git a/source/main.cpp b/source/main.cpp index db749a64..a7dd4fc5 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -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());