xref: /openbsd/sbin/fdisk/part.c (revision fba7235c)
1*fba7235cSkrw /*	$OpenBSD: part.c,v 1.73 2015/10/26 15:08:26 krw Exp $	*/
2a1705421Sweingart 
3a1705421Sweingart /*
4a1705421Sweingart  * Copyright (c) 1997 Tobias Weingartner
5a1705421Sweingart  *
610a68084Skrw  * Permission to use, copy, modify, and distribute this software for any
710a68084Skrw  * purpose with or without fee is hereby granted, provided that the above
810a68084Skrw  * copyright notice and this permission notice appear in all copies.
9a1705421Sweingart  *
1010a68084Skrw  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1110a68084Skrw  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1210a68084Skrw  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1310a68084Skrw  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1410a68084Skrw  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1510a68084Skrw  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1610a68084Skrw  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17a1705421Sweingart  */
18a1705421Sweingart 
19a7568474Sderaadt #include <sys/types.h>
20a7568474Sderaadt #include <sys/disklabel.h>
21e8252b55Skrw #include <err.h>
22a1705421Sweingart #include <stdio.h>
23*fba7235cSkrw #include <stdlib.h>
24184a329bSmillert #include <string.h>
25*fba7235cSkrw #include <uuid.h>
26abc6f793Skrw 
27a5472107Skrw #include "disk.h"
28a1705421Sweingart #include "misc.h"
29a5472107Skrw #include "part.h"
30a1705421Sweingart 
3153f0474fSkrw int	PRT_check_chs(struct prt *partn);
32a1705421Sweingart 
336c2b1c19Smickey static const struct part_type {
34a1705421Sweingart 	int	type;
356c2b1c19Smickey 	char	sname[14];
36*fba7235cSkrw 	char	guid[37];
37a1705421Sweingart } part_types[] = {
38*fba7235cSkrw 	{ 0x00, "unused      ", "00000000-0000-0000-0000-000000000000" },
39*fba7235cSkrw 	{ 0x01, "DOS FAT-12  ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
40764d6d49Stom 	{ 0x02, "XENIX /     "},   /* XENIX / filesystem */
41764d6d49Stom 	{ 0x03, "XENIX /usr  "},   /* XENIX /usr filesystem */
42*fba7235cSkrw 	{ 0x04, "DOS FAT-16  ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
43764d6d49Stom 	{ 0x05, "Extended DOS"},   /* Extended DOS */
44*fba7235cSkrw 	{ 0x06, "DOS > 32MB  ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
45*fba7235cSkrw 	{ 0x07, "NTFS        ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
46764d6d49Stom 	{ 0x08, "AIX fs      "},   /* AIX filesystem */
47764d6d49Stom 	{ 0x09, "AIX/Coherent"},   /* AIX boot partition or Coherent */
48764d6d49Stom 	{ 0x0A, "OS/2 Bootmgr"},   /* OS/2 Boot Manager or OPUS */
49*fba7235cSkrw 	{ 0x0B, "Win95 FAT-32", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
50*fba7235cSkrw 	{ 0x0C, "Win95 FAT32L", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
51*fba7235cSkrw 	{ 0x0E, "DOS FAT-16  ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
52764d6d49Stom 	{ 0x0F, "Extended LBA"},   /* Extended DOS LBA-mapped */
53764d6d49Stom 	{ 0x10, "OPUS        "},   /* OPUS */
54*fba7235cSkrw 	{ 0x11, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
55764d6d49Stom 	{ 0x12, "Compaq Diag."},   /* Compaq Diagnostics */
56*fba7235cSkrw 	{ 0x14, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
57*fba7235cSkrw 	{ 0x16, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
58*fba7235cSkrw 	{ 0x17, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
59764d6d49Stom 	{ 0x18, "AST swap    "},   /* AST Windows swapfile */
60764d6d49Stom 	{ 0x19, "Willowtech  "},   /* Willowtech Photon coS */
61*fba7235cSkrw 	{ 0x1C, "ThinkPad Rec", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
62764d6d49Stom 	{ 0x24, "NEC DOS     "},   /* NEC DOS */
63*fba7235cSkrw 	{ 0x27, "Win Recovery", "de94bba4-06d1-4d40-a16a-bfd50179d6ac" },
64*fba7235cSkrw 	{ 0x20, "Willowsoft  "},   /* Willowsoft OFS1 */
65764d6d49Stom 	{ 0x38, "Theos       "},   /* Theos */
66764d6d49Stom 	{ 0x39, "Plan 9      "},   /* Plan 9 */
67764d6d49Stom 	{ 0x40, "VENIX 286   "},   /* VENIX 286 or LynxOS */
68764d6d49Stom 	{ 0x41, "Lin/Minux DR"},   /* Linux/MINIX (sharing disk with DRDOS) or Personal RISC boot */
69*fba7235cSkrw 	{ 0x42, "LinuxSwap DR", "af9b60a0-1431-4f62-bc68-3311714a69ad" },
70764d6d49Stom 	{ 0x43, "Linux DR    "},   /* Linux native (sharing disk with DRDOS) */
71764d6d49Stom 	{ 0x4D, "QNX 4.2 Pri "},   /* QNX 4.2 Primary */
72764d6d49Stom 	{ 0x4E, "QNX 4.2 Sec "},   /* QNX 4.2 Secondary */
73764d6d49Stom 	{ 0x4F, "QNX 4.2 Ter "},   /* QNX 4.2 Tertiary */
74764d6d49Stom 	{ 0x50, "DM          "},   /* DM (disk manager) */
75764d6d49Stom 	{ 0x51, "DM          "},   /* DM6 Aux1 (or Novell) */
76764d6d49Stom 	{ 0x52, "CP/M or SysV"},   /* CP/M or Microport SysV/AT */
77764d6d49Stom 	{ 0x53, "DM          "},   /* DM6 Aux3 */
78764d6d49Stom 	{ 0x54, "Ontrack     "},   /* Ontrack */
79764d6d49Stom 	{ 0x55, "EZ-Drive    "},   /* EZ-Drive (disk manager) */
80764d6d49Stom 	{ 0x56, "Golden Bow  "},   /* Golden Bow (disk manager) */
81764d6d49Stom 	{ 0x5C, "Priam       "},   /* Priam Edisk (disk manager) */
82764d6d49Stom 	{ 0x61, "SpeedStor   "},   /* SpeedStor */
83764d6d49Stom 	{ 0x63, "ISC, HURD, *"},   /* ISC, System V/386, GNU HURD or Mach */
84764d6d49Stom 	{ 0x64, "NetWare 2.xx"},   /* Novell NetWare 2.xx */
85764d6d49Stom 	{ 0x65, "NetWare 3.xx"},   /* Novell NetWare 3.xx */
86764d6d49Stom 	{ 0x66, "NetWare 386 "},   /* Novell 386 NetWare */
87764d6d49Stom 	{ 0x67, "Novell      "},   /* Novell */
88764d6d49Stom 	{ 0x68, "Novell      "},   /* Novell */
89764d6d49Stom 	{ 0x69, "Novell      "},   /* Novell */
90764d6d49Stom 	{ 0x70, "DiskSecure  "},   /* DiskSecure Multi-Boot */
91764d6d49Stom 	{ 0x75, "PCIX        "},   /* PCIX */
92*fba7235cSkrw 	{ 0x7f, "ChromeKernel", "fe3a2a5d-4f32-41a7-b725-accc3285a309" },
93764d6d49Stom 	{ 0x80, "Minix (old) "},   /* Minix 1.1 ... 1.4a */
94764d6d49Stom 	{ 0x81, "Minix (new) "},   /* Minix 1.4b ... 1.5.10 */
95*fba7235cSkrw 	{ 0x82, "Linux swap  ", "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f" },
96*fba7235cSkrw 	{ 0x83, "Linux files*", "0fc63daf-8483-4772-8e79-3d69d8477de4" },
97764d6d49Stom 	{ 0x84, "OS/2 hidden "},   /* OS/2 hidden C: drive */
98764d6d49Stom 	{ 0x85, "Linux ext.  "},   /* Linux extended */
99764d6d49Stom 	{ 0x86, "NT FAT VS   "},   /* NT FAT volume set */
100764d6d49Stom 	{ 0x87, "NTFS VS     "},   /* NTFS volume set or HPFS mirrored */
101*fba7235cSkrw 	{ 0x8E, "Linux LVM   ", "e6d6d379-f507-44c2-a23c-238f2a3df928" },
102764d6d49Stom 	{ 0x93, "Amoeba FS   "},   /* Amoeba filesystem */
103764d6d49Stom 	{ 0x94, "Amoeba BBT  "},   /* Amoeba bad block table */
104764d6d49Stom 	{ 0x99, "Mylex       "},   /* Mylex EISA SCSI */
105764d6d49Stom 	{ 0x9F, "BSDI        "},   /* BSDI BSD/OS */
106764d6d49Stom 	{ 0xA0, "NotebookSave"},   /* Phoenix NoteBIOS save-to-disk */
107*fba7235cSkrw 	{ 0xA5, "FreeBSD     ", "516e7cb4-6ecf-11d6-8ff8-00022d09712b" },
108*fba7235cSkrw 	{ 0xA6, "OpenBSD     ", "824cc7a0-36a8-11e3-890a-952519ad3f61" },
109764d6d49Stom 	{ 0xA7, "NEXTSTEP    "},   /* NEXTSTEP */
110*fba7235cSkrw 	{ 0xA8, "MacOS X     ", "55465300-0000-11aa-aa11-00306543ecac" },
111*fba7235cSkrw 	{ 0xA9, "NetBSD      ", "516e7cb4-6ecf-11d6-8ff8-00022d09712b" },
112*fba7235cSkrw 	{ 0xAB, "MacOS X boot", "426f6f74-0000-11aa-aa11-00306543ecac" },
113*fba7235cSkrw 	{ 0xAF, "MacOS X HFS+", "48465300-0000-11aa-aa11-00306543ecac" },
114764d6d49Stom 	{ 0xB7, "BSDI filesy*"},   /* BSDI BSD/386 filesystem */
115764d6d49Stom 	{ 0xB8, "BSDI swap   "},   /* BSDI BSD/386 swap */
116*fba7235cSkrw 	{ 0xBF, "Solaris     ", "6a85cf4d-1dd2-11b2-99a6-080020736631" },
117764d6d49Stom 	{ 0xC0, "CTOS        "},   /* CTOS */
118764d6d49Stom 	{ 0xC1, "DRDOSs FAT12"},   /* DRDOS/sec (FAT-12) */
119764d6d49Stom 	{ 0xC4, "DRDOSs < 32M"},   /* DRDOS/sec (FAT-16, < 32M) */
120764d6d49Stom 	{ 0xC6, "DRDOSs >=32M"},   /* DRDOS/sec (FAT-16, >= 32M) */
121764d6d49Stom 	{ 0xC7, "HPFS Disbled"},   /* Syrinx (Cyrnix?) or HPFS disabled */
122764d6d49Stom 	{ 0xDB, "CPM/C.DOS/C*"},   /* Concurrent CPM or C.DOS or CTOS */
123764d6d49Stom 	{ 0xDE, "Dell Maint  "},   /* Dell maintenance partition */
124764d6d49Stom 	{ 0xE1, "SpeedStor   "},   /* DOS access or SpeedStor 12-bit FAT extended partition */
125764d6d49Stom 	{ 0xE3, "SpeedStor   "},   /* DOS R/O or SpeedStor or Storage Dimensions */
126764d6d49Stom 	{ 0xE4, "SpeedStor   "},   /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */
127*fba7235cSkrw 	{ 0xEB, "BeOS/i386   ", "42465331-3ba3-10f1-802a-4861696b7521" },
1282d874a94Sderaadt 	{ 0xEE, "EFI GPT     "},   /* EFI Protective Partition */
129*fba7235cSkrw 	{ 0xEF, "EFI Sys     ", "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" },
130764d6d49Stom 	{ 0xF1, "SpeedStor   "},   /* SpeedStor or Storage Dimensions */
131764d6d49Stom 	{ 0xF2, "DOS 3.3+ Sec"},   /* DOS 3.3+ Secondary */
132764d6d49Stom 	{ 0xF4, "SpeedStor   "},   /* SpeedStor >1024 cyl. or LANstep or IBM PS/2 IML */
133764d6d49Stom 	{ 0xFF, "Xenix BBT   "},   /* Xenix Bad Block Table */
134a1705421Sweingart };
135a1705421Sweingart 
1364b464610Sderaadt void
1378809fabbSderaadt PRT_printall(void)
1384b464610Sderaadt {
139d20bdfc6Skrw 	int i, idrows;
140d20bdfc6Skrw 
141d20bdfc6Skrw 	idrows = ((sizeof(part_types)/sizeof(struct part_type))+3)/4;
1424b464610Sderaadt 
143c2ad5584Sderaadt 	printf("Choose from the following Partition id values:\n");
144d20bdfc6Skrw 	for (i = 0; i < idrows; i++) {
145b5e17218Sderaadt 		printf("%02X %s   %02X %s   %02X %s",
146b5e17218Sderaadt 		    part_types[i].type, part_types[i].sname,
147b5e17218Sderaadt 		    part_types[i+idrows].type, part_types[i+idrows].sname,
148b5e17218Sderaadt 		    part_types[i+idrows*2].type, part_types[i+idrows*2].sname);
149d20bdfc6Skrw 		if ((i+idrows*3) < (sizeof(part_types)/sizeof(struct part_type))) {
150b5e17218Sderaadt 			printf("   %02X %s\n",
151b5e17218Sderaadt 			    part_types[i+idrows*3].type,
152b5e17218Sderaadt 			    part_types[i+idrows*3].sname);
153b5e17218Sderaadt 		} else
1544b464610Sderaadt 			printf( "\n" );
1554b464610Sderaadt 	}
156d20bdfc6Skrw }
157a1705421Sweingart 
1586c2b1c19Smickey const char *
1598809fabbSderaadt PRT_ascii_id(int id)
160a1705421Sweingart {
161a1705421Sweingart 	static char unknown[] = "<Unknown ID>";
162a1705421Sweingart 	int i;
163a1705421Sweingart 
164a1705421Sweingart 	for (i = 0; i < sizeof(part_types)/sizeof(struct part_type); i++) {
165a1705421Sweingart 		if (part_types[i].type == id)
1664b464610Sderaadt 			return (part_types[i].sname);
167a1705421Sweingart 	}
168a1705421Sweingart 
169a1705421Sweingart 	return (unknown);
170a1705421Sweingart }
171a1705421Sweingart 
172a1705421Sweingart void
173ac519580Skrw PRT_parse(struct dos_partition *prt, off_t offset, off_t reloff,
174ac519580Skrw     struct prt *partn)
175a1705421Sweingart {
176ca2e86e1Sprovos 	off_t off;
1770ac3b43bSmiod 	u_int32_t t;
178a1705421Sweingart 
17940b0f5f3Skrw 	partn->flag = prt->dp_flag;
18040b0f5f3Skrw 	partn->shead = prt->dp_shd;
181ca2e86e1Sprovos 
18240b0f5f3Skrw 	partn->ssect = (prt->dp_ssect) & 0x3F;
18340b0f5f3Skrw 	partn->scyl = ((prt->dp_ssect << 2) & 0xFF00) | prt->dp_scyl;
184a1705421Sweingart 
18540b0f5f3Skrw 	partn->id = prt->dp_typ;
18640b0f5f3Skrw 	partn->ehead = prt->dp_ehd;
18740b0f5f3Skrw 	partn->esect = (prt->dp_esect) & 0x3F;
18840b0f5f3Skrw 	partn->ecyl = ((prt->dp_esect << 2) & 0xFF00) | prt->dp_ecyl;
189a1705421Sweingart 
190c3e3230dSderaadt 	if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
191c3e3230dSderaadt 		off = reloff;
192c3e3230dSderaadt 	else
193c3e3230dSderaadt 		off = offset;
194ca2e86e1Sprovos 
1950ac3b43bSmiod #if 0 /* XXX */
19653f15ebcSkrw 	partn->bs = letoh32(prt->dp_start) + off;
19753f15ebcSkrw 	partn->ns = letoh32(prt->dp_size);
1980ac3b43bSmiod #else
1990ac3b43bSmiod 	memcpy(&t, &prt->dp_start, sizeof(u_int32_t));
2000ac3b43bSmiod 	partn->bs = letoh32(t) + off;
2010ac3b43bSmiod 	memcpy(&t, &prt->dp_size, sizeof(u_int32_t));
2020ac3b43bSmiod 	partn->ns = letoh32(t);
2030ac3b43bSmiod #endif
2044ed7cd7eSrahnds 
205ac519580Skrw 	PRT_fix_CHS(partn);
2064ed7cd7eSrahnds }
207a1705421Sweingart 
2084ed7cd7eSrahnds int
20953f0474fSkrw PRT_check_chs(struct prt *partn)
2104ed7cd7eSrahnds {
2114ed7cd7eSrahnds 	if ( (partn->shead > 255) ||
2124ed7cd7eSrahnds 		(partn->ssect >63) ||
2134ed7cd7eSrahnds 		(partn->scyl > 1023) ||
2144ed7cd7eSrahnds 		(partn->ehead >255) ||
2154ed7cd7eSrahnds 		(partn->esect >63) ||
2164ed7cd7eSrahnds 		(partn->ecyl > 1023) )
2174ed7cd7eSrahnds 	{
2187126966cSkrw 		return (0);
2194ed7cd7eSrahnds 	}
2207126966cSkrw 	return (1);
2214ed7cd7eSrahnds }
22249241bdaSkrw 
223a1705421Sweingart void
22440b0f5f3Skrw PRT_make(struct prt *partn, off_t offset, off_t reloff,
22540b0f5f3Skrw     struct dos_partition *prt)
226a1705421Sweingart {
227c3e3230dSderaadt 	off_t off;
22819304799Skrw 	u_int32_t ecsave, scsave;
2295f3fed51Skrw 	u_int64_t t;
230c3e3230dSderaadt 
23119304799Skrw 	/* Save (and restore below) cylinder info we may fiddle with. */
2326d5e103bSkjell 	scsave = partn->scyl;
2336d5e103bSkjell 	ecsave = partn->ecyl;
23419304799Skrw 
23519304799Skrw 	if ((partn->scyl > 1023) || (partn->ecyl > 1023)) {
2366d5e103bSkjell 		partn->scyl = (partn->scyl > 1023)? 1023: partn->scyl;
2376d5e103bSkjell 		partn->ecyl = (partn->ecyl > 1023)? 1023: partn->ecyl;
238c3e3230dSderaadt 	}
239c3e3230dSderaadt 	if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
240c3e3230dSderaadt 		off = reloff;
241c3e3230dSderaadt 	else
242c3e3230dSderaadt 		off = offset;
243a1705421Sweingart 
2444ed7cd7eSrahnds 	if (PRT_check_chs(partn)) {
24540b0f5f3Skrw 		prt->dp_shd = partn->shead & 0xFF;
24640b0f5f3Skrw 		prt->dp_ssect = (partn->ssect & 0x3F) |
24740b0f5f3Skrw 		    ((partn->scyl & 0x300) >> 2);
24840b0f5f3Skrw 		prt->dp_scyl = partn->scyl & 0xFF;
24940b0f5f3Skrw 		prt->dp_ehd = partn->ehead & 0xFF;
25040b0f5f3Skrw 		prt->dp_esect = (partn->esect & 0x3F) |
25140b0f5f3Skrw 		    ((partn->ecyl & 0x300) >> 2);
25240b0f5f3Skrw 		prt->dp_ecyl = partn->ecyl & 0xFF;
2534ed7cd7eSrahnds 	} else {
2544ed7cd7eSrahnds 		/* should this really keep flag, id and set others to 0xff? */
25540b0f5f3Skrw 		memset(prt, 0xFF, sizeof(*prt));
256ba49db25Skrw 		printf("Warning CHS values out of bounds only saving "
257ba49db25Skrw 		    "LBA values\n");
2584ed7cd7eSrahnds 	}
259a1705421Sweingart 
26040b0f5f3Skrw 	prt->dp_flag = partn->flag & 0xFF;
26140b0f5f3Skrw 	prt->dp_typ = partn->id & 0xFF;
26240b0f5f3Skrw 
2635f3fed51Skrw 	t = htole64(partn->bs - off);
2640ac3b43bSmiod 	memcpy(&prt->dp_start, &t, sizeof(u_int32_t));
2655f3fed51Skrw 	t = htole64(partn->ns);
2660ac3b43bSmiod 	memcpy(&prt->dp_size, &t, sizeof(u_int32_t));
26719304799Skrw 
2686d5e103bSkjell 	partn->scyl = scsave;
2696d5e103bSkjell 	partn->ecyl = ecsave;
2706d5e103bSkjell }
271a1705421Sweingart 
272a1705421Sweingart void
27353f0474fSkrw PRT_print(int num, struct prt *partn, char *units)
274a1705421Sweingart {
275*fba7235cSkrw 	const int secsize = unit_types[SECTORS].conversion;
2768ce00868Skjell 	double size;
2778ce00868Skjell 	int i;
2787126966cSkrw 
2798ce00868Skjell 	i = unit_lookup(units);
280a1705421Sweingart 
281a1705421Sweingart 	if (partn == NULL) {
282ba49db25Skrw 		printf("            Starting         Ending    "
283ba49db25Skrw 		    "     LBA Info:\n");
284ba49db25Skrw 		printf(" #: id      C   H   S -      C   H   S "
285ba49db25Skrw 		    "[       start:        size ]\n");
286ba49db25Skrw 		printf("---------------------------------------"
287ba49db25Skrw 		    "----------------------------------------\n");
288a1705421Sweingart 	} else {
289*fba7235cSkrw 		size = ((double)partn->ns * secsize) / unit_types[i].conversion;
290ba49db25Skrw 		printf("%c%1d: %.2X %6u %3u %3u - %6u %3u %3u "
291ba49db25Skrw 		    "[%12llu:%12.0f%s] %s\n",
292512f4667Skrw 		    (partn->flag == DOSACTIVE)?'*':' ',
293a1705421Sweingart 		    num, partn->id,
294a1705421Sweingart 		    partn->scyl, partn->shead, partn->ssect,
295a1705421Sweingart 		    partn->ecyl, partn->ehead, partn->esect,
2968ce00868Skjell 		    partn->bs, size,
2978ce00868Skjell 		    unit_types[i].abbr,
298a1705421Sweingart 		    PRT_ascii_id(partn->id));
299a1705421Sweingart 	}
300a1705421Sweingart }
301a1705421Sweingart 
302a1705421Sweingart void
303ac519580Skrw PRT_fix_BN(struct prt *part, int pn)
304a1705421Sweingart {
305a8483158Sotto 	u_int32_t spt, tpc, spc;
306a8483158Sotto 	u_int32_t start = 0;
307a8483158Sotto 	u_int32_t end = 0;
308a1705421Sweingart 
309eb4cb19dSkjell 	/* Zero out entry if not used */
310dda9932bSotto 	if (part->id == DOSPTYP_UNUSED) {
311eb4cb19dSkjell 		memset(part, 0, sizeof(*part));
312eb4cb19dSkjell 		return;
313eb4cb19dSkjell 	}
314eb4cb19dSkjell 
3155cbc8961Skrw 	/* Disk geometry. */
316ac519580Skrw 	spt = disk.sectors;
317ac519580Skrw 	tpc = disk.heads;
318a1705421Sweingart 	spc = spt * tpc;
319a1705421Sweingart 
320a1705421Sweingart 	start += part->scyl * spc;
321a1705421Sweingart 	start += part->shead * spt;
322a1705421Sweingart 	start += part->ssect - 1;
323a1705421Sweingart 
324a1705421Sweingart 	end += part->ecyl * spc;
325a1705421Sweingart 	end += part->ehead * spt;
326a1705421Sweingart 	end += part->esect - 1;
327a1705421Sweingart 
328a1705421Sweingart 	/* XXX - Should handle this... */
329a1705421Sweingart 	if (start > end)
330a1d76f6dSkrw 		warnx("Start of partition #%d after end!", pn);
331a1705421Sweingart 
332a1705421Sweingart 	part->bs = start;
333a1705421Sweingart 	part->ns = (end - start) + 1;
334a1705421Sweingart }
335a1705421Sweingart 
336a1705421Sweingart void
337ac519580Skrw PRT_fix_CHS(struct prt *part)
338a1705421Sweingart {
339a8483158Sotto 	u_int32_t spt, tpc, spc;
340a8483158Sotto 	u_int32_t start, end, size;
341a8483158Sotto 	u_int32_t cyl, head, sect;
342a1705421Sweingart 
343eb4cb19dSkjell 	/* Zero out entry if not used */
344e14e8952Skrw 	if (part->id == DOSPTYP_UNUSED || part->ns == 0) {
345eb4cb19dSkjell 		memset(part, 0, sizeof(*part));
346eb4cb19dSkjell 		return;
347eb4cb19dSkjell 	}
348eb4cb19dSkjell 
3495cbc8961Skrw 	/* Disk geometry. */
350ac519580Skrw 	spt = disk.sectors;
351ac519580Skrw 	tpc = disk.heads;
352a1705421Sweingart 	spc = spt * tpc;
353a1705421Sweingart 
354a1705421Sweingart 	start = part->bs;
355a1705421Sweingart 	size = part->ns;
356a1705421Sweingart 	end = (start + size) - 1;
357a1705421Sweingart 
358a1705421Sweingart 	/* Figure out starting CHS values */
359a1705421Sweingart 	cyl = (start / spc); start -= (cyl * spc);
360a1705421Sweingart 	head = (start / spt); start -= (head * spt);
361a1705421Sweingart 	sect = (start + 1);
362a1705421Sweingart 
363a1705421Sweingart 	part->scyl = cyl;
364a1705421Sweingart 	part->shead = head;
365a1705421Sweingart 	part->ssect = sect;
366a1705421Sweingart 
367a1705421Sweingart 	/* Figure out ending CHS values */
368a1705421Sweingart 	cyl = (end / spc); end -= (cyl * spc);
369a1705421Sweingart 	head = (end / spt); end -= (head * spt);
370a1705421Sweingart 	sect = (end + 1);
371a1705421Sweingart 
372a1705421Sweingart 	part->ecyl = cyl;
373a1705421Sweingart 	part->ehead = head;
374a1705421Sweingart 	part->esect = sect;
375a1705421Sweingart }
376*fba7235cSkrw 
377*fba7235cSkrw char *
378*fba7235cSkrw PRT_uuid_to_type(struct uuid *uuid)
379*fba7235cSkrw {
380*fba7235cSkrw 	static char partition_type[37];	/* Room for a GUID if needed. */
381*fba7235cSkrw 	char *uuidstr = NULL;
382*fba7235cSkrw 	int i, entries, status;
383*fba7235cSkrw 
384*fba7235cSkrw 	memset(partition_type, 0, sizeof(partition_type));
385*fba7235cSkrw 
386*fba7235cSkrw 	uuid_to_string(uuid, &uuidstr, &status);
387*fba7235cSkrw 	if (status != uuid_s_ok)
388*fba7235cSkrw 		goto done;
389*fba7235cSkrw 
390*fba7235cSkrw 	entries = sizeof(part_types) / sizeof(struct part_type);
391*fba7235cSkrw 
392*fba7235cSkrw 	for (i = 0; i < entries; i++) {
393*fba7235cSkrw 		if (memcmp(part_types[i].guid, uuidstr,
394*fba7235cSkrw 		    sizeof(part_types[i].guid)) == 0)
395*fba7235cSkrw 			break;
396*fba7235cSkrw 	}
397*fba7235cSkrw 
398*fba7235cSkrw 	if (i < entries)
399*fba7235cSkrw 		strlcpy(partition_type, part_types[i].sname,
400*fba7235cSkrw 		    sizeof(partition_type));
401*fba7235cSkrw 	else
402*fba7235cSkrw 		strlcpy(partition_type, uuidstr, sizeof(partition_type));
403*fba7235cSkrw 
404*fba7235cSkrw done:
405*fba7235cSkrw 	free(uuidstr);
406*fba7235cSkrw 
407*fba7235cSkrw 	return (partition_type);
408*fba7235cSkrw }
409*fba7235cSkrw 
410*fba7235cSkrw struct uuid *
411*fba7235cSkrw PRT_type_to_uuid(int type)
412*fba7235cSkrw {
413*fba7235cSkrw 	static struct uuid guid;
414*fba7235cSkrw 	int i, entries, status = uuid_s_ok;
415*fba7235cSkrw 
416*fba7235cSkrw 	memset(&guid, 0, sizeof(guid));
417*fba7235cSkrw 
418*fba7235cSkrw 	entries = sizeof(part_types) / sizeof(struct part_type);
419*fba7235cSkrw 
420*fba7235cSkrw 	for (i = 0; i < entries; i++) {
421*fba7235cSkrw 		if (part_types[i].type == type)
422*fba7235cSkrw 			break;
423*fba7235cSkrw 	}
424*fba7235cSkrw 	if (i < entries)
425*fba7235cSkrw 		uuid_from_string(part_types[i].guid, &guid, &status);
426*fba7235cSkrw 	if (i == entries || status != uuid_s_ok)
427*fba7235cSkrw 		uuid_from_string(part_types[0].guid, &guid, &status);
428*fba7235cSkrw 
429*fba7235cSkrw 	return (&guid);
430*fba7235cSkrw }
431