int disk_read_block (xsm_word *page, int block_num) { xsm_word *block; block = disk_get_block (block_num); memcpy(page, block, XSM_PAGE_SIZE * XSM_WORD_SIZE); return TRUE; }
int disk_write_page (xsm_word *page, int block_num) { xsm_word *block; block = disk_get_block (block_num); memcpy (block, page, XSM_PAGE_SIZE * XSM_WORD_SIZE); return TRUE; }
static uint8_t disk_load_partition_map(disk_t *disk, apple_partition_map_t *apm, uint32_t idx) { uint8_t block[512]; disk_get_block(disk, block, 1 + idx); memcpy(apm, block, sizeof(apple_partition_map_t)); fix_endian(apm->pmSigPad); fix_endian(apm->pmMapBlkCnt); fix_endian(apm->pmPyPartStart); fix_endian(apm->pmPartBlkCnt); fix_endian(apm->pmLgDataStart); fix_endian(apm->pmDataCnt); fix_endian(apm->pmPartStatus); fix_endian(apm->pmLgBootStart); fix_endian(apm->pmBootSize); fix_endian(apm->pmBootAddr); fix_endian(apm->pmBootAddr2); fix_endian(apm->pmBootEntry); fix_endian(apm->pmBootEntry2); fix_endian(apm->pmBootCksum); fix_endian(apm->bz.magic); fix_endian(apm->bz.inode); fix_endian(apm->bz.tmade); fix_endian(apm->bz.tmount); fix_endian(apm->bz.tunmount); fix_endian(apm->bz.abm_size); fix_endian(apm->bz.abm_ents); fix_endian(apm->bz.abm_start); if (memcmp(apm->pmSig, "PM", 2) != 0) { sprintf(disk->error_str, "partition index %u has bad magic %02x%02x", idx, apm->pmSig[0], apm->pmSig[1]); return 0; } return 1; }
static disk_t* open_disk (const char *disk_path, char *error_str) { disk_t *disk; uint8_t block[512]; apple_partition_map_t apm; uint32_t i; alloc_pool_t *pool = p_new_pool(NULL); FILE *f; disk = p_alloc(pool, sizeof(disk_t)); disk->pool = pool; disk->block_size = 512; disk->error_str = error_str; disk->path = disk_path; f = fopen(disk_path, "rb"); if (f == NULL) { sprintf(error_str, "Can't open that path"); goto fail; } disk->f = f; // Load the driver descriptor record disk_get_block(disk, block, 0); memcpy(&disk->ddr, block, sizeof(disk->ddr)); fix_endian(disk->ddr.sbBlkSize); fix_endian(disk->ddr.sbBlkCount); fix_endian(disk->ddr.sbDevType); fix_endian(disk->ddr.sbDevId); fix_endian(disk->ddr.sbData); fix_endian(disk->ddr.sbDrvrCount); fix_endian(disk->ddr.ddBlock); fix_endian(disk->ddr.ddSize); fix_endian(disk->ddr.ddType); // If the DDR block exists, (it doesn't have to necessarially) if (memcmp(disk->ddr.sbSig, "ER", 2) == 0) { // Can't handle non-512 byte block sizes if (disk->ddr.sbBlkSize != 512) { sprintf(error_str, "This disk uses blkSize=%u and I can't handle that", disk->ddr.sbBlkSize); goto fail; } } // slog("sizeof(apple_part_map_t) = %lu\n", sizeof(apple_partition_map_t)); // Load the partition maps if (!disk_load_partition_map(disk, &apm, 0)) goto fail; else if ((apm.pmMapBlkCnt > 256) || (apm.pmMapBlkCnt == 0)) { sprintf(error_str, "Crazy number of partitions on this disk %u", apm.pmMapBlkCnt); goto fail; } disk->num_partitions = apm.pmMapBlkCnt; disk->partition_maps = p_alloc(disk->pool, disk->num_partitions * sizeof(apple_partition_map_t)); disk->partitions = p_alloc(disk->pool, disk->num_partitions * sizeof(partition_t)); for (i=0; i<disk->num_partitions; i++) { if (!disk_load_partition_map(disk, &disk->partition_maps[i], i)) goto fail; memset(&disk->partitions[i], 0, sizeof(partition_t)); disk->partitions[i].disk = disk; disk->partitions[i].pool = disk->pool; disk->partitions[i].error_str = error_str; disk->partitions[i].start_block = disk->partition_maps[i].pmPyPartStart; disk->partitions[i].num_blocks = disk->partition_maps[i].pmPartBlkCnt; memcpy(disk->partitions[i].name, disk->partition_maps[i].pmPartName, 32); memcpy(disk->partitions[i].type, disk->partition_maps[i].pmPartType, 32); slog("%u type:%s name:%s\n", i, disk->partitions[i].type, disk->partitions[i].name); slog("bz_magic=0x%08x slice=%u\n", disk->partition_maps[i].bz.magic, disk->partition_maps[i].bz.slice); } return disk; fail: if (f) fclose(f); p_free_pool(pool); return NULL; }
static void part_get_block(partition_t *part, uint8_t buf[512], uint32_t blockno) { assert(blockno < part->num_blocks); disk_get_block(part->disk, buf, part->start_block + blockno); }