1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "volume_id_internal.h"
28
29struct mac_driver_desc {
30 uint8_t signature[2];
31 uint16_t block_size;
32 uint32_t block_count;
33} PACKED;
34
35struct mac_partition {
36 uint8_t signature[2];
37 uint16_t res1;
38 uint32_t map_count;
39 uint32_t start_block;
40 uint32_t block_count;
41 uint8_t name[32];
42 uint8_t type[32];
43} PACKED;
44
45int FAST_FUNC volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off)
46{
47 const uint8_t *buf;
48 struct mac_driver_desc *driver;
49 struct mac_partition *part;
50
51 dbg("probing at offset 0x%llx", (unsigned long long) off);
52
53 buf = volume_id_get_buffer(id, off, 0x200);
54 if (buf == NULL)
55 return -1;
56
57 part = (struct mac_partition *) buf;
58 if (part->signature[0] == 'P' && part->signature[1] == 'M'
59 && (memcmp(part->type, "Apple_partition_map", 19) == 0)
60 ) {
61
62
63
64
65 return 0;
66 }
67
68 driver = (struct mac_driver_desc *) buf;
69 if (driver->signature[0] == 'E' && driver->signature[1] == 'R') {
70
71
72 unsigned bsize = be16_to_cpu(driver->block_size);
73 int part_count;
74 int i;
75
76
77 buf = volume_id_get_buffer(id, off + bsize, 0x200);
78 if (buf == NULL)
79 return -1;
80
81 part = (struct mac_partition *) buf;
82 if (part->signature[0] != 'P' || part->signature[1] != 'M')
83 return -1;
84
85 part_count = be32_to_cpu(part->map_count);
86 dbg("expecting %d partition entries", part_count);
87
88 if (id->partitions != NULL)
89 free(id->partitions);
90 id->partitions = xzalloc(part_count * sizeof(struct volume_id_partition));
91
92 id->partition_count = part_count;
93
94 for (i = 0; i < part_count; i++) {
95 uint64_t poff;
96 uint64_t plen;
97
98 buf = volume_id_get_buffer(id, off + ((i+1) * bsize), 0x200);
99 if (buf == NULL)
100 return -1;
101
102 part = (struct mac_partition *) buf;
103 if (part->signature[0] != 'P' || part->signature[1] != 'M')
104 return -1;
105
106 poff = be32_to_cpu(part->start_block) * bsize;
107 plen = be32_to_cpu(part->block_count) * bsize;
108 dbg("found '%s' partition entry at 0x%llx, len 0x%llx",
109 part->type, (unsigned long long) poff,
110 (unsigned long long) plen);
111
112
113
114
115
116
117
118
119
120
121
122 }
123
124
125 return 0;
126 }
127
128 return -1;
129}
130