mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2025-01-11 19:39:09 +01:00
-FINALLY added wii game launching support for 3TB HDDs
This commit is contained in:
parent
2d6a737bc6
commit
eaf62500a9
@ -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
|
||||||
@ -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
|
// choose minimum wblk_sz that fits this partition size
|
||||||
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);
|
||||||
|
|
||||||
p->n_wii_sec = (p->n_hd_sec / p->wii_sec_sz) * (p->hd_sec_sz);
|
p->n_wii_sec = (p->n_hd_sec / p->wii_sec_sz) * (p->hd_sec_sz);
|
||||||
|
|
||||||
p->wbfs_sec_sz_s = head->wbfs_sec_sz_s;
|
p->wbfs_sec_sz_s = head->wbfs_sec_sz_s;
|
||||||
p->wbfs_sec_sz = 1 << p->wbfs_sec_sz_s;
|
p->wbfs_sec_sz = 1 << p->wbfs_sec_sz_s;
|
||||||
p->n_wbfs_sec = p->n_wii_sec >> (p->wbfs_sec_sz_s - p->wii_sec_sz_s);
|
p->n_wbfs_sec = p->n_wii_sec >> (p->wbfs_sec_sz_s - p->wii_sec_sz_s);
|
||||||
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,25 +193,26 @@ 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);
|
||||||
if(!d->header)
|
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->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,26 +315,31 @@ 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)
|
||||||
{
|
{
|
||||||
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;
|
if(header_size > (int)p->hd_sec_sz) header_size = p->hd_sec_sz;
|
||||||
u32 magic = wbfs_ntohl(*(u32*)(p->tmp_buffer + 24));
|
u32 magic = wbfs_ntohl(*(u32*)(p->tmp_buffer + 24));
|
||||||
if(magic != 0x5D1C9EA3)
|
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 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);
|
||||||
@ -340,13 +378,17 @@ u32 wbfs_count_usedblocks(wbfs_t *p)
|
|||||||
load_freeblocks(p);
|
load_freeblocks(p);
|
||||||
for(i = 0; i < p->n_wbfs_sec / (8 * 4); i++)
|
for(i = 0; i < p->n_wbfs_sec / (8 * 4); i++)
|
||||||
{
|
{
|
||||||
u32 v = wbfs_ntohl(p->freeblks[i]);
|
u32 v = wbfs_ntohl(p->freeblks[i]);
|
||||||
if(v == ~0U)
|
if(v == ~0U)
|
||||||
count += 32;
|
count += 32;
|
||||||
else if(v != 0)
|
else if(v != 0)
|
||||||
for(j = 0; j < 32; j++)
|
{
|
||||||
if (v & (1 << j))
|
for(j = 0; j < 32; j++)
|
||||||
count++;
|
{
|
||||||
|
if (v & (1 << j))
|
||||||
|
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,11 +416,13 @@ 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));
|
||||||
return (i * 32) + j + 1;
|
return (i * 32) + j + 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ~0;
|
return ~0;
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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];
|
||||||
|
@ -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);
|
||||||
|
@ -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
@ -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>
|
Loading…
x
Reference in New Issue
Block a user