diff --git a/HBC/META.XML b/HBC/META.XML index 0b2c1924..961b86c6 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,8 +2,8 @@ USB Loader GX USB Loader GX Team - 1.0 r967 - 201009241313 + 1.0 r968 + 201009241346 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/usbloader/partition_usbloader.c b/source/usbloader/partition_usbloader.c index a063ef95..1bd59d91 100644 --- a/source/usbloader/partition_usbloader.c +++ b/source/usbloader/partition_usbloader.c @@ -1,417 +1,418 @@ -// Modified by oggzee - -#include -#include -#include -#include - -#include "partition_usbloader.h" -#include "sdhc.h" -#include "usbstorage2.h" -#include "utils.h" -#include "wbfs.h" -#include "libwbfs/libwbfs.h" - -/* 'partition table' structure */ -typedef struct -{ - /* Zero bytes */ - u8 padding[446]; - - /* Partition table entries */ - partitionEntry entries[MAX_PARTITIONS]; -}ATTRIBUTE_PACKED partitionTable; - -s32 Partition_GetEntries(u32 device, partitionEntry *outbuf, u32 *outval) -{ - static partitionTable table ATTRIBUTE_ALIGN( 32 ); - - u32 cnt, sector_size; - s32 ret; - - /* Read from specified device */ - switch (device) - { - case WBFS_DEVICE_USB: - { - /* Get sector size */ - ret = USBStorage2_GetCapacity(§or_size); - if (ret == 0) return -1; - - /* Read partition table */ - ret = USBStorage2_ReadSectors(0, 1, &table); - if (ret < 0) return ret; - - break; - } - - case WBFS_DEVICE_SDHC: - { - /* SDHC sector size */ - sector_size = SDHC_SECTOR_SIZE; - - /* Read partition table */ - ret = SDHC_ReadSectors(0, 1, &table); - if (!ret) return -1; - - break; - } - - default: - return -1; - } - - /* Swap endianess */ - for (cnt = 0; cnt < 4; cnt++) - { - partitionEntry *entry = &table.entries[cnt]; - - entry->sector = swap32(entry->sector); - entry->size = swap32(entry->size); - } - - /* Set partition entries */ - memcpy(outbuf, table.entries, sizeof(table.entries)); - - /* Set sector size */ - *outval = sector_size; - - return 0; -} - -bool Device_ReadSectors(u32 device, u32 sector, u32 count, void *buffer) -{ - s32 ret; - - /* Read from specified device */ - switch (device) - { - case WBFS_DEVICE_USB: - ret = USBStorage2_ReadSectors(sector, count, buffer); - if (ret < 0) return false; - return true; - - case WBFS_DEVICE_SDHC: - return SDHC_ReadSectors(sector, count, buffer); - } - - return false; -} - -bool Device_WriteSectors(u32 device, u32 sector, u32 count, void *buffer) -{ - s32 ret; - - /* Read from specified device */ - switch (device) - { - case WBFS_DEVICE_USB: - ret = USBStorage2_WriteSectors(sector, count, buffer); - if (ret < 0) return false; - return true; - - case WBFS_DEVICE_SDHC: - return SDHC_WriteSectors(sector, count, buffer); - } - - return false; -} - -s32 Partition_GetEntriesEx(u32 device, partitionEntry *outbuf, u32 *psect_size, u8 *num) -{ - static partitionTable table ATTRIBUTE_ALIGN( 32 ); - partitionEntry *entry; - - u32 i, sector_size; - s32 ret; - int maxpart = *num; - - // Get sector size - switch (device) - { - case WBFS_DEVICE_USB: - ret = USBStorage2_GetCapacity(§or_size); - if (ret == 0) return -1; - break; - case WBFS_DEVICE_SDHC: - sector_size = SDHC_SECTOR_SIZE; - break; - default: - return -1; - } - /* Set sector size */ - *psect_size = sector_size; - - u32 ext = 0; - u32 next = 0; - - // Read partition table - ret = Device_ReadSectors(device, 0, 1, &table); - if (!ret) return -1; - // Check if it's a RAW WBFS disc, without partition table - if (get_fs_type(&table) == FS_TYPE_WBFS) - { - memset(outbuf, 0, sizeof(table.entries)); - wbfs_head_t *head = (wbfs_head_t*) &table; - outbuf->size = wbfs_ntohl( head->n_hd_sec ); - *num = 1; - return 0; - } - /* Swap endianess */ - for (i = 0; i < 4; i++) - { - entry = &table.entries[i]; - entry->sector = swap32(entry->sector); - entry->size = swap32(entry->size); - if (!ext && part_is_extended(entry->type)) - { - ext = entry->sector; - } - } - /* Set partition entries */ - memcpy(outbuf, table.entries, sizeof(table.entries)); - // num primary - *num = 4; - - if (!ext) return 0; - - next = ext; - // scan extended partition for logical - for (i = 0; i < maxpart - 4; i++) - { - ret = Device_ReadSectors(device, next, 1, &table); - if (!ret) break; - if (i == 0) - { - // handle the invalid scenario where wbfs is on an EXTENDED - // partition instead of on the Logical inside Extended. - if (get_fs_type(&table) == FS_TYPE_WBFS) break; - } - entry = &table.entries[0]; - entry->sector = swap32(entry->sector); - entry->size = swap32(entry->size); - if (entry->type && entry->size && entry->sector) - { - // rebase to abolute address - entry->sector += next; - // add logical - memcpy(&outbuf[*num], entry, sizeof(*entry)); - (*num)++; - // get next - entry++; - if (entry->type && entry->size && entry->sector) - { - next = ext + swap32(entry->sector); - } - else - { - break; - } - } - } - - return 0; -} - -bool part_is_extended(int type) -{ - if (type == 0x05) return true; - if (type == 0x0f) return true; - return false; -} - -bool part_is_data(int type) -{ - if (type && !part_is_extended(type)) return true; - return false; -} - -bool part_valid_data(partitionEntry *entry) -{ - if (entry->size && entry->type && entry->sector) - { - return part_is_data(entry->type); - } - return false; -} - -char* part_type_data(int type) -{ - switch (type) - { - case 0x01: - return "FAT12"; - case 0x04: - return "FAT16"; - case 0x06: - return "FAT16"; //+ - case 0x07: - return "NTFS"; - case 0x0b: - return "FAT32"; - case 0x0c: - return "FAT32"; - case 0x0e: - return "FAT16"; - case 0x82: - return "LxSWP"; - case 0x83: - return "LINUX"; - case 0x8e: - return "LxLVM"; - case 0xa8: - return "OSX"; - case 0xab: - return "OSXBT"; - case 0xaf: - return "OSXHF"; - case 0xe8: - return "LUKS"; - } - return NULL; -} - -char *part_type_name(int type) -{ - static char unk[8]; - if (type == 0) return "UNUSED"; - if (part_is_extended(type)) return "EXTEND"; - char *p = part_type_data(type); - if (p) return p; - sprintf(unk, "UNK-%02x", type); - return unk; -} - -int get_fs_type(void *buff) -{ - char *buf = buff; - // WBFS - wbfs_head_t *head = (wbfs_head_t *) buff; - if (head->magic == wbfs_htonl( WBFS_MAGIC )) return FS_TYPE_WBFS; - // 55AA - if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA) - { - // FAT - if (memcmp(buf + 0x36, "FAT", 3) == 0) return FS_TYPE_FAT16; - if (memcmp(buf + 0x52, "FAT", 3) == 0) return FS_TYPE_FAT32; - // NTFS - if (memcmp(buf + 0x03, "NTFS", 4) == 0) return FS_TYPE_NTFS; - } - return FS_TYPE_UNK; -} - -int get_part_fs(int fs_type) -{ - switch (fs_type) - { - case FS_TYPE_FAT32: - return PART_FS_FAT; - case FS_TYPE_NTFS: - return PART_FS_NTFS; - case FS_TYPE_WBFS: - return PART_FS_WBFS; - default: - return -1; - } -} - -bool is_type_fat(int type) -{ - return (type == FS_TYPE_FAT16 || type == FS_TYPE_FAT32); -} - -char *get_fs_name(int i) -{ - switch (i) - { - case FS_TYPE_FAT16: - return "FAT16"; - case FS_TYPE_FAT32: - return "FAT32"; - case FS_TYPE_NTFS: - return "NTFS"; - case FS_TYPE_WBFS: - return "WBFS"; - } - return ""; -} - -s32 Partition_GetList(u32 device, PartList *plist) -{ - partitionEntry *entry = NULL; - PartInfo *pinfo = NULL; - int i, ret; - - memset(plist, 0, sizeof(PartList)); - - // Get partition entries - plist->num = MAX_PARTITIONS_EX; - ret = Partition_GetEntriesEx(device, plist->pentry, &plist->sector_size, &plist->num); - if (ret < 0) - { - return -1; - } - // check for RAW WBFS disc - if (plist->num == 1) - { - pinfo = &plist->pinfo[0]; - entry = &plist->pentry[0]; - plist->wbfs_n = 1; - pinfo->wbfs_i = pinfo->index = 1; - return 0; - } - - char buf[plist->sector_size]; - - // scan partitions for filesystem type - for (i = 0; i < plist->num; i++) - { - pinfo = &plist->pinfo[i]; - entry = &plist->pentry[i]; - if (!entry->size) continue; - if (!entry->type) continue; - if (!entry->sector) continue; - // even though wrong, it's possible WBFS is on an extended part. - //if (!part_is_data(entry->type)) continue; - if (!Device_ReadSectors(device, entry->sector, 1, buf)) continue; - pinfo->fs_type = get_fs_type(buf); - if (pinfo->fs_type == FS_TYPE_WBFS) - { - // multiple wbfs on sdhc not supported - if (device == WBFS_DEVICE_SDHC && (plist->wbfs_n > 1 || i > 4)) continue; - plist->wbfs_n++; - pinfo->wbfs_i = pinfo->index = plist->wbfs_n; - } - else if (is_type_fat(pinfo->fs_type)) - { - plist->fat_n++; - pinfo->fat_i = pinfo->index = plist->fat_n; - } - else if (pinfo->fs_type == FS_TYPE_NTFS) - { - plist->ntfs_n++; - pinfo->ntfs_i = pinfo->index = plist->ntfs_n; - } - pinfo->part_fs = get_part_fs(pinfo->fs_type); - } - return 0; -} - -int Partition_FixEXT(u32 device, u8 part) -{ - static partitionTable table ATTRIBUTE_ALIGN( 32 ); - int ret; - - if (part > 3) return -1; - // Read partition table - ret = Device_ReadSectors(device, 0, 1, &table); - if (!ret) return -1; - if (part_is_extended(table.entries[part].type)) - { - table.entries[part].type = 0x0b; // FAT32 - ret = Device_WriteSectors(device, 0, 1, &table); - if (!ret) return -1; - return 0; - } - return -1; -} +// Modified by oggzee + +#include +#include +#include +#include + +#include "partition_usbloader.h" +#include "sdhc.h" +#include "usbstorage2.h" +#include "utils.h" +#include "wbfs.h" +#include "libwbfs/libwbfs.h" + +/* 'partition table' structure */ +typedef struct +{ + /* Zero bytes */ + u8 padding[446]; + + /* Partition table entries */ + partitionEntry entries[MAX_PARTITIONS]; +}ATTRIBUTE_PACKED partitionTable; + +s32 Partition_GetEntries(u32 device, partitionEntry *outbuf, u32 *outval) +{ + static partitionTable table ATTRIBUTE_ALIGN( 32 ); + + u32 cnt, sector_size; + s32 ret; + + /* Read from specified device */ + switch (device) + { + case WBFS_DEVICE_USB: + { + /* Get sector size */ + ret = USBStorage2_GetCapacity(§or_size); + if (ret == 0) return -1; + + /* Read partition table */ + ret = USBStorage2_ReadSectors(0, 1, &table); + if (ret < 0) return ret; + + break; + } + + case WBFS_DEVICE_SDHC: + { + /* SDHC sector size */ + sector_size = SDHC_SECTOR_SIZE; + + /* Read partition table */ + ret = SDHC_ReadSectors(0, 1, &table); + if (!ret) return -1; + + break; + } + + default: + return -1; + } + + /* Swap endianess */ + for (cnt = 0; cnt < 4; cnt++) + { + partitionEntry *entry = &table.entries[cnt]; + + entry->sector = swap32(entry->sector); + entry->size = swap32(entry->size); + } + + /* Set partition entries */ + memcpy(outbuf, table.entries, sizeof(table.entries)); + + /* Set sector size */ + *outval = sector_size; + + return 0; +} + +bool Device_ReadSectors(u32 device, u32 sector, u32 count, void *buffer) +{ + s32 ret; + + /* Read from specified device */ + switch (device) + { + case WBFS_DEVICE_USB: + ret = USBStorage2_ReadSectors(sector, count, buffer); + if (ret < 0) return false; + return true; + + case WBFS_DEVICE_SDHC: + return SDHC_ReadSectors(sector, count, buffer); + } + + return false; +} + +bool Device_WriteSectors(u32 device, u32 sector, u32 count, void *buffer) +{ + s32 ret; + + /* Read from specified device */ + switch (device) + { + case WBFS_DEVICE_USB: + ret = USBStorage2_WriteSectors(sector, count, buffer); + if (ret < 0) return false; + return true; + + case WBFS_DEVICE_SDHC: + return SDHC_WriteSectors(sector, count, buffer); + } + + return false; +} + +s32 Partition_GetEntriesEx(u32 device, partitionEntry *outbuf, u32 *psect_size, u8 *num) +{ + static u8 Buffer[sizeof(partitionTable)] ATTRIBUTE_ALIGN( 32 ); + partitionTable *table = (partitionTable *) Buffer; + partitionEntry *entry; + + u32 i, sector_size; + s32 ret; + int maxpart = *num; + + // Get sector size + switch (device) + { + case WBFS_DEVICE_USB: + ret = USBStorage2_GetCapacity(§or_size); + if (ret == 0) return -1; + break; + case WBFS_DEVICE_SDHC: + sector_size = SDHC_SECTOR_SIZE; + break; + default: + return -1; + } + /* Set sector size */ + *psect_size = sector_size; + + u32 ext = 0; + u32 next = 0; + + // Read partition table + ret = Device_ReadSectors(device, 0, 1, table); + if (!ret) return -1; + // Check if it's a RAW WBFS disc, without partition table + if (get_fs_type(table) == FS_TYPE_WBFS) + { + memset(outbuf, 0, sizeof(table->entries)); + wbfs_head_t * head = (wbfs_head_t *) Buffer; + outbuf->size = wbfs_ntohl( head->n_hd_sec ); + *num = 1; + return 0; + } + /* Swap endianess */ + for (i = 0; i < 4; i++) + { + entry = &table->entries[i]; + entry->sector = swap32(entry->sector); + entry->size = swap32(entry->size); + if (!ext && part_is_extended(entry->type)) + { + ext = entry->sector; + } + } + /* Set partition entries */ + memcpy(outbuf, table->entries, sizeof(table->entries)); + // num primary + *num = 4; + + if (!ext) return 0; + + next = ext; + // scan extended partition for logical + for (i = 0; i < maxpart - 4; i++) + { + ret = Device_ReadSectors(device, next, 1, table); + if (!ret) break; + if (i == 0) + { + // handle the invalid scenario where wbfs is on an EXTENDED + // partition instead of on the Logical inside Extended. + if (get_fs_type(&table) == FS_TYPE_WBFS) break; + } + entry = &table->entries[0]; + entry->sector = swap32(entry->sector); + entry->size = swap32(entry->size); + if (entry->type && entry->size && entry->sector) + { + // rebase to abolute address + entry->sector += next; + // add logical + memcpy(&outbuf[*num], entry, sizeof(*entry)); + (*num)++; + // get next + entry++; + if (entry->type && entry->size && entry->sector) + { + next = ext + swap32(entry->sector); + } + else + { + break; + } + } + } + + return 0; +} + +bool part_is_extended(int type) +{ + if (type == 0x05) return true; + if (type == 0x0f) return true; + return false; +} + +bool part_is_data(int type) +{ + if (type && !part_is_extended(type)) return true; + return false; +} + +bool part_valid_data(partitionEntry *entry) +{ + if (entry->size && entry->type && entry->sector) + { + return part_is_data(entry->type); + } + return false; +} + +char* part_type_data(int type) +{ + switch (type) + { + case 0x01: + return "FAT12"; + case 0x04: + return "FAT16"; + case 0x06: + return "FAT16"; //+ + case 0x07: + return "NTFS"; + case 0x0b: + return "FAT32"; + case 0x0c: + return "FAT32"; + case 0x0e: + return "FAT16"; + case 0x82: + return "LxSWP"; + case 0x83: + return "LINUX"; + case 0x8e: + return "LxLVM"; + case 0xa8: + return "OSX"; + case 0xab: + return "OSXBT"; + case 0xaf: + return "OSXHF"; + case 0xe8: + return "LUKS"; + } + return NULL; +} + +char *part_type_name(int type) +{ + static char unk[8]; + if (type == 0) return "UNUSED"; + if (part_is_extended(type)) return "EXTEND"; + char *p = part_type_data(type); + if (p) return p; + sprintf(unk, "UNK-%02x", type); + return unk; +} + +int get_fs_type(void *buff) +{ + char *buf = buff; + // WBFS + wbfs_head_t *head = (wbfs_head_t *) buff; + if (head->magic == wbfs_htonl( WBFS_MAGIC )) return FS_TYPE_WBFS; + // 55AA + if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA) + { + // FAT + if (memcmp(buf + 0x36, "FAT", 3) == 0) return FS_TYPE_FAT16; + if (memcmp(buf + 0x52, "FAT", 3) == 0) return FS_TYPE_FAT32; + // NTFS + if (memcmp(buf + 0x03, "NTFS", 4) == 0) return FS_TYPE_NTFS; + } + return FS_TYPE_UNK; +} + +int get_part_fs(int fs_type) +{ + switch (fs_type) + { + case FS_TYPE_FAT32: + return PART_FS_FAT; + case FS_TYPE_NTFS: + return PART_FS_NTFS; + case FS_TYPE_WBFS: + return PART_FS_WBFS; + default: + return -1; + } +} + +bool is_type_fat(int type) +{ + return (type == FS_TYPE_FAT16 || type == FS_TYPE_FAT32); +} + +char *get_fs_name(int i) +{ + switch (i) + { + case FS_TYPE_FAT16: + return "FAT16"; + case FS_TYPE_FAT32: + return "FAT32"; + case FS_TYPE_NTFS: + return "NTFS"; + case FS_TYPE_WBFS: + return "WBFS"; + } + return ""; +} + +s32 Partition_GetList(u32 device, PartList *plist) +{ + partitionEntry *entry = NULL; + PartInfo *pinfo = NULL; + int i, ret; + + memset(plist, 0, sizeof(PartList)); + + // Get partition entries + plist->num = MAX_PARTITIONS_EX; + ret = Partition_GetEntriesEx(device, plist->pentry, &plist->sector_size, &plist->num); + if (ret < 0) + { + return -1; + } + // check for RAW WBFS disc + if (plist->num == 1) + { + pinfo = &plist->pinfo[0]; + entry = &plist->pentry[0]; + plist->wbfs_n = 1; + pinfo->wbfs_i = pinfo->index = 1; + return 0; + } + + char buf[plist->sector_size]; + + // scan partitions for filesystem type + for (i = 0; i < plist->num; i++) + { + pinfo = &plist->pinfo[i]; + entry = &plist->pentry[i]; + if (!entry->size) continue; + if (!entry->type) continue; + if (!entry->sector) continue; + // even though wrong, it's possible WBFS is on an extended part. + //if (!part_is_data(entry->type)) continue; + if (!Device_ReadSectors(device, entry->sector, 1, buf)) continue; + pinfo->fs_type = get_fs_type(buf); + if (pinfo->fs_type == FS_TYPE_WBFS) + { + // multiple wbfs on sdhc not supported + if (device == WBFS_DEVICE_SDHC && (plist->wbfs_n > 1 || i > 4)) continue; + plist->wbfs_n++; + pinfo->wbfs_i = pinfo->index = plist->wbfs_n; + } + else if (is_type_fat(pinfo->fs_type)) + { + plist->fat_n++; + pinfo->fat_i = pinfo->index = plist->fat_n; + } + else if (pinfo->fs_type == FS_TYPE_NTFS) + { + plist->ntfs_n++; + pinfo->ntfs_i = pinfo->index = plist->ntfs_n; + } + pinfo->part_fs = get_part_fs(pinfo->fs_type); + } + return 0; +} + +int Partition_FixEXT(u32 device, u8 part) +{ + static partitionTable table ATTRIBUTE_ALIGN( 32 ); + int ret; + + if (part > 3) return -1; + // Read partition table + ret = Device_ReadSectors(device, 0, 1, &table); + if (!ret) return -1; + if (part_is_extended(table.entries[part].type)) + { + table.entries[part].type = 0x0b; // FAT32 + ret = Device_WriteSectors(device, 0, 1, &table); + if (!ret) return -1; + return 0; + } + return -1; +}