/* * zero_blocks() * * Zeros-out 'num' allocation blocks beginning with 'start'. */ static int zero_blocks(struct hfs_mdb *mdb, int start, int num) { hfs_buffer buf; int end; int j; start = mdb->fs_start + start * mdb->alloc_blksz; end = start + num * mdb->alloc_blksz; for (j=start; j<end; ++j) { if (hfs_buffer_ok(buf = hfs_buffer_get(mdb->sys_mdb, j, 0))) { memset(hfs_buffer_data(buf), 0, HFS_SECTOR_SIZE); hfs_buffer_dirty(buf); hfs_buffer_put(buf); } } return 0; }
/* * parse_new_part_table() * * Parse a new style partition map looking for the * start and length of the 'part'th HFS partition. */ static int parse_new_part_table(hfs_sysmdb sys_mdb, hfs_buffer buf, int part, hfs_s32 *size, hfs_s32 *start) { struct new_pmap *pm = (struct new_pmap *)hfs_buffer_data(buf); hfs_u32 pmap_entries = hfs_get_hl(pm->pmMapBlkCnt); int hfs_part = 0; int entry; for (entry = 0; (entry < pmap_entries) && !(*start); ++entry) { if (entry) { /* read the next partition map entry */ buf = hfs_buffer_get(sys_mdb, HFS_PMAP_BLK + entry, 1); if (!hfs_buffer_ok(buf)) { hfs_warn("hfs_fs: unable to " "read partition map.\n"); goto bail; } pm = (struct new_pmap *)hfs_buffer_data(buf); if (hfs_get_ns(pm->pmSig) != htons(HFS_NEW_PMAP_MAGIC)) { hfs_warn("hfs_fs: invalid " "entry in partition map\n"); hfs_buffer_put(buf); goto bail; } } /* look for an HFS partition */ if (!memcmp(pm->pmPartType,"Apple_HFS",9) && ((hfs_part++) == part)) { /* Found it! */ *start = hfs_get_hl(pm->pmPyPartStart); *size = hfs_get_hl(pm->pmPartBlkCnt); } hfs_buffer_put(buf); } return 0; bail: return 1; }
/* * hfs_part_find() * * Parse the partition map looking for the * start and length of the 'part'th HFS partition. */ int hfs_part_find(hfs_sysmdb sys_mdb, int part, int silent, hfs_s32 *size, hfs_s32 *start) { hfs_buffer buf; hfs_u16 sig; int dd_found = 0; int retval = 1; /* Read block 0 to see if this media is partitioned */ buf = hfs_buffer_get(sys_mdb, HFS_DD_BLK, 1); if (!hfs_buffer_ok(buf)) { hfs_warn("hfs_fs: Unable to read block 0.\n"); goto done; } sig = hfs_get_ns(((struct hfs_drvr_desc *)hfs_buffer_data(buf))->ddSig); hfs_buffer_put(buf); if (sig == htons(HFS_DRVR_DESC_MAGIC)) { /* We are definitely on partitioned media. */ dd_found = 1; } buf = hfs_buffer_get(sys_mdb, HFS_PMAP_BLK, 1); if (!hfs_buffer_ok(buf)) { hfs_warn("hfs_fs: Unable to read block 1.\n"); goto done; } *size = *start = 0; switch (hfs_get_ns(hfs_buffer_data(buf))) { case __constant_htons(HFS_OLD_PMAP_MAGIC): retval = parse_old_part_table(sys_mdb, buf, part, size, start); break; case __constant_htons(HFS_NEW_PMAP_MAGIC): retval = parse_new_part_table(sys_mdb, buf, part, size, start); break; default: if (dd_found) { /* The media claimed to have a partition map */ if (!silent) { hfs_warn("hfs_fs: This disk has an " "unrecognized partition map type.\n"); } } else { /* Conclude that the media is not partitioned */ retval = 0; } goto done; } if (!retval) { if (*start == 0) { if (part) { hfs_warn("hfs_fs: unable to locate " "HFS partition number %d.\n", part); } else { hfs_warn("hfs_fs: unable to locate any " "HFS partitions.\n"); } retval = 1; } else if (*size < 0) { hfs_warn("hfs_fs: Partition size > 1 Terabyte.\n"); retval = 1; } else if (*start < 0) { hfs_warn("hfs_fs: Partition begins beyond 1 " "Terabyte.\n"); retval = 1; } } done: return retval; }