1/* 2 * volume_id - reads filesystem label and uuid 3 * 4 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21#include "volume_id_internal.h" 22 23struct mac_driver_desc { 24 uint8_t signature[2]; 25 uint16_t block_size; 26 uint32_t block_count; 27} PACKED; 28 29struct mac_partition { 30 uint8_t signature[2]; 31 uint16_t res1; 32 uint32_t map_count; 33 uint32_t start_block; 34 uint32_t block_count; 35 uint8_t name[32]; 36 uint8_t type[32]; 37} PACKED; 38 39int FAST_FUNC volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off) 40{ 41 const uint8_t *buf; 42 struct mac_driver_desc *driver; 43 struct mac_partition *part; 44 45 dbg("probing at offset 0x%llx", (unsigned long long) off); 46 47 buf = volume_id_get_buffer(id, off, 0x200); 48 if (buf == NULL) 49 return -1; 50 51 part = (struct mac_partition *) buf; 52 if (part->signature[0] == 'P' && part->signature[1] == 'M' /* "PM" */ 53 && (memcmp(part->type, "Apple_partition_map", 19) == 0) 54 ) { 55 /* linux creates an own subdevice for the map 56 * just return the type if the drive header is missing */ 57// volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE); 58// id->type = "mac_partition_map"; 59 return 0; 60 } 61 62 driver = (struct mac_driver_desc *) buf; 63 if (driver->signature[0] == 'E' && driver->signature[1] == 'R') { /* "ER" */ 64 /* we are on a main device, like a CD 65 * just try to probe the first partition from the map */ 66 unsigned bsize = be16_to_cpu(driver->block_size); 67 int part_count; 68 int i; 69 70 /* get first entry of partition table */ 71 buf = volume_id_get_buffer(id, off + bsize, 0x200); 72 if (buf == NULL) 73 return -1; 74 75 part = (struct mac_partition *) buf; 76 if (part->signature[0] != 'P' || part->signature[1] != 'M') /* not "PM" */ 77 return -1; 78 79 part_count = be32_to_cpu(part->map_count); 80 dbg("expecting %d partition entries", part_count); 81 82 if (id->partitions != NULL) 83 free(id->partitions); 84 id->partitions = xzalloc(part_count * sizeof(struct volume_id_partition)); 85 86 id->partition_count = part_count; 87 88 for (i = 0; i < part_count; i++) { 89 uint64_t poff; 90 uint64_t plen; 91 92 buf = volume_id_get_buffer(id, off + ((i+1) * bsize), 0x200); 93 if (buf == NULL) 94 return -1; 95 96 part = (struct mac_partition *) buf; 97 if (part->signature[0] != 'P' || part->signature[1] != 'M') /* not "PM" */ 98 return -1; 99 100 poff = be32_to_cpu(part->start_block) * bsize; 101 plen = be32_to_cpu(part->block_count) * bsize; 102 dbg("found '%s' partition entry at 0x%llx, len 0x%llx", 103 part->type, (unsigned long long) poff, 104 (unsigned long long) plen); 105 106// id->partitions[i].pt_off = poff; 107// id->partitions[i].pt_len = plen; 108 109// if (memcmp(part->type, "Apple_Free", 10) == 0) { 110// volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNUSED); 111// } else if (memcmp(part->type, "Apple_partition_map", 19) == 0) { 112// volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_PARTITIONTABLE); 113// } else { 114// volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNPROBED); 115// } 116 } 117// volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE); 118// id->type = "mac_partition_map"; 119 return 0; 120 } 121 122 return -1; 123} 124