wbfs_t*wbfs_open_hd( rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, #ifdef WIN32 close_callback_t close_hd, #endif void *callback_data, int hd_sector_size, #ifdef WIN32 int num_hd_sector, #else int num_hd_sector __attribute((unused)), #endif int reset) { int i #ifdef UNUSED_STUFF = num_hd_sector #endif , ret; u8 *ptr,*tmp_buffer = wbfs_ioalloc(hd_sector_size); u8 part_table[16*4]; ret = read_hdsector(callback_data,0,1,tmp_buffer); if(ret) return 0; //find wbfs partition wbfs_memcpy(part_table,tmp_buffer+0x1be,16*4); ptr = part_table; for(i=0;i<4;i++,ptr+=16) { u32 part_lba = read_le32_unaligned(ptr+0x8); wbfs_head_t *head = (wbfs_head_t *)tmp_buffer; #ifdef UNUSED_STUFF ret = #endif read_hdsector(callback_data,part_lba,1,tmp_buffer); // verify there is the magic. if (head->magic == wbfs_htonl(WBFS_MAGIC)) { wbfs_t *p = wbfs_open_partition( read_hdsector, write_hdsector, #ifdef WIN32 close_hd, #endif callback_data, hd_sector_size, 0, part_lba,reset ); return p; } } if(reset)// XXX make a empty hd partition.. { } return 0; }
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 PART_FS_WBFS; // 55AA if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA) { // FAT if (memcmp(buf+0x36,"FAT",3) == 0) return PART_FS_FAT; //FAT16; if (memcmp(buf+0x52,"FAT",3) == 0) return PART_FS_FAT; //FAT32; // NTFS if (memcmp(buf+0x03,"NTFS",4) == 0) return PART_FS_NTFS; } return PART_FS_UNK; }
void PartitionHandle::AddPartition(const char *name, u64 lba_start, u64 sec_count, bool bootable, u8 part_type, u8 part_num) { u8 *buffer = (u8*)MEM2_alloc(MAX_BYTES_PER_SECTOR); if(buffer == NULL) return; if(!interface->readSectors(lba_start, 1, buffer)) { MEM2_free(buffer); return; } wbfs_head_t *head = (wbfs_head_t*)buffer; if(head->magic == wbfs_htonl(WBFS_MAGIC)) { name = "WBFS"; part_type = 0xBF; //Override partition type on WBFS //! correct sector size in physical sectors (512 bytes per sector) sec_count = (u64) head->n_hd_sec * (u64) (1 << head->hd_sec_sz_s) / (u64) BYTES_PER_SECTOR; } else if(*((u16 *)(buffer + 0x1FE)) == 0x55AA) { //! Partition type can be missleading the correct partition format. Stupid lazy ass Partition Editors. if((memcmp(buffer + 0x36, "FAT", 3) == 0 || memcmp(buffer + 0x52, "FAT", 3) == 0) && strncmp(PartFromType(part_type), "FAT", 3) != 0) { name = "FAT32"; part_type = 0x0c; } if(memcmp(buffer + 0x03, "NTFS", 4) == 0) { name = "NTFS"; part_type = 0x07; } } PartitionFS PartitionEntry; PartitionEntry.FSName = name; PartitionEntry.LBA_Start = lba_start; PartitionEntry.SecCount = sec_count; PartitionEntry.Bootable = bootable; PartitionEntry.PartitionType = part_type; PartitionEntry.PartitionNum = part_num; PartitionList.push_back(PartitionEntry); MEM2_free(buffer); }
wbfs_t*wbfs_open_partition(rw_sector_callback_t read_hdsector, rw_sector_callback_t write_hdsector, #ifdef WIN32 close_callback_t close_hd, #endif 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_head_t *head = wbfs_ioalloc(hd_sector_size?hd_sector_size:512); //constants, but put here for consistancy p->wii_sec_sz = 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_per_disc = 143432*2;//support for double layers discs.. p->head = head; p->part_lba = part_lba; // init the partition if (reset) { u8 sz_s; wbfs_memset(head,0,hd_sector_size); head->magic = wbfs_htonl(WBFS_MAGIC); head->hd_sec_sz_s = size_to_shift(hd_sector_size); head->n_hd_sec = wbfs_htonl(num_hd_sector); // choose minimum wblk_sz that fits this partition size for(sz_s=6;sz_s<11;sz_s++) { // 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; } head->wbfs_sec_sz_s = sz_s+p->wii_sec_sz_s; } else read_hdsector(callback_data,p->part_lba,1,head); if (head->magic != wbfs_htonl(WBFS_MAGIC)) 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 != 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_s = head->hd_sec_sz_s; 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<<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_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); //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); p->read_hdsector = read_hdsector; p->write_hdsector = write_hdsector; #ifdef WIN32 p->close_hd = close_hd; #endif 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 { // init with all free blocks p->freeblks = wbfs_ioalloc(ALIGN_LBA(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); 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->n_disc_open = 0; wbfs_sync(p); return p; error: wbfs_free(p); wbfs_iofree(head); return 0; }