mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-25 20:56:53 +01:00
*Added support for physical sector sizes other than 512 bytes per sector for wbfs partitions only! Others filesystems are currently still hardcoded in their libs. Tested with a 3TB drive with a sector size 4096 one wbfs partition (thanks dexter).
*Added initial source for support for virtual sector size other than 512 bytes per sector on wbfs partitions. This still doesn't work (not tested) and will still cause many code dumps because of some unfinished things. So don't use it yet. *New ehcmodule for Hermes IOS versions. This gives a big boost in compatibility to usb drives using Hermes cIOSes. Now many drives should work with it. Hermes cIOSes have now probably the best compatibility to usb devices. (big thanks to rodries here) (more to come ;))
This commit is contained in:
parent
1c3b3ac966
commit
2764ac6b76
@ -2,8 +2,8 @@
|
|||||||
<app version="1">
|
<app version="1">
|
||||||
<name> USB Loader GX</name>
|
<name> USB Loader GX</name>
|
||||||
<coder>USB Loader GX Team</coder>
|
<coder>USB Loader GX Team</coder>
|
||||||
<version>2.0 r1057</version>
|
<version>2.0 r1058</version>
|
||||||
<release_date>201101252019</release_date>
|
<release_date>201101261855</release_date>
|
||||||
<no_ios_reload/>
|
<no_ios_reload/>
|
||||||
<short_description>Loads games from USB-devices</short_description>
|
<short_description>Loads games from USB-devices</short_description>
|
||||||
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times.
|
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times.
|
||||||
|
@ -202,19 +202,26 @@ bool PartitionHandle::IsExisting(u64 lba)
|
|||||||
|
|
||||||
int PartitionHandle::FindPartitions()
|
int PartitionHandle::FindPartitions()
|
||||||
{
|
{
|
||||||
MASTER_BOOT_RECORD mbr;
|
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD *) malloc(MAX_BYTES_PER_SECTOR);
|
||||||
|
if(!mbr) return -1;
|
||||||
|
|
||||||
// Read the first sector on the device
|
// Read the first sector on the device
|
||||||
if (!interface->readSectors(0, 1, &mbr))
|
if (!interface->readSectors(0, 1, mbr))
|
||||||
|
{
|
||||||
|
free(mbr);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// If this is the devices master boot record
|
// If this is the devices master boot record
|
||||||
if (mbr.signature != MBR_SIGNATURE)
|
if (mbr->signature != MBR_SIGNATURE)
|
||||||
|
{
|
||||||
|
free(mbr);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
PARTITION_RECORD * partition = (PARTITION_RECORD *) &mbr.partitions[i];
|
PARTITION_RECORD * partition = (PARTITION_RECORD *) &mbr->partitions[i];
|
||||||
|
|
||||||
if(partition->type == PARTITION_TYPE_GPT)
|
if(partition->type == PARTITION_TYPE_GPT)
|
||||||
{
|
{
|
||||||
@ -237,34 +244,45 @@ int PartitionHandle::FindPartitions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(mbr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PartitionHandle::CheckEBR(u8 PartNum, sec_t ebr_lba)
|
void PartitionHandle::CheckEBR(u8 PartNum, sec_t ebr_lba)
|
||||||
{
|
{
|
||||||
EXTENDED_BOOT_RECORD ebr;
|
EXTENDED_BOOT_RECORD *ebr = (EXTENDED_BOOT_RECORD *) malloc(MAX_BYTES_PER_SECTOR);
|
||||||
|
if(!ebr) return;
|
||||||
sec_t next_erb_lba = 0;
|
sec_t next_erb_lba = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// Read and validate the extended boot record
|
// Read and validate the extended boot record
|
||||||
if (!interface->readSectors(ebr_lba + next_erb_lba, 1, &ebr))
|
if (!interface->readSectors(ebr_lba + next_erb_lba, 1, ebr))
|
||||||
return;
|
|
||||||
|
|
||||||
if (ebr.signature != EBR_SIGNATURE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(le32(ebr.partition.block_count) > 0 && !IsExisting(ebr_lba + next_erb_lba + le32(ebr.partition.lba_start)))
|
|
||||||
{
|
{
|
||||||
AddPartition(PartFromType(ebr.partition.type), ebr_lba + next_erb_lba + le32(ebr.partition.lba_start),
|
free(ebr);
|
||||||
le32(ebr.partition.block_count), (ebr.partition.status == PARTITION_BOOTABLE),
|
return;
|
||||||
ebr.partition.type, PartNum);
|
}
|
||||||
|
|
||||||
|
if (ebr->signature != EBR_SIGNATURE)
|
||||||
|
{
|
||||||
|
free(ebr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(le32(ebr->partition.block_count) > 0 && !IsExisting(ebr_lba + next_erb_lba + le32(ebr->partition.lba_start)))
|
||||||
|
{
|
||||||
|
AddPartition(PartFromType(ebr->partition.type), ebr_lba + next_erb_lba + le32(ebr->partition.lba_start),
|
||||||
|
le32(ebr->partition.block_count), (ebr->partition.status == PARTITION_BOOTABLE),
|
||||||
|
ebr->partition.type, PartNum);
|
||||||
}
|
}
|
||||||
// Get the start sector of the current partition
|
// Get the start sector of the current partition
|
||||||
// and the next extended boot record in the chain
|
// and the next extended boot record in the chain
|
||||||
next_erb_lba = le32(ebr.next_ebr.lba_start);
|
next_erb_lba = le32(ebr->next_ebr.lba_start);
|
||||||
}
|
}
|
||||||
while(next_erb_lba > 0);
|
while(next_erb_lba > 0);
|
||||||
|
|
||||||
|
free(ebr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u8 TYPE_UNUSED[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
static const u8 TYPE_UNUSED[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||||
@ -273,32 +291,39 @@ static const u8 TYPE_LINUX_MS_BASIC_DATA[16] = { 0xA2,0xA0,0xD0,0xEB,0xE5,0xB9,0
|
|||||||
|
|
||||||
int PartitionHandle::CheckGPT(u8 PartNum)
|
int PartitionHandle::CheckGPT(u8 PartNum)
|
||||||
{
|
{
|
||||||
GPT_HEADER gpt_header;
|
GPT_HEADER *gpt_header = (GPT_HEADER *) malloc(MAX_BYTES_PER_SECTOR);
|
||||||
|
if(!gpt_header) return -1;
|
||||||
|
|
||||||
// Read and validate the extended boot record
|
// Read and validate the extended boot record
|
||||||
if (!interface->readSectors(1, 1, &gpt_header))
|
if (!interface->readSectors(1, 1, gpt_header))
|
||||||
|
{
|
||||||
|
free(gpt_header);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if(strncmp(gpt_header.magic, "EFI PART", 8) != 0)
|
if(strncmp(gpt_header->magic, "EFI PART", 8) != 0)
|
||||||
|
{
|
||||||
|
free(gpt_header);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
gpt_header.part_table_lba = le64(gpt_header.part_table_lba);
|
gpt_header->part_table_lba = le64(gpt_header->part_table_lba);
|
||||||
gpt_header.part_entries = le32(gpt_header.part_entries);
|
gpt_header->part_entries = le32(gpt_header->part_entries);
|
||||||
gpt_header.part_entry_size = le32(gpt_header.part_entry_size);
|
gpt_header->part_entry_size = le32(gpt_header->part_entry_size);
|
||||||
gpt_header.part_entry_checksum = le32(gpt_header.part_entry_checksum);
|
gpt_header->part_entry_checksum = le32(gpt_header->part_entry_checksum);
|
||||||
|
|
||||||
u8 * sector_buf = new u8[BYTES_PER_SECTOR];
|
u8 * sector_buf = new u8[MAX_BYTES_PER_SECTOR];
|
||||||
|
|
||||||
u64 next_lba = gpt_header.part_table_lba;
|
u64 next_lba = gpt_header->part_table_lba;
|
||||||
|
|
||||||
for(u32 i = 0; i < gpt_header.part_entries; ++i)
|
for(u32 i = 0; i < gpt_header->part_entries; ++i)
|
||||||
{
|
{
|
||||||
if (!interface->readSectors(next_lba, 1, sector_buf))
|
if (!interface->readSectors(next_lba, 1, sector_buf))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for(u32 n = 0; n < BYTES_PER_SECTOR/gpt_header.part_entry_size; ++n, ++i)
|
for(u32 n = 0; n < BYTES_PER_SECTOR/gpt_header->part_entry_size; ++n, ++i)
|
||||||
{
|
{
|
||||||
GUID_PART_ENTRY * part_entry = (GUID_PART_ENTRY *) (sector_buf+gpt_header.part_entry_size*n);
|
GUID_PART_ENTRY * part_entry = (GUID_PART_ENTRY *) (sector_buf+gpt_header->part_entry_size*n);
|
||||||
|
|
||||||
if(memcmp(part_entry->part_type_guid, TYPE_UNUSED, 16) == 0)
|
if(memcmp(part_entry->part_type_guid, TYPE_UNUSED, 16) == 0)
|
||||||
continue;
|
continue;
|
||||||
@ -315,16 +340,20 @@ int PartitionHandle::CheckGPT(u8 PartNum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete [] sector_buf;
|
delete [] sector_buf;
|
||||||
|
free(gpt_header);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PartitionHandle::AddPartition(const char * name, u64 lba_start, u64 sec_count, bool bootable, u8 part_type, u8 part_num)
|
void PartitionHandle::AddPartition(const char * name, u64 lba_start, u64 sec_count, bool bootable, u8 part_type, u8 part_num)
|
||||||
{
|
{
|
||||||
char buffer[BYTES_PER_SECTOR];
|
char *buffer = (char *) malloc(MAX_BYTES_PER_SECTOR);
|
||||||
|
|
||||||
if (!interface->readSectors(lba_start, 1, buffer))
|
if (!interface->readSectors(lba_start, 1, buffer))
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wbfs_head_t *head = (wbfs_head_t *) buffer;
|
wbfs_head_t *head = (wbfs_head_t *) buffer;
|
||||||
|
|
||||||
@ -362,4 +391,5 @@ void PartitionHandle::AddPartition(const char * name, u64 lba_start, u64 sec_cou
|
|||||||
|
|
||||||
PartitionList.push_back(PartitionEntrie);
|
PartitionList.push_back(PartitionEntrie);
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,8 @@
|
|||||||
#define GUID_HIDDEN_PARTITION 0x2000000000000000LL /* Hidden partition */
|
#define GUID_HIDDEN_PARTITION 0x2000000000000000LL /* Hidden partition */
|
||||||
#define GUID_NO_AUTOMOUNT_PARTITION 0x4000000000000000LL /* Do not automount (e.g., do not assign drive letter) */
|
#define GUID_NO_AUTOMOUNT_PARTITION 0x4000000000000000LL /* Do not automount (e.g., do not assign drive letter) */
|
||||||
|
|
||||||
#define BYTES_PER_SECTOR 512 /* Default in libogc */
|
#define BYTES_PER_SECTOR 512 /* Default in libogc */
|
||||||
|
#define MAX_BYTES_PER_SECTOR 4096 /* Max bytes per sector */
|
||||||
|
|
||||||
typedef struct _PARTITION_RECORD {
|
typedef struct _PARTITION_RECORD {
|
||||||
u8 status; /* Partition status; see above */
|
u8 status; /* Partition status; see above */
|
||||||
|
@ -103,6 +103,14 @@ bool StartUpProcess::USBSpinUp()
|
|||||||
messageTxt->SetTextf("Waiting for HDD: %i sec left\n", retries/20);
|
messageTxt->SetTextf("Waiting for HDD: %i sec left\n", retries/20);
|
||||||
Draw();
|
Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(retries/20 == 18 && IOS_GetVersion() < 200)
|
||||||
|
{
|
||||||
|
DeviceHandler::DestroyInstance();
|
||||||
|
IosLoader::LoadAppCios();
|
||||||
|
DeviceHandler::Instance()->MountSD();
|
||||||
|
handle = DeviceHandler::GetUSBInterface();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while(!started && --retries > 0);
|
while(!started && --retries > 0);
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ int mload_init()
|
|||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if(hid<0) hid = iosCreateHeap(0x8000);
|
if(hid<0) hid = iosCreateHeap(0x10000);
|
||||||
|
|
||||||
if(hid<0)
|
if(hid<0)
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern unsigned char ehcmodule_5[3352];
|
extern unsigned char ehcmodule_5[25883];
|
||||||
|
|
||||||
#define ehcmodule_5_size sizeof(ehcmodule_5)
|
#define ehcmodule_5_size sizeof(ehcmodule_5)
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ u32 AppEntrypoint = 0;
|
|||||||
|
|
||||||
struct discHdr *dvdheader = NULL;
|
struct discHdr *dvdheader = NULL;
|
||||||
extern int wbfs_part_fs;
|
extern int wbfs_part_fs;
|
||||||
|
extern u32 hdd_sector_size;
|
||||||
extern int mountMethod;
|
extern int mountMethod;
|
||||||
|
|
||||||
int GameBooter::BootGCMode()
|
int GameBooter::BootGCMode()
|
||||||
@ -134,7 +135,8 @@ int GameBooter::SetupDisc(u8 * gameID)
|
|||||||
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if(IosLoader::IsWaninkokoIOS() && IOS_GetRevision() < 18)
|
if(((IosLoader::IsWaninkokoIOS() && IOS_GetRevision() < 18) ||
|
||||||
|
hdd_sector_size != 512) && wbfs_part_fs == PART_FS_WBFS)
|
||||||
{
|
{
|
||||||
gprintf("Disc_SetUSB...");
|
gprintf("Disc_SetUSB...");
|
||||||
ret = Disc_SetUSB(gameID);
|
ret = Disc_SetUSB(gameID);
|
||||||
|
@ -65,7 +65,7 @@ static char fs3[] ATTRIBUTE_ALIGN(32) = "/dev/usb/ehc";
|
|||||||
|
|
||||||
static u8 * mem2_ptr = NULL;
|
static u8 * mem2_ptr = NULL;
|
||||||
static s32 hid = -1, fd = -1;
|
static s32 hid = -1, fd = -1;
|
||||||
static u32 sector_size = 0;
|
u32 hdd_sector_size = 512;
|
||||||
|
|
||||||
s32 USBStorage2_Init(void)
|
s32 USBStorage2_Init(void)
|
||||||
{
|
{
|
||||||
@ -93,7 +93,7 @@ s32 USBStorage2_Init(void)
|
|||||||
if (ret < 0) goto err;
|
if (ret < 0) goto err;
|
||||||
|
|
||||||
/* Get device capacity */
|
/* Get device capacity */
|
||||||
if (USBStorage2_GetCapacity(§or_size) == 0)
|
if (USBStorage2_GetCapacity(&hdd_sector_size) == 0)
|
||||||
{
|
{
|
||||||
ret = IPC_ENOENT;
|
ret = IPC_ENOENT;
|
||||||
goto err;
|
goto err;
|
||||||
@ -120,6 +120,8 @@ void USBStorage2_Deinit(void)
|
|||||||
IOS_Close(fd);
|
IOS_Close(fd);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdd_sector_size = 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -143,9 +145,9 @@ s32 USBStorage2_GetCapacity(u32 *_sector_size)
|
|||||||
{
|
{
|
||||||
s32 ret;
|
s32 ret;
|
||||||
|
|
||||||
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", §or_size);
|
ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", &hdd_sector_size);
|
||||||
|
|
||||||
if (ret && _sector_size) *_sector_size = sector_size;
|
if (ret && _sector_size) *_sector_size = hdd_sector_size;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -162,14 +164,14 @@ s32 USBStorage2_ReadSectors(u32 sector, u32 numSectors, void *buffer)
|
|||||||
if (fd < 0) return fd;
|
if (fd < 0) return fd;
|
||||||
|
|
||||||
if (!mem2_ptr)
|
if (!mem2_ptr)
|
||||||
mem2_ptr = (u8 *) MEM2_alloc(sector_size * MAX_BUFFER_SECTORS);
|
mem2_ptr = (u8 *) MEM2_alloc(hdd_sector_size * MAX_BUFFER_SECTORS);
|
||||||
|
|
||||||
s32 read_secs, read_size;
|
s32 read_secs, read_size;
|
||||||
|
|
||||||
while(numSectors > 0)
|
while(numSectors > 0)
|
||||||
{
|
{
|
||||||
read_secs = numSectors > MAX_BUFFER_SECTORS ? MAX_BUFFER_SECTORS : numSectors;
|
read_secs = numSectors > MAX_BUFFER_SECTORS ? MAX_BUFFER_SECTORS : numSectors;
|
||||||
read_size = read_secs*sector_size;
|
read_size = read_secs*hdd_sector_size;
|
||||||
|
|
||||||
// Do not read more than MAX_BUFFER_SECTORS sectors at once and create a mem overflow!
|
// Do not read more than MAX_BUFFER_SECTORS sectors at once and create a mem overflow!
|
||||||
if (!isMEM2Buffer(buffer))
|
if (!isMEM2Buffer(buffer))
|
||||||
@ -206,14 +208,14 @@ s32 USBStorage2_WriteSectors(u32 sector, u32 numSectors, const void *buffer)
|
|||||||
|
|
||||||
/* Device not opened */
|
/* Device not opened */
|
||||||
if (!mem2_ptr)
|
if (!mem2_ptr)
|
||||||
mem2_ptr = (u8 *) MEM2_alloc(sector_size * MAX_BUFFER_SECTORS);
|
mem2_ptr = (u8 *) MEM2_alloc(hdd_sector_size * MAX_BUFFER_SECTORS);
|
||||||
|
|
||||||
s32 write_size, write_secs;
|
s32 write_size, write_secs;
|
||||||
|
|
||||||
while(numSectors > 0)
|
while(numSectors > 0)
|
||||||
{
|
{
|
||||||
write_secs = numSectors > MAX_BUFFER_SECTORS ? MAX_BUFFER_SECTORS : numSectors;
|
write_secs = numSectors > MAX_BUFFER_SECTORS ? MAX_BUFFER_SECTORS : numSectors;
|
||||||
write_size = write_secs*sector_size;
|
write_size = write_secs*hdd_sector_size;
|
||||||
|
|
||||||
/* MEM1 buffer */
|
/* MEM1 buffer */
|
||||||
if (!isMEM2Buffer(buffer))
|
if (!isMEM2Buffer(buffer))
|
||||||
|
@ -14,8 +14,6 @@ rw_sector_callback_t readCallback = NULL;
|
|||||||
rw_sector_callback_t writeCallback = NULL;
|
rw_sector_callback_t writeCallback = NULL;
|
||||||
const DISC_INTERFACE * currentHandle = NULL;
|
const DISC_INTERFACE * currentHandle = NULL;
|
||||||
|
|
||||||
static const u32 sector_size = 512;
|
|
||||||
|
|
||||||
s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf)
|
s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf)
|
||||||
{
|
{
|
||||||
void *buffer = NULL;
|
void *buffer = NULL;
|
||||||
@ -66,20 +64,23 @@ s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf)
|
|||||||
|
|
||||||
s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf)
|
s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf)
|
||||||
{
|
{
|
||||||
|
WBFS_PartInfo * info = (WBFS_PartInfo *) fp;
|
||||||
u32 cnt = 0;
|
u32 cnt = 0;
|
||||||
s32 ret;
|
s32 ret;
|
||||||
|
u32 partition_offset = info->partition_lba + (lba-info->partition_lba)*(info->wbfs_sector_size/info->hdd_sector_size);
|
||||||
|
count *= info->wbfs_sector_size/info->hdd_sector_size;
|
||||||
|
|
||||||
/* Do reads */
|
/* Do reads */
|
||||||
while (cnt < count)
|
while (cnt < count)
|
||||||
{
|
{
|
||||||
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
|
u8 *ptr = ((u8 *) iobuf) + (cnt * info->wbfs_sector_size);
|
||||||
u32 sectors = (count - cnt);
|
u32 sectors = (count - cnt);
|
||||||
|
|
||||||
/* Read sectors is too big */
|
/* Read sectors is too big */
|
||||||
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
||||||
|
|
||||||
/* USB read */
|
/* USB read */
|
||||||
ret = currentHandle->readSectors(lba + cnt, sectors, ptr);
|
ret = currentHandle->readSectors(partition_offset + cnt, sectors, ptr);
|
||||||
if (!ret) return -1;
|
if (!ret) return -1;
|
||||||
|
|
||||||
/* Increment counter */
|
/* Increment counter */
|
||||||
@ -91,20 +92,23 @@ s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf)
|
|||||||
|
|
||||||
s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf)
|
s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf)
|
||||||
{
|
{
|
||||||
|
WBFS_PartInfo * info = (WBFS_PartInfo *) fp;
|
||||||
u32 cnt = 0;
|
u32 cnt = 0;
|
||||||
s32 ret;
|
s32 ret;
|
||||||
|
u32 partition_offset = info->partition_lba + (lba-info->partition_lba)*(info->wbfs_sector_size/info->hdd_sector_size);
|
||||||
|
count *= info->wbfs_sector_size/info->hdd_sector_size;
|
||||||
|
|
||||||
/* Do writes */
|
/* Do writes */
|
||||||
while (cnt < count)
|
while (cnt < count)
|
||||||
{
|
{
|
||||||
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
|
u8 *ptr = ((u8 *) iobuf) + (cnt * info->wbfs_sector_size);
|
||||||
u32 sectors = (count - cnt);
|
u32 sectors = (count - cnt);
|
||||||
|
|
||||||
/* Write sectors is too big */
|
/* Write sectors is too big */
|
||||||
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
||||||
|
|
||||||
/* USB write */
|
/* USB write */
|
||||||
ret = currentHandle->writeSectors(lba + cnt, sectors, ptr);
|
ret = currentHandle->writeSectors(partition_offset + cnt, sectors, ptr);
|
||||||
if (!ret) return -1;
|
if (!ret) return -1;
|
||||||
|
|
||||||
/* Increment counter */
|
/* Increment counter */
|
||||||
@ -116,20 +120,23 @@ s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf)
|
|||||||
|
|
||||||
s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf)
|
s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf)
|
||||||
{
|
{
|
||||||
|
WBFS_PartInfo * info = (WBFS_PartInfo *) fp;
|
||||||
u32 cnt = 0;
|
u32 cnt = 0;
|
||||||
s32 ret;
|
s32 ret;
|
||||||
|
u32 partition_offset = info->partition_lba + (lba-info->partition_lba)*(info->wbfs_sector_size/info->hdd_sector_size);
|
||||||
|
count *= info->wbfs_sector_size/info->hdd_sector_size;
|
||||||
|
|
||||||
/* Do reads */
|
/* Do reads */
|
||||||
while (cnt < count)
|
while (cnt < count)
|
||||||
{
|
{
|
||||||
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
|
void *ptr = ((u8 *) iobuf) + (cnt * info->wbfs_sector_size);
|
||||||
u32 sectors = (count - cnt);
|
u32 sectors = (count - cnt);
|
||||||
|
|
||||||
/* Read sectors is too big */
|
/* Read sectors is too big */
|
||||||
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
||||||
|
|
||||||
/* SDHC read */
|
/* SDHC read */
|
||||||
ret = SDHC_ReadSectors(lba + cnt, sectors, ptr);
|
ret = SDHC_ReadSectors(partition_offset + cnt, sectors, ptr);
|
||||||
if (!ret) return -1;
|
if (!ret) return -1;
|
||||||
|
|
||||||
/* Increment counter */
|
/* Increment counter */
|
||||||
@ -141,20 +148,23 @@ s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf)
|
|||||||
|
|
||||||
s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf)
|
s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf)
|
||||||
{
|
{
|
||||||
|
WBFS_PartInfo * info = (WBFS_PartInfo *) fp;
|
||||||
u32 cnt = 0;
|
u32 cnt = 0;
|
||||||
s32 ret;
|
s32 ret;
|
||||||
|
u32 partition_offset = info->partition_lba + (lba-info->partition_lba)*(info->wbfs_sector_size/info->hdd_sector_size);
|
||||||
|
count *= info->wbfs_sector_size/info->hdd_sector_size;
|
||||||
|
|
||||||
/* Do writes */
|
/* Do writes */
|
||||||
while (cnt < count)
|
while (cnt < count)
|
||||||
{
|
{
|
||||||
void *ptr = ((u8 *) iobuf) + (cnt * sector_size);
|
void *ptr = ((u8 *) iobuf) + (cnt * info->wbfs_sector_size);
|
||||||
u32 sectors = (count - cnt);
|
u32 sectors = (count - cnt);
|
||||||
|
|
||||||
/* Write sectors is too big */
|
/* Write sectors is too big */
|
||||||
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
||||||
|
|
||||||
/* SDHC write */
|
/* SDHC write */
|
||||||
ret = SDHC_WriteSectors(lba + cnt, sectors, ptr);
|
ret = SDHC_WriteSectors(partition_offset + cnt, sectors, ptr);
|
||||||
if (!ret) return -1;
|
if (!ret) return -1;
|
||||||
|
|
||||||
/* Increment counter */
|
/* Increment counter */
|
||||||
|
@ -6,8 +6,17 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <gccore.h>
|
||||||
#include "libs/libwbfs/libwbfs.h"
|
#include "libs/libwbfs/libwbfs.h"
|
||||||
|
|
||||||
|
typedef struct _WBFS_PartInfo
|
||||||
|
{
|
||||||
|
u32 wbfs_sector_size;
|
||||||
|
u32 hdd_sector_size;
|
||||||
|
u32 partition_lba;
|
||||||
|
u32 partition_num_sec;
|
||||||
|
} WBFS_PartInfo;
|
||||||
|
|
||||||
extern rw_sector_callback_t readCallback;
|
extern rw_sector_callback_t readCallback;
|
||||||
extern rw_sector_callback_t writeCallback;
|
extern rw_sector_callback_t writeCallback;
|
||||||
extern const DISC_INTERFACE * currentHandle;
|
extern const DISC_INTERFACE * currentHandle;
|
||||||
|
@ -5,24 +5,37 @@
|
|||||||
#include "wbfs_rw.h"
|
#include "wbfs_rw.h"
|
||||||
|
|
||||||
extern int wbfs_part_fs;
|
extern int wbfs_part_fs;
|
||||||
|
extern u32 hdd_sector_size;
|
||||||
|
|
||||||
s32 Wbfs_Wbfs::Open()
|
s32 Wbfs_Wbfs::Open()
|
||||||
{
|
{
|
||||||
wbfs_t *part = NULL;
|
wbfs_t *part = NULL;
|
||||||
|
|
||||||
u8 buffer[512];
|
PartInfo.wbfs_sector_size = hdd_sector_size;
|
||||||
memset(buffer, 0, sizeof(buffer));
|
PartInfo.hdd_sector_size = hdd_sector_size;
|
||||||
|
PartInfo.partition_lba = lba;
|
||||||
|
PartInfo.partition_num_sec = size;
|
||||||
|
|
||||||
wbfs_head_t *head = (wbfs_head_t *) buffer;
|
u8 * buffer = (u8 *) malloc(hdd_sector_size);
|
||||||
|
memset(buffer, 0, hdd_sector_size);
|
||||||
|
|
||||||
if(readCallback(NULL, lba, 1, buffer) < 0)
|
if(readCallback(&PartInfo, lba, 1, buffer) < 0)
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wbfs_head_t head;
|
||||||
|
memcpy(&head, buffer, sizeof(wbfs_head_t));
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
if (head.magic != wbfs_htonl(WBFS_MAGIC))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (head->magic != wbfs_htonl(WBFS_MAGIC))
|
PartInfo.wbfs_sector_size = 1 << head.hd_sec_sz_s;
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Open partition */
|
/* Open partition */
|
||||||
part = wbfs_open_partition(readCallback, writeCallback, NULL, 512, head->n_hd_sec, lba, 0);
|
part = wbfs_open_partition(readCallback, writeCallback, &PartInfo, 1 << head.hd_sec_sz_s, head.n_hd_sec, lba, 0);
|
||||||
if (!part) return -1;
|
if (!part) return -1;
|
||||||
|
|
||||||
/* Close current hard disk */
|
/* Close current hard disk */
|
||||||
@ -65,10 +78,16 @@ void Wbfs_Wbfs::CloseDisc(wbfs_disc_t *disc)
|
|||||||
|
|
||||||
s32 Wbfs_Wbfs::Format()
|
s32 Wbfs_Wbfs::Format()
|
||||||
{
|
{
|
||||||
|
WBFS_PartInfo HDD_Inf;
|
||||||
|
HDD_Inf.wbfs_sector_size = hdd_sector_size;
|
||||||
|
HDD_Inf.hdd_sector_size = hdd_sector_size;
|
||||||
|
HDD_Inf.partition_lba = lba;
|
||||||
|
HDD_Inf.partition_num_sec = size;
|
||||||
|
|
||||||
wbfs_t *partition = NULL;
|
wbfs_t *partition = NULL;
|
||||||
|
|
||||||
/* Reset partition */
|
/* Reset partition */
|
||||||
partition = wbfs_open_partition(readCallback, writeCallback, NULL, 512, size, lba, 1);
|
partition = wbfs_open_partition(readCallback, writeCallback, &PartInfo, hdd_sector_size, size, lba, 1);
|
||||||
if (!partition) return -1;
|
if (!partition) return -1;
|
||||||
|
|
||||||
/* Free memory */
|
/* Free memory */
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "wbfs_base.h"
|
#include "wbfs_base.h"
|
||||||
#include "libs/libwbfs/libwbfs.h"
|
#include "libs/libwbfs/libwbfs.h"
|
||||||
|
#include "wbfs_rw.h"
|
||||||
|
|
||||||
class Wbfs_Wbfs: public Wbfs
|
class Wbfs_Wbfs: public Wbfs
|
||||||
{
|
{
|
||||||
@ -31,6 +32,8 @@ class Wbfs_Wbfs: public Wbfs
|
|||||||
|
|
||||||
u64 EstimateGameSize();
|
u64 EstimateGameSize();
|
||||||
int GetFragList(u8 *id);
|
int GetFragList(u8 *id);
|
||||||
|
private:
|
||||||
|
_WBFS_PartInfo PartInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_WBFS_WBFS_H
|
#endif //_WBFS_WBFS_H
|
||||||
|
Loading…
Reference in New Issue
Block a user