xref: /openbsd/sbin/pdisk/file_media.c (revision 274d7c50)
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
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
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
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
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
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
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