1 /* $OpenBSD: file_media.c,v 1.48 2016/01/30 17:21:10 krw Exp $ */
2
3 /*
4 * file_media.c -
5 *
6 * Written by Eryk Vershen
7 */
8
9 /*
10 * Copyright 1997,1998 by Apple Computer, Inc.
11 * All Rights Reserved
12 *
13 * Permission to use, copy, modify, and distribute this software and
14 * its documentation for any purpose and without fee is hereby granted,
15 * provided that the above copyright notice appears in all copies and
16 * that both the copyright notice and this permission notice appear in
17 * supporting documentation.
18 *
19 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE.
22 *
23 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
25 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
26 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
27 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 */
29
30 #include <sys/param.h> /* DEV_BSIZE */
31 #include <sys/queue.h>
32
33 #include <err.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38
39 #include "partition_map.h"
40 #include "file_media.h"
41
42 struct ddmap_ondisk {
43 uint8_t ddBlock[4];
44 uint8_t ddSize[2];
45 uint8_t ddType[2];
46 };
47
48 struct block0_ondisk {
49 uint8_t sbSig[2];
50 uint8_t sbBlkSize[2];
51 uint8_t sbBlkCount[4];
52 uint8_t sbDevType[2];
53 uint8_t sbDevId[2];
54 uint8_t sbData[4];
55 uint8_t sbDrvrCount[2];
56 uint8_t sbDDMap[64]; /* ddmap_ondisk[8] */
57 uint8_t reserved[430];
58 };
59
60 struct dpme_ondisk {
61 uint8_t dpme_signature[2];
62 uint8_t dpme_reserved_1[2];
63 uint8_t dpme_map_entries[4];
64 uint8_t dpme_pblock_start[4];
65 uint8_t dpme_pblocks[4];
66 uint8_t dpme_name[DPISTRLEN];
67 uint8_t dpme_type[DPISTRLEN];
68 uint8_t dpme_lblock_start[4];
69 uint8_t dpme_lblocks[4];
70 uint8_t dpme_flags[4];
71 uint8_t dpme_boot_block[4];
72 uint8_t dpme_boot_bytes[4];
73 uint8_t dpme_load_addr[4];
74 uint8_t dpme_reserved_2[4];
75 uint8_t dpme_goto_addr[4];
76 uint8_t dpme_reserved_3[4];
77 uint8_t dpme_checksum[4];
78 uint8_t dpme_processor_id[16];
79 uint8_t dpme_reserved_4[376];
80 };
81
82 static int read_block(int, uint64_t, void *);
83 static int write_block(int, uint64_t, void *);
84
85 static int
read_block(int fd,uint64_t sector,void * address)86 read_block(int fd, uint64_t sector, void *address)
87 {
88 ssize_t off;
89
90 off = pread(fd, address, DEV_BSIZE, sector * DEV_BSIZE);
91 if (off == DEV_BSIZE)
92 return 1;
93
94 if (off == 0)
95 fprintf(stderr, "end of file encountered");
96 else if (off == -1)
97 warn("reading file failed");
98 else
99 fprintf(stderr, "short read");
100
101 return 0;
102 }
103
104 static int
write_block(int fd,uint64_t sector,void * address)105 write_block(int fd, uint64_t sector, void *address)
106 {
107 ssize_t off;
108
109 off = pwrite(fd, address, DEV_BSIZE, sector * DEV_BSIZE);
110 if (off == DEV_BSIZE)
111 return 1;
112
113 warn("writing to file failed");
114 return 0;
115 }
116
117 int
read_block0(int fd,struct partition_map * map)118 read_block0(int fd, struct partition_map *map)
119 {
120 struct block0_ondisk *block0_ondisk;
121 struct ddmap_ondisk ddmap_ondisk;
122 int i;
123
124 block0_ondisk = malloc(sizeof(struct block0_ondisk));
125 if (block0_ondisk == NULL)
126 errx(1, "No memory to read block0");
127
128 if (read_block(fd, 0, block0_ondisk) == 0)
129 return 0;
130
131 memcpy(&map->sbSig, block0_ondisk->sbSig,
132 sizeof(map->sbSig));
133 map->sbSig = betoh16(map->sbSig);
134 memcpy(&map->sbBlkSize, block0_ondisk->sbBlkSize,
135 sizeof(map->sbBlkSize));
136 map->sbBlkSize = betoh16(map->sbBlkSize);
137 memcpy(&map->sbBlkCount, block0_ondisk->sbBlkCount,
138 sizeof(map->sbBlkCount));
139 map->sbBlkCount = betoh32(map->sbBlkCount);
140 memcpy(&map->sbDevType, block0_ondisk->sbDevType,
141 sizeof(map->sbDevType));
142 map->sbDevType = betoh16(map->sbDevType);
143 memcpy(&map->sbDevId, block0_ondisk->sbDevId,
144 sizeof(map->sbDevId));
145 map->sbDevId = betoh16(map->sbDevId);
146 memcpy(&map->sbData, block0_ondisk->sbData,
147 sizeof(map->sbData));
148 map->sbData = betoh32(map->sbData);
149 memcpy(&map->sbDrvrCount, block0_ondisk->sbDrvrCount,
150 sizeof(map->sbDrvrCount));
151 map->sbDrvrCount = betoh16(map->sbDrvrCount);
152
153 for (i = 0; i < 8; i++) {
154 memcpy(&ddmap_ondisk,
155 map->sbDDMap+i*sizeof(struct ddmap_ondisk),
156 sizeof(ddmap_ondisk));
157 memcpy(&map->sbDDMap[i].ddBlock, &ddmap_ondisk.ddBlock,
158 sizeof(map->sbDDMap[i].ddBlock));
159 map->sbDDMap[i].ddBlock =
160 betoh32(map->sbDDMap[i].ddBlock);
161 memcpy(&map->sbDDMap[i].ddSize, &ddmap_ondisk.ddSize,
162 sizeof(map->sbDDMap[i].ddSize));
163 map->sbDDMap[i].ddSize = betoh16(map->sbDDMap[i].ddSize);
164 memcpy(&map->sbDDMap[i].ddType, &ddmap_ondisk.ddType,
165 sizeof(map->sbDDMap[i].ddType));
166 map->sbDDMap[i].ddType = betoh32(map->sbDDMap[i].ddType);
167 }
168
169 free(block0_ondisk);
170 return 1;
171 }
172
173 int
write_block0(int fd,struct partition_map * map)174 write_block0(int fd, struct partition_map *map)
175 {
176 struct block0_ondisk *block0_ondisk;
177 struct ddmap_ondisk ddmap_ondisk;
178 int i, rslt;
179 uint32_t tmp32;
180 uint16_t tmp16;
181
182 block0_ondisk = malloc(sizeof(struct block0_ondisk));
183 if (block0_ondisk == NULL)
184 errx(1, "No memory to write block 0");
185
186 tmp16 = htobe16(map->sbSig);
187 memcpy(block0_ondisk->sbSig, &tmp16,
188 sizeof(block0_ondisk->sbSig));
189 tmp16 = htobe16(map->sbBlkSize);
190 memcpy(block0_ondisk->sbBlkSize, &tmp16,
191 sizeof(block0_ondisk->sbBlkSize));
192 tmp32 = htobe32(map->sbBlkCount);
193 memcpy(block0_ondisk->sbBlkCount, &tmp32,
194 sizeof(block0_ondisk->sbBlkCount));
195 tmp16 = htobe16(map->sbDevType);
196 memcpy(block0_ondisk->sbDevType, &tmp16,
197 sizeof(block0_ondisk->sbDevType));
198 tmp16 = htobe16(map->sbDevId);
199 memcpy(block0_ondisk->sbDevId, &tmp16,
200 sizeof(block0_ondisk->sbDevId));
201 tmp32 = htobe32(map->sbData);
202 memcpy(block0_ondisk->sbData, &tmp32,
203 sizeof(block0_ondisk->sbData));
204 tmp16 = htobe16(map->sbDrvrCount);
205 memcpy(block0_ondisk->sbDrvrCount, &tmp16,
206 sizeof(block0_ondisk->sbDrvrCount));
207
208 for (i = 0; i < 8; i++) {
209 tmp32 = htobe32(map->sbDDMap[i].ddBlock);
210 memcpy(ddmap_ondisk.ddBlock, &tmp32,
211 sizeof(ddmap_ondisk.ddBlock));
212 tmp16 = htobe16(map->sbDDMap[i].ddSize);
213 memcpy(&ddmap_ondisk.ddSize, &tmp16,
214 sizeof(ddmap_ondisk.ddSize));
215 tmp16 = betoh32(map->sbDDMap[i].ddType);
216 memcpy(&ddmap_ondisk.ddType, &tmp16,
217 sizeof(ddmap_ondisk.ddType));
218 memcpy(map->sbDDMap+i*sizeof(struct ddmap_ondisk),
219 &ddmap_ondisk, sizeof(ddmap_ondisk));
220 }
221
222 rslt = write_block(fd, 0, block0_ondisk);
223 free(block0_ondisk);
224 return rslt;
225 }
226
227 int
read_dpme(int fd,uint64_t sector,struct entry * entry)228 read_dpme(int fd, uint64_t sector, struct entry *entry)
229 {
230 struct dpme_ondisk *dpme_ondisk;
231
232 dpme_ondisk = malloc(sizeof(struct dpme_ondisk));
233 if (dpme_ondisk == NULL)
234 errx(1, "No memory to read dpme");
235
236 if (read_block(fd, sector, dpme_ondisk) == 0)
237 return 0;
238
239 memcpy(&entry->dpme_signature, dpme_ondisk->dpme_signature,
240 sizeof(entry->dpme_signature));
241 memcpy(&entry->dpme_map_entries, dpme_ondisk->dpme_map_entries,
242 sizeof(entry->dpme_map_entries));
243 memcpy(&entry->dpme_pblock_start, dpme_ondisk->dpme_pblock_start,
244 sizeof(entry->dpme_pblock_start));
245 memcpy(&entry->dpme_pblocks, dpme_ondisk->dpme_pblocks,
246 sizeof(entry->dpme_pblocks));
247 memcpy(&entry->dpme_lblock_start, dpme_ondisk->dpme_lblock_start,
248 sizeof(entry->dpme_lblock_start));
249 memcpy(&entry->dpme_lblocks, dpme_ondisk->dpme_lblocks,
250 sizeof(entry->dpme_lblocks));
251 memcpy(&entry->dpme_flags, dpme_ondisk->dpme_flags,
252 sizeof(entry->dpme_flags));
253 memcpy(&entry->dpme_boot_block, dpme_ondisk->dpme_boot_block,
254 sizeof(entry->dpme_boot_block));
255 memcpy(&entry->dpme_boot_bytes, dpme_ondisk->dpme_boot_bytes,
256 sizeof(entry->dpme_boot_bytes));
257 memcpy(&entry->dpme_load_addr, dpme_ondisk->dpme_load_addr,
258 sizeof(entry->dpme_load_addr));
259 memcpy(&entry->dpme_goto_addr, dpme_ondisk->dpme_goto_addr,
260 sizeof(entry->dpme_goto_addr));
261 memcpy(&entry->dpme_checksum, dpme_ondisk->dpme_checksum,
262 sizeof(entry->dpme_checksum));
263
264 entry->dpme_signature = betoh16(entry->dpme_signature);
265 entry->dpme_map_entries = betoh32(entry->dpme_map_entries);
266 entry->dpme_pblock_start = betoh32(entry->dpme_pblock_start);
267 entry->dpme_pblocks = betoh32(entry->dpme_pblocks);
268 entry->dpme_lblock_start = betoh32(entry->dpme_lblock_start);
269 entry->dpme_lblocks = betoh32(entry->dpme_lblocks);
270 entry->dpme_flags = betoh32(entry->dpme_flags);
271 entry->dpme_boot_block = betoh32(entry->dpme_boot_block);
272 entry->dpme_boot_bytes = betoh32(entry->dpme_boot_bytes);
273 entry->dpme_load_addr = betoh32(entry->dpme_load_addr);
274 entry->dpme_goto_addr = betoh32(entry->dpme_goto_addr);
275 entry->dpme_checksum = betoh32(entry->dpme_checksum);
276
277 memcpy(entry->dpme_reserved_1, dpme_ondisk->dpme_reserved_1,
278 sizeof(entry->dpme_reserved_1));
279 memcpy(entry->dpme_reserved_2, dpme_ondisk->dpme_reserved_2,
280 sizeof(entry->dpme_reserved_2));
281 memcpy(entry->dpme_reserved_3, dpme_ondisk->dpme_reserved_3,
282 sizeof(entry->dpme_reserved_3));
283 memcpy(entry->dpme_reserved_4, dpme_ondisk->dpme_reserved_4,
284 sizeof(entry->dpme_reserved_4));
285
286 strlcpy(entry->dpme_name, dpme_ondisk->dpme_name,
287 sizeof(entry->dpme_name));
288 strlcpy(entry->dpme_type, dpme_ondisk->dpme_type,
289 sizeof(entry->dpme_type));
290 strlcpy(entry->dpme_processor_id, dpme_ondisk->dpme_processor_id,
291 sizeof(entry->dpme_processor_id));
292
293 free(dpme_ondisk);
294 return 1;
295 }
296
297 int
write_dpme(int fd,uint64_t sector,struct entry * entry)298 write_dpme(int fd, uint64_t sector, struct entry *entry)
299 {
300 struct dpme_ondisk *dpme_ondisk;
301 int rslt;
302 uint32_t tmp32;
303 uint16_t tmp16;
304
305 dpme_ondisk = malloc(sizeof(struct dpme_ondisk));
306 if (dpme_ondisk == NULL)
307 errx(1, "No memory to write dpme");
308
309 memcpy(dpme_ondisk->dpme_name, entry->dpme_name,
310 sizeof(dpme_ondisk->dpme_name));
311 memcpy(dpme_ondisk->dpme_type, entry->dpme_type,
312 sizeof(dpme_ondisk->dpme_type));
313 memcpy(dpme_ondisk->dpme_processor_id, entry->dpme_processor_id,
314 sizeof(dpme_ondisk->dpme_processor_id));
315
316 memcpy(dpme_ondisk->dpme_reserved_1, entry->dpme_reserved_1,
317 sizeof(dpme_ondisk->dpme_reserved_1));
318 memcpy(dpme_ondisk->dpme_reserved_2, entry->dpme_reserved_2,
319 sizeof(dpme_ondisk->dpme_reserved_2));
320 memcpy(dpme_ondisk->dpme_reserved_3, entry->dpme_reserved_3,
321 sizeof(dpme_ondisk->dpme_reserved_3));
322 memcpy(dpme_ondisk->dpme_reserved_4, entry->dpme_reserved_4,
323 sizeof(dpme_ondisk->dpme_reserved_4));
324
325 tmp16 = htobe16(entry->dpme_signature);
326 memcpy(dpme_ondisk->dpme_signature, &tmp16,
327 sizeof(dpme_ondisk->dpme_signature));
328 tmp32 = htobe32(entry->dpme_map_entries);
329 memcpy(dpme_ondisk->dpme_map_entries, &tmp32,
330 sizeof(dpme_ondisk->dpme_map_entries));
331 tmp32 = htobe32(entry->dpme_pblock_start);
332 memcpy(dpme_ondisk->dpme_pblock_start, &tmp32,
333 sizeof(dpme_ondisk->dpme_pblock_start));
334 tmp32 = htobe32(entry->dpme_pblocks);
335 memcpy(dpme_ondisk->dpme_pblocks, &tmp32,
336 sizeof(dpme_ondisk->dpme_pblocks));
337 tmp32 = htobe32(entry->dpme_lblock_start);
338 memcpy(dpme_ondisk->dpme_lblock_start, &tmp32,
339 sizeof(dpme_ondisk->dpme_lblock_start));
340 tmp32 = betoh32(entry->dpme_lblocks);
341 memcpy(dpme_ondisk->dpme_lblocks, &tmp32,
342 sizeof(dpme_ondisk->dpme_lblocks));
343 tmp32 = betoh32(entry->dpme_flags);
344 memcpy(dpme_ondisk->dpme_flags, &tmp32,
345 sizeof(dpme_ondisk->dpme_flags));
346 tmp32 = htobe32(entry->dpme_boot_block);
347 memcpy(dpme_ondisk->dpme_boot_block, &tmp32,
348 sizeof(dpme_ondisk->dpme_boot_block));
349 tmp32 = htobe32(entry->dpme_boot_bytes);
350 memcpy(dpme_ondisk->dpme_boot_bytes, &tmp32,
351 sizeof(dpme_ondisk->dpme_boot_bytes));
352 tmp32 = betoh32(entry->dpme_load_addr);
353 memcpy(dpme_ondisk->dpme_load_addr, &tmp32,
354 sizeof(dpme_ondisk->dpme_load_addr));
355 tmp32 = betoh32(entry->dpme_goto_addr);
356 memcpy(dpme_ondisk->dpme_goto_addr, &tmp32,
357 sizeof(dpme_ondisk->dpme_goto_addr));
358 tmp32 = betoh32(entry->dpme_checksum);
359 memcpy(dpme_ondisk->dpme_checksum, &tmp32,
360 sizeof(dpme_ondisk->dpme_checksum));
361
362 rslt = write_block(fd, sector, dpme_ondisk);
363 free(dpme_ondisk);
364 return rslt;
365 }
366